hide some library classes to impl namespace

This commit is contained in:
BlackMATov
2020-03-25 02:59:40 +07:00
parent 2751cebc2a
commit 4f65de21c3
5 changed files with 207 additions and 188 deletions

View File

@@ -92,7 +92,7 @@ namespace e2d
class factory;
class library;
class asset_cache;
class asset_store;
class asset_group;
class asset_dependencies;

View File

@@ -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<str_hash, asset_ptr> assets_;
};
//
// asset_cache
//
class asset_cache final {
namespace impl
{
class asset_cache;
using asset_cache_iptr = intrusive_ptr<asset_cache>;
class asset_cache
: private noncopyable
, public ref_counter<asset_cache> {
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<str_hash, asset_ptr> 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<asset_cache_base>;
hash_map<utils::type_family_id, asset_cache_uptr> caches_;
hash_map<utils::type_family_id, impl::asset_cache_iptr> caches_;
};
}

View File

@@ -74,62 +74,65 @@ namespace e2d
// typed_asset_cache
//
template < typename T >
typename typed_asset_cache<T>::asset_ptr typed_asset_cache<T>::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<T>::store(str_hash address, const asset_ptr& asset) {
assets_[address] = asset;
}
template < typename T >
std::size_t typed_asset_cache<T>::asset_count() const noexcept {
return assets_.size();
}
template < typename T >
std::size_t typed_asset_cache<T>::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<T>::asset_ptr typed_asset_cache<T>::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<T>::store(str_hash address, const asset_ptr& asset) {
assets_[address] = asset;
}
template < typename T >
std::size_t typed_asset_cache<T>::asset_count() const noexcept {
return assets_.size();
}
template < typename T >
std::size_t typed_asset_cache<T>::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<Asset>::id();
const auto iter = caches_.find(family);
typed_asset_cache<Asset>* cache = iter != caches_.end() && iter->second
? static_cast<typed_asset_cache<Asset>*>(iter->second.get())
impl::typed_asset_cache<Asset>* cache = iter != caches_.end() && iter->second
? static_cast<impl::typed_asset_cache<Asset>*>(iter->second.get())
: nullptr;
if ( !cache ) {
cache = static_cast<typed_asset_cache<Asset>*>(caches_.emplace(
cache = static_cast<impl::typed_asset_cache<Asset>*>(caches_.emplace(
family,
std::make_unique<typed_asset_cache<Asset>>()).first->second.get());
make_intrusive<impl::typed_asset_cache<Asset>>()).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<Asset>::id());
const typed_asset_cache<Asset>* cache = iter != caches_.end() && iter->second
? static_cast<const typed_asset_cache<Asset>*>(iter->second.get())
const impl::typed_asset_cache<Asset>* cache = iter != caches_.end() && iter->second
? static_cast<const impl::typed_asset_cache<Asset>*>(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<Asset>::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){

View File

@@ -27,39 +27,42 @@ namespace e2d
// loading_asset
//
class loading_asset;
using loading_asset_iptr = intrusive_ptr<loading_asset>;
namespace impl
{
class loading_asset;
using loading_asset_iptr = intrusive_ptr<loading_asset>;
class loading_asset
: private noncopyable
, public ref_counter<loading_asset> {
public:
loading_asset() = default;
virtual ~loading_asset() noexcept = default;
class loading_asset
: private noncopyable
, public ref_counter<loading_asset> {
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<typed_loading_asset>;
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<typed_loading_asset>;
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<loading_asset_iptr>::iterator
vector<impl::loading_asset_iptr>::iterator
find_loading_asset_iter_(str_hash address) const noexcept;
template < typename Asset >
typename typed_loading_asset<Asset>::ptr
typename impl::typed_loading_asset<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<bool> cancelled_{false};
private:
mutable asset_cache cache_;
mutable asset_store store_;
mutable std::recursive_mutex mutex_;
mutable vector<loading_asset_iptr> loading_assets_;
mutable vector<impl::loading_asset_iptr> loading_assets_;
};
//
@@ -136,34 +139,37 @@ namespace e2d
// asset_dependency
//
class asset_dependency;
using asset_dependency_iptr = intrusive_ptr<asset_dependency>;
namespace impl
{
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;
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;
};
virtual const str& main_address() const noexcept = 0;
virtual stdex::promise<asset_ptr> 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<asset_ptr> load_async(const library& library) override;
private:
str main_address_;
};
const str& main_address() const noexcept override;
stdex::promise<asset_ptr> 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<asset_group> load_async(const library& library) const;
private:
flat_multimap<str, asset_dependency_iptr> dependencies_;
flat_multimap<str, impl::asset_dependency_iptr> dependencies_;
};
}

View File

@@ -11,33 +11,36 @@
namespace e2d
{
//
// loading_asset
// typed_loading_asset
//
template < typename Asset >
typed_loading_asset<Asset>::typed_loading_asset(str_hash address, promise_type promise)
: address_(address)
, promise_(std::move(promise)) {}
namespace impl
{
template < typename Asset >
typed_loading_asset<Asset>::typed_loading_asset(str_hash address, promise_type promise)
: address_(address)
, promise_(std::move(promise)) {}
template < typename Asset >
void typed_loading_asset<Asset>::cancel() noexcept {
promise_.reject(library_cancelled_exception());
}
template < typename Asset >
void typed_loading_asset<Asset>::cancel() noexcept {
promise_.reject(library_cancelled_exception());
}
template < typename Asset >
str_hash typed_loading_asset<Asset>::address() const noexcept {
return address_;
}
template < typename Asset >
str_hash typed_loading_asset<Asset>::address() const noexcept {
return address_;
}
template < typename Asset >
const typename typed_loading_asset<Asset>::promise_type&
typed_loading_asset<Asset>::promise() const noexcept {
return promise_;
}
template < typename Asset >
const typename typed_loading_asset<Asset>::promise_type&
typed_loading_asset<Asset>::promise() const noexcept {
return promise_;
}
template < typename Asset >
void typed_loading_asset<Asset>::wait(deferrer& deferrer) const noexcept {
deferrer.active_safe_wait_promise(promise_);
template < typename Asset >
void typed_loading_asset<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<typename Asset::load_result>(library_cancelled_exception());
}
if ( auto cached_asset = cache_.find<Asset>(main_address_hash) ) {
return stdex::make_resolved_promise(std::move(cached_asset));
if ( auto stored_asset = store_.find<Asset>(main_address_hash) ) {
return stdex::make_resolved_promise(std::move(stored_asset));
}
if ( auto asset = find_loading_asset_<Asset>(main_address_hash) ) {
@@ -101,7 +104,7 @@ namespace e2d
main_address_hash
](const typename Asset::load_result& new_asset){
std::lock_guard<std::recursive_mutex> guard(mutex_);
cache_.store<Asset>(main_address_hash, new_asset);
store_.store<Asset>(main_address_hash, new_asset);
remove_loading_asset_<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<Asset>(main_address_hash, p));
loading_assets_.push_back(new impl::typed_loading_asset<Asset>(main_address_hash, p));
}
return p;
@@ -174,22 +177,22 @@ namespace e2d
}
template < typename Asset >
vector<loading_asset_iptr>::iterator
vector<impl::loading_asset_iptr>::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<typed_loading_asset<Asset>>(asset);
&& dynamic_pointer_cast<impl::typed_loading_asset<Asset>>(asset);
});
}
template < typename Asset >
typename typed_loading_asset<Asset>::ptr
typename impl::typed_loading_asset<Asset>::ptr
library::find_loading_asset_(str_hash address) const noexcept {
auto iter = find_loading_asset_iter_<Asset>(address);
return iter != loading_assets_.end()
? static_pointer_cast<typed_loading_asset<Asset>>(*iter)
? static_pointer_cast<impl::typed_loading_asset<Asset>>(*iter)
: nullptr;
}
@@ -261,24 +264,27 @@ namespace e2d
// asset_dependency
//
template < typename Asset >
typed_asset_dependency<Asset>::typed_asset_dependency(str_view address)
: main_address_(address::parent(address)) {}
namespace impl
{
template < typename Asset >
typed_asset_dependency<Asset>::typed_asset_dependency(str_view address)
: main_address_(address::parent(address)) {}
template < typename Asset >
typed_asset_dependency<Asset>::~typed_asset_dependency() noexcept = default;
template < typename Asset >
typed_asset_dependency<Asset>::~typed_asset_dependency() noexcept = default;
template < typename Asset >
const str& typed_asset_dependency<Asset>::main_address() const noexcept {
return main_address_;
}
template < typename Asset >
const str& typed_asset_dependency<Asset>::main_address() const noexcept {
return main_address_;
}
template < typename Asset >
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);
});
template < typename Asset >
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);
});
}
}
//
@@ -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<Asset>(address));
impl::asset_dependency_iptr dep =
make_intrusive<impl::typed_asset_dependency<Asset>>(address);
dependencies_.emplace(dep->main_address(), std::move(dep));
return *this;
}