Finalize library bootstrap status and stabilize async asset regressions

This commit is contained in:
2026-04-04 19:44:59 +08:00
parent 013e5a73b9
commit bcef1f145b
25 changed files with 3415 additions and 81 deletions

View File

@@ -6,6 +6,7 @@
#include <XCEngine/Resources/Mesh/MeshLoader.h>
#include <XCEngine/Resources/Shader/ShaderLoader.h>
#include <XCEngine/Resources/Texture/TextureLoader.h>
#include <XCEngine/Resources/UI/UIDocumentLoaders.h>
#include <exception>
namespace XCEngine {
@@ -45,6 +46,9 @@ MaterialLoader g_materialLoader;
MeshLoader g_meshLoader;
ShaderLoader g_shaderLoader;
TextureLoader g_textureLoader;
UIViewLoader g_uiViewLoader;
UIThemeLoader g_uiThemeLoader;
UISchemaLoader g_uiSchemaLoader;
} // namespace
@@ -85,6 +89,9 @@ void ResourceManager::EnsureInitialized() {
RegisterBuiltinLoader(*this, g_meshLoader);
RegisterBuiltinLoader(*this, g_shaderLoader);
RegisterBuiltinLoader(*this, g_textureLoader);
RegisterBuiltinLoader(*this, g_uiViewLoader);
RegisterBuiltinLoader(*this, g_uiThemeLoader);
RegisterBuiltinLoader(*this, g_uiSchemaLoader);
m_assetImportService.Initialize();
m_asyncLoader = std::move(asyncLoader);
@@ -106,11 +113,12 @@ void ResourceManager::Shutdown() {
}
void ResourceManager::SetResourceRoot(const Containers::String& rootPath) {
EnsureInitialized();
m_resourceRoot = rootPath;
if (!m_resourceRoot.Empty()) {
ResourceFileSystem::Get().Initialize(rootPath);
m_assetImportService.SetProjectRoot(rootPath);
m_projectAssetIndex.RefreshFrom(m_assetImportService);
BootstrapProjectAssets();
} else {
m_assetImportService.SetProjectRoot(Containers::String());
ResourceFileSystem::Get().Shutdown();
@@ -122,6 +130,16 @@ const Containers::String& ResourceManager::GetResourceRoot() const {
return m_resourceRoot;
}
bool ResourceManager::BootstrapProjectAssets() {
if (m_resourceRoot.Empty()) {
return false;
}
const bool bootstrapped = m_assetImportService.BootstrapProject();
m_projectAssetIndex.RefreshFrom(m_assetImportService);
return bootstrapped;
}
void ResourceManager::AddRef(ResourceGUID guid) {
std::lock_guard lock(m_mutex);
@@ -199,6 +217,7 @@ void ResourceManager::Unload(ResourceGUID guid) {
if (it != nullptr) {
resource = *it;
m_resourceCache.Erase(guid);
m_cache.Remove(guid);
m_guidToPath.Erase(guid);
m_memoryUsage -= resource->GetMemorySize();
}
@@ -223,6 +242,7 @@ void ResourceManager::UnloadAll() {
}
m_resourceCache.Clear();
m_cache.Clear();
m_refCounts.Clear();
m_guidToPath.Clear();
m_memoryUsage = 0;
@@ -346,6 +366,7 @@ void ResourceManager::UnloadGroup(const Containers::Array<ResourceGUID>& guids)
if (it != nullptr) {
IResource* resource = *it;
m_resourceCache.Erase(guid);
m_cache.Remove(guid);
m_guidToPath.Erase(guid);
m_memoryUsage -= resource->GetMemorySize();
resourcesToRelease.PushBack(resource);
@@ -360,13 +381,69 @@ void ResourceManager::UnloadGroup(const Containers::Array<ResourceGUID>& guids)
}
}
void ResourceManager::RefreshAssetDatabase() {
void ResourceManager::RefreshProjectAssets() {
if (!m_resourceRoot.Empty()) {
m_assetImportService.Refresh();
m_projectAssetIndex.RefreshFrom(m_assetImportService);
}
}
bool ResourceManager::CanReimportProjectAsset(const Containers::String& path) const {
if (m_resourceRoot.Empty() || path.Empty()) {
return false;
}
ResourceType importType = ResourceType::Unknown;
return m_assetImportService.TryGetImportableResourceType(path, importType);
}
bool ResourceManager::ReimportProjectAsset(const Containers::String& path) {
if (m_resourceRoot.Empty() || path.Empty()) {
return false;
}
UnloadAll();
AssetImportService::ImportedAsset importedAsset;
const bool reimported = m_assetImportService.ReimportAsset(path, importedAsset);
m_projectAssetIndex.RefreshFrom(m_assetImportService);
if (reimported && importedAsset.assetGuid.IsValid() && !importedAsset.relativePath.Empty()) {
m_projectAssetIndex.RememberResolvedPath(importedAsset.assetGuid, importedAsset.relativePath);
}
return reimported;
}
bool ResourceManager::ClearProjectLibraryCache() {
if (m_resourceRoot.Empty()) {
return false;
}
UnloadAll();
const bool cleared = m_assetImportService.ClearLibraryCache();
m_projectAssetIndex.RefreshFrom(m_assetImportService);
return cleared;
}
bool ResourceManager::RebuildProjectAssetCache() {
if (m_resourceRoot.Empty()) {
return false;
}
UnloadAll();
const bool rebuilt = m_assetImportService.RebuildLibraryCache();
m_projectAssetIndex.RefreshFrom(m_assetImportService);
return rebuilt;
}
Containers::String ResourceManager::GetProjectLibraryRoot() const {
return m_assetImportService.GetLibraryRoot();
}
AssetImportService::ImportStatusSnapshot ResourceManager::GetProjectAssetImportStatus() const {
return m_assetImportService.GetLastImportStatus();
}
bool ResourceManager::TryGetAssetRef(const Containers::String& path, ResourceType resourceType, AssetRef& outRef) const {
const bool resolved = m_projectAssetIndex.TryGetAssetRef(m_assetImportService, path, resourceType, outRef);
@@ -510,12 +587,18 @@ LoadResult ResourceManager::LoadResource(const Containers::String& path,
}
Containers::String loadPath = path;
AssetDatabase::ResolvedAsset resolvedAsset;
if (!m_resourceRoot.Empty() &&
AssetImportService::ImportedAsset resolvedAsset;
ResourceType importableType = ResourceType::Unknown;
const bool shouldUseProjectArtifact =
!m_resourceRoot.Empty() &&
m_assetImportService.TryGetImportableResourceType(path, importableType) &&
importableType == type;
if (shouldUseProjectArtifact &&
m_assetImportService.EnsureArtifact(path, type, resolvedAsset) &&
resolvedAsset.artifactReady) {
m_projectAssetIndex.RememberResolvedPath(resolvedAsset.assetGuid, resolvedAsset.relativePath);
loadPath = resolvedAsset.artifactMainPath;
loadPath = resolvedAsset.runtimeLoadPath;
if (ShouldTraceResourcePath(path)) {
Debug::Logger::Get().Info(
Debug::LogCategory::FileSystem,