summaryrefslogtreecommitdiff
path: root/src/ecs.cpp
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2023-11-16 17:48:34 -0500
committerJonathan Bradley <jcb@pikum.xyz>2023-11-16 17:48:34 -0500
commitd93268b739db8a3eb815bf69370d33a590b827cc (patch)
tree7797210ade4064e49b15c82820c601089fe2dc19 /src/ecs.cpp
parenta6ec20bced20c489dfcf3702dfd99310dfbed7df (diff)
deleting instances works as expected
Diffstat (limited to 'src/ecs.cpp')
-rw-r--r--src/ecs.cpp76
1 files changed, 55 insertions, 21 deletions
diff --git a/src/ecs.cpp b/src/ecs.cpp
index 50ae95d..45d3bdc 100644
--- a/src/ecs.cpp
+++ b/src/ecs.cpp
@@ -25,10 +25,26 @@ struct InstanceBucket {
CompInstance instances[maxBucketItemCount];
};
+/*
+ * Entities that have been marked for removal by calling ECS_MarkForRemoval
+ *
+ * Used to build the other "removal" lists.
+ */
+DynArray<EntityHandle> entitiesMarkedForRemoval{16};
+
+/*
+ * Public list of entities that will be removed next tick
+ *
+ * Entity or child of entity that had ECS_MarkForRemoval called
+ */
DynArray<EntityHandle> EntitiesToBeRemoved{16}; // public
-DynArray<Entity> entitiesYetToBeRemoved{0, nullptr};
-DynArray<EntityHandle> entitiesMarkedForRemoval{16};
+/*
+ * The entities being removed this tick
+ *
+ * Each of these entities has gone a full tick in the "to be removed" state
+ */
+DynArray<Entity> entitiesYetToBeRemoved{0, nullptr};
DynArray<EntityHandle> EntitiesWithExcessInstances{16};
@@ -86,56 +102,67 @@ void ECS_MarkForRemoval(EntityHandle entityHandle) {
}
void ECS_Tick_Early(double delta) {
- entitiesYetToBeRemoved.Resize(EntitiesToBeRemoved.Count());
- EntitiesToBeRemoved.Resize(0);
+ // these reserves might happen 1 tick early, but that's fine
+ entitiesYetToBeRemoved.Reserve(entitiesMarkedForRemoval.Count());
+ EntitiesToBeRemoved.Resize(entitiesMarkedForRemoval.Count());
+ memcpy(EntitiesToBeRemoved.GetPtr(), entitiesMarkedForRemoval.GetPtr(), sizeof(EntityHandle) * entitiesMarkedForRemoval.Count());
+ entitiesYetToBeRemoved.Resize(0);
for (long b = 0; b <= Entities_BucketContainer.bucketCounter; ++b) {
uint64_t entCount = b == Entities_BucketContainer.bucketCounter ? Entities_BucketContainer.itemCounter >> 32 : maxBucketItemCount;
for (long e = 0; e < entCount; ++e) {
Entity *ent = &Entities_BucketContainer.buckets[b].entities[e];
if (ent->handle == EntityHandle_MAX) continue;
if (ent->isMarkedForRemoval) {
+ entitiesYetToBeRemoved.Push(*ent);
ent->handle = EntityHandle_MAX;
ent->parentHandle = EntityHandle_MAX;
ent->isMarkedForRemoval = false;
- entitiesYetToBeRemoved[0] = *ent;
- } else {
- if (entitiesMarkedForRemoval.Has(ent->handle) || EntitiesToBeRemoved.Has(ent->parentHandle)) {
- ent->isMarkedForRemoval = true;
- EntitiesToBeRemoved.Push(ent->handle);
- }
+ } else if (EntitiesToBeRemoved.Has(ent->handle)) {
+ ent->isMarkedForRemoval = true;
+ } else if (EntitiesToBeRemoved.Has(ent->parentHandle)) {
+ ent->isMarkedForRemoval = true;
+ EntitiesToBeRemoved.Push(ent->handle);
}
}
- }
+ }
for (long e = 0; e < entitiesYetToBeRemoved.Count(); ++e) {
Entity &clonedEnt = entitiesYetToBeRemoved[e];
CompGrBinds *grBinds = nullptr;
InstanceBucket *instBucket = nullptr;
CompInstance *inst = nullptr;
uint64_t instBucketIndex = 0;
- if (clonedEnt.grBindsHandle != GrBindsHandle_MAX) {
- GrBindsHandle_T bindsHandle_t{static_cast<GrBindsHandle_T>(clonedEnt.grBindsHandle)};
- auto b = Buckets_GetBucketIndex(bindsHandle_t);
- auto i = Buckets_GetItemIndex(bindsHandle_t);
- grBinds = &Comp_GrBinds_BucketContainer.buckets[b].compGrBinds[i];
- }
- if (grBinds != nullptr && clonedEnt.instanceHandle != InstanceHandle_MAX) {
+ if (clonedEnt.instanceHandle != InstanceHandle_MAX) {
InstanceHandle_T instanceHandle_t{static_cast<InstanceHandle_T>(clonedEnt.instanceHandle)};
auto b = Buckets_GetBucketIndex(instanceHandle_t);
auto i = Buckets_GetItemIndex(instanceHandle_t);
+ instBucketIndex = b;
instBucket = &Comp_Instance_BucketContainer.buckets[b];
inst = &instBucket->instances[i];
- instBucketIndex = b;
+ GrBindsHandle_T grBindsHandle_t = static_cast<GrBindsHandle_T>(inst->grBindsHandle);
+ b = Buckets_GetBucketIndex(grBindsHandle_t);
+ i = Buckets_GetItemIndex(grBindsHandle_t);
+ grBinds = &Comp_GrBinds_BucketContainer.buckets[b].compGrBinds[i];
+ }
+ if (grBinds == nullptr && clonedEnt.grBindsHandle != GrBindsHandle_MAX) {
+ GrBindsHandle_T bindsHandle_t{static_cast<GrBindsHandle_T>(clonedEnt.grBindsHandle)};
+ auto b = Buckets_GetBucketIndex(bindsHandle_t);
+ auto i = Buckets_GetItemIndex(bindsHandle_t);
+ grBinds = &Comp_GrBinds_BucketContainer.buckets[b].compGrBinds[i];
}
if (inst != nullptr) {
+ assert(grBinds != nullptr);
for (long bi = instBucketIndex; bi <= Comp_Instance_BucketContainer.bucketCounter; ++bi) {
uint64_t instCounter = 0;
if (bi == Comp_Instance_BucketContainer.bucketCounter) {
- instCounter = Comp_Instance_BucketContainer.itemCounter;
+ instCounter = Comp_Instance_BucketContainer.itemCounter >> 32;
} else {
instCounter = maxBucketItemCount;
}
auto &bucket = Comp_Instance_BucketContainer.buckets[bi];
for (long ii = 0; ii < instCounter; ++ii) {
+ if (bucket.instances[ii].entHandle == EntityHandle_MAX) {
+ continue;
+ }
if (bucket.instances[ii].grBindsHandle != clonedEnt.grBindsHandle) {
continue;
}
@@ -146,12 +173,15 @@ void ECS_Tick_Early(double delta) {
bucket.instances[ii].isNeedingUpdated = true;
}
}
- grBinds->instanceCounter -=1;
+ grBinds->instanceCounter -= 1;
inst->entHandle = EntityHandle_MAX;
inst->grBindsHandle = GrBindsHandle_MAX;
inst->index = ECS_UNSET_VAL;
inst->instanceHandle = InstanceHandle_MAX;
inst->isNeedingUpdated = false;
+ BtDynamicsWorld->removeRigidBody(inst->bt.rigidBody);
+ Pke_Delete<btDefaultMotionState>(inst->bt.motionState, MemBkt_Bullet);
+ Pke_Delete<btRigidBody>(inst->bt.rigidBody, MemBkt_Bullet);
} else if (grBinds != nullptr) {
/*
* 2023-09-05 JB note - the Vulkan assets (device memory, buffers,
@@ -171,6 +201,8 @@ void ECS_Tick(double delta) {
long count = Comp_Instance_BucketContainer.bucketCounter == b ? Comp_Instance_BucketContainer.itemCounter >> 32 : maxBucketItemCount;
for (uint32_t i = 0; i < count; ++i) {
auto &inst = bkt.instances[i];
+ if (inst.entHandle == EntityHandle_MAX)
+ continue;
auto activationState = inst.bt.rigidBody->getActivationState();
if (activationState == ISLAND_SLEEPING || activationState == DISABLE_SIMULATION || activationState == WANTS_DEACTIVATION) {
continue;
@@ -201,6 +233,8 @@ void ECS_Tick_Late(double delta) {
auto &inst = bkt.instances[i];
if (inst.isNeedingUpdated == false)
continue;
+ if (inst.entHandle == EntityHandle_MAX)
+ continue;
GrBindsHandle_T grBindsHandle_t{static_cast<GrBindsHandle_T>(inst.grBindsHandle)};
auto b_inner = Buckets_GetBucketIndex(grBindsHandle_t);