Add gaussian splat asset caching groundwork
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
@@ -109,6 +110,19 @@ bool PumpAsyncLoadsUntil(ResourceManager& manager,
|
||||
return condition();
|
||||
}
|
||||
|
||||
std::filesystem::path GetRepositoryRoot() {
|
||||
std::filesystem::path current = std::filesystem::path(__FILE__).parent_path();
|
||||
while (!current.empty()) {
|
||||
if (std::filesystem::exists(current / "project") &&
|
||||
std::filesystem::exists(current / "engine")) {
|
||||
return current;
|
||||
}
|
||||
current = current.parent_path();
|
||||
}
|
||||
|
||||
return std::filesystem::path(__FILE__).parent_path();
|
||||
}
|
||||
|
||||
bool DirectoryHasEntries(const std::filesystem::path& directoryPath) {
|
||||
std::error_code ec;
|
||||
if (!std::filesystem::exists(directoryPath, ec) || !std::filesystem::is_directory(directoryPath, ec)) {
|
||||
@@ -118,6 +132,38 @@ bool DirectoryHasEntries(const std::filesystem::path& directoryPath) {
|
||||
return std::filesystem::directory_iterator(directoryPath) != std::filesystem::directory_iterator();
|
||||
}
|
||||
|
||||
std::vector<std::string> SplitTabSeparatedLine(const std::string& line) {
|
||||
std::vector<std::string> fields;
|
||||
std::stringstream stream(line);
|
||||
std::string field;
|
||||
while (std::getline(stream, field, '\t')) {
|
||||
fields.push_back(field);
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
std::string ReadSourceHashFromAssetsDb(const std::filesystem::path& assetsDbPath,
|
||||
const std::string& relativePath) {
|
||||
std::ifstream input(assetsDbPath, std::ios::binary);
|
||||
if (!input.is_open()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string line;
|
||||
while (std::getline(input, line)) {
|
||||
if (line.empty() || line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::vector<std::string> fields = SplitTabSeparatedLine(line);
|
||||
if (fields.size() > 7 && fields[1] == relativePath) {
|
||||
return fields[7];
|
||||
}
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path> ListArtifactEntries(const std::filesystem::path& artifactsRoot) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
@@ -424,6 +470,47 @@ TEST(AssetImportService_Test, EnsureArtifactExposesContainerEntryRuntimeLoadPath
|
||||
fs::remove_all(projectRoot);
|
||||
}
|
||||
|
||||
TEST(AssetImportService_Test, BootstrapProjectDefersSourceHashUntilArtifactIsNeeded) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
AssetImportService importService;
|
||||
importService.Initialize();
|
||||
|
||||
const fs::path projectRoot = fs::temp_directory_path() / "xc_asset_import_service_deferred_source_hash_test";
|
||||
const fs::path assetsDir = projectRoot / "Assets";
|
||||
const fs::path materialPath = assetsDir / "runtime.material";
|
||||
|
||||
fs::remove_all(projectRoot);
|
||||
fs::create_directories(assetsDir);
|
||||
{
|
||||
std::ofstream materialFile(materialPath);
|
||||
ASSERT_TRUE(materialFile.is_open());
|
||||
materialFile << "{\n";
|
||||
materialFile << " \"renderQueue\": \"geometry\"\n";
|
||||
materialFile << "}\n";
|
||||
}
|
||||
|
||||
importService.SetProjectRoot(projectRoot.string().c_str());
|
||||
ASSERT_TRUE(importService.BootstrapProject());
|
||||
|
||||
const fs::path libraryRoot(importService.GetLibraryRoot().CStr());
|
||||
const fs::path assetsDbPath = libraryRoot / "assets.db";
|
||||
ASSERT_TRUE(fs::exists(assetsDbPath));
|
||||
EXPECT_FALSE(DirectoryHasEntries(libraryRoot / "Artifacts"));
|
||||
EXPECT_TRUE(ReadSourceHashFromAssetsDb(assetsDbPath, "Assets/runtime.material").empty());
|
||||
|
||||
AssetImportService::ImportedAsset importedAsset;
|
||||
ASSERT_TRUE(importService.EnsureArtifact("Assets/runtime.material", ResourceType::Material, importedAsset));
|
||||
EXPECT_TRUE(importedAsset.exists);
|
||||
EXPECT_TRUE(importedAsset.artifactReady);
|
||||
EXPECT_TRUE(importedAsset.imported);
|
||||
EXPECT_FALSE(ReadSourceHashFromAssetsDb(assetsDbPath, "Assets/runtime.material").empty());
|
||||
EXPECT_TRUE(DirectoryHasEntries(libraryRoot / "Artifacts"));
|
||||
|
||||
importService.Shutdown();
|
||||
fs::remove_all(projectRoot);
|
||||
}
|
||||
|
||||
TEST(ResourceManager_Test, RebuildProjectAssetCacheRefreshesLookupState) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
@@ -545,6 +632,58 @@ TEST(ResourceManager_Test, SetResourceRootBootstrapsProjectAssetCache) {
|
||||
fs::remove_all(projectRoot);
|
||||
}
|
||||
|
||||
TEST(ResourceManager_ProjectSample, BootstrapProjectKeepsCloudSourceHashDeferred) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path repositoryRoot = GetRepositoryRoot();
|
||||
const fs::path projectRoot = repositoryRoot / "project";
|
||||
const fs::path volumePath = projectRoot / "Assets" / "cloud.nvdb";
|
||||
|
||||
if (!fs::exists(volumePath)) {
|
||||
GTEST_SKIP() << "Project cloud volume fixture is not available.";
|
||||
}
|
||||
|
||||
ResourceManager& manager = ResourceManager::Get();
|
||||
manager.Initialize();
|
||||
|
||||
struct ResourceManagerGuard {
|
||||
ResourceManager* manager = nullptr;
|
||||
~ResourceManagerGuard() {
|
||||
if (manager != nullptr) {
|
||||
manager->Shutdown();
|
||||
}
|
||||
}
|
||||
} resourceManagerGuard{ &manager };
|
||||
|
||||
struct CurrentPathGuard {
|
||||
fs::path previousPath;
|
||||
~CurrentPathGuard() {
|
||||
if (!previousPath.empty()) {
|
||||
fs::current_path(previousPath);
|
||||
}
|
||||
}
|
||||
} currentPathGuard{ fs::current_path() };
|
||||
|
||||
fs::current_path(projectRoot);
|
||||
manager.SetResourceRoot(projectRoot.string().c_str());
|
||||
|
||||
AssetRef volumeRef;
|
||||
EXPECT_TRUE(manager.TryGetAssetRef("Assets/cloud.nvdb", ResourceType::VolumeField, volumeRef));
|
||||
EXPECT_TRUE(volumeRef.IsValid());
|
||||
|
||||
const AssetImportService::ImportStatusSnapshot status = manager.GetProjectAssetImportStatus();
|
||||
EXPECT_TRUE(status.HasValue());
|
||||
EXPECT_FALSE(status.inProgress);
|
||||
EXPECT_TRUE(status.success);
|
||||
EXPECT_EQ(std::string(status.operation.CStr()), "Bootstrap Project");
|
||||
|
||||
const fs::path assetsDbPath = projectRoot / "Library" / "assets.db";
|
||||
ASSERT_TRUE(fs::exists(assetsDbPath));
|
||||
EXPECT_TRUE(ReadSourceHashFromAssetsDb(assetsDbPath, "Assets/cloud.nvdb").empty());
|
||||
|
||||
manager.SetResourceRoot("");
|
||||
}
|
||||
|
||||
TEST(AssetImportService_Test, ClearLibraryAndReimportAllAssetsManageArtifactsExplicitly) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user