Engine²
Open-source game engine written in C++.
Loading...
Searching...
No Matches
ResourceManager.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Logger.hpp"
5#include <concepts>
6#include <entt/core/hashed_string.hpp>
7#include <entt/resource/cache.hpp>
8#include <fmt/format.h>
9#include <optional>
10#include <type_traits>
11
13
14template <typename TType>
15concept CViewStringable = std::is_constructible_v<std::string_view, const TType &> &&
16 !std::is_same_v<std::decay_t<TType>, entt::hashed_string>;
17
22template <typename ResourceType> class ResourceManager {
23 private:
29 struct ResourceLoader final {
30 using result_type = std::shared_ptr<ResourceType>;
31
32 template <typename... Args> result_type operator()(Args &&...args) const
33 {
34 return std::make_shared<ResourceType>(std::forward<Args>(args)...);
35 }
36 };
37
38 public:
39 ResourceManager() = default;
40 ~ResourceManager() = default;
41
44
45 ResourceManager(ResourceManager &&) noexcept = default;
46 ResourceManager &operator=(ResourceManager &&) noexcept = default;
47
57 template <typename... Args> entt::resource<ResourceType> Add(const entt::hashed_string &id, Args &&...args)
58 {
59 auto ret = cache.load(id, std::forward<Args>(args)...);
60
61 if (!ret.second)
62 {
63 Log::Warning(fmt::format("Resource with id {} already exists. Overwriting.", id.data()));
64 ret = cache.force_load(id, std::forward<Args>(args)...);
65 }
66
67 return ret.first->second;
68 }
69
70 template <CViewStringable TViewStringable, typename... Args>
71 entt::resource<ResourceType> Add(const TViewStringable &id, Args &&...args)
72 {
73 std::string_view stringViewId{id};
74 return Add(entt::hashed_string{stringViewId.data(), stringViewId.size()}, std::forward<Args>(args)...);
75 }
76
85 [[nodiscard]] ResourceType &Get(const entt::hashed_string &id)
86 {
87 auto resource = cache[id];
88
89 if (!resource)
90 throw ResourceManagerError(fmt::format("Resource with id {} not found.", id.data()));
91
92 return *resource;
93 }
94
95 template <CViewStringable TViewStringable> [[nodiscard]] ResourceType &Get(const TViewStringable &id)
96 {
97 std::string_view stringViewId{id};
98 return Get(entt::hashed_string{stringViewId.data(), stringViewId.size()});
99 }
100
109 [[nodiscard]] const ResourceType &Get(const entt::hashed_string &id) const
110 {
111 const auto &resource = cache[id];
112
113 if (!resource)
115 fmt::format("Resource with id {} not found.", std::string_view(id.data(), id.size())));
116
117 return *resource;
118 }
119 template <CViewStringable TViewStringable> [[nodiscard]] const ResourceType &Get(const TViewStringable &id) const
120 {
121 std::string_view stringViewId{id};
122 return Get(entt::hashed_string{stringViewId.data(), stringViewId.size()});
123 }
124
130 void Remove(const entt::hashed_string &id) { cache.erase(id); }
131
132 template <CViewStringable TViewStringable> void Remove(const TViewStringable &id)
133 {
134 std::string_view stringViewId{id};
135 Remove(entt::hashed_string{stringViewId.data(), stringViewId.size()});
136 }
137
144 [[nodiscard]] bool Contains(const entt::hashed_string &id) const { return cache.contains(id); }
145
146 template <CViewStringable TViewStringable> [[nodiscard]] bool Contains(const TViewStringable &id) const
147 {
148 std::string_view stringViewId{id};
149 return Contains(entt::hashed_string{stringViewId.data(), stringViewId.size()});
150 }
151
161 void SetDefault(ResourceType &&resource) { defaultResource = std::move(resource); }
162
163 template <typename... Args> void SetDefault(Args &&...args)
164 {
165 defaultResource = ResourceType(std::forward<Args>(args)...);
166 }
167
175 [[nodiscard]] ResourceType &GetDefault()
176 {
177 if (!defaultResource.has_value())
178 throw ResourceManagerError("No default resource is set.");
179
180 return *defaultResource;
181 }
182
190 [[nodiscard]] const ResourceType &GetDefault() const
191 {
192 if (!defaultResource.has_value())
193 throw ResourceManagerError("No default resource is set.");
194
195 return *defaultResource;
196 }
197
206 [[nodiscard]] ResourceType &GetOrDefault(const entt::hashed_string &id)
207 {
208 auto resource = cache[id];
209
210 if (resource)
211 return *resource;
212
213 if (!defaultResource.has_value())
215 fmt::format("Resource with id {} not found and no default resource is set.", id.data()));
216
217 return *defaultResource;
218 }
219
220 template <CViewStringable TViewStringable> [[nodiscard]] ResourceType &GetOrDefault(const TViewStringable &id)
221 {
222 std::string_view stringViewId{id};
223 return GetOrDefault(entt::hashed_string{stringViewId.data(), stringViewId.size()});
224 }
225
234 [[nodiscard]] const ResourceType &GetOrDefault(const entt::hashed_string &id) const
235 {
236 const auto &resource = cache[id];
237
238 if (resource)
239 return *resource;
240
241 if (!defaultResource.has_value())
243 fmt::format("Resource with id {} not found and no default resource is set.", id.data()));
244
245 return *defaultResource;
246 }
247
248 template <CViewStringable TViewStringable>
249 [[nodiscard]] const ResourceType &GetOrDefault(const TViewStringable &id) const
250 {
251 std::string_view stringViewId{id};
252 return GetOrDefault(entt::hashed_string{stringViewId.data(), stringViewId.size()});
253 }
254
260 [[nodiscard]] bool HasDefault() const { return defaultResource.has_value(); }
261
262 private:
263 entt::resource_cache<ResourceType, ResourceLoader> cache{};
264 std::optional<ResourceType> defaultResource = std::nullopt;
265};
266
267} // namespace Object::Resource
Definition ResourceManagerError.hpp:26
const ResourceType & GetDefault() const
Get the default resource.
Definition ResourceManager.hpp:190
void Remove(const entt::hashed_string &id)
Delete an resource from the manager.
Definition ResourceManager.hpp:130
ResourceManager & operator=(const ResourceManager &)=delete
entt::resource< BindGroup > Add(const entt::hashed_string &id, Args &&...args)
Definition ResourceManager.hpp:57
ResourceManager(ResourceManager &&) noexcept=default
void Remove(const TViewStringable &id)
Definition ResourceManager.hpp:132
const ResourceType & Get(const entt::hashed_string &id) const
Get the reference to a stored resource.
Definition ResourceManager.hpp:109
void SetDefault(Args &&...args)
Definition ResourceManager.hpp:163
std::optional< BindGroup > defaultResource
Definition ResourceManager.hpp:264
entt::resource< ResourceType > Add(const TViewStringable &id, Args &&...args)
Definition ResourceManager.hpp:71
const ResourceType & GetOrDefault(const entt::hashed_string &id) const
Get the reference to a stored resource, or the default resource if it doesn't exist.
Definition ResourceManager.hpp:234
const ResourceType & Get(const TViewStringable &id) const
Definition ResourceManager.hpp:119
ResourceType & GetOrDefault(const entt::hashed_string &id)
Get the reference to a stored resource, or the default resource if it doesn't exist.
Definition ResourceManager.hpp:206
const ResourceType & GetOrDefault(const TViewStringable &id) const
Definition ResourceManager.hpp:249
ResourceManager(const ResourceManager &)=delete
ResourceType & Get(const entt::hashed_string &id)
Get the reference to a stored resource.
Definition ResourceManager.hpp:85
ResourceType & Get(const TViewStringable &id)
Definition ResourceManager.hpp:95
void SetDefault(ResourceType &&resource)
Set the default resource that will be used as fallback.
Definition ResourceManager.hpp:161
ResourceType & GetOrDefault(const TViewStringable &id)
Definition ResourceManager.hpp:220
ResourceType & GetDefault()
Get the default resource.
Definition ResourceManager.hpp:175
bool HasDefault() const
Check if a default resource has been set.
Definition ResourceManager.hpp:260
entt::resource_cache< BindGroup, ResourceLoader > cache
Definition ResourceManager.hpp:263
bool Contains(const entt::hashed_string &id) const
Check whenever the resource with given id exists in the manager.
Definition ResourceManager.hpp:144
bool Contains(const TViewStringable &id) const
Definition ResourceManager.hpp:146
Definition ResourceManager.hpp:15
Definition ResourceManager.hpp:12
ResourceLoader structure is used to load a resource from another resource or from arguments.
Definition ResourceManager.hpp:29
result_type operator()(Args &&...args) const
Definition ResourceManager.hpp:32
std::shared_ptr< ResourceType > result_type
Definition ResourceManager.hpp:30