SDEngine
Game Engine
Loading...
Searching...
No Matches
EntityManager.inl
Go to the documentation of this file.
1#pragma once
2
3template<typename ExtraComponents, typename... Components>
5 m_manager(manager) {
6 USize min_size = std::numeric_limits<USize>::max();
8}
9
10template<typename ExtraComponents, typename... Components>
12 const ArenaVec<Entity>* dense_entities,
13 USize idx) :
14 manager(em), entities(dense_entities), index(idx) {
15 if (entities && index < entities->count && !is_valid())
16 next();
17}
18
19template<typename ExtraComponents, typename... Components>
25
26template<typename ExtraComponents, typename... Components>
27std::tuple<Entity, Components&...>
29 Entity current_entity = (*entities)[index];
30 return std::tuple_cat(std::make_tuple(current_entity),
32}
33
34template<typename ExtraComponents, typename... Components>
36 if (!entities)
37 return;
38 do {
39 index++;
40 } while (index < entities->count && !is_valid());
41}
42
43template<typename ExtraComponents, typename... Components>
45 if (!entities)
46 return false;
47 Entity current_entity = (*entities)[index];
48 return (manager.template has_component<Components>(current_entity) && ...);
49}
50
51template<typename ExtraComponents, typename... Components>
52typename ViewImpl<ExtraComponents, Components...>::Iterator
54 if (!m_smallest_pool) {
55 log::engine::warn(
56 "View has no valid component pools - scene may be empty or missing components");
57 return end();
58 }
60}
61
62template<typename ExtraComponents, typename... Components>
63typename ViewImpl<ExtraComponents, Components...>::Iterator
69
70template<typename ExtraComponents, typename... Components>
71template<typename Component>
74 minSize = 0;
75 m_smallest_pool = nullptr;
76 return;
77 }
78
79 auto* pool = m_manager.template get_component_pool<Component>();
80 if (pool->size() < minSize) {
81 minSize = pool->size();
82 m_smallest_pool = &pool->get_dense_entities();
83 }
84}
85
86template<typename ExtraComponents>
87template<typename T, typename... Args>
90 "Error: Component type is not registered, register it");
91 const USize type_id = component_info<T>::id();
93 while (m_component_pools.count <= type_id)
94 m_component_pools.push(m_pool_arena, ComponentPoolNode{});
95
96 auto& node = m_component_pools[type_id];
97 if (!node.pool) {
98 auto* pool = m_pool_arena->push_array<SparseEntitySet<T>>(1);
99 pool->arena = m_pool_arena;
100 node.pool = pool;
101 node.remove_fn = [](void* p, Entity e) -> bool {
102 return static_cast<SparseEntitySet<T>*>(p)->remove(e);
103 };
104 node.serialize_fn = [](void* p, Serializer& s) {
105 static_cast<SparseEntitySet<T>*>(p)->serialize(s);
106 };
107 node.deserialize_fn = [](void* p, Serializer& s) {
108 static_cast<SparseEntitySet<T>*>(p)->deserialize(s);
109 };
110 }
111
112 auto* pool = static_cast<SparseEntitySet<T>*>(node.pool);
113 if (m_entity_masks.get(e)->test(type_id))
114 log::engine::warn("Overwriting already existing component: {}, id: {} ",
115 component_info<T>::name,
116 type_id);
117
118 m_entity_masks.get(e)->set(type_id);
119 pool->add(e, std::forward<Args>(args)...);
120 return pool->get(e);
121}
122
123template<typename ExtraComponents>
124template<typename T>
127 "Error: Component type is not registered, register it");
128
129 USize type_id = component_info<T>::id();
130 if (type_id >= m_component_pools.count || !m_component_pools[type_id].pool ||
131 !m_entity_masks.get(e)->test(type_id))
132 return nullptr;
133
134 auto* pool = static_cast<SparseEntitySet<T>*>(m_component_pools[type_id].pool);
135 return pool->get(e);
136}
137
138template<typename ExtraComponents>
139template<typename T>
142 assert(has_component<T>(e) && "Entity doesnt have component");
143
144 auto* pool = static_cast<SparseEntitySet<T>*>(m_component_pools[typeId].pool);
145 return *pool->get(e);
146}
147
148template<typename ExtraComponents>
149template<typename T>
152 assert(has_component<T>(e) && "Entity doesnt have component");
153
154 auto* pool = static_cast<const SparseEntitySet<T>*>(m_component_pools[type_id].pool);
155 return *pool->get(e);
156}
157
158template<typename ExtraComponents>
159template<typename T>
162 "Error: Can't remove component type that isn't registered");
163
164 USize type_id = component_info<T>::id();
165 if (type_id >= m_component_pools.count || !m_component_pools[type_id].pool ||
166 !m_entity_masks.get(e)->test(type_id))
167 return false;
168
169 auto* pool = static_cast<SparseEntitySet<T>*>(m_component_pools[type_id].pool);
170 pool->remove(e);
171 m_entity_masks.get(e)->reset(type_id);
172 return true;
173}
174
175template<typename ExtraComponents>
176template<typename... Args>
178 if constexpr (sizeof...(Args) == 1) {
179 using T = std::tuple_element_t<0, std::tuple<Args...>>;
180 if constexpr (UnpackGroup<T>::is_group) {
181 return typename UnpackGroup<T>::type(*this);
182 } else {
183 return ViewImpl<ExtraComponents, T>(*this);
184 }
185 } else {
186 return ViewImpl<ExtraComponents, Args...>(*this);
187 }
188}
189
190template<typename ExtraComponents>
191template<typename T>
193 if (e.index >= m_entity_masks.get_dense_entities().count)
194 return false;
195 if (!is_alive(e))
196 return false;
197 auto mask = m_entity_masks.get(e);
198 return mask && mask->test(component_info<T>::id());
199}
200
201template<typename ExtraComponents>
202template<typename... Components>
204 return std::forward_as_tuple(get_component<Components>(e)...);
205}
206
207template<typename ExtraComponents>
208template<typename... Components>
209std::tuple<const Components&...>
213
214template<typename ExtraComponents>
215template<typename T>
217 static_assert(component_info<T>::is_registered != false, "Unregistered Component");
218 const USize type_id = component_info<T>::id();
219 if (type_id >= m_component_pools.count || !m_component_pools[type_id].pool)
220 return nullptr;
221
222 return static_cast<SparseEntitySet<T>*>(m_component_pools[type_id].pool);
223}
224
225template<typename ExtraComponents>
226template<typename T>
228 static_assert(component_info<T>::is_registered != false, "Unregistered Component");
229 const USize type_id = component_info<T>::id();
230 return type_id < m_component_pools.count && m_component_pools[type_id].pool;
231}
232
233template<typename ExtraComponents>
235 const uint32_t idx =
236 m_free_list.count == 0 ? static_cast<U32>(m_generations.count) + 1 : pop_free_list();
237
238 if (idx >= m_generations.count)
239 m_generations.push(m_pool_arena, 0);
240
241 Entity e = {idx, m_generations[idx]};
242
243 m_entity_masks.arena = m_pool_arena;
244 m_entity_masks.add(e, ComponentMask{});
245 return e;
246}
247
248template<typename ExtraComponents>
250 if (!is_alive(e))
251 return;
252
253 ComponentMask* mask = m_entity_masks.get(e);
254 assert(mask);
255
256 for (U64 i = 0; i < m_component_pools.count; ++i) {
257 auto& node = m_component_pools[i];
258 if (node.pool && mask->test(i))
259 node.remove_fn(node.pool, e);
260 }
261 mask->reset();
262 m_generations[e.index]++;
263 m_free_list.push(m_pool_arena, e.index);
264}
265
266template<typename ExtraComponents>
268 return e.index < m_generations.count && m_generations[e.index] == e.generation;
269}
270
271template<typename ExtraComponents>
273 const auto idx = m_free_list[m_free_list.count - 1];
274 m_free_list.count--;
275 return idx;
276}
277
278template<typename ExtraComponents>
280 s.write(static_cast<U32>(m_generations.count));
281 for (U64 i = 0; i < m_generations.count; ++i)
282 s.write(m_generations[i]);
283
284 s.write(static_cast<U32>(m_free_list.count));
285 for (U64 i = 0; i < m_free_list.count; ++i)
286 s.write(m_free_list[i]);
287
288 const auto& mask_entities = m_entity_masks.get_dense_entities();
289 U32 aliveCount = 0;
290 for (U64 i = 0; i < mask_entities.count; ++i) {
291 if (is_alive(mask_entities[i]))
292 aliveCount++;
293 }
294 s.write(aliveCount);
295
296 for (U64 i = 0; i < mask_entities.count; ++i) {
298 if (!is_alive(e))
299 continue;
300
301 s.write(e.index);
302 s.write(e.generation);
303 const ComponentMask* mask = m_entity_masks.get(e);
304 if (mask) {
305 for (USize word = 0; word < 4; ++word) {
306 U64 packed = 0;
307 for (USize bit = 0; bit < 64; ++bit) {
308 if (mask->test(word * 64 + bit))
309 packed |= (U64(1) << bit);
310 }
311 s.write(packed);
312 }
313 } else {
314 for (USize i = 0; i < 4; ++i)
315 s.write(static_cast<U64>(0));
316 }
317 }
318
320 for (U64 i = 0; i < m_component_pools.count; ++i) {
321 if (m_component_pools[i].pool && sd::ComponentFactory::is_registered(i))
323 }
324 s.write(serializable_count);
325
326 for (U64 i = 0; i < m_component_pools.count; ++i) {
327 if (m_component_pools[i].pool && sd::ComponentFactory::is_registered(i)) {
328 s.write(static_cast<U32>(i));
329 m_component_pools[i].serialize_fn(m_component_pools[i].pool, s);
330 }
331 }
332}
333
334template<typename ExtraComponents>
336 {
337 U32 count = s.read<U32>();
338 for (U32 i = 0; i < count; ++i)
339 m_generations.push(m_pool_arena, s.read<U32>());
340 }
341
342 {
343 U32 count = s.read<U32>();
344 for (U32 i = 0; i < count; ++i)
345 m_free_list.push(m_pool_arena, s.read<U32>());
346 }
347
348 U32 maskCount = s.read<U32>();
349 m_entity_masks.arena = m_pool_arena;
350 for (U32 i = 0; i < maskCount; ++i) {
351 U32 index = s.read<U32>();
352 U32 generation = s.read<U32>();
353 Entity e{index, generation};
354 m_entity_masks.add(e, ComponentMask{});
355 ComponentMask* mask = m_entity_masks.get(e);
356 if (mask) {
357 for (USize word = 0; word < 4; ++word) {
358 U64 packed = s.read<U64>();
359 for (USize bit = 0; bit < 64; ++bit) {
360 if (packed & (static_cast<U64>(1) << bit))
361 mask->set(word * 64 + bit);
362 }
363 }
364 } else {
365 for (USize j = 0; j < 4; ++j)
366 s.read<U64>();
367 }
368 }
369
370 for (U32 i = 0; i < m_free_list.count; ++i) {
371 assert(m_generations[m_free_list[i]] > 0 && "Freelist index has generation 0");
372 Entity e{m_free_list[i], m_generations[m_free_list[i]] - 1};
373 m_entity_masks.add(e, ComponentMask{});
374 }
375
376 U32 serializable_count = s.read<U32>();
377 m_component_pools.clear();
378
379 for (U32 i = 0; i < serializable_count; ++i) {
380 U32 componentId = s.read<U32>();
381 auto entry = sd::ComponentFactory::create(componentId, m_pool_arena);
382 if (entry.pool) {
383 entry.deserialize_fn(entry.pool, s);
384 if (componentId >= m_component_pools.count)
385 m_component_pools.push(m_pool_arena, ComponentPoolNode{});
386 m_component_pools[componentId] = entry;
387 }
388 }
389}
Definition arena_vec.hpp:6
static bool is_registered(U32 component_id)
Definition ComponentFactory.cpp:20
static ComponentPoolNode create(U32 component_id, Arena *arena)
Definition ComponentFactory.cpp:14
Definition ComponentPoolNode.hpp:9
Definition component_registration.hpp:19
Definition EntityManager.hpp:116
Definition EntityManager.hpp:64
T * add_component(Entity e, Args &&... args)
void serialize(Serializer &s) const
Definition EntityManager.inl:279
bool is_alive(Entity e) const
Definition EntityManager.inl:267
std::tuple< Components &... > get_component_group(Entity e)
Entity create()
Definition EntityManager.inl:234
std::bitset< 256 > ComponentMask
Definition EntityManager.hpp:158
bool has_component(Entity e) const
U32 pop_free_list()
Definition EntityManager.inl:272
void deserialize(Serializer &s)
Definition EntityManager.inl:335
void destroy(Entity e)
Definition EntityManager.inl:249
T * try_get_component(Entity e)
SparseEntitySet< T > * get_component_pool()
bool has_component_pool()
bool try_remove_component(Entity e)
T & get_component(Entity e)
Definition Entity.hpp:18
Definition serialization.hpp:38
Definition SparseEntitySet.hpp:12
bool remove(Entity entity)
Definition SparseEntitySet.hpp:66
T * get(Entity entity)
Definition SparseEntitySet.hpp:96
Arena * arena
Definition SparseEntitySet.hpp:17
Definition EntityManager.hpp:29
Iterator(manager_type &em, const ArenaVec< Entity > *dense_entities, USize idx)
Definition EntityManager.inl:11
bool is_valid() const
Definition EntityManager.inl:44
Iterator & operator++()
Definition EntityManager.inl:21
void next()
Definition EntityManager.inl:35
const ArenaVec< Entity > * entities
Definition EntityManager.hpp:31
std::tuple< Entity, Components &... > operator*() const
Definition EntityManager.inl:28
Definition EntityManager.hpp:20
manager_type & m_manager
Definition EntityManager.hpp:24
const ArenaVec< Entity > * m_smallest_pool
Definition EntityManager.hpp:25
void check_size(USize &minSize)
Iterator end()
Definition EntityManager.inl:64
Iterator begin()
Definition EntityManager.inl:53
consteval U64 type_id_of()
Definition type_id.hpp:6
std::uint32_t U32
Definition types.hpp:15
std::size_t USize
Definition types.hpp:18
std::uint64_t U64
Definition types.hpp:16