CG-Project2
Loading...
Searching...
No Matches
EntityManager.hpp
1#pragma once
2
3#include "../../../Opengl-Core/include/Core.hpp"
4#include "Component.hpp"
5
6#include <algorithm>
7#include <map>
8#include <memory>
9#include <string>
10#include <utility>
11#include <vector>
12
21class EntityManager {
22public:
23 using Index = unsigned int;
24
30 inline Index createEntity() {
31 auto id = this->m_currentId;
32 this->m_currentId++;
33
34 this->m_entities.emplace(id, "Entity " + std::to_string(id));
35 this->m_ettComponent.emplace(id, std::vector<Shared<Component>>{});
36
37 return id;
38 }
39
43 inline void resetIndex() {
44 this->m_currentId = 0;
45 }
46
52 inline std::vector<Index> getEntities() const {
53 std::vector<Index> res{};
54 for (auto [id, _] : this->m_ettComponent) {
55 res.push_back(id);
56 }
57 return res;
58 }
59
66 inline std::string getEntityName(const Index &id) const { return this->m_entities.at(id); }
67
73 inline void setEntityName(const Index &id, const std::string &name) { this->m_entities.at(id) = std::move(name); }
74
83 inline bool removeEntity(const Index &id) {
84 bool removed = this->m_entities.erase(id);
85 for (auto c : this->m_ettComponent.at(id)) {
86 c.reset();
87 }
88 this->m_ettComponent.erase(id);
89 for (auto it = this->m_compEntity.begin(); it != this->m_compEntity.end();) {
90 auto &ids = it->second;
91 ids.erase(std::remove(ALL(ids), id), ids.end());
92
93 if (ids.empty())
94 it = this->m_compEntity.erase(it);
95 else
96 ++it;
97 }
98
99 return removed;
100 }
101
108 inline bool isEntityValid(const Index &id) { return this->m_ettComponent.count(id); }
109
115 unsigned int getEntitiesCount() const { return this->m_entities.size(); }
116
128 template <typename T, typename... Args>
129 inline Shared<T> addComponent(const Index &id, Args &&...args) {
130 if (!this->isEntityValid(id))
131 return nullptr;
132
133 auto comp = CreateShared<T>(std::forward<Args>(args)...);
134 this->m_ettComponent.at(id).emplace_back(comp);
135
136 auto name = CLASSNAME(T);
137 if (this->m_compEntity.count(name)) {
138 this->m_compEntity.at(name).push_back(id);
139 } else {
140 this->m_compEntity.emplace(name, std::vector<Index>{});
141 this->m_compEntity.at(name).push_back(id);
142 }
143 return comp;
144 }
145
154 template <typename T>
155 inline bool removeComponent(const Index &id) {
156 if (!this->entityHasComponent<T>(id))
157 return false;
158
159 this->m_compEntity.at(CLASSNAME(T)).erase(std::find(ALL(this->m_compEntity.at(CLASSNAME(T))), id));
160 auto c = this->getComponentFromId<T>(id);
161 if (c != nullptr)
162 this->m_ettComponent.at(id).erase(std::find(ALL(this->m_ettComponent.at(id)), c));
163 return this->entityHasComponent<T>(id);
164 }
165
173 template <typename T>
174 inline bool entityHasComponent(const Index &id) {
175 return this->m_compEntity.count(CLASSNAME(T)) > 0 &&
176 std::find(ALL(this->m_compEntity.at(CLASSNAME(T))), id) != this->m_compEntity.at(CLASSNAME(T)).end();
177 }
178
186 template <typename T>
187 inline std::vector<Index> getEntitiesFromComponent() const {
188 if (!this->m_compEntity.count(CLASSNAME(T)))
189 return {};
190
191 return this->m_compEntity.at(CLASSNAME(T));
192 }
193
202 template <typename T>
203 inline Shared<T> getComponentFromId(const Index &id) {
204 if (!this->m_compEntity.count(CLASSNAME(T)))
205 return nullptr;
206
207 // the entity with id hasn't this component.
208 if (std::find(ALL(this->m_compEntity.at(CLASSNAME(T))), id) == this->m_compEntity.at(CLASSNAME(T)).end()) {
209 // std::cerr << "The entity with id (" << id << ") doesn't have this component (" << CLASSNAME(T) << ").\n";
210 return nullptr;
211 }
212
213 // finds T component by using dynamic cast.
214 return std::dynamic_pointer_cast<T>(*std::find_if(ALL(this->m_ettComponent.at(id)), [](auto e) {
215 return std::dynamic_pointer_cast<T>(e) != nullptr;
216 }));
217 }
218
219 EntityManager(EntityManager &other) = delete;
220
221 void operator=(const EntityManager &other) = delete;
222
229 inline static Shared<EntityManager> instance() {
230 if (s_pointer == nullptr) {
231 Shared<EntityManager> copy(new EntityManager());
232 copy.swap(s_pointer);
233 }
234 return s_pointer;
235 }
236
237private:
239 Index m_currentId = 0;
240
242 std::map<Index, std::string> m_entities{};
244 std::map<Index, std::vector<Shared<Component>>> m_ettComponent{};
246 std::map<std::string, std::vector<Index>> m_compEntity{};
247
249 inline static Shared<EntityManager> s_pointer = nullptr;
250
252 EntityManager() = default;
253};
254
255#include "../../../Opengl-Core/include/Core.hpp"
This class manages all the entities and the components instanced.
Definition EntityManager.hpp:21
Shared< T > addComponent(const Index &id, Args &&...args)
Adds a component to the given entity. It instances a shared pointer of that component and calls the c...
Definition EntityManager.hpp:129
bool removeEntity(const Index &id)
Removes the entity given from the ECS.
Definition EntityManager.hpp:83
void resetIndex()
Reset the ECS id, it is usually used when entities are cleaned.
Definition EntityManager.hpp:43
void setEntityName(const Index &id, const std::string &name)
Sets the name of the entity given.
Definition EntityManager.hpp:73
Shared< T > getComponentFromId(const Index &id)
Retrieves a shared pointer to the component of an entity.
Definition EntityManager.hpp:203
std::vector< Index > getEntitiesFromComponent() const
Retrieves all the entities that have the given component.
Definition EntityManager.hpp:187
bool entityHasComponent(const Index &id)
Checks if the given entity has the component.
Definition EntityManager.hpp:174
std::vector< Index > getEntities() const
Retrieves a vector containing all entities in the ECS.
Definition EntityManager.hpp:52
std::string getEntityName(const Index &id) const
Retrieves the entity name.
Definition EntityManager.hpp:66
static Shared< EntityManager > instance()
Retrieves the instance of the EntityManager. If it's not instanced, it will be instanced automaticall...
Definition EntityManager.hpp:229
bool removeComponent(const Index &id)
Removes a component from the given entity.
Definition EntityManager.hpp:155
unsigned int getEntitiesCount() const
Retrieves the number of entities in the ECS.
Definition EntityManager.hpp:115
Index createEntity()
Create an entity and increment the current index.
Definition EntityManager.hpp:30
bool isEntityValid(const Index &id)
Checks if the entity given has components.
Definition EntityManager.hpp:108