121 lines
3.9 KiB
C++
121 lines
3.9 KiB
C++
#include <Entity/EntityManager.h>
|
|
|
|
#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>
|
|
|
|
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;
|
|
}
|
|
|
|
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<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
|
|
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));
|
|
}
|
|
}
|
|
}
|