summaryrefslogtreecommitdiff
path: root/src/ecs.cpp
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2023-08-30 11:00:04 -0400
committerJonathan Bradley <jcb@pikum.xyz>2023-09-06 17:19:09 -0400
commitea218cad0ee862964e12bb7f15d442acb7de6c43 (patch)
treef9c15c073e2a60e957d6d6b74f5f991a28b222a9 /src/ecs.cpp
parent2bdb644e2f4f821a367713ad951369013be8b611 (diff)
first pass add ecs
Diffstat (limited to 'src/ecs.cpp')
-rw-r--r--src/ecs.cpp71
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);
+}