Files
bim_engine/docs/架构设计.md

503 lines
18 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 是一个面向开发者的 BIM 3D 引擎 SDK采用分层架构设计提供模型查看、测量、剖切、漫游等功能。
## 架构图
```
┌─────────────────────────────────────────────────────────────────┐
│ 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 变量,避免重绘整个组件树
- 订阅机制确保只更新必要的组件
---
**文档生成时间**: 2026-01-23
**文档版本**: 1.0.0