Files
XCEngine/engine/include/XCEngine/Core/Asset/AssetDatabase.h

133 lines
5.5 KiB
C++

#pragma once
#include <XCEngine/Core/Asset/AssetRef.h>
#include <XCEngine/Core/Containers/String.h>
#include <XCEngine/Core/Types.h>
#include <filesystem>
#include <unordered_map>
namespace XCEngine {
namespace Resources {
class AssetDatabase {
public:
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;
Containers::String artifactDirectory;
Containers::String mainArtifactPath;
Containers::String sourceHash;
Containers::String metaHash;
Core::uint64 sourceFileSize = 0;
Core::uint64 sourceWriteTime = 0;
LocalID mainLocalID = kMainAssetLocalID;
};
struct ResolvedAsset {
bool exists = false;
bool artifactReady = false;
Containers::String absolutePath;
Containers::String relativePath;
AssetGUID assetGuid;
ResourceType resourceType = ResourceType::Unknown;
Containers::String artifactMainPath;
Containers::String artifactDirectory;
LocalID mainLocalID = kMainAssetLocalID;
};
void Initialize(const Containers::String& projectRoot);
void Shutdown();
void Refresh();
bool ResolvePath(const Containers::String& requestPath,
Containers::String& outAbsolutePath,
Containers::String& outRelativePath) const;
bool TryGetAssetGuid(const Containers::String& requestPath, AssetGUID& outGuid) const;
bool TryGetAssetRef(const Containers::String& requestPath, ResourceType resourceType, AssetRef& outRef) const;
bool EnsureArtifact(const Containers::String& requestPath,
ResourceType requestedType,
ResolvedAsset& outAsset);
bool TryGetPrimaryAssetPath(const AssetGUID& guid, Containers::String& outRelativePath) 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; }
private:
static constexpr Core::uint32 kCurrentImporterVersion = 2;
void EnsureProjectLayout();
void LoadSourceAssetDB();
void SaveSourceAssetDB() const;
void LoadArtifactDB();
void SaveArtifactDB() const;
void ScanAssets();
void ScanAssetPath(const std::filesystem::path& path,
std::unordered_map<std::string, bool>& seenPaths);
void RemoveMissingRecords(const std::unordered_map<std::string, bool>& seenPaths);
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 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);
Containers::String BuildArtifactKey(const SourceAssetRecord& sourceRecord) const;
Containers::String BuildArtifactDirectory(const Containers::String& artifactKey) 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 m_projectRoot;
Containers::String m_assetsRoot;
Containers::String m_libraryRoot;
Containers::String m_sourceDbPath;
Containers::String m_artifactDbPath;
std::unordered_map<std::string, SourceAssetRecord> m_sourcesByPathKey;
std::unordered_map<AssetGUID, SourceAssetRecord> m_sourcesByGuid;
std::unordered_map<AssetGUID, ArtifactRecord> m_artifactsByGuid;
};
} // namespace Resources
} // namespace XCEngine