Files
bim_engine/docs/架构设计.md
yuding b96e5f3262 refactor: slim down EngineManager from 861 to 290 lines by removing passthrough proxy pattern
- EngineManager now only exposes public SDK API (initialize, loadModel, pause/resumeRendering, getEngineComponent, destroy)
- Internal managers access Engine component directly via this.engineComponent getter on BaseManager
- Non-manager components use registry.engine3d.getEngineComponent() for direct Engine access
- Replaced getEngine() with onRawEvent()/offRawEvent() for raw engine event access
- Migrated 62 call sites across 13 files (9 managers, 1 panel, 3 toolbar buttons)
- Updated all architecture docs, API docs, and README to reflect new patterns
2026-03-05 11:15:57 +08:00

3.9 KiB
Raw Blame History

iflow-engine SDK 架构设计

概述

iflow-engine 采用分层架构:BimEngine 作为入口,ManagerRegistry 作为实例级注册表Manager 层负责编排Component 层负责 UI/引擎封装Services/Core 层提供基础能力。

2026-03 的核心调整:

  • EngineManager 从“大量透传”收敛为“少量公共 API + 生命周期编排”
  • 内部 Manager 不再通过 registry.engine3d?.xxx() 间接透传,而是通过 BaseManager.engineComponent 直接访问 Engine 组件
  • 非 Manager 组件(如 toolbar 按钮、walk-path-panel通过 registry.engine3d?.getEngineComponent()?.xxx() 访问 Engine
  • Engine.getEngine() 已移除,改为 onRawEvent()/offRawEvent() 订阅底层事件

分层结构

BimEngine (入口 / Facade)
  └─ ManagerRegistry (实例级,不是全局单例)
       ├─ Managers (业务编排)
       │    ├─ EngineManager (公共 API + 初始化 + 右键菜单组装)
       │    ├─ *DialogManager / *ControlManager
       │    └─ ...
       ├─ Components (UI + Engine 封装)
       │    ├─ Engine (封装 iflow-engine-base)
       │    ├─ Dialog/Toolbar/Panel...
       │    └─ ...
       ├─ Services (Theme / Locale)
       └─ Core (EventEmitter / BaseManager / BaseDialogManager)

ManagerRegistry 设计

ManagerRegistry实例模式:每个 BimEngine 都创建独立 registry支持多实例隔离。

  • 无全局共享状态污染
  • 多画布/多引擎实例可并行
  • 事件总线隔离

关键文件:src/core/manager-registry.ts


Engine 访问策略(最新)

1) 外部 SDK 用户

通过 bimEngine.engineEngineManager)调用稳定公共 API

  • initialize(options?)
  • isInitialized()
  • loadModel(urls, options?)
  • pauseRendering()
  • resumeRendering()
  • destroy()

2) 内部 ManagerBaseManager 子类)

通过 BaseManager 新增 getter

protected get engineComponent(): Engine | null

直接调用 Engine 组件方法,例如:

this.engineComponent?.activeSection('box');
this.engineComponent?.setWalkSpeed(speed);

3) 非 Manager 组件

通过 registry 获取组件实例:

registry.engine3d?.getEngineComponent()?.toggleMiniMap();

EngineManager 职责边界

EngineManager 现在聚焦在“入口能力 + 组装能力”:

  1. 创建并持有 Engine 组件实例
  2. 初始化并持有 RightKeyManager
  3. 注册右键菜单项并编排右键行为
  4. 对外暴露少量稳定 API

不再承担:

  • Engine 全量方法的 1:1 透传

关键文件:src/managers/engine-manager.ts


原始引擎事件订阅策略

为避免暴露底层 raw engine 实例,Engine 组件提供:

  • onRawEvent(event, handler)
  • offRawEvent(event, handler)

例如测量与剖切盒事件:

this.engineComponent?.onRawEvent('measure-changed', handler);
this.engineComponent?.offRawEvent('measure-changed', handler);

关键文件:src/components/engine/index.ts


典型调用链

Toolbar Home

Button onClick
  -> registry.engine3d?.getEngineComponent()?.CameraGoHome()
  -> Engine.CameraGoHome()
  -> rawEngine.viewCube.CameraGoHome()

Section Box

SectionBoxDialogManager (BaseDialogManager)
  -> this.engineComponent?.activeSection('box')
  -> Engine.activeSection('box')
  -> rawEngine.clipping.active('box')

设计收益

  • 降低中间层重复代码:EngineManager 大幅瘦身
  • 减少三层转发链Manager 可直接访问 Engine 组件
  • 对外 API 稳定:仍保留 bimEngine.engine 作为入口
  • 保持封装边界:不暴露 raw engine仅开放受控事件桥接

后续建议

当前已完成“Manager 瘦身”阶段。若后续继续演进,可考虑将 Engine 组件按领域继续拆分measure/section/walk/model/scene进一步降低单类复杂度。