Tighten editor scene mutation boundary

This commit is contained in:
2026-04-28 17:53:36 +08:00
parent 357dc136fe
commit b67af931de
12 changed files with 290 additions and 62 deletions

View File

@@ -1,6 +1,5 @@
#include "Scene/EditorSceneRuntime.h"
#include <XCEngine/Components/ComponentFactoryRegistry.h>
#include <XCEngine/Components/CameraComponent.h>
#include <XCEngine/Components/Component.h>
#include <XCEngine/Components/GameObject.h>
@@ -236,6 +235,12 @@ Scene* EditorSceneRuntime::GetActiveScene() const {
return m_backend != nullptr ? m_backend->GetActiveScene() : nullptr;
}
EditorSceneHierarchySnapshot EditorSceneRuntime::BuildHierarchySnapshot() const {
return m_backend != nullptr
? m_backend->BuildHierarchySnapshot()
: EditorSceneHierarchySnapshot{};
}
::XCEngine::Components::CameraComponent* EditorSceneRuntime::GetSceneViewCamera() {
return EnsureSceneViewCamera() ? m_sceneViewCamera.camera : nullptr;
}
@@ -525,22 +530,10 @@ bool EditorSceneRuntime::AddComponentToSelectedGameObject(
return false;
}
const std::optional<GameObject::ID> selectedId = GetSelectedGameObjectId();
Scene* scene = GetActiveScene();
if (!selectedId.has_value() || scene == nullptr) {
return false;
}
GameObject* gameObject = scene->FindByID(selectedId.value());
if (gameObject == nullptr) {
return false;
}
Component* addedComponent =
::XCEngine::Components::ComponentFactoryRegistry::Get().CreateComponent(
gameObject,
std::string(componentTypeName));
if (addedComponent == nullptr) {
const std::string selectedItemId = GetSelectedItemId();
if (selectedItemId.empty() ||
m_backend == nullptr ||
!m_backend->AddComponent(selectedItemId, componentTypeName)) {
return false;
}
@@ -866,6 +859,48 @@ bool EditorSceneRuntime::ApplyTransformToolPreview(
return ApplyTransformSnapshot(snapshot);
}
bool EditorSceneRuntime::ApplyTransformToolWorldPreview(
EditorSceneObjectId targetId,
const Vector3& position,
const Quaternion& rotation) {
if (!m_toolState.dragState.active ||
targetId == kInvalidEditorSceneObjectId ||
targetId != m_toolState.dragState.initialTransform.targetId) {
return false;
}
SceneTransformSnapshot snapshot = m_toolState.dragState.initialTransform;
snapshot.targetId = targetId;
snapshot.position = position;
snapshot.rotation = rotation;
snapshot.valid = true;
return ApplyTransformSnapshot(snapshot);
}
bool EditorSceneRuntime::ApplyTransformToolLocalScalePreview(
EditorSceneObjectId targetId,
const Vector3& localScale) {
if (!m_toolState.dragState.active ||
targetId == kInvalidEditorSceneObjectId ||
targetId != m_toolState.dragState.initialTransform.targetId) {
return false;
}
Scene* scene = GetActiveScene();
if (scene == nullptr) {
return false;
}
GameObject* gameObject = scene->FindByID(targetId);
if (gameObject == nullptr || gameObject->GetTransform() == nullptr) {
return false;
}
gameObject->GetTransform()->SetLocalScale(localScale);
IncrementInspectorRevision();
return true;
}
bool EditorSceneRuntime::CommitTransformToolDrag() {
if (!m_toolState.dragState.active) {
return false;