Files
XCEngine/editor/AGENT.md

11 KiB
Raw Blame History

XCUI Editor Agent Guide

这份文档面向在 editor/ 下工作的 coding agent / 开发者。它描述当前 editor 的真实工程边界、窗口架构和修改约束,不是产品说明。

如果本文和当前代码、editor/CMakeLists.txt、实际目录结构冲突,以当前 checkout 为准,并在本次工作里同步修正文档。

1. 当前定位

editor/ 是当前 editor 应用主线。

当前工程事实:

  • 构建目标是 XCUIEditorApp
  • 输出名是 XCEngine,构建产物为 XCEngine.exe
  • editor/src 是可复用的 XCEditor UI framework。
  • editor/include/XCEditoreditor/src 的公开接口。
  • editor/app 是具体 XCEngine editor 应用层。
  • editor/resources 存放 editor 自有图标和 scene viewport shader。

虽然 editor/CMakeLists.txt 仍把这些代码编进一个可执行目标,但语义上已经分成 framework、app core、Win32 host 和 D3D12 host 四层。

2. 分层边界

推荐按下面五层理解和修改:

  1. editor/src / editor/include/XCEditor XCEditor UI framework。这里应保持通用不依赖具体项目、场景、Win32 宿主或 D3D12 实现。

  2. editor/app/CompositionFeaturesProjectSceneStateCommands Editor app core。这里装配 panel、项目运行时、场景运行时、选择状态、命令路由和 shell frame。

  3. editor/app/Windowing Editor host seam。这里放平台无关的窗口内容 contract、workspace/utility content assembly、frame orchestration 和 host-facing transfer request。

  4. editor/app/Platform/Win32 Win32 host。这里负责原生窗口、消息分发、窗口生命周期、输入收集、title bar / chrome 和 surface/presenter。

  5. editor/app/Rendering Editor rendering host。这里负责 D3D12 UI 渲染、窗口 swapchain、viewport 离屏资源、editor 图标纹理和 scene viewport pass。

依赖方向尽量保持:

app/platform + app/rendering -> app/windowing -> app/core -> XCEditor framework -> engine UI primitives

不要让 editor/src 反向依赖 editor/app

2.1 长期目标:把语义分层落成真实模块边界

当前 editor/ 已经有语义上的四层划分,但还没有真正的编译/依赖边界。窗口相关代码最重要的长期目标,不是继续细拆 Win32 目录里的类,而是把下面这条关系变成代码和构建系统都能强制执行的事实:

XCEditor framework
  <- editor app core
  <- editor host seam / app/Windowing
  <- Win32 host + D3D12 host

收敛要求:

  • editor/app/Platform/Win32 只负责 native window、message pump、input translation、chrome、lifecycle 和 surface/presenter 等宿主职责。
  • workspace mutation、utility window routing、shell composition、window content assembly 这类产品语义应逐步收敛到平台无关层,而不是继续堆进 Win32 host。
  • editor/src / editor/include/XCEditor 不允许反向依赖 editor/app;公开头文件不应暴露 App::* 类型。
  • 最终要通过独立 CMake target 和受限 include dirs 落实,而不是只靠目录约定。

后续凡是修改窗口系统,优先朝“缩小 Platform/Win32CompositionFeaturesUtilityWindowsRendering 的直接依赖面”这个方向收敛。如果一个新需求只能通过继续把业务语义塞进 Win32 host 才能完成,应先停下来评估是否缺少平台无关的 host seam。

3. 顶层启动流程

入口:

app/main.cpp
  -> RunXCUIEditorApp
  -> Application::Run

核心对象关系:

Application
  -> EditorContext
  -> EditorWindowManager
      -> EditorWindow
          -> EditorWindowRuntimeController
              -> D3D12WindowRenderer
              -> D3D12UiRenderer
              -> D3D12WindowRenderLoop
              -> EditorWindowContentController
                  -> EditorWorkspaceWindowContentController
                  -> EditorUtilityWindowContentController

