summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-05-29 16:11:37 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-05-29 16:11:37 -0400
commitd9dc3559296661249f9e5f1c3d0a8320cbf8fc29 (patch)
tree2a0203b676f15e8933960e786c8181354f73b121
parenta9bc23377bd9193cd3eb3ef2e91431d088d13d5d (diff)
pke: ecs: BucketContainer > pk_bkt_arr_t & cleanup
-rw-r--r--editor/editor.cpp59
-rw-r--r--src/asset-manager.cpp2
-rw-r--r--src/components.hpp14
-rw-r--r--src/ecs.cpp459
-rw-r--r--src/ecs.hpp6
-rw-r--r--src/entities.cpp15
-rw-r--r--src/font.cpp4
-rw-r--r--src/project.cpp20
-rw-r--r--src/serialization-component.cpp18
-rw-r--r--src/serialization.cpp21
-rw-r--r--src/window.cpp62
11 files changed, 343 insertions, 337 deletions
diff --git a/editor/editor.cpp b/editor/editor.cpp
index 057152f..667508d 100644
--- a/editor/editor.cpp
+++ b/editor/editor.cpp
@@ -746,7 +746,7 @@ void RecordImGuiEntityTypes() {
ImGui::PushID(i);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
- ImGui::Text("0x%08X 0x%08X", et.handle.bucketIndex, et.handle.itemIndex);
+ ImGui::Text("0x%08X 0x%08X", et.handle.b, et.handle.i);
ImGui::TableSetColumnIndex(1);
ImGui::Text("%*.*s", 0, (int)AssetKeyLength, et.modelAssetKey);
ImGui::TableSetColumnIndex(2);
@@ -981,7 +981,7 @@ bool RecordImGui_GenerateMTSDFModal() {
auto *assets = AM_GetAssets(b, count);
for (pk_handle_item_index_T i = 0; i < count; ++i) {
const auto &asset = assets[i];
- if (asset.handle == EntityHandle_MAX)
+ if (asset.handle == AssetHandle_MAX)
continue;
if (!PK_HAS_FLAG(asset.type, PKE_ASSET_TYPE_FONT)) {
continue;
@@ -1077,7 +1077,7 @@ void RecordImGuiAssets() {
ImGui::PushID(b);
for (pk_handle_item_index_T i = 0; i < count; ++i) {
const auto &asset = assets[i];
- if (asset.handle == EntityHandle_MAX)
+ if (asset.handle == AssetHandle_MAX)
continue;
ImGui::PushID(i);
ImGui::TableNextRow();
@@ -1170,7 +1170,7 @@ void RecordImGuiCameras() {
}
ImGui::EndDisabled();
ImGui::TableSetColumnIndex(1);
- ImGui::Text("0x%08X 0x%08X", cam.handle.bucketIndex, cam.handle.itemIndex);
+ ImGui::Text("0x%08X 0x%08X", cam.handle.b, cam.handle.i);
ImGui::TableSetColumnIndex(2);
ImGui::Text(pk_uuid_printf_format, pk_uuid_printf_var(cam.phys.target_inst_uuid));
ImGui::TableSetColumnIndex(3);
@@ -1501,7 +1501,7 @@ void RecordImGui_CompInstPos(bool readonly, CompInstance *component) {
rot.getEulerZYX(eul.z, eul.y, eul.x);
eul = glm::degrees(eul);
- ImGui::Text("InstanceHandle: 0x%08X 0x%08X", component->instanceHandle.bucketIndex, component->instanceHandle.itemIndex);
+ ImGui::Text("InstanceHandle: 0x%08X 0x%08X", component->instanceHandle.b, component->instanceHandle.i);
changed = ImGui::InputScalar("Instance Index", ImGuiDataType_U64, &component->index, nullptr, nullptr, nullptr, ImGuiInputTextFlags_ReadOnly) || changed;
changed = ImGui::InputScalarN("pos", ImGuiDataType_Float, &pos, 3, nullptr, nullptr, nullptr, inputTextFlags) || changed;
changed = ImGui::InputScalarN("rot (eul)", ImGuiDataType_Float, &eul, 3, nullptr, nullptr, nullptr, inputTextFlags) || changed;
@@ -1538,7 +1538,7 @@ void RecordImGui_CompInstPos(bool readonly, CompInstance *component) {
PkeCamera_TargetInstance(ActiveCamera->camHandle, component);
}
ImGui::SameLine();
- ImGui::Text("Active Camera: 0x%08X 0x%08X", ActiveCamera->handle.bucketIndex, ActiveCamera->handle.itemIndex);
+ ImGui::Text("Active Camera: 0x%08X 0x%08X", ActiveCamera->handle.b, ActiveCamera->handle.i);
ImGui::EndDisabled();
if (changed) {
@@ -1680,27 +1680,30 @@ void RecordImGuiProjectBrowser() {
void RecordImGuiSceneBrowser() {
NULL_CHAR_ARR(text, 128);
- CompInstance *instances;
- EntityType *entType;
- pk_handle_bucket_index_T bucketCount, i;
- pk_handle_item_index_T itemCount, k;
+
if (!ImGui::Begin("SceneBrowser", &pkeSettings.editorSettings.isShowingSceneEditor)) {
ImGui::End();
return;
}
- bucketCount = ECS_GetInstances_BucketCount();
- for (i = 0; i < bucketCount; ++i) {
- instances = ECS_GetInstances(0, itemCount);
- for (k = 0; k < itemCount; ++k) {
- if (instances[k].instanceHandle == InstanceHandle_MAX) continue;
- entType = EntityType_FindByEntityHandle(instances[k].entHandle);
- sprintf(text, "%s: %08x %08x", entType != nullptr ? entType->entityTypeCode.val : "(no type)", instances[k].instanceHandle.bucketIndex, instances[k].instanceHandle.itemIndex);
- if (ImGui::Button(text)) {
- selectedEntity = &instances[k];
- }
+ using InstIterFn = pk_tmpln_1<void, CompInstance*, void*>;
+ InstIterFn inst_iter_cb{};
+ inst_iter_cb.func = [&text](CompInstance *arr_obj_data) {
+ // EntityType *entType = EntityType_FindByEntityHandle(arr_obj_data->entHandle);
+ EntityType *entType = NULL;
+ CompGrBinds *grBinds = ECS_GetGrBinds(arr_obj_data->grBindsHandle);
+ if (grBinds != NULL) {
+ entType = static_cast<EntityType*>(ECS_GetEntity(grBinds->entHandle));
}
- }
+ sprintf(text, "%08x %08x", arr_obj_data->instanceHandle.b, arr_obj_data->instanceHandle.i);
+ if (ImGui::Button(text)) {
+ selectedEntity = arr_obj_data;
+ }
+ ImGui::SameLine();
+ sprintf(text, "EntityType: %s", entType != nullptr ? entType->entityTypeCode.val : "(no type)");
+ ImGui::Text("%s", text);
+ };
+ pk_bkt_arr_iterate(ECS_GetInstances(), &InstIterFn::invoke, &inst_iter_cb);
ImGui::End();
}
@@ -1743,15 +1746,21 @@ void RecordImGuiSceneEditor() {
reset = true;
}
}
+ reset = reset || (entGrBinds.next == 0 && entInstances.next == 0);
if (reset) {
pk_arr_clear(&entGrBinds);
pk_arr_clear(&entInstances);
entType = nullptr;
}
- if (entGrBinds.next == 0)
- ECS_GetGrBinds(ECS_GetEntity(selectedEntity->entHandle), entGrBinds);
- if (entInstances.next == 0)
+ if (entGrBinds.next == 0) {
+ CompGrBinds *grBinds = ECS_GetGrBinds(selectedEntity->grBindsHandle);
+ if (grBinds != NULL) {
+ ECS_GetGrBinds(ECS_GetEntity(grBinds->entHandle), entGrBinds);
+ }
+ }
+ if (entInstances.next == 0) {
ECS_GetInstances(ECS_GetEntity(selectedEntity->entHandle), entInstances);
+ }
if (entGrBinds.next > 0) {
if (ImGui::Button("Create Instance")) {
Entity_Base *entity = ECS_GetEntity(selectedEntity->entHandle);
@@ -1767,7 +1776,7 @@ void RecordImGuiSceneEditor() {
} else {
ImGui::Text("%s: %s", "EntType: ", "Unknown");
}
- ImGui::Text("%s: %08x %08x", "Entity Handle: ", selectedEntity->entHandle.bucketIndex, selectedEntity->entHandle.itemIndex);
+ ImGui::Text("%s: %08x %08x", "Entity Handle: ", selectedEntity->entHandle.b, selectedEntity->entHandle.i);
for (int64_t i = 0; i < entGrBinds.next; ++i) {
RecordImGui_CompGrBinds(true, entGrBinds[i]);
}
diff --git a/src/asset-manager.cpp b/src/asset-manager.cpp
index b7a82fd..a19937a 100644
--- a/src/asset-manager.cpp
+++ b/src/asset-manager.cpp
@@ -268,7 +268,7 @@ void AM_GC() {
for (long i = 0; i < Asset_BucketContainer.pkeHandle.itemIndex; ++i) {
Asset &asset = Asset_BucketContainer.buckets[b][i];
if (asset.referenceCount > 0) {
- fprintf(stderr, "[AM_GC] Asset '%.16s' still in use, count: %i", asset.key, asset.referenceCount);
+ fprintf(stderr, "[AM_GC] Asset '%.16s' still in use, count: %i\n", asset.key, asset.referenceCount);
continue;
}
if (asset.ptr != nullptr && asset.ptr != CAFE_BABE(void) && !PK_HAS_FLAG(asset.flags, PKE_ASSET_FLAGS_MEM_STATIC)) {
diff --git a/src/components.hpp b/src/components.hpp
index 7655863..1adeda3 100644
--- a/src/components.hpp
+++ b/src/components.hpp
@@ -13,15 +13,17 @@
const uint64_t ECS_UNSET_VAL = 0xFFFFFFFFFFFFFFFF;
const uint32_t ECS_UNSET_VAL_32 = 0xFFFFFFFF;
-struct EntityHandle : public pk_handle { };
-struct GrBindsHandle : public pk_handle { };
-struct InstanceHandle : public pk_handle { };
+struct EntityHandle : public pk_bkt_arr_handle { };
+struct GenericEntityHandle : public pk_bkt_arr_handle { };
+struct GrBindsHandle : public pk_bkt_arr_handle { };
+struct InstanceHandle : public pk_bkt_arr_handle { };
struct SceneHandle : public pk_bkt_arr_handle { };
struct LevelHandle : public pk_bkt_arr_handle { };
-constexpr EntityHandle EntityHandle_MAX = EntityHandle{ pk_handle_MAX_constexpr };
-constexpr GrBindsHandle GrBindsHandle_MAX = GrBindsHandle{ pk_handle_MAX_constexpr };
-constexpr InstanceHandle InstanceHandle_MAX = InstanceHandle{ pk_handle_MAX_constexpr };
+constexpr EntityHandle EntityHandle_MAX = EntityHandle{ pk_bkt_arr_handle_MAX_constexpr };
+constexpr GenericEntityHandle GenericEntityHandle_MAX = GenericEntityHandle{ pk_bkt_arr_handle_MAX_constexpr };
+constexpr GrBindsHandle GrBindsHandle_MAX = GrBindsHandle{ pk_bkt_arr_handle_MAX_constexpr };
+constexpr InstanceHandle InstanceHandle_MAX = InstanceHandle{ pk_bkt_arr_handle_MAX_constexpr };
constexpr SceneHandle SceneHandle_MAX = SceneHandle{ pk_bkt_arr_handle_MAX_constexpr };
constexpr LevelHandle LevelHandle_MAX = LevelHandle{ pk_bkt_arr_handle_MAX_constexpr };
diff --git a/src/ecs.cpp b/src/ecs.cpp
index 20e6b49..137686b 100644
--- a/src/ecs.cpp
+++ b/src/ecs.cpp
@@ -12,20 +12,13 @@
#include <BulletCollision/CollisionShapes/btConvexHullShape.h>
#include <glm/gtc/type_ptr.hpp>
-constexpr struct {
- const pk_handle_item_index_T generics = 256;
- const pk_handle_item_index_T entityPtrs = 256;
- const pk_handle_item_index_T grBinds = 64;
- const pk_handle_item_index_T instances = 256;
-} bcSizes;
-
struct ECS {
struct pk_membucket *bkt = nullptr;
struct ECSBucketContainers {
- BucketContainer<Entity_Base, pk_handle, 4> generics{};
- BucketContainer<Entity_Base *, EntityHandle, 4> entityPtrs{};
- BucketContainer<CompGrBinds, GrBindsHandle, 4> grBinds{};
- BucketContainer<CompInstance, InstanceHandle, 4> instances{};
+ pk_bkt_arr_t<Entity_Base> generics{};
+ pk_bkt_arr_t<Entity_Base *> entityPtrs{};
+ pk_bkt_arr_t<CompGrBinds> grBinds{};
+ pk_bkt_arr_t<CompInstance> instances{};
} bc;
} ecs;
@@ -61,15 +54,15 @@ bool ecs_pk_arr_find_first_matching_pointer(void *search_ptr, void *list_ptr) {
}
void ECS_GetEntity_Inner(EntityHandle entHandle, Entity_Base*& ent) {
- assert(pk_handle_validate(entHandle, ecs.bc.entityPtrs.pkeHandle, ecs.bc.entityPtrs.limits.itemIndex) == PK_HANDLE_VALIDATION_VALID);
- ent = ecs.bc.entityPtrs.buckets[entHandle.bucketIndex][entHandle.itemIndex];
+ assert(pk_bkt_arr_handle_validate(&ecs.bc.entityPtrs, entHandle) == PK_BKT_ARR_HANDLE_VALIDATION_VALID);
+ ent = ecs.bc.entityPtrs[entHandle];
}
void ECS_Init() {
- Buckets_Init(ecs.bc.generics, bcSizes.generics);
- Buckets_Init(ecs.bc.entityPtrs, bcSizes.entityPtrs);
- Buckets_Init(ecs.bc.grBinds, bcSizes.grBinds);
- Buckets_Init(ecs.bc.instances, bcSizes.instances);
+ new (&ecs.bc.generics) pk_bkt_arr_t<Entity_Base>{};
+ new (&ecs.bc.entityPtrs) pk_bkt_arr_t<Entity_Base*>{};
+ new (&ecs.bc.grBinds) pk_bkt_arr_t<CompGrBinds>{};
+ new (&ecs.bc.instances) pk_bkt_arr_t<CompInstance>{};
pk_arr_reserve(&entitiesMarkedForRemoval, 16);
pk_arr_reserve(&EntitiesToBeRemoved, 16);
pk_arr_reserve(&entitiesYetToBeRemoved, 16);
@@ -81,34 +74,38 @@ Entity_Base *ECS_CreateGenericEntity() {
* The only place this is called immediately calls ECS_CreateEntity afterwards.
* There is no need to generate a uuid
*/
- pk_handle newHandle{Buckets_NewHandle(ecs.bc.generics)};
- return &ecs.bc.generics.buckets[newHandle.bucketIndex][newHandle.itemIndex];
+ GenericEntityHandle newHandle{pk_bkt_arr_new_handle(&ecs.bc.generics)};
+ Entity_Base *ent = &ecs.bc.generics[newHandle];
+ new (ent) Entity_Base{};
+ return ent;
}
EntityHandle ECS_CreateEntity(Entity_Base *entity, Entity_Base *parentEntity) {
assert(entity != nullptr);
assert(entity->handle == EntityHandle_MAX && "Entity already created!");
- EntityHandle entityHandle{Buckets_NewHandle(ecs.bc.entityPtrs)};
+ EntityHandle entityHandle{pk_bkt_arr_new_handle(&ecs.bc.entityPtrs)};
entity->handle = entityHandle;
if (parentEntity) entity->parentHandle = parentEntity->handle;
if (entity->uuid == pk_uuid_max || entity->uuid == pk_uuid_zed) entity->uuid = pk_uuid_new_v7();
- ecs.bc.entityPtrs.buckets[entityHandle.bucketIndex][entityHandle.itemIndex] = entity;
+ ecs.bc.entityPtrs[entityHandle] = entity;
return entityHandle;
}
Entity_Base *ECS_GetEntity(EntityHandle handle) {
- if (pk_handle_validate(handle, ecs.bc.entityPtrs.pkeHandle, ecs.bc.entityPtrs.limits.itemIndex) != PK_HANDLE_VALIDATION_VALID) return nullptr;
+ if (pk_bkt_arr_handle_validate(&ecs.bc.entityPtrs, handle) != PK_BKT_ARR_HANDLE_VALIDATION_VALID) return nullptr;
return ecs.bc.entityPtrs[handle];
}
Entity_Base *ECS_GetEntityByUUID(pk_uuid uuid) {
- for (pk_handle_bucket_index_T b = 0; b <= ecs.bc.entityPtrs.pkeHandle.bucketIndex; ++b) {
- for (pk_handle_item_index_T i = 0; i < ecs.bc.entityPtrs.pkeHandle.itemIndex; ++i) {
- Entity_Base *bs = ecs.bc.entityPtrs.buckets[b][i];
- if (bs->uuid == uuid) return bs;
- }
- }
- return nullptr;
+ auto entity_ptr_find_cb = [](void *user_data, const void *arr_user_data, const void *arr_obj_data) {
+ (void)user_data;
+ const pk_uuid &uuid = *reinterpret_cast<const pk_uuid*>(arr_user_data);;
+ const Entity_Base &ent = **reinterpret_cast<const Entity_Base*const*>(arr_obj_data);
+ return (ent.uuid == uuid);
+ };
+ EntityHandle handle { pk_bkt_arr_find_first_handle(&ecs.bc.entityPtrs, entity_ptr_find_cb, NULL, &uuid) };
+ if (handle == EntityHandle_MAX) return nullptr;
+ return ecs.bc.entityPtrs[handle];
}
void ECS_MarkForRemoval(Entity_Base *entity) {
@@ -130,27 +127,36 @@ void ECS_Tick_Early(double delta) {
pk_arr_clear(&entitiesMarkedForRemoval);
// this has the potential to be slow as balls
- for (pk_handle_bucket_index_T b = 0; b <= ecs.bc.entityPtrs.pkeHandle.bucketIndex; ++b) {
- pk_handle_item_index_T entCount = b == ecs.bc.entityPtrs.pkeHandle.bucketIndex ? ecs.bc.entityPtrs.pkeHandle.itemIndex : ecs.bc.entityPtrs.limits.itemIndex;
- for (pk_handle_item_index_T e = 0; e < entCount; ++e) {
- Entity_Base *ent = ecs.bc.entityPtrs.buckets[b][e];
- if (ent->handle == EntityHandle_MAX) continue;
- Entity_Base *parentEnt = nullptr;
- if (ent->parentHandle != EntityHandle_MAX)
- parentEnt = ecs.bc.entityPtrs.buckets[ent->parentHandle.bucketIndex][ent->parentHandle.itemIndex];
- if (ent->isMarkedForRemoval) {
- pk_arr_append_t(&entitiesYetToBeRemoved, ent);
- ent->handle = EntityHandle_MAX;
- ent->parentHandle = EntityHandle_MAX;
- ent->isMarkedForRemoval = false;
- } else if (pk_arr_find_first_index(&EntitiesToBeRemoved, ent, ecs_pk_arr_find_first_matching_pointer) != uint32_t(-1)) {
- ent->isMarkedForRemoval = true;
- } else if (parentEnt != nullptr && pk_arr_find_first_index(&EntitiesToBeRemoved, parentEnt, ecs_pk_arr_find_first_matching_pointer) != uint32_t(-1)) {
- ent->isMarkedForRemoval = true;
- pk_arr_append_t(&EntitiesToBeRemoved, ent);
- }
+ // TODO 2025-05-29 JCB PERF
+ // Consider requiring components to register their entity containers.
+ // Then loop through each container individually.
+ // TODO 2025-05-29 JCB
+ // I'm replacing BucketContainer with pk_bkt_arr.
+ // BucketContainer could not free slots, while pk_bkt_arr can.
+ // Before, we unintentionally had everything sequential, with parents first.
+ // That may or may not have implications about this logic.
+ // Might need to do several passes?
+
+ auto ent_remove_cb = [](void *user_data, void *arr_obj_data) {
+ (void)user_data;
+ Entity_Base *ent = *reinterpret_cast<Entity_Base*const*>(arr_obj_data);
+ Entity_Base *parentEnt = nullptr;
+ if (ent->parentHandle != EntityHandle_MAX) {
+ parentEnt = ecs.bc.entityPtrs[ent->parentHandle];
}
- }
+ if (ent->isMarkedForRemoval) {
+ pk_arr_append_t(&entitiesYetToBeRemoved, ent);
+ ent->handle = EntityHandle_MAX;
+ ent->parentHandle = EntityHandle_MAX;
+ ent->isMarkedForRemoval = false;
+ } else if (pk_arr_find_first_index(&EntitiesToBeRemoved, ent, ecs_pk_arr_find_first_matching_pointer) != uint32_t(-1)) {
+ ent->isMarkedForRemoval = true;
+ } else if (parentEnt != nullptr && pk_arr_find_first_index(&EntitiesToBeRemoved, parentEnt, ecs_pk_arr_find_first_matching_pointer) != uint32_t(-1)) {
+ ent->isMarkedForRemoval = true;
+ pk_arr_append_t(&EntitiesToBeRemoved, ent);
+ }
+ };
+ pk_bkt_arr_iterate(&ecs.bc.entityPtrs, ent_remove_cb, NULL);
}
struct updateGrBindsAfter {
@@ -170,90 +176,85 @@ void ECS_Tick(double delta) {
uint32_t entityRemovalCount = entitiesYetToBeRemoved.next;
if (physicsTickCount == 0 && entityRemovalCount == 0) return;
+ using InstIterFn = pk_tmpln_1<void, CompInstance *, void *>;
+ using GrBindsIterFn = pk_tmpln_1<void, CompGrBinds *, void *>;
+ InstIterFn inst_iter_cb{};
+ GrBindsIterFn grbinds_iter_cb{};
+
pk_arr_t<updateGrBindsAfter> updateGrBinds;
updateGrBinds.bkt = pkeSettings.mem.bkt;
- for (long b = 0; b <= ecs.bc.instances.pkeHandle.bucketIndex; ++b) {
- auto &bkt = ecs.bc.instances.buckets[b];
- long count = ecs.bc.instances.pkeHandle.bucketIndex == b ? ecs.bc.instances.pkeHandle.itemIndex : ecs.bc.instances.limits.itemIndex;
- for (uint32_t i = 0; i < count; ++i) {
- auto &inst = bkt[i];
- if (inst.entHandle == EntityHandle_MAX)
- continue;
- auto activationState = inst.bt.rigidBody->getActivationState();
- if (activationState == ISLAND_SLEEPING || activationState == DISABLE_SIMULATION || activationState == WANTS_DEACTIVATION) {
- // do nothing
- } else {
- inst.isNeedingUpdated = true;
- }
- Entity_Base *ent = ecs.bc.entityPtrs.buckets[inst.entHandle.bucketIndex][inst.entHandle.itemIndex];
- if (entityRemovalCount > 0 && pk_arr_find_first_index(&entitiesYetToBeRemoved, ent, ecs_pk_arr_find_first_matching_pointer) != uint32_t(-1)) {
- if (inst.grBindsHandle != GrBindsHandle_MAX) {
- uint32_t afterIndex = pk_arr_find_first_index(&updateGrBinds, &inst.grBindsHandle, ecs_pk_arr_find_by_gr_binds_handle);
- updateGrBindsAfter *after = nullptr;
- if (afterIndex != uint32_t(-1)) {
- after = &updateGrBinds[afterIndex];
- } else {
- struct updateGrBindsAfter tmp{};
- tmp.grBindsHandle = inst.grBindsHandle;
- tmp.count = 0;
- pk_arr_append_t(&updateGrBinds, tmp);
- after = &updateGrBinds[updateGrBinds.next-1];
- }
- after->count += 1;
- }
- inst.entHandle = EntityHandle_MAX;
- inst.grBindsHandle = GrBindsHandle_MAX;
- inst.index = ECS_UNSET_VAL_32;
- inst.instanceHandle = InstanceHandle_MAX;
- inst.isNeedingUpdated = false;
- BtDynamicsWorld->removeRigidBody(inst.bt.rigidBody);
- pk_delete<btDefaultMotionState>(inst.bt.motionState, MemBkt_Bullet);
- pk_delete<btRigidBody>(inst.bt.rigidBody, MemBkt_Bullet);
- inst.bt.rigidBody = CAFE_BABE(btRigidBody);
- inst.bt.motionState = CAFE_BABE(btDefaultMotionState);
- continue;
- }
- if (updateGrBinds.next > 0 && inst.instanceHandle != InstanceHandle_MAX) {
+ inst_iter_cb.func = [entityRemovalCount, &updateGrBinds](CompInstance *arr_obj_data) {
+ CompInstance &inst = *arr_obj_data;
+ auto activationState = inst.bt.rigidBody->getActivationState();
+ if (activationState == ISLAND_SLEEPING || activationState == DISABLE_SIMULATION || activationState == WANTS_DEACTIVATION) {
+ // no-op
+ } else {
+ inst.isNeedingUpdated = true;
+ }
+ Entity_Base *ent = ecs.bc.entityPtrs[inst.entHandle];
+ if (entityRemovalCount > 0 && pk_arr_find_first_index(&entitiesYetToBeRemoved, ent, ecs_pk_arr_find_first_matching_pointer) != uint32_t(-1)) {
+ if (inst.grBindsHandle != GrBindsHandle_MAX) {
uint32_t afterIndex = pk_arr_find_first_index(&updateGrBinds, &inst.grBindsHandle, ecs_pk_arr_find_by_gr_binds_handle);
+ updateGrBindsAfter *after = nullptr;
if (afterIndex != uint32_t(-1)) {
- auto &after = updateGrBinds[afterIndex];
- inst.index -= after.count;
- inst.isNeedingUpdated = true;
+ after = &updateGrBinds[afterIndex];
+ } else {
+ struct updateGrBindsAfter tmp{};
+ tmp.grBindsHandle = inst.grBindsHandle;
+ tmp.count = 0;
+ pk_arr_append_t(&updateGrBinds, tmp);
+ after = &updateGrBinds[updateGrBinds.next-1];
}
+ after->count += 1;
}
- }
- }
- if (entityRemovalCount > 0 || updateGrBinds.next > 0) {
- for (pk_handle_bucket_index_T b = 0; b <= ecs.bc.grBinds.pkeHandle.bucketIndex; ++b) {
- auto &bkt = ecs.bc.grBinds.buckets[b];
- long count = ecs.bc.grBinds.pkeHandle.bucketIndex == b ? ecs.bc.grBinds.pkeHandle.itemIndex : ecs.bc.grBinds.limits.itemIndex;
- for (pk_handle_item_index_T i = 0; i < count; ++i) {
- auto &grBinds = bkt[i];
- if (grBinds.entHandle == EntityHandle_MAX) {
- continue;
- }
- uint32_t afterIndex = pk_arr_find_first_index(&updateGrBinds, &grBinds.grBindsHandle, ecs_pk_arr_find_by_gr_binds_handle);
- Entity_Base *ent = ecs.bc.entityPtrs.buckets[grBinds.entHandle.bucketIndex][grBinds.entHandle.itemIndex];
- if (pk_arr_find_first_index(&entitiesYetToBeRemoved, ent, ecs_pk_arr_find_first_matching_pointer) != uint32_t(-1)) {
- grBinds.entHandle = EntityHandle_MAX;
- grBinds.grBindsHandle = GrBindsHandle_MAX;
- grBinds.vkPipelineLayout = VK_NULL_HANDLE;
- grBinds.graphicsPipeline = VK_NULL_HANDLE;
- grBinds.collisionCallback = PkeCallback{};
- /*
- * 2023-09-05 JB note - the Vulkan assets (device memory, buffers,
- * pipeline layout, and descriptor set) are unloaded elsewhere, just,
- * as they were created elsewhere.
- */
- }
- if (afterIndex != uint32_t(-1)) {
- auto &after = updateGrBinds[afterIndex];
- grBinds.instanceCounter -= after.count;
- }
+ inst.entHandle = EntityHandle_MAX;
+ inst.grBindsHandle = GrBindsHandle_MAX;
+ inst.index = ECS_UNSET_VAL_32;
+ inst.instanceHandle = InstanceHandle_MAX;
+ inst.isNeedingUpdated = false;
+ BtDynamicsWorld->removeRigidBody(inst.bt.rigidBody);
+ pk_delete<btDefaultMotionState>(inst.bt.motionState, MemBkt_Bullet);
+ pk_delete<btRigidBody>(inst.bt.rigidBody, MemBkt_Bullet);
+ inst.bt.rigidBody = CAFE_BABE(btRigidBody);
+ inst.bt.motionState = CAFE_BABE(btDefaultMotionState);
+ return;
+ }
+ if (updateGrBinds.next > 0 && inst.instanceHandle != InstanceHandle_MAX) {
+ uint32_t afterIndex = pk_arr_find_first_index(&updateGrBinds, &inst.grBindsHandle, ecs_pk_arr_find_by_gr_binds_handle);
+ if (afterIndex != uint32_t(-1)) {
+ auto &after = updateGrBinds[afterIndex];
+ inst.index -= after.count;
+ inst.isNeedingUpdated = true;
}
}
+ };
+ pk_bkt_arr_iterate(&ecs.bc.instances, &InstIterFn::invoke, &inst_iter_cb);
+
+ grbinds_iter_cb.func = [&updateGrBinds](CompGrBinds *arr_obj_data) {
+ CompGrBinds &grBinds = *arr_obj_data;
+ uint32_t afterIndex = pk_arr_find_first_index(&updateGrBinds, &grBinds.grBindsHandle, ecs_pk_arr_find_by_gr_binds_handle);
+ Entity_Base *ent = ecs.bc.entityPtrs[grBinds.entHandle];
+ if (pk_arr_find_first_index(&entitiesYetToBeRemoved, ent, ecs_pk_arr_find_first_matching_pointer) != uint32_t(-1)) {
+ grBinds.entHandle = EntityHandle_MAX;
+ grBinds.grBindsHandle = GrBindsHandle_MAX;
+ grBinds.vkPipelineLayout = VK_NULL_HANDLE;
+ grBinds.graphicsPipeline = VK_NULL_HANDLE;
+ grBinds.collisionCallback = PkeCallback{};
+ /*
+ * 2023-09-05 JB note - the Vulkan assets (device memory, buffers,
+ * pipeline layout, and descriptor set) are unloaded elsewhere, just,
+ * as they were created elsewhere.
+ */
+ }
+ if (afterIndex != uint32_t(-1)) {
+ auto &after = updateGrBinds[afterIndex];
+ grBinds.instanceCounter -= after.count;
+ }
+ };
+ if (entityRemovalCount > 0 || updateGrBinds.next > 0) {
+ pk_bkt_arr_iterate(&ecs.bc.grBinds, &GrBindsIterFn::invoke, &grbinds_iter_cb);
}
}
@@ -274,69 +275,71 @@ void ECS_Tick_Late(double delta) {
PKVK_TmpBufferDetails tmpBufferDetails{};
pk_arr_t<InstanceBufferCopy> bufferUpdates;
bufferUpdates.bkt = pkeSettings.mem.bkt;
- for (long b = 0; b <= ecs.bc.instances.pkeHandle.bucketIndex; ++b) {
- auto &bkt = ecs.bc.instances.buckets[b];
- long count = ecs.bc.instances.pkeHandle.bucketIndex == b ? ecs.bc.instances.pkeHandle.itemIndex : ecs.bc.instances.limits.itemIndex;
- for (uint32_t i = 0; i < count; ++i) {
- auto &inst = bkt[i];
- if (inst.isNeedingUpdated == false)
- continue;
- if (inst.entHandle == EntityHandle_MAX)
- continue;
- if (inst.grBindsHandle == GrBindsHandle_MAX)
- continue;
-
- auto &grBinds = ecs.bc.grBinds.buckets[inst.grBindsHandle.bucketIndex][inst.grBindsHandle.itemIndex];
-
- InstanceBufferCopy *bfrUpdate = nullptr;
- for (long u = 0; u < bufferUpdates.next; ++u) {
- if (bufferUpdates[u].grBinds->grBindsHandle == inst.grBindsHandle) {
- bfrUpdate = &bufferUpdates[u];
- }
- }
- if (bfrUpdate == nullptr) {
- InstanceBufferCopy tmp{};
- tmp.grBinds = &grBinds;
- tmp.chunks.bkt = pkeSettings.mem.bkt;
- pk_arr_append_t(&bufferUpdates, tmp);
- bfrUpdate = &bufferUpdates[bufferUpdates.next-1];
- pk_arr_reserve(&bfrUpdate->chunks, 4);
- }
- InstanceBufferCopyChunk *chunk = nullptr;
- for (long ii = 0; ii < bfrUpdate->chunks.next; ++ii) {
- if (bfrUpdate->chunks[ii].endingIndex == inst.index - 1) {
- chunk = &bfrUpdate->chunks[ii];
- chunk->endingIndex += 1;
- break;
- }
+ using InstIterFn = pk_tmpln_1<void, CompInstance*, void*>;
+ InstIterFn inst_iter_cb{};
+
+ inst_iter_cb.func = [&bufferUpdates](CompInstance *arr_obj_data) {
+ CompInstance &inst = *arr_obj_data;
+ if (inst.isNeedingUpdated == false)
+ return;
+ if (inst.entHandle == EntityHandle_MAX)
+ return;
+ if (inst.grBindsHandle == GrBindsHandle_MAX)
+ return;
+
+ auto &grBinds = ecs.bc.grBinds[inst.grBindsHandle];
+
+ InstanceBufferCopy *bfrUpdate = nullptr;
+ for (long u = 0; u < bufferUpdates.next; ++u) {
+ if (bufferUpdates[u].grBinds->grBindsHandle == inst.grBindsHandle) {
+ bfrUpdate = &bufferUpdates[u];
}
- if (chunk == nullptr) {
- InstanceBufferCopyChunk tmp{};
- tmp.startingIndex = inst.index;
- tmp.endingIndex = inst.index;
- tmp.mats.bkt = pkeSettings.mem.bkt;
- tmp.dstBufferCopy = {};
- pk_arr_append_t(&bfrUpdate->chunks, tmp);
- chunk = &bfrUpdate->chunks[bfrUpdate->chunks.next-1];
- chunk->dstBufferCopy.dstOffset = sizeof(glm::mat4) * inst.index;
- pk_arr_reserve(&chunk->mats, 4);
+ }
+ if (bfrUpdate == nullptr) {
+ InstanceBufferCopy tmp{};
+ tmp.grBinds = &grBinds;
+ tmp.chunks.bkt = pkeSettings.mem.bkt;
+ pk_arr_append_t(&bufferUpdates, tmp);
+ bfrUpdate = &bufferUpdates[bufferUpdates.next-1];
+ pk_arr_reserve(&bfrUpdate->chunks, 4);
+ }
+
+ InstanceBufferCopyChunk *chunk = nullptr;
+ for (long ii = 0; ii < bfrUpdate->chunks.next; ++ii) {
+ if (bfrUpdate->chunks[ii].endingIndex == inst.index - 1) {
+ chunk = &bfrUpdate->chunks[ii];
+ chunk->endingIndex += 1;
+ break;
}
+ }
+ if (chunk == nullptr) {
+ InstanceBufferCopyChunk tmp{};
+ tmp.startingIndex = inst.index;
+ tmp.endingIndex = inst.index;
+ tmp.mats.bkt = pkeSettings.mem.bkt;
+ tmp.dstBufferCopy = {};
+ pk_arr_append_t(&bfrUpdate->chunks, tmp);
+ chunk = &bfrUpdate->chunks[bfrUpdate->chunks.next-1];
+ chunk->dstBufferCopy.dstOffset = sizeof(glm::mat4) * inst.index;
+ pk_arr_reserve(&chunk->mats, 4);
+ }
- btTransform btMatrix_posRot;
- inst.bt.motionState->getWorldTransform(btMatrix_posRot);
- float openglMatrix[16];
- btMatrix_posRot.getOpenGLMatrix(openglMatrix);
- glm::mat4 glmMat_posRot = glm::make_mat4(openglMatrix);
+ btTransform btMatrix_posRot;
+ inst.bt.motionState->getWorldTransform(btMatrix_posRot);
+ float openglMatrix[16];
+ btMatrix_posRot.getOpenGLMatrix(openglMatrix);
+ glm::mat4 glmMat_posRot = glm::make_mat4(openglMatrix);
- glm::vec3 scale;
- BulletToGlm(inst.bt.rigidBody->getCollisionShape()->getLocalScaling(), scale);
+ glm::vec3 scale;
+ BulletToGlm(inst.bt.rigidBody->getCollisionShape()->getLocalScaling(), scale);
+
+ pk_arr_append_t(&chunk->mats, glm::scale(glmMat_posRot, scale));
+ bfrUpdate->runningSize += sizeof(glm::mat4);
+ inst.isNeedingUpdated = false;
+ };
+ pk_bkt_arr_iterate(&ecs.bc.instances, &InstIterFn::invoke, &inst_iter_cb);
- pk_arr_append_t(&chunk->mats, glm::scale(glmMat_posRot, scale));
- bfrUpdate->runningSize += sizeof(glm::mat4);
- inst.isNeedingUpdated = false;
- }
- }
while (bufferUpdates.next > 0) {
InstanceBufferCopy &ibc = bufferUpdates[bufferUpdates.next - 1];
@@ -422,8 +425,8 @@ void ECS_HandleCollision(CompInstance *lhsInst, CompInstance *rhsInst) {
CompGrBinds *ECS_CreateGrBinds(Entity_Base *entity) {
assert(entity != nullptr && entity != CAFE_BABE(Entity_Base));
- GrBindsHandle grBindsHandle{Buckets_NewHandle(ecs.bc.grBinds)};
- auto *comp = &ecs.bc.grBinds.buckets[grBindsHandle.bucketIndex][grBindsHandle.itemIndex];
+ GrBindsHandle grBindsHandle{pk_bkt_arr_new_handle(&ecs.bc.grBinds)};
+ auto *comp = &ecs.bc.grBinds[grBindsHandle];
comp = new (comp) CompGrBinds{};
comp->entHandle = entity->handle;
comp->grBindsHandle = grBindsHandle;
@@ -433,44 +436,37 @@ CompGrBinds *ECS_CreateGrBinds(Entity_Base *entity) {
CompGrBinds *ECS_GetGrBinds(GrBindsHandle grBindsHandle) {
if (grBindsHandle == GrBindsHandle_MAX) return nullptr;
- assert(pk_handle_validate(grBindsHandle, ecs.bc.grBinds.pkeHandle, ecs.bc.grBinds.limits.itemIndex) == PK_HANDLE_VALIDATION_VALID);
- return &ecs.bc.grBinds.buckets[grBindsHandle.bucketIndex][grBindsHandle.itemIndex];
+ assert(pk_bkt_arr_handle_validate(&ecs.bc.grBinds, grBindsHandle) == PK_BKT_ARR_HANDLE_VALIDATION_VALID);
+ return &ecs.bc.grBinds[grBindsHandle];
}
void ECS_GetGrBinds(Entity_Base *entity, pk_arr_t<CompGrBinds *> &arr) {
if (entity == nullptr) return;
- for (pk_handle_bucket_index_T b = 0; b <= ecs.bc.grBinds.pkeHandle.bucketIndex; ++b) {
- auto &bkt = ecs.bc.grBinds.buckets[b];
- long itemCount = ecs.bc.grBinds.pkeHandle.bucketIndex == b ? ecs.bc.grBinds.pkeHandle.itemIndex : ecs.bc.grBinds.limits.itemIndex;
- for (pk_handle_item_index_T i = 0; i < itemCount; ++i) {
- CompGrBinds *grBinds = &bkt[i];
- if (grBinds->entHandle == entity->handle) {
- pk_arr_append(&arr, &grBinds);
- }
- }
- }
-}
-uint64_t ECS_GetGrBinds_BucketCount() {
- return ecs.bc.grBinds.pkeHandle.bucketIndex + 1;
+ // 2025-05-29 JCB PERF
+ // There's gotta be a better way to do this than looping ALL GrBinds...
+ // Let's leave it until it shows up in performance tests.
+
+ using GrBindsIterFn = pk_tmpln_1<void, CompGrBinds *, void *>;
+ GrBindsIterFn gr_binds_iter_cb{};
+
+ gr_binds_iter_cb.func = [&entity, &arr](CompGrBinds *arr_obj_data) {
+ if (arr_obj_data->entHandle == entity->handle) {
+ pk_arr_append(&arr, &arr_obj_data);
+ }
+ };
+ pk_bkt_arr_iterate(&ecs.bc.grBinds, &GrBindsIterFn::invoke, &gr_binds_iter_cb);
}
-CompGrBinds *ECS_GetGrBinds(pk_handle_bucket_index_T bucketIndex, pk_handle_item_index_T &itemCount) {
- if (bucketIndex == ecs.bc.grBinds.pkeHandle.bucketIndex) {
- itemCount = ecs.bc.grBinds.pkeHandle.itemIndex;
- } else {
- itemCount = ecs.bc.grBinds.limits.itemIndex;
- }
- return ecs.bc.grBinds.buckets[bucketIndex];
+pk_bkt_arr *ECS_GetGrBinds() {
+ return &ecs.bc.grBinds;
}
CompInstance *ECS_CreateInstance(Entity_Base *entity, pk_uuid uuid, CompGrBinds *entityTypeGrBinds, InstPos *inst_pos) {
assert(entity != nullptr && entity != CAFE_BABE(Entity_Base));
- InstanceHandle instanceHandle{Buckets_NewHandle(ecs.bc.instances)};
-
- auto *instBkt = ecs.bc.instances.buckets[instanceHandle.bucketIndex];
- auto *comp = &instBkt[instanceHandle.itemIndex];
+ InstanceHandle instanceHandle{pk_bkt_arr_new_handle(&ecs.bc.instances)};
+ auto *comp = &ecs.bc.instances[instanceHandle];
new (comp) CompInstance{};
comp->entHandle = entity->handle;
comp->instanceHandle = instanceHandle;
@@ -514,24 +510,28 @@ CompInstance *ECS_CreateInstance(Entity_Base *entity, pk_uuid uuid, CompGrBinds
CompInstance *ECS_GetInstance(InstanceHandle instanceHandle ) {
if (instanceHandle == InstanceHandle_MAX) return nullptr;
- assert(pk_handle_validate(instanceHandle, ecs.bc.instances.pkeHandle, ecs.bc.instances.limits.itemIndex) == PK_HANDLE_VALIDATION_VALID);
- auto *inst = &ecs.bc.instances.buckets[instanceHandle.bucketIndex][instanceHandle.itemIndex];
+ assert(pk_bkt_arr_handle_validate(&ecs.bc.instances, instanceHandle) == PK_BKT_ARR_HANDLE_VALIDATION_VALID);
+ auto *inst = &ecs.bc.instances[instanceHandle];
return inst;
}
void ECS_GetInstances(Entity_Base *entity, pk_arr_t<CompInstance *> &arr) {
if (entity == nullptr) return;
- for (pk_handle_bucket_index_T b = 0; b <= ecs.bc.instances.pkeHandle.bucketIndex; ++b) {
- auto &bkt = ecs.bc.instances.buckets[b];
- long itemCount = ecs.bc.instances.pkeHandle.bucketIndex == b ? ecs.bc.instances.pkeHandle.itemIndex : ecs.bc.instances.limits.itemIndex;
- for (pk_handle_item_index_T i = 0; i < itemCount; ++i) {
- CompInstance *inst = &bkt[i];
- if (inst->entHandle == entity->handle) {
- pk_arr_append(&arr, &inst);
- }
+
+ // 2025-05-29 JCB PERF
+ // There's gotta be a better way to do this than looping ALL GrBinds...
+ // Let's leave it until it shows up in performance tests.
+
+ using InstIterFn = pk_tmpln_1<void, CompInstance *, void *>;
+ InstIterFn inst_iter_cb{};
+
+ inst_iter_cb.func = [&entity, &arr](CompInstance *arr_obj_data) {
+ if (arr_obj_data->entHandle == entity->handle) {
+ pk_arr_append(&arr, &arr_obj_data);
}
- }
+ };
+ pk_bkt_arr_iterate(&ecs.bc.instances, &InstIterFn::invoke, &inst_iter_cb);
}
void ECS_UpdateInstance(CompInstance *instance, const InstPos &instPos, bool overridePhysics) {
@@ -549,17 +549,8 @@ void ECS_UpdateInstance(CompInstance *instance, const InstPos &instPos, bool ove
}
}
-uint64_t ECS_GetInstances_BucketCount() {
- return ecs.bc.instances.pkeHandle.bucketIndex + 1;
-}
-
-CompInstance *ECS_GetInstances(pk_handle_bucket_index_T bucketIndex, pk_handle_item_index_T &itemCount) {
- if (bucketIndex == ecs.bc.instances.pkeHandle.bucketIndex) {
- itemCount = ecs.bc.instances.pkeHandle.itemIndex;
- } else {
- itemCount = ecs.bc.instances.limits.itemIndex;
- }
- return ecs.bc.instances.buckets[bucketIndex];
+pk_bkt_arr *ECS_GetInstances() {
+ return &ecs.bc.instances;
}
void ECS_Teardown() {
@@ -567,8 +558,8 @@ void ECS_Teardown() {
pk_arr_reset(&entitiesYetToBeRemoved);
pk_arr_reset(&EntitiesToBeRemoved);
pk_arr_reset(&entitiesMarkedForRemoval);
- Buckets_Destroy(ecs.bc.instances);
- Buckets_Destroy(ecs.bc.grBinds);
- Buckets_Destroy(ecs.bc.entityPtrs);
- Buckets_Destroy(ecs.bc.generics);
+ ecs.bc.instances.~pk_bkt_arr_t<CompInstance>();
+ ecs.bc.grBinds.~pk_bkt_arr_t<CompGrBinds>();
+ ecs.bc.entityPtrs.~pk_bkt_arr_t<Entity_Base*>();
+ ecs.bc.generics.~pk_bkt_arr_t<Entity_Base>();
}
diff --git a/src/ecs.hpp b/src/ecs.hpp
index 7be6eac..91202c4 100644
--- a/src/ecs.hpp
+++ b/src/ecs.hpp
@@ -26,14 +26,12 @@ void ECS_HandleCollision(CompInstance *lhs, CompInstance *rhs);
CompGrBinds *ECS_CreateGrBinds(Entity_Base *);
CompGrBinds *ECS_GetGrBinds(GrBindsHandle grBindsHandle);
void ECS_GetGrBinds(Entity_Base *entity, pk_arr_t<CompGrBinds *> &arr);
-uint64_t ECS_GetGrBinds_BucketCount();
-CompGrBinds *ECS_GetGrBinds(pk_handle_bucket_index_T bucketIndex, pk_handle_item_index_T &itemCount);
+pk_bkt_arr *ECS_GetGrBinds();
CompInstance *ECS_CreateInstance(Entity_Base *entity, pk_uuid uuid, CompGrBinds *entityTypeGrBinds, InstPos *instance_pos);
CompInstance *ECS_GetInstance(InstanceHandle instanceHandle);
void ECS_GetInstances(Entity_Base *entity, pk_arr_t<CompInstance *> &arr);
void ECS_UpdateInstance(CompInstance *instance, const InstPos &instPos, bool overridePhysics = false);
-uint64_t ECS_GetInstances_BucketCount();
-CompInstance *ECS_GetInstances(pk_handle_bucket_index_T bucketIndex, pk_handle_item_index_T &itemCount);
+pk_bkt_arr *ECS_GetInstances();
#endif /* PKE_ECS_HPP */
diff --git a/src/entities.cpp b/src/entities.cpp
index 6b9cff4..09e9398 100644
--- a/src/entities.cpp
+++ b/src/entities.cpp
@@ -116,9 +116,10 @@ EntityType *EntityType_FindByTypeCode(const char *typeCode) {
EntityType *EntityType_FindByEntityHandle_Inner(EntityHandle handle) {
if (handle == EntityHandle_MAX) return nullptr;
- if (handle.bucketIndex > EntityType_BC.limits.bucketIndex) return nullptr;
- if (handle.itemIndex > EntityType_BC.limits.itemIndex) return nullptr;
- if (handle.bucketIndex == EntityType_BC.pkeHandle.bucketIndex && handle.itemIndex >= EntityType_BC.pkeHandle.itemIndex) return nullptr;
+ // 2025-05-29 JCB these are wrong
+ if (handle.b> EntityType_BC.limits.bucketIndex) return nullptr;
+ if (handle.i> EntityType_BC.limits.itemIndex) return nullptr;
+ if (handle.b== EntityType_BC.pkeHandle.bucketIndex && handle.i>= EntityType_BC.pkeHandle.itemIndex) return nullptr;
for (pk_handle_bucket_index_T b = 0; b <= EntityType_BC.pkeHandle.bucketIndex; ++b) {
auto &bkt = EntityType_BC.buckets[b];
long itemCount = EntityType_BC.pkeHandle.bucketIndex == b ? EntityType_BC.pkeHandle.itemIndex : EntityType_BC.limits.itemIndex;
@@ -281,8 +282,8 @@ void EntityType_Inner_UpdateDescriptorSets_EvCallabck(void *mgr_data, void *enti
(void)ev_data;
EntityHandle eh;
uint64_t id = reinterpret_cast<uint64_t>(entity_data);
- eh.bucketIndex = (pk_handle_bucket_index_T)(id >> 32);
- eh.itemIndex = (pk_handle_item_index_T)((id << 32) >> 32);
+ eh.b = (pk_handle_bucket_index_T)(id >> 32);
+ eh.i = (pk_handle_item_index_T)((id << 32) >> 32);
EntityType *et = EntityType_FindByEntityHandle(eh);
assert(et != nullptr);
@@ -1129,8 +1130,8 @@ void EntityType_Load(EntityType &et) {
EntityType_LoadMesh(helper, i);
}
uint64_t id = 0;
- id |= ((uint64_t)helper.et.handle.bucketIndex << 32);
- id |= ((uint64_t)helper.et.handle.itemIndex);
+ id |= ((uint64_t)helper.et.handle.b << 32);
+ id |= ((uint64_t)helper.et.handle.i);
helper.et.pke_ev_cb_id_framebuffer_resized = pk_ev_register_cb(pke_ev_mgr_id_window, pke_ev_id_framebuffer_length_changed, EntityType_Inner_UpdateDescriptorSets_EvCallabck, reinterpret_cast<void *>(id));
// TODO DeviceMemory
diff --git a/src/font.cpp b/src/font.cpp
index 2c91aa6..cce683b 100644
--- a/src/font.cpp
+++ b/src/font.cpp
@@ -52,8 +52,6 @@ struct FontInstanceBufferItem {
float padding[3];
};
-// BucketContainer<FontType, TextRenderHandle, 2> bktFont;
-
uint32_t utf8_to_unicode(const char* str, uint32_t &out) {
uint32_t i = 0;
out = 0;
@@ -798,7 +796,7 @@ FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&
ft->renders = arr;
}
fr = &ft->renders[(FontRenderIndex_T)idx_fr];
- *fr = {};
+ new (fr) FontRender{};
fr->uuid = uuid;
ECS_CreateEntity(fr, parent);
fr->fr_handle.index_ft = idx_ft;
diff --git a/src/project.cpp b/src/project.cpp
index 289d4b5..546ac8a 100644
--- a/src/project.cpp
+++ b/src/project.cpp
@@ -71,7 +71,7 @@ void Proj_SerializeEntityType(std::ostream &stream, const EntityType &et) {
NULL_CHAR_ARR(handleStr, 23);
NULL_CHAR_ARR(modelAssetKey, AssetKeyLength + 1);
NULL_CHAR_ARR(textureAssetKey, AssetKeyLength + 1);
- snprintf(handleStr, 22, "0x%08X 0x%08X", et.handle.bucketIndex, et.handle.itemIndex);
+ snprintf(handleStr, 22, "0x%08X 0x%08X", et.handle.b, et.handle.i);
snprintf(modelAssetKey, AssetKeyLength + 1, "%s", et.modelAssetKey);
EntityType e{};
if (modelAssetKey[0] != '\0')
@@ -174,7 +174,9 @@ void Proj_DeserializeEntityType(std::istream &stream) {
if (strcmp(PKE_PROJ_FILE_OBJ_END, projReadLine) == 0) {
EntityType *existingPtr = EntityType_FindByTypeCode(et.entityTypeCode.val);
if (existingPtr != nullptr) {
- // TODO leaks et.EntityTypeCode
+ if (et.entityTypeCode.reserved > 0) {
+ pk_delete<char>(et.entityTypeCode.val, et.entityTypeCode.reserved);
+ }
continue;
}
EntityType *etPtr = EntityType_Create(et.uuid);
@@ -209,10 +211,10 @@ void Proj_DeserializeEntityType(std::istream &stream) {
}
if (strstr(projReadLine, PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_TYPE_CODE)) {
uint64_t prefixLen = strlen(PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_TYPE_CODE);
- uint64_t len = strlen(projReadLine + prefixLen) + 1;
- char *val = pk_new<char>(len);
- memset(reinterpret_cast<void *>(val), '\0', len);
- memcpy(val, projReadLine + prefixLen, len);
+ et.entityTypeCode.length = strlen(projReadLine + prefixLen) + 1;
+ et.entityTypeCode.reserved = et.entityTypeCode.length + 1;
+ char *val = pk_new<char>(et.entityTypeCode.reserved);
+ snprintf(val, et.entityTypeCode.reserved, "%s", projReadLine + prefixLen);
et.entityTypeCode.val = val;
continue;
}
@@ -220,8 +222,10 @@ void Proj_DeserializeEntityType(std::istream &stream) {
uint64_t prefixLen = strlen(PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_HANDLE);
// 0x00000000 0x00000000
projReadLine[prefixLen + 10] = '\0';
- STR2NUM_ERROR result1 = str2num(et.handle.bucketIndex, projReadLine + prefixLen + 2, 16);
- STR2NUM_ERROR result2 = str2num(et.handle.itemIndex, projReadLine + prefixLen + 11, 16);
+ unsigned int b, i;
+ STR2NUM_ERROR result1 = str2num(b, projReadLine + prefixLen + 2, 16);
+ STR2NUM_ERROR result2 = str2num(i, projReadLine + prefixLen + 11, 16);
+ et.handle = EntityHandle { b, i };
assert(result1 == STR2NUM_ERROR::SUCCESS);
assert(result2 == STR2NUM_ERROR::SUCCESS);
continue;
diff --git a/src/serialization-component.cpp b/src/serialization-component.cpp
index dac8d35..df6d633 100644
--- a/src/serialization-component.cpp
+++ b/src/serialization-component.cpp
@@ -260,21 +260,27 @@ void pke_deserialize_instance(srlztn_deserialize_helper *h, pke_kve_container *k
if (strstr(kvec->arr[i].key, SRLZTN_INSTANCE_COMPONENT_MASS)) {
stn_res = pk_stn(&mass, kvec->arr[i].val, nullptr);
if (stn_res != PK_STN_RES_SUCCESS) {
- fprintf(stderr, "[pke_deserialize_instance] Failed to parse %s\n", SRLZTN_INSTANCE_COMPONENT_MASS);
+ fprintf(stderr, "[pke_deserialize_instance] Failed to parse %s, %i\n", SRLZTN_INSTANCE_COMPONENT_MASS, stn_res);
}
continue;
}
if (strstr(kvec->arr[i].key, SRLZTN_INSTANCE_COMPONENT_COLLISION_LAYER)) {
- stn_res = pk_stn(&comp.physicsLayer, kvec->arr[i].val, nullptr, 10);
+ PhysicsCollision_T layer;
+ stn_res = pk_stn(&layer, kvec->arr[i].val, nullptr, 10);
if (stn_res != PK_STN_RES_SUCCESS) {
- fprintf(stderr, "[pke_deserialize_instance] Failed to parse %s\n", SRLZTN_INSTANCE_COMPONENT_COLLISION_LAYER);
+ fprintf(stderr, "[pke_deserialize_instance] Failed to parse %s, %i\n", SRLZTN_INSTANCE_COMPONENT_COLLISION_LAYER, stn_res);
+ } else {
+ comp.physicsLayer = PhysicsCollision{layer};
}
continue;
}
if (strstr(kvec->arr[i].key, SRLZTN_INSTANCE_COMPONENT_COLLISION_MASK)) {
- stn_res = pk_stn(&comp.physicsMask, kvec->arr[i].val, nullptr, 10);
+ PhysicsCollision_T mask;
+ stn_res = pk_stn(&mask, kvec->arr[i].val, nullptr, 10);
if (stn_res != PK_STN_RES_SUCCESS) {
- fprintf(stderr, "[pke_deserialize_instance] Failed to parse %s\n", SRLZTN_INSTANCE_COMPONENT_COLLISION_MASK);
+ fprintf(stderr, "[pke_deserialize_instance] Failed to parse %s, %i\n", SRLZTN_INSTANCE_COMPONENT_COLLISION_MASK, stn_res);
+ } else {
+ comp.physicsMask = PhysicsCollision{mask};
}
continue;
}
@@ -284,7 +290,7 @@ void pke_deserialize_instance(srlztn_deserialize_helper *h, pke_kve_container *k
}
}
if (et_ptr == nullptr) {
- fprintf(stdout, "[Game::DeserializeInstance] Unknown EntityTypeCode, skipping instance.\n");
+ fprintf(stdout, "[pke_deserialize_instance] Unknown EntityTypeCode, skipping instance.\n");
}
btVector3 bt_pos;
btQuaternion bt_quat;
diff --git a/src/serialization.cpp b/src/serialization.cpp
index b7691fd..e7e1d4c 100644
--- a/src/serialization.cpp
+++ b/src/serialization.cpp
@@ -65,7 +65,10 @@ void pke_deserialize_project_from_stream(std::istream &i, srlztn_deserialize_hel
void pke_serialize_scene(srlztn_serialize_helper *h) {
using CamIterFn = pk_tmpln_1<void, PkeCamera*, void*>;
+ using InstIterFn = pk_tmpln_1<void, CompInstance*, void*>;
CamIterFn cam_iter_cb{};
+ InstIterFn inst_iter_cb{};
+
FontTypeIndex font_type_count;
FontType *fonts = FontType_GetFonts(font_type_count);
for (FontTypeIndex_T b = 0; b < (FontTypeIndex_T)font_type_count; ++b) {
@@ -84,18 +87,14 @@ void pke_serialize_scene(srlztn_serialize_helper *h) {
pke_serialize_ui_box(h, ui_boxes[i]);
}
- pk_handle_bucket_index_T instanceBucketCount = ECS_GetInstances_BucketCount();
- for (pk_handle_bucket_index_T b = 0; b < instanceBucketCount; ++b) {
- pk_handle_item_index_T count;
- auto *instances = ECS_GetInstances(b, count);
- for (pk_handle_item_index_T i = 0; i < count; ++i) {
- const auto &instance = instances[i];
- if (PK_HAS_FLAG(instance.comp_instance_flags, COMPONENT_INSTANCE_FLAG_DO_NOT_SERIALIZE)) {
- continue;
- }
- pke_serialize_instance(h, &instance);
+ inst_iter_cb.func = [&h](CompInstance *instance_ptr) {
+ const auto &instance = *instance_ptr;
+ if (PK_HAS_FLAG(instance.comp_instance_flags, COMPONENT_INSTANCE_FLAG_DO_NOT_SERIALIZE)) {
+ return;
}
- }
+ pke_serialize_instance(h, &instance);
+ };
+ pk_bkt_arr_iterate(ECS_GetInstances(), &InstIterFn::invoke, &inst_iter_cb);
cam_iter_cb.func = [&h](PkeCamera *cam_ptr) {
if (cam_ptr->camHandle == CameraHandle_MAX) {
diff --git a/src/window.cpp b/src/window.cpp
index acbe00e..2c2cf52 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -3194,44 +3194,42 @@ void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
VkDeviceSize offsets[1] = {0U};
- pk_handle_bucket_index_T bindBucketCount = ECS_GetGrBinds_BucketCount();
- for (pk_handle_bucket_index_T b = 0; b < bindBucketCount; ++b) {
- pk_handle_item_index_T itemCount;
- CompGrBinds *items = ECS_GetGrBinds(b, itemCount);
- for (pk_handle_item_index_T i = 0; i < itemCount; ++i) {
- CompGrBinds *binder = &items[i];
- if (binder->grBindsHandle == GrBindsHandle_MAX)
- continue;
- if (!binder->vkPipelineLayout)
- continue;
- if (binder->instanceBD.bindingCount < 1) {
- continue;
- }
- vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, binder->graphicsPipeline);
- vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, binder->vkPipelineLayout, 0, 1, &binder->vkDescriptorSets[imageIndex], 0, {});
- vkCmdBindVertexBuffers(commandBuffer, 0, 1, &UniformBuffers[imageIndex], offsets);
- vkCmdBindIndexBuffer(commandBuffer, binder->indexBD.buffer, binder->indexBD.offsets[0], VK_INDEX_TYPE_UINT16);
+ using GrBindsIterFn = pk_tmpln_1<void, CompGrBinds*, void*>;
+ GrBindsIterFn gr_binds_iter_cb{};
+ gr_binds_iter_cb.func = [commandBuffer, imageIndex](CompGrBinds *binder) {
+ VkDeviceSize offsets[1] = {0U};
+ if (binder->grBindsHandle == GrBindsHandle_MAX)
+ return;
+ if (!binder->vkPipelineLayout)
+ return;
+ if (binder->instanceBD.bindingCount < 1) {
+ return;
+ }
+ vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, binder->graphicsPipeline);
+ vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, binder->vkPipelineLayout, 0, 1, &binder->vkDescriptorSets[imageIndex], 0, {});
+ vkCmdBindVertexBuffers(commandBuffer, 0, 1, &UniformBuffers[imageIndex], offsets);
+ vkCmdBindIndexBuffer(commandBuffer, binder->indexBD.buffer, binder->indexBD.offsets[0], VK_INDEX_TYPE_UINT16);
- vkCmdBindVertexBuffers(commandBuffer, binder->vertexBD.firstBinding, binder->vertexBD.bindingCount, &binder->vertexBD.buffer, binder->vertexBD.offsets);
- vkCmdBindVertexBuffers(commandBuffer, binder->normalsBD.firstBinding, binder->normalsBD.bindingCount, &binder->normalsBD.buffer, binder->normalsBD.offsets);
- vkCmdBindVertexBuffers(commandBuffer, binder->uvBD.firstBinding, binder->uvBD.bindingCount, &binder->uvBD.buffer, binder->uvBD.offsets);
- vkCmdBindVertexBuffers(commandBuffer, binder->instanceBD.firstBinding, binder->instanceBD.bindingCount, &binder->instanceBD.buffer, binder->instanceBD.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, binder->vertexBD.firstBinding, binder->vertexBD.bindingCount, &binder->vertexBD.buffer, binder->vertexBD.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, binder->normalsBD.firstBinding, binder->normalsBD.bindingCount, &binder->normalsBD.buffer, binder->normalsBD.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, binder->uvBD.firstBinding, binder->uvBD.bindingCount, &binder->uvBD.buffer, binder->uvBD.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, binder->instanceBD.firstBinding, binder->instanceBD.bindingCount, &binder->instanceBD.buffer, binder->instanceBD.offsets);
- vkCmdDrawIndexed(commandBuffer, binder->indexCount, binder->instanceCounter, 0, 0, 0);
+ vkCmdDrawIndexed(commandBuffer, binder->indexCount, binder->instanceCounter, 0, 0, 0);
- if (pkeSettings.isRenderingDebug) {
- vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipelines.named.entity_wireframe);
- vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipe_layouts.named.ubo_txtr, 0, 1, &pkeDebugHitbox.vkDescriptorSets[imageIndex], 0, {});
+ if (pkeSettings.isRenderingDebug) {
+ vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipelines.named.entity_wireframe);
+ vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipe_layouts.named.ubo_txtr, 0, 1, &pkeDebugHitbox.vkDescriptorSets[imageIndex], 0, {});
- vkCmdBindVertexBuffers(commandBuffer, binder->physVertBD.firstBinding, 1, &binder->physVertBD.buffer, binder->physVertBD.offsets);
- vkCmdBindVertexBuffers(commandBuffer, binder->physNormBD.firstBinding, 1, &binder->physNormBD.buffer, binder->physVertBD.offsets);
- vkCmdBindVertexBuffers(commandBuffer, binder->physUvBD.firstBinding, 1, &binder->physUvBD.buffer, binder->physVertBD.offsets);
- vkCmdBindIndexBuffer(commandBuffer, binder->physIndxBD.buffer, binder->physIndxBD.offsets[0], VK_INDEX_TYPE_UINT16);
+ vkCmdBindVertexBuffers(commandBuffer, binder->physVertBD.firstBinding, 1, &binder->physVertBD.buffer, binder->physVertBD.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, binder->physNormBD.firstBinding, 1, &binder->physNormBD.buffer, binder->physVertBD.offsets);
+ vkCmdBindVertexBuffers(commandBuffer, binder->physUvBD.firstBinding, 1, &binder->physUvBD.buffer, binder->physVertBD.offsets);
+ vkCmdBindIndexBuffer(commandBuffer, binder->physIndxBD.buffer, binder->physIndxBD.offsets[0], VK_INDEX_TYPE_UINT16);
- vkCmdDrawIndexed(commandBuffer, binder->physIndxBD.bindingCount, binder->instanceCounter, 0, 0, 0);
- }
+ vkCmdDrawIndexed(commandBuffer, binder->physIndxBD.bindingCount, binder->instanceCounter, 0, 0, 0);
}
- }
+ };
+ pk_bkt_arr_iterate(ECS_GetGrBinds(), &GrBindsIterFn::invoke, &gr_binds_iter_cb);
if (pkeDebugHitbox.instanceBuffer != VK_NULL_HANDLE) {
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pkePipelines.pipelines.named.entity_wireframe);