diff --git a/editor/AGENTS.md b/editor/AGENTS.md index 1bbdc0af..5bccad38 100644 --- a/editor/AGENTS.md +++ b/editor/AGENTS.md @@ -78,9 +78,10 @@ Rules: utility panels now receive explicit bindings or panel-local contexts; do not recreate a catch-all mutable panel service bundle under a new name - `EditorFrameServices` remains a window/content orchestration boundary. It must - not be passed through the workspace-panel seam as a generic dependency source; - workspace panels should receive explicit panel-local bindings or typed - callbacks instead + stay on the window/content and shell-orchestration seam only. It must not be + passed through the workspace-panel seam or the utility-window panel seam as a + generic dependency source; workspace panels and utility panels should receive + explicit panel-local bindings or typed callbacks instead ## Working Rules @@ -89,6 +90,10 @@ Rules: - keep panel dependencies explicit. If a panel needs more data or actions, add a narrow panel-local context or binding instead of routing everything through a generic shared services struct +- keep utility-window dependencies explicit. Color picker, add-component, and + future utility panels must be constructed with the exact runtime/tool state + they use; do not make utility panel update paths depend on + `EditorFrameServices` - keep viewport-local state local. Camera/tool mode/pivot/space state for Scene belongs in `SceneViewportSession` on the feature/controller side; do not push it back into shared runtime/context/frame-service layers for convenience @@ -112,6 +117,7 @@ Rules: - no new shared mutable panel-services bag or service-locator style panel dependency bundle - no `EditorFrameServices` tunneling into workspace-panel update/prepare paths +- no `EditorFrameServices` tunneling into utility-window panel update paths - no new path where Scene viewport render requests or camera/tool state are recomputed from `EditorContext` instead of the owning `SceneViewportSession` - no scene-open side channel in `EditorProjectRuntime`; project UI must call the diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index ab4cf973..eb263d24 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -238,7 +238,6 @@ if(XCENGINE_BUILD_XCUI_EDITOR_CORE) app/Composition/EditorShellInteractionEngine.cpp app/Composition/EditorShellRuntime.cpp app/Composition/EditorShellSessionCoordinator.cpp - app/Composition/WorkspaceEventSync.cpp ) set(XCUI_EDITOR_APP_FEATURE_SOURCES diff --git a/editor/app/Bootstrap/Application.cpp b/editor/app/Bootstrap/Application.cpp index 1e27af2f..a82612cb 100644 --- a/editor/app/Bootstrap/Application.cpp +++ b/editor/app/Bootstrap/Application.cpp @@ -247,7 +247,12 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) { *m_resourceService, *m_windowHostRuntime, std::move(workspaceShellRuntimeFactory), - App::CreateEditorUtilityWindowPanel); + [this](App::EditorUtilityWindowKind kind) { + return App::CreateEditorUtilityWindowPanel( + kind, + m_editorContext->GetColorPickerToolState(), + m_editorContext->GetSceneRuntime()); + }); m_editorContext->SetExitRequestHandler([this]() { if (m_windowManager == nullptr) { diff --git a/editor/app/Composition/EditorContext.cpp b/editor/app/Composition/EditorContext.cpp index 196db030..399edf4e 100644 --- a/editor/app/Composition/EditorContext.cpp +++ b/editor/app/Composition/EditorContext.cpp @@ -4,7 +4,6 @@ #include "Scene/EditorSceneRuntime.h" #include "Panels/EditorPanelIds.h" #include "Viewport/EditorViewportRuntimeServices.h" -#include "WorkspaceEventSync.h" #include #include #include @@ -226,14 +225,6 @@ void EditorContext::SyncSessionFromCommandFocusService() { ResolveEditorActionRoute(m_session.activePanelId)); } -::XCEngine::UI::Editor::System::SystemInteractionService* EditorContext::GetSystemInteractionHost() { - return m_systemInteractionHost; -} - -const ::XCEngine::UI::Editor::System::SystemInteractionService* EditorContext::GetSystemInteractionHost() const { - return m_systemInteractionHost; -} - UIEditorWorkspaceController EditorContext::BuildWorkspaceController() const { return UIEditorWorkspaceController( m_shellAsset.panelRegistry, @@ -321,7 +312,7 @@ std::string EditorContext::DescribeWorkspaceState( std::vector EditorContext::SyncWorkspacePanelFrameEvents( const std::vector& panelEvents) { - return SyncWorkspaceEvents(*this, panelEvents); + return SyncWorkspacePanelEvents(panelEvents); } void EditorContext::SyncSceneViewportRenderRequest( @@ -440,5 +431,21 @@ void EditorContext::AppendConsoleEntry( } } +std::vector EditorContext::SyncWorkspacePanelEvents( + const std::vector& panelEvents) { + std::vector entries = {}; + SyncSessionFromSelectionService(); + + for (const EditorWorkspacePanelFrameEvent& event : panelEvents) { + SetStatus(event.status, event.message); + entries.push_back(WorkspaceTraceEntry{ + .channel = event.traceChannel, + .message = event.message, + }); + } + + return entries; +} + } // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Composition/EditorContext.h b/editor/app/Composition/EditorContext.h index ddd8a40c..add8fc5c 100644 --- a/editor/app/Composition/EditorContext.h +++ b/editor/app/Composition/EditorContext.h @@ -47,20 +47,18 @@ public: EditorEditCommandRoute* sceneRoute, EditorEditCommandRoute* inspectorRoute = nullptr) override; void SetExitRequestHandler(std::function handler); - const EditorSession& GetSession() const override; - EditorCommandFocusService& GetCommandFocusService() override; - const EditorCommandFocusService& GetCommandFocusService() const override; - EditorProjectRuntime& GetProjectRuntime() override; - const EditorProjectRuntime& GetProjectRuntime() const override; - EditorSceneRuntime& GetSceneRuntime() override; - const EditorSceneRuntime& GetSceneRuntime() const override; - EditorColorPickerToolState& GetColorPickerToolState() override; - const EditorColorPickerToolState& GetColorPickerToolState() const override; - void RequestOpenUtilityWindow(EditorUtilityWindowKind kind) override; - ::XCEngine::UI::Editor::System::SystemInteractionService* GetSystemInteractionHost() override; - const ::XCEngine::UI::Editor::System::SystemInteractionService* GetSystemInteractionHost() const override; + const EditorSession& GetSession() const; + EditorCommandFocusService& GetCommandFocusService(); + const EditorCommandFocusService& GetCommandFocusService() const; + EditorProjectRuntime& GetProjectRuntime(); + const EditorProjectRuntime& GetProjectRuntime() const; + EditorSceneRuntime& GetSceneRuntime(); + const EditorSceneRuntime& GetSceneRuntime() const; + EditorColorPickerToolState& GetColorPickerToolState(); + const EditorColorPickerToolState& GetColorPickerToolState() const; + void RequestOpenUtilityWindow(EditorUtilityWindowKind kind); const UIEditorTextMeasurer* GetTextMeasurer() const override; - bool RequestOpenSceneAsset(const std::filesystem::path& scenePath) override; + bool RequestOpenSceneAsset(const std::filesystem::path& scenePath); void SyncSessionFromWorkspace( const UIEditorWorkspaceController& workspaceController) override; void TickEditorRuntime() override; @@ -99,6 +97,8 @@ public: private: void AppendConsoleEntry(std::string channel, std::string message); + std::vector SyncWorkspacePanelEvents( + const std::vector& panelEvents); EditorShellAsset m_shellAsset = {}; EditorShellAssetValidationResult m_shellValidation = {}; diff --git a/editor/app/Composition/WorkspaceEventSync.cpp b/editor/app/Composition/WorkspaceEventSync.cpp deleted file mode 100644 index 72e19852..00000000 --- a/editor/app/Composition/WorkspaceEventSync.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "WorkspaceEventSync.h" - -#include "EditorContext.h" - -namespace XCEngine::UI::Editor::App { - -std::vector SyncWorkspaceEvents( - EditorContext& context, - const std::vector& panelEvents) { - std::vector entries = {}; - context.SyncSessionFromSelectionService(); - - for (const EditorWorkspacePanelFrameEvent& event : panelEvents) { - context.SetStatus(event.status, event.message); - entries.push_back(WorkspaceTraceEntry{ event.traceChannel, event.message }); - } - - return entries; -} - -} // namespace XCEngine::UI::Editor::App - - diff --git a/editor/app/Composition/WorkspaceEventSync.h b/editor/app/Composition/WorkspaceEventSync.h deleted file mode 100644 index 15fe5ef3..00000000 --- a/editor/app/Composition/WorkspaceEventSync.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "Windowing/EditorFrameServices.h" -#include "WorkspacePanels/EditorWorkspacePanelRuntime.h" - -#include - -namespace XCEngine::UI::Editor::App { - -class EditorContext; - -std::vector SyncWorkspaceEvents( - EditorContext& context, - const std::vector& panelEvents); - -} // namespace XCEngine::UI::Editor::App - diff --git a/editor/app/Core/UtilityWindows/EditorUtilityWindowRuntime.h b/editor/app/Core/UtilityWindows/EditorUtilityWindowRuntime.h index c8c3cb2c..a4fa75b2 100644 --- a/editor/app/Core/UtilityWindows/EditorUtilityWindowRuntime.h +++ b/editor/app/Core/UtilityWindows/EditorUtilityWindowRuntime.h @@ -13,8 +13,6 @@ namespace XCEngine::UI::Editor::App { -class EditorFrameServices; - enum class EditorUtilityWindowKind : std::uint8_t { None = 0, ColorPicker, @@ -53,7 +51,6 @@ public: virtual std::string_view GetDrawListId() const = 0; virtual void ResetInteractionState() = 0; virtual void Update( - EditorFrameServices& frameServices, const EditorUtilityWindowHostContext& hostContext, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents) = 0; virtual void Append(::XCEngine::UI::UIDrawList& drawList) const = 0; diff --git a/editor/app/Core/Windowing/EditorFrameServices.h b/editor/app/Core/Windowing/EditorFrameServices.h index c7c742d8..d540d02f 100644 --- a/editor/app/Core/Windowing/EditorFrameServices.h +++ b/editor/app/Core/Windowing/EditorFrameServices.h @@ -23,12 +23,7 @@ class SystemInteractionService; namespace XCEngine::UI::Editor::App { class EditorEditCommandRoute; -class EditorCommandFocusService; -class EditorProjectRuntime; -class EditorSceneRuntime; class EditorSceneViewportRuntime; -struct EditorColorPickerToolState; -struct EditorSession; struct WorkspaceTraceEntry { std::string channel = {}; @@ -48,20 +43,7 @@ public: EditorEditCommandRoute* projectRoute, EditorEditCommandRoute* sceneRoute, EditorEditCommandRoute* inspectorRoute) = 0; - virtual const EditorSession& GetSession() const = 0; - virtual EditorCommandFocusService& GetCommandFocusService() = 0; - virtual const EditorCommandFocusService& GetCommandFocusService() const = 0; - virtual EditorProjectRuntime& GetProjectRuntime() = 0; - virtual const EditorProjectRuntime& GetProjectRuntime() const = 0; - virtual EditorSceneRuntime& GetSceneRuntime() = 0; - virtual const EditorSceneRuntime& GetSceneRuntime() const = 0; - virtual EditorColorPickerToolState& GetColorPickerToolState() = 0; - virtual const EditorColorPickerToolState& GetColorPickerToolState() const = 0; - virtual ::XCEngine::UI::Editor::System::SystemInteractionService* GetSystemInteractionHost() = 0; - virtual const ::XCEngine::UI::Editor::System::SystemInteractionService* GetSystemInteractionHost() const = 0; virtual const UIEditorTextMeasurer* GetTextMeasurer() const = 0; - virtual void RequestOpenUtilityWindow(EditorUtilityWindowKind kind) = 0; - virtual bool RequestOpenSceneAsset(const std::filesystem::path& scenePath) = 0; virtual void SyncSessionFromWorkspace( const UIEditorWorkspaceController& workspaceController) = 0; virtual void SyncSessionFromCommandFocusService() = 0; diff --git a/editor/app/Features/ColorPicker/ColorPickerPanel.cpp b/editor/app/Features/ColorPicker/ColorPickerPanel.cpp index ff4af24a..fd650126 100644 --- a/editor/app/Features/ColorPicker/ColorPickerPanel.cpp +++ b/editor/app/Features/ColorPicker/ColorPickerPanel.cpp @@ -1,6 +1,5 @@ #include "ColorPickerPanel.h" -#include "Windowing/EditorFrameServices.h" #include "State/EditorColorPickerToolState.h" #include @@ -88,7 +87,6 @@ void ColorPickerPanel::ResetInteractionState() { } void ColorPickerPanel::Update( - EditorFrameServices& frameServices, const EditorUtilityWindowHostContext& hostContext, const std::vector& inputEvents) { if (!hostContext.mounted) { @@ -101,7 +99,7 @@ void ColorPickerPanel::Update( m_metrics = BuildColorPickerPanelMetrics(m_bounds); m_palette = BuildColorPickerPanelPalette(); - EditorColorPickerToolState& toolState = frameServices.GetColorPickerToolState(); + EditorColorPickerToolState& toolState = m_toolState; m_hasActiveTarget = toolState.active && !toolState.inspectorTarget.subjectKey.empty() && diff --git a/editor/app/Features/ColorPicker/ColorPickerPanel.h b/editor/app/Features/ColorPicker/ColorPickerPanel.h index fb0752d0..26502d08 100644 --- a/editor/app/Features/ColorPicker/ColorPickerPanel.h +++ b/editor/app/Features/ColorPicker/ColorPickerPanel.h @@ -8,14 +8,18 @@ namespace XCEngine::UI::Editor::App { +struct EditorColorPickerToolState; + class ColorPickerPanel final : public EditorUtilityWindowPanel { public: + explicit ColorPickerPanel(EditorColorPickerToolState& toolState) + : m_toolState(toolState) {} + std::string_view GetDrawListId() const override { return "XCEditorUtility.ColorPicker"; } void ResetInteractionState() override; void Update( - EditorFrameServices& frameServices, const EditorUtilityWindowHostContext& hostContext, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents) override; void Append(::XCEngine::UI::UIDrawList& drawList) const override; @@ -23,6 +27,7 @@ public: private: void ResetPanelState(); + EditorColorPickerToolState& m_toolState; bool m_visible = false; bool m_hasActiveTarget = false; ::XCEngine::UI::UIRect m_bounds = {}; diff --git a/editor/app/Features/EditorUtilityWindowRegistry.cpp b/editor/app/Features/EditorUtilityWindowRegistry.cpp index 40e4ef22..75558f6f 100644 --- a/editor/app/Features/EditorUtilityWindowRegistry.cpp +++ b/editor/app/Features/EditorUtilityWindowRegistry.cpp @@ -2,16 +2,20 @@ #include "ColorPicker/ColorPickerPanel.h" #include "Inspector/AddComponentPanel.h" +#include "Scene/EditorSceneRuntime.h" +#include "State/EditorColorPickerToolState.h" namespace XCEngine::UI::Editor::App { std::unique_ptr CreateEditorUtilityWindowPanel( - EditorUtilityWindowKind kind) { + EditorUtilityWindowKind kind, + EditorColorPickerToolState& colorPickerToolState, + EditorSceneRuntime& sceneRuntime) { switch (kind) { case EditorUtilityWindowKind::ColorPicker: - return std::make_unique(); + return std::make_unique(colorPickerToolState); case EditorUtilityWindowKind::AddComponent: - return std::make_unique(); + return std::make_unique(sceneRuntime); case EditorUtilityWindowKind::None: default: return nullptr; diff --git a/editor/app/Features/EditorUtilityWindowRegistry.h b/editor/app/Features/EditorUtilityWindowRegistry.h index f2719bb9..4e87de01 100644 --- a/editor/app/Features/EditorUtilityWindowRegistry.h +++ b/editor/app/Features/EditorUtilityWindowRegistry.h @@ -4,8 +4,13 @@ namespace XCEngine::UI::Editor::App { +struct EditorColorPickerToolState; +class EditorSceneRuntime; + std::unique_ptr CreateEditorUtilityWindowPanel( - EditorUtilityWindowKind kind); + EditorUtilityWindowKind kind, + EditorColorPickerToolState& colorPickerToolState, + EditorSceneRuntime& sceneRuntime); } // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Features/Inspector/AddComponentPanel.cpp b/editor/app/Features/Inspector/AddComponentPanel.cpp index 0fd3284a..8d0df899 100644 --- a/editor/app/Features/Inspector/AddComponentPanel.cpp +++ b/editor/app/Features/Inspector/AddComponentPanel.cpp @@ -3,7 +3,6 @@ #include "Inspector/Components/IInspectorComponentEditor.h" #include "Inspector/Components/InspectorComponentEditorRegistry.h" #include "Scene/EditorSceneRuntime.h" -#include "Windowing/EditorFrameServices.h" #include @@ -123,9 +122,7 @@ void AddComponentPanel::RebuildEntries( } } -bool AddComponentPanel::TryActivateEntry( - EditorSceneRuntime& sceneRuntime, - std::size_t entryIndex) { +bool AddComponentPanel::TryActivateEntry(std::size_t entryIndex) { if (entryIndex >= m_entries.size()) { return false; } @@ -135,14 +132,14 @@ bool AddComponentPanel::TryActivateEntry( return false; } - if (!sceneRuntime.AddComponentToSelectedGameObject(entry.componentTypeName)) { + if (!m_sceneRuntime.AddComponentToSelectedGameObject(entry.componentTypeName)) { return false; } const std::optional selectedObject = - sceneRuntime.GetSelectedObjectSnapshot(); + m_sceneRuntime.GetSelectedObjectSnapshot(); m_hasTarget = selectedObject.has_value(); - m_targetDisplayName = sceneRuntime.GetSelectedDisplayName(); + m_targetDisplayName = m_sceneRuntime.GetSelectedDisplayName(); RebuildEntries(selectedObject.has_value() ? &selectedObject.value() : nullptr); return true; } @@ -158,7 +155,6 @@ std::size_t AddComponentPanel::HitTestEntry(const UIPoint& point) const { } void AddComponentPanel::Update( - EditorFrameServices& frameServices, const EditorUtilityWindowHostContext& hostContext, const std::vector& inputEvents) { if (!hostContext.mounted) { @@ -166,13 +162,12 @@ void AddComponentPanel::Update( return; } - EditorSceneRuntime& sceneRuntime = frameServices.GetSceneRuntime(); m_visible = true; m_bounds = hostContext.bounds; const std::optional selectedObject = - sceneRuntime.GetSelectedObjectSnapshot(); + m_sceneRuntime.GetSelectedObjectSnapshot(); m_hasTarget = selectedObject.has_value(); - m_targetDisplayName = sceneRuntime.GetSelectedDisplayName(); + m_targetDisplayName = m_sceneRuntime.GetSelectedDisplayName(); RebuildEntries(selectedObject.has_value() ? &selectedObject.value() : nullptr); if (hostContext.focusLost) { @@ -211,7 +206,7 @@ void AddComponentPanel::Update( m_hoveredEntryIndex = HitTestEntry(event.position); if (m_pressedEntryIndex != kInvalidEntryIndex && m_pressedEntryIndex == m_hoveredEntryIndex) { - TryActivateEntry(sceneRuntime, m_pressedEntryIndex); + TryActivateEntry(m_pressedEntryIndex); } m_pressedEntryIndex = kInvalidEntryIndex; break; diff --git a/editor/app/Features/Inspector/AddComponentPanel.h b/editor/app/Features/Inspector/AddComponentPanel.h index 2838e2dc..2816faae 100644 --- a/editor/app/Features/Inspector/AddComponentPanel.h +++ b/editor/app/Features/Inspector/AddComponentPanel.h @@ -13,12 +13,14 @@ class EditorSceneRuntime; class AddComponentPanel final : public EditorUtilityWindowPanel { public: + explicit AddComponentPanel(EditorSceneRuntime& sceneRuntime) + : m_sceneRuntime(sceneRuntime) {} + std::string_view GetDrawListId() const override { return "XCEditorUtility.AddComponent"; } void ResetInteractionState() override; void Update( - EditorFrameServices& frameServices, const EditorUtilityWindowHostContext& hostContext, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents) override; void Append(::XCEngine::UI::UIDrawList& drawList) const override; @@ -34,9 +36,10 @@ private: void ResetPanelState(); void RebuildEntries(const EditorSceneObjectSnapshot* gameObject); - bool TryActivateEntry(EditorSceneRuntime& sceneRuntime, std::size_t entryIndex); + bool TryActivateEntry(std::size_t entryIndex); std::size_t HitTestEntry(const ::XCEngine::UI::UIPoint& point) const; + EditorSceneRuntime& m_sceneRuntime; bool m_visible = false; bool m_hasTarget = false; ::XCEngine::UI::UIRect m_bounds = {}; diff --git a/editor/app/Windowing/Content/EditorUtilityWindowContentController.cpp b/editor/app/Windowing/Content/EditorUtilityWindowContentController.cpp index d799aa52..7bc39e19 100644 --- a/editor/app/Windowing/Content/EditorUtilityWindowContentController.cpp +++ b/editor/app/Windowing/Content/EditorUtilityWindowContentController.cpp @@ -68,7 +68,6 @@ EditorUtilityWindowContentController::UpdateAndAppend( } m_panel->Update( - context.frameServices, EditorUtilityWindowHostContext{ .mounted = true, .bounds = context.bounds,