2026-03-05 11:15:57 +08:00
|
|
|
|
# iflow-engine SDK 架构设计
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
|
|
|
|
|
## 概述
|
|
|
|
|
|
|
2026-03-16 16:13:36 +08:00
|
|
|
|
iflow-engine 提供三个独立引擎类,均可单独导入:
|
|
|
|
|
|
|
|
|
|
|
|
| 类 | 定位 | 内部结构 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| `BimEngine` | 3D 完整引擎 | ManagerRegistry + 15 Managers + 20+ UI 组件 |
|
|
|
|
|
|
| `BimEngine2d` | 2D 图纸引擎 | ManagerRegistry(仅事件) + Engine2d 组件 |
|
|
|
|
|
|
| `BimEngine720` | 720° 全景引擎 | ManagerRegistry(仅事件) + Engine720 组件 |
|
|
|
|
|
|
|
|
|
|
|
|
三个类互不依赖,各自创建独立的 `ManagerRegistry` 实例。`BimEngine2d` 和 `BimEngine720` 跳过 Manager 层,直接使用底层组件。
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
2026-03 的核心调整:
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-16 16:13:36 +08:00
|
|
|
|
- 新增 `BimEngine2d`、`BimEngine720` 独立类,按需导入
|
|
|
|
|
|
- `BimEngine` 变为纯 3D 引擎,不再包含 2D/720 代码
|
2026-03-05 11:15:57 +08:00
|
|
|
|
- `EngineManager` 从“大量透传”收敛为“少量公共 API + 生命周期编排”
|
2026-03-16 16:13:36 +08:00
|
|
|
|
- 内部 Manager 统一通过 `BaseManager.engineComponent` 直接访问 `Engine` 组件
|
2026-03-05 11:15:57 +08:00
|
|
|
|
- `Engine.getEngine()` 已移除,改为 `onRawEvent()/offRawEvent()` 订阅底层事件
|
|
|
|
|
|
---
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
## 分层结构
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
```text
|
2026-03-16 16:13:36 +08:00
|
|
|
|
┌───────────────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ 用户 API 入口 │
|
|
|
|
|
|
│ BimEngine (3D) BimEngine2d (2D) BimEngine720 (720°) │
|
|
|
|
|
|
└────┬──────────────────┬────────────────────┬────────────────────┘
|
|
|
|
|
|
│ │ │
|
|
|
|
|
|
▼ ▼ ▼
|
|
|
|
|
|
ManagerRegistry ManagerRegistry ManagerRegistry
|
|
|
|
|
|
+ 15 Managers (仅事件总线) (仅事件总线)
|
|
|
|
|
|
+ 20+ UI 组件 + Engine2d 组件 + Engine720 组件
|
|
|
|
|
|
│ │ │
|
|
|
|
|
|
└──────┬───────────┴────────┬───────────┘
|
|
|
|
|
|
│ │
|
|
|
|
|
|
▼ ▼
|
|
|
|
|
|
Services (Theme/Locale) Core (EventEmitter/BaseManager)
|
|
|
|
|
|
│
|
|
|
|
|
|
▼
|
|
|
|
|
|
iflow-engine-base (createEngine / createEngine2d / createEngine720)
|
2026-01-23 16:27:04 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
---
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
## ManagerRegistry 设计
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
`ManagerRegistry` 是 **实例模式**:每个 `BimEngine` 都创建独立 registry,支持多实例隔离。
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
- ✅ 无全局共享状态污染
|
|
|
|
|
|
- ✅ 多画布/多引擎实例可并行
|
|
|
|
|
|
- ✅ 事件总线隔离
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
关键文件:`src/core/manager-registry.ts`
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
---
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
## Engine 访问策略(最新)
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
### 1) 外部 SDK 用户
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
通过 `bimEngine.engine`(`EngineManager`)调用稳定公共 API:
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
- `initialize(options?)`
|
|
|
|
|
|
- `isInitialized()`
|
|
|
|
|
|
- `loadModel(urls, options?)`
|
|
|
|
|
|
- `pauseRendering()`
|
|
|
|
|
|
- `resumeRendering()`
|
|
|
|
|
|
- `destroy()`
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
### 2) 内部 Manager(BaseManager 子类)
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
通过 `BaseManager` 新增 getter:
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
```ts
|
|
|
|
|
|
protected get engineComponent(): Engine | null
|
2026-01-23 16:27:04 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
直接调用 `Engine` 组件方法,例如:
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
```ts
|
|
|
|
|
|
this.engineComponent?.activeSection('box');
|
|
|
|
|
|
this.engineComponent?.setWalkSpeed(speed);
|
2026-01-23 16:27:04 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
### 3) 非 Manager 组件
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
通过 registry 获取组件实例:
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
```ts
|
|
|
|
|
|
registry.engine3d?.getEngineComponent()?.toggleMiniMap();
|
2026-01-23 16:27:04 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
---
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
## EngineManager 职责边界
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
`EngineManager` 现在聚焦在“入口能力 + 组装能力”:
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
1. 创建并持有 `Engine` 组件实例
|
|
|
|
|
|
2. 初始化并持有 `RightKeyManager`
|
|
|
|
|
|
3. 注册右键菜单项并编排右键行为
|
|
|
|
|
|
4. 对外暴露少量稳定 API
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
不再承担:
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
- 对 `Engine` 全量方法的 1:1 透传
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
关键文件:`src/managers/engine-manager.ts`
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
---
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
## 原始引擎事件订阅策略
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
为避免暴露底层 raw engine 实例,`Engine` 组件提供:
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
- `onRawEvent(event, handler)`
|
|
|
|
|
|
- `offRawEvent(event, handler)`
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
例如测量与剖切盒事件:
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
```ts
|
|
|
|
|
|
this.engineComponent?.onRawEvent('measure-changed', handler);
|
|
|
|
|
|
this.engineComponent?.offRawEvent('measure-changed', handler);
|
2026-01-23 16:27:04 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
关键文件:`src/components/engine/index.ts`
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
---
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
## 典型调用链
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
### Toolbar Home
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
```text
|
|
|
|
|
|
Button onClick
|
|
|
|
|
|
-> registry.engine3d?.getEngineComponent()?.CameraGoHome()
|
|
|
|
|
|
-> Engine.CameraGoHome()
|
|
|
|
|
|
-> rawEngine.viewCube.CameraGoHome()
|
2026-01-23 16:27:04 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
### Section Box
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
```text
|
|
|
|
|
|
SectionBoxDialogManager (BaseDialogManager)
|
|
|
|
|
|
-> this.engineComponent?.activeSection('box')
|
|
|
|
|
|
-> Engine.activeSection('box')
|
|
|
|
|
|
-> rawEngine.clipping.active('box')
|
2026-01-23 16:27:04 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
---
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
## 设计收益
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
- 降低中间层重复代码:`EngineManager` 大幅瘦身
|
|
|
|
|
|
- 减少三层转发链:Manager 可直接访问 `Engine` 组件
|
|
|
|
|
|
- 对外 API 稳定:仍保留 `bimEngine.engine` 作为入口
|
|
|
|
|
|
- 保持封装边界:不暴露 raw engine,仅开放受控事件桥接
|
2026-01-23 16:27:04 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-03-05 11:15:57 +08:00
|
|
|
|
## 后续建议
|
|
|
|
|
|
|
|
|
|
|
|
当前已完成“Manager 瘦身”阶段。若后续继续演进,可考虑将 `Engine` 组件按领域继续拆分(measure/section/walk/model/scene),进一步降低单类复杂度。
|
2026-03-16 16:13:36 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2D / 720 独立引擎设计
|
|
|
|
|
|
|
|
|
|
|
|
### 设计决策
|
|
|
|
|
|
|
|
|
|
|
|
不采用“一个 BimEngine 懒加载三种引擎”的方案,而是创建三个独立类。理由:
|
|
|
|
|
|
|
|
|
|
|
|
1. **按需导入**:只用 2D 的用户不需要打包 3D 的 UI 组件
|
|
|
|
|
|
2. **职责清晰**:3D 需要完整的 Manager 层,2D/720 只需轻量封装
|
|
|
|
|
|
3. **生命周期独立**:各自 destroy() 不影响其他实例
|
|
|
|
|
|
4. **共享服务**:`themeManager` 和 `localeManager` 依然是全局单例,主题切换对所有实例生效
|
|
|
|
|
|
|
|
|
|
|
|
### BimEngine2d 结构
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
BimEngine2d
|
|
|
|
|
|
├─ ManagerRegistry (仅事件总线)
|
|
|
|
|
|
└─ Engine2d 组件
|
|
|
|
|
|
└─ createEngine2d() (iflow-engine-base)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
- 构造时自动初始化,无需 `initialize()` 调用
|
|
|
|
|
|
- 直接暴露 `loadDrawing()`、`getLayers()`、`setLayerVisible()` 等 API
|
|
|
|
|
|
- 不创建任何 UI 组件(toolbar、dialog 等)
|
|
|
|
|
|
|
|
|
|
|
|
### BimEngine720 结构
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
BimEngine720
|
|
|
|
|
|
├─ ManagerRegistry (仅事件总线)
|
|
|
|
|
|
└─ Engine720 组件
|
|
|
|
|
|
└─ createEngine720() (iflow-engine-base)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
- 构造时自动初始化,配置 fov、zoom、rotate 等参数
|
|
|
|
|
|
- 直接暴露 `loadPanorama()`、`setFov()`、`lookAt()` 等 API
|
|
|
|
|
|
- 不创建任何 UI 组件
|
|
|
|
|
|
|
|
|
|
|
|
### 多引擎切换模式
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
同一容器同时只能有一个引擎实例。切换时:
|
|
|
|
|
|
1. current.destroy() // 销毁当前
|
|
|
|
|
|
2. new BimEngineXxx() // 创建新实例
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
**文档更新时间**: 2026-03-10
|