EditorContext 是全局共享应用状态。每个 workspace window 持有自己的 UIEditorWorkspaceControllerEditorShellRuntime。utility window 不持有 workspace controller。

4. 显式窗口架构

当前窗口系统已经显式区分两类窗口:

  • EditorWindowCategory::Workspace 主窗口和由 dock tab / panel 拖出的独立窗口。
  • EditorWindowCategory::Utility 颜色选择器、Add Component 这类天然工具窗。

两类窗口共享同一个 native host

EditorWindow
  -> EditorWindowRuntimeController
  -> D3D12WindowRenderLoop
  -> EditorWindowContentController

差异放在 content controller 和 policy 上,而不是靠“有没有 workspace binding”隐式推断。

4.1 Workspace Window

workspace window 的内容控制器是 EditorWorkspaceWindowContentController,内部持有:

  • UIEditorWorkspaceController
  • EditorShellRuntime
  • EditorWindowFrameOrchestrator

这类窗口是完整 shell/workspace 容器。主窗口和 detached workspace window 都属于这一类。

4.2 Utility Window

utility window 的内容控制器是 EditorUtilityWindowContentController,内部持有:

  • EditorUtilityWindowPanel

当前 utility 窗口通过 registry/factory 创建,已实现显式 descriptor

  • EditorUtilityWindowDescriptor
  • EditorUtilityWindowReusePolicy
  • EditorWindowChromePolicy
  • EditorWindowNativeStylePolicy

当前 ColorPickerAddComponent 都是单例复用窗口。

5. 窗口能力与策略

窗口内容能力由 EditorWindowContentCapabilities 描述。创建窗口时host 会校验:

  • Workspace 分类必须对应具备 workspace capability 的 content controller。
  • Utility 分类必须对应具备 utility capability 的 content controller。

这一步是硬校验,不再依赖后续 coordinator 通过空 binding 兜底。

窗口外观/宿主策略当前最少包括:

  • EditorWindowChromePolicy 当前用于控制 detached title bar tab strip、frame stats以及 utility window 的 topmost pin 按钮/默认置顶策略。
  • EditorWindowNativeStylePolicy 当前用于控制扩展窗口样式和是否复用 host 默认 style。

当前默认规则:

  • workspace window 允许 detached title bar tab strip。
  • utility window 不允许 detached title bar tab strip。
  • utility window 不显示 frame stats。
  • utility window 顶栏显示 topmost pin 按钮,且默认置顶。
  • utility window 使用 WS_EX_TOOLWINDOW

6. Workspace / Utility 协调器边界

6.1 Workspace Coordinator

EditorWindowWorkspaceCoordinator 只处理 Workspace 窗口:

  • 维护 window workspace set
  • 处理 detach panel
  • 处理 global tab drag
  • 处理 cross-window dock/drop
  • 更新 detached workspace title

utility window 不参与:

  • workspace set
  • dock target hit test
  • cross-window drop target

6.2 Utility Coordinator

EditorUtilityWindowCoordinator 只处理 utility window 请求:

  • 根据 EditorUtilityWindowDescriptor 创建工具窗
  • 按 reuse policy 决定复用还是新建
  • 对现有 utility window 做 focus / restore

不要把 utility window 塞进 workspace mutation 流程。

7. Frame Request 结构

EditorWindowFrameTransferRequests 已拆成两个子域:

workspace:
  beginGlobalTabDrag
  detachPanel

utility:
  openUtilityWindow

规则:

  • EditorWindowWorkspaceCoordinator 只消费 transferRequests.workspace
  • EditorUtilityWindowCoordinator 只消费 transferRequests.utility
  • queued immediate frame 也按两个子域分别合并

不要再把 workspace 和 utility 的窗口请求混进同一个平铺字段集合。

8. 每帧流程

当前每帧主路径:

