mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-14 16:09:06 +07:00
typed loading nested assets from library
This commit is contained in:
@@ -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_;
|
||||
|
||||
@@ -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_;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user