diff --git a/headers/enduro2d/high/_high.hpp b/headers/enduro2d/high/_high.hpp index 96fcdc11..8c01cf3d 100644 --- a/headers/enduro2d/high/_high.hpp +++ b/headers/enduro2d/high/_high.hpp @@ -92,7 +92,7 @@ namespace e2d class factory; class library; - class asset_cache; + class asset_store; class asset_group; class asset_dependencies; diff --git a/headers/enduro2d/high/asset.hpp b/headers/enduro2d/high/asset.hpp index 2d3d8b7d..cd0c4771 100644 --- a/headers/enduro2d/high/asset.hpp +++ b/headers/enduro2d/high/asset.hpp @@ -70,48 +70,52 @@ namespace e2d nested_content nested_content_; }; - // - // asset_cache_base - // - - class asset_cache_base : private noncopyable { - public: - asset_cache_base() = default; - virtual ~asset_cache_base() noexcept = default; - - virtual std::size_t asset_count() const noexcept = 0; - virtual std::size_t unload_unused_assets() noexcept = 0; - }; - - // - // typed_asset_cache - // - - template < typename Asset > - class typed_asset_cache : public asset_cache_base { - public: - using asset_ptr = typename Asset::ptr; - public: - typed_asset_cache() = default; - ~typed_asset_cache() noexcept final = default; - - asset_ptr find(str_hash address) const noexcept; - void store(str_hash address, const asset_ptr& asset); - - std::size_t asset_count() const noexcept override; - std::size_t unload_unused_assets() noexcept override; - private: - hash_map assets_; - }; - // // asset_cache // - class asset_cache final { + namespace impl + { + class asset_cache; + using asset_cache_iptr = intrusive_ptr; + + class asset_cache + : private noncopyable + , public ref_counter { + public: + asset_cache() = default; + virtual ~asset_cache() noexcept = default; + + virtual std::size_t asset_count() const noexcept = 0; + virtual std::size_t unload_unused_assets() noexcept = 0; + }; + + template < typename Asset > + class typed_asset_cache : public asset_cache { + public: + using asset_ptr = typename Asset::ptr; + public: + typed_asset_cache() = default; + ~typed_asset_cache() noexcept final = default; + + asset_ptr find(str_hash address) const noexcept; + void store(str_hash address, const asset_ptr& asset); + + std::size_t asset_count() const noexcept override; + std::size_t unload_unused_assets() noexcept override; + private: + hash_map assets_; + }; + } + + // + // asset_store + // + + class asset_store final { public: - asset_cache() = default; - ~asset_cache() noexcept = default; + asset_store() = default; + ~asset_store() noexcept = default; template < typename Asset > void store(str_hash address, const typename Asset::ptr& asset); @@ -125,8 +129,7 @@ namespace e2d std::size_t unload_unused_assets() noexcept; private: - using asset_cache_uptr = std::unique_ptr; - hash_map caches_; + hash_map caches_; }; } diff --git a/headers/enduro2d/high/asset.inl b/headers/enduro2d/high/asset.inl index 1f54fd9f..0d1e387c 100644 --- a/headers/enduro2d/high/asset.inl +++ b/headers/enduro2d/high/asset.inl @@ -74,62 +74,65 @@ namespace e2d // typed_asset_cache // - template < typename T > - typename typed_asset_cache::asset_ptr typed_asset_cache::find(str_hash address) const noexcept { - const auto iter = assets_.find(address); - return iter != assets_.end() - ? iter->second - : nullptr; - } - - template < typename T > - void typed_asset_cache::store(str_hash address, const asset_ptr& asset) { - assets_[address] = asset; - } - - template < typename T > - std::size_t typed_asset_cache::asset_count() const noexcept { - return assets_.size(); - } - - template < typename T > - std::size_t typed_asset_cache::unload_unused_assets() noexcept { - std::size_t result = 0u; - for ( auto iter = assets_.begin(); iter != assets_.end(); ) { - if ( !iter->second || 1 == iter->second->use_count() ) { - iter = assets_.erase(iter); - ++result; - } else { - ++iter; - } + namespace impl + { + template < typename T > + typename typed_asset_cache::asset_ptr typed_asset_cache::find(str_hash address) const noexcept { + const auto iter = assets_.find(address); + return iter != assets_.end() + ? iter->second + : nullptr; + } + + template < typename T > + void typed_asset_cache::store(str_hash address, const asset_ptr& asset) { + assets_[address] = asset; + } + + template < typename T > + std::size_t typed_asset_cache::asset_count() const noexcept { + return assets_.size(); + } + + template < typename T > + std::size_t typed_asset_cache::unload_unused_assets() noexcept { + std::size_t result = 0u; + for ( auto iter = assets_.begin(); iter != assets_.end(); ) { + if ( !iter->second || 1 == iter->second->use_count() ) { + iter = assets_.erase(iter); + ++result; + } else { + ++iter; + } + } + return result; } - return result; } // - // asset_cache + // asset_store // template < typename Asset > - void asset_cache::store(str_hash address, const typename Asset::ptr& asset) { + void asset_store::store(str_hash address, const typename Asset::ptr& asset) { const auto family = utils::type_family::id(); const auto iter = caches_.find(family); - typed_asset_cache* cache = iter != caches_.end() && iter->second - ? static_cast*>(iter->second.get()) + impl::typed_asset_cache* cache = iter != caches_.end() && iter->second + ? static_cast*>(iter->second.get()) : nullptr; if ( !cache ) { - cache = static_cast*>(caches_.emplace( + cache = static_cast*>(caches_.emplace( family, - std::make_unique>()).first->second.get()); + make_intrusive>()).first->second.get()); } cache->store(address, asset); } template < typename Asset > - typename Asset::ptr asset_cache::find(str_hash address) const noexcept { + typename Asset::ptr asset_store::find(str_hash address) const noexcept { const auto iter = caches_.find(utils::type_family::id()); - const typed_asset_cache* cache = iter != caches_.end() && iter->second - ? static_cast*>(iter->second.get()) + const impl::typed_asset_cache* cache = iter != caches_.end() && iter->second + ? static_cast*>(iter->second.get()) : nullptr; return cache ? cache->find(address) @@ -137,14 +140,14 @@ namespace e2d } template < typename Asset > - std::size_t asset_cache::asset_count() const noexcept { + std::size_t asset_store::asset_count() const noexcept { const auto iter = caches_.find(utils::type_family::id()); return iter != caches_.end() && iter->second ? iter->second->asset_count() : 0u; } - inline std::size_t asset_cache::asset_count() const noexcept { + inline std::size_t asset_store::asset_count() const noexcept { return std::accumulate( caches_.begin(), caches_.end(), std::size_t(0), [](std::size_t acc, const auto& p){ @@ -154,7 +157,7 @@ namespace e2d }); } - inline std::size_t asset_cache::unload_unused_assets() noexcept { + inline std::size_t asset_store::unload_unused_assets() noexcept { return std::accumulate( caches_.begin(), caches_.end(), std::size_t(0), [](std::size_t acc, const auto& p){ diff --git a/headers/enduro2d/high/library.hpp b/headers/enduro2d/high/library.hpp index 73f5c4a3..e09e7569 100644 --- a/headers/enduro2d/high/library.hpp +++ b/headers/enduro2d/high/library.hpp @@ -27,39 +27,42 @@ namespace e2d // loading_asset // - class loading_asset; - using loading_asset_iptr = intrusive_ptr; + namespace impl + { + class loading_asset; + using loading_asset_iptr = intrusive_ptr; - class loading_asset - : private noncopyable - , public ref_counter { - public: - loading_asset() = default; - virtual ~loading_asset() noexcept = default; + class loading_asset + : private noncopyable + , public ref_counter { + public: + loading_asset() = default; + virtual ~loading_asset() noexcept = default; - virtual void cancel() noexcept = 0; - virtual str_hash address() const noexcept = 0; - virtual void wait(deferrer& deferrer) const noexcept = 0; - }; + virtual void cancel() noexcept = 0; + virtual str_hash address() const noexcept = 0; + virtual void wait(deferrer& deferrer) const noexcept = 0; + }; - template < typename Asset > - class typed_loading_asset : public loading_asset { - public: - using ptr = intrusive_ptr; - using promise_type = typename Asset::load_async_result; - public: - typed_loading_asset(str_hash address, promise_type promise); - ~typed_loading_asset() noexcept override = default; + template < typename Asset > + class typed_loading_asset : public loading_asset { + public: + using ptr = intrusive_ptr; + using promise_type = typename Asset::load_async_result; + public: + typed_loading_asset(str_hash address, promise_type promise); + ~typed_loading_asset() noexcept override = default; - void cancel() noexcept override; - str_hash address() const noexcept override; - void wait(deferrer& deferrer) const noexcept override; + void cancel() noexcept override; + str_hash address() const noexcept override; + void wait(deferrer& deferrer) const noexcept override; - const promise_type& promise() const noexcept; - private: - str_hash address_; - promise_type promise_; - }; + const promise_type& promise() const noexcept; + private: + str_hash address_; + promise_type promise_; + }; + } // // library @@ -71,7 +74,7 @@ namespace e2d ~library() noexcept final; const url& root() const noexcept; - const asset_cache& cache() const noexcept; + const asset_store& store() const noexcept; std::size_t unload_unused_assets() noexcept; std::size_t loading_asset_count() const noexcept; @@ -89,11 +92,11 @@ namespace e2d typename Nested::load_async_result load_asset_async(str_view address) const; private: template < typename Asset > - vector::iterator + vector::iterator find_loading_asset_iter_(str_hash address) const noexcept; template < typename Asset > - typename typed_loading_asset::ptr + typename impl::typed_loading_asset::ptr find_loading_asset_(str_hash address) const noexcept; template < typename Asset > @@ -104,9 +107,9 @@ namespace e2d starter::library_parameters params_; std::atomic cancelled_{false}; private: - mutable asset_cache cache_; + mutable asset_store store_; mutable std::recursive_mutex mutex_; - mutable vector loading_assets_; + mutable vector loading_assets_; }; // @@ -136,34 +139,37 @@ namespace e2d // asset_dependency // - class asset_dependency; - using asset_dependency_iptr = intrusive_ptr; + namespace impl + { + class asset_dependency; + using asset_dependency_iptr = intrusive_ptr; - class asset_dependency - : private noncopyable - , public ref_counter { - public: - asset_dependency() = default; - virtual ~asset_dependency() noexcept = default; + class asset_dependency + : private noncopyable + , public ref_counter { + public: + asset_dependency() = default; + virtual ~asset_dependency() noexcept = default; - virtual const str& main_address() const noexcept = 0; - virtual stdex::promise load_async(const library& library) = 0; - }; + virtual const str& main_address() const noexcept = 0; + virtual stdex::promise load_async(const library& library) = 0; + }; - template < typename Asset > - class typed_asset_dependency : public asset_dependency { - public: - using asset_type = Asset; - using load_result = typename Asset::load_result; - public: - typed_asset_dependency(str_view address); - ~typed_asset_dependency() noexcept override; + template < typename Asset > + class typed_asset_dependency : public asset_dependency { + public: + using asset_type = Asset; + using load_result = typename Asset::load_result; + public: + typed_asset_dependency(str_view address); + ~typed_asset_dependency() noexcept override; - const str& main_address() const noexcept override; - stdex::promise load_async(const library& library) override; - private: - str main_address_; - }; + const str& main_address() const noexcept override; + stdex::promise load_async(const library& library) override; + private: + str main_address_; + }; + } // // asset_dependencies @@ -178,7 +184,7 @@ namespace e2d asset_dependencies& add_dependency(str_view address); stdex::promise load_async(const library& library) const; private: - flat_multimap dependencies_; + flat_multimap dependencies_; }; } diff --git a/headers/enduro2d/high/library.inl b/headers/enduro2d/high/library.inl index e59e84c7..4d2afc17 100644 --- a/headers/enduro2d/high/library.inl +++ b/headers/enduro2d/high/library.inl @@ -11,33 +11,36 @@ namespace e2d { // - // loading_asset + // typed_loading_asset // - template < typename Asset > - typed_loading_asset::typed_loading_asset(str_hash address, promise_type promise) - : address_(address) - , promise_(std::move(promise)) {} + namespace impl + { + template < typename Asset > + typed_loading_asset::typed_loading_asset(str_hash address, promise_type promise) + : address_(address) + , promise_(std::move(promise)) {} - template < typename Asset > - void typed_loading_asset::cancel() noexcept { - promise_.reject(library_cancelled_exception()); - } + template < typename Asset > + void typed_loading_asset::cancel() noexcept { + promise_.reject(library_cancelled_exception()); + } - template < typename Asset > - str_hash typed_loading_asset::address() const noexcept { - return address_; - } + template < typename Asset > + str_hash typed_loading_asset::address() const noexcept { + return address_; + } - template < typename Asset > - const typename typed_loading_asset::promise_type& - typed_loading_asset::promise() const noexcept { - return promise_; - } + template < typename Asset > + const typename typed_loading_asset::promise_type& + typed_loading_asset::promise() const noexcept { + return promise_; + } - template < typename Asset > - void typed_loading_asset::wait(deferrer& deferrer) const noexcept { - deferrer.active_safe_wait_promise(promise_); + template < typename Asset > + void typed_loading_asset::wait(deferrer& deferrer) const noexcept { + deferrer.active_safe_wait_promise(promise_); + } } // @@ -56,12 +59,12 @@ namespace e2d return params_.root(); } - inline const asset_cache& library::cache() const noexcept { - return cache_; + inline const asset_store& library::store() const noexcept { + return store_; } inline std::size_t library::unload_unused_assets() noexcept { - return cache_.unload_unused_assets(); + return store_.unload_unused_assets(); } inline std::size_t library::loading_asset_count() const noexcept { @@ -87,8 +90,8 @@ namespace e2d return stdex::make_rejected_promise(library_cancelled_exception()); } - if ( auto cached_asset = cache_.find(main_address_hash) ) { - return stdex::make_resolved_promise(std::move(cached_asset)); + if ( auto stored_asset = store_.find(main_address_hash) ) { + return stdex::make_resolved_promise(std::move(stored_asset)); } if ( auto asset = find_loading_asset_(main_address_hash) ) { @@ -101,7 +104,7 @@ namespace e2d main_address_hash ](const typename Asset::load_result& new_asset){ std::lock_guard guard(mutex_); - cache_.store(main_address_hash, new_asset); + store_.store(main_address_hash, new_asset); remove_loading_asset_(main_address_hash); return new_asset; }).except([ @@ -136,7 +139,7 @@ namespace e2d const auto zero_us = time::to_chrono(make_microseconds(0)); if ( p.wait_for(zero_us) == stdex::promise_wait_status::timeout ) { - loading_assets_.push_back(new typed_loading_asset(main_address_hash, p)); + loading_assets_.push_back(new impl::typed_loading_asset(main_address_hash, p)); } return p; @@ -174,22 +177,22 @@ namespace e2d } template < typename Asset > - vector::iterator + vector::iterator library::find_loading_asset_iter_(str_hash address) const noexcept { return std::find_if( loading_assets_.begin(), loading_assets_.end(), - [address](const loading_asset_iptr& asset) noexcept { + [address](const impl::loading_asset_iptr& asset) noexcept { return asset->address() == address - && dynamic_pointer_cast>(asset); + && dynamic_pointer_cast>(asset); }); } template < typename Asset > - typename typed_loading_asset::ptr + typename impl::typed_loading_asset::ptr library::find_loading_asset_(str_hash address) const noexcept { auto iter = find_loading_asset_iter_(address); return iter != loading_assets_.end() - ? static_pointer_cast>(*iter) + ? static_pointer_cast>(*iter) : nullptr; } @@ -261,24 +264,27 @@ namespace e2d // asset_dependency // - template < typename Asset > - typed_asset_dependency::typed_asset_dependency(str_view address) - : main_address_(address::parent(address)) {} + namespace impl + { + template < typename Asset > + typed_asset_dependency::typed_asset_dependency(str_view address) + : main_address_(address::parent(address)) {} - template < typename Asset > - typed_asset_dependency::~typed_asset_dependency() noexcept = default; + template < typename Asset > + typed_asset_dependency::~typed_asset_dependency() noexcept = default; - template < typename Asset > - const str& typed_asset_dependency::main_address() const noexcept { - return main_address_; - } + template < typename Asset > + const str& typed_asset_dependency::main_address() const noexcept { + return main_address_; + } - template < typename Asset > - stdex::promise typed_asset_dependency::load_async(const library& library) { - return library.load_main_asset_async(main_address_) - .then([](const typename Asset::load_result& main_asset){ - return asset_ptr(main_asset); - }); + template < typename Asset > + stdex::promise typed_asset_dependency::load_async(const library& library) { + return library.load_main_asset_async(main_address_) + .then([](const typename Asset::load_result& main_asset){ + return asset_ptr(main_asset); + }); + } } // @@ -287,7 +293,8 @@ namespace e2d template < typename Asset, typename Nested > asset_dependencies& asset_dependencies::add_dependency(str_view address) { - asset_dependency_iptr dep(new typed_asset_dependency(address)); + impl::asset_dependency_iptr dep = + make_intrusive>(address); dependencies_.emplace(dep->main_address(), std::move(dep)); return *this; }