13 KiB
XCUI Editor Agent Guide
Build Shape
The editor is a two-layer system.
XCUIEditorLibis the reusable framework library.XCUIEditorAppis the concrete editor application executable.- The build shape of
editor/isXCUIEditorLib <- XCUIEditorApp. editor/src/**andeditor/include/XCEditor/**belong to the framework layer.editor/app/**belongs to the app layer and is compiled directly intoXCUIEditorApp.app/Windowing,app/Platform/Win32,app/Rendering,app/Composition, and similar directories are internal partitions inside the app layer.- Types for multi-window editor authority, Win32 hosting, utility windows, and editor-only rendering stay in
editor/app/**. editor/include/XCEditor/**exposes framework-level APIs only.
Architecture shorthand for this repo:
XCUIEditorLib
<- XCUIEditorApp
When describing the current architecture, refer to windowing, platform, rendering, and host as app-internal partitions unless the build graph itself changes.
这份文档面向在 editor/ 下工作的 coding agent / 开发者。它描述当前 editor 的真实工程边界、窗口架构和修改约束,不是产品说明。
如果本文和当前代码、editor/CMakeLists.txt、实际目录结构冲突,以当前 checkout 为准,并在本次工作里同步修正文档。
1. 当前定位
editor/ 是当前 editor 应用主线。
当前工程事实:
- 可复用 UI framework 的真实构建目标是
XCUIEditorLib。 - editor 应用的真实可执行目标是
XCUIEditorApp。 XCUIEditorApp的输出名是XCEngine,产物为XCEngine.exe。editor/src+editor/include/XCEditor是 XCEditor framework。editor/app是具体 XCEngine editor 应用层。editor/resources存放 editor 自有图标和 scene viewport shader。
当前 editor/CMakeLists.txt 并没有把 app core、windowing seam、Win32 host、rendering host 拆成独立生产 target。除了 XCUIEditorLib 之外,其余 app / windowing / platform / rendering 代码仍直接编进 XCUIEditorApp。
XCUIEditorAppLib、XCUIEditorAppCore、XCUIEditorHost 不是当前 editor/CMakeLists.txt 里真实定义的生产 target;它们只在部分测试脚本或清理逻辑里作为条件名称出现。不要把这些名字当成当前已经存在的模块边界。
2. 当前分层
推荐按下面五层理解和修改,但要记住这主要是目录和语义边界,不是已经被 CMake 强制落实的编译边界:
-
editor/src/editor/include/XCEditorXCEditor framework。这里应保持通用,不依赖具体 editor app、Win32 宿主或 D3D12 实现。 -
editor/app/Composition、Commands、Features、Project、Scene、State、Support、System、UtilityWindowseditor 应用语义层。这里放 panel 组合、项目/场景运行时、选择状态、命令桥接、utility window 描述和 app 侧服务。 -
editor/app/Windowing平台无关的窗口主线。这里放 content controller contract、frame transfer request、workspace synchronization planner / presentation policy / authoritative window set。 -
editor/app/Platform/Win32Win32 host。这里负责 native window、消息分发、生命周期、输入翻译、窗口 chrome、host runtime 和 coordinator。 -
editor/app/Renderingeditor 渲染宿主。这里负责 D3D12 UI 渲染、窗口 render loop、swapchain、viewport 资源和 scene viewport pass。
依赖方向尽量保持为:
XCEditor framework
<- app semantics
<- app/windowing
<- Platform/Win32
<- app/Rendering
现实约束:
- 当前只有
XCUIEditorLib是真实独立 target。 - 其余层级只是目录和 ownership 约定。
- 修改时仍要主动控制 include 方向,避免把“语义上应该分层”写回成硬耦合。
3. 顶层启动流程
入口:
app/main.cpp
-> RunXCUIEditorApp
-> Application::Run
当前启动主线:
Application
-> EditorContext
-> Win32SystemInteractionHost
-> EditorWindowSystem
-> EditorWindowManager
-> EditorWindowHostRuntime
-> EditorWindowWorkspaceCoordinator
-> EditorUtilityWindowCoordinator
-> EditorWindowLifecycleCoordinator
primary workspace window 的 bootstrap 顺序是:
EditorContext::BuildWorkspaceController()
-> EditorWindowSystem::BootstrapPrimaryWindow(...)
-> EditorWindowManager::CreateWorkspaceWindow(...)
不要把 primary window authority 初始化放回 Win32 host。当前 authoritative bootstrap 已经在 EditorWindowSystem。
4. 当前窗口系统事实
4.1 Authority / Planner / Host Execution
当前多窗口 workspace 主线里,几个核心对象的职责是:
-
EditorWindowSystem- 持有 authoritative
UIEditorWindowWorkspaceSet - 通过
EditorWindowWorkspaceStore做 validation / commit - 构建 synchronization plan
- 处理显式
workspaceMutationrequest - 处理 destroyed window reconciliation
- 持有 authoritative
-
EditorWindowWorkspaceCoordinator- 采集 host snapshot
- 调用
EditorWindowSystem生成 plan - 执行 host-side create / update / close
- 处理 global tab drag、detach、cross-window dock/drop
- 处理 window presentation refresh
- 在 native destroy 时回到
EditorWindowSystem做 reconcile
重要事实:
EditorWindowWorkspaceCoordinator已不再直接写 authority store。- 但它仍然很厚,仍同时承担 host 执行、presentation refresh、drag/detach 流程和部分回滚时序。
- 当前不要把它描述成“纯粹的薄 host adapter”。
4.2 Live Workspace Projection 还没有完全去状态化
EditorWorkspaceWindowContentController 当前内部仍持有:
UIEditorWorkspaceControllerEditorShellRuntimeEditorWindowFrameOrchestrator
这意味着当前 workspace window 仍然有一个 live mutable controller。它已经不是 authority,但也还不是完全只读 projection。
当前真实行为是:
EditorWorkspaceWindowContentController::UpdateAndAppend(...)会在 layout snapshot 发生变化时发出显式workspaceMutationrequest。EditorWorkspaceWindowContentController现在持有显式EditorWorkspaceWindowProjection,host 常规同步 / presentation 路径优先消费 projection refresh,而不是整体替换 live controller。EditorWindow::TryGetWorkspaceController()仍保留给局部交互 / 过渡路径使用,但它不再是常规 host 同步主接口。- 每个 workspace window 依然持有自己的一份 live
UIEditorWorkspaceController。
因此:
- 不要把当前架构写成“projection-only content controller 已完成”。
5. 窗口类别与内容控制器
当前窗口系统显式区分两类窗口:
EditorWindowCategory::WorkspaceEditorWindowCategory::Utility
两类窗口共享同一个 native host:
EditorWindow
-> EditorWindowRuntimeController
-> D3D12WindowRenderLoop
-> EditorWindowContentController
5.1 Workspace Window
workspace window 的内容控制器是 EditorWorkspaceWindowContentController。
它是完整 shell/workspace 容器,用于:
- 主窗口
- detached workspace window
5.2 Utility Window
utility window 的内容控制器是 EditorUtilityWindowContentController,内部承载 EditorUtilityWindowPanel。
当前 registry / factory 主线是显式 descriptor 驱动:
EditorUtilityWindowDescriptorEditorUtilityWindowReusePolicyEditorWindowChromePolicyEditorWindowNativeStylePolicy
当前已注册的 utility window:
ColorPickerAddComponent
两者当前都使用 SingleInstance 复用策略。
5.3 Capability 校验
窗口内容能力由 EditorWindowContentCapabilities 描述,EditorWindowHostRuntime::CreateEditorWindow(...) 在创建时做硬校验:
Workspace分类要求capabilities.workspace == trueUtility分类要求capabilities.utilityPanel == true
不要依赖“后续 coordinator 看到空 binding 再兜底”这种旧思路。
6. Frame Request 与每帧主线
EditorWindowFrameTransferRequests 当前按两个子域组织:
workspace:
workspaceMutation
beginGlobalTabDrag
detachPanel
utility:
openUtilityWindow
当前事实:
workspaceMutation已经是 frame 内 workspace 变化的显式回传入口。openUtilityWindow来自EditorContext::RequestOpenUtilityWindow(...),由EditorWindowFrameOrchestrator消费 request state 后写入 frame transfer request。- queued immediate frame 也按这两个子域分别合并。
steady-state frame 主路径是:
Application::Run
-> EditorWindowManager::RenderAllWindows
-> EditorWindowHostRuntime::RenderAllWindows
-> EditorWindowFrameDriver::DriveFrame
-> EditorWindowRuntimeController::UpdateAndAppend
-> EditorWindowContentController::UpdateAndAppend
-> EditorWindowWorkspaceCoordinator::RefreshWindowPresentation
-> EditorWindowWorkspaceCoordinator::HandleWindowFrameTransferRequests
-> EditorUtilityWindowCoordinator::HandleWindowFrameTransferRequests
另外,WM_PAINT、WM_SIZE、WM_DPICHANGED、WM_EXITSIZEMOVE 等消息也会触发 immediate frame,并在 message dispatcher 中 flush queued transfer requests。
7. 修改规范
- 先判断改动属于 framework、app semantics、windowing、Win32 host 还是 rendering host。
- 小改动优先贴近现有模式,不顺手做跨层重构。
- 新增通用 widget 放
editor/src/editor/include/XCEditor。 - 新增具体 editor 功能放
editor/app/Features/<FeatureName>,再由 composition 装配。 - 新增 utility window 先补
EditorUtilityWindowKind、EditorUtilityWindowDescriptor、CreateEditorUtilityWindowPanel(...),不要直接在 Win32 coordinator 里硬编码窗口类型。 - 新增跨窗口语义时,优先增加显式 frame request 或 app/windowing plan builder,不要回退到 Win32 host 直接读写 authority。
- 修改窗口同步逻辑时,区分“当前代码事实”和“长期目标”。当前还存在 live mutable projection,不要按尚未落地的终态直接删接口。
- 不要让
editor/include/XCEditor/**暴露App::*类型。 - draw append 只负责绘制,不顺手修改 scene / project / authority 状态。
8. 当前架构债务
当前仍然存在的主要债务:
- 除
XCUIEditorLib外,app core、windowing、Win32 host、rendering host 还没有真实拆成独立 target。 EditorContext仍然很重,混合了 shell asset、项目/场景运行时、selection、command focus、utility window request 和状态输出。EditorShellRuntime仍然很重,既负责 shell compose / interaction,也负责 hosted panel、viewport request 和 draw append。EditorWorkspaceWindowContentController仍持有 live mutableUIEditorWorkspaceController,只是 host 常规同步 / presentation 已经切到 projection refresh;projection 和 authority 的边界仍未完全硬化。EditorWindowWorkspaceCoordinator仍然过厚,还没有收缩成纯粹的 host executor + native event bridge。EditorWindow::TryGetWorkspaceController()仍存在于交互 / 过渡路径,说明 live projection 去状态化还没完成;但常规同步路径已经不再依赖ReplaceWorkspaceController()。
这些都是当前事实,不要在新的规范文档或代码注释里把它们写成“已经解决”。
9. 验证入口
当前 editor 相关验证入口统一在 tests/UI/Editor:
editor_ui_testsframework 和基础 UI 单元测试。editor_windowing_phase1_tests当前窗口 authority / planner / reconcile 规则的 focused unit tests。xcui_editor_app_smokeeditor 启动烟测。tests/UI/Editor/manual_validation复杂交互人工验证场景。
条件事实:
editor_app_feature_tests只会在XCUIEditorAppLib等可选 target 真实存在时创建。- 不要把它当成当前 checkout 一定存在的测试目标。
涉及窗口系统的改动,优先保持:
XCUIEditorApp可构建editor_windowing_phase1_tests不回退xcui_editor_app_smoke不回退
10. 推荐阅读入口
开始 editor 相关任务时,优先阅读:
editor/CMakeLists.txteditor/app/Bootstrap/Application.*editor/app/Composition/EditorContext.*editor/app/Composition/EditorShellRuntime.*editor/app/Windowing/Content/EditorWindowContentController.heditor/app/Windowing/Content/EditorWorkspaceWindowContentController.*editor/app/Windowing/Frame/EditorWindowFrameOrchestrator.*editor/app/Windowing/System/EditorWindowSystem.*editor/app/Platform/Win32/Windowing/EditorWindow.*editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.*editor/app/Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.*editor/app/Platform/Win32/Windowing/EditorUtilityWindowCoordinator.*editor/app/UtilityWindows/EditorUtilityWindowRegistry.*tests/UI/Editor/unit/CMakeLists.txttests/UI/Editor/smoke/CMakeLists.txt