Files
bim_engine/docs/ARCHITECTURE.md
yuding 89ae01ffd7 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
2026-01-23 16:27:04 +08:00

18 KiB
Raw Blame History

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:

  • 初始化引擎和容器
  • 设置主题和语言
  • 访问各个管理器
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
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, PropertyPanelManager, ConstructTreeManagerBtn 用户交互
工具 MeasureDialogManager, SectionPlaneDialogManager, SectionAxisDialogManager, SectionBoxDialogManager 3D 操作工具
漫游 WalkControlManager, WalkPathDialogManager, WalkPlanViewDialogManager, MapDialogManager 漫游功能

4. Components Layer (组件层)

职责: 纯 UI 渲染,不包含业务逻辑。

设计模式: 组合模式 (Composite Pattern)

组件接口:

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

目的: 确保全局唯一实例,提供全局访问点。

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, 服务订阅

目的: 解耦事件发送者和接收者,支持多对多通信。

// 订阅
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

目的: 定义算法骨架,允许子类重写特定步骤。

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 初始化

目的: 封装对象创建逻辑,统一创建流程。

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() 被调用
    ↓
重新渲染文本内容

模块依赖关系

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

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

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. 添加新组件

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. 添加新主题

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 {}

事件使用

// 发送事件
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