diff --git a/SHADE_Engine/src/Resource/SHResourceManager.cpp b/SHADE_Engine/src/Resource/SHResourceManager.cpp index a82f7890..156c31c7 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.cpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.cpp @@ -21,6 +21,7 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHResourceHub SHResourceManager::resourceHub; std::unordered_map>> SHResourceManager::handlesMap; + std::unordered_map SHResourceManager::assetIdMap; std::unordered_map> SHResourceManager::typedFreeFuncMap; std::vector SHResourceManager::loadedAssetData; @@ -30,30 +31,65 @@ namespace SHADE void SHResourceManager::Unload(AssetID assetId) { // Search each library for the asset ID and try to free it + Handle handle; for (auto& typedHandleMap : handlesMap) { if (typedHandleMap.second.contains(assetId)) { + // Save handle for later + handle = typedHandleMap.second[assetId]; // Dispose typedFreeFuncMap[typedHandleMap.first](assetId); typedHandleMap.second.erase(assetId); } } + + // No handles were found + if (!handle) + return; + + for (auto& typedAssetIdsMap : assetIdMap) + { + if (typedAssetIdsMap.second.contains(handle)) + { + // Dispose + typedAssetIdsMap.second.erase(handle); + } + } } void SHResourceManager::FinaliseChanges() { - SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem(); - if (gfxSystem == nullptr) - throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed."); - gfxSystem->BuildMeshBuffers(); - gfxSystem->BuildTextures(); + SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem(); + if (gfxSystem == nullptr) + throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed."); + gfxSystem->BuildMeshBuffers(); + gfxSystem->BuildTextures(); - // Free CPU Resources - for (auto assetId : loadedAssetData) + // Free CPU Resources + for (auto assetId : loadedAssetData) + { + SHAssetManager::Unload(assetId); + } + loadedAssetData.clear(); + } + + /*-----------------------------------------------------------------------------------*/ + /* Query Functions */ + /*-----------------------------------------------------------------------------------*/ + std::optional SHResourceManager::GetAssetID(Handle handle) + { + const Handle GENERIC_HANDLE = Handle(handle); + + // Search each library for the asset ID and try to free it + for (auto& typedAssetIdsMap : assetIdMap) + { + if (typedAssetIdsMap.second.contains(GENERIC_HANDLE)) { - SHAssetManager::Unload(assetId); + return typedAssetIdsMap.second[GENERIC_HANDLE]; } - loadedAssetData.clear(); + } + + return {}; } } diff --git a/SHADE_Engine/src/Resource/SHResourceManager.h b/SHADE_Engine/src/Resource/SHResourceManager.h index f43b4a77..84f93b10 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.h +++ b/SHADE_Engine/src/Resource/SHResourceManager.h @@ -65,11 +65,41 @@ namespace SHADE /// static void FinaliseChanges(); + /*---------------------------------------------------------------------------------*/ + /* Query Functions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Retrieves the AssetID associated with a specified Handle. + /// Faster than the untemplated version. + /// + /// Type of resource to get the ID of. + /// Handle to get the AssetID of. + /// + /// AssetID for the specified Handle. If the Handle is invalid, there will be no + /// value. + /// + template + static std::optional GetAssetID(Handle handle); + /// + /// Retrieves the AssetID associated with a specified Handle. + /// Compared to the templated version, this function is slower as it requires + /// searching through the storage of all resource types. + /// + /// Handle to get the AssetID of. + /// + /// AssetID for the specified Handle. If the Handle is invalid, there will be no + /// value. + /// + static std::optional GetAssetID(Handle handle); + private: /*---------------------------------------------------------------------------------*/ /* Type Definitions */ /*---------------------------------------------------------------------------------*/ using AssetHandleMap = std::unordered_map>; + using HandleAssetMap = std::unordered_map, AssetID>; + using AssetHandleMapRef = std::reference_wrapper; + using HandleAssetMapRef = std::reference_wrapper; /*---------------------------------------------------------------------------------*/ /* Data Members */ @@ -77,6 +107,7 @@ namespace SHADE // Handles static SHResourceHub resourceHub; static std::unordered_map handlesMap; + static std::unordered_map assetIdMap; static std::unordered_map> typedFreeFuncMap; // Pointers to temp CPU resources static std::vector loadedAssetData; @@ -92,7 +123,7 @@ namespace SHADE /// /// Reference to the AssetHandleMap of the specified type. template - static AssetHandleMap& getAssetHandleMap(); + static std::pair getAssetHandleMap(); }; } diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index 593f8bb7..54ced715 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -34,9 +34,9 @@ namespace SHADE } /* Attempt to get existing loaded asset */ - AssetHandleMap& typedHandleMap = getAssetHandleMap(); - if (typedHandleMap.contains(assetId)) - return Handle(typedHandleMap[assetId]); + auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap(); + if (typedHandleMap.get().contains(assetId)) + return Handle(typedHandleMap.get()[assetId]); /* Otherwise, we need to load it! */ // Meshes @@ -66,7 +66,9 @@ namespace SHADE assetData->indices.size(), assetData->indices.data() ); - typedHandleMap.emplace(assetId, Handle(meshHandle)); + Handle genericHandle = Handle(meshHandle); + typedHandleMap.get().emplace(assetId, genericHandle); + typedAssetIdMap.get().emplace(genericHandle, assetId); return meshHandle; } // Textures @@ -95,7 +97,7 @@ namespace SHADE assetData->format, assetData->mipOffsets ); - typedHandleMap.emplace(assetId, Handle(texHandle)); + typedHandleMap.get().emplace(assetId, Handle(texHandle)); return texHandle; } } @@ -103,19 +105,22 @@ namespace SHADE template void SHResourceManager::Unload(Handle assetId) { - // Check if it is an usupported type + // Check if it is an unsupported type if (!std::is_same_v && !std::is_same_v) { static_assert(true, "Unsupported Resource Type specified for SHResourceManager."); } /* Attempt to get existing loaded asset */ - AssetHandleMap& typedHandleMap = getAssetHandleMap(); - if (typedHandleMap.contains(assetId)) + auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap(); + if (typedHandleMap.get().contains(assetId)) { // Dispose - static_cast>(typedHandleMap[assetId]).Free(); - typedHandleMap.erase(assetId); + Handle handle = typedHandleMap.get()[assetId]; + Handle typedHandle = static_cast>(handle); + typedHandle.Free(); + typedAssetIdMap.get().erase(handle); + typedHandleMap.get().erase(assetId); } else { @@ -124,24 +129,43 @@ namespace SHADE } } + /*-----------------------------------------------------------------------------------*/ + /* Query Functions */ + /*-----------------------------------------------------------------------------------*/ + template + static std::optional SHResourceManager::GetAssetID(Handle handle) + { + const Handle GENERIC_HANDLE = Handle(handle); + auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap(); + if (typedAssetIdMap.get().contains(GENERIC_HANDLE)) + { + return typedAssetIdMap.GetId()[GENERIC_HANDLE]; + } + + return {}; + } + /*-----------------------------------------------------------------------------------*/ /* Helper Functions */ /*-----------------------------------------------------------------------------------*/ template - SHResourceManager::AssetHandleMap& SHResourceManager::getAssetHandleMap() + std::pair SHResourceManager::getAssetHandleMap() { - if (!handlesMap.contains(typeid(ResourceType))) + const std::type_index TYPE = typeid(ResourceType); + + if (!handlesMap.contains(TYPE)) { - handlesMap.emplace(typeid(ResourceType), AssetHandleMap{}); + handlesMap.emplace(TYPE, AssetHandleMap{}); + assetIdMap.emplace(TYPE, HandleAssetMap{}); typedFreeFuncMap.emplace ( - typeid(ResourceType), - [](AssetID assetId) + TYPE, + [TYPE](AssetID assetId) { - static_cast>(SHResourceManager::handlesMap[typeid(ResourceType)][assetId]).Free(); + static_cast>(SHResourceManager::handlesMap[TYPE][assetId]).Free(); } ); } - return handlesMap[typeid(ResourceType)]; + return std::make_pair(std::ref(handlesMap[TYPE]), std::ref(assetIdMap[TYPE])); } }