Engine
Raylib based game framework
Loading...
Searching...
No Matches
ResourceManager.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Assert.hpp"
4#include "NonCopyable.hpp"
5
6#include <functional>
7#include <memory>
8#include <mutex>
9#include <optional>
10#include <raylib.h>
11#include <shared_mutex>
12#include <string>
13#include <typeindex>
14#include <unordered_map>
15
20
26class Cache : public NonCopyable<>
27{
28public:
29
30 virtual ~Cache() = default;
31};
32
43template <class Resource>
44class ResourceCache : public Cache
45{
46public:
47
54 ResourceCache(const std::function<std::optional<Resource>(const std::string&)>& loadFunction,
55 const std::function<void(Resource)>& unloadFunction) :
56 m_loadFunction(loadFunction),
57 m_unloadFunction(unloadFunction)
58 {
59 }
60
61 ResourceCache(const ResourceCache&) = delete;
62 ResourceCache& operator=(const ResourceCache&) = delete;
63
70 std::shared_ptr<Resource> Get(const std::string& name)
71 {
72 std::shared_lock lock(m_mutex);
73
74 auto it = m_map.find(name);
75 if (it != m_map.end())
76 {
77 return it->second;
78 }
79
80 return {};
81 }
82
91 std::shared_ptr<Resource> Load(const std::string& path)
92 {
93 std::optional<Resource> opt = m_loadFunction(path);
94
95 if (!opt)
96 {
97 return {};
98 }
99
100 auto unload = m_unloadFunction;
101
102 auto ptr = std::shared_ptr<Resource>(new Resource(std::move(*opt)), [unload](Resource* resource)
103 {
104 unload(*resource);
105 delete resource;
106 });
107
108 {
109 std::unique_lock lock(m_mutex);
110
111 m_map[path] = ptr;
112 }
113
114 return ptr;
115 }
116
126 std::shared_ptr<Resource> Add(Resource&& object, const std::string& name)
127 {
128 auto unload = m_unloadFunction;
129
130 auto ptr = std::shared_ptr<Resource>(new Resource(std::move(object)), [unload](Resource* resource)
131 {
132 unload(*resource);
133 delete resource;
134 });
135
136 {
137 std::unique_lock lock(m_mutex);
138
139 m_map[name] = ptr;
140 }
141
142 return ptr;
143 }
144
153 void Remove(const std::string& path)
154 {
155 std::unique_lock lock(m_mutex);
156
157 m_map.erase(path);
158 }
159
160private:
161
162 std::unordered_map<std::string, std::shared_ptr<Resource>> m_map;
163
164 std::function<std::optional<Resource>(const std::string&)> m_loadFunction;
165 std::function<void(Resource)> m_unloadFunction;
166
167 std::shared_mutex m_mutex;
168};
169
178class ResourceManager
179{
180public:
181
192 template <typename Resource, typename... Args>
193 std::shared_ptr<ResourceCache<Resource>> AddCache(Args&&... args)
194 {
195 std::unique_lock lock(m_mutex);
196
197 auto it = m_caches.find(typeid(Resource));
198 if (it != m_caches.end())
199 {
200 return std::static_pointer_cast<ResourceCache<Resource>>(it->second);
201 }
202
203 auto ptr = std::make_shared<ResourceCache<Resource>>(std::forward<Args>(args)...);
204
205 m_caches.emplace(typeid(Resource), ptr);
206
207 return ptr;
208 }
209
218 template <typename Resource>
219 std::shared_ptr<ResourceCache<Resource>> GetCache()
220 {
221 std::shared_lock lock(m_mutex);
222
223 auto it = m_caches.find(typeid(Resource));
224 Assert(it != m_caches.end(), "No cache exists holding type ", typeid(Resource).name());
225
226 return std::static_pointer_cast<ResourceCache<Resource>>(it->second);
227 }
228
237 template <typename Resource>
239 {
240 std::unique_lock lock(m_mutex);
241
242 m_caches.erase(typeid(Resource));
243 }
244
251 void ClearCaches();
252
253private:
254
255 ResourceManager() = default;
256
257 std::shared_mutex m_mutex;
258
259 std::unordered_map<std::type_index, std::shared_ptr<Cache>> m_caches;
260
261 friend class Engine;
262};
Abstract base for type-erased resource caches.
Definition ResourceManager.hpp:27
Core engine.
Definition Engine.hpp:90
Thread-safe cache for a single resource type.
Definition ResourceManager.hpp:45
std::shared_ptr< Resource > Load(const std::string &path)
Loads a resource from disk and caches it under its path.
Definition ResourceManager.hpp:91
std::shared_ptr< Resource > Add(Resource &&object, const std::string &name)
Stores an already-constructed resource under an arbitrary name.
Definition ResourceManager.hpp:126
std::shared_ptr< Resource > Get(const std::string &name)
Looks up a cached resource by name without loading it.
Definition ResourceManager.hpp:70
ResourceCache(const std::function< std::optional< Resource >(const std::string &)> &loadFunction, const std::function< void(Resource)> &unloadFunction)
Constructs a cache with the given load and unload functions.
Definition ResourceManager.hpp:54
void Remove(const std::string &path)
Removes a resource from the cache.
Definition ResourceManager.hpp:153
Owns a collection of typed resource caches.
Definition ResourceManager.hpp:179
void RemoveCache()
Removes the cache for the given resource type.
Definition ResourceManager.hpp:238
std::shared_ptr< ResourceCache< Resource > > GetCache()
Returns the cache for the given resource type.
Definition ResourceManager.hpp:219
std::shared_ptr< ResourceCache< Resource > > AddCache(Args &&... args)
Creates and registers a cache for a resource type.
Definition ResourceManager.hpp:193
void ClearCaches()
Removes all registered caches.
Definition ResourceManager.cpp:3