wip entity deserialization phase 1. Unit test not passing because of globals that assume only one entity manager / game state.

This commit is contained in:
2026-09-10 22:50:18 -04:00
parent 615d36b09c
commit 58b79fb499
9 changed files with 518 additions and 259 deletions
+28 -1
View File
@@ -15,9 +15,36 @@ void serialize(Archive& ar, NonNullPtr<Entity> entity)
}
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);
}
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;
}
+9 -4
View File
@@ -10,10 +10,11 @@ struct Entity final
{
DECLARE_CLASS()
EntityID ID = 0;
Class* derived_kind = nullptr;
DerivedType derived = nullptr;
Vector4 position = {};
EntityID ID = 0;
const Class* derived_kind = nullptr;
DerivedType derived = nullptr;
Vector4 position = {};
bool is_dirty = false;
};
// Can reinterpret cast to this to have the offset of Base and Kind for any entity
@@ -64,3 +65,7 @@ template <typename EntityType>
}
void serialize(Archive& ar, NonNullPtr<Entity> entity);
[[nodiscard]] const Class* find_class_by_name(String name);
[[nodiscard]] const Class* resolve_entity_class(uint8 kind, uint32 crc);
+24 -1
View File
@@ -1,6 +1,7 @@
#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>
@@ -67,7 +68,7 @@ EntityTemplate* RegisterEntity(EntityManager& manager, Entity* base, DerivedType
return ptr;
}
Entity* allocate_entity(EntityManager& manager, NonNullPtr<Class> derived_type_class)
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));
@@ -76,6 +77,7 @@ Entity* allocate_entity(EntityManager& manager, NonNullPtr<Class> derived_type_c
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();
@@ -118,3 +120,24 @@ void UpdateEntityManager(EntityManager& manager)
}
}
}
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;
}
+2 -1
View File
@@ -29,5 +29,6 @@ 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);
[[nodiscard]] Entity* allocate_entity(EntityManager& manager, NonNullPtr<const Class> derived_type_class);
void UpdateEntityManager(EntityManager& manager);
[[nodisacrd]] Entity* deserialize_entity(Archive& archive, EntityManager& manager);