typed loading nested assets from library

This commit is contained in:
2019-04-02 09:38:55 +07:00
parent 1604473252
commit 3bec77c73c
4 changed files with 79 additions and 14 deletions

View File

@@ -37,17 +37,19 @@ namespace e2d
// asset
//
class asset;
using asset_ptr = intrusive_ptr<asset>;
using nested_content = hash_map<str_hash, asset_ptr>;
class asset
: private noncopyable
, public ref_counter<asset> {
public:
asset();
virtual ~asset() noexcept;
virtual asset_ptr find_nested_asset(str_view name) const noexcept = 0;
};
using asset_ptr = intrusive_ptr<asset>;
using nested_content = hash_map<str_hash, asset_ptr>;
//
// content_asset
//
@@ -73,7 +75,7 @@ namespace e2d
template < typename T >
intrusive_ptr<T> find_nested_asset(str_view name) const noexcept;
asset_ptr find_nested_asset(str_view name) const noexcept;
asset_ptr find_nested_asset(str_view name) const noexcept override;
private:
Content content_;
nested_content nested_content_;

View File

@@ -11,6 +11,7 @@
#include "_high.hpp"
#include "asset.hpp"
#include "address.hpp"
namespace e2d
{
@@ -42,6 +43,12 @@ namespace e2d
template < typename Asset >
typename Asset::load_async_result load_asset_async(str_view address) const;
template < typename Asset, typename Nested >
typename Nested::load_result load_asset(str_view address) const;
template < typename Asset, typename Nested >
typename Nested::load_async_result load_asset_async(str_view address) const;
private:
url root_;
};

View File

@@ -27,24 +27,57 @@ namespace e2d
template < typename Asset >
typename Asset::load_async_result library::load_asset_async(str_view address) const {
const auto main_address = address::parent(address);
const auto main_address_hash = make_hash(main_address);
if ( !modules::is_initialized<asset_cache<Asset>>() ) {
return Asset::load_async(*this, address);
return Asset::load_async(*this, main_address);
}
auto& cache = the<asset_cache<Asset>>();
if ( auto cached_asset = cache.find(address) ) {
if ( auto cached_asset = cache.find(main_address_hash) ) {
return stdex::make_resolved_promise(std::move(cached_asset));
}
return Asset::load_async(*this, address)
return Asset::load_async(*this, main_address)
.then([
&cache,
address_hash = make_hash(address)
main_address_hash
](const typename Asset::load_result& new_asset){
cache.store(address_hash, new_asset);
cache.store(main_address_hash, new_asset);
return new_asset;
});
}
template < typename Asset, typename Nested >
typename Nested::load_result library::load_asset(str_view address) const {
auto p = load_asset_async<Asset, Nested>(address);
if ( modules::is_initialized<deferrer>() ) {
the<deferrer>().active_safe_wait_promise(p);
}
return p.get_or_default(nullptr);
}
template < typename Asset, typename Nested >
typename Nested::load_async_result library::load_asset_async(str_view address) const {
return load_asset_async<Asset>(address::parent(address))
.then([
nested_address = address::nested(address)
](const typename Asset::load_result& main_asset) mutable {
asset_ptr nested_asset = main_asset;
while ( nested_asset && !nested_address.empty() ) {
nested_asset = nested_asset->find_nested_asset(address::parent(nested_address));
nested_address = address::nested(nested_address);
}
using nested_asset_type = typename Nested::asset_type;
if ( auto result = dynamic_pointer_cast<nested_asset_type>(nested_asset) ) {
return result;
}
throw asset_loading_exception();
});
}
}
#endif

View File

@@ -23,14 +23,22 @@ namespace
}
};
class fake_nested_asset final : public content_asset<fake_nested_asset, int> {
};
class fake_asset final : public content_asset<fake_asset, int> {
public:
static load_async_result load_async(const library& library, str_view address) {
E2D_UNUSED(library);
return address == "42"
? stdex::make_resolved_promise(fake_asset::create(42, {
{"21", fake_asset::create(21)},
{"84", fake_asset::create(84)}}))
{"21", fake_nested_asset::create(21, {
{"2", fake_nested_asset::create(2)}
})},
{"84", fake_nested_asset::create(84, {
{"8", fake_nested_asset::create(8)}
})}
}))
: stdex::make_rejected_promise<load_result>(asset_loading_exception());
}
};
@@ -49,8 +57,23 @@ TEST_CASE("asset"){
REQUIRE_FALSE(fa->find_nested_asset("none"));
REQUIRE(fa->find_nested_asset("21"));
REQUIRE_FALSE(fa->find_nested_asset<binary_asset>("21"));
REQUIRE(fa->find_nested_asset<fake_asset>("21"));
REQUIRE(fa->find_nested_asset<fake_asset>("21")->content() == 21);
REQUIRE(fa->find_nested_asset<fake_asset>("84")->content() == 84);
REQUIRE(fa->find_nested_asset<fake_nested_asset>("21"));
REQUIRE(fa->find_nested_asset<fake_nested_asset>("21")->content() == 21);
REQUIRE(fa->find_nested_asset<fake_nested_asset>("84")->content() == 84);
}
{
REQUIRE(l.load_asset<fake_asset, fake_nested_asset>("42:/21"));
REQUIRE(l.load_asset<fake_asset, fake_nested_asset>("42:/21")->content() == 21);
REQUIRE_FALSE(l.load_asset<fake_asset, binary_asset>("42:/21"));
REQUIRE_FALSE(l.load_asset<fake_asset, fake_nested_asset>("42:/none"));
REQUIRE_FALSE(l.load_asset<fake_asset, fake_nested_asset>("42:/none:/21"));
REQUIRE(l.load_asset<fake_asset, fake_nested_asset>("42:/21:/2"));
REQUIRE(l.load_asset<fake_asset, fake_nested_asset>("42:/21:/2")->content() == 2);
REQUIRE_FALSE(l.load_asset<fake_asset, binary_asset>("42:/21:/2"));
REQUIRE_FALSE(l.load_asset<fake_asset, fake_nested_asset>("42:/21:/none"));
REQUIRE_FALSE(l.load_asset<fake_asset, fake_nested_asset>("42:/21:/none:/2"));
}
}