refactor(new_editor): split shell runtime update stages

This commit is contained in:
2026-04-22 15:01:03 +08:00
parent 2a8448cfbc
commit 77fe0a97a4
7 changed files with 328 additions and 134 deletions

View File

@@ -295,23 +295,6 @@ const UIEditorPanelDescriptor* ResolveSingleVisibleToolWindowPanelDescriptor(
: nullptr;
}
PanelInputContext BuildHostedPanelInputContext(
const UIEditorWorkspaceInteractionFrame& workspaceFrame,
bool allowInteraction,
std::string_view panelId) {
PanelInputContext inputContext = {};
inputContext.allowInteraction = allowInteraction;
inputContext.hasInputFocus =
IsUIEditorWorkspaceHostedPanelInputOwner(workspaceFrame.inputOwner, panelId);
inputContext.focusGained =
!IsUIEditorWorkspaceHostedPanelInputOwner(workspaceFrame.previousInputOwner, panelId) &&
inputContext.hasInputFocus;
inputContext.focusLost =
IsUIEditorWorkspaceHostedPanelInputOwner(workspaceFrame.previousInputOwner, panelId) &&
!inputContext.hasInputFocus;
return inputContext;
}
} // namespace
std::vector<UIInputEvent> FilterShellInputEventsForHostedContentCapture(
@@ -335,52 +318,6 @@ std::vector<UIInputEvent> FilterShellInputEventsForHostedContentCapture(
return filteredEvents;
}
bool ShouldHostedContentYieldPointerStream(
const UIEditorShellInteractionFrame& shellFrame,
bool shellInteractiveCaptureActive) {
if (shellInteractiveCaptureActive ||
shellFrame.result.requestPointerCapture ||
shellFrame.result.releasePointerCapture) {
return true;
}
return shellFrame.result.workspaceResult.dockHostResult.hitTarget.kind ==
UIEditorDockHostHitTargetKind::SplitterHandle;
}
std::vector<UIInputEvent> FilterHostedContentInputEventsForShellOwnership(
const std::vector<UIInputEvent>& inputEvents,
bool shellOwnsPointerStream) {
if (!shellOwnsPointerStream) {
return inputEvents;
}
std::vector<UIInputEvent> filteredEvents = {};
filteredEvents.reserve(inputEvents.size() + 1u);
bool strippedPointerInput = false;
UIInputEvent lastPointerEvent = {};
for (const UIInputEvent& event : inputEvents) {
if (IsPointerInputEventType(event.type)) {
strippedPointerInput = true;
lastPointerEvent = event;
continue;
}
filteredEvents.push_back(event);
}
if (strippedPointerInput) {
UIInputEvent leaveEvent = {};
leaveEvent.type = UIInputEventType::PointerLeave;
leaveEvent.position = lastPointerEvent.position;
leaveEvent.modifiers = lastPointerEvent.modifiers;
filteredEvents.push_back(leaveEvent);
}
return filteredEvents;
}
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::App {
@@ -424,21 +361,19 @@ void EditorShellRuntime::Update(
const Widgets::UIEditorDockHostLayout preUpdateDockLayout =
m_shellFrame.workspaceInteractionFrame.dockHostFrame.layout;
m_hierarchyPanel.SetSceneRuntime(&context.GetSceneRuntime());
m_hierarchyPanel.SetCommandFocusService(&context.GetCommandFocusService());
m_sceneEditCommandRoute.BindSceneRuntime(&context.GetSceneRuntime());
m_sceneViewportFeature.SetCommandFocusService(&context.GetCommandFocusService());
// Keep the previous render request available for readback-based picking during
// this update, then refresh it again after camera/navigation state changes.
m_sceneViewportFeature.SyncRenderRequest(context.GetSceneRuntime());
context.BindEditCommandRoutes(
&m_hierarchyPanel,
&m_projectPanel,
&m_sceneEditCommandRoute,
&m_inspectorPanel);
context.SyncSessionFromWorkspace(workspaceController);
UIEditorShellInteractionDefinition definition =
context.BuildShellDefinition(workspaceController, captureText, shellVariant);
m_sessionCoordinator.PrepareShellDefinition(
EditorShellSessionCoordinatorContext{
.context = context,
.workspaceController = workspaceController,
.captureText = captureText,
.shellVariant = shellVariant,
.hierarchyPanel = m_hierarchyPanel,
.inspectorPanel = m_inspectorPanel,
.projectPanel = m_projectPanel,
.sceneEditCommandRoute = m_sceneEditCommandRoute,
.sceneViewportFeature = m_sceneViewportFeature,
});
m_viewportHostService.BeginFrame();
const std::vector<::XCEngine::UI::UIInputEvent> shellEvents =
HasHostedContentCapture()
@@ -461,9 +396,19 @@ void EditorShellRuntime::Update(
preUpdateDockLayout,
workspaceController,
metrics.shellMetrics.dockHostMetrics)) {
context.SyncSessionFromWorkspace(workspaceController);
definition =
context.BuildShellDefinition(workspaceController, captureText, shellVariant);
m_sessionCoordinator.PrepareShellDefinition(
EditorShellSessionCoordinatorContext{
.context = context,
.workspaceController = workspaceController,
.captureText = captureText,
.shellVariant = shellVariant,
.hierarchyPanel = m_hierarchyPanel,
.inspectorPanel = m_inspectorPanel,
.projectPanel = m_projectPanel,
.sceneEditCommandRoute = m_sceneEditCommandRoute,
.sceneViewportFeature = m_sceneViewportFeature,
});
m_shellFrame = UpdateUIEditorShellInteraction(
m_shellInteractionState,
workspaceController,
@@ -474,64 +419,24 @@ void EditorShellRuntime::Update(
metrics);
}
const bool shellOwnsHostedContentPointerStream =
ShouldHostedContentYieldPointerStream(m_shellFrame, HasShellInteractiveCapture());
const std::vector<::XCEngine::UI::UIInputEvent> hostedContentEvents =
FilterHostedContentInputEventsForShellOwnership(
inputEvents,
shellOwnsHostedContentPointerStream);
m_sceneViewportFeature.Update(
context.GetSceneRuntime(),
m_shellInteractionState.workspaceInteractionState.composeState,
m_shellFrame.workspaceInteractionFrame.composeFrame);
ApplyViewportFramesToShellFrame(m_shellFrame, m_viewportHostService);
context.SyncSessionFromWorkspace(workspaceController);
context.UpdateStatusFromShellResult(workspaceController, m_shellFrame.result);
m_sessionCoordinator.FinalizeFrame(context, workspaceController, m_shellFrame.result);
const bool allowHostedInteraction = !m_shellFrame.result.workspaceInputSuppressed;
const PanelInputContext hierarchyInputContext = BuildHostedPanelInputContext(
m_shellFrame.workspaceInteractionFrame,
allowHostedInteraction,
kHierarchyPanelId);
const PanelInputContext projectInputContext = BuildHostedPanelInputContext(
m_shellFrame.workspaceInteractionFrame,
allowHostedInteraction,
kProjectPanelId);
const PanelInputContext inspectorInputContext = BuildHostedPanelInputContext(
m_shellFrame.workspaceInteractionFrame,
allowHostedInteraction,
kInspectorPanelId);
const PanelInputContext colorPickerInputContext = BuildHostedPanelInputContext(
m_shellFrame.workspaceInteractionFrame,
allowHostedInteraction,
kColorPickerPanelId);
m_projectPanel.SetProjectRuntime(&context.GetProjectRuntime());
m_projectPanel.SetCommandFocusService(&context.GetCommandFocusService());
m_projectPanel.SetSystemInteractionHost(context.GetSystemInteractionHost());
m_inspectorPanel.SetCommandFocusService(&context.GetCommandFocusService());
m_hierarchyPanel.Update(
m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame,
hostedContentEvents,
hierarchyInputContext);
m_projectPanel.Update(
m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame,
hostedContentEvents,
projectInputContext);
m_hostedPanelCoordinator.Update(
EditorShellHostedPanelCoordinatorContext{
.context = context,
.shellFrame = m_shellFrame,
.shellInteractionState = m_shellInteractionState,
.inputEvents = inputEvents,
.shellInteractiveCaptureActive = HasShellInteractiveCapture(),
.consolePanel = m_consolePanel,
.colorPickerPanel = m_colorPickerPanel,
.hierarchyPanel = m_hierarchyPanel,
.inspectorPanel = m_inspectorPanel,
.projectPanel = m_projectPanel,
.sceneViewportFeature = m_sceneViewportFeature,
});
m_traceEntries = SyncWorkspaceEvents(context, *this);
m_colorPickerPanel.Update(
context,
m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame,
hostedContentEvents,
colorPickerInputContext);
m_inspectorPanel.Update(
context,
m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame,
hostedContentEvents,
inspectorInputContext);
context.SyncSessionFromCommandFocusService();
m_consolePanel.Update(
context.GetSession(),
m_shellFrame.workspaceInteractionFrame.composeFrame.contentHostFrame);
}
} // namespace XCEngine::UI::Editor::App