#include "asset-manager.hpp" TypeSafeInt_B(AssetHandle); constexpr AssetHandle_T AssetIndexer_T{1ULL << 32}; constexpr AssetHandle AssetIndexer{AssetIndexer_T}; constexpr AssetHandle_T AssetIndexMax_T{63ULL << 32}; constexpr AssetHandle AssetIndexMax{AssetIndexMax_T}; constexpr AssetHandle_T AssetBucketMask_T{0x00000000FFFFFFFF}; constexpr AssetHandle AssetBucketMask{AssetBucketMask_T}; constexpr AssetHandle_T AssetIndexMask_T{0xFFFFFFFF00000000}; constexpr AssetHandle AssetIndexMask{AssetIndexMask_T}; static inline constexpr AssetHandle_T GetBucketIndex(AssetHandle assetHandle) { return static_cast(assetHandle & AssetBucketMask); } static inline constexpr AssetHandle_T GetAssetIndex(AssetHandle assetHandle) { AssetHandle_T index = static_cast(assetHandle & AssetIndexMask); return index >> 32; } struct AssetBucket { Asset assets[64]; }; uint64_t bucketIncrementer = 2; AssetHandle bucketCounter{0}; AssetHandle assetCounter{0}; AssetBucket *assetBuckets = nullptr; void AssetManagerInit() { assetBuckets = pke::PkeNew(bucketIncrementer); } 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"); AssetHandle assetHandle{assetCounter | bucketCounter}; // update our counters and buckets { assetCounter = assetCounter + AssetIndexer; if (assetCounter > AssetIndexMax) { assetCounter = AssetHandle{0}; ++bucketCounter; } if (bucketCounter > AssetHandle{bucketIncrementer}) { int64_t newIncrement = bucketIncrementer * 1.5; AssetBucket *newBuckets = pke::PkeNew(newIncrement); memcpy(newBuckets, assetBuckets, sizeof(AssetBucket) * bucketIncrementer); pke::PkeDelete(assetBuckets, bucketIncrementer); assetBuckets = newBuckets; bucketIncrementer = newIncrement; } } void *target = pke::PkeNew(size); std::memcpy(target, data, size); Asset *asset = &assetBuckets[GetBucketIndex(assetHandle)].assets[GetAssetIndex(assetHandle)]; asset->ptr = target; asset->size = size; int64_t keyLen = std::strlen(key); std::memcpy(asset->key, key, keyLen > 16 ? 16 : keyLen); return assetHandle; } AssetHandle RegisterAsset(char *path) { // TODO load file int64_t pathLen = strlen(path); return RegisterAsset(nullptr, 0, path + (pathLen > 16 ? pathLen - 16 : 0)); } void DestroyAsset(AssetHandle assetHandle) { Asset *asset = &assetBuckets[GetBucketIndex(assetHandle)].assets[GetAssetIndex(assetHandle)]; pke::PkeDelete(asset->ptr, asset->size); asset->ptr = CAFE_BABE(void); } const Asset *GetAsset(AssetHandle assetHandle) { return &assetBuckets[GetBucketIndex(assetHandle)].assets[GetAssetIndex(assetHandle)]; }