refactor(new_editor): tighten app dependency boundaries

This commit is contained in:
2026-04-19 02:48:41 +08:00
parent 7429f22fb1
commit c59cd83c38
86 changed files with 1754 additions and 1077 deletions

View File

@@ -0,0 +1,216 @@
# NewEditor UI第二阶段依赖方向补充收口计划
日期2026-04-19
## 背景
这是对 `docs/plan/NewEditor_UI第二阶段依赖方向子计划_2026-04-19.md` 的补充收口说明。
本补充只覆盖本轮严格审查后确认的两个根因,以及对应的正式解法与本轮落地结果。
## 严格审查补充结论
### 1. 真正的问题不是“几个 include 写错了”,而是 `new_editor/app` 里混放了两种责任
- 一类是 `AppCore` 责任产品状态、面板逻辑、场景工具、viewport 业务渲染组织。
- 一类是 `Win32/Host` 组合责任窗口宿主、D3D12 设备、NativeRenderer、窗口渲染循环。
- 现在这两类代码虽然目录上看似分层,但仍然通过具体实现头直接耦合,导致 `XCUIEditorAppLib` 的边界仍然偏假。
根因判断:
- 真正缺失的是一层窄契约,导致 `AppCore` 代码只能直接抓 `NativeRenderer``D3D12WindowRenderer``D3D12ShaderResourceDescriptorAllocator` 这类宿主实现。
- 只要没有窄契约,后续即使继续删 include也只是补丁式修补无法为后续 target 拆分提供稳定基础。
正式解法:
1. 先在 `new_editor/app/Host` 建立窄契约层,把 `AppCore` 真实需要的能力抽出来。
2. `AppCore` 只依赖窄契约,不再直接依赖 Host 具体实现头。
3. 在此基础上,再进入下一步 target 收口:把当前 `XCUIEditorAppLib` 继续拆成真正的 `AppCore``Win32 组合边界`
### 2. 公共 API 中真正存在的产品默认值泄漏,当前只确认到 `EditorShellAsset.screenId`
- `BuildDefaultUIEditorWorkspaceSession`
- `BuildDefaultUIEditorWorkspaceController`
- `BuildDefaultUIEditorWindowWorkspaceSet`
- `BuildDefaultUIEditorWindowWorkspaceController`
严格审查结论:
- 这四个 `BuildDefault*` 当前仍被大量公共层单测、集成测试和 structured shell 装配逻辑直接使用。
- 从行为上看,它们表达的是 UI workspace 的通用默认装配语义,不是 `new_editor` 产品私有策略。
- 因此这一批 API 当前不应强行下沉,否则会把通用装配能力误收口成产品实现。
真正的问题点是:
- `XCEditor/Shell/UIEditorShellAsset.h``screenId = "editor.shell"` 把产品默认值放进了公共结构体默认值里。
正式解法:
1. 公共 `EditorShellAsset` 只保留空默认值。
2. `"editor.shell"` 只在 `new_editor/app/Composition/EditorShellAssetBuilder.cpp` 这种产品装配位置赋值。
## 本轮执行项
### 已执行:抽离 Host 窄契约
新增:
- `new_editor/app/Host/TextureHost.h`
- `new_editor/app/Host/ViewportRenderHost.h`
- `new_editor/app/Host/ShaderResourceDescriptorAllocator.h`
本轮已经把以下 `AppCore` 代码改为依赖窄契约,而不是直接依赖 Host 具体实现:
- `BuiltInIcons`
- `EmbeddedPngLoader`
- `SceneViewportToolOverlay`
- `SceneViewportController`
- `ViewportRenderTargets`
- `ViewportHostService`
- `EditorShellRuntime`
本轮效果:
- feature / rendering / composition 中真正属于 `AppCore` 的代码,已经不再直接 include `NativeRenderer.h` / `D3D12WindowRenderer.h` / `D3D12ShaderResourceDescriptorAllocator.h`
- 当前残留的具体 Host 头依赖,已经主要收缩到真正的 Win32/Host 组合边界:
- `new_editor/app/Platform/Win32/EditorWindowInternalState.h`
- `new_editor/app/Rendering/D3D12/D3D12WindowRenderLoop.h`
- `new_editor/app/Rendering/Native/NativeRenderer.h`
- `new_editor/app/Rendering/Viewport/ViewportHostService.cpp` 中的具体 allocator 构造点
### 已执行:收掉公共 API 的产品默认值
已调整:
- `new_editor/include/XCEditor/Shell/UIEditorShellAsset.h`
当前状态:
- `EditorShellAsset.screenId` 默认值已改为空
- `"editor.shell"` 继续只在 `new_editor/app/Composition/EditorShellAssetBuilder.cpp` 中设置
## 验证结果
使用全新验证构建目录 `build_codex_verify` 完成了本轮验证。
已通过:
- `cmake -S . -B build_codex_verify -G "Visual Studio 17 2022" -A x64 -DXCENGINE_BUILD_XCUI_EDITOR_APP=ON -DFETCHCONTENT_SOURCE_DIR_GOOGLETEST=D:/Xuanchi/Main/XCEngine/build/_deps/googletest-src`
- `cmake --build build_codex_verify --config Debug --target editor_app_feature_tests`
- `build_codex_verify/tests/UI/Editor/unit/Debug/editor_app_feature_tests.exe`
结果:
- `82 / 82` 通过
## 本轮追加执行结果
### 已完成:把 `XCUIEditorAppLib` 正式拆成 `AppCore` 与 Win32 组合层
已调整:
- `new_editor/CMakeLists.txt`
- `tests/UI/Editor/unit/CMakeLists.txt`
当前 target 结构:
- `XCUIEditorAppCore`
- 承接 `app/State`
- 承接 `app/Composition`
- 承接 `app/Features`
- 承接 `app/Rendering/Viewport``app/Rendering/Assets`
- 承接 `app/Project` / `app/Scene` / `app/Internal`
- 承接 `src/App`
- `XCUIEditorAppLib`
- 只承接 `app/Platform/Win32`
- 作为 Win32 产品组合层,依赖 `XCUIEditorAppCore`
本轮效果:
- `AppCore` 已经从构建层面独立出来,不再和 Win32 窗口宿主代码混编在同一个 target 中
- `EditorWindow``WindowManager``ApplicationBootstrap` 这类窗口组合代码继续保留在最外层产品组合边界
- `editor_app_feature_tests` 现已显式链接 `XCUIEditorAppCore`,不再把所有产品逻辑都隐式压在 `XCUIEditorAppLib` 一个 target 上
### 已完成:补齐 `XCUIEditorApp` 的运行时 DLL 部署规则
根因:
- 干净构建目录下 `xcui_editor_app_smoke` 失败,退出码 `0xc0000135`
- 原因不是代码逻辑错误,而是 `XCUIEditorApp` target 缺少 `assimp``PhysX` 运行时 DLL 的 post-build 拷贝规则
已修复:
- `new_editor/CMakeLists.txt`
结果:
- `XCUIEditor.exe` 输出目录已自动部署:
- `assimp-vc143-mt.dll`
- `PhysXCommon_64.dll`
- `PhysXCooking_64.dll`
- `PhysXFoundation_64.dll`
- `PhysX_64.dll`
- `PVDRuntime_64.dll`
### 追加验证
已通过:
- `cmake --build build_codex_verify --config Debug --target XCUIEditorApp editor_app_feature_tests`
- `build_codex_verify/tests/UI/Editor/unit/Debug/editor_app_feature_tests.exe`
- `ctest --output-on-failure -C Debug --test-dir build_codex_verify -R '^xcui_editor_app_smoke$'`
结果:
- `editor_app_feature_tests`: `82 / 82` 通过
- `xcui_editor_app_smoke`: 通过
### 已完成:把 `EditorWindow` 的传输数据与私有状态正式拆开
已调整:
- `new_editor/app/Platform/Win32/EditorWindow.h`
- `new_editor/app/Platform/Win32/EditorWindowTransferRequests.h`
- `new_editor/app/Platform/Win32/EditorWindowInternalState.h`
- `new_editor/app/Platform/Win32/EditorWindowLifecycle.cpp`
- `new_editor/app/Platform/Win32/EditorWindowFrame.cpp`
- `new_editor/app/Platform/Win32/EditorWindowInput.cpp`
- `new_editor/app/Platform/Win32/EditorWindowBorderlessPlacement.cpp`
- `new_editor/app/Platform/Win32/EditorWindowBorderlessResize.cpp`
- `new_editor/app/Platform/Win32/EditorWindowTitleBarInteraction.cpp`
- `new_editor/app/Platform/Win32/EditorWindowTitleBarRendering.cpp`
- `new_editor/app/Platform/Win32/WindowMessageDispatcher.cpp`
- `new_editor/app/Platform/Win32/WindowManager/Internal.h`
- `new_editor/app/Platform/Win32/WindowManager/Lifecycle.cpp`
根因与处理:
- 旧的 `EditorWindowState.h` 同时承载了两类语义:
- 跨窗口/管理层需要消费的传输请求
- 只属于 `EditorWindow` 实现细节的渲染、输入、shell runtime、chrome 运行时状态
- 这会让 `EditorWindow.h``EditorShellRuntime``NativeRenderer``D3D12WindowRenderer``D3D12WindowRenderLoop``AutoScreenshot` 等具体实现全部泄漏到 Win32 公开头面。
- 本轮将 `EditorWindowPanelTransferRequest``EditorWindowFrameTransferRequests` 独立到轻量头 `EditorWindowTransferRequests.h`
- 将窗口私有实现状态收回到 `EditorWindowInternalState.h`,并由 `EditorWindow` 通过 `std::unique_ptr<EditorWindowState>` 私有持有。
本轮效果:
- `EditorWindow.h` 不再直接暴露私有状态聚合,也不再 include `Composition/EditorShellRuntime.h``Rendering/Native/NativeRenderer.h``Rendering/D3D12/D3D12WindowRenderer.h``Rendering/D3D12/D3D12WindowRenderLoop.h` 等宿主实现头。
- `EditorWindow.h` 进一步收缩为以前向声明为主,不再顺带带出 `XCEditor` 的 shell/workspace/dock 公开头。
- `WindowManager/Internal.h` 也不再顺带 include `UIEditorWindowWorkspaceController.h``UIEditorWorkspaceController.h`,这些公开 workspace 类型的完整依赖已回收到真正使用它们的 `WindowManager/Lifecycle.cpp`
- 当前 `new_editor/app/Platform/Win32` 头文件中,上述重依赖已只剩 `EditorWindowInternalState.h` 一处持有Win32 公开头面的边界已经和实现边界对齐。
追加验证:
- `cmake --build build_codex_verify --config Debug --target XCUIEditorApp editor_app_feature_tests`
- `build_codex_verify/tests/UI/Editor/unit/Debug/editor_app_feature_tests.exe`
- `ctest --output-on-failure -C Debug --test-dir build_codex_verify -R '^xcui_editor_app_smoke$'`
结果:
- `editor_app_feature_tests`: `82 / 82` 通过
- `xcui_editor_app_smoke`: 通过
## 下一步收口
1.`XCUIEditorAppCore` / `XCUIEditorAppLib` 已分离、`EditorWindow` 公开头已收缩的基础上,继续收紧 `target_include_directories`,把当前“目录还可穿透、但代码已不再依赖”的状态彻底变成“构建层也不能穿透”。
2. 继续审查 `WindowManager` / `Bootstrap` 头面的公开依赖,确认是否还存在类似 `EditorWindow` 这种“实现状态被头面顺带暴露”的问题。
3. 视下一轮审查结果,再决定是否需要把 `Bootstrap` 从可执行入口中进一步下沉为单独的产品装配 target。