Gaia-ECS v0.9.3
A simple and powerful entity component system
Loading...
Searching...
No Matches
id.h
1#pragma once
2#include "gaia/config/config.h"
3
4#include <cstdint>
5#include <type_traits>
6
7#include "gaia/cnt/sparse_storage.h"
8#include "gaia/core/hashing_policy.h"
9#include "gaia/core/utility.h"
10#include "gaia/ecs/id_fwd.h"
11
12namespace gaia {
13 namespace ecs {
14#define GAIA_ID(type) GAIA_ID_##type
15
16 using Identifier = uint64_t;
17 inline constexpr Identifier IdentifierBad = (Identifier)-1;
18 inline constexpr Identifier EntityCompMask = IdentifierBad << 1;
19 inline constexpr IdentifierId IdentifierIdBad = (IdentifierId)-1;
20
21 enum class DataStorageType : uint32_t {
23 Table,
25 Sparse,
26
27 Count = 2
28 };
29
30 // ------------------------------------------------------------------------------------
31 // Component
32 // ------------------------------------------------------------------------------------
33
34 struct GAIA_API Component final {
35 static constexpr uint32_t IdMask = IdentifierIdBad;
36 static constexpr uint32_t MaxComponentSize_Bits = 13;
37 static constexpr uint32_t MaxComponentSizeInBytes = (1 << MaxComponentSize_Bits) - 1;
38 static constexpr uint32_t MaxAlignment_Bits = MaxComponentSize_Bits;
39 static constexpr uint32_t MaxAlignment = MaxComponentSizeInBytes;
40
41 struct InternalData {
43 // detail::ComponentDescId id;
44 uint32_t id;
46 IdentifierData size : MaxComponentSize_Bits;
48 IdentifierData alig : MaxAlignment_Bits;
50 IdentifierData storage : 1;
52 IdentifierData soa : meta::StructToTupleMaxTypes_Bits;
54 IdentifierData unused : 1;
55 };
56 static_assert(sizeof(InternalData) == sizeof(Identifier));
57
58 union {
59 InternalData data;
60 Identifier val;
61 };
62
63 Component() noexcept = default;
64
65 Component(uint32_t id, uint32_t soa, uint32_t size, uint32_t alig, DataStorageType storage) noexcept {
66 data.id = id;
67 data.soa = soa;
68 data.size = size;
69 data.alig = alig;
70 data.storage = (IdentifierData)storage;
71 data.unused = 0;
72 }
73
74 GAIA_NODISCARD constexpr auto id() const noexcept {
75 return (uint32_t)data.id;
76 }
77
78 GAIA_NODISCARD constexpr auto soa() const noexcept {
79 return (uint32_t)data.soa;
80 }
81
82 GAIA_NODISCARD constexpr auto size() const noexcept {
83 return (uint32_t)data.size;
84 }
85
86 GAIA_NODISCARD constexpr auto alig() const noexcept {
87 return (uint32_t)data.alig;
88 }
89
90 GAIA_NODISCARD constexpr DataStorageType storage_type() const noexcept {
91 return (DataStorageType)data.storage;
92 }
93
94 GAIA_NODISCARD constexpr auto value() const noexcept {
95 return val;
96 }
97
98 GAIA_NODISCARD constexpr bool operator==(Component other) const noexcept {
99 return value() == other.value();
100 }
101
102 GAIA_NODISCARD constexpr bool operator!=(Component other) const noexcept {
103 return value() != other.value();
104 }
105
106 GAIA_NODISCARD constexpr bool operator<(Component other) const noexcept {
107 return id() < other.id();
108 }
109 };
110
111 //----------------------------------------------------------------------
112 // Entity kind
113 //----------------------------------------------------------------------
114
115 enum EntityKind : uint8_t {
116 // Generic entity, one per entity
117 EK_Gen = 0,
118 // Unique entity, one per chunk
119 EK_Uni
120 };
121
122 inline constexpr const char* EntityKindString[] = {"Gen", "Uni"};
123
124 //----------------------------------------------------------------------
125 // Id type deduction
126 //----------------------------------------------------------------------
127
128 template <typename T>
129 struct uni {
130 static_assert(core::is_raw_v<T>);
131 static_assert(
132 std::is_trivial_v<T> ||
133 // For non-trivial T the comparison operator must be implemented because
134 // defragmentation needs it to figure out if entities can be moved around.
136 "Non-trivial Uni component must implement operator==");
137
139 static constexpr EntityKind Kind = EntityKind::EK_Uni;
140
142 using TType = T;
146 using TTypeOriginal = T;
147 };
148
149 namespace detail {
150 template <typename, typename = void>
151 struct has_entity_kind: std::false_type {};
152 template <typename T>
153 struct has_entity_kind<T, std::void_t<decltype(T::Kind)>>: std::true_type {};
154
155 template <typename T>
158 static constexpr EntityKind Kind = EntityKind::EK_Gen;
159
161 using Type = core::raw_t<T>;
163 using TypeFull = Type;
165 using TypeOriginal = T;
166 };
167
168 template <typename T>
171 static constexpr EntityKind Kind = T::Kind;
172
174 using Type = typename T::TType;
176 using TypeFull = std::conditional_t<Kind == EntityKind::EK_Gen, Type, uni<Type>>;
178 using TypeOriginal = typename T::TTypeOriginal;
179 };
180
181 template <typename, typename = void>
182 struct is_gen_component: std::true_type {};
183 template <typename T>
184 struct is_gen_component<T, std::void_t<decltype(T::Kind)>>: std::bool_constant<T::Kind == EntityKind::EK_Gen> {};
185
186 template <typename T, typename = void>
189 };
190 template <typename T>
191 struct component_type<T, std::void_t<decltype(T::Kind)>> {
193 };
194 } // namespace detail
195
196 template <typename T>
197 using component_type_t = typename detail::component_type<T>::type;
198
199 template <typename T>
200 inline constexpr EntityKind entity_kind_v = component_type_t<T>::Kind;
201
202 //----------------------------------------------------------------------
203 // Pair helpers
204 //----------------------------------------------------------------------
205
206 namespace detail {
207 struct pair_base {};
208 } // namespace detail
209
217 template <typename Rel, typename Tgt>
218 class pair: public detail::pair_base {
219 using rel_comp_type = component_type_t<Rel>;
220 using tgt_comp_type = component_type_t<Tgt>;
221
222 public:
223 using rel = typename rel_comp_type::TypeFull;
224 using tgt = typename tgt_comp_type::TypeFull;
225 using rel_type = typename rel_comp_type::Type;
226 using tgt_type = typename tgt_comp_type::Type;
227 using rel_original = typename rel_comp_type::TypeOriginal;
228 using tgt_original = typename tgt_comp_type::TypeOriginal;
229 using type = std::conditional_t<!std::is_empty_v<rel_type> || std::is_empty_v<tgt_type>, rel, tgt>;
230 };
231
232 template <typename T>
233 struct is_pair {
234 static constexpr bool value = std::is_base_of<detail::pair_base, core::raw_t<T>>::value;
235 };
236
237 // ------------------------------------------------------------------------------------
238 // Entity
239 // ------------------------------------------------------------------------------------
240
241 struct GAIA_API Entity final {
242 static constexpr uint32_t IdMask = IdentifierIdBad;
243
246 EntityId id;
247
249 // Bits in this section need to be 1:1 with EntityContainer data.
250 // Note, the order of these bits is important because entities
251 // are sorted by their "val" member and many behaviors rely on this.
253
255 IdentifierData gen : 28;
257 IdentifierData ent : 1;
259 IdentifierData pair : 1;
261 IdentifierData kind : 1;
263 IdentifierData tmp : 1;
264
266 };
267 static_assert(sizeof(InternalData) == sizeof(Identifier));
268
269 union {
270 InternalData data;
271 Identifier val;
272 };
273
274 constexpr Entity() noexcept: val(IdentifierBad) {};
275
279 template <typename T, typename = std::enable_if_t<std::is_same_v<T, Identifier>>>
280 constexpr Entity(T value) noexcept: val(value) {}
281
283 Entity(EntityId id, IdentifierData gen) noexcept {
284 val = 0;
285 data.id = id;
286 data.gen = gen;
287 }
288
289 Entity(EntityId id, IdentifierData gen, bool isEntity, bool isPair, EntityKind kind) noexcept {
290 data.id = id;
291 data.gen = gen;
292 data.ent = isEntity;
293 data.pair = isPair;
294 data.kind = kind;
295 data.tmp = 0;
296 }
297
298 GAIA_NODISCARD constexpr auto id() const noexcept {
299 return (uint32_t)data.id;
300 }
301
302 GAIA_NODISCARD constexpr auto gen() const noexcept {
303 return (uint32_t)data.gen;
304 }
305
306 GAIA_NODISCARD constexpr bool entity() const noexcept {
307 return data.ent != 0;
308 }
309
310 GAIA_NODISCARD constexpr bool pair() const noexcept {
311 return data.pair != 0;
312 }
313
314 GAIA_NODISCARD constexpr bool comp() const noexcept {
315 return (data.pair | data.ent) == 0;
316 }
317
318 GAIA_NODISCARD constexpr auto kind() const noexcept {
319 return (EntityKind)data.kind;
320 }
321
322 GAIA_NODISCARD constexpr auto value() const noexcept {
323 return val;
324 }
325
326 GAIA_NODISCARD constexpr bool operator==(Entity other) const noexcept {
327 return value() == other.value();
328 }
329
330 GAIA_NODISCARD constexpr bool operator!=(Entity other) const noexcept {
331 return value() != other.value();
332 }
333
334 GAIA_NODISCARD constexpr bool operator<(Entity other) const noexcept {
335 return value() < other.value();
336 }
337 GAIA_NODISCARD constexpr bool operator<=(Entity other) const noexcept {
338 return value() <= other.value();
339 }
340
341 GAIA_NODISCARD constexpr bool operator>(Entity other) const noexcept {
342 return value() > other.value();
343 }
344 GAIA_NODISCARD constexpr bool operator>=(Entity other) const noexcept {
345 return value() >= other.value();
346 }
347
348 template <typename Serializer>
349 void save(Serializer& s) const;
350
351 template <typename Serializer>
352 void load(Serializer& s);
353 };
354
355 inline static const Entity EntityBad = Entity(IdentifierBad);
356
357 namespace detail {
359 uint32_t savedLastCoreComponentId = 0;
360 uint32_t currLastCoreComponentId = 0;
361 bool active = false;
362 };
363
364 // NOTE: Entity::load() only receives a serializer, not World state.
365 // Therefore the load-time core-id remap currently uses scoped ambient context.
366 // thread_local keeps concurrent world loads on different threads independent.
367 // Tradeoff: this is less explicit than carrying the remap state on the serializer.
368 inline thread_local EntityLoadRemapState g_entityLoadRemapState{};
369
372
373 EntityLoadRemapGuard(uint32_t savedLastCoreComponentId, uint32_t currLastCoreComponentId) noexcept:
374 prev(g_entityLoadRemapState) {
375 g_entityLoadRemapState.savedLastCoreComponentId = savedLastCoreComponentId;
376 g_entityLoadRemapState.currLastCoreComponentId = currLastCoreComponentId;
377 g_entityLoadRemapState.active = true;
378 }
379
381 g_entityLoadRemapState = prev;
382 }
383
385 EntityLoadRemapGuard& operator=(const EntityLoadRemapGuard&) = delete;
387 EntityLoadRemapGuard& operator=(EntityLoadRemapGuard&&) = delete;
388 };
389
390 GAIA_NODISCARD inline uint32_t remap_loaded_entity_id(
391 uint32_t id, uint32_t savedLastCoreComponentId, uint32_t currLastCoreComponentId) noexcept {
392 if (id == Entity::IdMask || //
393 id <= savedLastCoreComponentId || //
394 currLastCoreComponentId <= savedLastCoreComponentId //
395 )
396 return id;
397
398 return id + (currLastCoreComponentId - savedLastCoreComponentId);
399 }
400
401 GAIA_NODISCARD inline Entity
402 remap_loaded_entity(Entity entity, uint32_t savedLastCoreComponentId, uint32_t currLastCoreComponentId) noexcept {
403 if (entity == EntityBad)
404 return entity;
405
406 if (!entity.pair()) {
407 return Entity(
408 (EntityId)remap_loaded_entity_id(entity.id(), savedLastCoreComponentId, currLastCoreComponentId),
409 entity.gen(), entity.entity(), false, entity.kind());
410 }
411
412 return Entity(
413 (EntityId)remap_loaded_entity_id(entity.id(), savedLastCoreComponentId, currLastCoreComponentId),
414 (IdentifierData)remap_loaded_entity_id(entity.gen(), savedLastCoreComponentId, currLastCoreComponentId),
415 entity.entity(), true, entity.kind());
416 }
417
418 GAIA_NODISCARD inline Entity remap_loaded_entity(Entity entity) noexcept {
419 const auto& state = g_entityLoadRemapState;
420 if (!state.active)
421 return entity;
422
423 return remap_loaded_entity(entity, state.savedLastCoreComponentId, state.currLastCoreComponentId);
424 }
425 } // namespace detail
426
427 template <typename Serializer>
428 inline void Entity::save(Serializer& s) const {
429 s.save(val);
430 }
431
432 template <typename Serializer>
433 inline void Entity::load(Serializer& s) {
434 s.load(val);
435 *this = detail::remap_loaded_entity(*this);
436 }
437
439 struct GAIA_API EntityLookupKey {
441
442 private:
444 Entity m_entity;
446 LookupHash m_hash;
447
448 static LookupHash calc(Entity entity) {
449 return {core::calculate_hash64(entity.value())};
450 }
451
452 public:
453 static constexpr bool IsDirectHashKey = true;
454
455 EntityLookupKey() = default;
456 explicit EntityLookupKey(Entity entity): m_entity(entity), m_hash(calc(entity)) {}
457 ~EntityLookupKey() = default;
458
459 EntityLookupKey(const EntityLookupKey&) = default;
460 EntityLookupKey(EntityLookupKey&&) noexcept = default;
461 EntityLookupKey& operator=(const EntityLookupKey&) = default;
462 EntityLookupKey& operator=(EntityLookupKey&&) noexcept = default;
463
464 Entity entity() const {
465 return m_entity;
466 }
467
468 size_t hash() const {
469 return (size_t)m_hash.hash;
470 }
471
472 bool operator==(const EntityLookupKey& other) const {
473 if GAIA_LIKELY (m_hash != other.m_hash)
474 return false;
475
476 return m_entity == other.m_entity;
477 }
478
479 bool operator!=(const EntityLookupKey& other) const {
480 return !operator==(other);
481 }
482 };
483
484 inline static const EntityLookupKey EntityBadLookupKey = EntityLookupKey(EntityBad);
485
487 struct GAIA_API EntityDesc {
488 const char* name{};
489 uint32_t name_len{};
490 const char* alias{};
491 uint32_t alias_len{};
492 };
493
494 //----------------------------------------------------------------------
495 // Pair
496 //----------------------------------------------------------------------
497
499 template <>
501 Entity m_first;
502 Entity m_second;
503
504 public:
505 pair(Entity a, Entity b) noexcept: m_first(a), m_second(b) {}
506
507 operator Entity() const noexcept {
508 return Entity(
509 m_first.id(), m_second.id(),
510 // Pairs have no way of telling gen and uni entities apart.
511 // Therefore, for first, we use the entity bit as Gen/Uni...
512 (bool)m_first.kind(),
513 // Always true for pairs
514 true,
515 // ... and for second, we use the kind bit.
516 m_second.kind());
517 }
518
519 Entity first() const noexcept {
520 return m_first;
521 }
522
523 Entity second() const noexcept {
524 return m_second;
525 }
526
527 bool operator==(const pair& other) const {
528 return m_first == other.m_first && m_second == other.m_second;
529 }
530 bool operator!=(const pair& other) const {
531 return !operator==(other);
532 }
533 };
534
536
537 //----------------------------------------------------------------------
538 // Core components
539 //----------------------------------------------------------------------
540
541 namespace detail {
542 template <typename T, typename U = void>
543 struct actual_type {
544 using type = typename component_type<T>::type;
545 };
546
547 template <typename T>
548 struct actual_type<T, std::enable_if_t<is_pair<T>::value>> {
549 using storage_type = typename T::type;
550 using type = typename component_type<storage_type>::type;
551 };
552 } // namespace detail
553
554 template <typename T>
555 using actual_type_t = typename detail::actual_type<T>::type;
556
557 //----------------------------------------------------------------------
558 // Core components
559 //----------------------------------------------------------------------
560
561 // Core component. The entity it is attached to is ignored by queries
562 struct GAIA_API Core_ {};
563 // struct EntityDesc;
564 // struct Component;
565 struct GAIA_API OnDelete_ {};
566 struct GAIA_API OnDeleteTarget_ {};
567 struct GAIA_API Remove_ {};
568 struct GAIA_API Delete_ {};
569 struct GAIA_API Error_ {};
570 struct GAIA_API Requires_ {};
571 struct GAIA_API CantCombine_ {};
572 struct GAIA_API Exclusive_ {};
573 struct GAIA_API DontFragment_ {};
574 struct GAIA_API Sparse_ {};
575 struct GAIA_API Acyclic_ {};
576 struct GAIA_API All_ {};
577 struct GAIA_API ChildOf_ {};
578 struct GAIA_API Parent_ {};
579 struct GAIA_API Is_ {};
580 struct GAIA_API Prefab_ {};
581 struct GAIA_API OnInstantiate_ {};
582 struct GAIA_API Override_ {};
583 struct GAIA_API Inherit_ {};
584 struct GAIA_API DontInherit_ {};
585 struct GAIA_API Traversable_ {};
586 struct GAIA_API System_;
587 struct GAIA_API DependsOn_ {};
588 struct GAIA_API Observer_;
589
590 // Query variables
591 struct GAIA_API _Var0 {};
592 struct GAIA_API _Var1 {};
593 struct GAIA_API _Var2 {};
594 struct GAIA_API _Var3 {};
595 struct GAIA_API _Var4 {};
596 struct GAIA_API _Var5 {};
597 struct GAIA_API _Var6 {};
598 struct GAIA_API _Var7 {};
599
600 //----------------------------------------------------------------------
601 // Core component entities
602 //----------------------------------------------------------------------
603
604 // Core component. The entity it is attached to is ignored by queries
605 inline Entity Core = Entity(0, 0, false, false, EntityKind::EK_Gen);
606 inline Entity GAIA_ID(EntityDesc) = Entity(1, 0, false, false, EntityKind::EK_Gen);
607 inline Entity GAIA_ID(Component) = Entity(2, 0, false, false, EntityKind::EK_Gen);
608 // Cleanup rules
609 inline Entity OnDelete = Entity(3, 0, false, false, EntityKind::EK_Gen);
610 inline Entity OnDeleteTarget = Entity(4, 0, false, false, EntityKind::EK_Gen);
611 inline Entity Remove = Entity(5, 0, false, false, EntityKind::EK_Gen);
612 inline Entity Delete = Entity(6, 0, false, false, EntityKind::EK_Gen);
613 inline Entity Error = Entity(7, 0, false, false, EntityKind::EK_Gen);
614 // Entity dependencies
615 inline Entity Requires = Entity(8, 0, false, false, EntityKind::EK_Gen);
616 inline Entity CantCombine = Entity(9, 0, false, false, EntityKind::EK_Gen);
617 inline Entity Exclusive = Entity(10, 0, false, false, EntityKind::EK_Gen);
618 // Entity storage
619 inline Entity DontFragment = Entity(11, 0, false, false, EntityKind::EK_Gen);
620 inline Entity Sparse = Entity(12, 0, false, false, EntityKind::EK_Gen);
621 // Graph properties
622 inline Entity Acyclic = Entity(13, 0, false, false, EntityKind::EK_Gen);
623 inline Entity Traversable = Entity(14, 0, false, false, EntityKind::EK_Gen);
624 // Wildcard query entity
625 inline Entity All = Entity(15, 0, false, false, EntityKind::EK_Gen);
626 // Entity representing a physical hierarchy.
627 // When the relationship target is deleted all children are deleted as well.
628 inline Entity ChildOf = Entity(16, 0, false, false, EntityKind::EK_Gen);
629 // Entity representing a logical/non-fragmenting hierarchy.
630 inline Entity Parent = Entity(17, 0, false, false, EntityKind::EK_Gen);
631 // Alias for a base entity/inheritance
632 inline Entity Is = Entity(18, 0, false, false, EntityKind::EK_Gen);
633 // Template entity excluded from queries by default unless explicitly requested.
634 inline Entity Prefab = Entity(19, 0, false, false, EntityKind::EK_Gen);
635 // Prefab instantiation policy relation and values.
636 inline Entity OnInstantiate = Entity(20, 0, false, false, EntityKind::EK_Gen);
637 inline Entity Override = Entity(21, 0, false, false, EntityKind::EK_Gen);
638 inline Entity Inherit = Entity(22, 0, false, false, EntityKind::EK_Gen);
639 inline Entity DontInherit = Entity(23, 0, false, false, EntityKind::EK_Gen);
640 // Systems
641 inline Entity System = Entity(24, 0, false, false, EntityKind::EK_Gen);
642 inline Entity DependsOn = Entity(25, 0, false, false, EntityKind::EK_Gen);
643 // Observers
644 inline Entity Observer = Entity(26, 0, false, false, EntityKind::EK_Gen);
645 // Query variables
646 inline Entity Var0 = Entity(27, 0, false, false, EntityKind::EK_Gen);
647 inline Entity Var1 = Entity(28, 0, false, false, EntityKind::EK_Gen);
648 inline Entity Var2 = Entity(29, 0, false, false, EntityKind::EK_Gen);
649 inline Entity Var3 = Entity(30, 0, false, false, EntityKind::EK_Gen);
650 inline Entity Var4 = Entity(31, 0, false, false, EntityKind::EK_Gen);
651 inline Entity Var5 = Entity(32, 0, false, false, EntityKind::EK_Gen);
652 inline Entity Var6 = Entity(33, 0, false, false, EntityKind::EK_Gen);
653 inline Entity Var7 = Entity(34, 0, false, false, EntityKind::EK_Gen);
654 inline static constexpr uint32_t MaxVarCnt = 8;
655
656 // Core component ids are append-only.
657 // Existing core ids must remain stable; new core components may only be added
658 // after LastCoreComponent.
659 //
660 // Because of that, old snapshots stay loadable without bumping the serializer
661 // version: any serialized entity id greater than the saved last core id is
662 // remapped by the current core-id delta during load.
663 //
664 // Reordering or removing core components is not supported by this compatibility path.
665 // Always has to match the last internal entity.
666 inline Entity GAIA_ID(LastCoreComponent) = Var7;
667
668 //----------------------------------------------------------------------
669 // Helper functions
670 //----------------------------------------------------------------------
671
672 GAIA_NODISCARD inline bool is_wildcard(EntityId entityId) {
673 return entityId == All.id();
674 }
675
676 GAIA_NODISCARD inline bool is_wildcard(Entity entity) {
677 return entity.pair() && (is_wildcard(entity.id()) || is_wildcard(entity.gen()));
678 }
679
680 GAIA_NODISCARD inline bool is_wildcard(Pair pair) {
681 return pair.first() == All || pair.second() == All;
682 }
683
684 GAIA_NODISCARD inline bool is_variable(EntityId entityId) {
685 return entityId <= Var7.id() && entityId >= Var0.id();
686 }
687
688 GAIA_NODISCARD inline bool is_variable(Entity entity) {
689 return entity.id() <= Var7.id() && entity.id() >= Var0.id();
690 }
691
692 GAIA_NODISCARD inline bool is_variable(Pair pair) {
693 return is_variable(pair.first()) || is_variable(pair.second());
694 }
695
696 } // namespace ecs
697
698 namespace cnt {
699 template <>
700 struct to_sparse_id<ecs::Entity> {
701 static sparse_id get(const ecs::Entity& item) noexcept {
702 // Cut off the flags
703 return item.id();
704 }
705 };
706 } // namespace cnt
707} // namespace gaia
Wrapper for two Entities forming a relationship pair.
Definition id.h:500
Wrapper for two types forming a relationship pair. Depending on what types are used to form a pair it...
Definition id.h:218
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9
Definition sparse_storage.h:31
Definition utility.h:527
Definition utility.h:522
Definition id.h:575
Definition id.h:576
Definition id.h:571
Definition id.h:577
IdentifierData soa
Component is SoA.
Definition id.h:52
IdentifierData alig
Component alignment.
Definition id.h:48
IdentifierData size
Component size.
Definition id.h:46
uint32_t id
Index in the entity array.
Definition id.h:44
IdentifierData storage
Component storage kind. 0 = table, 1 = sparse.
Definition id.h:50
IdentifierData unused
Unused part.
Definition id.h:54
Definition id.h:34
Definition id.h:562
Definition id.h:568
Definition id.h:587
Definition id.h:573
Definition id.h:584
Component used to describe the entity name.
Definition id.h:487
Hashmap lookup structure used for Entity.
Definition id.h:439
EntityId id
Index in the entity array.
Definition id.h:246
IdentifierData tmp
0-real entity, 1-temporary entity
Definition id.h:263
IdentifierData kind
0-EntityKind::CT_Gen, 1-EntityKind::CT_Uni
Definition id.h:261
IdentifierData gen
Generation index. Incremented every time an entity is deleted.
Definition id.h:255
IdentifierData pair
0-ordinary, 1-pair
Definition id.h:259
IdentifierData ent
0-component, 1-entity
Definition id.h:257
Definition id.h:241
Entity(EntityId id, IdentifierData gen) noexcept
Special constructor for cnt::ilist.
Definition id.h:283
constexpr Entity(T value) noexcept
We need the entity to be braces-constructible and at the same type prevent it from getting constructe...
Definition id.h:280
Definition id.h:569
Definition id.h:572
Definition id.h:583
Definition id.h:579
Definition observer.h:238
Definition id.h:566
Definition id.h:565
Definition id.h:581
Definition id.h:582
Definition id.h:578
Definition id.h:580
Definition id.h:567
Definition id.h:570
Definition id.h:574
Definition id.h:585
Definition id.h:591
Definition id.h:592
Definition id.h:593
Definition id.h:594
Definition id.h:595
Definition id.h:596
Definition id.h:597
Definition id.h:598
Type TypeFull
Same as Type.
Definition id.h:163
T TypeOriginal
Original template type.
Definition id.h:165
core::raw_t< T > Type
Raw type with no additional sugar.
Definition id.h:161
static constexpr EntityKind Kind
Component kind.
Definition id.h:158
static constexpr EntityKind Kind
Component kind.
Definition id.h:171
std::conditional_t< Kind==EntityKind::EK_Gen, Type, uni< Type > > TypeFull
T or uni<T> depending on entity kind specified.
Definition id.h:176
typename T::TType Type
Raw type with no additional sugar.
Definition id.h:174
typename T::TTypeOriginal TypeOriginal
Original template type.
Definition id.h:178
Definition id.h:207
Definition id.h:233
Definition id.h:129
static constexpr EntityKind Kind
Component kind.
Definition id.h:139
T TTypeOriginal
Original template type.
Definition id.h:146
T TType
Raw type with no additional sugar.
Definition id.h:142