diff options
Diffstat (limited to 'src/entity_manager.h')
-rw-r--r-- | src/entity_manager.h | 64 |
1 files changed, 32 insertions, 32 deletions
diff --git a/src/entity_manager.h b/src/entity_manager.h index 5f0f2d4..a36d720 100644 --- a/src/entity_manager.h +++ b/src/entity_manager.h | |||
@@ -13,30 +13,30 @@ class EntityManager { | |||
13 | struct EntityData { | 13 | struct EntityData { |
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<std::set<std::type_index>, std::set<int>> cachedComponents; | 18 | std::map<std::set<std::type_index>, std::set<int>> cachedComponents; |
19 | 19 | ||
20 | int nextEntityID = 0; | 20 | int nextEntityID = 0; |
21 | 21 | ||
22 | template <class T, class... R> | 22 | template <class T, class... R> |
23 | std::set<int> getEntitiesWithComponentsHelper(std::set<std::type_index>& componentTypes) | 23 | std::set<int> getEntitiesWithComponentsHelper(std::set<std::type_index>& componentTypes) |
24 | { | 24 | { |
25 | componentTypes.insert(typeid(T)); | 25 | componentTypes.insert(typeid(T)); |
26 | 26 | ||
27 | return getEntitiesWithComponents<R...>(componentTypes); | 27 | return getEntitiesWithComponents<R...>(componentTypes); |
28 | } | 28 | } |
29 | 29 | ||
30 | template <class... R> | 30 | template <class... R> |
31 | std::set<int> getEntitiesWithComponents(std::set<std::type_index>& componentTypes) | 31 | std::set<int> getEntitiesWithComponents(std::set<std::type_index>& componentTypes) |
32 | { | 32 | { |
33 | return getEntitiesWithComponentsHelper<R...>(componentTypes); | 33 | return getEntitiesWithComponentsHelper<R...>(componentTypes); |
34 | } | 34 | } |
35 | 35 | ||
36 | public: | 36 | public: |
37 | EntityManager() = default; | 37 | EntityManager() = default; |
38 | EntityManager(const EntityManager& copy) = delete; | 38 | EntityManager(const EntityManager& copy) = delete; |
39 | 39 | ||
40 | int emplaceEntity() | 40 | int emplaceEntity() |
41 | { | 41 | { |
42 | // Find a suitable entity ID | 42 | // Find a suitable entity ID |
@@ -44,76 +44,76 @@ class EntityManager { | |||
44 | { | 44 | { |
45 | nextEntityID++; | 45 | nextEntityID++; |
46 | } | 46 | } |
47 | 47 | ||
48 | if (nextEntityID < 0) | 48 | if (nextEntityID < 0) |
49 | { | 49 | { |
50 | nextEntityID = 0; | 50 | nextEntityID = 0; |
51 | 51 | ||
52 | while ((entities.count(nextEntityID) == 1) && (nextEntityID >= 0)) | 52 | while ((entities.count(nextEntityID) == 1) && (nextEntityID >= 0)) |
53 | { | 53 | { |
54 | nextEntityID++; | 54 | nextEntityID++; |
55 | } | 55 | } |
56 | 56 | ||
57 | assert(nextEntityID >= 0); | 57 | assert(nextEntityID >= 0); |
58 | } | 58 | } |
59 | 59 | ||
60 | // Initialize the data | 60 | // Initialize the data |
61 | int id = nextEntityID++; | 61 | int id = nextEntityID++; |
62 | entities[id]; | 62 | entities[id]; |
63 | 63 | ||
64 | return id; | 64 | return id; |
65 | } | 65 | } |
66 | 66 | ||
67 | void deleteEntity(int entity) | 67 | void deleteEntity(int entity) |
68 | { | 68 | { |
69 | assert(entities.count(entity) == 1); | 69 | assert(entities.count(entity) == 1); |
70 | 70 | ||
71 | // Uncache components | 71 | // Uncache components |
72 | for (auto& cache : cachedComponents) | 72 | for (auto& cache : cachedComponents) |
73 | { | 73 | { |
74 | cache.second.erase(entity); | 74 | cache.second.erase(entity); |
75 | } | 75 | } |
76 | 76 | ||
77 | // Destroy the data | 77 | // Destroy the data |
78 | entities.erase(entity); | 78 | entities.erase(entity); |
79 | } | 79 | } |
80 | 80 | ||
81 | template <class T, class... Args> | 81 | template <class T, class... Args> |
82 | T& emplaceComponent(int entity, Args&&... args) | 82 | T& emplaceComponent(int entity, Args&&... args) |
83 | { | 83 | { |
84 | assert(entities.count(entity) == 1); | 84 | assert(entities.count(entity) == 1); |
85 | 85 | ||
86 | EntityData& data = entities[entity]; | 86 | EntityData& data = entities[entity]; |
87 | std::type_index componentType = typeid(T); | 87 | std::type_index componentType = typeid(T); |
88 | 88 | ||
89 | assert(data.components.count(componentType) == 0); | 89 | assert(data.components.count(componentType) == 0); |
90 | 90 | ||
91 | // Initialize the component | 91 | // Initialize the component |
92 | std::unique_ptr<T> ptr = std::unique_ptr<T>(new T(std::forward<Args>(args)...)); | 92 | std::unique_ptr<T> ptr = std::unique_ptr<T>(new T(std::forward<Args>(args)...)); |
93 | T& component = *ptr; | 93 | T& component = *ptr; |
94 | data.components[componentType] = std::move(ptr); | 94 | data.components[componentType] = std::move(ptr); |
95 | 95 | ||
96 | // Invalidate related caches | 96 | // Invalidate related caches |
97 | erase_if(cachedComponents, [&componentType] (std::pair<const std::set<std::type_index>, std::set<int>>& cache) { | 97 | erase_if(cachedComponents, [&componentType] (std::pair<const std::set<std::type_index>, std::set<int>>& cache) { |
98 | return cache.first.count(componentType) == 1; | 98 | return cache.first.count(componentType) == 1; |
99 | }); | 99 | }); |
100 | 100 | ||
101 | return component; | 101 | return component; |
102 | } | 102 | } |
103 | 103 | ||
104 | template <class T> | 104 | template <class T> |
105 | void removeComponent(int entity) | 105 | void removeComponent(int entity) |
106 | { | 106 | { |
107 | assert(entities.count(entity) == 1); | 107 | assert(entities.count(entity) == 1); |
108 | 108 | ||
109 | EntityData& data = entities[entity]; | 109 | EntityData& data = entities[entity]; |
110 | std::type_index componentType = typeid(T); | 110 | std::type_index componentType = typeid(T); |
111 | 111 | ||
112 | assert(data.components.count(componentType) == 1); | 112 | assert(data.components.count(componentType) == 1); |
113 | 113 | ||
114 | // Destroy the component | 114 | // Destroy the component |
115 | data.components.erase(componentType); | 115 | data.components.erase(componentType); |
116 | 116 | ||
117 | // Uncache the component | 117 | // Uncache the component |
118 | for (auto& cache : cachedComponents) | 118 | for (auto& cache : cachedComponents) |
119 | { | 119 | { |
@@ -123,25 +123,25 @@ class EntityManager { | |||
123 | } | 123 | } |
124 | } | 124 | } |
125 | } | 125 | } |
126 | 126 | ||
127 | template <class T> | 127 | template <class T> |
128 | T& getComponent(int entity) | 128 | T& getComponent(int entity) |
129 | { | 129 | { |
130 | assert(entities.count(entity) == 1); | 130 | assert(entities.count(entity) == 1); |
131 | 131 | ||
132 | EntityData& data = entities[entity]; | 132 | EntityData& data = entities[entity]; |
133 | std::type_index componentType = typeid(T); | 133 | std::type_index componentType = typeid(T); |
134 | 134 | ||
135 | assert(data.components.count(componentType) == 1); | 135 | assert(data.components.count(componentType) == 1); |
136 | 136 | ||
137 | return *((T*)data.components[componentType].get()); | 137 | return *((T*)data.components[componentType].get()); |
138 | } | 138 | } |
139 | 139 | ||
140 | template <class... R> | 140 | template <class... R> |
141 | std::set<int> getEntitiesWithComponents() | 141 | std::set<int> getEntitiesWithComponents() |
142 | { | 142 | { |
143 | std::set<std::type_index> componentTypes; | 143 | std::set<std::type_index> componentTypes; |
144 | 144 | ||
145 | return getEntitiesWithComponentsHelper<R...>(componentTypes); | 145 | return getEntitiesWithComponentsHelper<R...>(componentTypes); |
146 | } | 146 | } |
147 | }; | 147 | }; |