#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(); 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 callback) { LoadAsync(path, type, nullptr, callback); } void ResourceManager::LoadAsync(const Containers::String& path, ResourceType type, ImportSettings* settings, std::function 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 ResourceManager::GetResourcePaths() const { Containers::Array paths; for (const auto& pair : m_guidToPath) { paths.PushBack(pair.second); } return paths; } void ResourceManager::UnloadGroup(const Containers::Array& 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