- Split core resource architecture into Core/Asset/ (IResource, ResourceManager, ResourceCache, etc.)
- Moved IO layer into Core/IO/ (IResourceLoader, ResourceFileSystem, etc.)
- Reorganized concrete resource types into Resources/{Texture,Mesh,Material,Shader,AudioClip}/
- Updated all include paths from relative to <XCEngine/...> format
- Fixed circular dependency in Material.h (removed unnecessary ResourceManager.h include)
- Fixed malformed include syntax in ResourceManager.h and AsyncLoader.h
- Fixed glad.h path issues in CMakeLists.txt
212 lines
5.4 KiB
C++
212 lines
5.4 KiB
C++
#include "Resources/ResourceManager.h"
|
|
#include "Resources/ResourceHandle.h"
|
|
#include "Resources/ResourceTypes.h"
|
|
|
|
namespace XCEngine {
|
|
namespace Resources {
|
|
|
|
ResourceManager& ResourceManager::Get() {
|
|
static ResourceManager instance;
|
|
return instance;
|
|
}
|
|
|
|
void ResourceManager::Initialize() {
|
|
m_asyncLoader = Core::MakeUnique<AsyncLoader>();
|
|
m_asyncLoader->Initialize(2);
|
|
}
|
|
|
|
void ResourceManager::Shutdown() {
|
|
UnloadAll();
|
|
m_asyncLoader->Shutdown();
|
|
m_asyncLoader.reset();
|
|
}
|
|
|
|
void ResourceManager::SetResourceRoot(const Containers::String& rootPath) {
|
|
m_resourceRoot = rootPath;
|
|
}
|
|
|
|
const Containers::String& ResourceManager::GetResourceRoot() const {
|
|
return m_resourceRoot;
|
|
}
|
|
|
|
void ResourceManager::AddRef(ResourceGUID guid) {
|
|
std::lock_guard lock(m_mutex);
|
|
|
|
auto* it = m_refCounts.Find(guid);
|
|
if (it == nullptr) {
|
|
m_refCounts.Insert(guid, 1);
|
|
} else {
|
|
(*it)++;
|
|
}
|
|
|
|
if (!m_resourceCache.Contains(guid)) {
|
|
ReloadResource(guid);
|
|
}
|
|
}
|
|
|
|
void ResourceManager::Release(ResourceGUID guid) {
|
|
std::lock_guard lock(m_mutex);
|
|
|
|
auto* it = m_refCounts.Find(guid);
|
|
if (it != nullptr) {
|
|
(*it)--;
|
|
|
|
if (*it == 0) {
|
|
m_refCounts.Erase(guid);
|
|
m_cache.OnZeroRefCount(guid);
|
|
}
|
|
}
|
|
}
|
|
|
|
Core::uint32 ResourceManager::GetRefCount(ResourceGUID guid) const {
|
|
auto* it = m_refCounts.Find(guid);
|
|
return it != nullptr ? *it : 0;
|
|
}
|
|
|
|
void ResourceManager::RegisterLoader(IResourceLoader* loader) {
|
|
std::lock_guard lock(m_mutex);
|
|
m_loaders.Insert(loader->GetResourceType(), loader);
|
|
}
|
|
|
|
IResourceLoader* ResourceManager::GetLoader(ResourceType type) const {
|
|
auto* it = m_loaders.Find(type);
|
|
return it != nullptr ? *it : nullptr;
|
|
}
|
|
|
|
IResourceLoader* ResourceManager::FindLoader(ResourceType type) {
|
|
return GetLoader(type);
|
|
}
|
|
|
|
IResource* ResourceManager::FindInCache(ResourceGUID guid) {
|
|
std::lock_guard lock(m_mutex);
|
|
|
|
auto* it = m_resourceCache.Find(guid);
|
|
return it != nullptr ? *it : nullptr;
|
|
}
|
|
|
|
void ResourceManager::AddToCache(ResourceGUID guid, IResource* resource) {
|
|
std::lock_guard lock(m_mutex);
|
|
|
|
m_resourceCache.Insert(guid, resource);
|
|
m_memoryUsage += resource->GetMemorySize();
|
|
m_cache.Add(guid, resource);
|
|
|
|
if (m_memoryUsage > m_memoryBudget) {
|
|
m_cache.OnMemoryPressure(m_memoryUsage - m_memoryBudget);
|
|
}
|
|
}
|
|
|
|
void ResourceManager::Unload(ResourceGUID guid) {
|
|
std::lock_guard lock(m_mutex);
|
|
|
|
auto* it = m_resourceCache.Find(guid);
|
|
if (it != nullptr) {
|
|
IResource* resource = *it;
|
|
m_resourceCache.Erase(guid);
|
|
m_memoryUsage -= resource->GetMemorySize();
|
|
resource->Release();
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
m_resourceCache.Clear();
|
|
m_refCounts.Clear();
|
|
m_memoryUsage = 0;
|
|
}
|
|
|
|
void ResourceManager::SetMemoryBudget(size_t bytes) {
|
|
m_memoryBudget = bytes;
|
|
}
|
|
|
|
size_t ResourceManager::GetMemoryUsage() const {
|
|
return m_memoryUsage;
|
|
}
|
|
|
|
size_t ResourceManager::GetMemoryBudget() const {
|
|
return m_memoryBudget;
|
|
}
|
|
|
|
void ResourceManager::FlushCache() {
|
|
m_cache.Flush();
|
|
}
|
|
|
|
IResource* ResourceManager::Find(const Containers::String& path) {
|
|
return Find(ResourceGUID::Generate(path));
|
|
}
|
|
|
|
IResource* ResourceManager::Find(ResourceGUID guid) {
|
|
return FindInCache(guid);
|
|
}
|
|
|
|
bool ResourceManager::Exists(const Containers::String& path) const {
|
|
return Exists(ResourceGUID::Generate(path));
|
|
}
|
|
|
|
bool ResourceManager::Exists(ResourceGUID guid) const {
|
|
return m_resourceCache.Contains(guid);
|
|
}
|
|
|
|
Containers::String ResourceManager::ResolvePath(const Containers::String& relativePath) const {
|
|
return m_resourceRoot + "/" + relativePath;
|
|
}
|
|
|
|
void ResourceManager::LoadAsync(const Containers::String& path, ResourceType type,
|
|
std::function<void(LoadResult)> callback) {
|
|
LoadAsync(path, type, nullptr, callback);
|
|
}
|
|
|
|
void ResourceManager::LoadAsync(const Containers::String& path, ResourceType type,
|
|
ImportSettings* settings,
|
|
std::function<void(LoadResult)> callback) {
|
|
m_asyncLoader->Submit(path, type, settings, callback);
|
|
}
|
|
|
|
void ResourceManager::Unload(const Containers::String& path) {
|
|
Unload(ResourceGUID::Generate(path));
|
|
}
|
|
|
|
void ResourceManager::UnloadUnused() {
|
|
|
|
}
|
|
|
|
void ResourceManager::UnregisterLoader(ResourceType type) {
|
|
m_loaders.Erase(type);
|
|
}
|
|
|
|
void ResourceManager::ReloadResource(ResourceGUID guid) {
|
|
auto* pathIt = m_guidToPath.Find(guid);
|
|
if (pathIt == nullptr) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
Containers::Array<Containers::String> ResourceManager::GetResourcePaths() const {
|
|
Containers::Array<Containers::String> paths;
|
|
for (const auto& pair : m_guidToPath) {
|
|
paths.PushBack(pair.second);
|
|
}
|
|
return paths;
|
|
}
|
|
|
|
void ResourceManager::UnloadGroup(const Containers::Array<ResourceGUID>& guids) {
|
|
std::lock_guard lock(m_mutex);
|
|
for (const auto& guid : guids) {
|
|
auto* it = m_resourceCache.Find(guid);
|
|
if (it != nullptr) {
|
|
IResource* resource = *it;
|
|
m_resourceCache.Erase(guid);
|
|
m_memoryUsage -= resource->GetMemorySize();
|
|
resource->Release();
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace Resources
|
|
} // namespace XCEngine
|