- 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
154 lines
3.9 KiB
Markdown
154 lines
3.9 KiB
Markdown
# 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()` 订阅底层事件
|
||
|
||
---
|
||
|
||
## 分层结构
|
||
|
||
```text
|
||
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.engine`(`EngineManager`)调用稳定公共 API:
|
||
|
||
- `initialize(options?)`
|
||
- `isInitialized()`
|
||
- `loadModel(urls, options?)`
|
||
- `pauseRendering()`
|
||
- `resumeRendering()`
|
||
- `destroy()`
|
||
|
||
### 2) 内部 Manager(BaseManager 子类)
|
||
|
||
通过 `BaseManager` 新增 getter:
|
||
|
||
```ts
|
||
protected get engineComponent(): Engine | null
|
||
```
|
||
|
||
直接调用 `Engine` 组件方法,例如:
|
||
|
||
```ts
|
||
this.engineComponent?.activeSection('box');
|
||
this.engineComponent?.setWalkSpeed(speed);
|
||
```
|
||
|
||
### 3) 非 Manager 组件
|
||
|
||
通过 registry 获取组件实例:
|
||
|
||
```ts
|
||
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)`
|
||
|
||
例如测量与剖切盒事件:
|
||
|
||
```ts
|
||
this.engineComponent?.onRawEvent('measure-changed', handler);
|
||
this.engineComponent?.offRawEvent('measure-changed', handler);
|
||
```
|
||
|
||
关键文件:`src/components/engine/index.ts`
|
||
|
||
---
|
||
|
||
## 典型调用链
|
||
|
||
### Toolbar Home
|
||
|
||
```text
|
||
Button onClick
|
||
-> registry.engine3d?.getEngineComponent()?.CameraGoHome()
|
||
-> Engine.CameraGoHome()
|
||
-> rawEngine.viewCube.CameraGoHome()
|
||
```
|
||
|
||
### Section Box
|
||
|
||
```text
|
||
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),进一步降低单类复杂度。
|