Files
XCEngine/Pipeline/Core/AssetDatabase/Facade/AssetDatabase.h

212 lines
9.6 KiB
C++

#pragma once
#include <XCEngine/Core/Asset/AssetRef.h>
#include <XCEngine/Core/Asset/ProjectAssetTypes.h>
#include <XCEngine/Core/Containers/String.h>
#include <XCEngine/Core/Types.h>
#include <XCEngine/Resources/UI/UIDocumentTypes.h>
#include <filesystem>
#include <memory>
#include <unordered_map>
#include <vector>
namespace XCEngine {
namespace Resources {
class Mesh;
class Material;
namespace AssetDatabaseInternal {
class AssetDatabaseImportRunner;
class AssetDatabaseMaintenanceRunner;
class SourceAssetDB;
class ArtifactDB;
}
class AssetDatabase {
public:
AssetDatabase();
~AssetDatabase();
struct MaintenanceStats {
Core::uint32 importedAssetCount = 0;
Core::uint32 removedArtifactCount = 0;
};
struct ArtifactDependencyRecord {
Containers::String path;
Containers::String hash;
Core::uint64 fileSize = 0;
Core::uint64 writeTime = 0;
};
struct SourceAssetRecord {
AssetGUID guid;
Containers::String relativePath;
Containers::String metaPath;
bool isFolder = false;
Containers::String importerName;
Core::uint32 importerVersion = 0;
Containers::String metaHash;
Containers::String sourceHash;
Core::uint64 sourceFileSize = 0;
Core::uint64 sourceWriteTime = 0;
Containers::String lastKnownArtifactKey;
};
struct ArtifactRecord {
Containers::String artifactKey;
AssetGUID assetGuid;
Containers::String importerName;
Core::uint32 importerVersion = 0;
ResourceType resourceType = ResourceType::Unknown;
ArtifactStorageKind storageKind = ArtifactStorageKind::Unknown;
Containers::String artifactDirectory;
Containers::String mainArtifactPath;
Containers::String mainEntryName;
Containers::String sourceHash;
Containers::String metaHash;
Core::uint64 sourceFileSize = 0;
Core::uint64 sourceWriteTime = 0;
LocalID mainLocalID = kMainAssetLocalID;
std::vector<ArtifactDependencyRecord> dependencies;
};
struct ResolvedAsset {
bool exists = false;
bool artifactReady = false;
bool imported = false;
Containers::String absolutePath;
Containers::String relativePath;
AssetGUID assetGuid;
ResourceType resourceType = ResourceType::Unknown;
Containers::String artifactMainPath;
Containers::String artifactMainEntryPath;
Containers::String artifactDirectory;
ArtifactStorageKind artifactStorageKind = ArtifactStorageKind::Unknown;
Containers::String mainEntryName;
LocalID mainLocalID = kMainAssetLocalID;
};
void Initialize(const Containers::String& projectRoot);
void Shutdown();
MaintenanceStats Refresh();
bool ResolvePath(const Containers::String& requestPath,
Containers::String& outAbsolutePath,
Containers::String& outRelativePath) const;
bool TryGetAssetGuid(const Containers::String& requestPath, AssetGUID& outGuid) const;
bool TryGetImportableResourceType(const Containers::String& requestPath, ResourceType& outType) const;
bool TryGetAssetRef(const Containers::String& requestPath, ResourceType resourceType, AssetRef& outRef) const;
bool TryResolveAssetPath(const AssetRef& assetRef, Containers::String& outPath);
bool ReimportAsset(const Containers::String& requestPath,
ResolvedAsset& outAsset,
MaintenanceStats* outStats = nullptr);
bool ReimportAllAssets(MaintenanceStats* outStats = nullptr);
bool EnsureArtifact(const Containers::String& requestPath,
ResourceType requestedType,
ResolvedAsset& outAsset);
bool TryGetPrimaryAssetPath(const AssetGUID& guid, Containers::String& outRelativePath) const;
void BuildLookupSnapshot(std::unordered_map<std::string, AssetGUID>& outPathToGuid,
std::unordered_map<AssetGUID, Containers::String>& outGuidToPath) const;
const Containers::String& GetProjectRoot() const { return m_projectRoot; }
const Containers::String& GetAssetsRoot() const { return m_assetsRoot; }
const Containers::String& GetLibraryRoot() const { return m_libraryRoot; }
const Containers::String& GetLastErrorMessage() const { return m_lastErrorMessage; }
private:
friend class AssetDatabaseInternal::AssetDatabaseImportRunner;
friend class AssetDatabaseInternal::AssetDatabaseMaintenanceRunner;
static constexpr Core::uint32 kBaseImporterVersion = 7;
void EnsureProjectLayout();
void LoadSourceAssetDB();
void SaveSourceAssetDB() const;
void LoadArtifactDB();
void SaveArtifactDB() const;
bool EnsureMetaForPath(const std::filesystem::path& sourcePath,
bool isFolder,
SourceAssetRecord& outRecord);
bool ReadMetaFile(const std::filesystem::path& metaPath,
SourceAssetRecord& inOutRecord) const;
void WriteMetaFile(const std::filesystem::path& metaPath,
const SourceAssetRecord& record) const;
Containers::String NormalizeRelativePath(const std::filesystem::path& sourcePath) const;
static Containers::String NormalizePathString(const std::filesystem::path& path);
static Containers::String NormalizePathString(const Containers::String& path);
static Containers::String MakeKey(const Containers::String& path);
static Containers::String GetImporterNameForPath(const Containers::String& relativePath, bool isFolder);
static Core::uint32 GetCurrentImporterVersion(const Containers::String& importerName);
static ResourceType GetPrimaryResourceTypeForImporter(const Containers::String& importerName);
bool ShouldReimport(const SourceAssetRecord& sourceRecord,
const ArtifactRecord* artifactRecord) const;
bool ImportAsset(const SourceAssetRecord& sourceRecord,
ArtifactRecord& outRecord);
bool ImportTextureAsset(const SourceAssetRecord& sourceRecord,
ArtifactRecord& outRecord);
bool ImportMaterialAsset(const SourceAssetRecord& sourceRecord,
ArtifactRecord& outRecord);
bool ImportModelAsset(const SourceAssetRecord& sourceRecord,
ArtifactRecord& outRecord);
bool ImportShaderAsset(const SourceAssetRecord& sourceRecord,
ArtifactRecord& outRecord);
bool ImportGaussianSplatAsset(const SourceAssetRecord& sourceRecord,
ArtifactRecord& outRecord);
bool ImportVolumeFieldAsset(const SourceAssetRecord& sourceRecord,
ArtifactRecord& outRecord);
bool ImportUIDocumentAsset(const SourceAssetRecord& sourceRecord,
UIDocumentKind kind,
const char* artifactFileName,
ResourceType resourceType,
ArtifactRecord& outRecord);
Containers::String BuildArtifactKey(
const SourceAssetRecord& sourceRecord,
const std::vector<ArtifactDependencyRecord>& dependencies = {}) const;
Containers::String BuildArtifactDirectory(const Containers::String& artifactKey) const;
Containers::String BuildArtifactFilePath(const Containers::String& artifactKey,
const char* extension) const;
static Containers::String ReadWholeFileText(const std::filesystem::path& path);
static Containers::String ComputeFileHash(const std::filesystem::path& path);
static Core::uint64 GetFileSizeValue(const std::filesystem::path& path);
static Core::uint64 GetFileWriteTimeValue(const std::filesystem::path& path);
Containers::String NormalizeDependencyPath(const std::filesystem::path& path) const;
std::filesystem::path ResolveDependencyPath(const Containers::String& path) const;
bool CaptureDependencyRecord(const std::filesystem::path& path,
ArtifactDependencyRecord& outRecord) const;
bool AreDependenciesCurrent(const std::vector<ArtifactDependencyRecord>& dependencies) const;
bool CollectModelDependencies(const SourceAssetRecord& sourceRecord,
const std::vector<Containers::String>& importedTexturePaths,
std::vector<ArtifactDependencyRecord>& outDependencies) const;
bool CollectMaterialDependencies(const Material& material,
std::vector<ArtifactDependencyRecord>& outDependencies) const;
bool CollectShaderDependencies(const SourceAssetRecord& sourceRecord,
std::vector<ArtifactDependencyRecord>& outDependencies,
Containers::String* outError = nullptr) const;
void ClearLastErrorMessage();
void SetLastErrorMessage(const Containers::String& message);
AssetDatabaseInternal::SourceAssetDB& GetSourceAssetDB();
const AssetDatabaseInternal::SourceAssetDB& GetSourceAssetDB() const;
AssetDatabaseInternal::ArtifactDB& GetArtifactDB();
const AssetDatabaseInternal::ArtifactDB& GetArtifactDB() const;
Containers::String m_projectRoot;
Containers::String m_assetsRoot;
Containers::String m_libraryRoot;
Containers::String m_sourceDbPath;
Containers::String m_artifactDbPath;
Containers::String m_lastErrorMessage;
std::unique_ptr<AssetDatabaseInternal::SourceAssetDB> m_sourceAssetDB;
std::unique_ptr<AssetDatabaseInternal::ArtifactDB> m_artifactDB;
};
} // namespace Resources
} // namespace XCEngine