summary refs log tree commit diff stats
path: root/src/entity_manager.h
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2015-06-18 12:14:05 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2015-06-18 12:14:05 -0400
commit55c8a14a7e2b2dadf0def3e09f970818164366f5 (patch)
treee05795e83aa61dc5b951a70328b8499d3c583ea6 /src/entity_manager.h
parent879c2c04d9c3879f871cfe79f9b25fd23c5184b4 (diff)
downloadtherapy-55c8a14a7e2b2dadf0def3e09f970818164366f5.tar.gz
therapy-55c8a14a7e2b2dadf0def3e09f970818164366f5.tar.bz2
therapy-55c8a14a7e2b2dadf0def3e09f970818164366f5.zip
Now displaying player character
Diffstat (limited to 'src/entity_manager.h')
-rw-r--r--src/entity_manager.h169
1 files changed, 21 insertions, 148 deletions
diff --git a/src/entity_manager.h b/src/entity_manager.h index 74e758c..5f0f2d4 100644 --- a/src/entity_manager.h +++ b/src/entity_manager.h
@@ -6,70 +6,31 @@
6#include <set> 6#include <set>
7#include <cassert> 7#include <cassert>
8#include "component.h" 8#include "component.h"
9#include "algorithms.h"
9 10
10class EntityManager { 11class EntityManager {
11 private: 12 private:
12 struct EntityData { 13 struct EntityData {
13 int parent = -1;
14 std::map<std::type_index, std::unique_ptr<Component>> components; 14 std::map<std::type_index, std::unique_ptr<Component>> components;
15 }; 15 };
16 16
17 std::map<int, EntityData> entities; 17 std::map<int, EntityData> entities;
18 std::map<int, std::set<int>> cachedChildren;
19 std::map<std::set<std::type_index>, std::set<int>> cachedComponents; 18 std::map<std::set<std::type_index>, std::set<int>> cachedComponents;
20 19
21 int nextEntityID = 0; 20 int nextEntityID = 0;
22 21
23 bool ensureNoParentCycles(int entity, int parent) 22 template <class T, class... R>
23 std::set<int> getEntitiesWithComponentsHelper(std::set<std::type_index>& componentTypes)
24 { 24 {
25 EntityData& data = entities[parent]; 25 componentTypes.insert(typeid(T));
26 if (data.parent == entity)
27 {
28 return false;
29 } else if (data.parent == -1)
30 {
31 return true;
32 }
33 26
34 return ensureNoParentCycles(entity, data.parent); 27 return getEntitiesWithComponents<R...>(componentTypes);
35 } 28 }
36 29
30 template <class... R>
37 std::set<int> getEntitiesWithComponents(std::set<std::type_index>& componentTypes) 31 std::set<int> getEntitiesWithComponents(std::set<std::type_index>& componentTypes)
38 { 32 {
39 if (cachedComponents.count(componentTypes) == 1) 33 return getEntitiesWithComponentsHelper<R...>(componentTypes);
40 {
41 return cachedComponents[componentTypes];
42 }
43
44 std::set<int>& cache = cachedComponents[componentTypes];
45 for (auto& entity : entities)
46 {
47 EntityData& data = entity.second;
48 bool cacheEntity = true;
49
50 for (auto& componentType : componentTypes)
51 {
52 if (data.components.count(componentType) == 0)
53 {
54 cacheEntity = false;
55 break;
56 }
57 }
58
59 if (cacheEntity)
60 {
61 cache.insert(entity.first);
62 }
63 }
64
65 return cache;
66 }
67
68 template <class T, class... R> std::set<int> getEntitiesWithComponents(std::set<std::type_index>& componentTypes)
69 {
70 componentTypes.insert(typeid(T));
71
72 return getEntitiesWithComponents<R...>(componentTypes);
73 } 34 }
74 35
75 public: 36 public:
@@ -107,26 +68,6 @@ class EntityManager {
107 { 68 {
108 assert(entities.count(entity) == 1); 69 assert(entities.count(entity) == 1);
109 70
110 EntityData& data = entities[entity];
111
112 // Destroy the children
113 std::set<int> children = getChildren(entity);
114 for (int child : children)
115 {
116 EntityData& childData = entities[child];
117 childData.parent = -1;
118
119 deleteEntity(child);
120 }
121
122 // Uncache children
123 cachedChildren.erase(entity);
124
125 if ((data.parent != -1) && (cachedChildren.count(data.parent) == 1))
126 {
127 cachedChildren[data.parent].erase(entity);
128 }
129
130 // Uncache components 71 // Uncache components
131 for (auto& cache : cachedComponents) 72 for (auto& cache : cachedComponents)
132 { 73 {
@@ -137,81 +78,8 @@ class EntityManager {
137 entities.erase(entity); 78 entities.erase(entity);
138 } 79 }
139 80
140 std::set<int> getChildren(int parent) 81 template <class T, class... Args>
141 { 82 T& emplaceComponent(int entity, Args&&... args)
142 assert(entities.count(parent) == 1);
143
144 if (cachedChildren.count(parent) == 1)
145 {
146 return cachedChildren[parent];
147 }
148
149 std::set<int>& cache = cachedChildren[parent];
150 for (auto& entity : entities)
151 {
152 EntityData& data = entity.second;
153 if (data.parent == parent)
154 {
155 cache.insert(entity.first);
156 }
157 }
158
159 return cache;
160 }
161
162 void setParent(int entity, int parent)
163 {
164 assert(entities.count(entity) == 1);
165 assert(entities.count(parent) == 1);
166 assert(ensureNoParentCycles(entity, parent));
167
168 EntityData& data = entities[entity];
169
170 // Remove from old parent
171 if (data.parent != -1)
172 {
173 if (cachedChildren.count(data.parent) == 1)
174 {
175 cachedChildren[data.parent].erase(entity);
176 }
177 }
178
179 data.parent = parent;
180
181 // Cache new parent
182 if (cachedChildren.count(parent) == 1)
183 {
184 cachedChildren[parent].insert(entity);
185 }
186 }
187
188 void setNoParent(int entity)
189 {
190 assert(entities.count(entity) == 1);
191
192 EntityData& data = entities[entity];
193
194 // Remove from old parent
195 if (data.parent != -1)
196 {
197 if (cachedChildren.count(data.parent) == 1)
198 {
199 cachedChildren[data.parent].erase(entity);
200 }
201 }
202
203 data.parent = -1;
204 }
205
206 int getParent(int entity)
207 {
208 assert(entities.count(entity) == 1);
209
210 EntityData& data = entities[entity];
211 return data.parent;
212 }
213
214 template <class T, class... Args> T& emplaceComponent(int entity, Args&&... args)
215 { 83 {
216 assert(entities.count(entity) == 1); 84 assert(entities.count(entity) == 1);
217 85
@@ -226,14 +94,15 @@ class EntityManager {
226 data.components[componentType] = std::move(ptr); 94 data.components[componentType] = std::move(ptr);
227 95
228 // Invalidate related caches 96 // Invalidate related caches
229 std::remove_if(begin(cachedComponents), end(cachedComponents), [&] (std::pair<std::set<std::type_index>, int>& cache) { 97 erase_if(cachedComponents, [&componentType] (std::pair<const std::set<std::type_index>, std::set<int>>& cache) {
230 return cache.first.count(componentType) == 1; 98 return cache.first.count(componentType) == 1;
231 }); 99 });
232 100
233 return component; 101 return component;
234 } 102 }
235 103
236 template <class T> void removeComponent(int entity) 104 template <class T>
105 void removeComponent(int entity)
237 { 106 {
238 assert(entities.count(entity) == 1); 107 assert(entities.count(entity) == 1);
239 108
@@ -255,7 +124,8 @@ class EntityManager {
255 } 124 }
256 } 125 }
257 126
258 template <class T> T& getComponent(int entity) 127 template <class T>
128 T& getComponent(int entity)
259 { 129 {
260 assert(entities.count(entity) == 1); 130 assert(entities.count(entity) == 1);
261 131
@@ -264,16 +134,19 @@ class EntityManager {
264 134
265 assert(data.components.count(componentType) == 1); 135 assert(data.components.count(componentType) == 1);
266 136
267 return *(data.components[componentType]); 137 return *((T*)data.components[componentType].get());
268 } 138 }
269 139
270 template <class T, class... R> std::set<int> getEntitiesWithComponents() 140 template <class... R>
141 std::set<int> getEntitiesWithComponents()
271 { 142 {
272 std::set<std::type_index> componentTypes; 143 std::set<std::type_index> componentTypes;
273 componentTypes.insert(typeid(T));
274 144
275 return getEntitiesWithComponents<R...>(componentTypes); 145 return getEntitiesWithComponentsHelper<R...>(componentTypes);
276 } 146 }
277}; 147};
278 148
149template <>
150std::set<int> EntityManager::getEntitiesWithComponents<>(std::set<std::type_index>& componentTypes);
151
279#endif /* end of include guard: ENTITY_MANAGER_H_C5832F11 */ 152#endif /* end of include guard: ENTITY_MANAGER_H_C5832F11 */