2#include "gaia/config/config.h"
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#include "gaia/ser/ser_common.h"
15#define GAIA_ID(type) GAIA_ID_##type
17 using Identifier = uint64_t;
18 inline constexpr Identifier IdentifierBad = (Identifier)-1;
19 inline constexpr Identifier EntityCompMask = IdentifierBad << 1;
20 inline constexpr IdentifierId IdentifierIdBad = (IdentifierId)-1;
22 enum class DataStorageType : uint32_t {
36 static constexpr uint32_t IdMask = IdentifierIdBad;
37 static constexpr uint32_t MaxComponentSize_Bits = 13;
38 static constexpr uint32_t MaxComponentSizeInBytes = (1 << MaxComponentSize_Bits) - 1;
39 static constexpr uint32_t MaxAlignment_Bits = MaxComponentSize_Bits;
40 static constexpr uint32_t MaxAlignment = MaxComponentSizeInBytes;
46 IdentifierData
size : MaxComponentSize_Bits;
48 IdentifierData
alig : MaxAlignment_Bits;
52 IdentifierData
soa : meta::StructToTupleMaxTypes_Bits;
56 static_assert(
sizeof(
InternalData) ==
sizeof(Identifier));
65 Component(uint32_t
id, uint32_t soa, uint32_t size, uint32_t alig, DataStorageType storage) noexcept {
70 data.storage = (IdentifierData)storage;
74 GAIA_NODISCARD
constexpr auto id() const noexcept {
75 return (uint32_t)data.id;
78 GAIA_NODISCARD
constexpr auto soa() const noexcept {
79 return (uint32_t)data.soa;
82 GAIA_NODISCARD
constexpr auto size() const noexcept {
83 return (uint32_t)data.size;
86 GAIA_NODISCARD
constexpr auto alig() const noexcept {
87 return (uint32_t)data.alig;
90 GAIA_NODISCARD
constexpr DataStorageType storage_type() const noexcept {
91 return (DataStorageType)data.storage;
94 GAIA_NODISCARD
constexpr auto value() const noexcept {
98 GAIA_NODISCARD
constexpr bool operator==(Component other)
const noexcept {
99 return value() == other.value();
102 GAIA_NODISCARD
constexpr bool operator!=(Component other)
const noexcept {
103 return value() != other.value();
106 GAIA_NODISCARD
constexpr bool operator<(Component other)
const noexcept {
107 return id() < other.id();
110 template <
typename Serializer>
111 void save(Serializer& s)
const;
113 template <
typename Serializer>
114 void load(Serializer& s);
121 enum EntityKind : uint8_t {
128 inline constexpr const char* EntityKindString[] = {
"Gen",
"Uni"};
134 template <
typename T>
136 static_assert(core::is_raw_v<T>);
138 std::is_trivial_v<T> ||
142 "Non-trivial Uni component must implement operator==");
145 static constexpr EntityKind
Kind = EntityKind::EK_Uni;
156 template <
typename,
typename =
void>
158 template <
typename T>
161 template <
typename T>
164 static constexpr EntityKind
Kind = EntityKind::EK_Gen;
174 template <
typename T>
177 static constexpr EntityKind
Kind = T::Kind;
180 using Type =
typename T::TType;
182 using TypeFull = std::conditional_t<Kind == EntityKind::EK_Gen, Type, uni<Type>>;
187 template <
typename,
typename =
void>
189 template <
typename T>
190 struct is_gen_component<T, std::void_t<decltype(T::Kind)>>: std::bool_constant<T::Kind == EntityKind::EK_Gen> {};
192 template <
typename T,
typename =
void>
196 template <
typename T>
202 template <
typename T>
203 using component_type_t =
typename detail::component_type<T>::type;
205 template <
typename T>
206 inline constexpr EntityKind entity_kind_v = component_type_t<T>::Kind;
223 template <
typename Rel,
typename Tgt>
225 using rel_comp_type = component_type_t<Rel>;
226 using tgt_comp_type = component_type_t<Tgt>;
229 using rel =
typename rel_comp_type::TypeFull;
230 using tgt =
typename tgt_comp_type::TypeFull;
231 using rel_type =
typename rel_comp_type::Type;
232 using tgt_type =
typename tgt_comp_type::Type;
233 using rel_original =
typename rel_comp_type::TypeOriginal;
234 using tgt_original =
typename tgt_comp_type::TypeOriginal;
235 using type = std::conditional_t<!std::is_empty_v<rel_type> || std::is_empty_v<tgt_type>, rel, tgt>;
238 template <
typename T>
240 static constexpr bool value = std::is_base_of<detail::pair_base, core::raw_t<T>>::value;
248 static constexpr uint32_t IdMask = IdentifierIdBad;
273 static_assert(
sizeof(
InternalData) ==
sizeof(Identifier));
280 constexpr Entity() noexcept: val(IdentifierBad) {};
285 template <
typename T,
typename = std::enable_if_t<std::is_same_v<T, Identifier>>>
286 constexpr Entity(T value)
noexcept: val(value) {}
289 Entity(EntityId
id, IdentifierData gen)
noexcept {
295 Entity(EntityId
id, IdentifierData gen,
bool isEntity,
bool isPair, EntityKind kind)
noexcept {
304 GAIA_NODISCARD
constexpr auto id() const noexcept {
305 return (uint32_t)data.id;
308 GAIA_NODISCARD
constexpr auto gen() const noexcept {
309 return (uint32_t)data.gen;
312 GAIA_NODISCARD
constexpr bool entity() const noexcept {
313 return data.ent != 0;
316 GAIA_NODISCARD
constexpr bool pair() const noexcept {
317 return data.pair != 0;
320 GAIA_NODISCARD
constexpr bool comp() const noexcept {
321 return (data.pair | data.ent) == 0;
324 GAIA_NODISCARD
constexpr auto kind() const noexcept {
325 return (EntityKind)data.kind;
328 GAIA_NODISCARD
constexpr auto value() const noexcept {
332 GAIA_NODISCARD
constexpr bool operator==(Entity other)
const noexcept {
333 return value() == other.value();
336 GAIA_NODISCARD
constexpr bool operator!=(Entity other)
const noexcept {
337 return value() != other.value();
340 GAIA_NODISCARD
constexpr bool operator<(Entity other)
const noexcept {
341 return value() < other.value();
343 GAIA_NODISCARD
constexpr bool operator<=(Entity other)
const noexcept {
344 return value() <= other.value();
347 GAIA_NODISCARD
constexpr bool operator>(Entity other)
const noexcept {
348 return value() > other.value();
350 GAIA_NODISCARD
constexpr bool operator>=(Entity other)
const noexcept {
351 return value() >= other.value();
354 template <
typename Serializer>
355 void save(Serializer& s)
const;
357 template <
typename Serializer>
358 void load(Serializer& s);
361 inline static const Entity EntityBad = Entity(IdentifierBad);
365 uint32_t savedLastCoreComponentId = 0;
366 uint32_t currLastCoreComponentId = 0;
367 bool remapComponentIds =
false;
381 uint32_t savedLastCoreComponentId, uint32_t currLastCoreComponentId,
bool remapComponentIds)
noexcept:
382 prev(g_entityLoadRemapState) {
383 g_entityLoadRemapState.savedLastCoreComponentId = savedLastCoreComponentId;
384 g_entityLoadRemapState.currLastCoreComponentId = currLastCoreComponentId;
385 g_entityLoadRemapState.remapComponentIds = remapComponentIds;
386 g_entityLoadRemapState.active =
true;
390 g_entityLoadRemapState = prev;
399 GAIA_NODISCARD
inline uint32_t remap_loaded_entity_id(
400 uint32_t
id, uint32_t savedLastCoreComponentId, uint32_t currLastCoreComponentId)
noexcept {
401 if (
id == Entity::IdMask ||
402 id <= savedLastCoreComponentId ||
403 currLastCoreComponentId <= savedLastCoreComponentId
407 return id + (currLastCoreComponentId - savedLastCoreComponentId);
410 GAIA_NODISCARD
inline uint32_t remap_loaded_entity_id(uint32_t
id)
noexcept {
411 const auto& state = g_entityLoadRemapState;
415 return remap_loaded_entity_id(
id, state.savedLastCoreComponentId, state.currLastCoreComponentId);
418 GAIA_NODISCARD
inline Entity
419 remap_loaded_entity(Entity entity, uint32_t savedLastCoreComponentId, uint32_t currLastCoreComponentId)
noexcept {
420 if (entity == EntityBad)
423 if (!entity.pair()) {
425 (EntityId)remap_loaded_entity_id(entity.id(), savedLastCoreComponentId, currLastCoreComponentId),
426 entity.gen(), entity.entity(),
false, entity.kind());
430 (EntityId)remap_loaded_entity_id(entity.id(), savedLastCoreComponentId, currLastCoreComponentId),
431 (IdentifierData)remap_loaded_entity_id(entity.gen(), savedLastCoreComponentId, currLastCoreComponentId),
432 entity.entity(),
true, entity.kind());
435 GAIA_NODISCARD
inline Entity remap_loaded_entity(Entity entity)
noexcept {
436 const auto& state = g_entityLoadRemapState;
440 return remap_loaded_entity(entity, state.savedLastCoreComponentId, state.currLastCoreComponentId);
444 template <
typename Serializer>
445 inline void Entity::save(Serializer& s)
const {
449 template <
typename Serializer>
450 inline void Entity::load(Serializer& s) {
452 *
this = detail::remap_loaded_entity(*
this);
455 template <
typename Serializer>
456 inline void Component::save(Serializer& s)
const {
460 template <
typename Serializer>
461 inline void Component::load(Serializer& s) {
463 if (detail::g_entityLoadRemapState.active && detail::g_entityLoadRemapState.remapComponentIds)
464 data.
id = detail::remap_loaded_entity_id(data.
id);
478 return {core::calculate_hash64(entity.value())};
482 static constexpr bool IsDirectHashKey =
true;
497 size_t hash()
const {
498 return (
size_t)m_hash.hash;
502 if GAIA_LIKELY (m_hash != other.m_hash)
505 return m_entity == other.m_entity;
509 return !operator==(other);
520 uint32_t alias_len{};
536 operator Entity()
const noexcept {
538 m_first.id(), m_second.id(),
541 (
bool)m_first.kind(),
548 Entity first()
const noexcept {
552 Entity second()
const noexcept {
556 bool operator==(
const pair& other)
const {
557 return m_first == other.m_first && m_second == other.m_second;
559 bool operator!=(
const pair& other)
const {
560 return !operator==(other);
571 template <
typename T,
typename U =
void>
573 using type =
typename component_type<T>::type;
576 template <
typename T>
578 using storage_type =
typename T::type;
579 using type =
typename component_type<storage_type>::type;
583 template <
typename T>
584 using actual_type_t =
typename detail::actual_type<T>::type;
615 struct GAIA_API System_;
634 inline Entity Core =
Entity(0, 0,
false,
false, EntityKind::EK_Gen);
638 inline Entity OnDelete =
Entity(3, 0,
false,
false, EntityKind::EK_Gen);
639 inline Entity OnDeleteTarget =
Entity(4, 0,
false,
false, EntityKind::EK_Gen);
640 inline Entity Remove =
Entity(5, 0,
false,
false, EntityKind::EK_Gen);
641 inline Entity Delete =
Entity(6, 0,
false,
false, EntityKind::EK_Gen);
642 inline Entity Error =
Entity(7, 0,
false,
false, EntityKind::EK_Gen);
644 inline Entity Requires =
Entity(8, 0,
false,
false, EntityKind::EK_Gen);
645 inline Entity CantCombine =
Entity(9, 0,
false,
false, EntityKind::EK_Gen);
646 inline Entity Exclusive =
Entity(10, 0,
false,
false, EntityKind::EK_Gen);
648 inline Entity DontFragment =
Entity(11, 0,
false,
false, EntityKind::EK_Gen);
649 inline Entity Sparse =
Entity(12, 0,
false,
false, EntityKind::EK_Gen);
651 inline Entity Acyclic =
Entity(13, 0,
false,
false, EntityKind::EK_Gen);
652 inline Entity Traversable =
Entity(14, 0,
false,
false, EntityKind::EK_Gen);
654 inline Entity All =
Entity(15, 0,
false,
false, EntityKind::EK_Gen);
657 inline Entity ChildOf =
Entity(16, 0,
false,
false, EntityKind::EK_Gen);
659 inline Entity Parent =
Entity(17, 0,
false,
false, EntityKind::EK_Gen);
661 inline Entity Is =
Entity(18, 0,
false,
false, EntityKind::EK_Gen);
663 inline Entity Prefab =
Entity(19, 0,
false,
false, EntityKind::EK_Gen);
665 inline Entity OnInstantiate =
Entity(20, 0,
false,
false, EntityKind::EK_Gen);
666 inline Entity Override =
Entity(21, 0,
false,
false, EntityKind::EK_Gen);
667 inline Entity Inherit =
Entity(22, 0,
false,
false, EntityKind::EK_Gen);
668 inline Entity DontInherit =
Entity(23, 0,
false,
false, EntityKind::EK_Gen);
670 inline Entity System =
Entity(24, 0,
false,
false, EntityKind::EK_Gen);
671 inline Entity DependsOn =
Entity(25, 0,
false,
false, EntityKind::EK_Gen);
673 inline Entity Observer =
Entity(26, 0,
false,
false, EntityKind::EK_Gen);
675 inline Entity Var0 =
Entity(27, 0,
false,
false, EntityKind::EK_Gen);
676 inline Entity Var1 =
Entity(28, 0,
false,
false, EntityKind::EK_Gen);
677 inline Entity Var2 =
Entity(29, 0,
false,
false, EntityKind::EK_Gen);
678 inline Entity Var3 =
Entity(30, 0,
false,
false, EntityKind::EK_Gen);
679 inline Entity Var4 =
Entity(31, 0,
false,
false, EntityKind::EK_Gen);
680 inline Entity Var5 =
Entity(32, 0,
false,
false, EntityKind::EK_Gen);
681 inline Entity Var6 =
Entity(33, 0,
false,
false, EntityKind::EK_Gen);
682 inline Entity Var7 =
Entity(34, 0,
false,
false, EntityKind::EK_Gen);
685 inline constexpr uint32_t RuntimePrimitiveTypeBaseId = 34;
687 GAIA_NODISCARD
inline bool is_runtime_primitive_serialization_type_id(uint32_t typeId)
noexcept {
688 return typeId >= (uint32_t)ser::serialization_type_id::s8 && typeId <= (uint32_t)ser::serialization_type_id::f64;
691 GAIA_NODISCARD
inline Entity runtime_primitive_type_entity(ser::serialization_type_id type)
noexcept {
692 const auto typeId = (uint32_t)type;
693 if (!is_runtime_primitive_serialization_type_id(typeId))
695 return Entity((EntityId)(RuntimePrimitiveTypeBaseId + typeId), 0,
false,
false, EntityKind::EK_Gen);
698 GAIA_NODISCARD
inline bool
699 runtime_primitive_serialization_type(Entity type, ser::serialization_type_id& out)
noexcept {
703 const auto typeId = type.id() - RuntimePrimitiveTypeBaseId;
704 if (!is_runtime_primitive_serialization_type_id(typeId))
707 out = (ser::serialization_type_id)typeId;
711 inline Entity S8 = runtime_primitive_type_entity(ser::serialization_type_id::s8);
712 inline Entity U8 = runtime_primitive_type_entity(ser::serialization_type_id::u8);
713 inline Entity S16 = runtime_primitive_type_entity(ser::serialization_type_id::s16);
714 inline Entity U16 = runtime_primitive_type_entity(ser::serialization_type_id::u16);
715 inline Entity S32 = runtime_primitive_type_entity(ser::serialization_type_id::s32);
716 inline Entity U32 = runtime_primitive_type_entity(ser::serialization_type_id::u32);
717 inline Entity S64 = runtime_primitive_type_entity(ser::serialization_type_id::s64);
718 inline Entity U64 = runtime_primitive_type_entity(ser::serialization_type_id::u64);
719 inline Entity Bool = runtime_primitive_type_entity(ser::serialization_type_id::b);
720 inline Entity Char8 = runtime_primitive_type_entity(ser::serialization_type_id::c8);
721 inline Entity Char16 = runtime_primitive_type_entity(ser::serialization_type_id::c16);
722 inline Entity Char32 = runtime_primitive_type_entity(ser::serialization_type_id::c32);
723 inline Entity WChar = runtime_primitive_type_entity(ser::serialization_type_id::cw);
724 inline Entity F8 = runtime_primitive_type_entity(ser::serialization_type_id::f8);
725 inline Entity F16 = runtime_primitive_type_entity(ser::serialization_type_id::f16);
726 inline Entity F32 = runtime_primitive_type_entity(ser::serialization_type_id::f32);
727 inline Entity F64 = runtime_primitive_type_entity(ser::serialization_type_id::f64);
728 inline static constexpr uint32_t MaxVarCnt = 8;
740 inline Entity GAIA_ID(LastCoreComponent) = F64;
746 GAIA_NODISCARD
inline bool is_wildcard(EntityId entityId) {
747 return entityId == All.id();
750 GAIA_NODISCARD
inline bool is_wildcard(Entity entity) {
751 return entity.pair() && (is_wildcard(entity.id()) || is_wildcard(entity.gen()));
754 GAIA_NODISCARD
inline bool is_wildcard(Pair pair) {
755 return pair.first() == All || pair.second() == All;
758 GAIA_NODISCARD
inline bool is_variable(EntityId entityId) {
759 return entityId <= Var7.id() && entityId >= Var0.id();
762 GAIA_NODISCARD
inline bool is_variable(Entity entity) {
763 return entity.id() <= Var7.id() && entity.id() >= Var0.id();
766 GAIA_NODISCARD
inline bool is_variable(Pair pair) {
767 return is_variable(pair.first()) || is_variable(pair.second());
Array with variable size of elements of type.
Definition darray_impl.h:25
Wrapper for two Entities forming a relationship pair.
Definition id.h:529
Wrapper for two types forming a relationship pair. Depending on what types are used to form a pair it...
Definition id.h:224
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9
Definition sparse_storage.h:31
Detects whether T supports a free operator==.
Definition utility.h:766
Detects whether T defines operator== as a member function.
Definition utility.h:758
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
Component entity index.
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
Component used to describe the entity name.
Definition id.h:516
Hashmap lookup structure used for Entity.
Definition id.h:468
EntityId id
Index in the entity array.
Definition id.h:252
IdentifierData tmp
0-real entity, 1-temporary entity
Definition id.h:269
IdentifierData kind
0-EntityKind::CT_Gen, 1-EntityKind::CT_Uni
Definition id.h:267
IdentifierData gen
Generation index. Incremented every time an entity is deleted.
Definition id.h:261
IdentifierData pair
0-ordinary, 1-pair
Definition id.h:265
IdentifierData ent
0-component, 1-entity
Definition id.h:263
Entity(EntityId id, IdentifierData gen) noexcept
Special constructor for cnt::ilist.
Definition id.h:289
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:286
Definition observer.h:237
static constexpr EntityKind Kind
Component kind.
Definition id.h:145
T TTypeOriginal
Original template type.
Definition id.h:152
T TType
Raw type with no additional sugar.
Definition id.h:148