Added SHResourceManager and Generic Handle #104
|
@ -21,6 +21,7 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
SHResourceHub SHResourceManager::resourceHub;
|
||||
std::unordered_map<std::type_index, std::unordered_map<AssetID, Handle<void>>> SHResourceManager::handlesMap;
|
||||
std::unordered_map<std::type_index, SHADE::SHResourceManager::HandleAssetMap> SHResourceManager::assetIdMap;
|
||||
std::unordered_map<std::type_index, std::function<void(AssetID)>> SHResourceManager::typedFreeFuncMap;
|
||||
std::vector<AssetID> 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<SHGraphicsSystem>();
|
||||
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<SHGraphicsSystem>();
|
||||
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<AssetID> SHResourceManager::GetAssetID(Handle<void> 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 {};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,11 +65,41 @@ namespace SHADE
|
|||
/// </summary>
|
||||
static void FinaliseChanges();
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Query Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Retrieves the AssetID associated with a specified Handle.
|
||||
/// Faster than the untemplated version.
|
||||
/// </summary>
|
||||
/// <typeparam name="ResourceType">Type of resource to get the ID of.</typeparam>
|
||||
/// <param name="handle">Handle to get the AssetID of.</param>
|
||||
/// <return>
|
||||
/// AssetID for the specified Handle. If the Handle is invalid, there will be no
|
||||
/// value.
|
||||
/// </return>
|
||||
template<typename T>
|
||||
static std::optional<AssetID> GetAssetID(Handle<T> handle);
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="handle">Handle to get the AssetID of.</param>
|
||||
/// <return>
|
||||
/// AssetID for the specified Handle. If the Handle is invalid, there will be no
|
||||
/// value.
|
||||
/// </return>
|
||||
static std::optional<AssetID> GetAssetID(Handle<void> handle);
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
using AssetHandleMap = std::unordered_map<AssetID, Handle<void>>;
|
||||
using HandleAssetMap = std::unordered_map<Handle<void>, AssetID>;
|
||||
using AssetHandleMapRef = std::reference_wrapper<AssetHandleMap>;
|
||||
using HandleAssetMapRef = std::reference_wrapper<HandleAssetMap>;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
|
@ -77,6 +107,7 @@ namespace SHADE
|
|||
// Handles
|
||||
static SHResourceHub resourceHub;
|
||||
static std::unordered_map<std::type_index, AssetHandleMap> handlesMap;
|
||||
static std::unordered_map<std::type_index, HandleAssetMap> assetIdMap;
|
||||
static std::unordered_map<std::type_index, std::function<void(AssetID)>> typedFreeFuncMap;
|
||||
// Pointers to temp CPU resources
|
||||
static std::vector<AssetID> loadedAssetData;
|
||||
|
@ -92,7 +123,7 @@ namespace SHADE
|
|||
/// </typeparam>
|
||||
/// <returns>Reference to the AssetHandleMap of the specified type.</returns>
|
||||
template<typename ResourceType>
|
||||
static AssetHandleMap& getAssetHandleMap();
|
||||
static std::pair<AssetHandleMapRef, HandleAssetMapRef> getAssetHandleMap();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -34,9 +34,9 @@ namespace SHADE
|
|||
}
|
||||
|
||||
/* Attempt to get existing loaded asset */
|
||||
AssetHandleMap& typedHandleMap = getAssetHandleMap<ResourceType>();
|
||||
if (typedHandleMap.contains(assetId))
|
||||
return Handle<ResourceType>(typedHandleMap[assetId]);
|
||||
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<ResourceType>();
|
||||
if (typedHandleMap.get().contains(assetId))
|
||||
return Handle<ResourceType>(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<typename ResourceType>
|
||||
void SHResourceManager::Unload(Handle<ResourceType> assetId)
|
||||
{
|
||||
// Check if it is an usupported type
|
||||
// Check if it is an unsupported type
|
||||
if (!std::is_same_v<ResourceType, SHMesh> && !std::is_same_v<ResourceType, SHTexture>)
|
||||
{
|
||||
static_assert(true, "Unsupported Resource Type specified for SHResourceManager.");
|
||||
}
|
||||
|
||||
/* Attempt to get existing loaded asset */
|
||||
AssetHandleMap& typedHandleMap = getAssetHandleMap<ResourceType>();
|
||||
if (typedHandleMap.contains(assetId))
|
||||
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<ResourceType>();
|
||||
if (typedHandleMap.get().contains(assetId))
|
||||
{
|
||||
// Dispose
|
||||
static_cast<Handle<ResourceType>>(typedHandleMap[assetId]).Free();
|
||||
typedHandleMap.erase(assetId);
|
||||
Handle handle = typedHandleMap.get()[assetId];
|
||||
Handle<ResourceType> typedHandle = static_cast<Handle<ResourceType>>(handle);
|
||||
typedHandle.Free();
|
||||
typedAssetIdMap.get().erase(handle);
|
||||
typedHandleMap.get().erase(assetId);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -124,24 +129,43 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Query Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
template<typename T>
|
||||
static std::optional<AssetID> SHResourceManager::GetAssetID(Handle<T> handle)
|
||||
{
|
||||
const Handle GENERIC_HANDLE = Handle(handle);
|
||||
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<T>();
|
||||
if (typedAssetIdMap.get().contains(GENERIC_HANDLE))
|
||||
{
|
||||
return typedAssetIdMap.GetId()[GENERIC_HANDLE];
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
template<typename ResourceType>
|
||||
SHResourceManager::AssetHandleMap& SHResourceManager::getAssetHandleMap()
|
||||
std::pair<SHResourceManager::AssetHandleMapRef, SHResourceManager::HandleAssetMapRef> 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<Handle<ResourceType>>(SHResourceManager::handlesMap[typeid(ResourceType)][assetId]).Free();
|
||||
static_cast<Handle<ResourceType>>(SHResourceManager::handlesMap[TYPE][assetId]).Free();
|
||||
}
|
||||
);
|
||||
}
|
||||
return handlesMap[typeid(ResourceType)];
|
||||
return std::make_pair(std::ref(handlesMap[TYPE]), std::ref(assetIdMap[TYPE]));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue