diff options
Diffstat (limited to 'src/crepe/manager')
-rw-r--r-- | src/crepe/manager/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/crepe/manager/Mediator.h | 2 | ||||
-rw-r--r-- | src/crepe/manager/ResourceManager.cpp | 34 | ||||
-rw-r--r-- | src/crepe/manager/ResourceManager.h | 48 | ||||
-rw-r--r-- | src/crepe/manager/ResourceManager.hpp | 26 |
5 files changed, 113 insertions, 0 deletions
diff --git a/src/crepe/manager/CMakeLists.txt b/src/crepe/manager/CMakeLists.txt index 517b8a2..480c8ee 100644 --- a/src/crepe/manager/CMakeLists.txt +++ b/src/crepe/manager/CMakeLists.txt @@ -4,6 +4,7 @@ target_sources(crepe PUBLIC Manager.cpp SaveManager.cpp SceneManager.cpp + ResourceManager.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES @@ -16,5 +17,7 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES SaveManager.h SceneManager.h SceneManager.hpp + ResourceManager.h + ResourceManager.hpp ) diff --git a/src/crepe/manager/Mediator.h b/src/crepe/manager/Mediator.h index a91509e..475aed9 100644 --- a/src/crepe/manager/Mediator.h +++ b/src/crepe/manager/Mediator.h @@ -10,6 +10,7 @@ namespace crepe { class ComponentManager; class SceneManager; +class ResourceManager; /** * Struct to pass references to classes that would otherwise need to be singletons down to @@ -28,6 +29,7 @@ struct Mediator { OptionalRef<SceneManager> scene_manager; OptionalRef<SaveManager> save_manager = SaveManager::get_instance(); OptionalRef<EventManager> event_manager = EventManager::get_instance(); + OptionalRef<ResourceManager> resource_manager; }; } diff --git a/src/crepe/manager/ResourceManager.cpp b/src/crepe/manager/ResourceManager.cpp new file mode 100644 index 0000000..87585ad --- /dev/null +++ b/src/crepe/manager/ResourceManager.cpp @@ -0,0 +1,34 @@ +#include "util/Log.h" + +#include "ResourceManager.h" + +using namespace crepe; +using namespace std; + +ResourceManager::ResourceManager(Mediator & mediator) : Manager(mediator) { + mediator.resource_manager = *this; + dbg_trace(); +} +ResourceManager::~ResourceManager() { dbg_trace(); } + +void ResourceManager::clear() { + std::erase_if(this->resources, [](const pair<const Asset, CacheEntry> & pair) { + const CacheEntry & entry = pair.second; + return entry.persistent == false; + }); +} + +void ResourceManager::clear_all() { + this->resources.clear(); +} + +void ResourceManager::set_persistent(const Asset & asset, bool persistent) { + this->get_entry(asset).persistent = persistent; +} + +ResourceManager::CacheEntry & ResourceManager::get_entry(const Asset & asset) { + if (!this->resources.contains(asset)) + this->resources[asset] = {}; + return this->resources.at(asset); +} + diff --git a/src/crepe/manager/ResourceManager.h b/src/crepe/manager/ResourceManager.h new file mode 100644 index 0000000..e7e6abc --- /dev/null +++ b/src/crepe/manager/ResourceManager.h @@ -0,0 +1,48 @@ +#pragma once + +#include <memory> +#include <unordered_map> + +#include "../Resource.h" +#include "../api/Asset.h" + +#include "Manager.h" + +namespace crepe { + +/** + * \brief The ResourceManager is responsible for storing and managing assets over + * multiple scenes. + * + * The ResourceManager ensures that assets are loaded once and can be accessed + * across different scenes. It caches assets to avoid reloading them every time + * a scene is loaded. Assets are retained in memory until the ResourceManager is + * destroyed, at which point the cached assets are cleared. + */ +class ResourceManager : public Manager { +public: + ResourceManager(Mediator & mediator); + virtual ~ResourceManager(); // dbg_trace + +private: + struct CacheEntry { + std::unique_ptr<Resource> resource = nullptr; + bool persistent = false; + }; + //! A cache that holds all the assets, accessible by their file path, over multiple scenes. + std::unordered_map<const Asset, CacheEntry> resources; + CacheEntry & get_entry(const Asset & asset); + +public: + void set_persistent(const Asset & asset, bool persistent); + + template <typename Resource> + Resource & get(const Asset & asset); + + void clear(); + void clear_all(); +}; + +} // namespace crepe + +#include "ResourceManager.hpp" diff --git a/src/crepe/manager/ResourceManager.hpp b/src/crepe/manager/ResourceManager.hpp new file mode 100644 index 0000000..8270bc5 --- /dev/null +++ b/src/crepe/manager/ResourceManager.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include <format> + +#include "ResourceManager.h" + +namespace crepe { + +template <typename T> +T & ResourceManager::get(const Asset & asset) { + using namespace std; + static_assert(is_base_of<Resource, T>::value, "cache must recieve a derivative class of Resource"); + + CacheEntry & entry = this->get_entry(asset); + if (entry.resource == nullptr) + entry.resource = make_unique<T>(asset); + + T * concrete_resource = dynamic_cast<T *>(entry.resource.get()); + if (concrete_resource == nullptr) + throw runtime_error(format("ResourceManager: mismatch between requested type and actual type of resource ({})", asset.get_path())); + + return *concrete_resource; +} + +} + |