mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-15 00:11:55 +07:00
flat containers for library
This commit is contained in:
@@ -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<std::pair<Key, Value>> >
|
||||
using flat_map = flat_hpp::flat_map<Key, Value, Compare, Container>;
|
||||
|
||||
template < typename Key
|
||||
, typename Compare = std::less<>
|
||||
, typename Container = vector<Key> >
|
||||
using flat_multiset = flat_hpp::flat_multiset<Key, Compare, Container>;
|
||||
|
||||
template < typename Key
|
||||
, typename Value
|
||||
, typename Compare = std::less<>
|
||||
, typename Container = vector<std::pair<Key, Value>> >
|
||||
using flat_multimap = flat_hpp::flat_multimap<Key, Value, Compare, Container>;
|
||||
}
|
||||
|
||||
namespace e2d::stdex
|
||||
|
||||
@@ -131,39 +131,35 @@ namespace e2d
|
||||
template < typename Asset, typename Nested = Asset >
|
||||
typename Nested::load_result find_asset(str_view address) const;
|
||||
private:
|
||||
vector<std::pair<str, asset_ptr>> assets_;
|
||||
};
|
||||
|
||||
//
|
||||
// asset_dependency_base
|
||||
//
|
||||
|
||||
class asset_dependency_base;
|
||||
using asset_dependency_base_iptr = intrusive_ptr<asset_dependency_base>;
|
||||
|
||||
class asset_dependency_base
|
||||
: private noncopyable
|
||||
, public ref_counter<asset_dependency_base> {
|
||||
public:
|
||||
asset_dependency_base() = default;
|
||||
virtual ~asset_dependency_base() noexcept = default;
|
||||
|
||||
virtual const str& main_address() const noexcept = 0;
|
||||
virtual stdex::promise<asset_ptr> load_async(const library& library) = 0;
|
||||
flat_multimap<str, asset_ptr> assets_;
|
||||
};
|
||||
|
||||
//
|
||||
// asset_dependency
|
||||
//
|
||||
|
||||
class asset_dependency;
|
||||
using asset_dependency_iptr = intrusive_ptr<asset_dependency>;
|
||||
|
||||
class asset_dependency
|
||||
: private noncopyable
|
||||
, public ref_counter<asset_dependency> {
|
||||
public:
|
||||
asset_dependency() = default;
|
||||
virtual ~asset_dependency() noexcept = default;
|
||||
|
||||
virtual const str& main_address() const noexcept = 0;
|
||||
virtual stdex::promise<asset_ptr> 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<asset_ptr> load_async(const library& library) override;
|
||||
@@ -184,7 +180,7 @@ namespace e2d
|
||||
asset_dependencies& add_dependency(str_view address);
|
||||
stdex::promise<asset_group> load_async(const library& library) const;
|
||||
private:
|
||||
vector<asset_dependency_base_iptr> dependencies_;
|
||||
flat_multimap<str, asset_dependency_iptr> dependencies_;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Asset>(main_asset);
|
||||
if ( !typed_main_asset ) {
|
||||
@@ -275,20 +266,20 @@ namespace e2d
|
||||
//
|
||||
|
||||
template < typename Asset >
|
||||
asset_dependency<Asset>::asset_dependency(str_view address)
|
||||
typed_asset_dependency<Asset>::typed_asset_dependency(str_view address)
|
||||
: main_address_(address::parent(address)) {}
|
||||
|
||||
template < typename Asset >
|
||||
asset_dependency<Asset>::~asset_dependency() noexcept = default;
|
||||
typed_asset_dependency<Asset>::~typed_asset_dependency() noexcept = default;
|
||||
|
||||
template < typename Asset >
|
||||
const str& asset_dependency<Asset>::main_address() const noexcept {
|
||||
const str& typed_asset_dependency<Asset>::main_address() const noexcept {
|
||||
return main_address_;
|
||||
}
|
||||
|
||||
template < typename Asset >
|
||||
stdex::promise<asset_ptr> asset_dependency<Asset>::load_async(const library& library) {
|
||||
return library.load_main_asset_async<Asset>(main_address())
|
||||
stdex::promise<asset_ptr> typed_asset_dependency<Asset>::load_async(const library& library) {
|
||||
return library.load_main_asset_async<Asset>(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<Asset>(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<Asset>(address));
|
||||
dependencies_.emplace(dep->main_address(), std::move(dep));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline stdex::promise<asset_group> asset_dependencies::load_async(const library& library) const {
|
||||
vector<stdex::promise<std::pair<str, asset_ptr>>> 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<std::pair<str, asset_ptr>>& results){
|
||||
return asset_group()
|
||||
.add_assets(results.begin(), results.end());
|
||||
return asset_group().add_assets(results);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user