Files
bim_engine/docs/架构设计.md
2026-03-16 16:13:36 +08:00

218 lines
6.2 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.

# iflow-engine SDK 架构设计
## 概述
iflow-engine 提供三个独立引擎类,均可单独导入:
| 类 | 定位 | 内部结构 |
|---|---|---|
| `BimEngine` | 3D 完整引擎 | ManagerRegistry + 15 Managers + 20+ UI 组件 |
| `BimEngine2d` | 2D 图纸引擎 | ManagerRegistry(仅事件) + Engine2d 组件 |
| `BimEngine720` | 720° 全景引擎 | ManagerRegistry(仅事件) + Engine720 组件 |
三个类互不依赖,各自创建独立的 `ManagerRegistry` 实例。`BimEngine2d``BimEngine720` 跳过 Manager 层,直接使用底层组件。
2026-03 的核心调整:
- 新增 `BimEngine2d``BimEngine720` 独立类,按需导入
- `BimEngine` 变为纯 3D 引擎,不再包含 2D/720 代码
- `EngineManager` 从“大量透传”收敛为“少量公共 API + 生命周期编排”
- 内部 Manager 统一通过 `BaseManager.engineComponent` 直接访问 `Engine` 组件
- `Engine.getEngine()` 已移除,改为 `onRawEvent()/offRawEvent()` 订阅底层事件
---
## 分层结构
```text
┌───────────────────────────────────────────────────────────────────┐
│ 用户 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)
```
---
## 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) 内部 ManagerBaseManager 子类)
通过 `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进一步降低单类复杂度。
---
## 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