mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-14 16:09:06 +07:00
promises for async vfs operations
This commit is contained in:
125
headers/3rdparty/promise.hpp/promise.hpp
vendored
125
headers/3rdparty/promise.hpp/promise.hpp
vendored
@@ -178,16 +178,16 @@ namespace promise_hpp
|
||||
then([
|
||||
n = next,
|
||||
f = std::forward<ResolveF>(on_resolve)
|
||||
](const T& v) mutable {
|
||||
](auto&& v) mutable {
|
||||
auto np = invoke_hpp::invoke(
|
||||
std::forward<decltype(f)>(f),
|
||||
v);
|
||||
np.then([n]() mutable {
|
||||
std::forward<decltype(v)>(v));
|
||||
std::move(np).then([n]() mutable {
|
||||
n.resolve();
|
||||
}, [n](std::exception_ptr e) mutable {
|
||||
}).except([n](std::exception_ptr e) mutable {
|
||||
n.reject(e);
|
||||
});
|
||||
}, [n = next](std::exception_ptr e) mutable {
|
||||
}).except([n = next](std::exception_ptr e) mutable {
|
||||
n.reject(e);
|
||||
});
|
||||
|
||||
@@ -205,16 +205,16 @@ namespace promise_hpp
|
||||
then([
|
||||
n = next,
|
||||
f = std::forward<ResolveF>(on_resolve)
|
||||
](const T& v) mutable {
|
||||
](auto&& v) mutable {
|
||||
auto np = invoke_hpp::invoke(
|
||||
std::forward<decltype(f)>(f),
|
||||
v);
|
||||
np.then([n](const typename ResolveFR::value_type& nv) mutable {
|
||||
n.resolve(nv);
|
||||
}, [n](std::exception_ptr e) mutable {
|
||||
std::forward<decltype(v)>(v));
|
||||
std::move(np).then([n](auto&& nv) mutable {
|
||||
n.resolve(std::forward<decltype(nv)>(nv));
|
||||
}).except([n](std::exception_ptr e) mutable {
|
||||
n.reject(e);
|
||||
});
|
||||
}, [n = next](std::exception_ptr e) mutable {
|
||||
}).except([n = next](std::exception_ptr e) mutable {
|
||||
n.reject(e);
|
||||
});
|
||||
|
||||
@@ -225,10 +225,10 @@ namespace promise_hpp
|
||||
auto then_all(ResolveF&& on_resolve) {
|
||||
return then([
|
||||
f = std::forward<ResolveF>(on_resolve)
|
||||
](const T& v) mutable {
|
||||
](auto&& v) mutable {
|
||||
auto r = invoke_hpp::invoke(
|
||||
std::forward<decltype(f)>(f),
|
||||
v);
|
||||
std::forward<decltype(v)>(v));
|
||||
return make_all_promise(std::move(r));
|
||||
});
|
||||
}
|
||||
@@ -237,10 +237,10 @@ namespace promise_hpp
|
||||
auto then_any(ResolveF&& on_resolve) {
|
||||
return then([
|
||||
f = std::forward<ResolveF>(on_resolve)
|
||||
](const T& v) mutable {
|
||||
](auto&& v) mutable {
|
||||
auto r = invoke_hpp::invoke(
|
||||
std::forward<decltype(f)>(f),
|
||||
v);
|
||||
std::forward<decltype(v)>(v));
|
||||
return make_any_promise(std::move(r));
|
||||
});
|
||||
}
|
||||
@@ -274,14 +274,13 @@ namespace promise_hpp
|
||||
template < typename RejectF >
|
||||
promise<T> except(RejectF&& on_reject) {
|
||||
return then(
|
||||
[](const T& value) { return value; },
|
||||
[](auto&& v) { return std::forward<decltype(v)>(v); },
|
||||
std::forward<RejectF>(on_reject));
|
||||
}
|
||||
|
||||
template < typename U >
|
||||
bool resolve(U&& value) {
|
||||
return state_->resolve(
|
||||
std::forward<U>(value));
|
||||
return state_->resolve(std::forward<U>(value));
|
||||
}
|
||||
|
||||
bool reject(std::exception_ptr e) noexcept {
|
||||
@@ -298,6 +297,14 @@ namespace promise_hpp
|
||||
return state_->get();
|
||||
}
|
||||
|
||||
const T& get_or_default(const T& def) const noexcept {
|
||||
try {
|
||||
return get();
|
||||
} catch (...) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
void wait() const noexcept {
|
||||
state_->wait();
|
||||
}
|
||||
@@ -391,10 +398,10 @@ namespace promise_hpp
|
||||
|
||||
template < typename U, typename ResolveF, typename RejectF >
|
||||
std::enable_if_t<std::is_void<U>::value, void>
|
||||
attach(promise<U>& next, ResolveF&& resolve, RejectF&& reject) {
|
||||
attach(promise<U>& next, ResolveF&& on_resolve, RejectF&& on_reject) {
|
||||
auto reject_h = [
|
||||
n = next,
|
||||
f = std::forward<RejectF>(reject)
|
||||
f = std::forward<RejectF>(on_reject)
|
||||
](std::exception_ptr e) mutable {
|
||||
try {
|
||||
invoke_hpp::invoke(
|
||||
@@ -408,18 +415,15 @@ namespace promise_hpp
|
||||
|
||||
auto resolve_h = [
|
||||
n = next,
|
||||
f = std::forward<ResolveF>(resolve),
|
||||
j = reject_h
|
||||
](const T& v) mutable {
|
||||
f = std::forward<ResolveF>(on_resolve)
|
||||
](auto&& v) mutable {
|
||||
try {
|
||||
invoke_hpp::invoke(
|
||||
std::forward<decltype(f)>(f),
|
||||
v);
|
||||
std::forward<decltype(v)>(v));
|
||||
n.resolve();
|
||||
} catch (...) {
|
||||
invoke_hpp::invoke(
|
||||
std::move(j),
|
||||
std::current_exception());
|
||||
n.reject(std::current_exception());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -429,10 +433,10 @@ namespace promise_hpp
|
||||
|
||||
template < typename U, typename ResolveF, typename RejectF >
|
||||
std::enable_if_t<!std::is_void<U>::value, void>
|
||||
attach(promise<U>& next, ResolveF&& resolve, RejectF&& reject) {
|
||||
attach(promise<U>& next, ResolveF&& on_resolve, RejectF&& on_reject) {
|
||||
auto reject_h = [
|
||||
n = next,
|
||||
f = std::forward<RejectF>(reject)
|
||||
f = std::forward<RejectF>(on_reject)
|
||||
](std::exception_ptr e) mutable {
|
||||
try {
|
||||
invoke_hpp::invoke(
|
||||
@@ -446,18 +450,15 @@ namespace promise_hpp
|
||||
|
||||
auto resolve_h = [
|
||||
n = next,
|
||||
f = std::forward<ResolveF>(resolve),
|
||||
j = reject_h
|
||||
](const T& v) mutable {
|
||||
f = std::forward<ResolveF>(on_resolve)
|
||||
](auto&& v) mutable {
|
||||
try {
|
||||
auto r = invoke_hpp::invoke(
|
||||
std::forward<decltype(f)>(f),
|
||||
v);
|
||||
std::forward<decltype(v)>(v));
|
||||
n.resolve(std::move(r));
|
||||
} catch (...) {
|
||||
invoke_hpp::invoke(
|
||||
std::move(j),
|
||||
std::current_exception());
|
||||
n.reject(std::current_exception());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -576,12 +577,12 @@ namespace promise_hpp
|
||||
]() mutable {
|
||||
auto np = invoke_hpp::invoke(
|
||||
std::forward<decltype(f)>(f));
|
||||
np.then([n]() mutable {
|
||||
std::move(np).then([n]() mutable {
|
||||
n.resolve();
|
||||
}, [n](std::exception_ptr e) mutable {
|
||||
}).except([n](std::exception_ptr e) mutable {
|
||||
n.reject(e);
|
||||
});
|
||||
}, [n = next](std::exception_ptr e) mutable {
|
||||
}).except([n = next](std::exception_ptr e) mutable {
|
||||
n.reject(e);
|
||||
});
|
||||
|
||||
@@ -602,12 +603,12 @@ namespace promise_hpp
|
||||
]() mutable {
|
||||
auto np = invoke_hpp::invoke(
|
||||
std::forward<decltype(f)>(f));
|
||||
np.then([n](const typename ResolveFR::value_type& nv) mutable {
|
||||
n.resolve(nv);
|
||||
}, [n](std::exception_ptr e) mutable {
|
||||
std::move(np).then([n](auto&& nv) mutable {
|
||||
n.resolve(std::forward<decltype(nv)>(nv));
|
||||
}).except([n](std::exception_ptr e) mutable {
|
||||
n.reject(e);
|
||||
});
|
||||
}, [n = next](std::exception_ptr e) mutable {
|
||||
}).except([n = next](std::exception_ptr e) mutable {
|
||||
n.reject(e);
|
||||
});
|
||||
|
||||
@@ -687,6 +688,14 @@ namespace promise_hpp
|
||||
state_->get();
|
||||
}
|
||||
|
||||
void get_or_default() const noexcept {
|
||||
try {
|
||||
return get();
|
||||
} catch (...) {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
|
||||
void wait() const noexcept {
|
||||
state_->wait();
|
||||
}
|
||||
@@ -777,10 +786,10 @@ namespace promise_hpp
|
||||
|
||||
template < typename U, typename ResolveF, typename RejectF >
|
||||
std::enable_if_t<std::is_void<U>::value, void>
|
||||
attach(promise<U>& next, ResolveF&& resolve, RejectF&& reject) {
|
||||
attach(promise<U>& next, ResolveF&& on_resolve, RejectF&& on_reject) {
|
||||
auto reject_h = [
|
||||
n = next,
|
||||
f = std::forward<RejectF>(reject)
|
||||
f = std::forward<RejectF>(on_reject)
|
||||
](std::exception_ptr e) mutable {
|
||||
try {
|
||||
invoke_hpp::invoke(
|
||||
@@ -794,17 +803,14 @@ namespace promise_hpp
|
||||
|
||||
auto resolve_h = [
|
||||
n = next,
|
||||
f = std::forward<ResolveF>(resolve),
|
||||
j = reject_h
|
||||
f = std::forward<ResolveF>(on_resolve)
|
||||
]() mutable {
|
||||
try {
|
||||
invoke_hpp::invoke(
|
||||
std::forward<decltype(f)>(f));
|
||||
n.resolve();
|
||||
} catch (...) {
|
||||
invoke_hpp::invoke(
|
||||
std::move(j),
|
||||
std::current_exception());
|
||||
n.reject(std::current_exception());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -814,10 +820,10 @@ namespace promise_hpp
|
||||
|
||||
template < typename U, typename ResolveF, typename RejectF >
|
||||
std::enable_if_t<!std::is_void<U>::value, void>
|
||||
attach(promise<U>& next, ResolveF&& resolve, RejectF&& reject) {
|
||||
attach(promise<U>& next, ResolveF&& on_resolve, RejectF&& on_reject) {
|
||||
auto reject_h = [
|
||||
n = next,
|
||||
f = std::forward<RejectF>(reject)
|
||||
f = std::forward<RejectF>(on_reject)
|
||||
](std::exception_ptr e) mutable {
|
||||
try {
|
||||
invoke_hpp::invoke(
|
||||
@@ -831,17 +837,14 @@ namespace promise_hpp
|
||||
|
||||
auto resolve_h = [
|
||||
n = next,
|
||||
f = std::forward<ResolveF>(resolve),
|
||||
j = reject_h
|
||||
f = std::forward<ResolveF>(on_resolve)
|
||||
]() mutable {
|
||||
try {
|
||||
auto r = invoke_hpp::invoke(
|
||||
std::forward<decltype(f)>(f));
|
||||
n.resolve(std::move(r));
|
||||
} catch (...) {
|
||||
invoke_hpp::invoke(
|
||||
std::move(j),
|
||||
std::current_exception());
|
||||
n.reject(std::current_exception());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1020,11 +1023,11 @@ namespace promise_hpp
|
||||
context,
|
||||
resolver,
|
||||
result_index
|
||||
](const child_promise_value_t& v) mutable {
|
||||
if ( context->apply_result(result_index, v) ) {
|
||||
](auto&& v) mutable {
|
||||
if ( context->apply_result(result_index, std::forward<decltype(v)>(v)) ) {
|
||||
resolver(std::move(context->results));
|
||||
}
|
||||
}, rejector);
|
||||
}).except(rejector);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1051,7 +1054,7 @@ namespace promise_hpp
|
||||
|
||||
return make_promise<child_promise_value_t>([begin, end](auto&& resolver, auto&& rejector){
|
||||
for ( auto iter = begin; iter != end; ++iter ) {
|
||||
(*iter).then(resolver, rejector);
|
||||
(*iter).then(resolver).except(rejector);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -17,6 +17,12 @@ namespace e2d
|
||||
}
|
||||
};
|
||||
|
||||
class vfs_load_async_exception final : public exception {
|
||||
const char* what() const noexcept final {
|
||||
return "vfs load async exception";
|
||||
}
|
||||
};
|
||||
|
||||
class vfs final : public module<vfs> {
|
||||
public:
|
||||
vfs();
|
||||
@@ -27,8 +33,7 @@ namespace e2d
|
||||
virtual ~file_source() noexcept = default;
|
||||
virtual bool valid() const noexcept = 0;
|
||||
virtual bool exists(str_view path) const = 0;
|
||||
virtual input_stream_uptr open(str_view path) const = 0;
|
||||
virtual std::pair<buffer,bool> load(str_view path) const = 0;
|
||||
virtual input_stream_uptr read(str_view path) const = 0;
|
||||
virtual output_stream_uptr write(str_view path, bool append) const = 0;
|
||||
virtual bool trace(str_view path, filesystem::trace_func func) const = 0;
|
||||
};
|
||||
@@ -43,10 +48,15 @@ namespace e2d
|
||||
bool unregister_scheme_alias(str_view scheme);
|
||||
|
||||
bool exists(const url& url) const;
|
||||
input_stream_uptr open(const url& url) const;
|
||||
std::pair<buffer,bool> load(const url& url) const;
|
||||
|
||||
input_stream_uptr read(const url& url) const;
|
||||
output_stream_uptr write(const url& url, bool append) const;
|
||||
stdex::promise<std::pair<buffer,bool>> load_async(const url& url) const;
|
||||
|
||||
bool load(const url& url, buffer& dst) const;
|
||||
stdex::promise<buffer> load_async(const url& url) const;
|
||||
|
||||
bool load_as_string(const url& url, str& dst) const;
|
||||
stdex::promise<str> load_as_string_async(const url& url) const;
|
||||
|
||||
template < typename Iter >
|
||||
bool extract(const url& url, Iter result_iter) const;
|
||||
@@ -64,8 +74,7 @@ namespace e2d
|
||||
~archive_file_source() noexcept final;
|
||||
bool valid() const noexcept final;
|
||||
bool exists(str_view path) const final;
|
||||
input_stream_uptr open(str_view path) const final;
|
||||
std::pair<buffer,bool> load(str_view path) const final;
|
||||
input_stream_uptr read(str_view path) const final;
|
||||
output_stream_uptr write(str_view path, bool append) const final;
|
||||
bool trace(str_view path, filesystem::trace_func func) const final;
|
||||
private:
|
||||
@@ -79,8 +88,7 @@ namespace e2d
|
||||
~filesystem_file_source() noexcept final;
|
||||
bool valid() const noexcept final;
|
||||
bool exists(str_view path) const final;
|
||||
input_stream_uptr open(str_view path) const final;
|
||||
std::pair<buffer,bool> load(str_view path) const final;
|
||||
input_stream_uptr read(str_view path) const final;
|
||||
output_stream_uptr write(str_view path, bool append) const final;
|
||||
bool trace(str_view path, filesystem::trace_func func) const final;
|
||||
};
|
||||
|
||||
Submodule modules/promise.hpp updated: 4fb77fb49d...5871ecea02
@@ -95,7 +95,7 @@ namespace
|
||||
bool initialize() final {
|
||||
the<vfs>().register_scheme<archive_file_source>(
|
||||
"piratepack",
|
||||
the<vfs>().open(url("resources://bin/kenney_piratepack.zip")));
|
||||
the<vfs>().read(url("resources://bin/kenney_piratepack.zip")));
|
||||
|
||||
the<vfs>().register_scheme_alias(
|
||||
"ships",
|
||||
@@ -104,9 +104,9 @@ namespace
|
||||
shader_ = the<render>().create_shader(
|
||||
vs_source_cstr, fs_source_cstr);
|
||||
texture1_ = the<render>().create_texture(
|
||||
the<vfs>().open(url("ships://ship (2).png")));
|
||||
the<vfs>().read(url("ships://ship (2).png")));
|
||||
texture2_ = the<render>().create_texture(
|
||||
the<vfs>().open(url("ships://ship (19).png")));
|
||||
the<vfs>().read(url("ships://ship (19).png")));
|
||||
|
||||
if ( !shader_ || !texture1_ || !texture2_ ) {
|
||||
return false;
|
||||
|
||||
@@ -155,7 +155,7 @@ namespace
|
||||
bool initialize() final {
|
||||
the<vfs>().register_scheme<archive_file_source>(
|
||||
"piratepack",
|
||||
the<vfs>().open(url("resources://bin/kenney_piratepack.zip")));
|
||||
the<vfs>().read(url("resources://bin/kenney_piratepack.zip")));
|
||||
|
||||
the<vfs>().register_scheme_alias(
|
||||
"ships",
|
||||
@@ -165,7 +165,7 @@ namespace
|
||||
vs_source_cstr, fs_source_cstr);
|
||||
|
||||
texture_ = the<render>().create_texture(
|
||||
the<vfs>().open(url("ships://ship (3).png")));
|
||||
the<vfs>().read(url("ships://ship (3).png")));
|
||||
|
||||
if ( !shader_ || !texture_ ) {
|
||||
return false;
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace
|
||||
bool initialize() final {
|
||||
the<vfs>().register_scheme<archive_file_source>(
|
||||
"piratepack",
|
||||
the<vfs>().open(url("resources://bin/kenney_piratepack.zip")));
|
||||
the<vfs>().read(url("resources://bin/kenney_piratepack.zip")));
|
||||
|
||||
the<vfs>().register_scheme_alias(
|
||||
"ships",
|
||||
@@ -120,7 +120,7 @@ namespace
|
||||
vs_source_cstr, fs_source_cstr);
|
||||
|
||||
texture_ = the<render>().create_texture(
|
||||
the<vfs>().open(url("ships://ship (3).png")));
|
||||
the<vfs>().read(url("ships://ship (3).png")));
|
||||
|
||||
if ( !shader_ || !texture_ ) {
|
||||
return false;
|
||||
|
||||
@@ -98,7 +98,10 @@ namespace e2d
|
||||
const auto resolved_url = resolve_url(url);
|
||||
const auto scheme_iter = schemes.find(resolved_url.scheme());
|
||||
return (scheme_iter != schemes.cend() && scheme_iter->second)
|
||||
? stdex::invoke(std::forward<F>(f), scheme_iter->second, resolved_url.path())
|
||||
? stdex::invoke(
|
||||
std::forward<F>(f),
|
||||
scheme_iter->second,
|
||||
resolved_url.path())
|
||||
: std::forward<R>(fallback_result);
|
||||
}
|
||||
};
|
||||
@@ -140,22 +143,14 @@ namespace e2d
|
||||
}, false);
|
||||
}
|
||||
|
||||
input_stream_uptr vfs::open(const url& url) const {
|
||||
input_stream_uptr vfs::read(const url& url) const {
|
||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||
return state_->with_file_source(url,
|
||||
[](const file_source_uptr& source, const str& path) {
|
||||
return source->open(path);
|
||||
return source->read(path);
|
||||
}, input_stream_uptr());
|
||||
}
|
||||
|
||||
std::pair<buffer,bool> vfs::load(const url& url) const {
|
||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||
return state_->with_file_source(url,
|
||||
[](const file_source_uptr& source, const str& path) {
|
||||
return source->load(path);
|
||||
}, std::make_pair(buffer(), false));
|
||||
}
|
||||
|
||||
output_stream_uptr vfs::write(const url& url, bool append) const {
|
||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||
return state_->with_file_source(url,
|
||||
@@ -164,13 +159,40 @@ namespace e2d
|
||||
}, output_stream_uptr());
|
||||
}
|
||||
|
||||
stdex::promise<std::pair<buffer,bool>> vfs::load_async(const url& url) const {
|
||||
return state_->worker.async([](input_stream_uptr stream){
|
||||
buffer buf;
|
||||
return streams::try_read_tail(buf, stream)
|
||||
? std::make_pair(std::move(buf), true)
|
||||
: std::make_pair(buffer(), false);
|
||||
}, open(url));
|
||||
bool vfs::load(const url& url, buffer& dst) const {
|
||||
return load_async(url)
|
||||
.then([&dst](auto&& src){
|
||||
dst = std::forward<decltype(src)>(src);
|
||||
return true;
|
||||
}).get_or_default(false);
|
||||
}
|
||||
|
||||
stdex::promise<buffer> vfs::load_async(const url& url) const {
|
||||
return state_->worker.async([this](auto&& url_copy){
|
||||
buffer content;
|
||||
if ( !streams::try_read_tail(content, read(url_copy)) ) {
|
||||
throw vfs_load_async_exception();
|
||||
}
|
||||
return content;
|
||||
}, url);
|
||||
}
|
||||
|
||||
bool vfs::load_as_string(const url& url, str& dst) const {
|
||||
return load_as_string_async(url)
|
||||
.then([&dst](auto&& src){
|
||||
dst = std::forward<decltype(src)>(src);
|
||||
return true;
|
||||
}).get_or_default(false);
|
||||
}
|
||||
|
||||
stdex::promise<str> vfs::load_as_string_async(const url& url) const {
|
||||
return state_->worker.async([this](auto&& url_copy){
|
||||
str content;
|
||||
if ( !streams::try_read_tail(content, read(url_copy)) ) {
|
||||
throw vfs_load_async_exception();
|
||||
}
|
||||
return content;
|
||||
}, url);
|
||||
}
|
||||
|
||||
bool vfs::trace(const url& url, filesystem::trace_func func) const {
|
||||
@@ -250,7 +272,7 @@ namespace e2d
|
||||
MZ_ZIP_FLAG_CASE_SENSITIVE);
|
||||
}
|
||||
|
||||
input_stream_uptr archive_file_source::open(str_view path) const {
|
||||
input_stream_uptr archive_file_source::read(str_view path) const {
|
||||
try {
|
||||
struct owned_state_t {
|
||||
state::archive_ptr archive;
|
||||
@@ -265,19 +287,6 @@ namespace e2d
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<buffer,bool> archive_file_source::load(str_view path) const {
|
||||
std::size_t mem_size = 0;
|
||||
void* mem = mz_zip_reader_extract_file_to_heap(
|
||||
state_->archive.get(),
|
||||
make_utf8(path).c_str(),
|
||||
&mem_size,
|
||||
MZ_ZIP_FLAG_CASE_SENSITIVE);
|
||||
std::unique_ptr<void, decltype(&mz_free)> mem_uptr(mem, mz_free);
|
||||
return mem
|
||||
? std::make_pair(buffer(mem, mem_size), true)
|
||||
: std::make_pair(buffer(), false);
|
||||
}
|
||||
|
||||
output_stream_uptr archive_file_source::write(str_view path, bool append) const {
|
||||
E2D_UNUSED(path, append);
|
||||
return nullptr;
|
||||
@@ -338,17 +347,10 @@ namespace e2d
|
||||
return filesystem::file_exists(path);
|
||||
}
|
||||
|
||||
input_stream_uptr filesystem_file_source::open(str_view path) const {
|
||||
input_stream_uptr filesystem_file_source::read(str_view path) const {
|
||||
return make_read_file(path);
|
||||
}
|
||||
|
||||
std::pair<buffer,bool> filesystem_file_source::load(str_view path) const {
|
||||
buffer buf;
|
||||
return filesystem::try_read_all(buf, path)
|
||||
? std::make_pair(std::move(buf), true)
|
||||
: std::make_pair(buffer(), false);
|
||||
}
|
||||
|
||||
output_stream_uptr filesystem_file_source::write(str_view path, bool append) const {
|
||||
if ( !filesystem::create_directory_recursive(path::parent_path(path)) ) {
|
||||
return nullptr;
|
||||
|
||||
@@ -1390,7 +1390,7 @@ namespace e2d
|
||||
|
||||
const auto asset_url = library.root() / address;
|
||||
input_stream_uptr stream = modules::is_initialized<vfs>()
|
||||
? the<vfs>().open(asset_url)
|
||||
? the<vfs>().read(asset_url)
|
||||
: input_stream_uptr();
|
||||
|
||||
if ( !stream ) {
|
||||
@@ -1462,7 +1462,7 @@ namespace e2d
|
||||
|
||||
const auto asset_url = library.root() / address;
|
||||
input_stream_uptr stream = modules::is_initialized<vfs>()
|
||||
? the<vfs>().open(asset_url)
|
||||
? the<vfs>().read(asset_url)
|
||||
: input_stream_uptr();
|
||||
|
||||
if ( !stream ) {
|
||||
|
||||
@@ -25,21 +25,27 @@ TEST_CASE("vfs"){
|
||||
}
|
||||
{
|
||||
buffer b;
|
||||
auto r = v.open({"file", file_path});
|
||||
auto r = v.read({"file", file_path});
|
||||
REQUIRE(r);
|
||||
REQUIRE(streams::try_read_tail(b, r));
|
||||
REQUIRE(b == buffer{"hello", 5});
|
||||
REQUIRE(v.open({"file2", file_path}) == input_stream_uptr());
|
||||
REQUIRE(v.open({"file", nofile_path}) == input_stream_uptr());
|
||||
REQUIRE(v.read({"file2", file_path}) == input_stream_uptr());
|
||||
REQUIRE(v.read({"file", nofile_path}) == input_stream_uptr());
|
||||
}
|
||||
{
|
||||
auto r = v.load({"file", file_path});
|
||||
REQUIRE(r.second);
|
||||
REQUIRE(r.first == buffer{"hello", 5});
|
||||
buffer b0;
|
||||
REQUIRE(v.load({"file", file_path}, b0));
|
||||
REQUIRE(b0 == buffer{"hello", 5});
|
||||
|
||||
auto r2 = v.load_async({"file", file_path}).get();
|
||||
REQUIRE(r2.second);
|
||||
REQUIRE(r2.first == buffer{"hello", 5});
|
||||
auto b1 = v.load_async({"file", file_path}).get();
|
||||
REQUIRE(b1 == buffer{"hello", 5});
|
||||
|
||||
str b2;
|
||||
REQUIRE(v.load_as_string({"file", file_path}, b2));
|
||||
REQUIRE(b2 == "hello");
|
||||
|
||||
auto b3 = v.load_as_string_async({"file", file_path}).get();
|
||||
REQUIRE(b3 == "hello");
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -58,17 +64,17 @@ TEST_CASE("vfs"){
|
||||
|
||||
REQUIRE_FALSE(v.register_scheme<archive_file_source>(
|
||||
"archive",
|
||||
v.open(url("resources://bin/noresources.zip"))));
|
||||
v.read(url("resources://bin/noresources.zip"))));
|
||||
|
||||
REQUIRE(v.register_scheme<filesystem_file_source>("file"));
|
||||
|
||||
REQUIRE_FALSE(v.register_scheme<archive_file_source>(
|
||||
"archive",
|
||||
v.open(url("resources://bin/noresources.zip"))));
|
||||
v.read(url("resources://bin/noresources.zip"))));
|
||||
|
||||
REQUIRE(v.register_scheme<archive_file_source>(
|
||||
"archive",
|
||||
v.open(url("resources://bin/resources.zip"))));
|
||||
v.read(url("resources://bin/resources.zip"))));
|
||||
|
||||
REQUIRE(v.exists({"archive", "test.txt"}));
|
||||
REQUIRE_FALSE(v.exists({"archive", "TEst.txt"}));
|
||||
@@ -122,50 +128,70 @@ TEST_CASE("vfs"){
|
||||
REQUIRE_FALSE(v.extract(url("archive://test.txt"), std::back_inserter(result)));
|
||||
}
|
||||
{
|
||||
auto f = v.open(url("archive://test.txt"));
|
||||
auto f = v.read(url("archive://test.txt"));
|
||||
REQUIRE(f);
|
||||
buffer b;
|
||||
REQUIRE(streams::try_read_tail(b, f));
|
||||
REQUIRE(b == buffer("hello", 5));
|
||||
}
|
||||
{
|
||||
auto r = v.load(url("archive://test.txt"));
|
||||
REQUIRE(r.second);
|
||||
REQUIRE(r.first == buffer("hello", 5));
|
||||
buffer b0;
|
||||
REQUIRE(v.load(url("archive://test.txt"), b0));
|
||||
REQUIRE(b0 == buffer("hello", 5));
|
||||
|
||||
auto r2 = v.load_async(url("archive://test.txt")).get();
|
||||
REQUIRE(r2.second);
|
||||
REQUIRE(r2.first == buffer("hello", 5));
|
||||
auto b1 = v.load_async(url("archive://test.txt")).get();
|
||||
REQUIRE(b1 == buffer("hello", 5));
|
||||
|
||||
str b2;
|
||||
REQUIRE(v.load_as_string(url("archive://test.txt"), b2));
|
||||
REQUIRE(b2 == "hello");
|
||||
|
||||
auto b3 = v.load_as_string_async(url("archive://test.txt")).get();
|
||||
REQUIRE(b3 == "hello");
|
||||
}
|
||||
{
|
||||
auto f = v.open(url("archive://folder/file.txt"));
|
||||
auto f = v.read(url("archive://folder/file.txt"));
|
||||
REQUIRE(f);
|
||||
buffer b;
|
||||
REQUIRE(streams::try_read_tail(b, f));
|
||||
REQUIRE(b == buffer("world", 5));
|
||||
}
|
||||
{
|
||||
auto r = v.load(url("archive://folder/file.txt"));
|
||||
REQUIRE(r.second);
|
||||
REQUIRE(r.first == buffer("world", 5));
|
||||
buffer b0;
|
||||
REQUIRE(v.load(url("archive://folder/file.txt"), b0));
|
||||
REQUIRE(b0 == buffer("world", 5));
|
||||
|
||||
auto r2 = v.load_async(url("archive://folder/file.txt")).get();
|
||||
REQUIRE(r2.second);
|
||||
REQUIRE(r2.first == buffer("world", 5));
|
||||
auto b1 = v.load_async(url("archive://folder/file.txt")).get();
|
||||
REQUIRE(b1 == buffer("world", 5));
|
||||
|
||||
str b2;
|
||||
REQUIRE(v.load_as_string(url("archive://folder/file.txt"), b2));
|
||||
REQUIRE(b2 == "world");
|
||||
|
||||
auto b3 = v.load_as_string_async(url("archive://folder/file.txt")).get();
|
||||
REQUIRE(b3 == "world");
|
||||
}
|
||||
{
|
||||
REQUIRE(v.open(url("archive://TEst.txt")) == input_stream_uptr());
|
||||
REQUIRE(v.read(url("archive://TEst.txt")) == input_stream_uptr());
|
||||
|
||||
auto r = v.load(url("archive://TEst.txt"));
|
||||
REQUIRE_FALSE(r.second);
|
||||
REQUIRE(r.first.empty());
|
||||
buffer b0;
|
||||
REQUIRE_FALSE(v.load(url("archive://TEst.txt"), b0));
|
||||
REQUIRE(b0.empty());
|
||||
|
||||
auto r2 = v.load_async(url("archive://TEst.txt")).get();
|
||||
REQUIRE_FALSE(r2.second);
|
||||
REQUIRE(r2.first.empty());
|
||||
REQUIRE_THROWS_AS(
|
||||
v.load_async(url("archive://TEst.txt")).get(),
|
||||
vfs_load_async_exception);
|
||||
|
||||
str b2;
|
||||
REQUIRE_FALSE(v.load_as_string(url("archive://TEst.txt"), b2));
|
||||
REQUIRE(b2.empty());
|
||||
|
||||
REQUIRE_THROWS_AS(
|
||||
v.load_as_string_async(url("archive://TEst.txt")).get(),
|
||||
vfs_load_async_exception);
|
||||
}
|
||||
{
|
||||
auto f = v.open(url("archive://test.txt"));
|
||||
auto f = v.read(url("archive://test.txt"));
|
||||
REQUIRE(f);
|
||||
REQUIRE(v.unregister_scheme("archive"));
|
||||
buffer b;
|
||||
|
||||
Reference in New Issue
Block a user