diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-05-29 16:11:37 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-05-29 16:11:37 -0400 |
| commit | d9dc3559296661249f9e5f1c3d0a8320cbf8fc29 (patch) | |
| tree | 2a0203b676f15e8933960e786c8181354f73b121 | |
| parent | a9bc23377bd9193cd3eb3ef2e91431d088d13d5d (diff) | |
pke: ecs: BucketContainer > pk_bkt_arr_t & cleanup
| -rw-r--r-- | editor/editor.cpp | 59 | ||||
| -rw-r--r-- | src/asset-manager.cpp | 2 | ||||
| -rw-r--r-- | src/components.hpp | 14 | ||||
| -rw-r--r-- | src/ecs.cpp | 459 | ||||
| -rw-r--r-- | src/ecs.hpp | 6 | ||||
| -rw-r--r-- | src/entities.cpp | 15 | ||||
| -rw-r--r-- | src/font.cpp | 4 | ||||
| -rw-r--r-- | src/project.cpp | 20 | ||||
| -rw-r--r-- | src/serialization-component.cpp | 18 | ||||
| -rw-r--r-- | src/serialization.cpp | 21 | ||||
| -rw-r--r-- | src/window.cpp | 62 |
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); |
