summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-05-30 14:41:54 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-05-30 14:41:54 -0400
commit781410537a1c7ddac340efabeedd4c9309e5cf39 (patch)
tree7253babcfc7fd8766095fdf89eca7a9fd3952912 /src
parent6ff0a1f8f7775752db8219dc270a56c4e64b4c7e (diff)
pke: asset: BucketContainer>pk_bkt_arr_t & cleanup
Diffstat (limited to 'src')
-rw-r--r--src/asset-manager.cpp166
-rw-r--r--src/asset-manager.hpp15
-rw-r--r--src/project.cpp57
-rw-r--r--src/window.cpp2
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