Added SHResourceManager and Generic Handle #104
|
@ -21,6 +21,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
SHResourceHub SHResourceManager::resourceHub;
|
SHResourceHub SHResourceManager::resourceHub;
|
||||||
std::unordered_map<std::type_index, std::unordered_map<AssetID, Handle<void>>> SHResourceManager::handlesMap;
|
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::unordered_map<std::type_index, std::function<void(AssetID)>> SHResourceManager::typedFreeFuncMap;
|
||||||
std::vector<AssetID> SHResourceManager::loadedAssetData;
|
std::vector<AssetID> SHResourceManager::loadedAssetData;
|
||||||
|
|
||||||
|
@ -30,15 +31,31 @@ namespace SHADE
|
||||||
void SHResourceManager::Unload(AssetID assetId)
|
void SHResourceManager::Unload(AssetID assetId)
|
||||||
{
|
{
|
||||||
// Search each library for the asset ID and try to free it
|
// Search each library for the asset ID and try to free it
|
||||||
|
Handle handle;
|
||||||
for (auto& typedHandleMap : handlesMap)
|
for (auto& typedHandleMap : handlesMap)
|
||||||
{
|
{
|
||||||
if (typedHandleMap.second.contains(assetId))
|
if (typedHandleMap.second.contains(assetId))
|
||||||
{
|
{
|
||||||
|
// Save handle for later
|
||||||
|
handle = typedHandleMap.second[assetId];
|
||||||
// Dispose
|
// Dispose
|
||||||
typedFreeFuncMap[typedHandleMap.first](assetId);
|
typedFreeFuncMap[typedHandleMap.first](assetId);
|
||||||
typedHandleMap.second.erase(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()
|
void SHResourceManager::FinaliseChanges()
|
||||||
|
@ -56,4 +73,23 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
loadedAssetData.clear();
|
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))
|
||||||
|
{
|
||||||
|
return typedAssetIdsMap.second[GENERIC_HANDLE];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,11 +65,41 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static void FinaliseChanges();
|
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:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
using AssetHandleMap = std::unordered_map<AssetID, Handle<void>>;
|
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 */
|
/* Data Members */
|
||||||
|
@ -77,6 +107,7 @@ namespace SHADE
|
||||||
// Handles
|
// Handles
|
||||||
static SHResourceHub resourceHub;
|
static SHResourceHub resourceHub;
|
||||||
static std::unordered_map<std::type_index, AssetHandleMap> handlesMap;
|
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;
|
static std::unordered_map<std::type_index, std::function<void(AssetID)>> typedFreeFuncMap;
|
||||||
// Pointers to temp CPU resources
|
// Pointers to temp CPU resources
|
||||||
static std::vector<AssetID> loadedAssetData;
|
static std::vector<AssetID> loadedAssetData;
|
||||||
|
@ -92,7 +123,7 @@ namespace SHADE
|
||||||
/// </typeparam>
|
/// </typeparam>
|
||||||
/// <returns>Reference to the AssetHandleMap of the specified type.</returns>
|
/// <returns>Reference to the AssetHandleMap of the specified type.</returns>
|
||||||
template<typename ResourceType>
|
template<typename ResourceType>
|
||||||
static AssetHandleMap& getAssetHandleMap();
|
static std::pair<AssetHandleMapRef, HandleAssetMapRef> getAssetHandleMap();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt to get existing loaded asset */
|
/* Attempt to get existing loaded asset */
|
||||||
AssetHandleMap& typedHandleMap = getAssetHandleMap<ResourceType>();
|
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<ResourceType>();
|
||||||
if (typedHandleMap.contains(assetId))
|
if (typedHandleMap.get().contains(assetId))
|
||||||
return Handle<ResourceType>(typedHandleMap[assetId]);
|
return Handle<ResourceType>(typedHandleMap.get()[assetId]);
|
||||||
|
|
||||||
/* Otherwise, we need to load it! */
|
/* Otherwise, we need to load it! */
|
||||||
// Meshes
|
// Meshes
|
||||||
|
@ -66,7 +66,9 @@ namespace SHADE
|
||||||
assetData->indices.size(),
|
assetData->indices.size(),
|
||||||
assetData->indices.data()
|
assetData->indices.data()
|
||||||
);
|
);
|
||||||
typedHandleMap.emplace(assetId, Handle(meshHandle));
|
Handle genericHandle = Handle(meshHandle);
|
||||||
|
typedHandleMap.get().emplace(assetId, genericHandle);
|
||||||
|
typedAssetIdMap.get().emplace(genericHandle, assetId);
|
||||||
return meshHandle;
|
return meshHandle;
|
||||||
}
|
}
|
||||||
// Textures
|
// Textures
|
||||||
|
@ -95,7 +97,7 @@ namespace SHADE
|
||||||
assetData->format,
|
assetData->format,
|
||||||
assetData->mipOffsets
|
assetData->mipOffsets
|
||||||
);
|
);
|
||||||
typedHandleMap.emplace(assetId, Handle(texHandle));
|
typedHandleMap.get().emplace(assetId, Handle(texHandle));
|
||||||
return texHandle;
|
return texHandle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,19 +105,22 @@ namespace SHADE
|
||||||
template<typename ResourceType>
|
template<typename ResourceType>
|
||||||
void SHResourceManager::Unload(Handle<ResourceType> assetId)
|
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>)
|
if (!std::is_same_v<ResourceType, SHMesh> && !std::is_same_v<ResourceType, SHTexture>)
|
||||||
{
|
{
|
||||||
static_assert(true, "Unsupported Resource Type specified for SHResourceManager.");
|
static_assert(true, "Unsupported Resource Type specified for SHResourceManager.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt to get existing loaded asset */
|
/* Attempt to get existing loaded asset */
|
||||||
AssetHandleMap& typedHandleMap = getAssetHandleMap<ResourceType>();
|
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<ResourceType>();
|
||||||
if (typedHandleMap.contains(assetId))
|
if (typedHandleMap.get().contains(assetId))
|
||||||
{
|
{
|
||||||
// Dispose
|
// Dispose
|
||||||
static_cast<Handle<ResourceType>>(typedHandleMap[assetId]).Free();
|
Handle handle = typedHandleMap.get()[assetId];
|
||||||
typedHandleMap.erase(assetId);
|
Handle<ResourceType> typedHandle = static_cast<Handle<ResourceType>>(handle);
|
||||||
|
typedHandle.Free();
|
||||||
|
typedAssetIdMap.get().erase(handle);
|
||||||
|
typedHandleMap.get().erase(assetId);
|
||||||
}
|
}
|
||||||
else
|
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 */
|
/* Helper Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
template<typename ResourceType>
|
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
|
typedFreeFuncMap.emplace
|
||||||
(
|
(
|
||||||
typeid(ResourceType),
|
TYPE,
|
||||||
[](AssetID assetId)
|
[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