201 lines
9.8 KiB
Markdown
201 lines
9.8 KiB
Markdown
# Editor Agent Guide
|
|
|
|
This file is for agents working in `editor/**` and `tests/UI/Editor/**`.
|
|
Treat the current code and tests as source of truth. If this guide drifts from
|
|
the checkout, update it in the same change.
|
|
|
|
## Current Priority
|
|
|
|
The editor is not in a "split more layers for their own sake" phase.
|
|
|
|
The primary product line is still runtime/product loop closure:
|
|
|
|
- extend the bound `EditorRuntimeCoordinator` instead of adding panel-local
|
|
shortcuts for `run.*`, scene document commands, or project scene opens
|
|
- keep play mode transactional: `EditorRuntimeCoordinator` must enter play
|
|
through `EditorSceneRuntime::BeginPlaySession`, and `RuntimeLoop` must run
|
|
the play-session runtime scene rather than the editable document scene
|
|
- drive `EditorRuntimeCoordinator` from the app frame pump exactly once per
|
|
outer frame; do not tick runtime from per-window shell/content update paths
|
|
- keep `scripts.*` coordinator-owned and capability-driven. `scripts.rebuild`
|
|
must evaluate/dispatch through the bound scripting runtime service and expose
|
|
the real availability/failure message rather than a hardcoded stub
|
|
- keep `Game`, `Scene`, `Inspector`, `Selection`, and `Console` coherent across
|
|
runtime transitions
|
|
|
|
Do not burn time on broad architectural churn unless it directly unlocks that
|
|
product loop or removes an active architectural hazard.
|
|
|
|
## Engine Boundary Status
|
|
|
|
The old public `EditorEngineServices` god interface is gone.
|
|
|
|
The current editor-to-engine boundaries are narrow and must stay narrow:
|
|
|
|
- `EditorSceneBackendFactory`
|
|
- `SceneViewportEngineBridge`
|
|
- `GameViewportEngineBridge`
|
|
- `EditorShaderProvider`
|
|
- `EditorEngineLifecycle`
|
|
|
|
`EngineEditorComposition` in `editor/app/Services/Engine/EngineEditorServices.*`
|
|
is an internal composition root that hands out those narrow interfaces. It is
|
|
not a new shared facade for features to depend on.
|
|
|
|
Rules:
|
|
|
|
- do not recreate `EditorEngineServices`
|
|
- do not add a replacement god interface under a different name
|
|
- do not make new panels, passes, or runtimes depend on a catch-all engine
|
|
service locator
|
|
- keep render-pass dependencies low-level: passes may depend on
|
|
`EditorShaderProvider`, not on scene backend creation or lifecycle code
|
|
- composition owns assembly; features and passes must receive explicit
|
|
dependencies
|
|
|
|
## Product Truths
|
|
|
|
- `GameViewportFeature`, `GameViewportRenderService`, and related tests exist.
|
|
`EditorRuntimeCoordinator` is now the app-level owner for play-mode command
|
|
routing and uses `RuntimeLoop` for the active play-session scene.
|
|
- Play mode is a scene transaction. The engine scene backend snapshots the
|
|
editable scene, replaces it with a runtime scene for play/step, and restores
|
|
the editable scene when the play session ends. Do not start runtime playback
|
|
directly from `EditorSceneRuntime::GetActiveScene()`.
|
|
- `EditorHostCommandBridge` delegates `file.*`, `run.*`, and `scripts.*` to a
|
|
bound runtime owner. If no owner is bound, it must continue exposing honest
|
|
disabled messages.
|
|
- host-command context is workspace-shell local, not editor-global. The active
|
|
panel fallback and command-focus resolution must come from the current
|
|
`UIEditorWorkspaceController` plus that shell's
|
|
`EditorCommandFocusService`. Do not put window-local command routing back on
|
|
`EditorSession`, `EditorContext`, or any app-global bridge/shortcut manager.
|
|
- `EditorSceneRuntime` owns raw scene editing behavior and scene mutations. It
|
|
may return transient startup/open/new results, but it must not own the live
|
|
scene document state. Scene viewport private state now lives in
|
|
`SceneViewportSession`, owned by the scene viewport feature/panel instance,
|
|
not by `EditorContext`, `EditorFrameServices`, or the shared scene runtime.
|
|
`EditorSceneRuntime` also owns the unified scene-edit transaction/history
|
|
layer: hierarchy edits, inspector mutations, and scene gizmo commits must all
|
|
flow through the same backend snapshot-based undo/redo path rather than
|
|
panel-local or transform-only history. `EditorRuntimeCoordinator` owns scene
|
|
document state: current path/name, dirty flag, new/open/save routing, and
|
|
runtime-mode transitions.
|
|
- `EditorRuntimeCoordinator` time advancement is app-owned. It must tick once
|
|
per outer application frame before window rendering, not once per workspace
|
|
window or once per shell update.
|
|
- `ProjectPanel` may identify an openable scene asset, but scene document loading
|
|
must go through the bound typed scene-open request callback and the
|
|
coordinator. Do not reintroduce `ProjectRuntime` pending-open queues.
|
|
- `scripts.rebuild` is coordinator-owned and routes through the bound
|
|
scripting-runtime service. Keep its evaluation/dispatch honest: expose the
|
|
live capability/failure message from that service rather than a hardcoded
|
|
placeholder.
|
|
- the old shared `EditorPanelServices` dependency bag is gone. Workspace and
|
|
utility panels now receive explicit bindings or panel-local contexts; do not
|
|
recreate a catch-all mutable panel service bundle under a new name
|
|
- `EditorFrameServices` remains a window/content orchestration boundary. It must
|
|
stay on the window/content and shell-orchestration seam only. It must not be
|
|
passed through the workspace-panel seam or the utility-window panel seam as a
|
|
generic dependency source; workspace panels and utility panels should receive
|
|
explicit panel-local bindings or typed callbacks instead. Runtime time-step
|
|
ownership does not belong on this interface. Command routing ownership also
|
|
does not belong on this interface: do not add host-command bridge bindings,
|
|
command-focus syncing, or active-route/session transport back to
|
|
`EditorFrameServices`.
|
|
|
|
## Working Rules
|
|
|
|
- prefer explicit owner/coordinator/runtime-service seams over direct panel to
|
|
engine hookups
|
|
- keep panel dependencies explicit. If a panel needs more data or actions, add a
|
|
narrow panel-local context or binding instead of routing everything through a
|
|
generic shared services struct
|
|
- keep utility-window dependencies explicit. Color picker, add-component, and
|
|
future utility panels must be constructed with the exact runtime/tool state
|
|
they use; do not make utility panel update paths depend on
|
|
`EditorFrameServices`
|
|
- keep command routing shell-local. `UIEditorShortcutManager`,
|
|
`EditorHostCommandBridge`, and `EditorCommandFocusService` must be owned by
|
|
the workspace shell/runtime set that serves one window. If a command needs
|
|
active-panel context, pass the current `UIEditorWorkspaceController`; do not
|
|
mirror that context into `EditorSession`
|
|
- keep viewport-local state local. Camera/tool mode/pivot/space state for Scene
|
|
belongs in `SceneViewportSession` on the feature/controller side; do not push
|
|
it back into shared runtime/context/frame-service layers for convenience
|
|
- do not reintroduce `void*` plus callback-function panel hooks for scene-open
|
|
or utility-window requests; use typed callbacks or explicit requester
|
|
interfaces instead
|
|
- when changing runtime or document flow, inspect `EditorSession`,
|
|
`EditorRuntimeCoordinator`, `EditorHostCommandBridge`, the relevant feature,
|
|
and the matching tests
|
|
- if a change affects ownership, state flow, or command routing, add or update
|
|
tests in `tests/UI/Editor/unit`
|
|
- keep multi-window work behind runtime/document correctness; do not move it
|
|
ahead of core ownership closure
|
|
|
|
## Do Not Regress
|
|
|
|
- no new service-locator style editor-to-engine dependency
|
|
- no new low-level render pass dependency on scene backend creation or lifecycle
|
|
- no silent fallback where a command should fail honestly
|
|
- no panel-local shortcut that bypasses the intended runtime owner
|
|
- no new shared mutable panel-services bag or service-locator style panel
|
|
dependency bundle
|
|
- no `EditorFrameServices` tunneling into workspace-panel update/prepare paths
|
|
- no `EditorFrameServices` tunneling into utility-window panel update paths
|
|
- no global host-command bridge or global shortcut manager shared across editor
|
|
windows
|
|
- no `EditorSession.activePanelId`, `EditorSession.activeRoute`, or equivalent
|
|
session mirrors for per-window command context
|
|
- no per-window or per-shell runtime ticking path; runtime must not advance once
|
|
per workspace window
|
|
- no new live scene document metadata on `EditorSceneRuntime`; coordinator
|
|
remains the single owner for current path/name/dirty state
|
|
- no new path where Scene viewport render requests or camera/tool state are
|
|
recomputed from `EditorContext` instead of the owning `SceneViewportSession`
|
|
- no scene-open side channel in `EditorProjectRuntime`; project UI must call the
|
|
panel service request hook
|
|
- no play-mode path that mutates the editable scene in place or skips
|
|
`EditorScenePlaySession`
|
|
- no new transform-only or panel-local scene undo stack; all scene mutations
|
|
must record through `EditorSceneRuntime`'s unified snapshot transaction
|
|
history
|
|
|
|
## Good Entry Points
|
|
|
|
- `editor/app/Bootstrap/Application.cpp`
|
|
- `editor/app/Composition/EditorContext.cpp`
|
|
- `editor/app/Composition/EditorShellRuntime.cpp`
|
|
- `editor/app/Services/Runtime/EditorRuntimeCoordinator.cpp`
|
|
- `editor/app/Rendering/Viewport/ViewportHostService.cpp`
|
|
- `editor/app/Services/Engine/EngineEditorServices.h`
|
|
- `editor/app/Services/Scene/EditorSceneRuntime.cpp`
|
|
- `editor/app/Core/Commands/EditorHostCommandBridge.cpp`
|
|
- `docs/plan/editor-next-stage-runtime-plan.md`
|
|
- `docs/plan/editor-engine-services-refactor-plan.md`
|
|
|
|
## Verification
|
|
|
|
Minimum verification for editor app/core changes:
|
|
|
|
```powershell
|
|
cmake --build build --config Debug --target editor_app_core_tests
|
|
cmake --build build --config Debug --target editor_app_feature_tests
|
|
```
|
|
|
|
When the executable path is affected, also rebuild:
|
|
|
|
```powershell
|
|
cmake --build build --config Debug --target XCEditor
|
|
```
|
|
|
|
Relevant focused tests include:
|
|
|
|
- `test_editor_host_command_bridge.cpp`
|
|
- `test_editor_runtime_coordinator.cpp`
|
|
- `test_game_viewport_runtime.cpp`
|
|
- `test_project_panel.cpp`
|
|
- `test_scene_viewport_render_plan.cpp`
|
|
- `test_scene_viewport_runtime.cpp`
|