EG/PROJECT_OPTIMIZATION_ANALYSIS.md

271 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PROJECT_OPTIMIZATION_ANALYSIS
> 基于本地代码静态扫描生成(不含远程仓库信息,不含 `RenderPipelineFile/` 第三方目录)。
- 分析时间: 2026-02-28
- 扫描范围: `main.py`, `Start_Run.py`, `core/`, `scene/`, `project/`, `ui/`, `ssbo_component/`, `TransformGizmo/`, `scripts/`, `tools/`, `templates/`
## 0. 执行进展(非 VR
- 已完成 `EditorContext` 适配层:`core/editor_context.py`
- 已接入文件:
- `core/event_handler.py`
- `core/selection.py`
- `core/InfoPanelManager.py`
- `ui/panels/runtime_actions.py`
- `core/terrain_manager.py`
- `scene/scene_manager_convert_tiles_mixin.py`
- `scene/scene_manager_serialization_mixin.py`
- `scene/scene_manager_model_mixin.py`
- 效果(本地静态检索):
- 直接访问 `world.interface_manager`: `0`
- 直接访问 `interface_manager.treeWidget`: `0`
- `app.gui_manager` 仅剩注释引用(`ui/panels/editor_panels_left.py`
- Task B 第一轮已落地(`scene_manager_io_mixin.loadScene`
- 已抽出流程 helper
- `_preflight_load_scene`
- `_cleanup_after_failed_load`
- `_clear_current_scene_for_load`
- `_load_scene_root_from_file`
- `_bootstrap_scene_tree_for_loaded_root`
- `_load_scene_gui_metadata`
- `_retry_load_scene`
- `loadScene` 行数:`556 -> 366`
- 已清理重复异常分支:`_rebuildParentChildRelationships` 内重复 `except` 已移除
## 1. 总体画像
- Python 文件: `146`
- 代码总行数: `58,371`
- `except Exception` / `except:` 总计: `950`
-`except:` 总计: `63`
- 旧上下文关键词引用总量:
- `interface_manager`: `35`
- `treeWidget`: `10`
- `gui_manager`: `77`
结论:
- Qt 依赖已清理后,当前主要技术债集中在三类:
- 过大函数(可维护性差)
- 异常处理过宽(问题可观测性差)
- 旧 GUI 上下文命名耦合(边界不清晰)
## 2. 热点文件(按规模/风险)
### 2.1 超大文件 Top
1. `core/vr_manager.py` (`3553` 行)
2. `core/selection.py` (`2942` 行)
3. `core/InfoPanelManager.py` (`1726` 行)
4. `ui/LUI/lui_manager_editor.py` (`1724` 行)
5. `ui/panels/property_helpers.py` (`1711` 行)
6. `ui/LUI/lui_function_properties.py` (`1707` 行)
7. `TransformGizmo/rotate_gizmo.py` (`1587` 行)
8. `ui/panels/animation_tools.py` (`1579` 行)
### 2.2 长函数 Top优先拆分
1. `ui/LUI/lui_function_properties.py::_draw_component_properties` (`1441` 行)
2. `scene/scene_manager_io_mixin.py::loadScene` (`556` 行)
3. `ui/panels/animation_tools.py::_getActor` (`510` 行)
4. `main.py::__init__` (`375` 行)
5. `ui/LUI/lui_manager_interaction.py::_update_drag` (`348` 行)
6. `ui/panels/editor_panels_left.py::_draw_resource_manager` (`310` 行)
7. `scene/scene_manager_io_mixin.py::processNode` (`281` 行)
8. `core/selection.py::updateGizmoDrag` (`278` 行)
### 2.3 异常处理密度高(可观测性风险)
1. `ui/panels/animation_tools.py` (`except* = 85`)
2. `core/vr_manager.py` (`71`)
3. `core/selection.py` (`57`)
4. `ui/panels/property_helpers.py` (`54`)
5. `ui/panels/app_actions.py` (`46`)
6. `scene/scene_manager_model_mixin.py` (`36`)
7. `scene/scene_manager_serialization_mixin.py` (`27`)
8. `scene/scene_manager_io_mixin.py` (`20`)
9. `project/project_manager.py` (`20`)
10. `ui/panels/runtime_actions.py` (`20`)
`except:` 集中区:
- `core/selection.py` (`7`)
- `scene/scene_manager_model_mixin.py` (`7`)
- `ui/panels/editor_panels_right_material.py` (`6`)
- `ui/panels/editor_panels_left.py` (`5`)
### 2.4 旧上下文耦合集中区历史基线Task A 前)
1. `ui/panels/runtime_actions.py` (`gui_manager=29`)
2. `core/event_handler.py` (`interface_manager=11`, `gui_manager=11`)
3. `ui/panels/editor_panels_right.py` (`gui_manager=18`)
4. `scene/scene_manager_serialization_mixin.py` (`interface_manager=6`, `treeWidget=2`, `gui_manager=5`)
5. `core/selection.py` (`interface_manager=4`, `treeWidget=1`)
6. `core/InfoPanelManager.py` (`interface_manager=4`, `treeWidget=1`)
7. `core/terrain_manager.py` (`interface_manager=3`, `treeWidget=2`)
## 3. 优化优先级(建议执行顺序)
## P0: 上下文收敛(先做)
目标: 统一 GUI/场景树访问边界,减少跨模块 `hasattr(..., 'interface_manager')``treeWidget` 语义残留。
建议动作:
1. 引入 `EditorContext`(或 `UIContext`)统一提供:
- `get_tree_adapter()`
- `get_gui_service()`
- `get_selection_service()`
2. 在以下文件先改为调用上下文接口:
- `core/event_handler.py`
- `core/selection.py`
- `core/InfoPanelManager.py`
- `core/terrain_manager.py`
- `scene/scene_manager_serialization_mixin.py`
- `scene/scene_manager_convert_tiles_mixin.py`
- `ui/panels/runtime_actions.py`
预期收益:
- 降低命名残留与多处 `hasattr` 防御代码。
- 后续模块拆分时边界更稳定。
## P1: 大函数拆分(第二阶段)
目标: 将核心长函数拆分成“流程编排 + 子步骤函数”,减少单函数认知负担。
建议拆分顺序:
1. `scene/scene_manager_io_mixin.py::loadScene`
2. `main.py::__init__`
3. `ui/panels/animation_tools.py::_getActor`
4. `core/selection.py::updateGizmoDrag`
5. `ui/LUI/lui_function_properties.py::_draw_component_properties`(可按“变换/布局/视觉/交互/脚本”分区)
预期收益:
- 回归问题定位更快。
- 面板和场景加载逻辑更易测试。
## P2: 异常处理治理(并行推进)
目标: 将“吞异常”改为“有边界的降级 + 可追踪日志”。
建议规则:
1. 禁止新增裸 `except:`
2. 高风险路径必须记录上下文:
- 节点名/资源路径/操作类型/当前工具状态
3. 对可恢复错误使用 `warning`,不可恢复错误返回显式失败值。
优先文件:
- `ui/panels/animation_tools.py`
- `core/vr_manager.py`
- `core/selection.py`
- `ui/panels/property_helpers.py`
- `scene/scene_manager_io_mixin.py`
## 4. 下一步可直接执行的任务包
### Task A推荐先做1-2 天)
- 建立 `core/editor_context.py`(或同级命名)
-`event_handler/selection/InfoPanelManager/runtime_actions` 接入上下文
- 保持外部 API 不变,仅替换内部访问路径
### Task B1 天)
- 重构 `scene_manager_io_mixin.loadScene`
- `preflight`
- `clear_old_scene`
- `load_bam`
- `rebuild_scene_tree`
- `post_load_sync`
### Task C1 天)
- 统一异常日志工具(轻量封装)
- 首批替换 `animation_tools.py``property_helpers.py`
## 4.1 本轮深入分析(非 VRP1 准备)
### A) `scene/scene_manager_io_mixin.py::loadScene`(核心优先)
- 函数规模: `556`
- 近似圈复杂度: `114`
- 关键问题:
- 单函数同时承担 8 类职责(校验/清理/加载/树同步/节点递归处理/脚本恢复/材质恢复/重试)。
- 内嵌 `processNode` 递归函数长达 `281` 行,可测试性差。
- 调试输出密度高(`print` 与注释 `print` 很多),影响可读性和噪声控制。
- `scene/scene_manager_io_mixin.py:1026``scene/scene_manager_io_mixin.py:1032` 存在重复 `except Exception` 分支(可合并)。
- `scene/scene_manager_io_mixin.py:946` 的 GUI 重建入口目前仍注释,行为边界不清晰。
- 建议拆分(保持外部 API `loadScene` 不变):
- `_preflight_scene_file(filename) -> (ok, normalized_path, reason)`
- `_cleanup_before_load(tree_widget, retry_count)`
- `_load_bam_scene(filename) -> scene_or_none`
- `_bootstrap_tree_items(scene, tree_widget)`
- `_walk_loaded_scene(scene, tree_widget) -> loaded_nodes`
- `_restore_loaded_nodes_state(node_path, processed_lights, loaded_nodes)`(从 `processNode` 中抽)
- `_post_load_finalize(scene, loaded_nodes, filename)`
- `_retry_load_scene(filename, retry_count, error) -> bool`
- 验收标准:
- `loadScene` 主体压缩到 `120` 行以内,只保留流程编排。
- 节点恢复行为(位置/材质/脚本/可见性)与当前一致。
- 失败重试逻辑保持语义一致。
- 当前状态2026-02-28:
- 第一轮已完成(预检/清理/加载/树初始化/GUI元数据/重试)。
- 剩余主要体积来自内嵌 `processNode`,下一轮应继续提取为独立方法。
### B) `main.py::__init__`(第二优先)
- 函数规模: `375`
- 近似圈复杂度: `15`
- 问题性质:
- 复杂度不高,但“启动装配职责”过于集中,初始化顺序风险高。
- 建议拆分:
- `_init_legacy_compat_fields()`
- `_init_core_services_non_vr()`(不含 VR
- `_init_imgui_runtime()`
- `_init_panel_modules()`
- `_init_runtime_state_flags()`
- `_bind_input_shortcuts()`
- `_init_drag_drop_and_messages()`
- 约束:
- VR 初始化保持原样,不纳入本轮改造范围。
### C) `ui/panels/animation_tools.py::_getActor`(第三优先)
- 函数规模: `510`
- 近似圈复杂度: `143`
- 关键问题:
- 路径推断、缓存策略、Actor 构建、autoBind 回退、GLTF 特化混在一个函数中。
- 局部嵌套函数层级深,行为分支很难覆盖测试。
- 建议拆分:
- `_resolve_actor_owner_and_paths(origin_model)`
- `_load_actor_from_candidate_paths(owner_model, paths)`
- `_load_actor_via_memory_fallback(owner_model, origin_model)`
- `_load_actor_via_gltf_special(path)`
- `_validate_actor_playable(actor_or_proxy)`
- `_cache_actor(owner_model, actor)`
- 验收标准:
- `_getActor` 保留为流程入口,长度控制到 `150` 行以内。
- 保持当前“优先路径加载,失败回退内存/autoBind”的策略不变。
## 4.2 Task B 执行顺序建议(非 VR
1. 先拆 `loadScene`(收益最大,且与 VR 无关)。
2. 再整理 `main.__init__`(降低后续模块接入冲突)。
3. 最后处理 `_getActor`(风险最高,建议独立提交并做手工回归)。
## 5. 与现有文档关系
- 模块总索引: `PROJECT_MODULE_INDEX.md`
- Qt 迁移状态: `QT_TO_IMGUI_MIGRATION_CHECKLIST.md`
- 历史分析: `IMGUI_MODULE_ANALYSIS.md`
---
如果按此路线继续,建议下一轮直接从 **Task A** 开始,我可以先落地上下文适配层并改 4 个高耦合文件。