feat(new_editor): wire project, inspector, and viewport runtime
This commit is contained in:
204
tests/UI/Editor/unit/test_hierarchy_scene_binding.cpp
Normal file
204
tests/UI/Editor/unit/test_hierarchy_scene_binding.cpp
Normal file
@@ -0,0 +1,204 @@
|
||||
#include "Features/Hierarchy/HierarchyModel.h"
|
||||
#include "Scene/EditorSceneBridge.h"
|
||||
|
||||
#include <XCEngine/Components/GameObject.h>
|
||||
#include <XCEngine/Core/Asset/ResourceManager.h>
|
||||
#include <XCEngine/Scene/Scene.h>
|
||||
#include <XCEngine/Scene/SceneManager.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
namespace {
|
||||
|
||||
using ::XCEngine::Components::GameObject;
|
||||
using ::XCEngine::Components::Scene;
|
||||
using ::XCEngine::Components::SceneManager;
|
||||
|
||||
class ScopedSceneManagerReset final {
|
||||
public:
|
||||
ScopedSceneManagerReset() {
|
||||
Reset();
|
||||
}
|
||||
|
||||
~ScopedSceneManagerReset() {
|
||||
Reset();
|
||||
}
|
||||
|
||||
private:
|
||||
static void Reset() {
|
||||
SceneManager& manager = SceneManager::Get();
|
||||
const auto scenes = manager.GetAllScenes();
|
||||
for (Scene* scene : scenes) {
|
||||
manager.UnloadScene(scene);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class TemporaryProjectRoot final {
|
||||
public:
|
||||
TemporaryProjectRoot() {
|
||||
const auto uniqueSuffix =
|
||||
std::chrono::steady_clock::now().time_since_epoch().count();
|
||||
m_root =
|
||||
std::filesystem::temp_directory_path() /
|
||||
("xcui_hierarchy_scene_bridge_" + std::to_string(uniqueSuffix));
|
||||
}
|
||||
|
||||
~TemporaryProjectRoot() {
|
||||
std::error_code errorCode = {};
|
||||
std::filesystem::remove_all(m_root, errorCode);
|
||||
}
|
||||
|
||||
const std::filesystem::path& Root() const {
|
||||
return m_root;
|
||||
}
|
||||
|
||||
private:
|
||||
std::filesystem::path m_root = {};
|
||||
};
|
||||
|
||||
TEST(HierarchySceneBindingTests, BuildFromSceneUsesRealGameObjectIds) {
|
||||
ScopedSceneManagerReset reset = {};
|
||||
|
||||
Scene* scene = SceneManager::Get().CreateScene("Main");
|
||||
ASSERT_NE(scene, nullptr);
|
||||
SceneManager::Get().SetActiveScene(scene);
|
||||
|
||||
GameObject* root = scene->CreateGameObject("Root");
|
||||
ASSERT_NE(root, nullptr);
|
||||
GameObject* child = scene->CreateGameObject("Child", root);
|
||||
ASSERT_NE(child, nullptr);
|
||||
|
||||
const HierarchyModel model = HierarchyModel::BuildFromScene(scene);
|
||||
const HierarchyNode* rootNode =
|
||||
model.FindNode(MakeEditorGameObjectItemId(root->GetID()));
|
||||
ASSERT_NE(rootNode, nullptr);
|
||||
EXPECT_EQ(rootNode->label, "Root");
|
||||
ASSERT_EQ(rootNode->children.size(), 1u);
|
||||
EXPECT_EQ(
|
||||
rootNode->children.front().nodeId,
|
||||
MakeEditorGameObjectItemId(child->GetID()));
|
||||
EXPECT_EQ(rootNode->children.front().label, "Child");
|
||||
}
|
||||
|
||||
TEST(HierarchySceneBindingTests, DuplicateGameObjectClonesHierarchyIntoScene) {
|
||||
ScopedSceneManagerReset reset = {};
|
||||
|
||||
Scene* scene = SceneManager::Get().CreateScene("Main");
|
||||
ASSERT_NE(scene, nullptr);
|
||||
SceneManager::Get().SetActiveScene(scene);
|
||||
|
||||
GameObject* root = scene->CreateGameObject("Root");
|
||||
ASSERT_NE(root, nullptr);
|
||||
GameObject* child = scene->CreateGameObject("Child", root);
|
||||
ASSERT_NE(child, nullptr);
|
||||
|
||||
const std::string duplicateId =
|
||||
DuplicateEditorGameObject(MakeEditorGameObjectItemId(root->GetID()));
|
||||
ASSERT_FALSE(duplicateId.empty());
|
||||
|
||||
const HierarchyModel model = HierarchyModel::BuildFromScene(scene);
|
||||
const HierarchyNode* duplicateNode = model.FindNode(duplicateId);
|
||||
ASSERT_NE(duplicateNode, nullptr);
|
||||
EXPECT_EQ(duplicateNode->label, "Root");
|
||||
ASSERT_EQ(duplicateNode->children.size(), 1u);
|
||||
EXPECT_EQ(duplicateNode->children.front().label, "Child");
|
||||
|
||||
const auto roots = scene->GetRootGameObjects();
|
||||
EXPECT_EQ(roots.size(), 2u);
|
||||
}
|
||||
|
||||
TEST(HierarchySceneBindingTests, RenameGameObjectUpdatesRealSceneAndProjection) {
|
||||
ScopedSceneManagerReset reset = {};
|
||||
|
||||
Scene* scene = SceneManager::Get().CreateScene("Main");
|
||||
ASSERT_NE(scene, nullptr);
|
||||
SceneManager::Get().SetActiveScene(scene);
|
||||
|
||||
GameObject* gameObject = scene->CreateGameObject("Camera");
|
||||
ASSERT_NE(gameObject, nullptr);
|
||||
|
||||
const std::string itemId =
|
||||
MakeEditorGameObjectItemId(gameObject->GetID());
|
||||
ASSERT_TRUE(RenameEditorGameObject(itemId, "PlayerCamera"));
|
||||
EXPECT_EQ(gameObject->GetName(), "PlayerCamera");
|
||||
|
||||
const HierarchyModel model = HierarchyModel::BuildFromScene(scene);
|
||||
const HierarchyNode* node = model.FindNode(itemId);
|
||||
ASSERT_NE(node, nullptr);
|
||||
EXPECT_EQ(node->label, "PlayerCamera");
|
||||
}
|
||||
|
||||
TEST(HierarchySceneBindingTests, ReparentAndMoveToRootOperateOnRealScene) {
|
||||
ScopedSceneManagerReset reset = {};
|
||||
|
||||
Scene* scene = SceneManager::Get().CreateScene("Main");
|
||||
ASSERT_NE(scene, nullptr);
|
||||
SceneManager::Get().SetActiveScene(scene);
|
||||
|
||||
GameObject* parentA = scene->CreateGameObject("ParentA");
|
||||
ASSERT_NE(parentA, nullptr);
|
||||
GameObject* parentB = scene->CreateGameObject("ParentB");
|
||||
ASSERT_NE(parentB, nullptr);
|
||||
GameObject* child = scene->CreateGameObject("Child", parentA);
|
||||
ASSERT_NE(child, nullptr);
|
||||
|
||||
ASSERT_TRUE(ReparentEditorGameObject(
|
||||
MakeEditorGameObjectItemId(child->GetID()),
|
||||
MakeEditorGameObjectItemId(parentB->GetID())));
|
||||
EXPECT_EQ(child->GetParent(), parentB);
|
||||
|
||||
HierarchyModel model = HierarchyModel::BuildFromScene(scene);
|
||||
const HierarchyNode* parentBNode =
|
||||
model.FindNode(MakeEditorGameObjectItemId(parentB->GetID()));
|
||||
ASSERT_NE(parentBNode, nullptr);
|
||||
ASSERT_EQ(parentBNode->children.size(), 1u);
|
||||
EXPECT_EQ(parentBNode->children.front().label, "Child");
|
||||
|
||||
ASSERT_TRUE(MoveEditorGameObjectToRoot(
|
||||
MakeEditorGameObjectItemId(child->GetID())));
|
||||
EXPECT_EQ(child->GetParent(), nullptr);
|
||||
|
||||
model = HierarchyModel::BuildFromScene(scene);
|
||||
const auto roots = scene->GetRootGameObjects();
|
||||
EXPECT_EQ(roots.size(), 3u);
|
||||
}
|
||||
|
||||
TEST(HierarchySceneBindingTests, EnsureStartupSceneLoadsMainSceneAndSetsActive) {
|
||||
ScopedSceneManagerReset reset = {};
|
||||
TemporaryProjectRoot projectRoot = {};
|
||||
|
||||
const std::filesystem::path scenePath =
|
||||
projectRoot.Root() / "Assets" / "Scenes" / "Main.xc";
|
||||
std::filesystem::create_directories(scenePath.parent_path());
|
||||
{
|
||||
Scene scene("Main");
|
||||
scene.CreateGameObject("Camera");
|
||||
scene.Save(scenePath.string());
|
||||
}
|
||||
|
||||
const EditorStartupSceneResult result =
|
||||
EnsureEditorStartupScene(projectRoot.Root());
|
||||
EXPECT_TRUE(result.ready);
|
||||
EXPECT_TRUE(result.loadedFromDisk);
|
||||
ASSERT_NE(GetActiveEditorScene(), nullptr);
|
||||
EXPECT_EQ(GetActiveEditorScene()->GetName(), "Main");
|
||||
|
||||
const HierarchyModel model =
|
||||
HierarchyModel::BuildFromScene(GetActiveEditorScene());
|
||||
EXPECT_FALSE(model.Empty());
|
||||
|
||||
SceneManager& sceneManager = SceneManager::Get();
|
||||
const auto scenes = sceneManager.GetAllScenes();
|
||||
for (Scene* scene : scenes) {
|
||||
sceneManager.UnloadScene(scene);
|
||||
}
|
||||
::XCEngine::Resources::ResourceManager::Get().Shutdown();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
Reference in New Issue
Block a user