diff --git a/headers/enduro2d/base/types.hpp b/headers/enduro2d/base/types.hpp index 8c6411b3..e80e853c 100644 --- a/headers/enduro2d/base/types.hpp +++ b/headers/enduro2d/base/types.hpp @@ -11,6 +11,8 @@ #include <3rdparty/variant/variant.hpp> #include <3rdparty/flat.hpp/flat_set.hpp> #include <3rdparty/flat.hpp/flat_map.hpp> +#include <3rdparty/flat.hpp/flat_multiset.hpp> +#include <3rdparty/flat.hpp/flat_multimap.hpp> namespace e2d { @@ -72,6 +74,17 @@ namespace e2d , typename Compare = std::less<> , typename Container = vector> > using flat_map = flat_hpp::flat_map; + + template < typename Key + , typename Compare = std::less<> + , typename Container = vector > + using flat_multiset = flat_hpp::flat_multiset; + + template < typename Key + , typename Value + , typename Compare = std::less<> + , typename Container = vector> > + using flat_multimap = flat_hpp::flat_multimap; } namespace e2d::stdex diff --git a/headers/enduro2d/high/library.hpp b/headers/enduro2d/high/library.hpp index 939398e2..99cb0655 100644 --- a/headers/enduro2d/high/library.hpp +++ b/headers/enduro2d/high/library.hpp @@ -131,39 +131,35 @@ namespace e2d template < typename Asset, typename Nested = Asset > typename Nested::load_result find_asset(str_view address) const; private: - vector> assets_; - }; - - // - // asset_dependency_base - // - - class asset_dependency_base; - using asset_dependency_base_iptr = intrusive_ptr; - - class asset_dependency_base - : private noncopyable - , public ref_counter { - public: - asset_dependency_base() = default; - virtual ~asset_dependency_base() noexcept = default; - - virtual const str& main_address() const noexcept = 0; - virtual stdex::promise load_async(const library& library) = 0; + flat_multimap assets_; }; // // asset_dependency // + 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; + + virtual const str& main_address() const noexcept = 0; + virtual stdex::promise load_async(const library& library) = 0; + }; + template < typename Asset > - class asset_dependency : public asset_dependency_base { + class typed_asset_dependency : public asset_dependency { public: using asset_type = Asset; using load_result = typename Asset::load_result; public: - asset_dependency(str_view address); - ~asset_dependency() noexcept override; + 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; @@ -184,7 +180,7 @@ namespace e2d asset_dependencies& add_dependency(str_view address); stdex::promise load_async(const library& library) const; private: - vector dependencies_; + flat_multimap dependencies_; }; } diff --git a/headers/enduro2d/high/library.inl b/headers/enduro2d/high/library.inl index b847f988..b8cd13e8 100644 --- a/headers/enduro2d/high/library.inl +++ b/headers/enduro2d/high/library.inl @@ -236,12 +236,7 @@ namespace e2d inline asset_group& asset_group::add_asset(str_view address, const asset_ptr& asset) { str main_address = address::parent(address); - const auto iter = std::upper_bound( - assets_.begin(), assets_.end(), main_address, - [](const str& l, const auto& r){ - return l < r.first; - }); - assets_.insert(iter, std::make_pair(std::move(main_address), asset)); + assets_.emplace(std::move(main_address), asset); return *this; } @@ -249,12 +244,8 @@ namespace e2d typename Nested::load_result asset_group::find_asset(str_view address) const { const str main_address = address::parent(address); const str nested_address = address::nested(address); - auto iter = std::lower_bound( - assets_.begin(), assets_.end(), main_address, - [](const auto& l, const str& r) noexcept { - return l.first < r; - }); - for ( ; iter != assets_.end() && iter->first == main_address; ++iter ) { + const auto [first, last] = assets_.equal_range(main_address); + for ( auto iter = first; iter != last; ++iter ) { asset_ptr main_asset = iter->second; typename Asset::load_result typed_main_asset = dynamic_pointer_cast(main_asset); if ( !typed_main_asset ) { @@ -275,20 +266,20 @@ namespace e2d // template < typename Asset > - asset_dependency::asset_dependency(str_view address) + typed_asset_dependency::typed_asset_dependency(str_view address) : main_address_(address::parent(address)) {} template < typename Asset > - asset_dependency::~asset_dependency() noexcept = default; + typed_asset_dependency::~typed_asset_dependency() noexcept = default; template < typename Asset > - const str& asset_dependency::main_address() const noexcept { + const str& typed_asset_dependency::main_address() const noexcept { return main_address_; } template < typename Asset > - stdex::promise asset_dependency::load_async(const library& library) { - return library.load_main_asset_async(main_address()) + 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); }); @@ -300,31 +291,24 @@ namespace e2d template < typename Asset, typename Nested > asset_dependencies& asset_dependencies::add_dependency(str_view address) { - asset_dependency_base_iptr dep(new asset_dependency(address)); - auto iter = std::upper_bound( - dependencies_.begin(), dependencies_.end(), dep->main_address(), - [](const str& l, const auto& r){ - return l < r->main_address(); - }); - dependencies_.insert(iter, std::move(dep)); + asset_dependency_iptr dep(new typed_asset_dependency(address)); + dependencies_.emplace(dep->main_address(), std::move(dep)); return *this; } inline stdex::promise asset_dependencies::load_async(const library& library) const { vector>> promises; promises.reserve(dependencies_.size()); - std::transform( - dependencies_.begin(), dependencies_.end(), std::back_inserter(promises), - [&library](const asset_dependency_base_iptr& dep){ - return dep->load_async(library) - .then([main_address = dep->main_address()](const asset_ptr& asset){ - return std::make_pair(main_address, asset); - }); - }); + for ( const auto& [_, dep] : dependencies_ ) { + promises.push_back(dep->load_async(library).then([ + dep = dep + ](const asset_ptr& asset){ + return std::make_pair(dep->main_address(), asset); + })); + } return stdex::make_all_promise(std::move(promises)) .then([](const vector>& results){ - return asset_group() - .add_assets(results.begin(), results.end()); + return asset_group().add_assets(results); }); } }