Serialization : started to unify how to allocate entity whether its from MakeEntity or during deserialization.

This commit is contained in:
2026-09-08 23:24:48 -04:00
parent 3123d2f2e6
commit 615d36b09c
14 changed files with 307 additions and 194 deletions
+8 -16
View File
@@ -2,22 +2,6 @@
#include <Core/Common/serialization.h>
namespace
{
void serialize_entity(Archive& ar, uint16 /*version*/, void* payload)
{
Assert(payload);
Entity* entity = static_cast<Entity*>(payload);
SERIALIZE(ar, id, entity->ID);
SERIALIZE(ar, position, entity->position);
}
} // namespace
DEFINE_CLASS_VERSIONED(Entity, 1, nullptr, serialize_entity)
DEFINE_ENTITY_VERSIONED(Inert, 1, nullptr)
void serialize(Archive& ar, NonNullPtr<Entity> entity)
{
// Entity fields
@@ -29,3 +13,11 @@ void serialize(Archive& ar, NonNullPtr<Entity> entity)
serialize(ar, entity->derived_kind, entity->derived);
}
}
DEFINE_CLASS_VERSIONED(Entity, 1, nullptr)
internal void serialize(Archive& ar, uint16 /*version*/, Entity& entity)
{
SERIALIZE(ar, id, entity.ID);
SERIALIZE(ar, position, entity.position);
}
+13 -61
View File
@@ -1,24 +1,10 @@
#pragma once
#include <Core/Common/CoreUtils.h>
#include <Core/Common/EnumUtils.h>
#include <Core/Math/Vector.h>
#include <Core/Memory/Allocator.h>
#include <Core/Memory/MemoryArena.h>
#include <Engine/Class.h>
#define DECLARE_ENTITY() \
Entity* base; \
DECLARE_CLASS()
#define DEFINE_ENTITY_VERSIONED(entity, version, serialize_fct) \
constexpr Class entityKind##entity = MakeClass(ConstString(#entity), (uint8)Entity_Type::entity, (version), \
&classKindEntity, sizeof(entity), alignof(entity), (serialize_fct)); \
Class* entity::kind = const_cast<Class*>(&entityKind##entity);
struct EntityManager;
using DerivedType = void*;
using EntityID = uint64_t;
#include <Entity/entity_common.h>
#include <Entity/EntityManager.h>
struct Entity final
{
@@ -30,44 +16,8 @@ struct Entity final
Vector4 position = {};
};
struct Inert
{
DECLARE_ENTITY()
index_t MeshInstance = indexMax;
};
// clang-format off
#define ENTITY_TYPE_LIST(X) X(Inert),
#define AS_ENUM(name) name
enum class Entity_Type : uint8
{
ENTITY_TYPE_LIST(AS_ENUM)
Count
};
#undef AS_ENUM
#define AS_STR(name) #name
inline const char* kEntity_type_names[] = {
ENTITY_TYPE_LIST(AS_STR)
"Count"
};
#undef AS_STR
#define AS_CLASS(name) name::kind
inline Class* kEntity_type_class_ptr[]
{
ENTITY_TYPE_LIST(AS_CLASS)
nullptr
};
#undef AS_CLASS
#define ENTITY(kind) ToUnderlying(Entity_Type::kind)
// clang-format on
// Can reinterpret cast to this to have the offset of Base and Kind for any entity
struct entity_template
struct EntityTemplate
{
DECLARE_ENTITY();
};
@@ -91,15 +41,17 @@ template <typename EntityType>
requires EntityConcept<EntityType>
[[nodiscard]] EntityType* MakeEntity(EntityManager& manager, float x, float y, float z)
{
EntityType result;
Entity base;
base.position.x = x;
base.position.y = y;
base.position.z = z;
base.position.w = 1.0f;
base.derived_kind = EntityType::kind;
Entity* base_ptr = allocate_entity(manager, EntityType::kind);
Assert(base_ptr);
return (EntityType*)RegisterEntity(manager, &base, &result);
base_ptr->ID = EntityManager::ID++;
base_ptr->position.x = x;
base_ptr->position.y = y;
base_ptr->position.z = z;
base_ptr->position.w = 1.0f;
return (EntityType*)base_ptr->derived;
}
template <typename EntityType>
+41 -4
View File
@@ -3,6 +3,7 @@
#include <Core/Common/EnumUtils.h>
#include <Data/World.h>
#include <Entity/Entity.h>
#include <Entity/entity_types.h>
#include <game.h>
#include <Graphics/MeshRenderer.h>
@@ -43,16 +44,16 @@ EntityManager& GetEntityManager()
return *entityManager;
}
entity_template* RegisterEntity(EntityManager& manager, Entity* base, DerivedType entity)
EntityTemplate* RegisterEntity(EntityManager& manager, Entity* base, DerivedType entity)
{
base->ID = EntityManager::ID++;
base->derived = entity;
manager.Entities.PushBack(*base);
auto* ptr = (entity_template*)ArenaPushSize(manager.by_type[base->derived_kind->kind].arena,
base->derived_kind->size_of, base->derived_kind->alignment,
false JULIET_DEBUG_PARAM(kEntity_type_names[base->derived_kind->kind]));
auto* ptr = (EntityTemplate*)ArenaPushSize(manager.by_type[base->derived_kind->kind].arena,
base->derived_kind->size_of, base->derived_kind->alignment,
false JULIET_DEBUG_PARAM(kEntity_type_names[base->derived_kind->kind]));
MemCopy(ptr, entity, base->derived_kind->size_of);
manager.by_type[base->derived_kind->kind].count += 1;
@@ -66,6 +67,42 @@ entity_template* RegisterEntity(EntityManager& manager, Entity* base, DerivedTyp
return ptr;
}
Entity* allocate_entity(EntityManager& manager, NonNullPtr<Class> derived_type_class)
{
Assert(derived_type_class->kind < ENTITY(Count));
Assert(derived_type_class->size_of >= sizeof(EntityTemplate));
Assert(derived_type_class->alignment > 0);
Assert(derived_type_class->initialize_fct);
Entity base_template = {};
base_template.derived_kind = derived_type_class;
manager.Entities.PushBack(base_template);
Entity* base_ptr = manager.Entities.Back();
Assert(base_ptr);
typed_entity_array& typed_array = manager.by_type[derived_type_class->kind];
Assert(typed_array.arena);
void* derived = ArenaPushSize(typed_array.arena, derived_type_class->size_of, derived_type_class->alignment,
false JULIET_DEBUG_PARAM(kEntity_type_names[derived_type_class->kind]));
Assert(derived);
derived_type_class->initialize_fct(derived);
auto* derived_template = (EntityTemplate*)derived;
base_ptr->derived = derived;
derived_template->base = base_ptr;
if (typed_array.array == nullptr)
{
typed_array.array = derived_template;
}
typed_array.count += 1;
return base_ptr;
}
void UpdateEntityManager(EntityManager& manager)
{
// Todo : inert by definition dont move, but this is for test
+13 -10
View File
@@ -1,16 +1,18 @@
#pragma once
#include <Core/Container/Vector.h>
#include <Entity/Entity.h>
#include <Entity/entity_common.h>
struct Entity;
struct World;
struct EntityTemplate;
struct Entity;
struct Class;
struct typed_entity_array
{
Arena* arena;
entity_template* array;
size_t count;
Arena* arena;
EntityTemplate* array;
size_t count;
};
struct EntityManager
@@ -23,8 +25,9 @@ struct EntityManager
typed_entity_array by_type[ENTITY(Count)];
};
void InitEntityManager(NonNullPtr<World> world);
void ShutdownEntityManager();
EntityManager& GetEntityManager();
entity_template* RegisterEntity(EntityManager& manager, Entity* base, DerivedType entity);
void UpdateEntityManager(EntityManager& manager);
void InitEntityManager(NonNullPtr<World> world);
void ShutdownEntityManager();
EntityManager& GetEntityManager();
EntityTemplate* RegisterEntity(EntityManager& manager, Entity* base, DerivedType entity);
[[nodiscard]] Entity* allocate_entity(EntityManager& manager, NonNullPtr<Class> derived_type_class);
void UpdateEntityManager(EntityManager& manager);
+21
View File
@@ -0,0 +1,21 @@
#include <Entity/entity_common.h>
#include <Entity/Entity.h>
#include <Entity/entity_types.h>
// clang-format off
#define AS_STR(name) #name
const char* kEntity_type_names[] = {
ENTITY_TYPE_LIST(AS_STR)
"Count"
};
#undef AS_STR
#define AS_CLASS(name) name::kind
const Class* kEntity_type_class_ptr[]
{
ENTITY_TYPE_LIST(AS_CLASS)
nullptr
};
#undef AS_CLASS
// clang-format on
+40
View File
@@ -0,0 +1,40 @@
#pragma once
#include <Core/Common/EnumUtils.h>
#include <Engine/Class.h>
struct Class;
using DerivedType = void*;
using EntityID = uint64_t;
// clang-format off
#define ENTITY_TYPE_LIST(X) X(Inert),
#define AS_ENUM(name) name
enum class Entity_Type : uint8
{
ENTITY_TYPE_LIST(AS_ENUM)
Count
};
#undef AS_ENUM
extern const char* kEntity_type_names[];
extern const Class* kEntity_type_class_ptr[];
#define ENTITY(kind) ToUnderlying(Entity_Type::kind)
// clang-format on
struct Entity;
#define DECLARE_ENTITY() \
Entity* base; \
DECLARE_CLASS()
#define DEFINE_ENTITY_VERSIONED(entity, version) \
constexpr Class entityKind##entity = \
MakeClass(ConstString(#entity), (uint8)Entity_Type::entity, (version), &class_kind_Entity, sizeof(entity), \
alignof(entity), (&initialize_thunk<entity>), (&serialize_thunk<entity>)); \
Class* entity::kind = const_cast<Class*>(&entityKind##entity);
// Note: Needed by every classes see define above
extern const Class class_kind_Entity;
+4
View File
@@ -0,0 +1,4 @@
#include <Entity/entity_types.h>
DEFINE_ENTITY_VERSIONED(Inert, 1)
internal void serialize(Archive& /*ar*/, uint16 /*version*/, Inert& /*inert*/) {}
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#include <Entity/entity_common.h>
struct Inert
{
DECLARE_ENTITY()
index_t MeshInstance = indexMax;
};