mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-16 14:08:59 +07:00
Merge branch 'master' into feature/flipbook
This commit is contained in:
@@ -30,6 +30,9 @@
|
||||
|
||||
#include "systems/render_system.hpp"
|
||||
|
||||
#include "address.hpp"
|
||||
#include "asset.hpp"
|
||||
#include "asset.inl"
|
||||
#include "atlas.hpp"
|
||||
#include "flipbook.hpp"
|
||||
#include "library.hpp"
|
||||
|
||||
@@ -44,14 +44,14 @@ namespace e2d
|
||||
|
||||
template < typename Asset, typename Content >
|
||||
class content_asset;
|
||||
class content_asset_base;
|
||||
|
||||
class library;
|
||||
class asset;
|
||||
|
||||
template < typename T >
|
||||
class asset_cache;
|
||||
class asset_cache_base;
|
||||
|
||||
class library;
|
||||
|
||||
class atlas;
|
||||
class flipbook;
|
||||
class model;
|
||||
|
||||
15
headers/enduro2d/high/address.hpp
Normal file
15
headers/enduro2d/high/address.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019 Matvey Cherevko
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "_high.hpp"
|
||||
|
||||
namespace e2d { namespace address
|
||||
{
|
||||
str parent(str_view address);
|
||||
str nested(str_view address);
|
||||
}}
|
||||
148
headers/enduro2d/high/asset.hpp
Normal file
148
headers/enduro2d/high/asset.hpp
Normal file
@@ -0,0 +1,148 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019 Matvey Cherevko
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef E2D_INCLUDE_GUARD_1122A7CA62954AEF9E0A787064D28F73
|
||||
#define E2D_INCLUDE_GUARD_1122A7CA62954AEF9E0A787064D28F73
|
||||
#pragma once
|
||||
|
||||
#include "_high.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
//
|
||||
// asset_loading_exception
|
||||
//
|
||||
|
||||
class asset_loading_exception : public exception {
|
||||
const char* what() const noexcept override {
|
||||
return "asset loading exception";
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// bad_asset_factory_operation
|
||||
//
|
||||
|
||||
class bad_asset_factory_operation final : public exception {
|
||||
public:
|
||||
const char* what() const noexcept final {
|
||||
return "bad asset factory operation";
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// 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;
|
||||
};
|
||||
|
||||
//
|
||||
// content_asset
|
||||
//
|
||||
|
||||
template < typename Asset, typename Content >
|
||||
class content_asset : public asset {
|
||||
public:
|
||||
using asset_type = Asset;
|
||||
using content_type = Content;
|
||||
|
||||
using ptr = intrusive_ptr<Asset>;
|
||||
using load_result = intrusive_ptr<Asset>;
|
||||
using load_async_result = stdex::promise<load_result>;
|
||||
public:
|
||||
static load_result create();
|
||||
static load_result create(Content content);
|
||||
static load_result create(Content content, nested_content nested_content);
|
||||
|
||||
void fill(Content content);
|
||||
void fill(Content content, nested_content nested_content);
|
||||
|
||||
const Content& content() const noexcept;
|
||||
|
||||
template < typename T >
|
||||
intrusive_ptr<T> 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_;
|
||||
};
|
||||
|
||||
//
|
||||
// asset_cache_base
|
||||
//
|
||||
|
||||
class asset_cache_base : private noncopyable {
|
||||
public:
|
||||
asset_cache_base();
|
||||
virtual ~asset_cache_base() noexcept;
|
||||
|
||||
static std::size_t unload_all_unused_assets() noexcept;
|
||||
virtual std::size_t unload_self_unused_assets() noexcept = 0;
|
||||
private:
|
||||
static std::mutex mutex_;
|
||||
static hash_set<asset_cache_base*> caches_;
|
||||
};
|
||||
|
||||
//
|
||||
// asset_cache
|
||||
//
|
||||
|
||||
template < typename Asset >
|
||||
class asset_cache : public asset_cache_base
|
||||
, public module<asset_cache<Asset>> {
|
||||
public:
|
||||
using asset_ptr = typename Asset::ptr;
|
||||
public:
|
||||
asset_cache(library& l);
|
||||
~asset_cache() noexcept final;
|
||||
|
||||
asset_ptr find(str_hash address) const noexcept;
|
||||
void store(str_hash address, const asset_ptr& asset);
|
||||
|
||||
void clear() noexcept;
|
||||
std::size_t asset_count() const noexcept;
|
||||
|
||||
std::size_t unload_self_unused_assets() noexcept override;
|
||||
private:
|
||||
library& library_;
|
||||
mutable std::mutex mutex_;
|
||||
hash_map<str_hash, asset_ptr> assets_;
|
||||
};
|
||||
|
||||
//
|
||||
// asset_factory
|
||||
//
|
||||
|
||||
class asset_factory : public module<asset_factory> {
|
||||
public:
|
||||
using asset_creator = std::function<
|
||||
stdex::promise<asset_ptr>(const library& library, str_view address)>;
|
||||
public:
|
||||
asset_factory();
|
||||
~asset_factory() noexcept final;
|
||||
|
||||
template < typename Asset >
|
||||
asset_factory& register_asset(str_hash type);
|
||||
asset_factory& register_creator(str_hash type, asset_creator creator);
|
||||
private:
|
||||
std::mutex mutex_;
|
||||
hash_map<str_hash, asset_creator> creators_;
|
||||
};
|
||||
}
|
||||
|
||||
#include "asset.inl"
|
||||
#endif
|
||||
150
headers/enduro2d/high/asset.inl
Normal file
150
headers/enduro2d/high/asset.inl
Normal file
@@ -0,0 +1,150 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019 Matvey Cherevko
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef E2D_INCLUDE_GUARD_6FD0B1DD12004CF78E7AC5FBBC36E854
|
||||
#define E2D_INCLUDE_GUARD_6FD0B1DD12004CF78E7AC5FBBC36E854
|
||||
#pragma once
|
||||
|
||||
#include "_high.hpp"
|
||||
#include "asset.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
//
|
||||
// content_asset
|
||||
//
|
||||
|
||||
template < typename Asset, typename Content >
|
||||
typename content_asset<Asset, Content>::load_result
|
||||
content_asset<Asset, Content>::create() {
|
||||
return load_result(new Asset());
|
||||
}
|
||||
|
||||
template < typename Asset, typename Content >
|
||||
typename content_asset<Asset, Content>::load_result
|
||||
content_asset<Asset, Content>::create(Content content) {
|
||||
auto result = create();
|
||||
result->fill(std::move(content));
|
||||
return result;
|
||||
}
|
||||
|
||||
template < typename Asset, typename Content >
|
||||
typename content_asset<Asset, Content>::load_result
|
||||
content_asset<Asset, Content>::create(Content content, nested_content nested_content) {
|
||||
auto result = create();
|
||||
result->fill(std::move(content), std::move(nested_content));
|
||||
return result;
|
||||
}
|
||||
|
||||
template < typename Asset, typename Content >
|
||||
void content_asset<Asset, Content>::fill(Content content) {
|
||||
content_ = std::move(content);
|
||||
}
|
||||
|
||||
template < typename Asset, typename Content >
|
||||
void content_asset<Asset, Content>::fill(Content content, nested_content nested_content) {
|
||||
content_ = std::move(content);
|
||||
nested_content_ = std::move(nested_content);
|
||||
}
|
||||
|
||||
template < typename Asset, typename Content >
|
||||
const Content& content_asset<Asset, Content>::content() const noexcept {
|
||||
return content_;
|
||||
}
|
||||
|
||||
template < typename Asset, typename Content >
|
||||
template < typename T >
|
||||
intrusive_ptr<T> content_asset<Asset, Content>::find_nested_asset(str_view name) const noexcept {
|
||||
return dynamic_pointer_cast<T>(find_nested_asset(name));
|
||||
}
|
||||
|
||||
template < typename Asset, typename Content >
|
||||
asset_ptr content_asset<Asset, Content>::find_nested_asset(str_view name) const noexcept {
|
||||
const auto iter = nested_content_.find(name);
|
||||
return iter != nested_content_.end()
|
||||
? iter->second
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
//
|
||||
// asset_cache
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
asset_cache<T>::asset_cache(library& l)
|
||||
: library_(l) {}
|
||||
|
||||
template < typename T >
|
||||
asset_cache<T>::~asset_cache() noexcept = default;
|
||||
|
||||
template < typename T >
|
||||
typename asset_cache<T>::asset_ptr asset_cache<T>::find(str_hash address) const noexcept {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
const auto iter = assets_.find(address);
|
||||
return iter != assets_.end()
|
||||
? iter->second
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
void asset_cache<T>::store(str_hash address, const asset_ptr& asset) {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
assets_[address] = asset;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
void asset_cache<T>::clear() noexcept {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
assets_.clear();
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
std::size_t asset_cache<T>::asset_count() const noexcept {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
return assets_.size();
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
std::size_t asset_cache<T>::unload_self_unused_assets() noexcept {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
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;
|
||||
}
|
||||
|
||||
//
|
||||
// asset_factory
|
||||
//
|
||||
|
||||
template < typename Asset >
|
||||
asset_factory& asset_factory::register_asset(str_hash type) {
|
||||
return register_creator(type, [](const library& library, str_view address) {
|
||||
return Asset::load_async(library, address)
|
||||
.then([](const typename Asset::load_result& result){
|
||||
return static_pointer_cast<asset>(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
inline asset_factory& asset_factory::register_creator(str_hash type, asset_creator creator) {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
bool success = creators_.insert(
|
||||
std::make_pair(type, std::move(creator))).second;
|
||||
if ( !success ) {
|
||||
throw bad_asset_factory_operation();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -8,15 +8,13 @@
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../atlas.hpp"
|
||||
#include "../library.hpp"
|
||||
#include "../atlas.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class atlas_asset final : public content_asset<atlas_asset, atlas> {
|
||||
public:
|
||||
atlas_asset(content_type content)
|
||||
: content_asset<atlas_asset, atlas>(std::move(content)) {}
|
||||
static load_async_result load_async(library& library, str_view address);
|
||||
static load_async_result load_async(const library& library, str_view address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../library.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class binary_asset final : public content_asset<binary_asset, buffer> {
|
||||
public:
|
||||
binary_asset(content_type content)
|
||||
: content_asset<binary_asset, buffer>(std::move(content)) {}
|
||||
static load_async_result load_async(library& library, str_view address);
|
||||
static load_async_result load_async(const library& library, str_view address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,15 +8,13 @@
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../flipbook.hpp"
|
||||
#include "../library.hpp"
|
||||
#include "../flipbook.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class flipbook_asset final : public content_asset<flipbook_asset, flipbook> {
|
||||
public:
|
||||
flipbook_asset(content_type content)
|
||||
: content_asset<flipbook_asset, flipbook>(std::move(content)) {}
|
||||
static load_async_result load_async(library& library, str_view address);
|
||||
static load_async_result load_async(const library& library, str_view address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../library.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class image_asset final : public content_asset<image_asset, image> {
|
||||
public:
|
||||
image_asset(content_type content)
|
||||
: content_asset<image_asset, image>(std::move(content)) {}
|
||||
static load_async_result load_async(library& library, str_view address);
|
||||
static load_async_result load_async(const library& library, str_view address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../library.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class material_asset final : public content_asset<material_asset, render::material> {
|
||||
public:
|
||||
material_asset(content_type content)
|
||||
: content_asset<material_asset, render::material>(std::move(content)) {}
|
||||
static load_async_result load_async(library& library, str_view address);
|
||||
static load_async_result load_async(const library& library, str_view address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../library.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class mesh_asset final : public content_asset<mesh_asset, mesh> {
|
||||
public:
|
||||
mesh_asset(content_type content)
|
||||
: content_asset<mesh_asset, mesh>(std::move(content)) {}
|
||||
static load_async_result load_async(library& library, str_view address);
|
||||
static load_async_result load_async(const library& library, str_view address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,15 +8,13 @@
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../model.hpp"
|
||||
#include "../library.hpp"
|
||||
#include "../model.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class model_asset final : public content_asset<model_asset, model> {
|
||||
public:
|
||||
model_asset(content_type content)
|
||||
: content_asset<model_asset, model>(std::move(content)) {}
|
||||
static load_async_result load_async(library& library, str_view address);
|
||||
static load_async_result load_async(const library& library, str_view address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../library.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class shader_asset final : public content_asset<shader_asset, shader_ptr> {
|
||||
public:
|
||||
shader_asset(content_type content)
|
||||
: content_asset<shader_asset, shader_ptr>(std::move(content)) {}
|
||||
static load_async_result load_async(library& library, str_view address);
|
||||
static load_async_result load_async(const library& library, str_view address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../library.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class shape_asset final : public content_asset<shape_asset, shape> {
|
||||
public:
|
||||
shape_asset(content_type content)
|
||||
: content_asset<shape_asset, shape>(std::move(content)) {}
|
||||
static load_async_result load_async(library& library, str_view address);
|
||||
static load_async_result load_async(const library& library, str_view address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,15 +8,13 @@
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../sprite.hpp"
|
||||
#include "../library.hpp"
|
||||
#include "../sprite.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class sprite_asset final : public content_asset<sprite_asset, sprite> {
|
||||
public:
|
||||
sprite_asset(content_type content)
|
||||
: content_asset<sprite_asset, sprite>(std::move(content)) {}
|
||||
static load_async_result load_async(library& library, str_view address);
|
||||
static load_async_result load_async(const library& library, str_view address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../library.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class text_asset final : public content_asset<text_asset, str> {
|
||||
public:
|
||||
text_asset(content_type content)
|
||||
: content_asset<text_asset, str>(std::move(content)) {}
|
||||
static load_async_result load_async(library& library, str_view address);
|
||||
static load_async_result load_async(const library& library, str_view address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../_high.hpp"
|
||||
|
||||
#include "../library.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class texture_asset final : public content_asset<texture_asset, texture_ptr> {
|
||||
public:
|
||||
texture_asset(content_type content)
|
||||
: content_asset<texture_asset, texture_ptr>(std::move(content)) {}
|
||||
static load_async_result load_async(library& library, str_view address);
|
||||
static load_async_result load_async(const library& library, str_view address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
|
||||
#include "_high.hpp"
|
||||
|
||||
#include "asset.hpp"
|
||||
#include "address.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
//
|
||||
@@ -23,54 +26,6 @@ namespace e2d
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// asset_loading_exception
|
||||
//
|
||||
|
||||
class asset_loading_exception : public exception {
|
||||
const char* what() const noexcept override = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// content_asset_base
|
||||
//
|
||||
|
||||
class content_asset_base
|
||||
: private noncopyable
|
||||
, public ref_counter<content_asset_base> {
|
||||
public:
|
||||
content_asset_base() = default;
|
||||
virtual ~content_asset_base() noexcept = default;
|
||||
};
|
||||
|
||||
//
|
||||
// content_asset
|
||||
//
|
||||
|
||||
template < typename Asset, typename Content >
|
||||
class content_asset : public content_asset_base {
|
||||
public:
|
||||
using asset_type = Asset;
|
||||
using content_type = Content;
|
||||
|
||||
using ptr = intrusive_ptr<Asset>;
|
||||
using load_result = intrusive_ptr<Asset>;
|
||||
using load_async_result = stdex::promise<load_result>;
|
||||
public:
|
||||
static load_result create(Content content) {
|
||||
return load_result(new Asset(std::move(content)));
|
||||
}
|
||||
|
||||
content_asset(Content content)
|
||||
: content_(std::move(content)) {}
|
||||
|
||||
const Content& content() const noexcept {
|
||||
return content_;
|
||||
}
|
||||
private:
|
||||
Content content_;
|
||||
};
|
||||
|
||||
//
|
||||
// library
|
||||
//
|
||||
@@ -84,55 +39,19 @@ namespace e2d
|
||||
std::size_t unload_unused_assets() noexcept;
|
||||
|
||||
template < typename Asset >
|
||||
typename Asset::load_result load_asset(str_view address);
|
||||
typename Asset::load_result load_main_asset(str_view address) const;
|
||||
|
||||
template < typename Asset >
|
||||
typename Asset::load_async_result load_asset_async(str_view address);
|
||||
typename Asset::load_async_result load_main_asset_async(str_view address) const;
|
||||
|
||||
template < typename Asset, typename Nested = Asset >
|
||||
typename Nested::load_result load_asset(str_view address) const;
|
||||
|
||||
template < typename Asset, typename Nested = Asset >
|
||||
typename Nested::load_async_result load_asset_async(str_view address) const;
|
||||
private:
|
||||
url root_;
|
||||
};
|
||||
|
||||
//
|
||||
// asset_cache_base
|
||||
//
|
||||
|
||||
class asset_cache_base : private noncopyable {
|
||||
public:
|
||||
asset_cache_base();
|
||||
virtual ~asset_cache_base() noexcept;
|
||||
|
||||
static std::size_t unload_all_unused_assets() noexcept;
|
||||
virtual std::size_t unload_self_unused_assets() noexcept = 0;
|
||||
private:
|
||||
static std::mutex mutex_;
|
||||
static hash_set<asset_cache_base*> caches_;
|
||||
};
|
||||
|
||||
//
|
||||
// asset_cache
|
||||
//
|
||||
|
||||
template < typename Asset >
|
||||
class asset_cache : public asset_cache_base
|
||||
, public module<asset_cache<Asset>> {
|
||||
public:
|
||||
using asset_result = typename Asset::load_result;
|
||||
public:
|
||||
asset_cache(library& l);
|
||||
~asset_cache() noexcept final;
|
||||
|
||||
asset_result find(str_hash address) const;
|
||||
void store(str_hash address, const asset_result& asset);
|
||||
|
||||
void clear() noexcept;
|
||||
std::size_t asset_count() const noexcept;
|
||||
|
||||
std::size_t unload_self_unused_assets() noexcept override;
|
||||
private:
|
||||
library& library_;
|
||||
mutable std::mutex mutex_;
|
||||
hash_map<str_hash, asset_result> assets_;
|
||||
};
|
||||
}
|
||||
|
||||
#include "library.inl"
|
||||
|
||||
@@ -13,13 +13,9 @@
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
//
|
||||
// library
|
||||
//
|
||||
|
||||
template < typename Asset >
|
||||
typename Asset::load_result library::load_asset(str_view address) {
|
||||
auto p = load_asset_async<Asset>(address);
|
||||
typename Asset::load_result library::load_main_asset(str_view address) const {
|
||||
auto p = load_main_asset_async<Asset>(address);
|
||||
|
||||
if ( modules::is_initialized<deferrer>() ) {
|
||||
the<deferrer>().active_safe_wait_promise(p);
|
||||
@@ -29,77 +25,61 @@ namespace e2d
|
||||
}
|
||||
|
||||
template < typename Asset >
|
||||
typename Asset::load_async_result library::load_asset_async(str_view address) {
|
||||
typename Asset::load_async_result library::load_main_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)
|
||||
](auto&& new_asset){
|
||||
cache.store(address_hash, new_asset);
|
||||
return std::forward<decltype(new_asset)>(new_asset);
|
||||
main_address_hash
|
||||
](const typename Asset::load_result& new_asset){
|
||||
cache.store(main_address_hash, new_asset);
|
||||
return new_asset;
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// asset_cache
|
||||
//
|
||||
template < typename Asset, typename Nested >
|
||||
typename Nested::load_result library::load_asset(str_view address) const {
|
||||
auto p = load_asset_async<Asset, Nested>(address);
|
||||
|
||||
template < typename T >
|
||||
asset_cache<T>::asset_cache(library& l)
|
||||
: library_(l) {}
|
||||
|
||||
template < typename T >
|
||||
asset_cache<T>::~asset_cache() noexcept = default;
|
||||
|
||||
template < typename T >
|
||||
typename asset_cache<T>::asset_result asset_cache<T>::find(str_hash address) const {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
const auto iter = assets_.find(address);
|
||||
return iter != assets_.end()
|
||||
? iter->second
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
void asset_cache<T>::store(str_hash address, const asset_result& asset) {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
assets_[address] = asset;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
void asset_cache<T>::clear() noexcept {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
assets_.clear();
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
std::size_t asset_cache<T>::asset_count() const noexcept {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
return assets_.size();
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
std::size_t asset_cache<T>::unload_self_unused_assets() noexcept {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
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;
|
||||
}
|
||||
if ( modules::is_initialized<deferrer>() ) {
|
||||
the<deferrer>().active_safe_wait_promise(p);
|
||||
}
|
||||
return result;
|
||||
|
||||
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_main_asset_async<Asset>(address::parent(address))
|
||||
.then([
|
||||
address = str(address)
|
||||
](const typename Asset::load_result& main_asset){
|
||||
asset_ptr nested_asset = main_asset;
|
||||
str nested_address = address::nested(address);
|
||||
|
||||
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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ namespace e2d
|
||||
const texture_asset::ptr& texture() const noexcept;
|
||||
const material_asset::ptr& material() const noexcept;
|
||||
private:
|
||||
v2f size_;
|
||||
v2f pivot_;
|
||||
b2f texrect_;
|
||||
texture_asset::ptr texture_;
|
||||
|
||||
39
sources/enduro2d/high/address.cpp
Normal file
39
sources/enduro2d/high/address.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019 Matvey Cherevko
|
||||
******************************************************************************/
|
||||
|
||||
#include <enduro2d/high/address.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
|
||||
const str_view address_separator = ":/";
|
||||
|
||||
str_view::iterator str_view_search(str_view str, str_view s_str) noexcept {
|
||||
return std::search(str.begin(), str.end(), s_str.begin(), s_str.end());
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d { namespace address
|
||||
{
|
||||
str parent(str_view address) {
|
||||
const auto sep_e = str_view_search(address, address_separator);
|
||||
if ( sep_e == address.end() ) {
|
||||
return address;
|
||||
}
|
||||
const auto sep_d = std::distance(address.begin(), sep_e);
|
||||
return address.substr(0, static_cast<std::size_t>(sep_d));
|
||||
}
|
||||
|
||||
str nested(str_view address) {
|
||||
const auto sep_e = str_view_search(address, address_separator);
|
||||
if ( sep_e == address.end() ) {
|
||||
return str();
|
||||
}
|
||||
const auto sep_d = std::distance(address.begin(), sep_e);
|
||||
return address.substr(static_cast<std::size_t>(sep_d) + address_separator.size());
|
||||
}
|
||||
}}
|
||||
49
sources/enduro2d/high/asset.cpp
Normal file
49
sources/enduro2d/high/asset.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019 Matvey Cherevko
|
||||
******************************************************************************/
|
||||
|
||||
#include <enduro2d/high/asset.hpp>
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
//
|
||||
// asset
|
||||
//
|
||||
|
||||
asset::asset() = default;
|
||||
asset::~asset() noexcept = default;
|
||||
|
||||
//
|
||||
// asset_cache_base
|
||||
//
|
||||
|
||||
std::mutex asset_cache_base::mutex_;
|
||||
hash_set<asset_cache_base*> asset_cache_base::caches_;
|
||||
|
||||
asset_cache_base::asset_cache_base() {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
caches_.insert(this);
|
||||
}
|
||||
|
||||
asset_cache_base::~asset_cache_base() noexcept {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
caches_.erase(this);
|
||||
}
|
||||
|
||||
std::size_t asset_cache_base::unload_all_unused_assets() noexcept {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
return std::accumulate(caches_.begin(), caches_.end(), std::size_t(0),
|
||||
[](std::size_t acc, asset_cache_base* cache){
|
||||
return acc + cache->unload_self_unused_assets();
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// asset_factory
|
||||
//
|
||||
|
||||
asset_factory::asset_factory() = default;
|
||||
asset_factory::~asset_factory() noexcept = default;
|
||||
}
|
||||
@@ -145,7 +145,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<atlas> parse_atlas(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -187,7 +187,7 @@ namespace
|
||||
namespace e2d
|
||||
{
|
||||
atlas_asset::load_async_result atlas_asset::load_async(
|
||||
library& library, str_view address)
|
||||
const library& library, str_view address)
|
||||
{
|
||||
return library.load_asset_async<json_asset>(address)
|
||||
.then([
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace
|
||||
namespace e2d
|
||||
{
|
||||
binary_asset::load_async_result binary_asset::load_async(
|
||||
library& library, str_view address)
|
||||
const library& library, str_view address)
|
||||
{
|
||||
const auto asset_url = library.root() / address;
|
||||
return the<vfs>().load_async(asset_url)
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<flipbook::frame> parse_flipbook_atlas_frame(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -140,7 +140,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<flipbook::frame> parse_flipbook_texture_frame(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -174,7 +174,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<flipbook::frame> parse_flipbook_frame(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -191,7 +191,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<vector<flipbook::frame>> parse_flipbook_frames(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -245,7 +245,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<flipbook> parse_flipbook(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -290,7 +290,7 @@ namespace
|
||||
namespace e2d
|
||||
{
|
||||
flipbook_asset::load_async_result flipbook_asset::load_async(
|
||||
library& library, str_view address)
|
||||
const library& library, str_view address)
|
||||
{
|
||||
return library.load_asset_async<json_asset>(address)
|
||||
.then([
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace
|
||||
namespace e2d
|
||||
{
|
||||
image_asset::load_async_result image_asset::load_async(
|
||||
library& library, str_view address)
|
||||
const library& library, str_view address)
|
||||
{
|
||||
return library.load_asset_async<binary_asset>(address)
|
||||
.then([](const binary_asset::load_result& image_data){
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace
|
||||
namespace e2d
|
||||
{
|
||||
json_asset::load_async_result json_asset::load_async(
|
||||
library& library, str_view address)
|
||||
const library& library, str_view address)
|
||||
{
|
||||
return library.load_asset_async<text_asset>(address)
|
||||
.then([](const text_asset::load_result& json_data){
|
||||
|
||||
@@ -15,6 +15,6 @@ namespace e2d
|
||||
class json_asset final : public content_asset<json_asset, rapidjson::Document> {
|
||||
public:
|
||||
using content_asset<json_asset, rapidjson::Document>::content_asset;
|
||||
static load_async_result load_async(library& library, str_view address);
|
||||
static load_async_result load_async(const library& library, str_view address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -492,7 +492,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<shader_ptr> parse_shader_block(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -506,7 +506,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<texture_ptr> parse_texture_block(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -520,7 +520,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<std::pair<str_hash,render::sampler_state>> parse_sampler_state(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -669,7 +669,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<render::property_block> parse_property_block(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -1092,7 +1092,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<render::pass_state> parse_pass_state(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -1126,7 +1126,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<render::material> parse_material(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -1169,7 +1169,7 @@ namespace
|
||||
namespace e2d
|
||||
{
|
||||
material_asset::load_async_result material_asset::load_async(
|
||||
library& library, str_view address)
|
||||
const library& library, str_view address)
|
||||
{
|
||||
return library.load_asset_async<json_asset>(address)
|
||||
.then([
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace
|
||||
namespace e2d
|
||||
{
|
||||
mesh_asset::load_async_result mesh_asset::load_async(
|
||||
library& library, str_view address)
|
||||
const library& library, str_view address)
|
||||
{
|
||||
return library.load_asset_async<binary_asset>(address)
|
||||
.then([](const binary_asset::load_result& mesh_data){
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<model> parse_model(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -97,7 +97,7 @@ namespace
|
||||
namespace e2d
|
||||
{
|
||||
model_asset::load_async_result model_asset::load_async(
|
||||
library& library, str_view address)
|
||||
const library& library, str_view address)
|
||||
{
|
||||
return library.load_asset_async<json_asset>(address)
|
||||
.then([
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<shader_ptr> parse_shader(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -84,7 +84,7 @@ namespace
|
||||
namespace e2d
|
||||
{
|
||||
shader_asset::load_async_result shader_asset::load_async(
|
||||
library& library, str_view address)
|
||||
const library& library, str_view address)
|
||||
{
|
||||
return library.load_asset_async<json_asset>(address)
|
||||
.then([
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace
|
||||
namespace e2d
|
||||
{
|
||||
shape_asset::load_async_result shape_asset::load_async(
|
||||
library& library, str_view address)
|
||||
const library& library, str_view address)
|
||||
{
|
||||
return library.load_asset_async<binary_asset>(address)
|
||||
.then([](const binary_asset::load_result& shape_data){
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<sprite> parse_sprite_with_atlas(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -130,7 +130,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<sprite> parse_sprite_with_texture(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -183,7 +183,7 @@ namespace
|
||||
}
|
||||
|
||||
stdex::promise<sprite> parse_sprite(
|
||||
library& library,
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
@@ -203,7 +203,7 @@ namespace
|
||||
namespace e2d
|
||||
{
|
||||
sprite_asset::load_async_result sprite_asset::load_async(
|
||||
library& library, str_view address)
|
||||
const library& library, str_view address)
|
||||
{
|
||||
return library.load_asset_async<json_asset>(address)
|
||||
.then([
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace
|
||||
namespace e2d
|
||||
{
|
||||
text_asset::load_async_result text_asset::load_async(
|
||||
library& library, str_view address)
|
||||
const library& library, str_view address)
|
||||
{
|
||||
const auto asset_url = library.root() / address;
|
||||
return the<vfs>().load_as_string_async(asset_url)
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace
|
||||
namespace e2d
|
||||
{
|
||||
texture_asset::load_async_result texture_asset::load_async(
|
||||
library& library, str_view address)
|
||||
const library& library, str_view address)
|
||||
{
|
||||
return library.load_asset_async<image_asset>(address)
|
||||
.then([](const image_asset::load_result& texture_data){
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace
|
||||
namespace e2d
|
||||
{
|
||||
xml_asset::load_async_result xml_asset::load_async(
|
||||
library& library, str_view address)
|
||||
const library& library, str_view address)
|
||||
{
|
||||
return library.load_asset_async<text_asset>(address)
|
||||
.then([](const text_asset::load_result& xml_data){
|
||||
|
||||
@@ -15,6 +15,6 @@ namespace e2d
|
||||
class xml_asset final : public content_asset<xml_asset, pugi::xml_document> {
|
||||
public:
|
||||
using content_asset<xml_asset, pugi::xml_document>::content_asset;
|
||||
static load_async_result load_async(library& library, str_view address);
|
||||
static load_async_result load_async(const library& library, str_view address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,17 +6,8 @@
|
||||
|
||||
#include <enduro2d/high/library.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
//
|
||||
// library
|
||||
//
|
||||
|
||||
library::library(const url& root)
|
||||
: root_(root) {}
|
||||
|
||||
@@ -29,29 +20,4 @@ namespace e2d
|
||||
std::size_t library::unload_unused_assets() noexcept {
|
||||
return asset_cache_base::unload_all_unused_assets();
|
||||
}
|
||||
|
||||
//
|
||||
// asset_cache_base
|
||||
//
|
||||
|
||||
std::mutex asset_cache_base::mutex_;
|
||||
hash_set<asset_cache_base*> asset_cache_base::caches_;
|
||||
|
||||
asset_cache_base::asset_cache_base() {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
caches_.insert(this);
|
||||
}
|
||||
|
||||
asset_cache_base::~asset_cache_base() noexcept {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
caches_.erase(this);
|
||||
}
|
||||
|
||||
std::size_t asset_cache_base::unload_all_unused_assets() noexcept {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
return std::accumulate( caches_.begin(), caches_.end(), std::size_t(0),
|
||||
[](std::size_t acc, asset_cache_base* cache){
|
||||
return acc + cache->unload_self_unused_assets();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ namespace e2d
|
||||
}
|
||||
|
||||
void sprite::clear() noexcept {
|
||||
size_ = v2f::zero();
|
||||
pivot_ = v2f::zero();
|
||||
texrect_ = b2f::zero();
|
||||
texture_.reset();
|
||||
@@ -37,7 +36,6 @@ namespace e2d
|
||||
|
||||
void sprite::swap(sprite& other) noexcept {
|
||||
using std::swap;
|
||||
swap(size_, other.size_);
|
||||
swap(pivot_, other.pivot_);
|
||||
swap(texrect_, other.texrect_);
|
||||
swap(texture_, other.texture_);
|
||||
@@ -55,7 +53,6 @@ namespace e2d
|
||||
sprite& sprite::assign(const sprite& other) {
|
||||
if ( this != &other ) {
|
||||
sprite s;
|
||||
s.size_ = other.size_;
|
||||
s.pivot_ = other.pivot_;
|
||||
s.texrect_ = other.texrect_;
|
||||
s.texture_ = other.texture_;
|
||||
|
||||
@@ -28,10 +28,10 @@ namespace
|
||||
using namespace e2d;
|
||||
|
||||
template < typename Module, typename... Args >
|
||||
void safe_module_initialize(Args&&... args) {
|
||||
if ( !modules::is_initialized<Module>() ) {
|
||||
modules::initialize<Module>(std::forward<Args>(args)...);
|
||||
}
|
||||
Module& safe_module_initialize(Args&&... args) {
|
||||
return modules::is_initialized<Module>()
|
||||
? modules::instance<Module>()
|
||||
: modules::initialize<Module>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
class starter_application final : public application {
|
||||
@@ -137,11 +137,24 @@ namespace e2d
|
||||
safe_module_initialize<asset_cache<sprite_asset>>(the<library>());
|
||||
safe_module_initialize<asset_cache<text_asset>>(the<library>());
|
||||
safe_module_initialize<asset_cache<texture_asset>>(the<library>());
|
||||
safe_module_initialize<asset_factory>()
|
||||
.register_asset<atlas_asset>("atlas")
|
||||
.register_asset<binary_asset>("binary")
|
||||
.register_asset<image_asset>("image")
|
||||
.register_asset<material_asset>("material")
|
||||
.register_asset<mesh_asset>("mesh")
|
||||
.register_asset<model_asset>("model")
|
||||
.register_asset<shader_asset>("shader")
|
||||
.register_asset<shape_asset>("shape")
|
||||
.register_asset<sprite_asset>("sprite")
|
||||
.register_asset<text_asset>("text")
|
||||
.register_asset<texture_asset>("texture");
|
||||
safe_module_initialize<world>();
|
||||
}
|
||||
|
||||
starter::~starter() noexcept {
|
||||
modules::shutdown<world>();
|
||||
modules::shutdown<asset_factory>();
|
||||
modules::shutdown<asset_cache<texture_asset>>();
|
||||
modules::shutdown<asset_cache<text_asset>>();
|
||||
modules::shutdown<asset_cache<sprite_asset>>();
|
||||
|
||||
31
untests/sources/untests_high/address.cpp
Normal file
31
untests/sources/untests_high/address.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019 Matvey Cherevko
|
||||
******************************************************************************/
|
||||
|
||||
#include "_high.hpp"
|
||||
using namespace e2d;
|
||||
|
||||
TEST_CASE("address") {
|
||||
SECTION("parent") {
|
||||
REQUIRE(address::parent("") == "");
|
||||
REQUIRE(address::parent(":/") == "");
|
||||
REQUIRE(address::parent(":/child") == "");
|
||||
REQUIRE(address::parent("at/las.json") == "at/las.json");
|
||||
REQUIRE(address::parent("at/las.json:/") == "at/las.json");
|
||||
REQUIRE(address::parent("at/las.json:/spr/ite.png") == "at/las.json");
|
||||
REQUIRE(address::parent("at/las.json:/spr/ite.png:/") == "at/las.json");
|
||||
REQUIRE(address::parent("at/las.json:/spr/ite.png:/child") == "at/las.json");
|
||||
}
|
||||
SECTION("nested") {
|
||||
REQUIRE(address::nested("") == "");
|
||||
REQUIRE(address::nested(":/") == "");
|
||||
REQUIRE(address::nested(":/chi/ld") == "chi/ld");
|
||||
REQUIRE(address::nested("at/las.json") == "");
|
||||
REQUIRE(address::nested("at/las.json:/") == "");
|
||||
REQUIRE(address::nested("at/las.json:/spr/ite.png") == "spr/ite.png");
|
||||
REQUIRE(address::nested("at/las.json:/spr/ite.png:/") == "spr/ite.png:/");
|
||||
REQUIRE(address::nested("at/las.json:/spr/ite.png:/chi/ld") == "spr/ite.png:/chi/ld");
|
||||
}
|
||||
}
|
||||
79
untests/sources/untests_high/asset.cpp
Normal file
79
untests/sources/untests_high/asset.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019 Matvey Cherevko
|
||||
******************************************************************************/
|
||||
|
||||
#include "_high.hpp"
|
||||
using namespace e2d;
|
||||
|
||||
namespace
|
||||
{
|
||||
class safe_starter_initializer final : private noncopyable {
|
||||
public:
|
||||
safe_starter_initializer() {
|
||||
modules::initialize<starter>(0, nullptr,
|
||||
starter::parameters(
|
||||
engine::parameters("asset_untests", "enduro2d")
|
||||
.without_graphics(true)));
|
||||
}
|
||||
|
||||
~safe_starter_initializer() noexcept {
|
||||
modules::shutdown<starter>();
|
||||
}
|
||||
};
|
||||
|
||||
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_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());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("asset"){
|
||||
safe_starter_initializer initializer;
|
||||
library& l = the<library>();
|
||||
{
|
||||
REQUIRE_FALSE(l.load_asset<fake_asset>("none"));
|
||||
|
||||
auto fa = l.load_asset<fake_asset>("42");
|
||||
REQUIRE(fa);
|
||||
REQUIRE(fa->content() == 42);
|
||||
|
||||
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_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"));
|
||||
}
|
||||
}
|
||||
@@ -99,25 +99,33 @@ TEST_CASE("library"){
|
||||
auto material_res = l.load_asset<material_asset>("material.json");
|
||||
REQUIRE(material_res);
|
||||
|
||||
auto atlas_res = l.load_asset<atlas_asset>("atlas.json");
|
||||
REQUIRE(atlas_res);
|
||||
REQUIRE(atlas_res->content().texture() == texture_res);
|
||||
REQUIRE(atlas_res->content().regions().size() == 1);
|
||||
REQUIRE(atlas_res->content().find_region("sprite"));
|
||||
REQUIRE(atlas_res->content().find_region("sprite")->name == make_hash("sprite"));
|
||||
REQUIRE(atlas_res->content().find_region("sprite")->pivot == v2f(1.f,2.f));
|
||||
REQUIRE(atlas_res->content().find_region("sprite")->texrect == b2f(5.f,6.f,7.f,8.f));
|
||||
REQUIRE_FALSE(atlas_res->content().find_region("sprite2"));
|
||||
REQUIRE(atlas_res->content().shape_regions().size() == 1);
|
||||
REQUIRE(atlas_res->content().find_shape_region("shape_sprite"));
|
||||
REQUIRE(atlas_res->content().find_shape_region("shape_sprite")->name == make_hash("shape_sprite"));
|
||||
REQUIRE(atlas_res->content().find_shape_region("shape_sprite")->pivot == v2f(3.f,4.f));
|
||||
REQUIRE(atlas_res->content().find_shape_region("shape_sprite")->points == vector<v2f>{
|
||||
{1.f, 2.f},
|
||||
{3.f, 4.f},
|
||||
{5.f, 6.f}
|
||||
});
|
||||
REQUIRE_FALSE(atlas_res->content().find_shape_region("shape_sprite2"));
|
||||
{
|
||||
auto atlas_res = l.load_asset<atlas_asset>("atlas.json");
|
||||
REQUIRE(atlas_res);
|
||||
|
||||
REQUIRE(atlas_res->content().texture() == texture_res);
|
||||
REQUIRE(atlas_res->content().regions().size() == 1);
|
||||
REQUIRE(atlas_res->content().shape_regions().size() == 1);
|
||||
|
||||
const atlas::region* region = atlas_res->content().find_region("sprite");
|
||||
REQUIRE(region);
|
||||
REQUIRE(region->name == make_hash("sprite"));
|
||||
REQUIRE(region->pivot == v2f(1.f,2.f));
|
||||
REQUIRE(region->texrect == b2f(5.f,6.f,7.f,8.f));
|
||||
|
||||
const atlas::shape_region* shape_region = atlas_res->content().find_shape_region("shape_sprite");
|
||||
REQUIRE(shape_region);
|
||||
REQUIRE(shape_region->name == make_hash("shape_sprite"));
|
||||
REQUIRE(shape_region->pivot == v2f(3.f,4.f));
|
||||
REQUIRE(shape_region->points == vector<v2f>{
|
||||
{1.f, 2.f},
|
||||
{3.f, 4.f},
|
||||
{5.f, 6.f}
|
||||
});
|
||||
|
||||
REQUIRE_FALSE(atlas_res->content().find_region("sprite2"));
|
||||
REQUIRE_FALSE(atlas_res->content().find_shape_region("shape_sprite2"));
|
||||
}
|
||||
|
||||
{
|
||||
auto sprite_res = l.load_asset<sprite_asset>("sprite_a.json");
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
* Copyright (C) 2018 Matvey Cherevko
|
||||
******************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "_high.hpp"
|
||||
using namespace e2d;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user