EG/PROJECT_OPTIMIZATION_ANALYSIS.md

9.9 KiB
Raw Blame History

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.pyproperty_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:1026scene/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 个高耦合文件。