Application::Run
  -> EditorWindowManager::RenderAllWindows
      -> EditorWindowRuntimeController::BeginFrame
      -> EditorWindowRuntimeController::UpdateAndAppend
          -> EditorWindowFrameOrchestrator::UpdateAndAppend
              -> EditorShellRuntime::Update
                  -> EditorShellSessionCoordinator::PrepareShellDefinition
                  -> EditorShellInteractionEngine::Update
                      -> UpdateUIEditorShellInteraction
                      -> ViewportHostService::RequestViewport
                  -> EditorShellSessionCoordinator::FinalizeFrame
                  -> EditorShellHostedPanelCoordinator::Update
              -> EditorShellRuntime::Append
      -> EditorWindowRuntimeController::RenderRequestedViewports
      -> EditorWindowRuntimeController::Present

重要约束:

  • viewport 先在 shell layout 阶段通过 RequestViewport() 申明尺寸和纹理需求。
  • 再在 RenderRequestedViewports() 阶段真正渲染。
  • 不要打乱这两个阶段的顺序。

9. 修改规范

  • 先判断改动属于 framework、app core、windowing seam、Win32 host 还是 rendering host。
  • 小改动优先贴近现有模式,不顺手做跨层重构。
  • 新增通用 widget 放 editor/src / editor/include/XCEditor
  • 新增具体 editor 功能放 editor/app/Features/<FeatureName>,再由 composition 装配。
  • 新增 host-facing window content、frame request、content assembly 放 editor/app/Windowing
  • 新增 Win32 宿主行为放 editor/app/Platform/Win32,通过 seam/controller/policy 与 app core 通信。
  • 新增 viewport 渲染资源或 pass 放 editor/app/Rendering/Viewporteditor/resources/shaders/scene-viewport
  • draw append 只负责绘制,不修改 editor runtime 或 scene/project state。
  • D3D12 host、Win32 host、panel 之间避免双向强耦合。

10. 当前架构债务

这轮重构完成后,仍有以下债务:

  • editor/CMakeLists.txt 还没有把 framework、app core、windowing seam、Win32 host、D3D12 host 拆成独立 target。
  • EditorContext 仍然过重混合了全局状态、service locator、command bridge、session sync 和状态输出。
  • EditorShellRuntime 仍然过重,既持有 panel又持有 viewport host、shell frame、draw composer 和 interaction coordinator。
  • panel 仍缺少统一 feature 接口,HierarchyPanelProjectPanelInspectorPanel 只是模式相似。
  • app/Windowing 目前只是首刀 ownership 调整workspace / utility window orchestration 仍主要停留在 Win32 coordinator。

这些债务后续要分步处理,不要一次性重写整个窗口系统。

11. 验证基线

当前这轮窗口架构重构的验证状态:

  • 用户已完成 GUI 行为验证。
  • cmake --build build --config Debug --target XCUIEditorApp 已通过。
  • build/editor/Debug/XCEngine.exe 的 12 秒启动冒烟测试已通过,进程可正常响应关闭请求。

后续涉及窗口架构的改动,至少应维持这条验证基线。

12. 推荐阅读入口

开始 editor 相关任务时,优先阅读:

  • editor/CMakeLists.txt
  • editor/app/Bootstrap/Application.*
  • editor/app/Composition/EditorContext.*
  • editor/app/Composition/EditorShellRuntime.*
  • editor/app/Windowing/Content/EditorWindowContentController.h
  • editor/app/Windowing/Frame/EditorWindowFrameOrchestrator.*
  • editor/app/Platform/Win32/Windowing/EditorWindow.*
  • editor/app/Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.*
  • editor/app/Platform/Win32/Windowing/EditorUtilityWindowCoordinator.*
  • editor/app/UtilityWindows/EditorUtilityWindowRegistry.*
  • editor/include/XCEditor/Workspace/UIEditorWorkspaceController.h
  • editor/include/XCEditor/Shell/UIEditorShellInteraction.h