124 lines
11 KiB
Markdown
124 lines
11 KiB
Markdown
# XCEditor Agent Guide
|
||
|
||
本文面向以后在 `editor/` 下工作的 coding agent / 开发者。若本文与代码、`CMakeLists.txt` 或测试目标冲突,以代码为准,并在同一次改动中更新本文。
|
||
|
||
## 长期目标
|
||
|
||
- `editor/` 是当前 XCUI 编辑器主线,不是旧 `mvs/editor` 或 `new_editor` 入口。长期方向是把可复用 UI shell 与产品编辑器装配继续分离清楚。
|
||
- `XCUIEditor` 保持为平台无关、后端无关的静态库。公共头在 `include/XCEditor/**`,实现主要在 `src/**`;不要放入 Win32、D3D12、DXGI、产品面板状态或工程 runtime 事实。
|
||
- `XCEditorCore` 承担产品编辑器核心。代码主要在 `app/Core`、`app/Composition`、`app/Features`、`app/Services`、`app/Windowing`,并通过 `XCEditorCoreRendering` 对象库接入 `app/Rendering`;它不直接拥有 Win32 消息循环。
|
||
- `XCEditor` 是可选 Win32 + D3D12 应用壳。代码在 `app/Bootstrap`、`app/Host/Win32`、`app/Host/D3D12`,负责窗口、DPI、消息分发、swapchain、UI 纹理和截图。
|
||
- 产品装配应以 `app/Core/Product/EditorProductManifest.*` 为单一事实源。正式 panel 集、action route、runtime owner、viewport renderer owner 先在 manifest 中声明,再派生 shell / menu / command / runtime / viewport 注册。
|
||
- UI widget / shell / workspace 代码优先保持 model/state/request/frame/result 风格。新增行为要能被 `tests/UI/Editor/unit` 以纯状态方式测试。
|
||
- scene/project 的用户操作应通过 runtime 或 command route 进入,不要在 draw/append 阶段直接改 scene 或文件系统。
|
||
- scene 渲染私有逻辑不要塞进 panel 或 shell。新增渲染能力时先判断它属于 engine `Rendering/RHI`、editor viewport pass bundle,还是 UI overlay。
|
||
- 资源路径、图标、shader、截图输出都应走明确服务或 host 接口。不要硬编码从当前工作目录猜路径;手动验证截图不得写回 source tree。
|
||
|
||
## 当前情况
|
||
|
||
- `editor/AGENTS.md` 本身被 `app/Bootstrap/Application.cpp` 的 `HasEditorRepoMarkers()` 用作仓库根定位标记之一。不要重命名、删除或移动它;如果根定位规则变了,同时更新本文。
|
||
- 顶层 `CMakeLists.txt` 默认启用 `XCENGINE_BUILD_XCUI_EDITOR_CORE` 和 `XCENGINE_BUILD_XCUI_EDITOR_APP`。构建 core/app 时必须启用 `XCENGINE_ENABLE_RENDERING_EDITOR_SUPPORT`。
|
||
- `XCEditor` 目标输出名是 `XCEngine.exe`,Debug 产物位于 `build/editor/Debug/XCEngine.exe`。
|
||
- 当前应用没有命令行项目选择流程;`EditorContext` 将项目根固定为 `<repoRoot>/project`,不要沿用旧文档里的 `--project <path>` 说法。
|
||
- 当前面板 ID 为 `hierarchy`、`scene`、`game`、`inspector`、`console`、`project`,由 `EditorProductManifest.*` 声明并驱动注册。
|
||
- 当前 `game` panel 是 viewport shell,但 renderer owner 是 placeholder,不是正式 Game runtime。它会显示 `Game view runtime is not implemented`,不要假设 Game view 已完整实现。
|
||
- 当前 command 事实:`file.exit` 已绑定退出;`edit.*` 通过 active route 分发到 hierarchy/project/scene/inspector;`assets.*` 通过 project route 分发;多数 `file.*`、`run.*`、`scripts.*`、`help.about` 仍只是菜单/命令 surface,未拥有完整 host owner。
|
||
- `EditorContext` 是产品级状态聚合点:`EditorSession`、project runtime、scene runtime、selection、command focus、utility window request、shortcut manager 和 host command bridge 都在这里串接。
|
||
- `UIEditorWorkspaceController` 管单窗口 workspace model/session;`EditorWindowSystem` 管多窗口 workspace set。跨窗口 detach、close、update 必须经过 synchronization plan。
|
||
- `EditorWorkspacePanelRuntimeSet` 托管产品面板生命周期。新增 panel 时先改 `EditorProductManifest.*`,再按需要调整 `BuildEditorWorkspaceModel()` 的默认布局和测试;不要再手工在 registry / menu / runtime set / viewport host 多处分别补定义。
|
||
- `EditorSelectionService` 是 hierarchy/project/inspector/scene viewport 之间的选择同步核心。不要在单个 panel 内维护另一套长期选择真相。
|
||
- `EditorProjectRuntime` 包装 `ProjectBrowserModel`,负责 project tree/grid、选择、文件操作、scene asset open request。文件系统改动后要刷新并 revalidate selection。
|
||
- `EditorSceneRuntime` 负责 startup scene、editor scene camera、hierarchy selection、component list、transform edit history 和 scene tool state。
|
||
|
||
当前目录地图:
|
||
|
||
- `include/XCEditor/Foundation`:命令注册/分发、快捷键、主题、文本测量接口、runtime trace。
|
||
- `include/XCEditor/Fields`:bool、number、text、enum、asset、object、color、vector、property grid 等编辑字段的绘制模型与交互。
|
||
- `include/XCEditor/Collections`:list/tree/tab/scroll/inline rename/drag-drop 等集合控件。
|
||
- `include/XCEditor/Docking`、`include/XCEditor/Workspace`:dock host、workspace tree、layout persistence、splitter correction、panel detach/transfer。
|
||
- `include/XCEditor/Shell`:menu/toolbar/status/workspace 的 shell 组合与交互入口。
|
||
- `include/XCEditor/Viewport`:viewport slot/shell/input bridge。这里是通用 UI viewport 容器,不是 scene renderer。
|
||
- `include/XCEditor/Windowing`:多窗口 workspace 状态、同步计划和 presentation policy。
|
||
- `src/**`:对应公共头的实现。保持偏纯函数/状态机风格。
|
||
- `app/Core`:产品级 contracts、session、command focus、selection、panel services、scene/project/viewport/windowing 接口。
|
||
- `app/Core/Product`:产品 manifest。这里定义正式 panel 集、route 归属、runtime owner 和 viewport renderer owner。
|
||
- `app/Composition`:装配编辑器 shell。`EditorContext` 拥有 session、project runtime、scene runtime、selection、command bridge;`EditorShellRuntime` 驱动 shell interaction、hosted panels 和 viewport runtime。
|
||
- `app/Features`:产品面板与场景视图工具。
|
||
- `app/Rendering`:编辑器 viewport、icon、object-id picking、grid/outline/helper pass 相关服务。渲染执行仍走 engine `Rendering + RHI`。
|
||
- `app/Host`:宿主接口实现。Win32/D3D12 细节只能待在这里或 rendering host 实现里。
|
||
- `app/Windowing`:窗口实例、内容控制器、生命周期协调器、workspace 多窗口同步、截图和 frame orchestration。
|
||
- `resources/Icons`、`resources/shaders/scene-viewport`:内置图标和 scene viewport shader。资源路径由 app/rendering 层解析。
|
||
|
||
当前启动和帧流程:
|
||
|
||
```text
|
||
wWinMain
|
||
-> RunXCEditor
|
||
-> Application::Initialize / Run
|
||
-> EditorContext::Initialize
|
||
-> BuildEditorApplicationShellAsset
|
||
-> EditorWindowSystem::BootstrapPrimaryWindow
|
||
-> EditorWindowManager::CreateWorkspaceWindow
|
||
-> EditorWindowRuntimeController
|
||
-> EditorWorkspaceWindowContentController
|
||
-> EditorShellRuntime::Update / Append / RenderRequestedViewports
|
||
```
|
||
|
||
- `Application::Run()` pump Win32 message,更新 `ResourceManager::UpdateAsyncLoads()`,然后让 `EditorWindowManager::RenderAllWindows()` 驱动所有窗口。
|
||
- `EditorWindowRuntimeController::BeginFrame()` 从 D3D12 runtime 取 `RenderContext`,content controller 先更新 shell 与 hosted panels,再 present UI draw data。
|
||
- `EditorShellInteractionEngine::Update()` 先 `BeginFrame()` 清空 viewport 请求,再运行 `UpdateUIEditorShellInteraction()`,最后把每个 viewport shell 的尺寸提交给 `EditorViewportRuntimeServices::RequestViewport()`。
|
||
- `EditorShellRuntime::RenderRequestedViewports()` 在 UI shell 更新后调用 viewport runtime,把 scene viewport 渲染进离屏纹理,再由 shell frame 展示。
|
||
|
||
当前 Scene Viewport 分层:
|
||
|
||
- `src/Viewport` 和 `include/XCEditor/Viewport`:viewport slot/shell/input bridge,只处理 UI 容器和输入桥。
|
||
- `app/Features/Scene/SceneViewportController.*`:场景视图产品交互,处理 Q/W/E/R 工具切换、F 聚焦、鼠标导航、scene icon picking、transform gizmo。
|
||
- `app/Core/Scene/EditorSceneRuntime.*`:scene selection、editor camera、transform undo/redo、component mutation 和 scene render request 的事实来源。
|
||
- `app/Rendering/Viewport/ViewportHostService.*`:离屏 viewport 资源管理和 renderer 注册。
|
||
- `app/Rendering/Viewport/SceneViewportRenderService.*`:调用 engine `SceneRenderer`,插入 grid、selection outline、selected helpers、object-id 等 editor pass。
|
||
- object-id picking 依赖有效 object-id surface 和 frame serial,修改时要覆盖 `test_viewport_object_id_picker.cpp` 及相关 viewport render plan 测试。
|
||
|
||
当前构建和验证入口:
|
||
|
||
```powershell
|
||
cmake --build build --config Debug --target XCUIEditor
|
||
cmake --build build --config Debug --target XCEditorCore
|
||
cmake --build build --config Debug --target XCEditor
|
||
cmake --build build --config Debug --target editor_ui_tests
|
||
cmake --build build --config Debug --target editor_app_core_tests
|
||
cmake --build build --config Debug --target editor_app_feature_tests
|
||
cmake --build build --config Debug --target editor_windowing_phase1_tests
|
||
cmake --build build --config Debug --target editor_ui_smoke_targets
|
||
cmake --build build --config Debug --target editor_ui_manual_validation_scenarios
|
||
```
|
||
|
||
```powershell
|
||
ctest --test-dir build -C Debug -R "editor|xceditor" --output-on-failure
|
||
```
|
||
|
||
- `XCUIEditor` widget/shell/workspace 改动:跑 `editor_ui_tests`、`editor_windowing_phase1_tests`。
|
||
- `app/Core`、project/scene/session/command 改动:跑 `editor_app_core_tests`。
|
||
- scene viewport、project panel、window input routing 改动:跑 `editor_app_feature_tests`。
|
||
- Win32/D3D12 host 或启动流程改动:跑 `editor_ui_smoke_targets`,必要时跑 `xceditor_smoke`。
|
||
- 手动 UI 场景:跑 `editor_ui_manual_validation_scenarios`。
|
||
|
||
有用环境变量:
|
||
|
||
- `XCUIEDITOR_SMOKE_TEST=1`:启用应用自退出 smoke 模式。
|
||
- `XCUIEDITOR_SMOKE_TEST_FRAME_LIMIT=<n>`:smoke 模式帧数上限。
|
||
- `XCUIEDITOR_SMOKE_TEST_DURATION_SECONDS=<n>`:smoke 模式持续时间。
|
||
- `XCUI_AUTO_CAPTURE_ON_STARTUP=1`:启动后自动截图。
|
||
|
||
## 过去执行
|
||
|
||
- 已把 editor 产品装配的 panel 声明收敛到 `app/Core/Product/EditorProductManifest.*`,并让 panel registry、View > Panels 菜单、panel 激活命令、action route、workspace runtime set 和 viewport renderer 注册从 manifest 派生。
|
||
- 已把 `game` panel 明确标成 placeholder viewport,而不是隐式共享 scene renderer 或假装 Game runtime 已完成。
|
||
- 已新增 manifest validation 测试,确保产品 manifest 能声明 panel runtime owner 和 viewport renderer owner,并覆盖 `game` placeholder 的预期状态。
|
||
- 已更新根 `AGENT.md` 和本文件,去掉旧 `--project` 说法,记录当前 XCUI editor、`XCEditorCore` 分层和 product manifest 规则。
|
||
- 本次改动验证过:
|
||
- `cmake --build build --config Debug --target XCEditor`
|
||
- `cmake --build build --config Debug --target editor_app_core_tests`
|
||
- `.\build\tests\UI\Editor\unit\Debug\editor_app_core_tests.exe --gtest_filter=EditorShellAssetValidationTest.*`
|
||
- `cmake --build build --config Debug --target editor_app_feature_tests`
|
||
- `.\build\tests\UI\Editor\unit\Debug\editor_app_feature_tests.exe`
|