R-Type
Registry.hpp
Go to the documentation of this file.
1 /*
2 ** EPITECH PROJECT, 2023
3 ** R-Type
4 ** File description:
5 ** Registry
6 */
7 
8 #ifndef REGISTRY_HPP_
9 #define REGISTRY_HPP_
10 #include <any>
11 #include <functional>
12 #include <string>
13 #include <typeindex>
14 #include <utility>
15 #include <algorithm>
16 #include "Entity.hpp"
17 #include "Error.hpp"
18 #include "SparseArray.hpp"
19 
20 namespace Debug
21 {
22  class DebugMenu;
23 }
24 #ifdef DEBUG
25 #endif
26 
27 namespace GameEngine
28 {
30  class Registry
31  {
32 #ifdef DEBUG
33 #endif
34  friend class Debug::DebugMenu;
35 
36  public:
39  Registry(const std::size_t maxEntities) : _maxEntities(maxEntities){};
40 
44  template <class Component>
46  {
47  _container.insert({std::type_index(typeid(Component)), SparseArray<Component>()});
49  std::any_cast<SparseArray<Component> &>(_container[std::type_index(typeid(Component))]);
50  ret.resize(_maxEntities);
51  std::function<void(Registry &, const Entity &)> deleter = [](Registry &registry, const Entity &entity) {
52  registry.getComponent<Component>().erase(entity);
53  };
54  _deleters.push_back(deleter);
55  return ret;
56  };
60  template <class Component>
62  {
64  std::any_cast<SparseArray<Component> &>(_container[std::type_index(typeid(Component))]);
65  return ret;
66  };
70  template <class Component>
72  {
73  const SparseArray<Component> &ret =
74  std::any_cast<SparseArray<Component> &>(_container.at(std::type_index(typeid(Component))));
75  return ret;
76  };
77 
81  {
82  std::size_t id;
83 
84  if (!_emptyIndexes.empty()) {
85  id = _emptyIndexes.front();
86  _emptyIndexes.erase(_emptyIndexes.begin());
87  return Entity(id);
88  }
89  if (_nbEntities > _maxEntities)
91  id = _nbEntities;
92  _nbEntities++;
93  return Entity(id);
94  };
98  Entity spawnEntity(const std::size_t &id)
99  {
100  if (id > _maxEntities)
102  if (!_emptyIndexes.empty()) {
103  auto it = std::lower_bound(_emptyIndexes.begin(), _emptyIndexes.end(), id);
104  if (it != _emptyIndexes.end())
105  _emptyIndexes.erase(it);
106  return Entity(id);
107  }
108  for (; _nbEntities != id; _nbEntities++)
109  _emptyIndexes.push_back(_nbEntities);
110  std::sort(_emptyIndexes.begin(), _emptyIndexes.end());
111  _nbEntities++;
112  return Entity(id);
113  };
117  Entity getEntityById(const std::size_t &id) const
118  {
119  if (id > _nbEntities || id > _maxEntities)
121  if (std::binary_search(_emptyIndexes.begin(), _emptyIndexes.end(), id))
123  return Entity(id);
124  };
127  void killEntity(const Entity &entity)
128  {
129  _emptyIndexes.push_back(entity);
130  std::sort(_emptyIndexes.begin(), _emptyIndexes.end());
131  for (std::size_t i = 0; i < _deleters.size(); i++)
132  _deleters[i](*this, entity);
133  };
134 
140  template <typename Component>
141  typename SparseArray<Component>::referenceType addComponent(const Entity &entity, Component &&component)
142  {
143  return getComponent<Component>().insert_at(entity, component);
144  };
150  template <typename Component>
151  typename SparseArray<Component>::referenceType addComponent(const Entity &entity, const Component &component)
152  {
153  return getComponent<Component>().insert_at(entity, component);
154  };
161  template <typename Component, typename... Params>
162  typename SparseArray<Component>::referenceType emplaceComponent(const Entity &entity, Params &&...params)
163  {
164  return getComponent<Component>().emplace_at(entity, params...);
165  };
169  template <typename Component>
170  void removeComponent(const Entity &entity)
171  {
172  getComponent<Component>().erase(entity);
173  };
177  template <typename Component>
179  {
180  if (_container.find(std::type_index(typeid(Component))) != _container.end())
181  return true;
182  return false;
183  };
184 
190  template <typename Function, class... Components>
191  void addSystem(const Function &function)
192  {
193  std::function<void()> system = [this, function]() { function(getComponent<Components>()...); };
194 
195  _systems.push_back(system);
196  };
202  template <typename SystemClass, class... Components>
203  void addSystem(std::shared_ptr<SystemClass> systemClass)
204  {
205  std::function<void()> system = [this, systemClass]() mutable {
206  (*systemClass)(getComponent<Components>()...);
207  };
208 
209  _systems.push_back(system);
210  };
212  void runSystems()
213  {
214  for (std::size_t i = 0; i < _systems.size(); i++)
215  _systems[i]();
216  }
217 
218  private:
220  std::unordered_map<std::type_index, std::any> _container;
222  std::vector<std::function<void(Registry &, const Entity &)>> _deleters;
224  std::vector<std::function<void()>> _systems;
226  std::vector<std::size_t> _emptyIndexes;
228  std::size_t _maxEntities;
230  std::size_t _nbEntities = 0;
231  };
232 } // namespace GameEngine
233 
234 #endif /* !REGISTRY_HPP_ */
TooMuchEntitiesError Class Error Error thrown when exceeding the maximum number of entities.
Definition: Error.hpp:69
TooMuchEntitiesError Class Error Error thrown when exceeding the maximum number of entities.
Definition: Error.hpp:53
Entity class for the game engine.
Definition: Entity.hpp:18
Entity component system, handling entities, components and systems.
Definition: Registry.hpp:31
void runSystems()
Runs all the registered system functions. Need to be called in the main loop.
Definition: Registry.hpp:212
Entity spawnEntity()
Spawns a new entity. Entities can't be spawned otherwise.
Definition: Registry.hpp:80
bool isComponentRegistered()
tells if a component is registered
Definition: Registry.hpp:178
Registry(const std::size_t maxEntities)
Constructor.
Definition: Registry.hpp:39
Entity spawnEntity(const std::size_t &id)
Spawns a new entity. Entities can't be spawned otherwise.
Definition: Registry.hpp:98
Entity getEntityById(const std::size_t &id) const
Getter for an entity at a given index. Will throw an error if the entity hasn't been spawned.
Definition: Registry.hpp:117
SparseArray< Component > & registerComponent()
Register a new component to the registry.
Definition: Registry.hpp:45
friend class Debug::DebugMenu
Definition: Registry.hpp:34
void addSystem(std::shared_ptr< SystemClass > systemClass)
Adds a system to the registry. This method is to use when the class system needs to stay at the same ...
Definition: Registry.hpp:203
void killEntity(const Entity &entity)
Kills the entity given, it destroys all the components to this entity.
Definition: Registry.hpp:127
void removeComponent(const Entity &entity)
Removes a component to the specified entity.
Definition: Registry.hpp:170
SparseArray< Component >::referenceType emplaceComponent(const Entity &entity, Params &&...params)
Emplace the component type to the entities given.
Definition: Registry.hpp:162
SparseArray< Component > & getComponent()
Getter to a speecific component's SparseArray.
Definition: Registry.hpp:61
const SparseArray< Component > & getComponent() const
Getter to a speecific component's SparseArray.
Definition: Registry.hpp:71
SparseArray< Component >::referenceType addComponent(const Entity &entity, const Component &component)
Add a component to the entity given.
Definition: Registry.hpp:151
SparseArray< Component >::referenceType addComponent(const Entity &entity, Component &&component)
Add a component to the entity given.
Definition: Registry.hpp:141
void addSystem(const Function &function)
Adds a system to the registry. The system function can take reference to some component's SparseArray...
Definition: Registry.hpp:191
Array which can have empty indexes.
Definition: SparseArray.hpp:19
valueType & referenceType
Reference to valueType.
Definition: SparseArray.hpp:24
void resize(const std::size_t &count)
Resize the array.
Definition: SparseArray.hpp:164
Definition: Registry.hpp:21
Definition: AssetManager.hpp:15