diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2023-08-30 11:00:04 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2023-09-06 17:19:09 -0400 |
| commit | ea218cad0ee862964e12bb7f15d442acb7de6c43 (patch) | |
| tree | f9c15c073e2a60e957d6d6b74f5f991a28b222a9 /src/ecs.cpp | |
| parent | 2bdb644e2f4f821a367713ad951369013be8b611 (diff) | |
first pass add ecs
Diffstat (limited to 'src/ecs.cpp')
| -rw-r--r-- | src/ecs.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/ecs.cpp b/src/ecs.cpp new file mode 100644 index 0000000..2c0a26f --- /dev/null +++ b/src/ecs.cpp @@ -0,0 +1,71 @@ + +#include "ecs.hpp" + +TypeSafeInt_B(EntityHandle); +const uint64_t bucketItemCount = 256; + +struct EntityBucket{ + Entity entities[bucketItemCount]; +}; + +uint64_t entityBucketIncrementer = 2; +EntityHandle_T entityBucketCounter{0}; +EntityHandle_T entityCounter{0}; +EntityBucket *entityBuckets = nullptr; +DynArray<EntityHandle> entitiesMarkedForRemoval{16}; +DynArray<EntityHandle> EntitiesToBeRemoved{16}; + +void ECS_Init() { + entityBuckets = pke::PkeNew<EntityBucket>(entityBucketIncrementer); +} + +EntityHandle ECS_CreateEntity_Inner(EntityHandle parentEntityHandle) { + EntityHandle_T entityHandle_T{Buckets_NewHandle<EntityBucket>(bucketItemCount, entityBucketIncrementer, entityBucketCounter, entityCounter, entityBuckets)}; + EntityHandle entityHandle{entityHandle_T}; + + Entity *entity = &entityBuckets[Buckets_GetBucketIndex(entityHandle_T)].entities[Buckets_GetItemIndex(entityHandle_T)]; + + entity->handle = entityHandle; + entity->parentHandle = parentEntityHandle; + + return entityHandle; +} + +EntityHandle ECS_CreateEntity(EntityHandle parentEntityHandle) { + return ECS_CreateEntity_Inner(parentEntityHandle); +} + +void ECS_MarkForRemoval(EntityHandle entityHandle) { + auto b = Buckets_GetBucketIndex(static_cast<EntityHandle_T>(entityHandle)); + auto e = Buckets_GetItemIndex(static_cast<EntityHandle_T>(entityHandle)); + const Entity *ent = &entityBuckets[b].entities[e]; + assert(ent->isMarkedForRemoval == false && "Entity already marked for removal"); + entitiesMarkedForRemoval.Push(entityHandle); +} + +void ECS_Tick(double delta) { + EntitiesToBeRemoved.Resize(0); + for (long b = 0; b <= entityBucketCounter; ++b) { + uint64_t entCount = b == entityBucketCounter ? entityCounter >> 32 : bucketItemCount; + for (long e = 0; e < entCount; ++e) { + Entity *ent = &entityBuckets[b].entities[e]; + if (ent->handle == EntityHandle{EntityHandle_T{0xFFFFFFFFFFFFFFFF}}) continue; + if (ent->isMarkedForRemoval) { + ent->handle = EntityHandle{EntityHandle_T{0xFFFFFFFFFFFFFFFF}}; + ent->parentHandle = EntityHandle{EntityHandle_T{0xFFFFFFFFFFFFFFFF}}; + ent->isMarkedForRemoval = false; + } else { + if (entitiesMarkedForRemoval.Has(ent->handle)) { + ent->isMarkedForRemoval = true; + EntitiesToBeRemoved.Push(ent->handle); + continue; + } + if (EntitiesToBeRemoved.Has(ent->parentHandle)) { + ent->isMarkedForRemoval = true; + EntitiesToBeRemoved.Push(ent->handle); + } + } + } + } + entitiesMarkedForRemoval.Resize(0); +} |
