#include "asset-manager.hpp" TypeSafeInt_B(AssetHandle); struct AssetBucket { Asset assets[256]; }; uint64_t assetBucketIncrementer = 2; AssetHandle_T assetBucketCounter{0}; AssetHandle_T assetCounter{0}; AssetBucket *assetBuckets = nullptr; void AssetManagerInit() { assetBuckets = pke::PkeNew(assetBucketIncrementer); } AssetHandle RegisterAsset_Inner(const void *src, void *dst, int64_t size, const char *key) { AssetHandle_T assetHandle_T{Buckets_NewHandle(256ULL, assetBucketIncrementer, assetBucketCounter, assetCounter, assetBuckets)}; AssetHandle assetHandle{assetHandle_T}; if (src != nullptr) { std::memcpy(dst, src, size); } Asset *asset = &assetBuckets[Buckets_GetBucketIndex(assetHandle_T)].assets[Buckets_GetItemIndex(assetHandle_T)]; asset->ptr = dst; asset->size = size; int64_t keyLen = std::strlen(key); std::memcpy(asset->key, key, keyLen > 16 ? 16 : keyLen); return assetHandle; } AssetHandle RegisterAsset(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::PkeNew(size); return RegisterAsset_Inner(data, target, size, key); } AssetHandle RegisterAsset(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::PkeNew(fileSize); int64_t pathLen = strlen(path); auto assetHandle = RegisterAsset_Inner(nullptr, target, 0, path + (pathLen > 16 ? pathLen - 16 : 0)); AssetHandle_T assetHandle_T = static_cast(assetHandle); Asset *asset = &assetBuckets[Buckets_GetBucketIndex(assetHandle_T)].assets[Buckets_GetItemIndex(assetHandle_T)]; file.seekg(0); file.read(static_cast(asset->ptr), fileSize); file.close(); asset->size = fileSize; return assetHandle; } void DestroyAsset(AssetHandle assetHandle) { AssetHandle_T assetHandle_T = static_cast(assetHandle); auto itemIndex = Buckets_GetItemIndex(assetHandle_T); Asset *asset = &assetBuckets[Buckets_GetBucketIndex(assetHandle_T)].assets[itemIndex]; pke::PkeDelete(asset->ptr, asset->size); for (long i = 0; i < 16; ++i) { asset->key[i] = 0; } asset->size = 0; asset->ptr = CAFE_BABE(void); if (itemIndex == assetCounter - (1ULL << 32)) { assetCounter -= (1ULL << 32); } } const Asset *GetAsset(AssetHandle assetHandle) { AssetHandle_T assetHandle_T = static_cast(assetHandle); return &assetBuckets[Buckets_GetBucketIndex(assetHandle_T)].assets[Buckets_GetItemIndex(assetHandle_T)]; }