275 lines
12 KiB
Markdown
275 lines
12 KiB
Markdown
# XCUI Editor Agent Guide
|
||
|
||
This file documents the current editor architecture for agents working under
|
||
`editor/`. It describes the code that exists in this checkout, not a desired
|
||
future shape.
|
||
|
||
If this file conflicts with the current code, `editor/CMakeLists.txt`, or the
|
||
real directory tree, trust the code and update this file in the same change.
|
||
|
||
## Build Shape
|
||
|
||
The important production targets are:
|
||
|
||
- `XCUIEditorLib`: reusable XCEditor framework code from `editor/src` and
|
||
`editor/include/XCEditor`, including the reusable window authority,
|
||
synchronization planner, and presentation projection under
|
||
`XCEditor/Windowing`.
|
||
- `XCUIEditorAppWindowing`: app-internal static library for the current
|
||
host contracts, content controllers, coordinators, frame transfer flow, and
|
||
window manager.
|
||
- `XCUIEditorApp`: concrete editor executable. Its output name is `XCEngine`.
|
||
|
||
Do not invent target boundaries that are not present in `editor/CMakeLists.txt`.
|
||
Names such as `XCUIEditorAppCore`, `XCUIEditorAppLib`, and `XCUIEditorHost`
|
||
are not current production library boundaries in this checkout.
|
||
|
||
There is now a narrow public `editor/include/XCEditor/Windowing` layer for the
|
||
generic window authority model, synchronization plan/planner, and presentation
|
||
projection. App-specific window orchestration remains under
|
||
`editor/app/Windowing`, and the concrete Win32 host remains under
|
||
`editor/app/Platform/Win32`.
|
||
|
||
## Layering
|
||
|
||
Use these ownership boundaries when changing code:
|
||
|
||
- `editor/include/XCEditor` and `editor/src`: reusable editor framework.
|
||
Keep this layer independent from app state, Win32, D3D12 host code, and
|
||
`App::*` types.
|
||
- `editor/include/XCEditor/Windowing` and `editor/src/Windowing`: reusable
|
||
window authority, validation, synchronization planning, commit, and
|
||
presentation projection. Keep this layer generic and free of app content,
|
||
host runtime, native platform, and rendering details.
|
||
- `editor/app/Composition`, `Commands`, `Features`, `Project`, `Scene`,
|
||
`State`, `System`, `UtilityWindows`: editor product semantics.
|
||
- `editor/app/Windowing/Content`, `Coordinator`, `Frame`, `Host`: platform
|
||
neutral app window orchestration.
|
||
- `editor/app/Platform/Win32`: native window, message dispatch, input,
|
||
lifecycle, chrome, and concrete host runtime.
|
||
- `editor/app/Rendering`: editor rendering host and D3D12 integration.
|
||
|
||
The semantic dependency direction should remain:
|
||
|
||
```text
|
||
XCEditor framework
|
||
<- editor app semantics
|
||
<- app windowing runtime
|
||
<- Win32 host / rendering host
|
||
```
|
||
|
||
## Startup Flow
|
||
|
||
The application starts through:
|
||
|
||
```text
|
||
app/main.cpp
|
||
-> RunXCUIEditorApp
|
||
-> Application::Run
|
||
-> Application::Initialize
|
||
```
|
||
|
||
The primary workspace window is initialized through:
|
||
|
||
```text
|
||
EditorContext::BuildWorkspaceController()
|
||
-> EditorWindowSystem::BootstrapPrimaryWindow(...)
|
||
-> EditorWindowManager::CreateWorkspaceWindow(...)
|
||
-> EditorWindowContentFactory::CreateWorkspaceContentController(...)
|
||
-> EditorWindowHostRuntime::CreateHostWindow(...)
|
||
```
|
||
|
||
Keep authoritative window bootstrap in `EditorWindowSystem`; do not move it
|
||
back into the Win32 host.
|
||
|
||
## Window Authority Model
|
||
|
||
`EditorWindowSystem` owns the authoritative `UIEditorWindowWorkspaceSet` through
|
||
`EditorWindowWorkspaceStore`.
|
||
|
||
Normal per-frame workspace edits now use direct writes into that authoritative
|
||
state:
|
||
|
||
```text
|
||
EditorWorkspaceWindowContentController::UpdateAndAppend(...)
|
||
-> EditorWindowSystem::TryBuildLiveWindowWorkspaceController(windowId, ...)
|
||
-> UIEditorWorkspaceController::BindToState(...)
|
||
-> workspace operations mutate the bound authoritative workspace/session
|
||
```
|
||
|
||
The old normal path is obsolete:
|
||
|
||
```text
|
||
snapshot diff
|
||
-> workspaceMutation frame request
|
||
-> coordinator
|
||
-> synchronization plan
|
||
-> commit
|
||
```
|
||
|
||
Do not reintroduce `workspaceMutation` as the steady-state route for ordinary
|
||
layout, tab, visibility, or active-panel edits inside an existing workspace
|
||
window.
|
||
|
||
Cross-window create, update, close, and destroyed-window reconciliation still
|
||
use the planner/coordinator flow:
|
||
|
||
```text
|
||
target UIEditorWindowWorkspaceSet
|
||
-> EditorWindowSystem::BuildPlanForWindowSet(...)
|
||
-> EditorWindowWorkspaceCoordinator::ApplySynchronizationPlan(...)
|
||
-> EditorWindowSystem::CommitSynchronizationPlan(...)
|
||
```
|
||
|
||
`EditorWindowWorkspaceCoordinator::RefreshWindowPresentation(...)` refreshes
|
||
each workspace window projection from authoritative state. Presentation should
|
||
follow authority; it should not become a second source of truth.
|
||
|
||
## Frame Transfer Requests
|
||
|
||
`EditorWindowFrameTransferRequests` is only for host-side or cross-window side
|
||
effects that cannot be represented as direct in-window workspace edits.
|
||
|
||
Current request fields are:
|
||
|
||
- `workspace.beginGlobalTabDrag`
|
||
- `workspace.detachPanel`
|
||
- `utility.openUtilityWindow`
|
||
|
||
There is no `workspace.workspaceMutation` field in the current frame transfer
|
||
contract. Treat any doc, comment, or test name that says otherwise as stale.
|
||
|
||
## Window Categories
|
||
|
||
Workspace and utility windows share the native host path but use distinct
|
||
content controllers.
|
||
|
||
- Workspace windows use `EditorWorkspaceWindowContentController`.
|
||
- Utility windows use `EditorUtilityWindowContentController`.
|
||
- App windowing creates content through `EditorWindowContentFactory`.
|
||
- The concrete host validates `EditorWindowContentCapabilities` when a native
|
||
host window is created.
|
||
|
||
Utility windows are descriptor driven through `EditorUtilityWindowDescriptor`,
|
||
`EditorUtilityWindowRegistry`, and `CreateEditorUtilityWindowPanel(...)`.
|
||
Register new utility windows there rather than hard-coding them in Win32 host
|
||
logic.
|
||
|
||
## Modification Rules
|
||
|
||
- First decide whether the change belongs to XCEditor framework, app semantics,
|
||
app windowing, Win32 host, or rendering host.
|
||
- Keep public framework headers free of `App::*`, Win32, and D3D12 host types.
|
||
- Do not add `editor/app` as an include directory for `XCUIEditorLib`.
|
||
App-only services must cross into framework code through framework-owned
|
||
interfaces and app-side adapters.
|
||
- Do not compile `${XCUI_EDITOR_SHARED_SOURCES}` directly into `XCUIEditorApp`;
|
||
the executable should consume shared framework code through `XCUIEditorLib`.
|
||
- Use `editor/include/XCEditor/Windowing` and `editor/src/Windowing` for
|
||
generic window authority, synchronization, validation, and presentation
|
||
projection.
|
||
- Use `editor/app/Windowing` for app-specific window runtime semantics,
|
||
content, frame transfer, host contracts, and coordinators.
|
||
- Use `editor/app/Platform/Win32` only for native host behavior and message
|
||
integration.
|
||
- Do not let `editor/app/Windowing` include `Platform/Win32` or D3D12 concrete
|
||
host headers.
|
||
- Do not let Win32 host code create workspace or utility content directly.
|
||
It should receive content through the app-windowing host contract.
|
||
- Use direct authoritative workspace binding for ordinary in-window workspace
|
||
mutations.
|
||
- Use synchronization plans for operations that create, close, replace, or
|
||
reconcile workspace windows.
|
||
- Use frame transfer requests only for host-side or cross-window effects.
|
||
|
||
## Current Architecture Debt
|
||
|
||
The highest-value windowing boundary has been hardened: `XCUIEditorLib` now
|
||
owns the reusable window authority, synchronization planner, workspace store,
|
||
and presentation projection under `XCEditor/Windowing`. `XCUIEditorAppWindowing`
|
||
owns the app-internal content controller factory, coordinators, frame transfer
|
||
flow, host contracts, and manager. The Win32 host is the concrete native
|
||
adapter and creates native host windows from content supplied by app windowing.
|
||
|
||
The framework/app compile boundary is also enforced. `XCUIEditorLib` does not
|
||
receive `editor/app` includes, and `XCUIEditorApp` does not directly compile
|
||
the shared framework sources. When framework UI code needs app-provided data
|
||
such as loaded icons, expose a framework-owned interface and adapt it in app
|
||
composition code.
|
||
|
||
The main remaining debt is promotion discipline around the app runtime surface.
|
||
`XCUIEditorAppWindowing` is still app-internal and may depend on app semantics
|
||
such as `EditorContext`, `EditorShellRuntime`, utility window descriptors, and
|
||
product-specific content. Do not promote host interfaces, frame transfer, or
|
||
content controllers to `XCEditor` until they are generic enough to expose.
|
||
|
||
## Validation
|
||
|
||
Default editor validation is only the app build plus the 12-second smoke run:
|
||
|
||
```powershell
|
||
cmake --build build --config Debug --target editor_ui_smoke_targets
|
||
build\tests\UI\Editor\smoke\Debug\editor_ui_smoke_runner.exe build\editor\Debug\XCEngine.exe
|
||
```
|
||
|
||
Do not run `editor_windowing_phase1_tests`, `editor_ui_tests`, or broader test
|
||
targets by default. Run them only when the user explicitly asks for them or a
|
||
separate targeted change makes them necessary.
|
||
|
||
The runner sets `XCUIEDITOR_SMOKE_TEST_DURATION_SECONDS=12`, waits for the
|
||
editor to launch, lets the app auto-exit, and treats a clean editor exit as
|
||
success.
|
||
|
||
## Recommended Reading
|
||
|
||
Start with these files for editor/windowing work:
|
||
|
||
- `editor/CMakeLists.txt`
|
||
- `editor/app/Bootstrap/Application.*`
|
||
- `editor/app/Composition/EditorContext.*`
|
||
- `editor/app/Composition/EditorShellRuntime.*`
|
||
- `editor/include/XCEditor/Workspace/UIEditorWorkspaceController.h`
|
||
- `editor/src/Workspace/UIEditorWorkspaceController.cpp`
|
||
- `editor/include/XCEditor/Windowing/System/EditorWindowSystem.h`
|
||
- `editor/include/XCEditor/Windowing/System/EditorWindowSynchronizationPlan.h`
|
||
- `editor/include/XCEditor/Windowing/System/EditorWindowSynchronizationPlanner.h`
|
||
- `editor/include/XCEditor/Windowing/Presentation/EditorWorkspaceWindowProjection.h`
|
||
- `editor/include/XCEditor/Windowing/Presentation/EditorWindowPresentationPolicy.h`
|
||
- `editor/src/Windowing/System/EditorWindowSystem.cpp`
|
||
- `editor/src/Windowing/System/EditorWindowWorkspaceStore.*`
|
||
- `editor/src/Windowing/System/EditorWindowSynchronizationPlanner.cpp`
|
||
- `editor/src/Windowing/Presentation/EditorWindowPresentationPolicy.cpp`
|
||
- `editor/app/Windowing/Host/EditorWindowHostInterfaces.h`
|
||
- `editor/app/Windowing/Content/EditorWindowContentController.h`
|
||
- `editor/app/Windowing/Content/EditorWindowContentFactory.*`
|
||
- `editor/app/Windowing/Content/EditorWorkspaceWindowContentController.*`
|
||
- `editor/app/Windowing/Frame/EditorWindowFrameOrchestrator.*`
|
||
- `editor/app/Windowing/Frame/EditorWindowTransferRequests.h`
|
||
- `editor/app/Windowing/Coordinator/EditorWindowWorkspaceCoordinator.*`
|
||
- `editor/app/Windowing/Coordinator/EditorUtilityWindowCoordinator.*`
|
||
- `editor/app/Windowing/EditorWindowManager.*`
|
||
- `editor/app/Platform/Win32/Windowing/EditorWindow.*`
|
||
- `editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.*`
|
||
- `editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.*`
|
||
- `tests/UI/Editor/smoke/CMakeLists.txt`
|
||
|
||
## 前面几刀
|
||
|
||
- 最近一刀封死 framework -> app 的反向依赖:`UIEditorShellCompose`
|
||
不再认识 `App::BuiltInIcons`,改由 `UIEditorShellIconResolver` 抽象取图标,
|
||
app 在 `EditorShellDrawComposer` 里用 adapter 连接 `BuiltInIcons`。
|
||
- 同一刀收紧构建边界:`XCUIEditorLib` 不再拥有 `editor/app` include,
|
||
`XCUIEditorApp` 不再直接编译 `${XCUI_EDITOR_SHARED_SOURCES}`,也不再把
|
||
`editor/src` 加进 include;app 通过 `XCUIEditorLib` 消费 framework。
|
||
- 前一刀把窗口权威核心切到 framework:`EditorWindowSystem`、同步计划/规划器、
|
||
workspace store 和 presentation projection 位于 `editor/include/XCEditor/Windowing`
|
||
与 `editor/src/Windowing`。
|
||
- `editor/app/Windowing` 保留 app-specific 的 content controllers、coordinators、
|
||
frame transfer、host contracts 和 `EditorWindowManager`;Win32 host 仍只做
|
||
native adapter。
|
||
- 未提升到 `XCEditor` 的内容包括 `EditorContext`、`EditorShellRuntime`、utility
|
||
descriptors/panels、host interfaces、content controllers、coordinators、
|
||
frame transfer 和 Win32/D3D12 host。
|
||
- 默认验证也收口:只构建 `XCUIEditorApp` 相关 smoke 目标并跑 12 秒 smoke;
|
||
需要专项覆盖时再单独运行 windowing/unit targets。
|