diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-05-30 14:41:54 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-05-30 14:41:54 -0400 |
| commit | 781410537a1c7ddac340efabeedd4c9309e5cf39 (patch) | |
| tree | 7253babcfc7fd8766095fdf89eca7a9fd3952912 | |
| parent | 6ff0a1f8f7775752db8219dc270a56c4e64b4c7e (diff) | |
pke: asset: BucketContainer>pk_bkt_arr_t & cleanup
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | editor/editor.cpp | 112 | ||||
| -rw-r--r-- | src/asset-manager.cpp | 166 | ||||
| -rw-r--r-- | src/asset-manager.hpp | 15 | ||||
| -rw-r--r-- | src/project.cpp | 57 | ||||
| -rw-r--r-- | src/window.cpp | 2 | ||||
| -rw-r--r-- | tests/pke-test-asset-manager.cpp | 47 | ||||
| -rw-r--r-- | tests/pke-test-asset-manager.h | 16 | ||||
| -rw-r--r-- | tests/pke-test.cpp | 4 |
9 files changed, 230 insertions, 191 deletions
@@ -299,11 +299,13 @@ $(DIR_DBG)/libpke-example.a: $(DIR_OBJ)/example.so $(DIR_BIN)/libpke-test.a: $(DIR_OBJ)/pke-test-dummy.o $(DIR_BIN)/libpke-test.a: $(DIR_OBJ)/pke-test-static-ui.o $(DIR_BIN)/libpke-test.a: $(DIR_OBJ)/pke-test-serialization.o +$(DIR_BIN)/libpke-test.a: $(DIR_OBJ)/pke-test-asset-manager.o ar rcs $@ $(filter %.o,$^) $(DIR_DBG)/libpke-test.a: $(DIR_OBJ)/pke-test-dummy.so $(DIR_DBG)/libpke-test.a: $(DIR_OBJ)/pke-test-static-ui.so $(DIR_DBG)/libpke-test.a: $(DIR_OBJ)/pke-test-serialization.so +$(DIR_DBG)/libpke-test.a: $(DIR_OBJ)/pke-test-asset-manager.so ar rcs $@ $(filter %.so,$^) $(DIR_BIN)/pke-editor: $(DIR_BIN)/libpke-editor.a $(DIR_BIN)/libpke.a $(DIR_BIN)/libImgui.a $(DIR_BIN)/libBullet3.a diff --git a/editor/editor.cpp b/editor/editor.cpp index 667508d..3de8d85 100644 --- a/editor/editor.cpp +++ b/editor/editor.cpp @@ -534,22 +534,19 @@ struct AssetPickerSearchStruct { AssetType type{PKE_ASSET_TYPE_ALL}; }; void RecordImGui_AssetPicker(AssetPickerSearchStruct &apss) { - assetLabel tmp{}; if (shouldRebuildAssetList == true) { if (assetEntries.next == 0) { - pk_handle_bucket_index_T bCount = AM_GetBucketCount(); - for (pk_handle_bucket_index_T b = 0; b < bCount; ++b) { - pk_handle_item_index_T iCount = 0; - Asset *assets = AM_GetAssets(b, iCount); - for (pk_handle_item_index_T i = 0; i < iCount; ++i) { - const Asset &a = assets[i]; - tmp.key[AssetKeyLength-1] = '\0'; - tmp.handle = a.handle; - tmp.type = a.type; - strncpy(tmp.key, a.key, AssetKeyLength); - pk_arr_append_t(&assetEntries, tmp); - } - } + auto asset_iter_fn = [](void *user_data, void *arr_obj_data) { + (void)user_data; + assetLabel tmp{}; + const Asset &a = *reinterpret_cast<Asset*>(arr_obj_data); + tmp.key[AssetKeyLength-1] = '\0'; + tmp.handle = a.handle; + tmp.type = a.type; + strncpy(tmp.key, a.key, AssetKeyLength); + pk_arr_append_t(&assetEntries, tmp); + }; + pk_bkt_arr_iterate(AM_GetAssets(), asset_iter_fn, NULL); } std::qsort(assetEntries.data, assetEntries.next, sizeof(assetLabel), assetLabelCmp); } @@ -576,12 +573,12 @@ void RecordImGui_AssetPicker(AssetPickerSearchStruct &apss) { void RecordImGuiModalCreateAsset() { if (ImGui::BeginPopupModal("CreateAsset", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { static char assetPath[256]; - static char assetKey[AssetKeyLength + 1]; + static char assetKeyBuffer[AssetKeyLength + 1]; static AssetType type; assetPath[255] = '\0'; - assetKey[AssetKeyLength] = '\0'; + assetKeyBuffer[AssetKeyLength] = '\0'; - ImGui::InputText("Asset Key", assetKey, AssetKeyLength); + ImGui::InputText("Asset Key", assetKeyBuffer, AssetKeyLength+1); static uint32_t assetTypeMask = 0U; if (ImGui::CheckboxFlags("Shader", &assetTypeMask, 1U << static_cast<AssetType_T>(PKE_ASSET_TYPE_SHADER))) { @@ -620,6 +617,8 @@ void RecordImGuiModalCreateAsset() { bool shouldClose = false; if (ImGui::Button("Create")) { + AssetKey assetKey = {'\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'}; + memcpy(assetKey, assetKeyBuffer, PK_MIN(AssetKeyLength, strlen(assetKeyBuffer))); AM_Register(assetKey, type, assetPath); shouldRebuildAssetList = true; pk_arr_clear(&assetEntries); @@ -633,7 +632,7 @@ void RecordImGuiModalCreateAsset() { if (shouldClose) { type = PKE_ASSET_TYPE_UNSET; assetTypeMask = 0U; - assetKey[0] = '\0'; + assetKeyBuffer[0] = '\0'; assetPath[0] = '\0'; ImGui::CloseCurrentPopup(); } @@ -975,23 +974,18 @@ bool RecordImGui_GenerateMTSDFModal() { ImGui::Text("Select font:"); ImGui::BeginDisabled(msdf_settings.minimum_scale <= 0.0 || msdf_settings.px_range <= 0.0); - pk_handle_bucket_index_T asset_bucket_count = AM_GetBucketCount(); - for (pk_handle_bucket_index_T b = 0; b < asset_bucket_count; ++b) { - pk_handle_item_index_T count; - 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 == AssetHandle_MAX) - continue; - if (!PK_HAS_FLAG(asset.type, PKE_ASSET_TYPE_FONT)) { - continue; - } - if (ImGui::Selectable(asset.basePath)) { - GenerateMTSDF(&msdf_settings, &asset); - ImGui::CloseCurrentPopup(); - } + auto asset_iter_fn = [](void *user_data, void *arr_obj_data) { + (void)user_data; + const Asset &a = *reinterpret_cast<Asset*>(arr_obj_data); + if (!PK_HAS_FLAG(a.type, PKE_ASSET_TYPE_FONT)) { + return; } - } + if (ImGui::Selectable(a.basePath)) { + GenerateMTSDF(&msdf_settings, &a); + ImGui::CloseCurrentPopup(); + } + }; + pk_bkt_arr_iterate(AM_GetAssets(), asset_iter_fn, NULL); ImGui::EndDisabled(); ImGui::Separator(); if (ImGui::Button("Cancel")) { @@ -1070,35 +1064,29 @@ void RecordImGuiAssets() { ImGui::TableSetupColumn("Ref Count"); ImGui::TableHeadersRow(); - pk_handle_bucket_index_T asset_bucket_count = AM_GetBucketCount(); - for (pk_handle_bucket_index_T b = 0; b < asset_bucket_count; ++b) { - pk_handle_item_index_T count; - auto *assets = AM_GetAssets(b, count); - ImGui::PushID(b); - for (pk_handle_item_index_T i = 0; i < count; ++i) { - const auto &asset = assets[i]; - if (asset.handle == AssetHandle_MAX) - continue; - ImGui::PushID(i); - ImGui::TableNextRow(); - ImGui::TableSetColumnIndex(0); - // buttons go here - ImGui::TableSetColumnIndex(1); - ImGui::Text("%i", (uint8_t)asset.type); - ImGui::TableSetColumnIndex(2); - ImGui::Text("0x%08X 0x%08X", asset.handle.bucketIndex, asset.handle.itemIndex); - ImGui::TableSetColumnIndex(3); - ImGui::Text("%.16s", asset.key); - ImGui::TableSetColumnIndex(4); - ImGui::Text("%p", asset.ptr); - ImGui::TableSetColumnIndex(5); - ImGui::Text("%li", asset.size); - ImGui::TableSetColumnIndex(6); - ImGui::Text("%hhi", asset.referenceCount); - ImGui::PopID(); - } + size_t counter = 0; + auto asset_iter_fn = [](void *user_data, void *arr_obj_data) { + size_t &counter = *reinterpret_cast<size_t*>(user_data); + const Asset &asset = *reinterpret_cast<Asset*>(arr_obj_data); + ImGui::PushID(counter++); + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + // buttons go here + ImGui::TableSetColumnIndex(1); + ImGui::Text("%i", (uint8_t)asset.type); + ImGui::TableSetColumnIndex(2); + ImGui::Text("0x%.08X 0x%.08X", asset.handle.b, asset.handle.i); + ImGui::TableSetColumnIndex(3); + ImGui::Text("%.16s", asset.key); + ImGui::TableSetColumnIndex(4); + ImGui::Text("%p", asset.ptr); + ImGui::TableSetColumnIndex(5); + ImGui::Text("%li", asset.size); + ImGui::TableSetColumnIndex(6); + ImGui::Text("%hhi", asset.referenceCount); ImGui::PopID(); - } + }; + pk_bkt_arr_iterate(AM_GetAssets(), asset_iter_fn, &counter); ImGui::EndTable(); } ImGui::End(); diff --git a/src/asset-manager.cpp b/src/asset-manager.cpp index a19937a..daaf6da 100644 --- a/src/asset-manager.cpp +++ b/src/asset-manager.cpp @@ -1,7 +1,7 @@ #include "asset-manager.hpp" -#include "bucketed-array.hpp" +#include "pk.h" #include "thread-pool.hpp" #include <cstring> @@ -9,11 +9,10 @@ #include <fstream> #include <future> -const pk_handle_item_index_T maxAssetItemsPerBucket = 64; - -BucketContainer<Asset, AssetHandle> Asset_BucketContainer{}; - -ThreadPoolHandle assetThreadPool = ThreadPoolHandle_MAX; +struct Asset_Master { + pk_bkt_arr_t<Asset> bc{}; + ThreadPoolHandle thread_pool = ThreadPoolHandle_MAX; +} asset_mstr; AssetKey EngineDefinedAssets[EngineDefinedAssetCount] = { "pke_prsnt_vrt\0\0", @@ -27,8 +26,8 @@ AssetKey EngineDefinedAssets[EngineDefinedAssetCount] = { }; void AM_Init() { - Buckets_Init(Asset_BucketContainer, maxAssetItemsPerBucket); - assetThreadPool = PkeThreads_Init(2, 255); + new (&asset_mstr.bc) pk_bkt_arr_t<Asset>{}; + asset_mstr.thread_pool = PkeThreads_Init(2, 255); AM_Register(EngineDefinedAssets[0], PKE_ASSET_TYPE_SHADER, "assets/shaders/present.vert.spv"); AM_Register(EngineDefinedAssets[1], PKE_ASSET_TYPE_SHADER, "assets/shaders/present.frag.spv"); AM_Register(EngineDefinedAssets[2], PKE_ASSET_TYPE_SHADER, "assets/shaders/vertex.vert.spv"); @@ -54,24 +53,19 @@ void AM_Load_Task(Asset &asset) { asset.state = PKE_ASSET_LOADING_STATE_LOADED; } -inline Asset *AM_Get_Inner(AssetKey key) { - for (pk_handle_bucket_index_T b = 0; b <= Asset_BucketContainer.pkeHandle.bucketIndex; ++b) { - pk_handle_item_index_T count = 0; - if (b == Asset_BucketContainer.pkeHandle.bucketIndex) { - count = Asset_BucketContainer.pkeHandle.itemIndex; - } else { - count = maxAssetItemsPerBucket; - } - for (pk_handle_item_index_T i = 0; i < count; ++i) { - if (strncmp(key, Asset_BucketContainer.buckets[b][i].key, 16) == 0) { - return &Asset_BucketContainer.buckets[b][i]; - } - } - } - return nullptr; +inline Asset *AM_Get_Inner(const char (&key)[AssetKeyLength]) { + auto asset_find_cb = [](void *user_data, const void *user_obj_data, const void *arr_obj_data) { + (void)user_data; + const char (&inner_key)[16] = *reinterpret_cast<const char(*&)[16]>(user_obj_data); + const Asset *asset = reinterpret_cast<const Asset *>(arr_obj_data); + return strncmp(inner_key, asset->key, 16) == 0; + }; + AssetHandle handle { pk_bkt_arr_find_first_handle(&asset_mstr.bc, asset_find_cb, NULL, &key[0]) }; + if (handle == AssetHandle_MAX) return nullptr; + return &asset_mstr.bc[handle]; } -AssetHandle AM_Register(AssetKey key, AssetType type, const void *data, int64_t size, std::size_t alignment) { +AssetHandle AM_Register(const AssetKey &key, AssetType type, const void *data, int64_t size, std::size_t alignment) { assert(data != nullptr && "Attempt to register invalid asset data"); assert(data != CAFE_BABE(void) && "Attempt to register invalid asset data"); assert(size != 0 && "Attempt to register asset data of size 0"); @@ -79,8 +73,8 @@ AssetHandle AM_Register(AssetKey key, AssetType type, const void *data, int64_t if (searchedAsset != nullptr) { return searchedAsset->handle; } - AssetHandle assetHandle{Buckets_NewHandle(Asset_BucketContainer)}; - Asset &asset = Asset_BucketContainer.buckets[assetHandle.bucketIndex][assetHandle.itemIndex]; + AssetHandle assetHandle{pk_bkt_arr_new_handle(&asset_mstr.bc)}; + Asset &asset = asset_mstr.bc[assetHandle]; new (&asset) Asset{}; asset.handle = assetHandle; strncpy(asset.key, key, AssetKeyLength); @@ -94,13 +88,13 @@ AssetHandle AM_Register(AssetKey key, AssetType type, const void *data, int64_t return assetHandle; } -AssetHandle AM_Register(AssetKey key, AssetType type, const char *path) { +AssetHandle AM_Register(const AssetKey &key, AssetType type, const char *path) { Asset *searchedAsset = AM_Get_Inner(key); if (searchedAsset != nullptr) { return searchedAsset->handle; } - AssetHandle assetHandle{Buckets_NewHandle(Asset_BucketContainer)}; - Asset &asset = Asset_BucketContainer.buckets[assetHandle.bucketIndex][assetHandle.itemIndex]; + AssetHandle assetHandle{pk_bkt_arr_new_handle(&asset_mstr.bc)}; + Asset &asset = asset_mstr.bc[assetHandle]; new (&asset) Asset{}; asset.handle = assetHandle; strncpy(asset.key, key, AssetKeyLength); @@ -116,7 +110,7 @@ AssetHandle AM_Register(AssetKey key, AssetType type, const char *path) { AM_Load_Task(asset); }); asset.future = task->get_future(); - PkeThreads_Enqueue(assetThreadPool, task); + PkeThreads_Enqueue(asset_mstr.thread_pool, task); return assetHandle; } @@ -131,8 +125,8 @@ AssetHandle AM_Register(const char *path, AssetType type) { return searchedAsset->handle; } - AssetHandle assetHandle{Buckets_NewHandle(Asset_BucketContainer)}; - Asset &asset = Asset_BucketContainer.buckets[assetHandle.bucketIndex][assetHandle.itemIndex]; + AssetHandle assetHandle{pk_bkt_arr_new_handle(&asset_mstr.bc)}; + Asset &asset = asset_mstr.bc[assetHandle]; new (&asset) Asset{}; asset.handle = assetHandle; strncpy(asset.key, assetKey, AssetKeyLength); @@ -147,11 +141,11 @@ AssetHandle AM_Register(const char *path, AssetType type) { AM_Load_Task(asset); }); asset.future = task->get_future(); - PkeThreads_Enqueue(assetThreadPool, task); + PkeThreads_Enqueue(asset_mstr.thread_pool, task); return assetHandle; } -AssetHandle AM_Register_Static(AssetKey key, AssetType type, const void *data, int64_t size) { +AssetHandle AM_Register_Static(const AssetKey &key, AssetType type, const void *data, int64_t size) { assert(data != nullptr && "Attempt to register invalid asset data"); assert(data != CAFE_BABE(void) && "Attempt to register invalid asset data"); assert(size != 0 && "Attempt to register asset data of size 0"); @@ -159,8 +153,8 @@ AssetHandle AM_Register_Static(AssetKey key, AssetType type, const void *data, i if (searchedAsset != nullptr) { return searchedAsset->handle; } - AssetHandle assetHandle{Buckets_NewHandle(Asset_BucketContainer)}; - Asset &asset = Asset_BucketContainer.buckets[assetHandle.bucketIndex][assetHandle.itemIndex]; + AssetHandle assetHandle{pk_bkt_arr_new_handle(&asset_mstr.bc)}; + Asset &asset = asset_mstr.bc[assetHandle]; new (&asset) Asset{}; asset.handle = assetHandle; strncpy(asset.key, key, AssetKeyLength); @@ -175,15 +169,15 @@ AssetHandle AM_Register_Static(AssetKey key, AssetType type, const void *data, i void AM_Release(AssetHandle assetHandle) { assert(assetHandle != AssetHandle_MAX); - Asset &asset = Asset_BucketContainer.buckets[assetHandle.bucketIndex][assetHandle.itemIndex]; + Asset &asset = asset_mstr.bc[assetHandle]; asset.referenceCount -= 1; assert(asset.referenceCount >= 0 && "asset was unloaded more times than it was retrieved"); } const Asset *AM_Get(AssetHandle assetHandle) { - auto validationResult = pk_handle_validate(assetHandle, Asset_BucketContainer.pkeHandle, maxAssetItemsPerBucket); - assert(validationResult == 0); - auto &asset = Asset_BucketContainer.buckets[assetHandle.bucketIndex][assetHandle.itemIndex]; + auto validationResult = pk_bkt_arr_handle_validate(&asset_mstr.bc, assetHandle); + assert(validationResult == PK_BKT_ARR_HANDLE_VALIDATION_VALID); + auto &asset = asset_mstr.bc[assetHandle]; if (asset.state == PKE_ASSET_LOADING_STATE_LOADED) { asset.referenceCount += 1; return &asset; @@ -198,7 +192,7 @@ const Asset *AM_Get(AssetHandle assetHandle) { AM_Load_Task(asset); }); asset.future = task->get_future(); - PkeThreads_Enqueue(assetThreadPool, task); + PkeThreads_Enqueue(asset_mstr.thread_pool, task); } if (asset.state == PKE_ASSET_LOADING_STATE_LOADING) { if (asset.future.valid()) { @@ -215,7 +209,7 @@ const Asset *AM_Get(AssetHandle assetHandle) { return &asset; } -const AssetHandle AM_GetHandle(AssetKey key) { +const AssetHandle AM_GetHandle(const AssetKey &key) { Asset *searchedAsset = AM_Get_Inner(key); if (searchedAsset != nullptr) { return searchedAsset->handle; @@ -223,67 +217,53 @@ const AssetHandle AM_GetHandle(AssetKey key) { return AssetHandle_MAX; } -pk_handle_bucket_index_T AM_GetBucketCount() { - return Asset_BucketContainer.pkeHandle.bucketIndex + 1; -} - -Asset *AM_GetAssets(pk_handle_bucket_index_T bucketIndex, pk_handle_item_index_T &itemCount) { - if (bucketIndex == Asset_BucketContainer.pkeHandle.bucketIndex) { - itemCount = Asset_BucketContainer.pkeHandle.itemIndex; - } else { - itemCount = maxAssetItemsPerBucket; - } - return Asset_BucketContainer.buckets[bucketIndex]; +pk_bkt_arr *AM_GetAssets() { + return &asset_mstr.bc; } void AM_DebugPrint() { - printf("Asset Manager printout:\n"); - for (uint64_t b = 0; b <= Asset_BucketContainer.pkeHandle.bucketIndex; ++b) { - auto &bkt = Asset_BucketContainer.buckets[b]; - uint64_t counter = b == Asset_BucketContainer.pkeHandle.bucketIndex ? Asset_BucketContainer.pkeHandle.itemIndex : maxAssetItemsPerBucket; - for (uint64_t i = 0; i < counter; ++i) { - auto &asset = bkt[i]; - /* - if (asset.size == 0) - continue; - */ - printf("-Asset: 0x%016lX\n", (b << 32) + i); - printf("\tkey: %.16s\n", asset.key); - if (asset.basePath != nullptr) { - printf("\tbasePath: %s\n", asset.basePath); - } else { - printf("\tbasePath: %p\n", (void *)nullptr); - } - printf("\tsize: %ld\n", asset.size); - printf("\tptr %p\n", asset.ptr); - printf("\tfuture: %i\n", asset.future.valid()); - printf("\treferenceCount: %i\n", asset.referenceCount); - printf("\tAssetLoadingState: %hhu\n", static_cast<AssetLoadingState_T>(asset.state)); + fprintf(stdout, "Asset Manager printout:\n"); + auto asset_iter_fn = [](void *user_data, void *arr_obj_data) { + (void)user_data; + Asset &asset = *reinterpret_cast<Asset *>(arr_obj_data); + printf("-Asset: 0x%.08X 0x%.08X\n", asset.handle.b, asset.handle.i); + printf("\tkey: %.16s\n", asset.key); + if (asset.basePath != nullptr) { + printf("\tbasePath: %s\n", asset.basePath); + } else { + printf("\tbasePath: %p\n", (void *)nullptr); } - } + printf("\tsize: %ld\n", asset.size); + printf("\tptr %p\n", asset.ptr); + printf("\tfuture: %i\n", asset.future.valid()); + printf("\treferenceCount: %i\n", asset.referenceCount); + printf("\tAssetLoadingState: %hhu\n", static_cast<AssetLoadingState_T>(asset.state)); + }; + pk_bkt_arr_iterate(&asset_mstr.bc, asset_iter_fn, NULL); } void AM_GC() { - for (long b = 0; b <= Asset_BucketContainer.pkeHandle.bucketIndex; ++b) { - 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\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)) { - pk_delete_base(asset.ptr, asset.size); - } - asset.size = 0; - asset.ptr = CAFE_BABE(void); - asset.future = std::future<void>{}; - asset.state = PKE_ASSET_LOADING_STATE_UNLOADED; + auto asset_iter_fn = [](void *user_data, void *arr_obj_data) { + (void)user_data; + Asset &asset = *reinterpret_cast<Asset *>(arr_obj_data); + if (asset.referenceCount > 0) { + fprintf(stdout, "[AM_GC] Asset '%.16s' still in use, count: %i\n", asset.key, asset.referenceCount); + return; } - } + if (asset.ptr != nullptr && asset.ptr != CAFE_BABE(void) && !PK_HAS_FLAG(asset.flags, PKE_ASSET_FLAGS_MEM_STATIC)) { + pk_delete_base(asset.ptr, asset.size); + fprintf(stdout, "[AM_GC] Asset '%.16s' not in use, freeing.\n", asset.key); + } + asset.size = 0; + asset.ptr = CAFE_BABE(void); + new (&asset.future) std::future<void>{}; + asset.state = PKE_ASSET_LOADING_STATE_UNLOADED; + }; + pk_bkt_arr_iterate(&asset_mstr.bc, asset_iter_fn, NULL); } void AM_Teardown() { AM_GC(); - Buckets_Destroy(Asset_BucketContainer); - PkeThreads_Teardown(assetThreadPool); + pk_bkt_arr_teardown(&asset_mstr.bc); + PkeThreads_Teardown(asset_mstr.thread_pool); } diff --git a/src/asset-manager.hpp b/src/asset-manager.hpp index 5106375..bf065f2 100644 --- a/src/asset-manager.hpp +++ b/src/asset-manager.hpp @@ -6,9 +6,9 @@ #include <cstdint> #include <future> -struct AssetHandle : public pk_handle { }; +struct AssetHandle : public pk_bkt_arr_handle { }; -constexpr AssetHandle AssetHandle_MAX = AssetHandle{ pk_handle_MAX_constexpr }; +constexpr AssetHandle AssetHandle_MAX = AssetHandle{ pk_bkt_arr_handle_MAX_constexpr }; TypeSafeInt_constexpr(AssetLoadingState, uint8_t, 0xFF); TypeSafeInt_constexpr(AssetType, uint8_t, 0xFF); @@ -50,15 +50,14 @@ struct Asset { }; void AM_Init(); -AssetHandle AM_Register(AssetKey key, AssetType type, const void *data, int64_t size, std::size_t alignment); +AssetHandle AM_Register(const AssetKey &key, AssetType type, const void *data, int64_t size, std::size_t alignment); AssetHandle AM_Register(const char *path, AssetType type); -AssetHandle AM_Register(AssetKey key, AssetType type, const char *path); -AssetHandle AM_Register_Static(AssetKey key, AssetType type, const void *data, int64_t size); +AssetHandle AM_Register(const AssetKey &key, AssetType type, const char *path); +AssetHandle AM_Register_Static(const AssetKey &key, AssetType type, const void *data, int64_t size); void AM_Release(AssetHandle assetHandle); const Asset *AM_Get(AssetHandle assetHandle); -const AssetHandle AM_GetHandle(AssetKey key); -pk_handle_bucket_index_T AM_GetBucketCount(); -Asset *AM_GetAssets(pk_handle_bucket_index_T bucketIndex, pk_handle_item_index_T &itemCount); +const AssetHandle AM_GetHandle(const AssetKey &key); +pk_bkt_arr *AM_GetAssets(); void AM_Teardown(); void AM_DebugPrint(); diff --git a/src/project.cpp b/src/project.cpp index 546ac8a..dcb84ae 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -1,6 +1,7 @@ #include "project.hpp" +#include "asset-manager.hpp" #include "components.hpp" #include "plugins.hpp" #include "entities.hpp" @@ -292,11 +293,13 @@ void Proj_DeserializeEntityType(std::istream &stream) { } void Proj_DeserializeAssset(std::istream &stream) { - char keyStr[AssetKeyLength + 1]; - keyStr[AssetKeyLength] = '\0'; - char basePath[256]; + size_t prefixLen, strLen; + AssetKey keyStr; + keyStr[AssetKeyLength-1] = '\0'; + const size_t path_len = 256; + char basePath[path_len]; basePath[0] = '\0'; - basePath[255] = '\0'; + basePath[path_len-1] = '\0'; AssetType at{PKE_ASSET_TYPE_UNSET}; while (memset(projReadLine, 0, projReadLineLength), stream.getline(projReadLine, projReadLineLength)) { if (strcmp(projReadLine, PKE_PROJ_FILE_OBJ_END) == 0) { @@ -304,18 +307,20 @@ void Proj_DeserializeAssset(std::istream &stream) { return; } if (strstr(projReadLine, PKE_PROJ_FILE_ASSET_KEY) != nullptr) { - uint64_t prefixLen = strlen(PKE_PROJ_FILE_ASSET_KEY); - strncpy(keyStr, projReadLine + prefixLen, AssetKeyLength); + prefixLen = strlen(PKE_PROJ_FILE_ASSET_KEY); + strLen = strlen(projReadLine) - prefixLen; + memset(keyStr, '\0', AssetKeyLength); + memcpy(keyStr, projReadLine + prefixLen, PK_MIN(AssetKeyLength, strLen)); continue; } if (strstr(projReadLine, PKE_PROJ_FILE_ASSET_BASE_PATH) != nullptr) { - uint64_t prefixLen = strlen(PKE_PROJ_FILE_ASSET_BASE_PATH); + prefixLen = strlen(PKE_PROJ_FILE_ASSET_BASE_PATH); uint64_t strLen = strlen(projReadLine) - prefixLen; - strncpy(basePath, projReadLine + prefixLen, strLen + 1); + strncpy(basePath, projReadLine + prefixLen, PK_MIN(strLen + 1, path_len)); continue; } if (strstr(projReadLine, PKE_PROJ_FILE_ASSET_TYPE) != nullptr) { - uint64_t prefixLen = strlen(PKE_PROJ_FILE_ASSET_TYPE); + prefixLen = strlen(PKE_PROJ_FILE_ASSET_TYPE); AssetType_T val{}; STR2NUM_ERROR result = str2num(val, projReadLine + prefixLen); at = AssetType{val}; @@ -375,25 +380,25 @@ void PkeProject_Save(const char *filePath) { f << PKE_PROJ_FILE_OBJ_END << std::endl; */ - pk_handle_bucket_index_T assetB = AM_GetBucketCount(); - for (pk_handle_bucket_index_T b = 0; b < assetB; ++b) { - pk_handle_item_index_T assetI = 0; - auto *assets = AM_GetAssets(b, assetI); - for (pk_handle_item_index_T i = 0; i < assetI; ++i) { - if (PK_HAS_FLAG(assets[i].flags, PKE_ASSET_FLAGS_MEM_STATIC)) continue; - bool isGlobalAsset = false; - for (long k = 0; k < EngineDefinedAssetCount; ++k) { - if (strncmp(EngineDefinedAssets[k], assets[i].key, AssetKeyLength) == 0) { - isGlobalAsset = true; - break; - } + using AssetLoopFn = pk_tmpln_1<void, Asset *, void *>; + AssetLoopFn asset_loop_cb{}; + asset_loop_cb.func = [&stream](Asset *arr_obj_data) { + if (PK_HAS_FLAG(arr_obj_data->flags, PKE_ASSET_FLAGS_MEM_STATIC)) return; + // TODO 2025-05-30 JCB + // This should be a flag + bool isGlobalAsset = false; + for (long k = 0; k < EngineDefinedAssetCount; ++k) { + if (strncmp(EngineDefinedAssets[k], arr_obj_data->key, AssetKeyLength) == 0) { + isGlobalAsset = true; + break; } - if (isGlobalAsset) continue; - stream << PKE_PROJ_FILE_OBJ_ASSET << std::endl; - Proj_SerializeAsset(stream, assets[i]); - stream << PKE_PROJ_FILE_OBJ_END << std::endl; } - } + if (isGlobalAsset) return; + stream << PKE_PROJ_FILE_OBJ_ASSET << std::endl; + Proj_SerializeAsset(stream, *arr_obj_data); + stream << PKE_PROJ_FILE_OBJ_END << std::endl; + }; + pk_bkt_arr_iterate(AM_GetAssets(), &AssetLoopFn::invoke, &asset_loop_cb); const auto entBucketCount = EntityType_GetBucketCount(); for (pk_handle_bucket_index_T b = 0; b < entBucketCount; ++b) { diff --git a/src/window.cpp b/src/window.cpp index 12ee3b4..6753cfa 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -3658,7 +3658,7 @@ void DestroyWindow() { VkShaderModule UploadShader(AssetHandle handle) { const Asset *asset = AM_Get(handle); if (asset == nullptr || asset->state != PKE_ASSET_LOADING_STATE_LOADED) { - fprintf(stderr, "[Window::UploadShader] asset '%.08X %.08X' failed to load.", handle.bucketIndex, handle.itemIndex); + fprintf(stderr, "[Window::UploadShader] asset '%.08X %.08X' failed to load.", handle.b, handle.i); return NULL; } #ifndef NDEBUG diff --git a/tests/pke-test-asset-manager.cpp b/tests/pke-test-asset-manager.cpp new file mode 100644 index 0000000..82e1345 --- /dev/null +++ b/tests/pke-test-asset-manager.cpp @@ -0,0 +1,47 @@ + +#include "./pke-test-asset-manager.h" + +#include "asset-manager.hpp" +#include "ecs.hpp" +#include "font.hpp" +#include "thread-pool.hpp" + +void pke_test_asset_manager_spinup() { + PkeThreads_Init(); + AM_Init(); + ECS_Init(); + FontType_Init(); +}; + +void pke_test_asset_manager_teardown() { + FontType_Teardown(); + ECS_Teardown(); + AM_Teardown(); + PkeThreads_Teardown(); +}; + +int pke_test_asset_manager_001() { + AssetHandle handle = AM_GetHandle(AssetKey { "fnt_mquin_img" }); + const Asset *a = AM_Get(handle); + AM_Release(handle); + return int(a != NULL && handle != AssetHandle_MAX); +} + +struct pke_test_group *pke_test_asset_manager_get_group() { + static const uint64_t test_count = 1; + static struct pke_test tests[test_count] = { + { + .title = "test 001", + .func = pke_test_asset_manager_001, + .expected_result = 1, + } + }; + static struct pke_test_group group = {}; + group.title = "asset_manager"; + group.n_tests = test_count; + group.tests = &tests[0]; + group.test_setup = pke_test_asset_manager_spinup; + group.test_teardown = pke_test_asset_manager_teardown; + + return &group; +} diff --git a/tests/pke-test-asset-manager.h b/tests/pke-test-asset-manager.h new file mode 100644 index 0000000..802b67f --- /dev/null +++ b/tests/pke-test-asset-manager.h @@ -0,0 +1,16 @@ +#ifndef PKE_PKE_TEST_ASSET_MANAGER_H +#define PKE_PKE_TEST_ASSET_MANAGER_H + +#include "pke-test-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct pke_test_group *pke_test_asset_manager_get_group(); + +#ifdef __cplusplus +} +#endif + +#endif /* PKE_PKE_TEST_ASSET_MANAGER_H */ diff --git a/tests/pke-test.cpp b/tests/pke-test.cpp index 78ad662..2e9eb9d 100644 --- a/tests/pke-test.cpp +++ b/tests/pke-test.cpp @@ -1,9 +1,10 @@ #include "./pke-test-types.h" +#include "./pke-test-asset-manager.h" #include "./pke-test-dummy.h" -#include "./pke-test-static-ui.h" #include "./pke-test-serialization.h" +#include "./pke-test-static-ui.h" #include "pk.h" #include "unistd.h" @@ -38,6 +39,7 @@ int main(int argc, char *argv[]) pke_test_dummy_get_group, pke_test_static_ui_get_group, pke_test_serialization_get_group, + pke_test_asset_manager_get_group, NULL, }; |
