2026-04-27 13:40:26 +08:00
|
|
|
# Editor Core Refactor Plan
|
|
|
|
|
|
|
|
|
|
## Goal
|
|
|
|
|
|
|
|
|
|
This refactor turns the current `editor/app` directory map from a documented
|
|
|
|
|
convention into a build-checked architecture.
|
|
|
|
|
|
|
|
|
|
The desired production shape is:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
XCUIEditor
|
|
|
|
|
reusable editor UI framework:
|
|
|
|
|
widgets, docking, shell, workspace, menu, viewport slots, field controls
|
|
|
|
|
|
|
|
|
|
XCEditorCore
|
|
|
|
|
editor product core:
|
|
|
|
|
composition, commands, state, project and scene services, feature panels,
|
|
|
|
|
window/workspace core, and host-facing contracts
|
|
|
|
|
|
|
|
|
|
XCEditor
|
|
|
|
|
thin executable host:
|
|
|
|
|
main, Win32 process/window host, D3D12 runtime host, resources, startup,
|
|
|
|
|
final object wiring
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`XCEditor` may keep the output name `XCEngine.exe`; the target name should
|
|
|
|
|
remain `XCEditor`.
|
|
|
|
|
|
|
|
|
|
## Current Problem
|
|
|
|
|
|
|
|
|
|
The reusable layer is mostly healthy:
|
|
|
|
|
|
|
|
|
|
- `editor/include/XCEditor/**` and `editor/src/**` form `XCUIEditor`.
|
|
|
|
|
- `XCUIEditor` is testable and mostly free of app, Win32, and D3D12 concerns.
|
|
|
|
|
|
2026-04-27 15:37:39 +08:00
|
|
|
The app layer has a good directory vocabulary but enforcement is still
|
|
|
|
|
incomplete:
|
2026-04-27 13:40:26 +08:00
|
|
|
|
2026-04-27 18:45:31 +08:00
|
|
|
- `XCEditorCore` now limits its public app include surface to
|
|
|
|
|
`editor/app/Core`, `editor/app/Commands`, `editor/app/State`, and
|
|
|
|
|
`editor/app/Host`, but the app still carries internal include-path residue
|
|
|
|
|
and has not yet converged on the final directory names.
|
|
|
|
|
- Feature panels no longer use `Composition/EditorContext.h` directly, but
|
|
|
|
|
app-core tests still need to be restored before the boundary is exercised
|
|
|
|
|
outside the executable host.
|
2026-04-27 13:40:26 +08:00
|
|
|
- App-side tests exist but are not consistently wired into CMake; some are
|
|
|
|
|
stale and reference removed headers.
|
|
|
|
|
|
2026-04-27 14:19:52 +08:00
|
|
|
Completed boundary cuts:
|
|
|
|
|
|
|
|
|
|
- Project service ownership has moved to `editor/app/Services/Project`.
|
|
|
|
|
`EditorProjectRuntime` depends on the service-owned `ProjectBrowserModel`,
|
|
|
|
|
and `Features/Project/ProjectPanel` owns the widget-tree projection.
|
2026-04-27 15:37:39 +08:00
|
|
|
- Panel IDs live under `editor/app/Core/Panels`, and workspace panel runtime
|
|
|
|
|
contracts live under `editor/app/Core/WorkspacePanels`.
|
|
|
|
|
- Shared window category, lifecycle, chrome-policy, and native-host-policy
|
|
|
|
|
contracts live under `editor/app/Core/Windowing`.
|
|
|
|
|
- Utility-window kinds, descriptors, and panel contracts live under
|
|
|
|
|
`editor/app/Core/UtilityWindows`; concrete Color Picker/Add Component panel
|
|
|
|
|
creation lives under `editor/app/Features/EditorUtilityWindowRegistry.*` and
|
|
|
|
|
is injected from `Application`.
|
2026-04-27 16:22:46 +08:00
|
|
|
- Panel-facing app services live under
|
|
|
|
|
`editor/app/Core/Panels/EditorPanelServices.h`. Workspace-panel and
|
|
|
|
|
utility-window runtime contracts accept this service view instead of
|
|
|
|
|
`EditorContext`, so concrete feature panels no longer depend on
|
|
|
|
|
`Composition/EditorContext.h`.
|
2026-04-27 17:17:29 +08:00
|
|
|
- Win32 now hands render startup a neutral
|
|
|
|
|
`Rendering::Host::EditorWindowRenderRuntimeSurface` value, and D3D12 no
|
|
|
|
|
longer includes `Platform/Win32/**` editor surface headers to obtain `HWND`.
|
2026-04-27 18:45:31 +08:00
|
|
|
- Neutral host-facing contracts now live under
|
|
|
|
|
`editor/app/Host/Interfaces`, including editor window host interfaces,
|
|
|
|
|
render-runtime contracts, texture/viewport host contracts, pointer-capture
|
|
|
|
|
contracts, and system interaction service interfaces.
|
|
|
|
|
- Shared window screen geometry, chrome metrics, and frame transfer requests
|
|
|
|
|
now live under `editor/app/Core/Windowing`, and
|
|
|
|
|
`XCEditorCore` no longer exports the whole `editor/app` root as a public
|
|
|
|
|
include directory.
|
2026-04-27 14:19:52 +08:00
|
|
|
|
2026-04-27 13:40:26 +08:00
|
|
|
The root issue is not the existence of a single executable target by itself.
|
2026-04-27 18:45:31 +08:00
|
|
|
The root issue was that shared app contracts were stored inside concrete layer
|
|
|
|
|
directories, and CMake exposed the whole `editor/app` include root through
|
|
|
|
|
`XCEditorCore` usage requirements. The public include surface has now been
|
|
|
|
|
narrowed; remaining work is to remove internal source compatibility with the
|
|
|
|
|
private app root and finish wiring app-core tests against the narrowed surface.
|
2026-04-27 13:40:26 +08:00
|
|
|
|
|
|
|
|
## Target Directory Shape
|
|
|
|
|
|
|
|
|
|
The refactor should converge on this shape:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
editor/app/
|
|
|
|
|
Core/
|
|
|
|
|
Commands/
|
|
|
|
|
Panels/
|
|
|
|
|
State/
|
|
|
|
|
UtilityWindows/
|
2026-04-27 15:37:39 +08:00
|
|
|
Windowing/
|
2026-04-27 13:40:26 +08:00
|
|
|
WorkspacePanels/
|
|
|
|
|
|
|
|
|
|
Services/
|
|
|
|
|
Project/
|
|
|
|
|
Scene/
|
|
|
|
|
|
|
|
|
|
Features/
|
|
|
|
|
Console/
|
|
|
|
|
ColorPicker/
|
|
|
|
|
Hierarchy/
|
|
|
|
|
Inspector/
|
|
|
|
|
Project/
|
|
|
|
|
Scene/
|
|
|
|
|
|
|
|
|
|
Windowing/
|
|
|
|
|
Content/
|
|
|
|
|
Coordinator/
|
|
|
|
|
Frame/
|
|
|
|
|
Host/
|
|
|
|
|
Runtime/
|
|
|
|
|
|
|
|
|
|
Host/
|
|
|
|
|
Interfaces/
|
|
|
|
|
Win32/
|
|
|
|
|
D3D12/
|
|
|
|
|
|
|
|
|
|
Bootstrap/
|
|
|
|
|
Support/
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This is a convergence target, not a requirement to move every file at once.
|
|
|
|
|
The first cut should only move contracts that are already acting as global app
|
|
|
|
|
interfaces.
|
|
|
|
|
|
|
|
|
|
## Dependency Rules
|
|
|
|
|
|
|
|
|
|
The final direction should be:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
XCEditor -> XCEditorCore -> XCUIEditor -> XCEngine
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Within `XCEditorCore`:
|
|
|
|
|
|
|
|
|
|
- `Composition` may depend on `Core`, `Services`, `Windowing` contracts, and
|
|
|
|
|
`XCUIEditor`.
|
|
|
|
|
- `Composition` must not include concrete feature panel headers.
|
|
|
|
|
- `Features` may depend on `Core`, `Services`, and `XCUIEditor`.
|
|
|
|
|
- `Services` must not depend on `Features`.
|
|
|
|
|
- `State` must not depend on `Composition`.
|
|
|
|
|
- `Windowing` may depend on `Core`, `Composition` interfaces, and
|
|
|
|
|
`XCUIEditor`, but must not include Win32 or D3D12 concrete host headers.
|
|
|
|
|
- Host contracts may live in `Core` or `Host/Interfaces`.
|
|
|
|
|
- Win32 and D3D12 concrete implementations live outside `XCEditorCore` unless
|
|
|
|
|
they are purely abstract host contracts.
|
|
|
|
|
|
|
|
|
|
## Phase 1: Fix Shared Contract Placement
|
|
|
|
|
|
|
|
|
|
Move the most obviously misplaced shared contracts first.
|
|
|
|
|
|
|
|
|
|
### 1. Panel IDs
|
|
|
|
|
|
|
|
|
|
Move:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
editor/app/Composition/EditorPanelIds.h
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
to:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
editor/app/Core/Panels/EditorPanelIds.h
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Then update all includes to use `Core/Panels/EditorPanelIds.h`.
|
|
|
|
|
|
|
|
|
|
Reason: panel IDs are global app model constants, not composition-private
|
|
|
|
|
implementation details.
|
|
|
|
|
|
|
|
|
|
### 2. Workspace Panel Runtime Contract
|
|
|
|
|
|
|
|
|
|
Split the existing workspace panel registry header:
|
|
|
|
|
|
|
|
|
|
Current:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
editor/app/Features/EditorWorkspacePanelRegistry.h
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Target:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
editor/app/Core/WorkspacePanels/EditorWorkspacePanelRuntime.h
|
|
|
|
|
editor/app/Features/EditorWorkspacePanelRegistry.h
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The new core header owns:
|
|
|
|
|
|
|
|
|
|
- `EditorWorkspacePanelCursorKind`
|
|
|
|
|
- `EditorWorkspacePanelUpdatePhase`
|
|
|
|
|
- `EditorWorkspacePanelFrameEvent`
|
|
|
|
|
- `EditorWorkspacePanelInitializationContext`
|
|
|
|
|
- `EditorWorkspacePanelShutdownContext`
|
|
|
|
|
- `EditorWorkspacePanelUpdateContext`
|
|
|
|
|
- `EditorWorkspacePanel`
|
|
|
|
|
- `EditorWorkspacePanelRuntimeSet`
|
|
|
|
|
|
|
|
|
|
The feature registry header owns only:
|
|
|
|
|
|
|
|
|
|
- `CreateEditorWorkspacePanelRuntimeSet()`
|
|
|
|
|
|
|
|
|
|
Reason: composition should depend on the panel runtime interface, not on the
|
|
|
|
|
feature registry. Concrete feature construction belongs to `Features`.
|
|
|
|
|
|
|
|
|
|
### 3. Keep the First Cut Buildable
|
|
|
|
|
|
|
|
|
|
This phase should not change behavior.
|
|
|
|
|
|
|
|
|
|
Expected behavioral diff: none.
|
|
|
|
|
|
|
|
|
|
Expected dependency improvement:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
Composition -> Core/WorkspacePanels
|
|
|
|
|
Features -> Core/WorkspacePanels
|
2026-04-27 16:22:46 +08:00
|
|
|
Features -> Core/Panels
|
2026-04-27 13:40:26 +08:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This does not fully solve all cycles, but it removes the worst misplaced public
|
|
|
|
|
contract and creates the landing zone for the next cut.
|
|
|
|
|
|
2026-04-27 16:22:46 +08:00
|
|
|
Completed follow-up:
|
|
|
|
|
|
|
|
|
|
- `EditorPanelServices` now carries the panel-facing references to session,
|
|
|
|
|
project runtime, scene runtime, command focus, color-picker state, system
|
|
|
|
|
interaction, text measurement, and utility-window requests.
|
|
|
|
|
- `EditorWorkspacePanelRuntimeSet` updates a single phase at a time; Composition
|
|
|
|
|
owns the command-focus sync point between main panels and after-focus panels.
|
|
|
|
|
- Concrete workspace and utility panels use `EditorPanelServices` and no longer
|
|
|
|
|
include `Composition/EditorContext.h`.
|
|
|
|
|
|
2026-04-27 13:40:26 +08:00
|
|
|
## Phase 2: Introduce XCEditorCore
|
|
|
|
|
|
|
|
|
|
Create:
|
|
|
|
|
|
|
|
|
|
```cmake
|
|
|
|
|
add_library(XCEditorCore STATIC ...)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Initial contents:
|
|
|
|
|
|
|
|
|
|
- `app/Core/**`
|
|
|
|
|
- `app/Commands/**`
|
|
|
|
|
- `app/Composition/**`
|
|
|
|
|
- `app/Features/**`
|
|
|
|
|
- `app/Project/**` or `app/Services/Project/**`
|
|
|
|
|
- `app/Scene/**` or `app/Services/Scene/**`
|
|
|
|
|
- `app/State/**`
|
2026-04-27 15:37:39 +08:00
|
|
|
- `app/Core/UtilityWindows/**`
|
|
|
|
|
- `app/Core/Windowing/**`
|
2026-04-27 13:40:26 +08:00
|
|
|
- `app/Windowing/**` core files that do not require Win32 or D3D12
|
|
|
|
|
- host-facing abstract interfaces
|
|
|
|
|
|
|
|
|
|
Keep in `XCEditor` executable:
|
|
|
|
|
|
|
|
|
|
- `app/main.cpp`
|
|
|
|
|
- `app/Bootstrap/Application.*`
|
|
|
|
|
- `app/Bootstrap/EditorApp.rc`
|
|
|
|
|
- `app/Platform/Win32/**`
|
|
|
|
|
- `app/Rendering/D3D12/**`
|
|
|
|
|
- any concrete host glue that includes `windows.h`
|
|
|
|
|
|
|
|
|
|
`XCEditor` links `XCEditorCore`, `XCUIEditor`, and concrete platform/rendering
|
|
|
|
|
libraries.
|
|
|
|
|
|
|
|
|
|
Important: do not hide Win32/D3D12 in `XCEditorCore` just to make the first
|
|
|
|
|
CMake edit easier. If a source file needs `windows.h`, it belongs in the host
|
|
|
|
|
side until a neutral interface exists.
|
|
|
|
|
|
|
|
|
|
## Phase 3: Restore App-Core Tests
|
|
|
|
|
|
|
|
|
|
Create or restore:
|
|
|
|
|
|
|
|
|
|
```cmake
|
|
|
|
|
editor_app_core_tests
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This target should link:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
XCEditorCore
|
|
|
|
|
GTest::gtest_main
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Start with tests that should not need Win32/D3D12:
|
|
|
|
|
|
|
|
|
|
- `test_editor_host_command_bridge.cpp`
|
|
|
|
|
- `test_editor_project_runtime.cpp`
|
|
|
|
|
- `test_editor_shell_asset_validation.cpp`
|
|
|
|
|
- `test_project_browser_model.cpp`
|
|
|
|
|
- `test_hierarchy_scene_binding.cpp`
|
|
|
|
|
- `test_inspector_presentation.cpp`
|
|
|
|
|
|
|
|
|
|
Then either fix or remove stale test references:
|
|
|
|
|
|
|
|
|
|
- `Ports/SystemInteractionPort.h`
|
|
|
|
|
- `Rendering/Viewport/ViewportRenderTargetInternal.h`
|
|
|
|
|
|
|
|
|
|
The test target is part of the architecture. If app core cannot be tested
|
|
|
|
|
without starting the executable host, the boundary is not real.
|
|
|
|
|
|
|
|
|
|
## Phase 4: Service and Feature Boundary Cleanup
|
|
|
|
|
|
|
|
|
|
After `XCEditorCore` exists, remove remaining service-to-feature dependencies.
|
|
|
|
|
|
|
|
|
|
### Project
|
|
|
|
|
|
2026-04-27 14:19:52 +08:00
|
|
|
Completed:
|
2026-04-27 13:40:26 +08:00
|
|
|
|
|
|
|
|
```text
|
2026-04-27 14:19:52 +08:00
|
|
|
Services/Project/EditorProjectRuntime.h -> Services/Project/ProjectBrowserModel.h
|
|
|
|
|
Features/Project/ProjectPanel.h -> Services/Project/EditorProjectRuntime.h
|
2026-04-27 13:40:26 +08:00
|
|
|
```
|
|
|
|
|
|
2026-04-27 14:19:52 +08:00
|
|
|
Current shape:
|
2026-04-27 13:40:26 +08:00
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
Services/Project/ProjectBrowserModel.h
|
|
|
|
|
Services/Project/EditorProjectRuntime.h
|
|
|
|
|
Features/Project/ProjectPanel.h
|
|
|
|
|
```
|
|
|
|
|
|
2026-04-27 14:19:52 +08:00
|
|
|
`ProjectBrowserModel` is now service-owned domain/project state. It exposes
|
|
|
|
|
folder, asset, and breadcrumb data, while `ProjectPanel` converts folders into
|
|
|
|
|
`UIEditorTreeViewItem` presentation data. Keep future project filesystem and
|
|
|
|
|
command-target behavior in `Services/Project`, not under `Features/Project`.
|
2026-04-27 13:40:26 +08:00
|
|
|
|
|
|
|
|
### Scene
|
|
|
|
|
|
|
|
|
|
Keep scene runtime as a service layer. Scene viewport feature code may use
|
|
|
|
|
scene services, but scene services should not depend on concrete feature UI.
|
|
|
|
|
|
|
|
|
|
### Utility Windows
|
|
|
|
|
|
2026-04-27 15:37:39 +08:00
|
|
|
Completed:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
UtilityWindows/EditorUtilityWindowKind.h
|
|
|
|
|
UtilityWindows/EditorUtilityWindowPanel.h
|
|
|
|
|
UtilityWindows/EditorUtilityWindowRegistry.*
|
|
|
|
|
-> Core/UtilityWindows/EditorUtilityWindowRuntime.h
|
|
|
|
|
-> Core/UtilityWindows/EditorUtilityWindowRegistry.*
|
|
|
|
|
-> Features/EditorUtilityWindowRegistry.*
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Current shape:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
Core/UtilityWindows/EditorUtilityWindowRuntime.h
|
|
|
|
|
Core/UtilityWindows/EditorUtilityWindowRegistry.*
|
|
|
|
|
Features/EditorUtilityWindowRegistry.*
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Keep utility kinds, descriptors, host context, panel contract, and factory
|
|
|
|
|
type in `Core/UtilityWindows`. Keep concrete utility panel construction in
|
|
|
|
|
`Features/EditorUtilityWindowRegistry.*` and inject it from the application
|
|
|
|
|
composition root. Windowing may resolve descriptors from Core, but must not
|
|
|
|
|
include Color Picker, Add Component, or other concrete feature-panel headers.
|
2026-04-27 13:40:26 +08:00
|
|
|
|
|
|
|
|
## Phase 5: Host Boundary Cleanup
|
|
|
|
|
|
|
|
|
|
Split neutral host contracts from concrete implementations.
|
|
|
|
|
|
|
|
|
|
Target:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
app/Host/Interfaces/
|
|
|
|
|
EditorWindowHostInterfaces.h
|
|
|
|
|
EditorWindowRenderRuntime.h
|
|
|
|
|
UiTextureHost.h
|
|
|
|
|
ViewportRenderHost.h
|
|
|
|
|
SystemInteractionService.h
|
|
|
|
|
|
|
|
|
|
app/Host/Win32/
|
|
|
|
|
Win32SystemInteractionHost.*
|
|
|
|
|
EditorWindow.*
|
|
|
|
|
message dispatch, DPI, chrome, pointer capture
|
|
|
|
|
|
|
|
|
|
app/Host/D3D12/
|
|
|
|
|
D3D12EditorWindowRenderRuntime.*
|
|
|
|
|
D3D12 UI renderer, texture host, text system, swap chain presenter
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Then replace concrete Win32/D3D12 cross-includes with a neutral surface or
|
|
|
|
|
factory contract.
|
|
|
|
|
|
2026-04-27 18:45:31 +08:00
|
|
|
Completed cuts:
|
2026-04-27 17:17:29 +08:00
|
|
|
|
|
|
|
|
- The old `Win32EditorWindowRenderRuntimeSurface` concrete adapter was removed.
|
|
|
|
|
- `EditorWindowRenderRuntimeSurface` is now a value contract in
|
2026-04-27 18:45:31 +08:00
|
|
|
`Host/Interfaces/EditorWindowRenderRuntime.h`.
|
2026-04-27 17:17:29 +08:00
|
|
|
- Win32 fills that neutral contract during native surface capture; D3D12 reads
|
|
|
|
|
the native handle from the contract instead of including a Win32 editor
|
|
|
|
|
windowing header.
|
2026-04-27 18:45:31 +08:00
|
|
|
- Neutral host-facing contracts now live under `app/Host/Interfaces/`.
|
|
|
|
|
- `EditorWindowTransferRequests`, window screen geometry, and title-bar chrome
|
|
|
|
|
metrics now live under `app/Core/Windowing/`.
|
|
|
|
|
- `XCEditorCore` now keeps `editor/app` as a private implementation include
|
|
|
|
|
root while exposing only `app/Core`, `app/Commands`, `app/State`, and
|
|
|
|
|
`app/Host` through its public usage requirements.
|
|
|
|
|
- Remaining work in this phase is to continue converging concrete host code on
|
|
|
|
|
the `app/Host/Win32` and `app/Host/D3D12` directory shape.
|
2026-04-27 17:17:29 +08:00
|
|
|
|
2026-04-27 13:40:26 +08:00
|
|
|
## Phase 6: Documentation Update
|
|
|
|
|
|
|
|
|
|
Update `editor/AGENTS.md` after each completed boundary cut.
|
|
|
|
|
|
|
|
|
|
Required changes:
|
|
|
|
|
|
|
|
|
|
- production target shape becomes `XCUIEditor`, `XCEditorCore`, `XCEditor`
|
|
|
|
|
- `Core` owns shared app contracts
|
|
|
|
|
- `Features/EditorWorkspacePanelRegistry.*` owns concrete feature factories
|
|
|
|
|
- app tests link `XCEditorCore`
|
|
|
|
|
- no new app code should add direct `Composition <-> Features` cycles
|
|
|
|
|
|
|
|
|
|
## Validation
|
|
|
|
|
|
|
|
|
|
Run these after each phase where possible:
|
|
|
|
|
|
|
|
|
|
```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
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
When app smoke is available:
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
ctest -C Debug -R xceditor_smoke --output-on-failure
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
If `XCEditorCore` does not exist yet, skip that target until Phase 2 lands.
|
|
|
|
|
|
|
|
|
|
## Done Criteria
|
|
|
|
|
|
|
|
|
|
The refactor is complete when:
|
|
|
|
|
|
|
|
|
|
- `XCEditorCore.lib` exists and is linked by `XCEditor`.
|
|
|
|
|
- `XCEditor` executable source is limited to host startup and concrete
|
|
|
|
|
platform/render backend wiring.
|
|
|
|
|
- `Composition` no longer includes concrete feature panel headers.
|
|
|
|
|
- `Services` no longer include `Features/**`.
|
|
|
|
|
- Win32 and D3D12 communicate through neutral host/render contracts.
|
|
|
|
|
- app-core tests are wired into CMake and build without running the executable.
|
|
|
|
|
- `editor/AGENTS.md` describes the new target shape and directory rules.
|
|
|
|
|
|