aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/manager
diff options
context:
space:
mode:
Diffstat (limited to 'src/crepe/manager')
-rw-r--r--src/crepe/manager/CMakeLists.txt3
-rw-r--r--src/crepe/manager/Mediator.h2
-rw-r--r--src/crepe/manager/ResourceManager.cpp34
-rw-r--r--src/crepe/manager/ResourceManager.h48
-rw-r--r--src/crepe/manager/ResourceManager.hpp26
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;
+}
+
+}
+