feat: upgrade iflow-engine-base to v1.0.5, add pause/resume rendering API
- Update iflow-engine-base from 1.0.1 to 1.0.5 - Change default engine version from v1 to v2 - Add pauseRendering() and resumeRendering() methods - Add switch model feature in demos - Update model URLs in demos - Add new documentation files
This commit is contained in:
386
docs/MODULES/core.md
Normal file
386
docs/MODULES/core.md
Normal file
@@ -0,0 +1,386 @@
|
||||
# Core 模块文档
|
||||
|
||||
## 模块概述
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **模块名** | core |
|
||||
| **职责** | 提供 SDK 的核心基础设施:事件发射、Manager 注册表、Manager 生命周期管理 |
|
||||
| **公开 API** | 4 个类 |
|
||||
| **状态** | ✅ 稳定 |
|
||||
|
||||
## 代码地图
|
||||
|
||||
```
|
||||
src/core/
|
||||
├── event-emitter.ts # 事件发射器
|
||||
├── manager-registry.ts # Manager 注册表(单例)
|
||||
├── base-manager.ts # Manager 抽象基类
|
||||
└── base-dialog-manager.ts # 对话框 Manager 基类
|
||||
```
|
||||
|
||||
| 文件 | 行数 | 职责 | 导出 |
|
||||
|------|------|------|------|
|
||||
| `event-emitter.ts` | 70 | 发布/订阅事件系统 | `EventEmitter` |
|
||||
| `manager-registry.ts` | 127 | 全局单例注册表 | `ManagerRegistry` |
|
||||
| `base-manager.ts` | 57 | Manager 基类 | `BaseManager` |
|
||||
| `base-dialog-manager.ts` | 145 | 对话框 Manager 基类 | `BaseDialogManager` |
|
||||
|
||||
## 架构设计
|
||||
|
||||
### 类关系图
|
||||
|
||||
```
|
||||
EventEmitter
|
||||
↑ (组合)
|
||||
ManagerRegistry (单例)
|
||||
↑ (访问)
|
||||
BaseManager (抽象类)
|
||||
↑ (继承)
|
||||
BaseDialogManager (抽象类)
|
||||
↑ (继承)
|
||||
具体 Manager 类
|
||||
```
|
||||
|
||||
### 设计模式
|
||||
|
||||
| 模式 | 应用 | 说明 |
|
||||
|------|------|------|
|
||||
| 单例模式 | ManagerRegistry | 全局唯一实例 |
|
||||
| 发布/订阅 | EventEmitter | 解耦事件通信 |
|
||||
| 模板方法 | BaseDialogManager | 定义对话框生命周期 |
|
||||
|
||||
---
|
||||
|
||||
## EventEmitter
|
||||
|
||||
### 概述
|
||||
|
||||
轻量级事件发射器,提供发布/订阅功能。
|
||||
|
||||
### API
|
||||
|
||||
```typescript
|
||||
class EventEmitter {
|
||||
// 订阅事件,返回取消订阅函数
|
||||
on(event: string, listener: (payload: any) => void): () => void;
|
||||
|
||||
// 取消订阅
|
||||
off(event: string, listener: (payload: any) => void): void;
|
||||
|
||||
// 发送事件
|
||||
emit(event: string, payload?: any): void;
|
||||
|
||||
// 清除所有监听器
|
||||
clear(): void;
|
||||
}
|
||||
```
|
||||
|
||||
### 使用示例
|
||||
|
||||
```typescript
|
||||
const emitter = new EventEmitter();
|
||||
|
||||
// 订阅
|
||||
const unsubscribe = emitter.on('user:login', (data) => {
|
||||
console.log('User logged in:', data);
|
||||
});
|
||||
|
||||
// 发送
|
||||
emitter.emit('user:login', { userId: 123 });
|
||||
|
||||
// 取消订阅
|
||||
unsubscribe();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ManagerRegistry
|
||||
|
||||
### 概述
|
||||
|
||||
全局单例注册表,集中管理所有 Manager 实例,提供跨 Manager 通信。
|
||||
|
||||
### API
|
||||
|
||||
```typescript
|
||||
class ManagerRegistry {
|
||||
// 获取单例
|
||||
static getInstance(): ManagerRegistry;
|
||||
|
||||
// 重置单例(用于测试)
|
||||
static reset(): void;
|
||||
|
||||
// 容器元素
|
||||
container: HTMLElement | null;
|
||||
wrapper: HTMLElement | null;
|
||||
|
||||
// Manager 实例
|
||||
toolbar: ToolbarManager | null;
|
||||
dialog: DialogManager | null;
|
||||
engine3d: EngineManager | null;
|
||||
buttonGroup: ButtonGroupManager | null;
|
||||
rightKey: RightKeyManager | null;
|
||||
constructTree: ConstructTreeManagerBtn | null;
|
||||
propertyPanel: PropertyPanelManager | null;
|
||||
measure: MeasureDialogManager | null;
|
||||
walkControl: WalkControlManager | null;
|
||||
map: MapDialogManager | null;
|
||||
sectionPlane: SectionPlaneDialogManager | null;
|
||||
sectionAxis: SectionAxisDialogManager | null;
|
||||
sectionBox: SectionBoxDialogManager | null;
|
||||
|
||||
// 事件方法
|
||||
emit<K extends keyof EngineEvents>(event: K, payload: EngineEvents[K]): void;
|
||||
on<K extends keyof EngineEvents>(event: K, listener: (payload: EngineEvents[K]) => void): () => void;
|
||||
off<K extends keyof EngineEvents>(event: K, listener: (payload: EngineEvents[K]) => void): void;
|
||||
clearEvents(): void;
|
||||
}
|
||||
```
|
||||
|
||||
### 使用示例
|
||||
|
||||
```typescript
|
||||
const registry = ManagerRegistry.getInstance();
|
||||
|
||||
// 访问 Manager
|
||||
registry.toolbar?.show();
|
||||
registry.measure?.switchMode('distance');
|
||||
|
||||
// 发送事件
|
||||
registry.emit('engine:model-loaded', { url: 'model.gltf' });
|
||||
|
||||
// 订阅事件
|
||||
const unsubscribe = registry.on('engine:object-clicked', (payload) => {
|
||||
console.log('Object clicked:', payload.objectId);
|
||||
});
|
||||
```
|
||||
|
||||
### 支持的事件
|
||||
|
||||
| 事件 | 数据类型 | 说明 |
|
||||
|------|---------|------|
|
||||
| `ui:open-dialog` | `{ id: string; data?: any }` | 打开对话框 |
|
||||
| `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` | `{}` | 地图关闭 |
|
||||
|
||||
---
|
||||
|
||||
## BaseManager
|
||||
|
||||
### 概述
|
||||
|
||||
所有 Manager 的抽象基类,提供注册表访问和事件订阅管理。
|
||||
|
||||
### API
|
||||
|
||||
```typescript
|
||||
abstract class BaseManager {
|
||||
// 受保护属性
|
||||
protected registry: ManagerRegistry;
|
||||
|
||||
// 受保护方法
|
||||
protected subscribe<K extends keyof EngineEvents>(
|
||||
event: K,
|
||||
handler: (payload: EngineEvents[K]) => void
|
||||
): void;
|
||||
|
||||
protected emit<K extends keyof EngineEvents>(
|
||||
event: K,
|
||||
payload: EngineEvents[K]
|
||||
): void;
|
||||
|
||||
// 公开方法
|
||||
destroy(): void;
|
||||
}
|
||||
```
|
||||
|
||||
### 使用示例
|
||||
|
||||
```typescript
|
||||
export class CustomManager extends BaseManager {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public initialize(): void {
|
||||
// 订阅事件(自动管理生命周期)
|
||||
this.subscribe('engine:model-loaded', (payload) => {
|
||||
console.log('Model loaded:', payload.url);
|
||||
});
|
||||
}
|
||||
|
||||
public doSomething(): void {
|
||||
// 发送事件
|
||||
this.emit('custom:action', { data: 'value' });
|
||||
|
||||
// 访问其他 Manager
|
||||
this.registry.toolbar?.show();
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
// 自动清理所有订阅
|
||||
super.destroy();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 特性
|
||||
|
||||
- **自动资源清理**: `destroy()` 时自动取消所有订阅
|
||||
- **类型安全**: 使用 TypeScript 泛型确保事件类型
|
||||
- **注册表访问**: 可通过 `this.registry` 访问所有 Manager
|
||||
|
||||
---
|
||||
|
||||
## BaseDialogManager
|
||||
|
||||
### 概述
|
||||
|
||||
对话框 Manager 的抽象基类,封装对话框的完整生命周期。
|
||||
|
||||
### API
|
||||
|
||||
```typescript
|
||||
abstract class BaseDialogManager extends BaseManager {
|
||||
// 抽象属性(子类必须实现)
|
||||
protected abstract get dialogId(): string;
|
||||
protected abstract get dialogTitle(): string;
|
||||
|
||||
// 抽象方法(子类必须实现)
|
||||
protected abstract createContent(): HTMLElement;
|
||||
|
||||
// 可选属性(子类可重写)
|
||||
protected get dialogWidth(): number; // 默认: 300
|
||||
protected get dialogHeight(): number | 'auto'; // 默认: 'auto'
|
||||
protected get dialogOptions(): DialogManagerOptions;
|
||||
|
||||
// 钩子方法(子类可重写)
|
||||
protected onDialogCreated(): void;
|
||||
protected onDialogClose(): void;
|
||||
protected onBeforeDestroy(): void;
|
||||
protected getDialogPosition(): { x: number; y: number };
|
||||
|
||||
// 公开方法
|
||||
show(): void;
|
||||
hide(): void;
|
||||
toggle(): void;
|
||||
isOpen(): boolean;
|
||||
destroy(): void;
|
||||
}
|
||||
|
||||
interface DialogManagerOptions {
|
||||
draggable?: boolean; // 默认 true
|
||||
resizable?: boolean; // 默认 false
|
||||
}
|
||||
```
|
||||
|
||||
### 使用示例
|
||||
|
||||
```typescript
|
||||
export class MeasureDialogManager extends BaseDialogManager {
|
||||
private panel: MeasurePanel | null = null;
|
||||
|
||||
protected get dialogId(): string {
|
||||
return 'measure-dialog';
|
||||
}
|
||||
|
||||
protected get dialogTitle(): string {
|
||||
return 'measure.dialogTitle'; // i18n key
|
||||
}
|
||||
|
||||
protected get dialogWidth(): number {
|
||||
return 250;
|
||||
}
|
||||
|
||||
protected createContent(): HTMLElement {
|
||||
this.panel = new MeasurePanel({
|
||||
onModeChange: (mode) => {
|
||||
this.registry.engine3d?.activateMeasure(mode);
|
||||
}
|
||||
});
|
||||
this.panel.init();
|
||||
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.appendChild(this.panel.element);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
protected onDialogCreated(): void {
|
||||
this.dialog?.fitHeight(false);
|
||||
}
|
||||
|
||||
protected onDialogClose(): void {
|
||||
this.registry.toolbar?.setBtnActive('measure', false);
|
||||
}
|
||||
|
||||
protected onBeforeDestroy(): void {
|
||||
this.panel?.destroy();
|
||||
this.panel = null;
|
||||
}
|
||||
|
||||
// 业务方法
|
||||
public switchMode(mode: string): void {
|
||||
this.panel?.switchMode(mode);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 生命周期
|
||||
|
||||
```
|
||||
show()
|
||||
↓
|
||||
销毁旧对话框
|
||||
↓
|
||||
createContent() ← 子类实现
|
||||
↓
|
||||
创建 BimDialog
|
||||
↓
|
||||
onDialogCreated() ← 钩子
|
||||
↓
|
||||
显示中...
|
||||
↓
|
||||
hide() / 关闭按钮
|
||||
↓
|
||||
onDialogClose() ← 钩子
|
||||
↓
|
||||
onBeforeDestroy() ← 钩子
|
||||
↓
|
||||
销毁对话框
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 依赖关系
|
||||
|
||||
```
|
||||
BaseDialogManager
|
||||
↓ 继承
|
||||
BaseManager
|
||||
↓ 依赖
|
||||
ManagerRegistry
|
||||
↓ 组合
|
||||
EventEmitter
|
||||
```
|
||||
|
||||
### 被依赖情况
|
||||
|
||||
| 模块 | 依赖方式 |
|
||||
|------|---------|
|
||||
| managers/* | 继承 BaseManager 或 BaseDialogManager |
|
||||
| components/* | 间接依赖(通过 Manager) |
|
||||
| BimEngine | 使用 ManagerRegistry |
|
||||
|
||||
---
|
||||
|
||||
**文档生成时间**: 2026-01-23
|
||||
Reference in New Issue
Block a user