Uranus  1.0.1.0
Uranus is a GameEngine written in C++
Loading...
Searching...
No Matches
Registry.hpp
1/*
2** EPITECH PROJECT, 2023
3** Registry.hpp
4** File description:
5** Registry.hpp
6*/
7
8#ifndef URANUS_REGISTRY_HPP
9#define URANUS_REGISTRY_HPP
10
11#include "Entity.hpp"
12#include "SparseArray.hpp"
13#include <any>
14#include <functional>
15#include <list>
16#include <stdexcept>
17#include <typeindex>
18#include <unordered_map>
19
20namespace uranus::ecs {
24 class Registry {
25 public:
32 template<class Component>
33 SparseArray<Component> &registerComponent(std::function<void(const size_t &)> &);
34
41 template<class Component>
42 SparseArray<Component> &registerComponent(std::function<void(const size_t &)> &&);
43
50 template<class Component>
51 typename SparseArray<Component>::ReferenceType getComponent(const Entity &e);
52
59 template<class Component>
60 typename SparseArray<Component>::ConstReferenceType getComponent(const Entity &e) const;
61
68 template<class Component>
69 typename SparseArray<Component>::ReferenceType getComponent(const size_t &e);
70
77 template<class Component>
78 typename SparseArray<Component>::ConstReferenceType getComponent(const size_t &e) const;
79
85 template<class Component>
87
93 template<class Component>
95
101
107 Entity entityFromIndex(std::size_t idx) const;
108
113 void killEntity(const Entity &e);
114
119 void killEntity(const size_t &e);
120
124 void killAllEntities();
125
133 template<typename Component>
134 typename SparseArray<Component>::ReferenceType addComponent(const Entity &to, Component &&c);
135
144 template<typename Component, typename... Params>
145 typename SparseArray<Component>::ReferenceType emplaceComponent(const Entity &to, Params &&...p);
146
152 template<typename Component>
153 void removeComponent(const Entity &from);
154
160 template<typename Component>
161 void removeComponent(const size_t &from);
162
167 int entitiesAliveCount() const;
168
173 size_t getEntityCounter() const;
174
179 // size_t getEntityAliveMaxIndex() const;
180 private:
181 std::unordered_map<std::type_index, std::any> _componentsArrays;
182 std::unordered_map<std::type_index, std::function<void(size_t const &)>> _destroyArrays;
183 size_t _entityCounter = 0;
184 std::list<size_t> _freeIds;
185 };
186
187 template<class Component>
188 SparseArray<Component> &Registry::registerComponent(std::function<void(const size_t &)> &&deleteFunction)
189 {
190 auto const &typeIndex = std::type_index(typeid(Component)); // NOLINT
191 if (_componentsArrays.find(typeIndex) != _componentsArrays.end()) throw std::runtime_error("Component already registered");
192 if (_destroyArrays.find(typeIndex) != _destroyArrays.end()) throw std::runtime_error("Delete function already registered");
194 _destroyArrays[typeIndex] = deleteFunction;
195 return std::any_cast<SparseArray<Component> &>(_componentsArrays[typeIndex]);
196 }
197
198 template<class Component>
199 SparseArray<Component> &Registry::registerComponent(std::function<void(const size_t &)> &deleteFunction)
200 {
201 auto const &typeIndex = std::type_index(typeid(Component)); // NOLINT
202 if (_componentsArrays.find(typeIndex) != _componentsArrays.end()) throw std::runtime_error("Component already registered");
203 if (_destroyArrays.find(typeIndex) != _destroyArrays.end()) throw std::runtime_error("Delete function already registered");
205 _destroyArrays[typeIndex] = deleteFunction;
206 return std::any_cast<SparseArray<Component> &>(_componentsArrays[typeIndex]);
207 }
208
209 template<class Component>
210 typename SparseArray<Component>::ReferenceType Registry::getComponent(const Entity &e)
211 {
212 auto const &typeIndex = std::type_index(typeid(Component)); // NOLINT
213 if (_componentsArrays.find(typeIndex) == _componentsArrays.end()) throw std::runtime_error("Component not registered");
214 return std::any_cast<SparseArray<Component> &>(_componentsArrays[typeIndex])[e];
215 }
216
217 template<class Component>
218 typename SparseArray<Component>::ReferenceType Registry::getComponent(const size_t &e)
219 {
220 auto const &typeIndex = std::type_index(typeid(Component)); // NOLINT
221 if (_componentsArrays.find(typeIndex) == _componentsArrays.end()) throw std::runtime_error("Component not registered");
222 return std::any_cast<SparseArray<Component> &>(_componentsArrays[typeIndex])[e];
223 }
224
225 template<class Component>
226 typename SparseArray<Component>::ConstReferenceType Registry::getComponent(const Entity &e) const
227 {
228 auto const &typeIndex = std::type_index(typeid(Component)); // NOLINT
229 if (_componentsArrays.find(typeIndex) == _componentsArrays.end()) throw std::runtime_error("Component not registered");
230 return std::any_cast<SparseArray<Component> const &>(_componentsArrays.at(typeIndex))[e];
231 }
232
233 template<class Component>
234 typename SparseArray<Component>::ConstReferenceType Registry::getComponent(const size_t &e) const
235 {
236 auto const &typeIndex = std::type_index(typeid(Component)); // NOLINT
237 if (_componentsArrays.find(typeIndex) == _componentsArrays.end()) throw std::runtime_error("Component not registered");
238 return std::any_cast<SparseArray<Component> const &>(_componentsArrays.at(typeIndex))[e];
239 }
240
241 template<class Component>
243 {
244 auto const &typeIndex = std::type_index(typeid(Component)); // NOLINT
245 if (_componentsArrays.find(typeIndex) == _componentsArrays.end()) throw std::runtime_error("Component not registered");
246 return std::any_cast<SparseArray<Component> &>(_componentsArrays[typeIndex]);
247 }
248
249 template<class Component>
251 {
252 auto const &typeIndex = std::type_index(typeid(Component)); // NOLINT
253 if (_componentsArrays.find(typeIndex) == _componentsArrays.end()) throw std::runtime_error("Component not registered");
254 return std::any_cast<SparseArray<Component> const &>(_componentsArrays.at(typeIndex));
255 }
256
258 {
259 if (_freeIds.empty())
260 return Entity(_entityCounter++);
261 const size_t id = _freeIds.front();
262 _freeIds.pop_front();
263 return Entity(id);
264 }
265
266 inline Entity Registry::entityFromIndex(std::size_t idx) const
267 {
268 return Entity(idx);
269 }
270
271 inline void Registry::killEntity(const Entity &e)
272 {
273 _freeIds.push_back(e._id);
274 for (auto &i : _destroyArrays) {
275 i.second(e._id);
276 }
277 }
278
279 inline void Registry::killEntity(const size_t &e)
280 {
281 _freeIds.push_back(e);
282 for (auto &i : _destroyArrays) {
283 i.second(e);
284 }
285 }
286
288 {
289 for (size_t i = 0; i < _entityCounter; i++) {
290 killEntity(i);
291 }
292 _freeIds.clear();
293 _entityCounter = 0;
294 }
295
296 template<typename Component>
297 typename SparseArray<Component>::ReferenceType Registry::addComponent(const Entity &to, Component &&c)
298 {
299 auto &components = getComponents<Component>();
300 return components.insertAt(to, std::forward<Component>(c));
301 }
302
303 template<typename Component, typename... Params>
304 typename SparseArray<Component>::ReferenceType Registry::emplaceComponent(const Entity &to, Params &&...p)
305 {
306 auto &components = getComponents<Component>();
307 return components.emplaceAt(to, std::forward<Params>(p)...);
308 }
309
310 template<typename Component>
312 {
313 auto &components = getComponents<Component>();
314 components.erase(from);
315 }
316
317 template<typename Component>
318 void Registry::removeComponent(const size_t &from)
319 {
320 auto &components = getComponents<Component>();
321 components.erase(from);
322 }
323
325 {
326 return _entityCounter - _freeIds.size();
327 }
328
329 inline size_t Registry::getEntityCounter() const
330 {
331 return _entityCounter;
332 }
333
334 // //TODO what if there is no entity alive cf view
335 // inline size_t Registry::getEntityAliveMaxIndex() const {
336 // for (long int i = static_cast<int>(_entityCounter); i >= 0; i--) {
337 // if (_freeIds.empty() || *std::max_element(_freeIds.begin(), _freeIds.end()) < i)
338 // return i;
339 // }
340 // return 0;
341 // }
342} // namespace uranus::ecs
343
344#endif // URANUS_REGISTRY_HPP
Entity class, used to identify entities.
Definition: Entity.hpp:20
size_t _id
Id of the entity.
Definition: Entity.hpp:47
Registry class, used to store and manage entities and their components.
Definition: Registry.hpp:24
size_t getEntityCounter() const
Get the counter used to generate new entity ids.
Definition: Registry.hpp:329
Entity spawnEntity()
Spawn a new entity.
Definition: Registry.hpp:257
SparseArray< Component > & registerComponent(std::function< void(const size_t &)> &)
Register a component type and it's delete function.
Definition: Registry.hpp:199
std::unordered_map< std::type_index, std::function< void(size_t const &)> > _destroyArrays
Map containing all the components delete functions.
Definition: Registry.hpp:182
SparseArray< Component >::ReferenceType emplaceComponent(const Entity &to, Params &&...p)
Emplace a component to an entity.
Definition: Registry.hpp:304
SparseArray< Component > const & getComponents() const
Get the const SparseArray of a component type.
void killAllEntities()
Destroy all entities.
Definition: Registry.hpp:287
SparseArray< Component > & getComponents()
Get the SparseArray of a component type.
Definition: Registry.hpp:242
void killEntity(const Entity &e)
Destroy an entity.
Definition: Registry.hpp:271
size_t _entityCounter
Counter used to generate new entity ids.
Definition: Registry.hpp:183
Entity entityFromIndex(std::size_t idx) const
Create an entity from an index.
Definition: Registry.hpp:266
std::unordered_map< std::type_index, std::any > _componentsArrays
Get the maximum index of an entity.
Definition: Registry.hpp:181
std::list< size_t > _freeIds
Queue containing the ids of the destroyed entities.
Definition: Registry.hpp:184
int entitiesAliveCount() const
Get the number of entities alive.
Definition: Registry.hpp:324
SparseArray< Component >::ReferenceType addComponent(const Entity &to, Component &&c)
Add a component to an entity.
Definition: Registry.hpp:297
SparseArray< Component >::ReferenceType getComponent(const Entity &e)
Get a component from an entity.
Definition: Registry.hpp:210
void removeComponent(const Entity &from)
Remove a component from an entity.
Definition: Registry.hpp:311
SparseArray class, used to store components in a sparse way.
Definition: SparseArray.hpp:22