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 | |
| parent | a6ec20bced20c489dfcf3702dfd99310dfbed7df (diff) | |
deleting instances works as expected
| -rw-r--r-- | src/ecs.cpp | 76 | ||||
| -rw-r--r-- | src/game.cpp | 20 |
2 files changed, 71 insertions, 25 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); diff --git a/src/game.cpp b/src/game.cpp index 7069ac9..bb4bbd6 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -532,6 +532,13 @@ void Game_Tick(double delta) { } ECS_Tick_Early(delta); + if (EntitiesToBeRemoved.Has(selectedEntity)) { + selectedEntity = EntityHandle_MAX; + } + if (EntitiesToBeRemoved.Has(hoveredEntity)) { + hoveredEntity = EntityHandle_MAX; + } + ECS_Tick(delta); PkeInput_Tick(delta); @@ -751,9 +758,6 @@ void Game_Tick(double delta) { cameraDbg.rot = glm::quat(glm::vec3(0.f, 0.f, axis4)) * cameraDbg.rot; cameraDbg.stale = cameraDbg.stale | PKE_CAMERA_STALE_ROT; } - } else { - cameraDefault.target = glm::vec3(0.f, 0.f, 0.f); - cameraDefault.stale = cameraDefault.stale | PKE_CAMERA_STALE_ROT; } EntityType_Tick_Late(delta); ECS_Tick_Late(delta); @@ -849,13 +853,14 @@ void RecordImGuiEntityList() { ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg }; - if (ImGui::BeginTable("Entities", 6, tableFlags)) { + if (ImGui::BeginTable("Entities", 7, tableFlags)) { ImGui::TableSetupColumn("Select"); ImGui::TableSetupColumn("EntityHandle"); ImGui::TableSetupColumn("ParentEntityHandle"); ImGui::TableSetupColumn("GrBindsHandle"); ImGui::TableSetupColumn("InstanceHandle"); ImGui::TableSetupColumn("IsMarkedForRemoval"); + ImGui::TableSetupColumn("Delete"); ImGui::TableHeadersRow(); uint64_t bucketCount = ECS_GetEntities_BucketCount(); @@ -868,8 +873,10 @@ void RecordImGuiEntityList() { ImGui::PushID(row); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); + ImGui::BeginDisabled(selectedEntity == entity->handle); if (ImGui::Button("Select")) selectedEntity = entity->handle; + ImGui::EndDisabled(); ImGui::TableSetColumnIndex(1); ImGui::Text("0x%016lX", static_cast<EntityHandle_T>(entity->handle)); ImGui::TableSetColumnIndex(2); @@ -880,6 +887,11 @@ void RecordImGuiEntityList() { ImGui::Text("0x%016lX", static_cast<InstanceHandle_T>(entity->instanceHandle)); ImGui::TableSetColumnIndex(5); ImGui::Text("%u", entity->isMarkedForRemoval); + ImGui::TableSetColumnIndex(6); + ImGui::BeginDisabled(selectedEntity != entity->handle); + if (ImGui::Button("Delete")) + ECS_MarkForRemoval(entity->handle); + ImGui::EndDisabled(); ImGui::PopID(); } ImGui::PopID(); |
