summaryrefslogtreecommitdiff
path: root/src
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
parenta6ec20bced20c489dfcf3702dfd99310dfbed7df (diff)
deleting instances works as expected
Diffstat (limited to 'src')
-rw-r--r--src/ecs.cpp76
-rw-r--r--src/game.cpp20
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();