Serialization : started to unify how to allocate entity whether its from MakeEntity or during deserialization.
This commit is contained in:
+8
-16
@@ -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
@@ -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>
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -0,0 +1,4 @@
|
||||
#include <Entity/entity_types.h>
|
||||
|
||||
DEFINE_ENTITY_VERSIONED(Inert, 1)
|
||||
internal void serialize(Archive& /*ar*/, uint16 /*version*/, Inert& /*inert*/) {}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <Entity/entity_common.h>
|
||||
|
||||
struct Inert
|
||||
{
|
||||
DECLARE_ENTITY()
|
||||
|
||||
index_t MeshInstance = indexMax;
|
||||
};
|
||||
Reference in New Issue
Block a user