feat: expand editor scripting asset and viewport flow

This commit is contained in:
2026-04-03 13:22:30 +08:00
parent ed8c27fde2
commit a05d0b80a2
124 changed files with 10397 additions and 1737 deletions

View File

@@ -9,12 +9,14 @@
#include "Core/EditorContext.h"
#include "Core/PlaySessionController.h"
#include <XCEngine/Core/Asset/ResourceManager.h>
#include <XCEngine/Core/Math/Quaternion.h>
#include <XCEngine/Core/Math/Vector3.h>
#include <chrono>
#include <filesystem>
#include <fstream>
#include <iterator>
#include <string>
namespace fs = std::filesystem;
@@ -343,6 +345,17 @@ TEST_F(EditorActionRoutingTest, MainMenuRouterRequestsPlayPauseResumeAndStepEven
m_context.GetEventBus().Unsubscribe<PlayModeStepRequestedEvent>(playStepSubscription);
}
TEST_F(EditorActionRoutingTest, ProjectCommandsReportWhenScriptAssembliesCanBeRebuilt) {
EXPECT_TRUE(Commands::CanRebuildScriptAssemblies(m_context));
m_context.SetRuntimeMode(EditorRuntimeMode::Play);
EXPECT_FALSE(Commands::CanRebuildScriptAssemblies(m_context));
m_context.SetRuntimeMode(EditorRuntimeMode::Edit);
m_context.SetProjectPath(std::string());
EXPECT_FALSE(Commands::CanRebuildScriptAssemblies(m_context));
}
TEST_F(EditorActionRoutingTest, PlayModeAllowsRuntimeSceneUndoRedoButKeepsSceneDocumentCommandsBlocked) {
const fs::path savedScenePath = m_projectRoot / "Assets" / "Scenes" / "PlayModeRuntimeEditing.xc";
ASSERT_TRUE(m_context.GetSceneManager().SaveSceneAs(savedScenePath.string()));
@@ -470,6 +483,68 @@ TEST_F(EditorActionRoutingTest, ProjectCommandsRenameAssetUpdatesSelectionAndPre
EXPECT_EQ(m_context.GetProjectManager().GetSelectedItemPath(), renamedItem->fullPath);
}
TEST_F(EditorActionRoutingTest, ProjectCommandsMigrateSceneAssetReferencesRewritesLegacyScenePayloads) {
using ::XCEngine::Resources::ResourceManager;
const fs::path assetsDir = m_projectRoot / "Assets";
const fs::path scenesDir = assetsDir / "Scenes";
const fs::path materialPath = assetsDir / "runtime.material";
const fs::path scenePath = scenesDir / "LegacyScene.xc";
{
std::ofstream materialFile(materialPath.string(), std::ios::out | std::ios::trunc);
ASSERT_TRUE(materialFile.is_open());
materialFile << "{\n";
materialFile << " \"renderQueue\": \"geometry\",\n";
materialFile << " \"renderState\": {\n";
materialFile << " \"cull\": \"back\"\n";
materialFile << " }\n";
materialFile << "}\n";
}
{
std::ofstream sceneFile(scenePath.string(), std::ios::out | std::ios::trunc);
ASSERT_TRUE(sceneFile.is_open());
sceneFile << "# XCEngine Scene File\n";
sceneFile << "scene=Legacy Scene\n";
sceneFile << "active=1\n\n";
sceneFile << "gameobject_begin\n";
sceneFile << "id=1\n";
sceneFile << "uuid=1\n";
sceneFile << "name=Legacy Object\n";
sceneFile << "active=1\n";
sceneFile << "parent=0\n";
sceneFile << "transform=position=0,0,0;rotation=0,0,0,1;scale=1,1,1;\n";
sceneFile << "component=MeshFilter;mesh=builtin://meshes/cube;meshRef=;\n";
sceneFile << "component=MeshRenderer;materials=Assets/runtime.material;materialRefs=;castShadows=1;receiveShadows=1;renderLayer=0;\n";
sceneFile << "gameobject_end\n";
}
ASSERT_TRUE(Commands::CanMigrateSceneAssetReferences(m_context));
const IProjectManager::SceneAssetReferenceMigrationReport report =
Commands::MigrateSceneAssetReferences(m_context);
EXPECT_EQ(report.scannedSceneCount, 1u);
EXPECT_EQ(report.migratedSceneCount, 1u);
EXPECT_EQ(report.unchangedSceneCount, 0u);
EXPECT_EQ(report.failedSceneCount, 0u);
std::ifstream migratedScene(scenePath.string(), std::ios::in | std::ios::binary);
ASSERT_TRUE(migratedScene.is_open());
std::string migratedText((std::istreambuf_iterator<char>(migratedScene)),
std::istreambuf_iterator<char>());
EXPECT_NE(migratedText.find("meshPath=builtin://meshes/cube;"), std::string::npos);
EXPECT_EQ(migratedText.find("component=MeshFilter;mesh=builtin://meshes/cube;"), std::string::npos);
EXPECT_NE(migratedText.find("materialPaths=;"), std::string::npos);
EXPECT_NE(migratedText.find("materialRefs="), std::string::npos);
EXPECT_EQ(migratedText.find("materialRefs=;"), std::string::npos);
EXPECT_EQ(migratedText.find("component=MeshRenderer;materials="), std::string::npos);
ResourceManager::Get().SetResourceRoot("");
ResourceManager::Get().Shutdown();
}
TEST_F(EditorActionRoutingTest, ProjectItemContextRequestSelectsAssetAndStoresPopupTarget) {
const fs::path assetsDir = m_projectRoot / "Assets";
const fs::path filePath = assetsDir / "ContextAsset.txt";