Implement initial Unity-style asset library cache
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include <XCEngine/Core/Asset/ResourceManager.h>
|
||||
#include <XCEngine/Core/Asset/ResourceHandle.h>
|
||||
#include <XCEngine/Core/Asset/ResourceTypes.h>
|
||||
#include <XCEngine/Core/IO/ResourceFileSystem.h>
|
||||
#include <XCEngine/Resources/Material/MaterialLoader.h>
|
||||
#include <XCEngine/Resources/Mesh/MeshLoader.h>
|
||||
#include <XCEngine/Resources/Shader/ShaderLoader.h>
|
||||
@@ -31,6 +32,10 @@ ResourceManager& ResourceManager::Get() {
|
||||
}
|
||||
|
||||
void ResourceManager::Initialize() {
|
||||
if (m_asyncLoader) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_asyncLoader = Core::MakeUnique<AsyncLoader>();
|
||||
m_asyncLoader->Initialize(2);
|
||||
|
||||
@@ -42,12 +47,23 @@ void ResourceManager::Initialize() {
|
||||
|
||||
void ResourceManager::Shutdown() {
|
||||
UnloadAll();
|
||||
m_asyncLoader->Shutdown();
|
||||
m_asyncLoader.reset();
|
||||
if (m_asyncLoader) {
|
||||
m_asyncLoader->Shutdown();
|
||||
m_asyncLoader.reset();
|
||||
}
|
||||
m_assetDatabase.Shutdown();
|
||||
ResourceFileSystem::Get().Shutdown();
|
||||
}
|
||||
|
||||
void ResourceManager::SetResourceRoot(const Containers::String& rootPath) {
|
||||
m_resourceRoot = rootPath;
|
||||
if (!m_resourceRoot.Empty()) {
|
||||
ResourceFileSystem::Get().Initialize(rootPath);
|
||||
m_assetDatabase.Initialize(rootPath);
|
||||
} else {
|
||||
ResourceFileSystem::Get().Shutdown();
|
||||
m_assetDatabase.Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
const Containers::String& ResourceManager::GetResourceRoot() const {
|
||||
@@ -111,7 +127,8 @@ IResource* ResourceManager::FindInCache(ResourceGUID guid) {
|
||||
|
||||
void ResourceManager::AddToCache(ResourceGUID guid, IResource* resource) {
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
|
||||
resource->m_guid = guid;
|
||||
m_resourceCache.Insert(guid, resource);
|
||||
m_memoryUsage += resource->GetMemorySize();
|
||||
m_cache.Add(guid, resource);
|
||||
@@ -128,6 +145,7 @@ void ResourceManager::Unload(ResourceGUID guid) {
|
||||
if (it != nullptr) {
|
||||
IResource* resource = *it;
|
||||
m_resourceCache.Erase(guid);
|
||||
m_guidToPath.Erase(guid);
|
||||
m_memoryUsage -= resource->GetMemorySize();
|
||||
resource->Release();
|
||||
}
|
||||
@@ -135,13 +153,16 @@ void ResourceManager::Unload(ResourceGUID guid) {
|
||||
|
||||
void ResourceManager::UnloadAll() {
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
for (size_t i = 0; i < m_resourceCache.Size(); ++i) {
|
||||
// This is a simplified approach - we'd need a way to iterate
|
||||
// For now, just clear everything
|
||||
|
||||
const auto cachedResources = m_resourceCache.GetPairs();
|
||||
for (const auto& pair : cachedResources) {
|
||||
if (pair.second != nullptr) {
|
||||
pair.second->Release();
|
||||
}
|
||||
}
|
||||
m_resourceCache.Clear();
|
||||
m_refCounts.Clear();
|
||||
m_guidToPath.Clear();
|
||||
m_memoryUsage = 0;
|
||||
}
|
||||
|
||||
@@ -209,6 +230,10 @@ void ResourceManager::ReloadResource(ResourceGUID guid) {
|
||||
if (pathIt == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Containers::String path = *pathIt;
|
||||
auto* typeIt = m_resourceCache.Find(guid);
|
||||
(void)typeIt;
|
||||
}
|
||||
|
||||
Containers::Array<Containers::String> ResourceManager::GetResourcePaths() const {
|
||||
@@ -226,11 +251,60 @@ void ResourceManager::UnloadGroup(const Containers::Array<ResourceGUID>& guids)
|
||||
if (it != nullptr) {
|
||||
IResource* resource = *it;
|
||||
m_resourceCache.Erase(guid);
|
||||
m_guidToPath.Erase(guid);
|
||||
m_memoryUsage -= resource->GetMemorySize();
|
||||
resource->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ResourceManager::RefreshAssetDatabase() {
|
||||
if (!m_resourceRoot.Empty()) {
|
||||
m_assetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
bool ResourceManager::TryGetAssetRef(const Containers::String& path, ResourceType resourceType, AssetRef& outRef) const {
|
||||
return m_assetDatabase.TryGetAssetRef(path, resourceType, outRef);
|
||||
}
|
||||
|
||||
LoadResult ResourceManager::LoadResource(const Containers::String& path,
|
||||
ResourceType type,
|
||||
ImportSettings* settings) {
|
||||
const ResourceGUID guid = ResourceGUID::Generate(path);
|
||||
|
||||
if (IResource* cached = FindInCache(guid)) {
|
||||
return LoadResult(cached);
|
||||
}
|
||||
|
||||
IResourceLoader* loader = FindLoader(type);
|
||||
if (loader == nullptr) {
|
||||
Debug::Logger::Get().Warning(Debug::LogCategory::FileSystem,
|
||||
Containers::String("No loader found for resource type: ") +
|
||||
GetResourceTypeName(type));
|
||||
return LoadResult(false, "Loader not found");
|
||||
}
|
||||
|
||||
Containers::String loadPath = path;
|
||||
AssetDatabase::ResolvedAsset resolvedAsset;
|
||||
if (!m_resourceRoot.Empty() &&
|
||||
m_assetDatabase.EnsureArtifact(path, type, resolvedAsset) &&
|
||||
resolvedAsset.artifactReady) {
|
||||
loadPath = resolvedAsset.artifactMainPath;
|
||||
}
|
||||
|
||||
LoadResult result = loader->Load(loadPath, settings);
|
||||
if (!result || result.resource == nullptr) {
|
||||
Debug::Logger::Get().Error(Debug::LogCategory::FileSystem,
|
||||
Containers::String("Failed to load resource: ") + path + " - " + result.errorMessage);
|
||||
return result;
|
||||
}
|
||||
|
||||
result.resource->m_path = path;
|
||||
AddToCache(guid, result.resource);
|
||||
m_guidToPath.Insert(guid, path);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace Resources
|
||||
} // namespace XCEngine
|
||||
|
||||
Reference in New Issue
Block a user