diff --git a/editor/AGENTS.md b/editor/AGENTS.md index b6910c77..d29b4212 100644 --- a/editor/AGENTS.md +++ b/editor/AGENTS.md @@ -66,16 +66,22 @@ Rules: owns scene document state: current path/name, dirty flag, new/open/save routing, and runtime-mode transitions. - `ProjectPanel` may identify an openable scene asset, but scene document loading - must go through `EditorPanelServices::RequestOpenSceneAsset` and the + must go through `EditorFrameServices::RequestOpenSceneAsset` and the coordinator. Do not reintroduce `ProjectRuntime` pending-open queues. - `scripts.rebuild` has a bound coordinator owner, but no in-process script assembly builder is currently wired. Keep it disabled and explicit until that builder exists. +- the old shared `EditorPanelServices` dependency bag is gone. Workspace and + utility panels now receive explicit bindings or panel-local contexts; do not + recreate a catch-all mutable panel service bundle under a new name ## Working Rules - prefer explicit owner/coordinator/runtime-service seams over direct panel to engine hookups +- 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 - when changing runtime or document flow, inspect `EditorSession`, `EditorRuntimeCoordinator`, `EditorHostCommandBridge`, the relevant feature, and the matching tests @@ -90,6 +96,8 @@ Rules: - no new low-level render pass dependency on scene backend creation or lifecycle - no silent fallback where a command should fail honestly - no panel-local shortcut that bypasses the intended runtime owner +- no new shared mutable panel-services bag or service-locator style panel + dependency bundle - no scene-open side channel in `EditorProjectRuntime`; project UI must call the panel service request hook - no play-mode path that mutates the editable scene in place or skips diff --git a/editor/app/Composition/EditorContext.cpp b/editor/app/Composition/EditorContext.cpp index cfc64cb5..e2fddc80 100644 --- a/editor/app/Composition/EditorContext.cpp +++ b/editor/app/Composition/EditorContext.cpp @@ -17,22 +17,6 @@ using ::XCEngine::UI::Editor::BuildEditorShellShortcutManager; using ::XCEngine::UI::Editor::UIEditorWorkspacePanelPresentationModel; using ::XCEngine::UI::Editor::AppendUIEditorRuntimeTrace; -void RequestEditorContextUtilityWindow( - void* requester, - EditorUtilityWindowKind kind) { - auto* context = static_cast(requester); - if (context != nullptr) { - context->RequestOpenUtilityWindow(kind); - } -} - -bool RequestEditorContextOpenSceneAsset( - void* requester, - const std::filesystem::path& scenePath) { - auto* context = static_cast(requester); - return context != nullptr && context->RequestOpenSceneAsset(scenePath); -} - std::string ComposeStatusText( std::string_view status, std::string_view message) { @@ -260,20 +244,8 @@ const UIEditorShellInteractionServices& EditorContext::GetShellServices() const return m_shellServices; } -EditorPanelServices EditorContext::BuildPanelServices() { - return EditorPanelServices{ - .session = m_session, - .projectRuntime = m_projectRuntime, - .sceneRuntime = m_sceneRuntime, - .commandFocusService = m_commandFocusService, - .colorPickerToolState = m_colorPickerToolState, - .systemInteractionHost = m_systemInteractionHost, - .textMeasurer = m_shellServices.textMeasurer, - .utilityWindowRequester = this, - .requestUtilityWindow = RequestEditorContextUtilityWindow, - .sceneAssetOpenRequester = this, - .requestOpenSceneAsset = RequestEditorContextOpenSceneAsset, - }; +const UIEditorTextMeasurer* EditorContext::GetTextMeasurer() const { + return m_shellServices.textMeasurer; } bool EditorContext::RequestOpenSceneAsset(const std::filesystem::path& scenePath) { diff --git a/editor/app/Composition/EditorContext.h b/editor/app/Composition/EditorContext.h index 3f793eee..3adcf34b 100644 --- a/editor/app/Composition/EditorContext.h +++ b/editor/app/Composition/EditorContext.h @@ -1,6 +1,5 @@ #pragma once -#include "Panels/EditorPanelServices.h" #include "Environment/EditorRuntimePaths.h" #include "Windowing/EditorFrameServices.h" #include "Scene/EditorSceneRuntime.h" @@ -47,6 +46,20 @@ 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; + System::SystemInteractionService* GetSystemInteractionHost() override; + const System::SystemInteractionService* GetSystemInteractionHost() const override; + const UIEditorTextMeasurer* GetTextMeasurer() const override; + bool RequestOpenSceneAsset(const std::filesystem::path& scenePath) override; void SyncSessionFromWorkspace( const UIEditorWorkspaceController& workspaceController) override; void TickEditorRuntime() override; @@ -54,30 +67,16 @@ public: bool IsValid() const override; const std::string& GetValidationMessage() const override; const EditorShellAsset& GetShellAsset() const; - const EditorSession& GetSession() const; - EditorCommandFocusService& GetCommandFocusService(); - const EditorCommandFocusService& GetCommandFocusService() const; - EditorProjectRuntime& GetProjectRuntime(); - const EditorProjectRuntime& GetProjectRuntime() const; - EditorSceneRuntime& GetSceneRuntime(); - const EditorSceneRuntime& GetSceneRuntime() const; EditorRuntimeCoordinator& GetRuntimeCoordinator(); const EditorRuntimeCoordinator& GetRuntimeCoordinator() const; - EditorColorPickerToolState& GetColorPickerToolState(); - const EditorColorPickerToolState& GetColorPickerToolState() const; - void RequestOpenUtilityWindow(EditorUtilityWindowKind kind); std::optional ConsumeOpenUtilityWindowRequest() override; void SetSelection(EditorSelectionState selection); void ClearSelection(); void SyncSessionFromSelectionService(); void SyncSessionFromCommandFocusService() override; - System::SystemInteractionService* GetSystemInteractionHost(); - const System::SystemInteractionService* GetSystemInteractionHost() const; UIEditorWorkspaceController BuildWorkspaceController() const; const UIEditorShellInteractionServices& GetShellServices() const override; - EditorPanelServices BuildPanelServices() override; - bool RequestOpenSceneAsset(const std::filesystem::path& scenePath); UIEditorShellInteractionDefinition BuildShellDefinition( const UIEditorWorkspaceController& workspaceController, diff --git a/editor/app/Composition/EditorShellHostedPanelCoordinator.cpp b/editor/app/Composition/EditorShellHostedPanelCoordinator.cpp index c52c38da..7bdbaf8e 100644 --- a/editor/app/Composition/EditorShellHostedPanelCoordinator.cpp +++ b/editor/app/Composition/EditorShellHostedPanelCoordinator.cpp @@ -20,9 +20,8 @@ void EditorShellHostedPanelCoordinator::Update( context.inputEvents, shellOwnsHostedContentPointerStream); - EditorPanelServices services = context.frameServices.BuildPanelServices(); const EditorWorkspacePanelUpdateContext updateContext{ - .services = services, + .frameServices = context.frameServices, .shellFrame = context.shellFrame, .shellInteractionState = context.shellInteractionState, .hostedContentEvents = hostedContentEvents, diff --git a/editor/app/Composition/EditorShellSessionCoordinator.cpp b/editor/app/Composition/EditorShellSessionCoordinator.cpp index b61adcb3..a399e13d 100644 --- a/editor/app/Composition/EditorShellSessionCoordinator.cpp +++ b/editor/app/Composition/EditorShellSessionCoordinator.cpp @@ -6,9 +6,8 @@ namespace XCEngine::UI::Editor::App { UIEditorShellInteractionDefinition EditorShellSessionCoordinator::PrepareShellDefinition( const EditorShellSessionCoordinatorContext& context) const { - EditorPanelServices services = context.frameServices.BuildPanelServices(); context.workspacePanels.PrepareForShellDefinition( - services, + context.frameServices, context.workspaceController); context.frameServices.BindEditCommandRoutes( context.workspacePanels.FindCommandRoute(EditorActionRoute::Hierarchy), diff --git a/editor/app/Core/Panels/EditorPanelServices.h b/editor/app/Core/Panels/EditorPanelServices.h deleted file mode 100644 index f3287875..00000000 --- a/editor/app/Core/Panels/EditorPanelServices.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include -#include - -namespace XCEngine::UI::Editor { - -class UIEditorTextMeasurer; - -} // namespace XCEngine::UI::Editor - -namespace XCEngine::UI::Editor::System { - -class SystemInteractionService; - -} // namespace XCEngine::UI::Editor::System - -namespace XCEngine::UI::Editor::App { - -class EditorCommandFocusService; -class EditorProjectRuntime; -class EditorSceneRuntime; -enum class EditorUtilityWindowKind : std::uint8_t; -struct EditorColorPickerToolState; -struct EditorSession; - -struct EditorPanelServices { - using UtilityWindowRequestFn = void (*)(void*, EditorUtilityWindowKind); - using SceneAssetOpenRequestFn = bool (*)( - void*, - const std::filesystem::path&); - - EditorSession& session; - EditorProjectRuntime& projectRuntime; - EditorSceneRuntime& sceneRuntime; - EditorCommandFocusService& commandFocusService; - EditorColorPickerToolState& colorPickerToolState; - System::SystemInteractionService* systemInteractionHost = nullptr; - const UIEditorTextMeasurer* textMeasurer = nullptr; - void* utilityWindowRequester = nullptr; - UtilityWindowRequestFn requestUtilityWindow = nullptr; - void* sceneAssetOpenRequester = nullptr; - SceneAssetOpenRequestFn requestOpenSceneAsset = nullptr; - - void RequestOpenUtilityWindow(EditorUtilityWindowKind kind) const { - if (requestUtilityWindow != nullptr) { - requestUtilityWindow(utilityWindowRequester, kind); - } - } - - bool RequestOpenSceneAsset(const std::filesystem::path& scenePath) const { - return requestOpenSceneAsset != nullptr && - requestOpenSceneAsset(sceneAssetOpenRequester, scenePath); - } -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Core/UtilityWindows/EditorUtilityWindowRuntime.h b/editor/app/Core/UtilityWindows/EditorUtilityWindowRuntime.h index dc39a991..c8c3cb2c 100644 --- a/editor/app/Core/UtilityWindows/EditorUtilityWindowRuntime.h +++ b/editor/app/Core/UtilityWindows/EditorUtilityWindowRuntime.h @@ -1,6 +1,5 @@ #pragma once -#include "Panels/EditorPanelServices.h" #include "Windowing/EditorWindowTypes.h" #include @@ -14,6 +13,8 @@ namespace XCEngine::UI::Editor::App { +class EditorFrameServices; + enum class EditorUtilityWindowKind : std::uint8_t { None = 0, ColorPicker, @@ -52,7 +53,7 @@ public: virtual std::string_view GetDrawListId() const = 0; virtual void ResetInteractionState() = 0; virtual void Update( - EditorPanelServices& services, + 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 1473e325..3e8b5309 100644 --- a/editor/app/Core/Windowing/EditorFrameServices.h +++ b/editor/app/Core/Windowing/EditorFrameServices.h @@ -1,6 +1,5 @@ #pragma once -#include "Panels/EditorPanelServices.h" #include "UtilityWindows/EditorUtilityWindowRuntime.h" #include "Windowing/EditorShellVariant.h" #include "WorkspacePanels/EditorWorkspacePanelRuntime.h" @@ -10,14 +9,26 @@ #include #include +#include #include #include #include +namespace XCEngine::UI::Editor::System { + +class SystemInteractionService; + +} // namespace XCEngine::UI::Editor::System + namespace XCEngine::UI::Editor::App { class EditorEditCommandRoute; +class EditorCommandFocusService; +class EditorProjectRuntime; +class EditorSceneRuntime; class EditorSceneViewportRuntime; +struct EditorColorPickerToolState; +struct EditorSession; struct WorkspaceTraceEntry { std::string channel = {}; @@ -37,13 +48,26 @@ 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 System::SystemInteractionService* GetSystemInteractionHost() = 0; + virtual const 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; virtual void TickEditorRuntime() = 0; virtual const UIEditorShellInteractionServices& GetShellServices() const = 0; - virtual EditorPanelServices BuildPanelServices() = 0; virtual UIEditorShellInteractionDefinition BuildShellDefinition( const UIEditorWorkspaceController& workspaceController, std::string_view captureText, diff --git a/editor/app/Core/WorkspacePanels/EditorWorkspacePanelRuntime.cpp b/editor/app/Core/WorkspacePanels/EditorWorkspacePanelRuntime.cpp index 8b8f9bda..c556a0cb 100644 --- a/editor/app/Core/WorkspacePanels/EditorWorkspacePanelRuntime.cpp +++ b/editor/app/Core/WorkspacePanels/EditorWorkspacePanelRuntime.cpp @@ -51,10 +51,10 @@ void EditorWorkspacePanelRuntimeSet::ResetInteractionState() { } void EditorWorkspacePanelRuntimeSet::PrepareForShellDefinition( - EditorPanelServices& services, + EditorFrameServices& frameServices, UIEditorWorkspaceController& workspaceController) { for (const std::unique_ptr& panel : m_panels) { - panel->PrepareForShellDefinition(services, workspaceController); + panel->PrepareForShellDefinition(frameServices, workspaceController); } } diff --git a/editor/app/Core/WorkspacePanels/EditorWorkspacePanelRuntime.h b/editor/app/Core/WorkspacePanels/EditorWorkspacePanelRuntime.h index e77bdeb6..ee6c04d3 100644 --- a/editor/app/Core/WorkspacePanels/EditorWorkspacePanelRuntime.h +++ b/editor/app/Core/WorkspacePanels/EditorWorkspacePanelRuntime.h @@ -3,9 +3,8 @@ #include "Assets/EditorIconService.h" #include "Commands/EditorEditCommandRoute.h" #include "Environment/EditorRuntimePaths.h" -#include "State/EditorSession.h" -#include "Panels/EditorPanelServices.h" #include "Viewport/EditorViewportRuntimeServices.h" +#include "State/EditorSession.h" #include #include @@ -29,6 +28,8 @@ struct UIInputEvent; namespace XCEngine::UI::Editor::App { +class EditorFrameServices; + enum class EditorWorkspacePanelCursorKind : std::uint8_t { Arrow = 0, ResizeEW @@ -55,7 +56,7 @@ struct EditorWorkspacePanelInitializationContext { struct EditorWorkspacePanelShutdownContext {}; struct EditorWorkspacePanelUpdateContext { - EditorPanelServices& services; + EditorFrameServices& frameServices; UIEditorShellInteractionFrame& shellFrame; UIEditorShellInteractionState& shellInteractionState; const std::vector<::XCEngine::UI::UIInputEvent>& hostedContentEvents; @@ -73,9 +74,9 @@ public: virtual void Shutdown(const EditorWorkspacePanelShutdownContext&) {} virtual void ResetInteractionState() {} virtual void PrepareForShellDefinition( - EditorPanelServices& services, + EditorFrameServices& frameServices, UIEditorWorkspaceController& workspaceController) { - (void)services; + (void)frameServices; (void)workspaceController; } virtual EditorWorkspacePanelUpdatePhase GetUpdatePhase() const { @@ -113,7 +114,7 @@ public: void Shutdown(const EditorWorkspacePanelShutdownContext& context); void ResetInteractionState(); void PrepareForShellDefinition( - EditorPanelServices& services, + EditorFrameServices& frameServices, UIEditorWorkspaceController& workspaceController); void UpdatePhase( const EditorWorkspacePanelUpdateContext& context, diff --git a/editor/app/Features/ColorPicker/ColorPickerPanel.cpp b/editor/app/Features/ColorPicker/ColorPickerPanel.cpp index 1b142f43..ff4af24a 100644 --- a/editor/app/Features/ColorPicker/ColorPickerPanel.cpp +++ b/editor/app/Features/ColorPicker/ColorPickerPanel.cpp @@ -1,6 +1,6 @@ #include "ColorPickerPanel.h" -#include "Panels/EditorPanelServices.h" +#include "Windowing/EditorFrameServices.h" #include "State/EditorColorPickerToolState.h" #include @@ -88,7 +88,7 @@ void ColorPickerPanel::ResetInteractionState() { } void ColorPickerPanel::Update( - EditorPanelServices& services, + EditorFrameServices& frameServices, const EditorUtilityWindowHostContext& hostContext, const std::vector& inputEvents) { if (!hostContext.mounted) { @@ -101,7 +101,7 @@ void ColorPickerPanel::Update( m_metrics = BuildColorPickerPanelMetrics(m_bounds); m_palette = BuildColorPickerPanelPalette(); - EditorColorPickerToolState& toolState = services.colorPickerToolState; + EditorColorPickerToolState& toolState = frameServices.GetColorPickerToolState(); 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 94ca4bca..fb0752d0 100644 --- a/editor/app/Features/ColorPicker/ColorPickerPanel.h +++ b/editor/app/Features/ColorPicker/ColorPickerPanel.h @@ -15,7 +15,7 @@ public: } void ResetInteractionState() override; void Update( - EditorPanelServices& services, + EditorFrameServices& frameServices, const EditorUtilityWindowHostContext& hostContext, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents) override; void Append(::XCEngine::UI::UIDrawList& drawList) const override; diff --git a/editor/app/Features/EditorWorkspacePanelRegistry.cpp b/editor/app/Features/EditorWorkspacePanelRegistry.cpp index 6894a5ad..8b929c2d 100644 --- a/editor/app/Features/EditorWorkspacePanelRegistry.cpp +++ b/editor/app/Features/EditorWorkspacePanelRegistry.cpp @@ -9,9 +9,11 @@ #include "Scene/SceneEditCommandRoute.h" #include "Scene/SceneViewportFeature.h" #include "Product/EditorProductManifest.h" +#include "Windowing/EditorFrameServices.h" #include +#include #include #include @@ -26,6 +28,22 @@ constexpr int kProjectUpdatePriority = 20; constexpr int kInspectorUpdatePriority = 30; constexpr int kConsoleUpdatePriority = 40; +void RequestUtilityWindowFromFrameServices( + void* requester, + EditorUtilityWindowKind kind) { + auto* frameServices = static_cast(requester); + if (frameServices != nullptr) { + frameServices->RequestOpenUtilityWindow(kind); + } +} + +bool RequestSceneAssetFromFrameServices( + void* requester, + const std::filesystem::path& scenePath) { + auto* frameServices = static_cast(requester); + return frameServices != nullptr && frameServices->RequestOpenSceneAsset(scenePath); +} + const UIEditorHostedPanelDispatchEntry& ResolveHostedPanelDispatchEntry( const UIEditorHostedPanelDispatchFrame& dispatchFrame, std::string_view panelId) { @@ -187,7 +205,7 @@ public: void Update(const EditorWorkspacePanelUpdateContext& context) override { m_panel.Update( - context.services.session, + context.frameServices.GetSession(), ResolveHostedPanelDispatchEntry( context.shellFrame.hostedPanelDispatchFrame, GetPanelId())); @@ -230,10 +248,10 @@ public: } void PrepareForShellDefinition( - EditorPanelServices& services, + EditorFrameServices& frameServices, UIEditorWorkspaceController&) override { - m_panel.SetSceneRuntime(&services.sceneRuntime); - m_panel.SetCommandFocusService(&services.commandFocusService); + m_panel.SetSceneRuntime(&frameServices.GetSceneRuntime()); + m_panel.SetCommandFocusService(&frameServices.GetCommandFocusService()); } void Update(const EditorWorkspacePanelUpdateContext& context) override { @@ -291,9 +309,18 @@ public: } void Update(const EditorWorkspacePanelUpdateContext& context) override { - m_panel.SetCommandFocusService(&context.services.commandFocusService); + m_panel.SetCommandFocusService(&context.frameServices.GetCommandFocusService()); + InspectorPanelContext panelContext{ + .session = context.frameServices.GetSession(), + .projectRuntime = context.frameServices.GetProjectRuntime(), + .sceneRuntime = context.frameServices.GetSceneRuntime(), + .colorPickerToolState = context.frameServices.GetColorPickerToolState(), + .textMeasurer = context.frameServices.GetTextMeasurer(), + .utilityWindowRequester = &context.frameServices, + .requestUtilityWindow = RequestUtilityWindowFromFrameServices, + }; m_panel.Update( - context.services, + panelContext, ResolveHostedPanelDispatchEntry( context.shellFrame.hostedPanelDispatchFrame, GetPanelId()), @@ -340,12 +367,12 @@ public: } void Update(const EditorWorkspacePanelUpdateContext& context) override { - m_panel.SetProjectRuntime(&context.services.projectRuntime); - m_panel.SetCommandFocusService(&context.services.commandFocusService); - m_panel.SetSystemInteractionHost(context.services.systemInteractionHost); + m_panel.SetProjectRuntime(&context.frameServices.GetProjectRuntime()); + m_panel.SetCommandFocusService(&context.frameServices.GetCommandFocusService()); + m_panel.SetSystemInteractionHost(context.frameServices.GetSystemInteractionHost()); m_panel.SetSceneAssetOpenRequestHandler( - context.services.sceneAssetOpenRequester, - context.services.requestOpenSceneAsset); + &context.frameServices, + RequestSceneAssetFromFrameServices); m_panel.Update( ResolveHostedPanelDispatchEntry( context.shellFrame.hostedPanelDispatchFrame, @@ -428,16 +455,16 @@ public: } void PrepareForShellDefinition( - EditorPanelServices& services, + EditorFrameServices& frameServices, UIEditorWorkspaceController&) override { - m_commandRoute.BindSceneRuntime(&services.sceneRuntime); - m_feature.SetCommandFocusService(&services.commandFocusService); - m_feature.SyncRenderRequest(services.sceneRuntime); + m_commandRoute.BindSceneRuntime(&frameServices.GetSceneRuntime()); + m_feature.SetCommandFocusService(&frameServices.GetCommandFocusService()); + m_feature.SyncRenderRequest(frameServices.GetSceneRuntime()); } void Update(const EditorWorkspacePanelUpdateContext& context) override { m_feature.Update( - context.services.sceneRuntime, + context.frameServices.GetSceneRuntime(), context.shellInteractionState.workspaceInteractionState.composeState, context.shellFrame.workspaceInteractionFrame.composeFrame); } @@ -483,9 +510,9 @@ public: } void PrepareForShellDefinition( - EditorPanelServices& services, + EditorFrameServices& frameServices, UIEditorWorkspaceController&) override { - m_feature.SetCommandFocusService(&services.commandFocusService); + m_feature.SetCommandFocusService(&frameServices.GetCommandFocusService()); } void Update(const EditorWorkspacePanelUpdateContext& context) override { diff --git a/editor/app/Features/Inspector/AddComponentPanel.cpp b/editor/app/Features/Inspector/AddComponentPanel.cpp index db9b66eb..0fd3284a 100644 --- a/editor/app/Features/Inspector/AddComponentPanel.cpp +++ b/editor/app/Features/Inspector/AddComponentPanel.cpp @@ -1,8 +1,9 @@ #include "Inspector/AddComponentPanel.h" -#include "Panels/EditorPanelServices.h" #include "Inspector/Components/IInspectorComponentEditor.h" #include "Inspector/Components/InspectorComponentEditorRegistry.h" +#include "Scene/EditorSceneRuntime.h" +#include "Windowing/EditorFrameServices.h" #include @@ -123,7 +124,7 @@ void AddComponentPanel::RebuildEntries( } bool AddComponentPanel::TryActivateEntry( - EditorPanelServices& services, + EditorSceneRuntime& sceneRuntime, std::size_t entryIndex) { if (entryIndex >= m_entries.size()) { return false; @@ -134,14 +135,14 @@ bool AddComponentPanel::TryActivateEntry( return false; } - if (!services.sceneRuntime.AddComponentToSelectedGameObject(entry.componentTypeName)) { + if (!sceneRuntime.AddComponentToSelectedGameObject(entry.componentTypeName)) { return false; } const std::optional selectedObject = - services.sceneRuntime.GetSelectedObjectSnapshot(); + sceneRuntime.GetSelectedObjectSnapshot(); m_hasTarget = selectedObject.has_value(); - m_targetDisplayName = services.sceneRuntime.GetSelectedDisplayName(); + m_targetDisplayName = sceneRuntime.GetSelectedDisplayName(); RebuildEntries(selectedObject.has_value() ? &selectedObject.value() : nullptr); return true; } @@ -157,7 +158,7 @@ std::size_t AddComponentPanel::HitTestEntry(const UIPoint& point) const { } void AddComponentPanel::Update( - EditorPanelServices& services, + EditorFrameServices& frameServices, const EditorUtilityWindowHostContext& hostContext, const std::vector& inputEvents) { if (!hostContext.mounted) { @@ -165,12 +166,13 @@ void AddComponentPanel::Update( return; } + EditorSceneRuntime& sceneRuntime = frameServices.GetSceneRuntime(); m_visible = true; m_bounds = hostContext.bounds; const std::optional selectedObject = - services.sceneRuntime.GetSelectedObjectSnapshot(); + sceneRuntime.GetSelectedObjectSnapshot(); m_hasTarget = selectedObject.has_value(); - m_targetDisplayName = services.sceneRuntime.GetSelectedDisplayName(); + m_targetDisplayName = sceneRuntime.GetSelectedDisplayName(); RebuildEntries(selectedObject.has_value() ? &selectedObject.value() : nullptr); if (hostContext.focusLost) { @@ -209,7 +211,7 @@ void AddComponentPanel::Update( m_hoveredEntryIndex = HitTestEntry(event.position); if (m_pressedEntryIndex != kInvalidEntryIndex && m_pressedEntryIndex == m_hoveredEntryIndex) { - TryActivateEntry(services, m_pressedEntryIndex); + TryActivateEntry(sceneRuntime, m_pressedEntryIndex); } m_pressedEntryIndex = kInvalidEntryIndex; break; diff --git a/editor/app/Features/Inspector/AddComponentPanel.h b/editor/app/Features/Inspector/AddComponentPanel.h index 5c5f2ed9..2838e2dc 100644 --- a/editor/app/Features/Inspector/AddComponentPanel.h +++ b/editor/app/Features/Inspector/AddComponentPanel.h @@ -9,6 +9,8 @@ namespace XCEngine::UI::Editor::App { +class EditorSceneRuntime; + class AddComponentPanel final : public EditorUtilityWindowPanel { public: std::string_view GetDrawListId() const override { @@ -16,7 +18,7 @@ public: } void ResetInteractionState() override; void Update( - EditorPanelServices& services, + EditorFrameServices& frameServices, const EditorUtilityWindowHostContext& hostContext, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents) override; void Append(::XCEngine::UI::UIDrawList& drawList) const override; @@ -32,7 +34,7 @@ private: void ResetPanelState(); void RebuildEntries(const EditorSceneObjectSnapshot* gameObject); - bool TryActivateEntry(EditorPanelServices& services, std::size_t entryIndex); + bool TryActivateEntry(EditorSceneRuntime& sceneRuntime, std::size_t entryIndex); std::size_t HitTestEntry(const ::XCEngine::UI::UIPoint& point) const; bool m_visible = false; diff --git a/editor/app/Features/Inspector/InspectorPanel.cpp b/editor/app/Features/Inspector/InspectorPanel.cpp index 64f2bef6..77e3f73e 100644 --- a/editor/app/Features/Inspector/InspectorPanel.cpp +++ b/editor/app/Features/Inspector/InspectorPanel.cpp @@ -1,6 +1,5 @@ #include "InspectorPanel.h" -#include "Panels/EditorPanelServices.h" #include "UtilityWindows/EditorUtilityWindowRuntime.h" #include "State/EditorColorPickerToolState.h" #include "Inspector/InspectorFieldValueApplier.h" @@ -450,36 +449,36 @@ Widgets::UIEditorPropertyGridField* InspectorPanel::FindMutableField( } void InspectorPanel::CapturePresentationStamps( - const EditorPanelServices& services) { - m_lastSceneSelectionStamp = services.sceneRuntime.GetSelectionStamp(); - m_lastProjectSelectionStamp = services.projectRuntime.GetSelectionStamp(); - m_lastSceneInspectorRevision = services.sceneRuntime.GetInspectorRevision(); + const InspectorPanelContext& context) { + m_lastSceneSelectionStamp = context.sceneRuntime.GetSelectionStamp(); + m_lastProjectSelectionStamp = context.projectRuntime.GetSelectionStamp(); + m_lastSceneInspectorRevision = context.sceneRuntime.GetInspectorRevision(); } void InspectorPanel::RebuildPresentation( - EditorPanelServices& services, + InspectorPanelContext& context, bool subjectChanged) { m_presentation = BuildInspectorPresentationModel( m_subject, - services.sceneRuntime, + context.sceneRuntime, InspectorComponentEditorRegistry::Get()); - CapturePresentationStamps(services); + CapturePresentationStamps(context); SyncExpansionState(subjectChanged); SyncSelectionState(); } -void InspectorPanel::ForceResyncPresentation(EditorPanelServices& services) { +void InspectorPanel::ForceResyncPresentation(InspectorPanelContext& context) { if (m_subject.kind != InspectorSubjectKind::SceneObject) { - RebuildPresentation(services, false); + RebuildPresentation(context, false); return; } const std::string structureSignature = BuildInspectorStructureSignature( m_subject, - services.sceneRuntime, + context.sceneRuntime, InspectorComponentEditorRegistry::Get()); if (structureSignature != m_presentation.structureSignature) { - RebuildPresentation(services, false); + RebuildPresentation(context, false); return; } @@ -487,38 +486,38 @@ void InspectorPanel::ForceResyncPresentation(EditorPanelServices& services) { SyncInspectorPresentationModelValues( m_presentation, m_subject, - services.sceneRuntime, + context.sceneRuntime, InspectorComponentEditorRegistry::Get()); if (!syncResult.success) { - RebuildPresentation(services, false); + RebuildPresentation(context, false); return; } m_presentation.structureSignature = structureSignature; - CapturePresentationStamps(services); + CapturePresentationStamps(context); SyncSelectionState(); } void InspectorPanel::RefreshPresentation( - EditorPanelServices& services, + InspectorPanelContext& context, bool subjectChanged) { if (subjectChanged) { - RebuildPresentation(services, true); + RebuildPresentation(context, true); return; } switch (m_subject.kind) { case InspectorSubjectKind::ProjectAsset: if (m_lastProjectSelectionStamp != - services.projectRuntime.GetSelectionStamp()) { - RebuildPresentation(services, false); + context.projectRuntime.GetSelectionStamp()) { + RebuildPresentation(context, false); } return; case InspectorSubjectKind::SceneObject: { - const EditorSceneRuntime& sceneRuntime = services.sceneRuntime; + const EditorSceneRuntime& sceneRuntime = context.sceneRuntime; if (m_lastSceneSelectionStamp != sceneRuntime.GetSelectionStamp()) { - RebuildPresentation(services, false); + RebuildPresentation(context, false); return; } @@ -531,7 +530,7 @@ void InspectorPanel::RefreshPresentation( sceneRuntime, InspectorComponentEditorRegistry::Get()); if (structureSignature != m_presentation.structureSignature) { - RebuildPresentation(services, false); + RebuildPresentation(context, false); return; } @@ -542,12 +541,12 @@ void InspectorPanel::RefreshPresentation( sceneRuntime, InspectorComponentEditorRegistry::Get()); if (!syncResult.success) { - RebuildPresentation(services, false); + RebuildPresentation(context, false); return; } m_presentation.structureSignature = structureSignature; - CapturePresentationStamps(services); + CapturePresentationStamps(context); SyncSelectionState(); return; } @@ -558,8 +557,8 @@ void InspectorPanel::RefreshPresentation( } } -bool InspectorPanel::ApplyColorPickerToolValue(EditorPanelServices& services) { - EditorColorPickerToolState& toolState = services.colorPickerToolState; +bool InspectorPanel::ApplyColorPickerToolValue(InspectorPanelContext& context) { + EditorColorPickerToolState& toolState = context.colorPickerToolState; if (m_sceneRuntime == nullptr || !toolState.active || toolState.revision == m_lastAppliedColorPickerRevision || @@ -585,16 +584,16 @@ bool InspectorPanel::ApplyColorPickerToolValue(EditorPanelServices& services) { const bool applied = ApplyChangedField(field->fieldId); m_lastAppliedColorPickerRevision = toolState.revision; if (!applied) { - ForceResyncPresentation(services); + ForceResyncPresentation(context); return false; } - RefreshPresentation(services, false); + RefreshPresentation(context, false); return true; } void InspectorPanel::RequestColorPicker( - EditorPanelServices& services, + InspectorPanelContext& context, std::string_view fieldId) { const Widgets::UIEditorPropertyGridField* field = FindField(fieldId); if (field == nullptr || @@ -604,12 +603,12 @@ void InspectorPanel::RequestColorPicker( } OpenEditorColorPickerToolForInspectorField( - services.colorPickerToolState, + context.colorPickerToolState, m_subjectKey, field->fieldId, field->colorValue.value, field->colorValue.showAlpha); - services.RequestOpenUtilityWindow(EditorUtilityWindowKind::ColorPicker); + context.RequestOpenUtilityWindow(EditorUtilityWindowKind::ColorPicker); } void InspectorPanel::ResetAddComponentButtonState() { @@ -618,7 +617,7 @@ void InspectorPanel::ResetAddComponentButtonState() { } void InspectorPanel::UpdateAddComponentButton( - EditorPanelServices& services, + InspectorPanelContext& context, const std::vector& inputEvents) { if (!ShouldShowAddComponentButton()) { ResetAddComponentButtonState(); @@ -659,7 +658,7 @@ void InspectorPanel::UpdateAddComponentButton( if (m_addComponentButtonPressed && ContainsPoint(buttonRect, event.position)) { - services.RequestOpenUtilityWindow(EditorUtilityWindowKind::AddComponent); + context.RequestOpenUtilityWindow(EditorUtilityWindowKind::AddComponent); } m_addComponentButtonHovered = ContainsPoint(buttonRect, event.position); @@ -711,7 +710,7 @@ bool InspectorPanel::ApplyChangedField(std::string_view fieldId) { } void InspectorPanel::Update( - EditorPanelServices& services, + InspectorPanelContext& context, const UIEditorHostedPanelDispatchEntry& dispatchEntry, const std::vector& inputEvents) { if (!dispatchEntry.mounted) { @@ -721,9 +720,9 @@ void InspectorPanel::Update( m_visible = true; m_bounds = dispatchEntry.bounds; - m_sceneRuntime = &services.sceneRuntime; - m_textMeasurer = services.textMeasurer; - m_subject = BuildInspectorSubject(services.session, services.sceneRuntime); + m_sceneRuntime = &context.sceneRuntime; + m_textMeasurer = context.textMeasurer; + m_subject = BuildInspectorSubject(context.session, context.sceneRuntime); const std::string nextSubjectKey = BuildSubjectKey(); const bool subjectChanged = m_subjectKey != nextSubjectKey; @@ -732,8 +731,8 @@ void InspectorPanel::Update( ResetInteractionState(); } - RefreshPresentation(services, subjectChanged); - ApplyColorPickerToolValue(services); + RefreshPresentation(context, subjectChanged); + ApplyColorPickerToolValue(context); const std::vector filteredEvents = BuildUIEditorPanelInputEvents( @@ -802,21 +801,21 @@ void InspectorPanel::Update( m_gridFrame.result = interactionFrame.result; if (interactionFrame.result.pickerRequested && !interactionFrame.result.requestedFieldId.empty()) { - RequestColorPicker(services, interactionFrame.result.requestedFieldId); + RequestColorPicker(context, interactionFrame.result.requestedFieldId); } if (interactionFrame.result.fieldValueChanged && !interactionFrame.result.changedFieldId.empty()) { if (ApplyChangedField(interactionFrame.result.changedFieldId)) { - RefreshPresentation(services, false); + RefreshPresentation(context, false); } else { - ForceResyncPresentation(services); + ForceResyncPresentation(context); } } } RebuildScrollableLayout(); - UpdateAddComponentButton(services, filteredEvents); + UpdateAddComponentButton(context, filteredEvents); } void InspectorPanel::Append(UIDrawList& drawList) const { diff --git a/editor/app/Features/Inspector/InspectorPanel.h b/editor/app/Features/Inspector/InspectorPanel.h index 9abd6dfa..811782ad 100644 --- a/editor/app/Features/Inspector/InspectorPanel.h +++ b/editor/app/Features/Inspector/InspectorPanel.h @@ -22,14 +22,35 @@ namespace XCEngine::UI::Editor::App { class EditorCommandFocusService; +struct EditorColorPickerToolState; +class EditorProjectRuntime; class EditorSceneRuntime; -struct EditorPanelServices; +struct EditorSession; +enum class EditorUtilityWindowKind : std::uint8_t; + +struct InspectorPanelContext { + using UtilityWindowRequestFn = void (*)(void*, EditorUtilityWindowKind); + + const EditorSession& session; + EditorProjectRuntime& projectRuntime; + EditorSceneRuntime& sceneRuntime; + EditorColorPickerToolState& colorPickerToolState; + const ::XCEngine::UI::Editor::UIEditorTextMeasurer* textMeasurer = nullptr; + void* utilityWindowRequester = nullptr; + UtilityWindowRequestFn requestUtilityWindow = nullptr; + + void RequestOpenUtilityWindow(EditorUtilityWindowKind kind) const { + if (requestUtilityWindow != nullptr) { + requestUtilityWindow(utilityWindowRequester, kind); + } + } +}; class InspectorPanel final : public EditorEditCommandRoute { public: void SetCommandFocusService(EditorCommandFocusService* commandFocusService); void Update( - EditorPanelServices& services, + InspectorPanelContext& context, const UIEditorHostedPanelDispatchEntry& dispatchEntry, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents); void Append(::XCEngine::UI::UIDrawList& drawList) const; @@ -58,15 +79,15 @@ private: const InspectorPresentationComponentBinding* FindSelectedComponentBinding() const; const Widgets::UIEditorPropertyGridField* FindField(std::string_view fieldId) const; Widgets::UIEditorPropertyGridField* FindMutableField(std::string_view fieldId); - void CapturePresentationStamps(const EditorPanelServices& services); - void RebuildPresentation(EditorPanelServices& services, bool subjectChanged); - void RefreshPresentation(EditorPanelServices& services, bool subjectChanged); - void ForceResyncPresentation(EditorPanelServices& services); - bool ApplyColorPickerToolValue(EditorPanelServices& services); - void RequestColorPicker(EditorPanelServices& services, std::string_view fieldId); + void CapturePresentationStamps(const InspectorPanelContext& context); + void RebuildPresentation(InspectorPanelContext& context, bool subjectChanged); + void RefreshPresentation(InspectorPanelContext& context, bool subjectChanged); + void ForceResyncPresentation(InspectorPanelContext& context); + bool ApplyColorPickerToolValue(InspectorPanelContext& context); + void RequestColorPicker(InspectorPanelContext& context, std::string_view fieldId); void ResetAddComponentButtonState(); void UpdateAddComponentButton( - EditorPanelServices& services, + InspectorPanelContext& context, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents); bool ApplyChangedField(std::string_view fieldId); diff --git a/editor/app/Windowing/Content/EditorUtilityWindowContentController.cpp b/editor/app/Windowing/Content/EditorUtilityWindowContentController.cpp index d1fe207c..d799aa52 100644 --- a/editor/app/Windowing/Content/EditorUtilityWindowContentController.cpp +++ b/editor/app/Windowing/Content/EditorUtilityWindowContentController.cpp @@ -67,9 +67,8 @@ EditorUtilityWindowContentController::UpdateAndAppend( return {}; } - EditorPanelServices services = context.frameServices.BuildPanelServices(); m_panel->Update( - services, + context.frameServices, EditorUtilityWindowHostContext{ .mounted = true, .bounds = context.bounds,