212 lines
9.6 KiB
C++
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
|