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 /src | |
| parent | 6ff0a1f8f7775752db8219dc270a56c4e64b4c7e (diff) | |
pke: asset: BucketContainer>pk_bkt_arr_t & cleanup
Diffstat (limited to 'src')
| -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 |
4 files changed, 112 insertions, 128 deletions
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 |
