Files
bim_engine/docs/MODULES/core.md

387 lines
8.6 KiB
Markdown
Raw Normal View History

# 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