Helios Engine
A modular ECS based data-oriented C++23 game engine framework
Loading...
Searching...
No Matches
manager.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <helios/assert.hpp>
8
9#include <array>
10#include <concepts>
11#include <cstddef>
12#include <type_traits>
13
14namespace helios::ecs {
15
16/**
17 * @brief Resource manager for storing and managing resources of various types.
18 * @details Stores resources inline using `MultiTypeMap<TypedBuffer>`.
19 * @note Not thread-safe.
20 */
22public:
23 ResourceManager() = default;
25 ResourceManager(ResourceManager&&) noexcept = default;
26 ~ResourceManager() = default;
27
28 ResourceManager& operator=(const ResourceManager&) = default;
29 ResourceManager& operator=(ResourceManager&&) noexcept = default;
30
31 /// @brief Clears all resources, destroying stored values and removing all
32 /// entries.
33 void Clear() { resources_.ResetAll(); }
34
35 /**
36 * @brief Inserts a new resource.
37 * @details Replaces existing resource if present.
38 * @tparam T Resource type
39 * @param resource Resource to insert
40 */
41 template <ResourceTrait T>
42 void Insert(T&& resource);
43
44 /**
45 * @brief Inserts multiple resources.
46 * @details Replaces existing resources if present.
47 * @tparam Ts Resource types, must be unique and non-empty
48 * @param resources Resources to insert
49 */
50 template <ResourceTrait... Ts>
51 requires utils::UniqueTypes<Ts...> && (sizeof...(Ts) > 1)
52 void Insert(Ts&&... resources) {
53 (Insert(std::forward<Ts>(resources)), ...);
54 }
55
56 /**
57 * @brief Tries to insert resource if not present.
58 * @tparam T Resource type
59 * @param resource Resource to insert
60 * @return True if inserted, false if resource already exists
61 */
62 template <ResourceTrait T>
63 bool TryInsert(T&& resource);
64
65 /**
66 * @brief Tries to insert resources if not present.
67 * @tparam Ts Resource types, must be unique and non-empty
68 * @param resources Resources to insert
69 * @return True if inserted, false if resource already exists
70 */
71 template <ResourceTrait... Ts>
72 requires utils::UniqueTypes<Ts...> && (sizeof...(Ts) > 1)
73 auto TryInsert(Ts&&... resources) -> std::array<bool, sizeof...(Ts)> {
74 return {TryInsert(std::forward<Ts>(resources))...};
75 }
76
77 /**
78 * @brief Emplaces a new resource in-place.
79 * @details Constructs resource directly in storage.
80 * @tparam T Resource type
81 * @tparam Args Constructor argument types
82 * @param args Arguments to forward to resource constructor
83 */
84 template <ResourceTrait T, typename... Args>
85 requires std::constructible_from<T, Args...>
86 void Emplace(Args&&... args);
87
88 /**
89 * @brief Tries to emplace a resource if not present.
90 * @tparam T Resource type
91 * @tparam Args Constructor argument types
92 * @param args Arguments to forward to resource constructor
93 * @return True if emplaced, false if resource already exists
94 */
95 template <ResourceTrait T, typename... Args>
96 requires std::constructible_from<T, Args...>
97 bool TryEmplace(Args&&... args);
98
99 /**
100 * @brief Removes a resource.
101 * @warning Triggers assertion if resource doesn't exist.
102 * @tparam T Resource type
103 */
104 template <ResourceTrait T>
105 void Remove();
106
107 /**
108 * @brief Tries to remove a resource.
109 * @tparam T Resource type
110 * @return True if removed, false if resource didn't exist
111 */
112 template <ResourceTrait T>
113 bool TryRemove() {
114 return resources_.Remove<T>();
115 }
116
117 /**
118 * @brief Gets mutable reference to a resource.
119 * @warning Triggers assertion if resource doesn't exist.
120 * @tparam T Resource type
121 * @return Mutable reference to resource
122 */
123 template <ResourceTrait T>
124 [[nodiscard]] T& Get() noexcept;
125
126 /**
127 * @brief Gets const reference to a resource.
128 * @warning Triggers assertion if resource doesn't exist.
129 * @tparam T Resource type
130 * @return Const reference to resource
131 */
132 template <ResourceTrait T>
133 [[nodiscard]] const T& Get() const noexcept;
134
135 /**
136 * @brief Tries to get mutable pointer to a resource.
137 * @tparam T Resource type
138 * @return Pointer to resource, or `nullptr` if not found
139 */
140 template <ResourceTrait T>
141 [[nodiscard]] T* TryGet() noexcept;
142
143 /**
144 * @brief Tries to get const pointer to a resource.
145 * @tparam T Resource type
146 * @return Const pointer to resource, or `nullptr` if not found
147 */
148 template <ResourceTrait T>
149 [[nodiscard]] const T* TryGet() const noexcept;
150
151 /**
152 * @brief Checks if a resource exists.
153 * @tparam T Resource type
154 * @return True if resource exists, false otherwise
155 */
156 template <ResourceTrait T>
157 [[nodiscard]] bool Has() const noexcept {
158 return resources_.Contains<T>();
159 }
160
161 /**
162 * @brief Gets the number of stored resources.
163 * @return Resource count
164 */
165 [[nodiscard]] size_t Count() const noexcept { return resources_.TypeCount(); }
166
167private:
168 using StorageType = container::TypedBuffer<>;
170
171 MapType resources_;
172};
173
174template <ResourceTrait T>
175inline void ResourceManager::Insert(T&& resource) {
176 using DecayedT = std::remove_cvref_t<T>;
177 auto& buf = resources_.Ensure<DecayedT>();
178 buf.template Set<DecayedT>(std::forward<T>(resource));
179}
180
181template <ResourceTrait T>
182inline bool ResourceManager::TryInsert(T&& resource) {
183 using DecayedT = std::remove_cvref_t<T>;
184 if (resources_.Contains<DecayedT>() && !resources_.Empty<DecayedT>()) {
185 return false;
186 }
187 auto& buf = resources_.Ensure<DecayedT>();
188 buf.template Set<DecayedT>(std::forward<T>(resource));
189 return true;
190}
191
192template <ResourceTrait T, typename... Args>
193 requires std::constructible_from<T, Args...>
194inline void ResourceManager::Emplace(Args&&... args) {
195 auto& buf = resources_.Ensure<T>();
196 buf.template Set<T>(std::forward<Args>(args)...);
197}
198
199template <ResourceTrait T, typename... Args>
200 requires std::constructible_from<T, Args...>
201inline bool ResourceManager::TryEmplace(Args&&... args) {
202 if (resources_.Contains<T>() && !resources_.Empty<T>()) {
203 return false;
204 }
205 auto& buf = resources_.Ensure<T>();
206 buf.template Set<T>(std::forward<Args>(args)...);
207 return true;
208}
209
210template <ResourceTrait T>
212 [[maybe_unused]] const bool removed = resources_.Remove<T>();
213 HELIOS_ASSERT(removed, "Resource '{}' does not exist!", ResourceNameOf<T>());
214}
215
216template <ResourceTrait T>
217inline T& ResourceManager::Get() noexcept {
218 auto* buf = resources_.TryGet<T>();
219 HELIOS_ASSERT(buf != nullptr && !buf->Empty(),
220 "Resource '{}' does not exist!", ResourceNameOf<T>());
221 return buf->template Value<T>();
222}
223
224template <ResourceTrait T>
225inline const T& ResourceManager::Get() const noexcept {
226 const auto* buf = resources_.TryGet<T>();
227 HELIOS_ASSERT(buf != nullptr && !buf->Empty(),
228 "Resource '{}' does not exist!", ResourceNameOf<T>());
229 return buf->template Value<T>();
230}
231
232template <ResourceTrait T>
233inline T* ResourceManager::TryGet() noexcept {
234 auto* buf = resources_.TryGet<T>();
235 if (buf == nullptr || buf->Empty()) {
236 return nullptr;
237 }
238 return &buf->template Value<T>();
239}
240
241template <ResourceTrait T>
242inline const T* ResourceManager::TryGet() const noexcept {
243 const auto* buf = resources_.TryGet<T>();
244 if (buf == nullptr || buf->Empty()) {
245 return nullptr;
246 }
247 return &buf->template Value<T>();
248}
249
250} // namespace helios::ecs
#define HELIOS_ASSERT(condition,...)
Assertion macro that aborts execution in debug builds.
Definition assert.hpp:259
Generic type-indexed map that stores one Storage instance per registered type key.
constexpr Storage & Ensure()
Ensures a Storage entry exists for type T and returns a reference to it.
Type-erased single-instance byte storage.
size_t Count() const noexcept
Gets the number of stored resources.
Definition manager.hpp:165
T * TryGet() noexcept
Tries to get mutable pointer to a resource.
Definition manager.hpp:233
void Insert(Ts &&... resources)
Inserts multiple resources.
Definition manager.hpp:52
void Insert(T &&resource)
Inserts a new resource.
Definition manager.hpp:175
bool TryEmplace(Args &&... args)
Tries to emplace a resource if not present.
Definition manager.hpp:201
T & Get() noexcept
Gets mutable reference to a resource.
Definition manager.hpp:217
ResourceManager(const ResourceManager &)=default
bool TryRemove()
Tries to remove a resource.
Definition manager.hpp:113
void Emplace(Args &&... args)
Emplaces a new resource in-place.
Definition manager.hpp:194
void Remove()
Removes a resource.
Definition manager.hpp:211
bool Has() const noexcept
Checks if a resource exists.
Definition manager.hpp:157
auto TryInsert(Ts &&... resources) -> std::array< bool, sizeof...(Ts)>
Tries to insert resources if not present.
Definition manager.hpp:73
void Clear()
Clears all resources, destroying stored values and removing all entries.
Definition manager.hpp:33
bool TryInsert(T &&resource)
Tries to insert resource if not present.
Definition manager.hpp:182
ResourceManager(ResourceManager &&) noexcept=default
Concept for valid resource types.
Definition resource.hpp:25
Concept that checks if all types in a pack are unique (after removing cv/ref qualifiers).
constexpr std::string_view ResourceNameOf() noexcept
Gets name for a resource type.
Definition resource.hpp:93