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
This commit is contained in:
639
docs/架构设计.md
639
docs/架构设计.md
@@ -1,502 +1,153 @@
|
||||
# iflow-engine SDK 架构文档
|
||||
# iflow-engine SDK 架构设计
|
||||
|
||||
## 概述
|
||||
|
||||
iflow-engine 是一个面向开发者的 BIM 3D 引擎 SDK,采用分层架构设计,提供模型查看、测量、剖切、漫游等功能。
|
||||
iflow-engine 采用分层架构:`BimEngine` 作为入口,`ManagerRegistry` 作为实例级注册表,Manager 层负责编排,Component 层负责 UI/引擎封装,Services/Core 层提供基础能力。
|
||||
|
||||
## 架构图
|
||||
2026-03 的核心调整:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ BimEngine │
|
||||
│ (主入口 / 门面模式) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ ManagerRegistry │ │
|
||||
│ │ (单例 / 全局注册表) │ │
|
||||
│ │ ┌─────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ EventEmitter (事件总线) │ │ │
|
||||
│ │ └─────────────────────────────────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ Managers Layer │ │
|
||||
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
|
||||
│ │ │EngineManager │ │ToolbarManager│ │ DialogManager│ │ │
|
||||
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
|
||||
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
|
||||
│ │ │MeasureDialog │ │SectionDialog │ │WalkControl │ │ │
|
||||
│ │ │Manager │ │Manager │ │Manager │ │ │
|
||||
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
|
||||
│ │ ... (15 个管理器) │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ Components Layer │ │
|
||||
│ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │
|
||||
│ │ │ Engine │ │ Dialog │ │ Tree │ │ Menu │ │ButtonGr│ │ │
|
||||
│ │ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ │ │
|
||||
│ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │
|
||||
│ │ │Collapse│ │ Tab │ │Descript│ │Measure │ │Section │ │ │
|
||||
│ │ │ │ │ │ │ │ │Panel │ │Panel │ │ │
|
||||
│ │ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ │ │
|
||||
│ │ ... (20+ 个组件) │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ Services Layer │ │
|
||||
│ │ ┌──────────────────┐ ┌──────────────────┐ │ │
|
||||
│ │ │ LocaleManager │ │ ThemeManager │ │ │
|
||||
│ │ │ (国际化服务) │ │ (主题服务) │ │ │
|
||||
│ │ └──────────────────┘ └──────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ Core Layer │ │
|
||||
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
|
||||
│ │ │ EventEmitter │ │ BaseManager │ │BaseDialog │ │ │
|
||||
│ │ │ │ │ │ │Manager │ │ │
|
||||
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ External Dependencies │
|
||||
│ ┌──────────────────────┐ ┌──────────────────────┐ │
|
||||
│ │ iflow-engine-base │ │ Three.js │ │
|
||||
│ │ (第三方 3D 引擎核心) │ │ (3D 渲染库) │ │
|
||||
│ └──────────────────────┘ └──────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 分层说明
|
||||
|
||||
### 1. BimEngine (入口层)
|
||||
|
||||
**职责**: 作为 SDK 的唯一入口,整合所有功能,提供简洁的公开 API。
|
||||
|
||||
**设计模式**: 门面模式 (Facade Pattern)
|
||||
|
||||
**核心 API**:
|
||||
- 初始化引擎和容器
|
||||
- 设置主题和语言
|
||||
- 访问各个管理器
|
||||
|
||||
```typescript
|
||||
const engine = new BimEngine('container', {
|
||||
locale: 'zh-CN',
|
||||
theme: 'dark'
|
||||
});
|
||||
|
||||
// 访问管理器
|
||||
engine.engine.loadModel('model.gltf');
|
||||
engine.toolbar.show();
|
||||
engine.measure.show();
|
||||
```
|
||||
|
||||
### 2. ManagerRegistry (注册表层)
|
||||
|
||||
**职责**: 全局单例,集中管理所有 Manager 实例,提供跨 Manager 通信。
|
||||
|
||||
**设计模式**: 单例模式 (Singleton) + 服务定位器 (Service Locator)
|
||||
|
||||
**特点**:
|
||||
- 避免 Manager 之间的循环依赖
|
||||
- 提供类型安全的事件系统
|
||||
- 支持动态访问任意 Manager
|
||||
|
||||
```typescript
|
||||
const registry = ManagerRegistry.getInstance();
|
||||
registry.toolbar?.show();
|
||||
registry.emit('engine:model-loaded', { url: 'model.gltf' });
|
||||
```
|
||||
|
||||
### 3. Managers Layer (管理器层)
|
||||
|
||||
**职责**: 处理业务逻辑,协调组件交互,管理组件生命周期。
|
||||
|
||||
**设计模式**: 模板方法模式 (Template Method)
|
||||
|
||||
**管理器分类**:
|
||||
|
||||
| 类别 | 管理器 | 职责 |
|
||||
|------|--------|------|
|
||||
| 核心 | EngineManager | 3D 引擎管理 |
|
||||
| UI 容器 | ToolbarManager, DialogManager, ButtonGroupManager | 容器组件管理 |
|
||||
| 交互 | RightKeyManager, ComponentDetailManager, ConstructTreeManagerBtn | 用户交互 |
|
||||
| 工具 | MeasureDialogManager, SectionPlaneDialogManager, SectionAxisDialogManager, SectionBoxDialogManager | 3D 操作工具 |
|
||||
| 漫游 | WalkControlManager, WalkPathDialogManager, WalkPlanViewDialogManager, MapDialogManager | 漫游功能 |
|
||||
|
||||
### 4. Components Layer (组件层)
|
||||
|
||||
**职责**: 纯 UI 渲染,不包含业务逻辑。
|
||||
|
||||
**设计模式**: 组合模式 (Composite Pattern)
|
||||
|
||||
**组件接口**:
|
||||
```typescript
|
||||
interface IBimComponent {
|
||||
element: HTMLElement;
|
||||
init(): void;
|
||||
setTheme(theme: ThemeConfig): void;
|
||||
setLocales?(): void;
|
||||
destroy(): void;
|
||||
}
|
||||
```
|
||||
|
||||
**组件分类**:
|
||||
|
||||
| 类别 | 组件 | 说明 |
|
||||
|------|------|------|
|
||||
| 核心 | Engine | 3D 视口容器 |
|
||||
| 容器 | Dialog, Tree, Menu, ButtonGroup | 承载内容的容器组件 |
|
||||
| 面板 | MeasurePanel, SectionPlanePanel, WalkControlPanel | 功能面板 |
|
||||
| 展示 | Collapse, Tab, Description | 数据展示组件 |
|
||||
|
||||
### 5. Services Layer (服务层)
|
||||
|
||||
**职责**: 提供横切关注点的全局服务。
|
||||
|
||||
**设计模式**: 单例模式 + 观察者模式
|
||||
|
||||
| 服务 | 职责 |
|
||||
|------|------|
|
||||
| LocaleManager | 国际化,多语言支持 |
|
||||
| ThemeManager | 主题管理,明暗切换 |
|
||||
|
||||
### 6. Core Layer (核心层)
|
||||
|
||||
**职责**: 提供基础设施和抽象。
|
||||
|
||||
| 类 | 职责 |
|
||||
|-----|------|
|
||||
| EventEmitter | 事件发布/订阅 |
|
||||
| BaseManager | Manager 基类,提供注册表访问和事件管理 |
|
||||
| BaseDialogManager | 对话框 Manager 基类,封装对话框生命周期 |
|
||||
|
||||
## 设计模式详解
|
||||
|
||||
### 1. 单例模式 (Singleton)
|
||||
|
||||
**应用**: ManagerRegistry, LocaleManager, ThemeManager
|
||||
|
||||
**目的**: 确保全局唯一实例,提供全局访问点。
|
||||
|
||||
```typescript
|
||||
export class ManagerRegistry {
|
||||
private static instance: ManagerRegistry | null = null;
|
||||
|
||||
public static getInstance(): ManagerRegistry {
|
||||
if (!ManagerRegistry.instance) {
|
||||
ManagerRegistry.instance = new ManagerRegistry();
|
||||
}
|
||||
return ManagerRegistry.instance;
|
||||
}
|
||||
|
||||
public static reset(): void {
|
||||
ManagerRegistry.instance = null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 观察者模式 (Observer)
|
||||
|
||||
**应用**: EventEmitter, 服务订阅
|
||||
|
||||
**目的**: 解耦事件发送者和接收者,支持多对多通信。
|
||||
|
||||
```typescript
|
||||
// 订阅
|
||||
const unsubscribe = registry.on('engine:model-loaded', (payload) => {
|
||||
console.log('Model loaded:', payload.url);
|
||||
});
|
||||
|
||||
// 发布
|
||||
registry.emit('engine:model-loaded', { url: 'model.gltf' });
|
||||
|
||||
// 取消订阅
|
||||
unsubscribe();
|
||||
```
|
||||
|
||||
### 3. 模板方法模式 (Template Method)
|
||||
|
||||
**应用**: BaseManager, BaseDialogManager
|
||||
|
||||
**目的**: 定义算法骨架,允许子类重写特定步骤。
|
||||
|
||||
```typescript
|
||||
export abstract class BaseDialogManager extends BaseManager {
|
||||
// 模板方法
|
||||
public show(): void {
|
||||
this.destroyDialog();
|
||||
const content = this.createContent(); // 抽象方法
|
||||
this.createDialog(content);
|
||||
this.onDialogCreated(); // 钩子方法
|
||||
}
|
||||
|
||||
// 抽象方法 - 子类必须实现
|
||||
protected abstract createContent(): HTMLElement;
|
||||
|
||||
// 钩子方法 - 子类可选重写
|
||||
protected onDialogCreated(): void {}
|
||||
protected onDialogClose(): void {}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 工厂模式 (Factory)
|
||||
|
||||
**应用**: BimEngine 初始化
|
||||
|
||||
**目的**: 封装对象创建逻辑,统一创建流程。
|
||||
|
||||
```typescript
|
||||
private init() {
|
||||
this.engine = new EngineManager(this.wrapper);
|
||||
this.dialog = new DialogManager(this.wrapper);
|
||||
this.toolbar = new ToolbarManager(this.wrapper);
|
||||
// ... 创建其他管理器
|
||||
}
|
||||
```
|
||||
|
||||
## 数据流
|
||||
|
||||
### 1. 用户交互流
|
||||
|
||||
```
|
||||
用户操作 (点击按钮)
|
||||
↓
|
||||
Toolbar 组件捕获事件
|
||||
↓
|
||||
ToolbarManager 处理
|
||||
↓
|
||||
发送事件到 Registry
|
||||
↓
|
||||
目标 Manager 响应
|
||||
↓
|
||||
更新相关组件 UI
|
||||
```
|
||||
|
||||
### 2. 主题变更流
|
||||
|
||||
```
|
||||
用户调用 setTheme('dark')
|
||||
↓
|
||||
ThemeManager.setTheme()
|
||||
↓
|
||||
更新内部状态
|
||||
↓
|
||||
通知所有订阅者
|
||||
↓
|
||||
各组件 setTheme() 被调用
|
||||
↓
|
||||
更新 CSS 变量和样式
|
||||
```
|
||||
|
||||
### 3. 国际化变更流
|
||||
|
||||
```
|
||||
用户调用 setLocale('en-US')
|
||||
↓
|
||||
LocaleManager.setLocale()
|
||||
↓
|
||||
更新内部状态
|
||||
↓
|
||||
通知所有订阅者
|
||||
↓
|
||||
各组件 setLocales() 被调用
|
||||
↓
|
||||
重新渲染文本内容
|
||||
```
|
||||
|
||||
## 模块依赖关系
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
BimEngine --> ManagerRegistry
|
||||
BimEngine --> LocaleManager
|
||||
BimEngine --> ThemeManager
|
||||
|
||||
ManagerRegistry --> EventEmitter
|
||||
|
||||
EngineManager --> BaseManager
|
||||
ToolbarManager --> BaseManager
|
||||
DialogManager --> BaseManager
|
||||
|
||||
MeasureDialogManager --> BaseDialogManager
|
||||
SectionPlaneDialogManager --> BaseDialogManager
|
||||
WalkControlManager --> BaseManager
|
||||
|
||||
BaseDialogManager --> BaseManager
|
||||
BaseManager --> ManagerRegistry
|
||||
|
||||
Engine --> ThemeManager
|
||||
Dialog --> ThemeManager
|
||||
Tree --> ThemeManager
|
||||
Tree --> LocaleManager
|
||||
Menu --> ThemeManager
|
||||
Menu --> LocaleManager
|
||||
|
||||
ThemeManager --> darkTheme
|
||||
ThemeManager --> lightTheme
|
||||
LocaleManager --> zhCN
|
||||
LocaleManager --> enUS
|
||||
```
|
||||
|
||||
## 扩展点
|
||||
|
||||
### 1. 添加新 Manager
|
||||
|
||||
```typescript
|
||||
import { BaseManager } from '../core/base-manager';
|
||||
|
||||
export class CustomManager extends BaseManager {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public initialize(): void {
|
||||
this.subscribe('engine:model-loaded', this.onModelLoaded.bind(this));
|
||||
}
|
||||
|
||||
private onModelLoaded(payload: any): void {
|
||||
// 处理逻辑
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
super.destroy();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 添加新对话框 Manager
|
||||
|
||||
```typescript
|
||||
import { BaseDialogManager } from '../core/base-dialog-manager';
|
||||
|
||||
export class CustomDialogManager extends BaseDialogManager {
|
||||
protected get dialogId(): string {
|
||||
return 'custom-dialog';
|
||||
}
|
||||
|
||||
protected get dialogTitle(): string {
|
||||
return 'custom.dialogTitle';
|
||||
}
|
||||
|
||||
protected createContent(): HTMLElement {
|
||||
const div = document.createElement('div');
|
||||
// 创建内容
|
||||
return div;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 添加新组件
|
||||
|
||||
```typescript
|
||||
import type { ThemeConfig } from '../themes/types';
|
||||
|
||||
export class CustomComponent {
|
||||
public element: HTMLElement;
|
||||
|
||||
constructor(private options: CustomOptions) {
|
||||
this.element = document.createElement('div');
|
||||
}
|
||||
|
||||
public init(): void {
|
||||
// 初始化
|
||||
}
|
||||
|
||||
public setTheme(theme: ThemeConfig): void {
|
||||
// 应用主题
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
this.element.remove();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 添加新语言
|
||||
|
||||
1. 创建语言文件 `src/locales/ja-JP.ts`
|
||||
2. 更新类型 `src/locales/types.ts`
|
||||
3. 注册到 LocaleManager
|
||||
|
||||
### 5. 添加新主题
|
||||
|
||||
```typescript
|
||||
import { createThemeFromPartial, lightTheme } from 'iflow-engine';
|
||||
|
||||
const customTheme = createThemeFromPartial(lightTheme, {
|
||||
name: 'custom',
|
||||
primary: '#ff6b6b',
|
||||
// 其他自定义属性
|
||||
});
|
||||
|
||||
themeManager.setCustomTheme(customTheme);
|
||||
```
|
||||
|
||||
## 事件系统
|
||||
|
||||
### 事件类型
|
||||
|
||||
| 类别 | 事件 | 数据 |
|
||||
|------|------|------|
|
||||
| UI | `ui:open-dialog` | `{ id: string; data?: any }` |
|
||||
| UI | `ui:close-dialog` | `{ id: string }` |
|
||||
| 引擎 | `engine:model-loaded` | `{ url: string }` |
|
||||
| 引擎 | `engine:object-clicked` | `{ objectId: string; position: Point3D }` |
|
||||
| 树 | `ui:tree-node-check` | `{ id: string; checked: boolean; node: any }` |
|
||||
| 树 | `ui:tree-node-select` | `{ id: string; selected: boolean; node: any }` |
|
||||
| 系统 | `sys:theme-changed` | `{ theme: string }` |
|
||||
| 系统 | `sys:locale-changed` | `{ locale: string }` |
|
||||
| 漫游 | `walk:speed-change` | `{ speed: number }` |
|
||||
| 漫游 | `walk:path-mode-toggle` | `{ isActive: boolean }` |
|
||||
| 地图 | `map:opened` | `{}` |
|
||||
| 地图 | `map:closed` | `{}` |
|
||||
|
||||
### 事件使用
|
||||
|
||||
```typescript
|
||||
// 发送事件
|
||||
registry.emit('engine:model-loaded', { url: 'model.gltf' });
|
||||
|
||||
// 订阅事件
|
||||
const unsubscribe = registry.on('engine:model-loaded', (payload) => {
|
||||
console.log('Model loaded:', payload.url);
|
||||
});
|
||||
|
||||
// 在 Manager 中使用
|
||||
this.subscribe('engine:model-loaded', this.handleModelLoaded.bind(this));
|
||||
this.emit('custom:action', { data: 'value' });
|
||||
```
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 1. 懒加载
|
||||
|
||||
- 组件按需创建,不预先实例化
|
||||
- 对话框在首次 show() 时才创建 DOM
|
||||
|
||||
### 2. 事件清理
|
||||
|
||||
- BaseManager 自动追踪订阅,destroy 时统一清理
|
||||
- 避免内存泄漏
|
||||
|
||||
### 3. DOM 操作优化
|
||||
|
||||
- 使用 requestAnimationFrame 节流拖拽/缩放
|
||||
- 批量 DOM 更新
|
||||
|
||||
### 4. 主题切换
|
||||
|
||||
- 使用 CSS 变量,避免重绘整个组件树
|
||||
- 订阅机制确保只更新必要的组件
|
||||
- `EngineManager` 从“大量透传”收敛为“少量公共 API + 生命周期编排”
|
||||
- 内部 Manager 不再通过 `registry.engine3d?.xxx()` 间接透传,而是通过 `BaseManager.engineComponent` 直接访问 `Engine` 组件
|
||||
- 非 Manager 组件(如 toolbar 按钮、walk-path-panel)通过 `registry.engine3d?.getEngineComponent()?.xxx()` 访问 `Engine`
|
||||
- `Engine.getEngine()` 已移除,改为 `onRawEvent()/offRawEvent()` 订阅底层事件
|
||||
|
||||
---
|
||||
|
||||
**文档生成时间**: 2026-01-23
|
||||
**文档版本**: 1.0.0
|
||||
## 分层结构
|
||||
|
||||
```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),进一步降低单类复杂度。
|
||||
|
||||
Reference in New Issue
Block a user