Files
XCEngine/editor/AGENTS.md

16 KiB
Raw Blame History

XCEditor Agent Guide

本文面向以后在 editor/ 下工作的 coding agent / 开发者。若本文与代码、CMakeLists.txt 或测试目标冲突,以代码为准,并在同一次改动中更新本文。

长期目标

  • editor/ 是当前 XCUI 编辑器主线,不是旧 mvs/editornew_editor 入口。长期方向是把可复用 UI shell 与产品编辑器装配继续分离清楚。
  • XCUIEditor 保持为平台无关、后端无关的静态库。公共头在 include/XCEditor/**,实现主要在 src/**;不要放入 Win32、D3D12、DXGI、产品面板状态或工程 runtime 事实。
  • XCEditorCore 承担产品编辑器核心。代码主要在 app/Coreapp/Compositionapp/Featuresapp/Servicesapp/Windowing,并通过 XCEditorCoreRendering 对象库接入 app/Rendering;它不直接拥有 Win32 消息循环。
  • XCEditor 是可选 Win32 + D3D12 应用壳。代码在 app/Bootstrapapp/Host/Win32app/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 feature / panel 层不得直接 SetPosition()SetRotation()SetLocalScale()CreateComponent() 或类似写入 engine object graph交互预览也必须回到 EditorSceneRuntime,再由 backend/adapter 执行。
  • engine 全局 runtime 访问权统一收口到 app/Core/Engine/EditorEngineServices.h 合约和 app/Services/Engine/EngineEditorServices.* 生产实现。SceneManager::Get()ResourceManager::Get()RenderObjectIdRegistry::Get() 这类入口只能在该生产 adapter 内出现。
  • scene 事实所有权走 app/Core/Scene/EditorSceneBackend.h 合约。EditorSceneRuntime 只消费显式 backendEngineEditorSceneBackend 必须吃显式注入的 engine manager / resource manager不要在 scene runtime、panel、composition 或 viewport pass 中重新触碰 engine 全局单例。读模型优先经由 runtime/backend 快照派生,例如 hierarchy 使用 EditorSceneHierarchySnapshot,不要让面板从 Scene* 现场重建业务模型。
  • scene 渲染私有逻辑不要塞进 panel 或 shell。新增渲染能力时先判断它属于 engine Rendering/RHI、editor viewport pass bundle还是 UI overlay。
  • 运行时路径以 app/Core/Environment/EditorRuntimePaths.h 为显式契约。workspace、executable、resource、project、capture 根路径由 bootstrap 一次性解析并向下传递;不要在下游重新从 repo root、当前工作目录或文档文件推导运行环境。
  • 资源路径、图标、shader、截图输出都应走明确服务或 host 接口。不要硬编码从当前工作目录猜路径;手动验证截图不得写回 source tree。

当前情况

  • editor/AGENTS.md 只是协作说明,不是运行时定位标记。Application::ResolveRuntimePaths() 当前用稳定工程标记(根 CMakeLists.txteditor/resourcesproject)定位开发 workspace并填充 EditorRuntimePaths
  • 顶层 CMakeLists.txt 默认启用 XCENGINE_BUILD_XCUI_EDITOR_COREXCENGINE_BUILD_XCUI_EDITOR_APP。构建 core/app 时必须启用 XCENGINE_ENABLE_RENDERING_EDITOR_SUPPORT
  • XCEditor 目标输出名是 XCEngine.exeDebug 产物位于 build/editor/Debug/XCEngine.exe
  • 当前应用没有命令行项目选择流程;默认项目根由 EditorRuntimePaths.projectRoot 提供,开发 workspace 下通常是 <workspaceRoot>/project。不要沿用旧文档里的 --project <path> 说法。
  • 当前面板 ID 为 hierarchyscenegameinspectorconsoleproject,由 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/inspectorassets.* 通过 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 都在这里串接;初始化只接收 EditorRuntimePaths,不再自行拼接 repo/project/resource 路径。
  • UIEditorWorkspaceController 管单窗口 workspace model/sessionEditorWindowSystem 管多窗口 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。
  • ProjectPanel 只消费由 EditorContext / EditorPanelServices 提供的 EditorProjectRuntime,不再拥有或初始化自己的 project runtime。测试也应显式创建 EditorProjectRuntime 并通过 SetProjectRuntime() 注入,不要把 projectRoot 传给 panel。
  • EditorEngineServices 是 editor 接入 engine 全局 runtime 的唯一生产 adapter。Application 创建它并向 EditorContext、window shell runtime、viewport runtime 传递;下游只消费显式服务。
  • EditorSceneBackend 是 scene document/backend 的显式边界;EngineEditorSceneBackendEditorEngineServices 创建,并通过显式 SceneManager& / ResourceManager& 接入真实 engine runtime。EditorSceneRuntime 负责 startup scene 编排、editor scene camera、hierarchy selection、component list、transform edit history 和 scene tool state但不直接访问 engine 单例。
  • scene object graph 写入必须停在 EditorSceneBackend 生产 adapter 内。EditorSceneRuntime 可以编排 undo/redo、selection stamp、inspector revision 和 tool state但组件移除、component mutation、Transform inspector 写入、gizmo 预览/撤销写入都应通过 backend command 执行,不要在 runtime / feature / panel 层直接 RemoveComponent()SetPosition()SetRotation()SetScale()SetLocal*()
  • EditorSceneRuntime::BuildHierarchySnapshot() 是 hierarchy 面板的 scene 读入口;HierarchyModel 从该快照构建 UI tree。不要重新把 hierarchy 绑定回 Scene*
  • transform gizmo support 只负责几何计算和 hit/drag 状态;预览写入通过 SceneGizmoUndoBridge 调回 EditorSceneRuntime::ApplyTransformTool*Preview()。不要在 SceneViewportTransformGizmoSupport.* 里直接写 GameObject transform。

当前目录地图:

  • include/XCEditor/Foundation:命令注册/分发、快捷键、主题、文本测量接口、runtime trace。
  • include/XCEditor/Fieldsbool、number、text、enum、asset、object、color、vector、property grid 等编辑字段的绘制模型与交互。
  • include/XCEditor/Collectionslist/tree/tab/scroll/inline rename/drag-drop 等集合控件。
  • include/XCEditor/Dockinginclude/XCEditor/Workspacedock host、workspace tree、layout persistence、splitter correction、panel detach/transfer。
  • include/XCEditor/Shellmenu/toolbar/status/workspace 的 shell 组合与交互入口。
  • include/XCEditor/Viewportviewport slot/shell/input bridge。这里是通用 UI viewport 容器,不是 scene renderer。
  • include/XCEditor/Windowing:多窗口 workspace 状态、同步计划和 presentation policy。
  • src/**:对应公共头的实现。保持偏纯函数/状态机风格。
  • app/Core:产品级 contracts、session、command focus、selection、panel services、engine services、scene/project/viewport/windowing 接口。
  • app/Core/Scenescene backend 合约和 editor scene runtime 可消费的公共 scene 标识工具。
  • app/Core/Environment运行时路径契约。bootstrap 负责解析 EditorRuntimePathscore/composition/features/rendering 只消费显式路径。
  • app/Core/Product:产品 manifest。这里定义正式 panel 集、route 归属、runtime owner 和 viewport renderer owner。
  • app/Composition:装配编辑器 shell。EditorContext 拥有 session、project runtime、scene runtime、selection、command bridgeEditorShellRuntime 驱动 shell interaction、hosted panels 和 viewport runtime。
  • app/Features:产品面板与场景视图工具。
  • app/Services:产品 runtime 的生产服务实现。engine 全局 runtime 接入集中在 app/Services/Engine/EngineEditorServices.*scene backend 由该 adapter 生产project runtime 集中在 app/Services/Project
  • 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/Iconsresources/shaders/scene-viewport:内置图标和 scene viewport shader。资源路径由 app/rendering 层解析。

当前启动和帧流程:

wWinMain
-> RunXCEditor
-> Application::Initialize / Run
-> Application::ResolveRuntimePaths
-> 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 取 RenderContextcontent 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/Viewportinclude/XCEditor/Viewportviewport slot/shell/input bridge只处理 UI 容器和输入桥。
  • app/Features/Scene/SceneViewportController.*:场景视图产品交互,处理 Q/W/E/R 工具切换、F 聚焦、鼠标导航、scene icon picking、transform gizmo。
  • app/Core/Scene/EditorSceneBackend.hscene backend contract、startup scene result 和 game object item id helpers。
  • app/Services/Scene/EditorSceneRuntime.*scene selection、editor camera、transform undo/redo、component mutation 和 scene render request 的事实来源;它必须通过注入的 EditorSceneBackend 访问真实 scene。
  • app/Services/Engine/EngineEditorServices.*:当前唯一允许直接接入 engine SceneManager / ResourceManager / RenderObjectIdRegistry 的生产 adapter。
  • 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 测试。

当前构建和验证入口:

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
ctest --test-dir build -C Debug -R "editor|xceditor" --output-on-failure
  • XCUIEditor widget/shell/workspace 改动:跑 editor_ui_testseditor_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 规则。
  • 已移除 ProjectPanel 自持 EditorProjectRuntime 的 fallback 路径project runtime 事实源现在只来自 EditorContext,面板测试改为显式 runtime 注入。
  • 已把 scene 的 engine 全局访问收敛到 EngineEditorSceneBackend,让 EditorSceneRuntime 通过 EditorSceneBackend 合约初始化、打开 scene 和执行 hierarchy mutation新增 backend contract 单测覆盖无 backend 失败和 fake backend 注入。
  • 已新增 EditorEngineServices 边界,把 SceneManager::Get()ResourceManager::Get()RenderObjectIdRegistry::Get()ApplicationEditorContext 和 viewport shader/object-id 路径收口到 app/Services/Engine/EngineEditorServices.*EditorContext 现在通过显式 engine service 创建 scene backend并会在 scene runtime 初始化失败时返回失败。
  • 已把 hierarchy 面板的 scene 读取改为 EditorSceneHierarchySnapshot 快照路径,HierarchyModel 不再由 panel 直接拿 Scene* 构建;已把 inspector 添加组件动作收口到 EditorSceneBackend::AddComponent(),让 ComponentFactoryRegistry::Get() 留在 engine adapter 内。
  • 已把 scene transform gizmo 的拖拽预览写入从 feature support 层移到 EditorSceneRuntimesupport 层不再直接 SetPosition() / SetRotation() / SetLocalScale()
  • 已把 EditorSceneRuntime 内的组件移除、Transform inspector 写入、component mutation、transform snapshot restore 和 gizmo preview 写入继续收口到 EditorSceneBackend command真实 engine object graph 写入现在由 EngineEditorSceneBackend 执行runtime 只负责状态编排和 revision/undo 维护。
  • 本次改动验证过:
    • cmake --build build --config Debug --target XCEditor
    • cmake --build build --config Debug --target editor_app_core_tests
    • cmake --build build --config Debug --target editor_app_feature_tests