diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2023-11-16 17:48:34 -0500 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2023-11-16 17:48:34 -0500 |
| commit | d93268b739db8a3eb815bf69370d33a590b827cc (patch) | |
| tree | 7797210ade4064e49b15c82820c601089fe2dc19 /src/ecs.cpp | |
| parent | a6ec20bced20c489dfcf3702dfd99310dfbed7df (diff) | |
deleting instances works as expected
Diffstat (limited to 'src/ecs.cpp')
| -rw-r--r-- | src/ecs.cpp | 76 |
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); |
