Shkyera Engine
Easy to use, game engine for Python
Loading...
Searching...
No Matches
Registry.hpp
Go to the documentation of this file.
1
7#pragma once
8
9#include <memory>
10#include <typeindex>
11#include <unordered_set>
12
13#include <Common/Assert.hpp>
14#include <Common/Logger.hpp>
15#include <Common/Types.hpp>
16#include <ECS/Entity.hpp>
20#include <ECS/SparseSet.hpp>
21
22namespace shkyera {
23
28class Registry {
29 public:
33 Registry() = default;
34
38 ~Registry() = default;
39
40 Registry(const Registry& other);
41
43
50
57
66 template <typename Component, typename... Args>
69 if constexpr (std::is_base_of_v<SingletonComponent<Component>, Component>) {
70 if (componentSet.contains(entity)) {
71 Logger::ERROR(std::string("Cannot add a Singleton Component (") + typeid(Component).name() +
72 "), because another entity already has it.");
73 return componentSet.get(entity);
74 }
75 }
76 componentSet.add(entity, Component(std::forward<Args>(args)...));
77 return componentSet.get(entity);
78 }
79
80 template <typename Component>
85
86 template <typename Component, typename... Args>
88 static_assert(std::is_base_of_v<SingletonComponent<Component>, Component>,
89 "Component assignment is only possible for Singleton Components.");
90
92 componentSet.clear();
93 return addComponent<Component>(entity, std::forward<Args>(args)...);
94 }
95
102 template <typename Component>
104 static_assert(!std::is_base_of_v<SingletonComponent<Component>, Component>,
105 "Component removal is only possible for non-Singleton Components.");
107 }
108
116 template <typename Component>
119 }
120
128 template <typename... Components>
130 return (... && (hasComponent<Components>(entity)));
131 }
132
140 template <typename Component>
144
152 template <typename Component>
156
163 template <typename Component>
167
174 template <typename Component>
178
179 template <typename Component>
180 std::vector<Component>& getComponents() {
181 return getOrCreateComponentSet<Component>().getComponents();
182 }
183
184 template <typename Component>
185 const std::vector<Component>& getComponents() const {
186 return getOrCreateComponentSet<Component>().getComponents();
187 }
188
189 template <typename Component>
190 std::optional<Entity> getEntity() const {
191 static_assert(std::is_base_of_v<SingletonComponent<Component>, Component>,
192 "Obtaining an Entity of a Component is only possible for SingletonComponents");
194 if (!singletonComponentSet.empty()) {
195 return (*singletonComponentSet.begin()).first;
196 }
197 return std::nullopt;
198 }
199
200 template <typename Component>
202 static_assert(std::is_base_of_v<SingletonComponent<Component>, Component>,
203 "Obtaining a Component is only possible for SingletonComponents");
204 if (const auto entityOpt = getEntity<Component>()) {
206 }
207 return nullptr;
208 }
209
211
212 const EntityHierarchy& getHierarchy() const;
213
214 private:
215 using ParentAndChild = std::pair<Entity, Entity>;
216
223 template <typename Component>
225 const auto typeId = typeid(Component).hash_code();
226 if (_componentSets.find(typeId) == _componentSets.end()) {
227 _componentSets[typeId] = std::make_unique<SparseSet<Component>>();
228 }
229 return *static_cast<SparseSet<Component>*>(_componentSets.at(typeId).get());
230 }
231
238 template <typename Component>
240 const auto typeId = typeid(Component).hash_code();
241 if (_componentSets.find(typeId) == _componentSets.end()) {
242 _componentSets[typeId] = std::make_unique<SparseSet<Component>>();
243 }
244 return *static_cast<SparseSet<Component>*>(_componentSets.at(typeId).get());
245 }
246
247 mutable std::unordered_map<size_t, std::unique_ptr<SparseSetBase>>
248 _componentSets; //< Map of component sets by type ID.
249 EntityProvider _entityProvider; //< Manages the creation and management of entities.
250 EntityHierarchy _entityHierarchy; //< Maintains the parent-child relationships between the entities
251};
252
253} // namespace shkyera
Manages a pool of unused entity identifiers and provides mechanisms for requesting and removing them.
Definition EntityHierarchy.hpp:20
Definition EntityProvider.hpp:19
Definition Registry.hpp:28
std::optional< Entity > getEntity() const
Definition Registry.hpp:190
Registry & operator=(const Registry &other)
Definition Registry.cpp:14
std::vector< Component > & getComponents()
Definition Registry.hpp:180
EntityProvider _entityProvider
Definition Registry.hpp:249
Registry()=default
const Component & getComponent(Entity entity) const
Definition Registry.hpp:153
Component & addComponent(Entity entity, Args &&... args)
Definition Registry.hpp:67
SparseSet< Component > & getOrCreateComponentSet()
Definition Registry.hpp:224
void removeEntity(Entity entity)
Definition Registry.cpp:32
Component * getComponent()
Definition Registry.hpp:201
void clearComponents()
Definition Registry.hpp:81
void removeComponent(Entity entity)
Definition Registry.hpp:103
SparseSet< Component > & getComponentSet()
Definition Registry.hpp:164
const SparseSet< Component > & getOrCreateComponentSet() const
Definition Registry.hpp:239
EntityHierarchy & getHierarchy()
Definition Registry.cpp:38
std::pair< Entity, Entity > ParentAndChild
Definition Registry.hpp:215
const SparseSet< Component > & getComponentSet() const
Definition Registry.hpp:175
bool hasComponent(Entity entity) const
Definition Registry.hpp:117
bool hasComponents(Entity entity) const
Definition Registry.hpp:129
const std::vector< Component > & getComponents() const
Definition Registry.hpp:185
std::unordered_map< size_t, std::unique_ptr< SparseSetBase > > _componentSets
Definition Registry.hpp:248
EntityHierarchy _entityHierarchy
Definition Registry.hpp:250
Component & getComponent(Entity entity)
Definition Registry.hpp:141
Entity addEntity()
Definition Registry.cpp:28
Component & assignComponent(Entity entity, Args &&... args)
Definition Registry.hpp:87
~Registry()=default
Definition Asset.hpp:6
uint32_t Entity
Definition Entity.hpp:7
Definition Clock.hpp:9