#include "asset-manager.hpp" TypeSafeInt_B(AssetHandle); const uint64_t maxAssetItemsPerBucket = 256; struct AssetBucket { Asset assets[maxAssetItemsPerBucket]; }; BucketContainer Asset_BucketContainer{}; void AM_Init() { Buckets_Init(Asset_BucketContainer); } AssetHandle AM_Register_Inner(const void *src, void *dst, int64_t size, const char *key) { AssetHandle_T assetHandle_T{Buckets_NewHandle(maxAssetItemsPerBucket, Asset_BucketContainer)}; if (src != nullptr) { std::memcpy(dst, src, size); } auto b = Buckets_GetBucketIndex(assetHandle_T); auto e = Buckets_GetItemIndex(assetHandle_T); Asset *asset = &Asset_BucketContainer.buckets[b].assets[e]; asset->ptr = dst; asset->size = size; int64_t keyLen = std::strlen(key); std::memcpy(asset->key, key, keyLen > 16 ? 16 : keyLen); return AssetHandle{assetHandle_T}; } AssetHandle AM_Register(const void *data, int64_t size, const char *key) { 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"); void *target = Pke_New(size); return AM_Register_Inner(data, target, size, key); } AssetHandle AM_Register(const char *path) { std::ifstream file(path, std::ios::ate | std::ios::binary); if (!file.is_open()) { throw "failed to open file"; } auto fileSize = (int64_t)file.tellg(); void *target = Pke_New(fileSize); int64_t pathLen = strlen(path); auto assetHandle = AM_Register_Inner(nullptr, target, 0, path + (pathLen > 16 ? pathLen - 16 : 0)); auto b = Buckets_GetBucketIndex(static_cast(assetHandle)); auto e = Buckets_GetItemIndex(static_cast(assetHandle)); Asset *asset = &Asset_BucketContainer.buckets[b].assets[e]; file.seekg(0); file.read(static_cast(asset->ptr), fileSize); file.close(); asset->size = fileSize; return assetHandle; } void AM_Destroy(AssetHandle assetHandle) { AssetHandle_T assetHandle_T = static_cast(assetHandle); auto b = Buckets_GetBucketIndex(assetHandle_T); auto i = Buckets_GetItemIndex(assetHandle_T); Asset *asset = &Asset_BucketContainer.buckets[b].assets[i]; Pke_Delete(asset->ptr, asset->size); asset->size = 0; asset->ptr = CAFE_BABE(void); auto lastGivenIndex = ((Asset_BucketContainer.itemCounter - (1ULL << 32)) >> 32); if (i == lastGivenIndex) { Asset_BucketContainer.itemCounter = lastGivenIndex; } } const Asset *AM_Get(AssetHandle assetHandle) { AssetHandle_T assetHandle_T = static_cast(assetHandle); auto b = Buckets_GetBucketIndex(assetHandle_T); auto i = Buckets_GetItemIndex(assetHandle_T); return &Asset_BucketContainer.buckets[b].assets[i]; } void AM_DebugPrint() { printf("Asset Manager printout:\n"); for (uint64_t b = 0; b <= Asset_BucketContainer.bucketCounter; ++b) { auto &bkt = Asset_BucketContainer.buckets[b]; long counter = b == Asset_BucketContainer.bucketCounter ? Asset_BucketContainer.itemCounter >> 32 : maxAssetItemsPerBucket; for (uint64_t i = 0; i < counter; ++i) { auto &asset = bkt.assets[i]; /* if (asset.size == 0) continue; */ printf("-Asset: 0x%016lX\n", b + (i << 32)); printf("\tkey: %s\n", asset.key); printf("\tsize: %ld\n", asset.size); printf("\tptr %p\n", asset.ptr); } } } void AM_Teardown() { Buckets_Destroy(Asset_BucketContainer); }