conversion to c by gemini 4 argon

This commit is contained in:
Patedam committed 2026-10-16 23:40:45 -04:00
1 parent b70e2d21d2
commit f9356f9ba7
369 files changed
+18074 -107634

No files matched your search

+115
View File
@@ -0,0 +1,115 @@
#include <Entity/Entity.h>
#include <Core/Common/serialization.h>
#include <Core/Memory/Utils.h>
#include <stdlib.h>
void serialize_entity(Archive* ar, Entity* entity)
{
Assert(ar != NULL);
Assert(entity != NULL);
// Entity fields
serialize_class(ar, ClassKind(Entity), entity);
// Derived fields
if (entity->derived_kind != NULL && entity->derived != NULL)
{
serialize_class(ar, entity->derived_kind, entity->derived);
}
}
internal void init_Entity(void* payload)
{
Assert(payload != NULL);
Entity* entity = (Entity*)payload;
MemZeroStruct(entity);
}
internal void serialize_Entity(Archive* ar, uint16 version, void* payload)
{
(void)version;
Assert(ar != NULL);
Assert(payload != NULL);
Entity* entity = (Entity*)payload;
SERIALIZE_U64(ar, id, &entity->ID);
SERIALIZE_VEC4(ar, position, &entity->position);
}
DEFINE_CLASS_VERSIONED(Entity, 1, NULL)
String format_entity_id(Arena* arena, EntityID entity_id)
{
Assert(arena != NULL);
// Format:
// U = UserID
// LC = Local Entity Counter
// UU_LCLCLCLCLCLCLC
uint8 user_id = get_user_id(entity_id);
uint64 counter = get_local_counter(entity_id);
const size_t kBufferSize = 18;
char* buffer = ArenaPushArray(arena, char, kBufferSize);
Assert(buffer != NULL);
juliet_snprintf(buffer, kBufferSize, "%02X_%014llX", (unsigned int)user_id, (unsigned long long)counter);
String result = { .Str = buffer, .Size = kBufferSize - 1 };
return result;
}
bool8 parse_entity_id(String str, EntityID* out_id)
{
Assert(out_id != NULL);
bool8 result = false;
*out_id = kInvalid_entity_id;
if (!(str.Size != 17 || str.Str == NULL || str.Str[2] != '_'))
{
char user_hex[3] = { str.Str[0], str.Str[1], '\0' };
char* end = user_hex;
uint8 user_id = (uint8)strtoul(user_hex, &end, 16);
if (end != user_hex && user_id != kInvalid_user_id)
{
char* counter_hex = str.Str + 3;
end = counter_hex;
uint64 counter = strtoull(counter_hex, &end, 16);
if (end != counter_hex && counter < kEntityID_user_id_mask)
{
*out_id = make_entity_id(user_id, counter);
result = true;
}
}
}
return result;
}
const Class* resolve_entity_class(uint8 kind, uint32 crc)
{
Assert(kind <= ENTITY(Count));
const Class* class_ptr = kEntity_type_class_ptr[kind];
Assert(class_ptr != NULL);
Assert(class_get_crc(class_ptr) == crc);
return class_ptr;
}
const Class* find_class_by_name(String name)
{
Assert(IsValidString(name));
const Class* result = NULL;
const uint32 name_crc = crc32_bytes(name.Str, name.Size);
for (uint8 kind = 0; kind < ENTITY(Count); ++kind)
{
const Class* class_ptr = resolve_entity_class(kind, name_crc);
if (class_ptr != NULL)
{
result = class_ptr;
break;
}
}
return result;
}
-92
View File
@@ -1,92 +0,0 @@
#include <Entity/Entity.h>
#include <Core/Common/serialization.h>
void serialize(Archive& ar, NonNullPtr<Entity> entity)
{
// Entity fields
serialize(ar, Entity::kind, entity.Get());
// Derived fields
if (entity->derived_kind != nullptr && entity->derived != nullptr)
{
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);
}
String format_entity_id(NonNullPtr<Arena> arena, EntityID entity_id)
{
// Format:
// U = UserID
// LC = Local Entity Counter
// UU_LCLCLCLCLCLCLC
uint8 user_id = get_user_id(entity_id);
uint64 counter = get_local_counter(entity_id);
constexpr size_t kBufferSize = 18;
char* buffer = ArenaPushArray<char>(arena, kBufferSize);
Assert(buffer);
juliet_snprintf(buffer, kBufferSize, "%02X_%014llX", (unsigned int)user_id, counter);
return { buffer, kBufferSize - 1 };
}
bool parse_entity_id(String str, EntityID& out_id)
{
bool result = false;
out_id = kInvalid_entity_id;
if (!(str.Size != 17 || str.Str == nullptr || str.Str[2] != '_'))
{
char user_hex[3]{ str.Str[0], str.Str[1], '\0' };
char* end = user_hex;
uint8 user_id = strtoul(user_hex, &end, 16);
if (end != user_hex && user_id != kInvalid_user_id)
{
char* counter_hex = str.Str + 3;
end = counter_hex;
uint64 counter = strtoull(counter_hex, &end, 16);
if (end != counter_hex && counter < kEntityID_user_id_mask)
{
out_id = make_entity_id(user_id, counter);
result = true;
}
}
}
return result;
}
const Class* resolve_entity_class(uint8 kind, uint32 crc)
{
Assert(kind <= ENTITY(Count));
NonNullPtr<const Class> class_ptr = kEntity_type_class_ptr[kind];
Assert(class_ptr->CRC == crc);
return class_ptr.Get();
}
const Class* find_class_by_name(String name)
{
Assert(IsValid(name));
const Class* result = nullptr;
const uint32 name_crc = crc32(name.Str, name.Size);
for (uint8 kind = 0; kind < ENTITY(Count); ++kind)
{
const Class* class_ptr = resolve_entity_class(kind, name_crc);
if (class_ptr != nullptr)
{
result = class_ptr;
break;
}
}
return result;
}
+48 -51
View File
@@ -6,98 +6,95 @@
#include <Entity/entity_common.h>
#include <Entity/EntityManager.h>
struct Entity final
typedef struct Entity Entity;
struct Entity
{
DECLARE_CLASS()
EntityID ID = 0;
const Class* derived_kind = nullptr;
DerivedType derived = nullptr;
Vector4 position = {};
bool is_dirty = false;
EntityID ID;
const Class* derived_kind;
DerivedType derived;
Vector4 position;
bool8 is_dirty;
};
DECLARE_CLASS(Entity)
// Can reinterpret cast to this to have the offset of Base and Kind for any entity
// Can cast to this to have the offset of base for any entity
typedef struct EntityTemplate EntityTemplate;
struct EntityTemplate
{
DECLARE_ENTITY();
DECLARE_ENTITY()
};
//
template <typename EntityType>
concept EntityConcept = requires(EntityType entity) {
{ EntityType::kind } -> std::convertible_to<const Class*>;
requires std::same_as<decltype(entity.base), Entity*>;
};
inline constexpr EntityID make_entity_id(uint8 user_id, uint64 local_counter)
static inline EntityID make_entity_id(uint8 user_id, uint64 local_counter)
{
Assert(user_id != kInvalid_user_id);
Assert((local_counter & kEntityID_user_id_mask) == kInvalid_entity_id);
EntityID result = kInvalid_user_id;
result = ((EntityID)user_id << kEntityID_user_id_shift) | (local_counter & kEntityID_user_id_mask);
EntityID result = ((EntityID)user_id << kEntityID_user_id_shift) | (local_counter & kEntityID_user_id_mask);
return result;
}
inline constexpr uint8 get_user_id(EntityID entity_id)
static inline uint8 get_user_id(EntityID entity_id)
{
return (((uint8)entity_id & kEntityID_user_id_mask) << kEntityID_user_id_shift);
return (uint8)((entity_id & kEntityID_user_id_mask) >> kEntityID_user_id_shift);
}
inline constexpr uint64 get_local_counter(EntityID entity_id)
static inline uint64 get_local_counter(EntityID entity_id)
{
return (uint64)entity_id & kEntityID_user_id_mask;
return (uint64)entity_id & ~kEntityID_user_id_mask;
}
inline constexpr bool is_entity_id_valid(EntityID entity_id)
static inline bool8 is_entity_id_valid(EntityID entity_id)
{
bool result = entity_id != kInvalid_entity_id;
bool8 result = (entity_id != kInvalid_entity_id);
return result;
}
template <typename EntityType>
requires EntityConcept<EntityType>
[[nodiscard]] bool IsA(const Entity* entity)
static inline bool8 IsEntityA(const Entity* entity, const Class* kind)
{
Assert(entity != nullptr);
return entity->derived_kind == EntityType::kind;
Assert(entity != NULL);
return entity->derived_kind == kind;
}
template <typename EntityType>
requires EntityConcept<EntityType>
[[nodiscard]] EntityType* MakeEntity(EntityManager& manager, float x, float y, float z)
{
Entity* base_ptr = allocate_entity(manager, EntityType::kind);
Assert(base_ptr);
#define IsEntityOfType(entity_ptr, EntityType) IsEntityA((entity_ptr), ClassKind(EntityType))
base_ptr->ID = EntityManager::ID++;
static inline void* make_entity_by_class(EntityManager* manager, const Class* kind, float x, float y, float z)
{
Assert(manager != NULL);
Assert(kind != NULL);
Entity* base_ptr = allocate_entity(manager, kind);
Assert(base_ptr != NULL);
base_ptr->ID = g_entity_manager_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;
return base_ptr->derived;
}
template <typename EntityType>
requires EntityConcept<EntityType>
[[nodiscard]] EntityType* DownCast(Entity* entity)
#define MakeEntity(EntityType, manager_ptr, x, y, z) \
((EntityType*)make_entity_by_class((manager_ptr), ClassKind(EntityType), (x), (y), (z)))
static inline void* down_cast_entity(Entity* entity, const Class* kind)
{
Assert(entity != nullptr);
Assert(IsA<EntityType>(entity));
return static_cast<EntityType*>(entity->derived);
Assert(entity != NULL);
Assert(IsEntityA(entity, kind));
return entity->derived;
}
void serialize(Archive& ar, NonNullPtr<Entity> entity);
#define DownCastEntity(EntityType, entity_ptr) ((EntityType*)down_cast_entity((entity_ptr), ClassKind(EntityType)))
JULIET_API uint8 get_local_user_id();
void serialize_entity(Archive* ar, Entity* entity);
JULIET_API String format_entity_id(NonNullPtr<Arena> arena, EntityID id);
JULIET_API uint8 get_local_user_id(void);
JULIET_API bool parse_entity_id(String str, EntityID& outId);
JULIET_API String format_entity_id(Arena* arena, EntityID id);
[[nodiscard]] const Class* find_class_by_name(String name);
JULIET_API bool8 parse_entity_id(String str, EntityID* outId);
[[nodiscard]] const Class* resolve_entity_class(uint8 kind, uint32 crc);
const Class* find_class_by_name(String name);
const Class* resolve_entity_class(uint8 kind, uint32 crc);
+190
View File
@@ -0,0 +1,190 @@
#include <Entity/EntityManager.h>
#include <Core/Common/serialization.h>
#include <Core/Memory/Utils.h>
#include <Data/World.h>
#include <Engine/user.h>
#include <Entity/Entity.h>
#include <Entity/entity_types.h>
#include <game.h>
#include <Graphics/MeshRenderer.h>
EntityID g_entity_manager_id = 0;
void InitEntityManager(World* world)
{
Assert(world != NULL);
EntityManager* newManager = ArenaPushStruct(world->WorldArena, EntityManager);
newManager->next_local_counter = 1ULL;
world->EntityManager = newManager;
VectorArenaCreate(&newManager->Entities, Entity, world->WorldArena, 100000 JULIET_DEBUG_PARAM("Entities"));
ArenaParams by_type_params = { .ReserveSize = Kilobytes(1),
.CommitSize = Kilobytes(1),
.Name = "" JULIET_DEBUG_ONLY(, .DoNotReserveMore = true) };
for (uint8 i = 0; i < ENTITY(Count); ++i)
{
by_type_params.Name = kEntity_type_names[i];
newManager->by_type[i].arena = ArenaAllocate(by_type_params);
newManager->by_type[i].array = NULL;
newManager->by_type[i].count = 0;
}
}
void ShutdownEntityManager(void)
{
EntityManager* manager = GetEntityManager();
for (uint8 i = 0; i < ENTITY(Count); ++i)
{
ArenaRelease(manager->by_type[i].arena);
}
vector_arena_destroy(&manager->Entities);
}
EntityManager* GetEntityManager(void)
{
EntityManager* entityManager = GetGameState()->World->EntityManager;
Assert(entityManager != NULL);
return entityManager;
}
EntityID generate_next_entity_id(EntityManager* manager)
{
Assert(manager != NULL);
UserID user = get_local_user_id();
Assert(user != kInvalid_user_id);
Assert(manager->next_local_counter != kEntityID_user_id_mask);
EntityID new_id = make_entity_id(user, manager->next_local_counter);
manager->next_local_counter += 1ULL;
return new_id;
}
EntityTemplate* RegisterEntity(EntityManager* manager, Entity* base, DerivedType entity)
{
Assert(manager != NULL);
Assert(base != NULL);
base->ID = g_entity_manager_id++;
base->derived = entity;
VectorArenaPushPtr(Entity, &manager->Entities, base);
EntityTemplate* 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;
ptr->base = VectorArenaBack(Entity, &manager->Entities);
if (manager->by_type[base->derived_kind->kind].array == NULL)
{
manager->by_type[base->derived_kind->kind].array = ptr;
}
return ptr;
}
Entity* allocate_entity(EntityManager* manager, const Class* derived_type_class)
{
Assert(manager != NULL);
Assert(derived_type_class != NULL);
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 != NULL);
Entity base_template = { 0 };
base_template.derived_kind = derived_type_class;
base_template.is_dirty = true;
VectorArenaPushPtr(Entity, &manager->Entities, &base_template);
Entity* base_ptr = VectorArenaBack(Entity, &manager->Entities);
Assert(base_ptr != NULL);
typed_entity_array* typed_array = &manager->by_type[derived_type_class->kind];
Assert(typed_array->arena != NULL);
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 != NULL);
derived_type_class->initialize_fct(derived);
EntityTemplate* derived_template = (EntityTemplate*)derived;
base_ptr->derived = derived;
derived_template->base = base_ptr;
if (typed_array->array == NULL)
{
typed_array->array = derived_template;
}
typed_array->count += 1;
return base_ptr;
}
void UpdateEntityManager(EntityManager* manager)
{
Assert(manager != NULL);
// Todo : inert by definition dont move, but this is for test
typed_entity_array* by_type = &manager->by_type[ENTITY(Inert)];
for (index_t i = 0; i < by_type->count; ++i)
{
Inert* inert = ((Inert*)by_type->array) + i;
if (inert->MeshInstance != indexMax)
{
Matrix transform =
MatrixTranslation(inert->base->position.x, inert->base->position.y, inert->base->position.z);
SetMeshInstanceTransform(inert->MeshInstance, &transform);
}
}
}
Entity* deserialize_entity(Archive* ar, EntityManager* manager)
{
Assert(ar != NULL);
Assert(manager != NULL);
Assert(ar->loading);
String class_name = { 0 };
SERIALIZE_STR(ar, Class, &class_name);
const Class* class_ptr = find_class_by_name(class_name);
Assert(class_ptr != NULL);
Entity* entity_base = allocate_entity(manager, class_ptr);
Assert(entity_base != NULL);
serialize_entity(ar, entity_base);
if (entity_base->ID >= g_entity_manager_id)
{
g_entity_manager_id = entity_base->ID + 1;
}
entity_base->is_dirty = false;
return entity_base;
}
void update_local_counter(EntityManager* manager, EntityID entity_id)
{
Assert(manager != NULL);
uint8 user_id = get_local_user_id();
if (get_user_id(entity_id) == user_id)
{
uint64 counter = get_local_counter(entity_id);
if (counter >= manager->next_local_counter)
{
manager->next_local_counter = counter + 1ULL;
}
}
}
-170
View File
@@ -1,170 +0,0 @@
#include <Entity/EntityManager.h>
#include <Core/Common/EnumUtils.h>
#include <Core/Common/serialization.h>
#include <Data/World.h>
#include <Entity/Entity.h>
#include <Entity/entity_types.h>
#include <game.h>
#include <Graphics/MeshRenderer.h>
#include "Engine/user.h"
EntityID EntityManager::ID = 0;
void InitEntityManager(NonNullPtr<World> world)
{
EntityManager* newManager = ArenaPushStruct<EntityManager>(world->WorldArena);
world->EntityManager = newManager;
newManager->Entities.Create(world->WorldArena JULIET_DEBUG_PARAM("Entities"));
ArenaParams by_type_params{ .ReserveSize = Kilobytes(1),
.CommitSize = Kilobytes(1),
.Name = "" JULIET_DEBUG_ONLY(, .CanReserveMore = false) };
for (uint8 i = 0; i < ENTITY(Count); ++i)
{
by_type_params.Name = kEntity_type_names[i];
newManager->by_type[i].arena = ArenaAllocate(by_type_params);
newManager->by_type[i].array = nullptr;
}
}
void ShutdownEntityManager()
{
auto& manager = GetEntityManager();
for (typed_entity_array& type : manager.by_type)
{
ArenaRelease(type.arena);
}
manager.Entities.Destroy();
}
EntityManager& GetEntityManager()
{
NonNullPtr entityManager = GetGameState()->World->EntityManager;
return *entityManager;
}
EntityID generate_next_entity_id(EntityManager& manager)
{
UserID user = get_local_user_id();
Assert(user != kInvalid_user_id);
Assert(manager.next_local_counter != kEntityID_user_id_mask);
EntityID new_id = make_entity_id(user, manager.next_local_counter);
manager.next_local_counter += 1ULL;
return new_id;
}
EntityTemplate* RegisterEntity(EntityManager& manager, Entity* base, DerivedType entity)
{
base->ID = EntityManager::ID++;
base->derived = entity;
manager.Entities.PushBack(*base);
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;
ptr->base = manager.Entities.Back();
if (manager.by_type[base->derived_kind->kind].array == nullptr)
{
manager.by_type[base->derived_kind->kind].array = ptr;
}
return ptr;
}
Entity* allocate_entity(EntityManager& manager, NonNullPtr<const 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;
base_template.is_dirty = true;
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
auto& by_type = manager.by_type[ENTITY(Inert)];
for (index_t i = 0; i < by_type.count; ++i)
{
Inert* inert = reinterpret_cast<Inert*>(by_type.array) + i;
if (inert->MeshInstance != indexMax)
{
SetMeshInstanceTransform(inert->MeshInstance,
MatrixTranslation(inert->base->position.x, inert->base->position.y,
inert->base->position.z));
}
}
}
Entity* deserialize_entity(Archive& ar, EntityManager& manager)
{
Assert(ar.loading);
String class_name;
SERIALIZE(ar, Class, class_name);
NonNullPtr<const Class> class_ptr = find_class_by_name(class_name);
NonNullPtr<Entity> entity_base = allocate_entity(manager, class_ptr);
serialize(ar, entity_base);
if (entity_base->ID >= EntityManager::ID)
{
EntityManager::ID = entity_base->ID + 1;
}
entity_base->is_dirty = false;
return entity_base;
}
void update_local_counter(EntityManager& manager, EntityID entity_id)
{
uint8 user_id = get_local_user_id();
if (get_user_id(entity_id) == user_id)
{
uint64 counter = get_local_counter(entity_id);
if (counter >= manager.next_local_counter)
{
manager.next_local_counter = counter + 1ULL;
}
}
}
+20 -16
View File
@@ -3,11 +3,13 @@
#include <Core/Container/Vector.h>
#include <Entity/entity_common.h>
struct World;
struct EntityTemplate;
struct Entity;
struct Class;
typedef struct World World;
typedef struct EntityTemplate EntityTemplate;
typedef struct Entity Entity;
typedef struct Class Class;
typedef struct Archive Archive;
typedef struct typed_entity_array typed_entity_array;
struct typed_entity_array
{
Arena* arena;
@@ -15,22 +17,24 @@ struct typed_entity_array
size_t count;
};
typedef struct EntityManager EntityManager;
struct EntityManager
{
static EntityID ID;
uint64 next_local_counter = 1ULL;
uint64 next_local_counter;
// TODO: Should be a pool
VectorArena<Entity, 100'000> Entities;
VectorArena Entities;
typed_entity_array by_type[ENTITY(Count)];
typed_entity_array by_type[Entity_Type_Count];
};
void InitEntityManager(NonNullPtr<World> world);
void ShutdownEntityManager();
EntityManager& GetEntityManager();
EntityTemplate* RegisterEntity(EntityManager& manager, Entity* base, DerivedType entity);
[[nodiscard]] Entity* allocate_entity(EntityManager& manager, NonNullPtr<const Class> derived_type_class);
void UpdateEntityManager(EntityManager& manager);
[[nodiscard]] Entity* deserialize_entity(Archive& archive, EntityManager& manager);
void update_local_counter(EntityManager& manager, EntityID entity_id);
extern EntityID g_entity_manager_id;
void InitEntityManager(World* world);
void ShutdownEntityManager(void);
EntityManager* GetEntityManager(void);
EntityTemplate* RegisterEntity(EntityManager* manager, Entity* base, DerivedType entity);
Entity* allocate_entity(EntityManager* manager, const Class* derived_type_class);
void UpdateEntityManager(EntityManager* manager);
Entity* deserialize_entity(Archive* archive, EntityManager* manager);
void update_local_counter(EntityManager* manager, EntityID entity_id);
@@ -5,17 +5,16 @@
// clang-format off
#define AS_STR(name) #name
const char* kEntity_type_names[] = {
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[]
{
#define AS_CLASS(name) &class_kind_##name
const Class* kEntity_type_class_ptr[] = {
ENTITY_TYPE_LIST(AS_CLASS)
nullptr
NULL
};
#undef AS_CLASS
// clang-format on
+26 -24
View File
@@ -1,46 +1,48 @@
#pragma once
#include <Core/Common/EnumUtils.h>
#include <Engine/Class.h>
struct Class;
using DerivedType = void*;
using EntityID = uint64_t;
typedef void* DerivedType;
typedef uint64 EntityID;
constexpr uint8 kInvalid_user_id = 0U;
constexpr EntityID kInvalid_entity_id = 0ULL;
constexpr EntityID kEntityID_user_id_shift = 56ULL;
constexpr EntityID kEntityID_user_id_mask = 0xFF00'0000'0000'0000ULL;
#define kInvalid_user_id ((uint8)0U)
#define kInvalid_entity_id ((EntityID)0ULL)
#define kEntityID_user_id_shift ((EntityID)56ULL)
#define kEntityID_user_id_mask ((EntityID)0xFF00000000000000ULL)
// clang-format off
#define ENTITY_TYPE_LIST(X) X(Inert),
#define AS_ENUM(name) name
enum class Entity_Type : uint8
typedef uint8 Entity_Type;
#define AS_ENUM(name) Entity_Type_##name
enum
{
ENTITY_TYPE_LIST(AS_ENUM)
Count
Entity_Type_Count
};
#undef AS_ENUM
extern const char* kEntity_type_names[];
extern const char* kEntity_type_names[];
extern const Class* kEntity_type_class_ptr[];
#define ENTITY(kind) ToUnderlying(Entity_Type::kind)
#define ENTITY(kind) ((uint8)Entity_Type_##kind)
// clang-format on
struct Entity;
typedef struct Entity Entity;
#define DECLARE_ENTITY() \
Entity* base; \
DECLARE_CLASS()
#define DECLARE_ENTITY() Entity* base;
#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);
#define DEFINE_ENTITY_VERSIONED(entity, version_num) \
const Class class_kind_##entity = { \
.Name = ConstString(#entity), \
.kind = (uint8)Entity_Type_##entity, \
.version = (version_num), \
.base_class = &class_kind_Entity, \
.initialize_fct = init_##entity, \
.serialize_fct = serialize_##entity, \
.size_of = sizeof(entity), \
.alignment = AlignOf(entity) \
};
// Note: Needed by every classes see define above
// Note: Needed by every entity class (see define above)
extern const Class class_kind_Entity;
+22
View File
@@ -0,0 +1,22 @@
#include <Entity/entity_types.h>
#include <Core/Common/serialization.h>
internal void init_Inert(void* payload)
{
Assert(payload != NULL);
Inert* inert = (Inert*)payload;
inert->base = NULL;
inert->MeshInstance = indexMax;
}
internal void serialize_Inert(Archive* ar, uint16 version, void* payload)
{
(void)version;
Assert(ar != NULL);
Assert(payload != NULL);
Inert* inert = (Inert*)payload;
SERIALIZE_U64(ar, MeshInstance, &inert->MeshInstance);
}
DEFINE_ENTITY_VERSIONED(Inert, 1)
-9
View File
@@ -1,9 +0,0 @@
#include <Entity/entity_types.h>
#include <Core/Common/serialization.h>
DEFINE_ENTITY_VERSIONED(Inert, 1)
internal void serialize(Archive& ar, uint16 /*version*/, Inert& inert)
{
SERIALIZE(ar, MeshInstance, inert.MeshInstance);
}
+3 -1
View File
@@ -2,9 +2,11 @@
#include <Entity/entity_common.h>
typedef struct Inert Inert;
struct Inert
{
DECLARE_ENTITY()
index_t MeshInstance = indexMax;
index_t MeshInstance;
};
DECLARE_CLASS(Inert)