# Engine 组件详细文档 > 本文档详细描述 Engine 组件的实现细节,包括 API、UI 结构、逻辑流程等,供 AI 根据文档重现组件。 --- ## 1. 组件概述 ### 1.1 基本信息 - **组件名称**: `Engine` - **文件路径**: `src/components/engine/index.ts` - **类型定义**: `src/components/engine/types.ts` - **实现接口**: `IBimComponent` - **用途**: 封装第三方 3D 引擎 SDK,提供统一的 3D 引擎管理接口 ### 1.2 在 SDK 中的位置 - Engine 组件是独立的 3D 引擎组件 - 必须通过 `EngineManager` 使用,不允许直接使用 - `EngineManager` 位于 `src/managers/engine-manager.ts` - 采用延迟初始化模式,需要用户主动调用 `init()` 方法 ### 1.3 第三方 SDK 依赖 - 依赖 `iflow-engine-base` npm 包中的 `createEngine` 函数 - 通过依赖注入方式使用,不直接导入 --- ## 2. 组件类 API 文档 ### 2.1 构造函数 ```typescript constructor(options: EngineOptions) ``` **参数**: - `options`: `EngineOptions` - 3D 引擎配置选项 **默认配置**: ```typescript { backgroundColor: 0x1a1a1a, // 默认深色背景 version: 'v1', // 默认使用 v1 版本 showStats: false, // 默认不显示统计 showViewCube: true // 默认显示视图立方体 } ``` **行为**: - 解析容器元素 - 如果容器没有 id,生成一个唯一的 id - 保存配置选项(设置默认值) ### 2.2 公共方法 #### `init(): void` 初始化组件(实现 `IBimComponent` 接口) **功能**: - 检查是否已初始化或已销毁 - 创建引擎配置对象 - 调用 `createEngineSDK()` 创建引擎实例 - 标记为已初始化 - 订阅主题变化 - 应用当前主题 **错误处理**: - 如果创建失败,抛出错误并标记为未初始化 #### `setTheme(theme: ThemeConfig): void` 设置主题(实现 `IBimComponent` 接口) **参数**: - `theme`: `ThemeConfig` - 全局主题配置 **功能**: - 根据主题名称选择背景色: - `dark`: 使用深色背景 `0x1a1a1a` - `light`: 使用浅色背景 `0xf5f5f5` - `custom`: 使用配置中的 `backgroundColor` 或默认值 - 尝试更新引擎背景色: - 如果引擎有 `setBackgroundColor()` 方法,调用它 - 否则,如果引擎有 `scene.background`,设置其颜色 #### `setLocales(): void` 设置语言(实现 `IBimComponent` 接口) **功能**: - 3D 引擎组件暂时不需要本地化 - 方法为空实现 #### `isInitialized(): boolean` 检查是否已初始化 **返回**: `boolean` - 是否已初始化 #### `loadModel(url: string, options?: ModelLoadOptions): void` 加载 3D 模型 **参数**: - `url`: `string` - 模型文件 URL(必需) - `options`: `ModelLoadOptions` (可选) - 加载选项 **功能**: - 检查引擎是否已初始化 - 检查 URL 是否提供 - 调用引擎的 `loader.loadModel()` 方法加载模型 **加载选项**: - `position`: `[number, number, number]` - 模型位置 [x, y, z] - `rotation`: `[number, number, number]` - 模型旋转(弧度)[x, y, z] - `scale`: `[number, number, number]` - 模型缩放 [x, y, z] - `id`: `string` - 模型 ID(可选) #### `getEngine(): any` 获取原始 3D 引擎实例 **返回**: 第三方 3D 引擎实例或 `null` **功能**: - 返回底层 3D 引擎实例 - 用于直接调用第三方引擎的其他 API #### `destroy(): void` 销毁组件(实现 `IBimComponent` 接口) **功能**: - 取消主题订阅 - 清空容器内容 - 标记为已销毁和未初始化 **注意**: 不销毁引擎实例本身(由第三方 SDK 管理) --- ## 3. 分化组件说明 **Engine 组件没有分化组件**。 --- ## 4. Manager API 文档 ### 4.1 EngineManager 类 **文件路径**: `src/managers/engine-manager.ts` **继承关系**: `EngineManager extends BimComponent` ### 4.2 构造函数 ```typescript constructor(engine: BimEngine, container: HTMLElement) ``` **参数**: - `engine`: `BimEngine` - 引擎实例 - `container`: `HTMLElement` - 3D 引擎挂载的目标容器 **行为**: - 保存容器引用 - **不自动初始化引擎**(延迟初始化模式) ### 4.3 公共方法 #### `initialize(options?: Omit): boolean` 初始化 3D 引擎 **参数**: - `options`: `Omit` (可选) - 引擎配置选项 **返回**: `boolean` - 是否初始化成功 **功能**: - 如果已经初始化,先销毁旧的实例 - 创建 `Engine` 组件实例 - 调用组件的 `init()` 方法初始化引擎 - 返回初始化结果 **错误处理**: - 如果初始化失败,返回 `false` 并输出错误信息 #### `isInitialized(): boolean` 检查 3D 引擎是否已初始化 **返回**: `boolean` - 是否已初始化 #### `loadModel(url: string, options?: ModelLoadOptions): void` 加载 3D 模型 **参数**: - `url`: `string` - 模型文件 URL - `options`: `ModelLoadOptions` (可选) - 加载选项 **功能**: - 检查引擎是否已初始化 - 如果未初始化,输出错误信息 - 调用引擎组件的 `loadModel()` 方法 #### `getEngine(): any` 获取原始 3D 引擎实例 **返回**: 第三方 3D 引擎实例或 `null` **功能**: - 用于直接调用第三方引擎的其他 API - 如果引擎未初始化,返回 `null` 并输出警告 #### `destroy(): void` 销毁 3D 引擎实例 **功能**: - 调用引擎组件的 `destroy()` 方法 - 清空引擎实例引用 --- ## 5. UI 详细描述 ### 5.1 DOM 结构 **Engine 组件不直接创建 UI 元素**,而是: 1. **使用容器元素**: - 容器元素由外部提供(通过 `EngineOptions.container`) - 如果容器没有 id,组件会生成一个唯一的 id 2. **第三方 SDK 创建 UI**: - 第三方 SDK 的 `createEngine()` 函数会在容器内创建 3D 场景 - 可能包括: - Canvas 元素(WebGL 渲染) - 统计面板(如果 `showStats: true`) - 视图立方体(如果 `showViewCube: true`) ### 5.2 容器 ID 生成 **算法**: ```typescript containerId = `engine-container-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; ``` **格式**: `engine-container-[时间戳]-[随机字符串]` **示例**: `engine-container-1704067200000-k3j9x2m1p` ### 5.3 第三方 SDK 配置 **传递给 `createEngine()` 的配置对象**: ```typescript { containerId: string, // 容器 ID backgroundColor: number, // 背景色(十六进制数字) version: 'v1' | 'v2', // WebGL 版本 showStats: boolean, // 是否显示统计 showViewCube: boolean // 是否显示视图立方体 } ``` --- ## 6. 逻辑流程详细描述 ### 6.1 初始化流程 1. **构造函数调用**: - 解析容器元素 - 生成或使用容器 ID - 保存配置选项(设置默认值) 2. **init() 方法执行**(用户主动调用): - 检查是否已初始化,如果是则返回 - 检查是否已销毁,如果是则报错 - 创建引擎配置对象 - 调用 `createEngineSDK()` 创建引擎实例 - 检查引擎实例是否创建成功 - 标记为已初始化 - 订阅主题变化:`themeManager.subscribe()` - 应用当前主题 ### 6.2 生命周期 #### 创建阶段 - 构造函数 → 保存配置 #### 初始化阶段(延迟) - 用户调用 `init()` → 创建引擎实例 → 订阅主题 #### 运行阶段 - 响应主题变更:`setTheme()` 被调用 - 加载模型:`loadModel()` 被调用 - 用户交互:3D 场景交互(由第三方 SDK 处理) #### 销毁阶段 - `destroy()` 被调用 - 取消主题订阅 - 清空容器 - 更新状态 ### 6.3 主题变更流程 1. 主题变更 → `themeManager` 通知订阅者 2. `setTheme()` 方法被调用 3. 根据主题名称选择背景色: - `dark` → `0x1a1a1a` - `light` → `0xf5f5f5` - `custom` → 使用配置值或默认值 4. 尝试更新引擎背景色: - 方法 1: 调用 `engine.setBackgroundColor(backgroundColor)` - 方法 2: 设置 `engine.scene.background.setHex(backgroundColor)` ### 6.4 模型加载流程 1. 用户调用 `loadModel(url, options)` 2. 检查引擎是否已初始化 3. 检查 URL 是否提供 4. 调用 `engine.loader.loadModel(url, options)` 5. 第三方 SDK 处理模型加载 ### 6.5 状态管理 #### 内部状态 - `_isInitialized`: 是否已初始化 - `_isDestroyed`: 是否已销毁 - `engine`: 第三方 3D 引擎实例 - `containerId`: 容器 ID - `options`: 引擎配置选项 #### 订阅管理 - `unsubscribeTheme`: 主题订阅取消函数 ### 6.6 与其他组件的交互 - **与 EngineManager**: 通过 Manager 创建和管理 - **与 ThemeManager**: 订阅主题变更 - **与第三方 SDK**: 通过 `createEngine()` 函数创建引擎实例 --- ## 7. 国际化支持 ### 7.1 使用的翻译键 **Engine 组件不使用翻译键**(3D 引擎不需要国际化)。 ### 7.2 语言变更处理 - `setLocales()` 方法为空实现 - 不订阅语言变更 --- ## 8. 主题支持 ### 8.1 使用的主题变量 - 根据主题名称选择背景色: - `dark` 主题 → `0x1a1a1a`(深色背景) - `light` 主题 → `0xf5f5f5`(浅色背景) - `custom` 主题 → 使用配置值或默认值 ### 8.2 主题变更处理 - 组件订阅 `themeManager.subscribe()` - 主题变更时,`setTheme()` 方法被调用 - 根据主题名称选择背景色 - 尝试更新引擎背景色(通过引擎 API) ### 8.3 实现细节 ```typescript public setTheme(theme: ThemeConfig): void { let backgroundColor: number; if (theme.name === 'dark') { backgroundColor = 0x1a1a1a; } else if (theme.name === 'light') { backgroundColor = 0xf5f5f5; } else { backgroundColor = this.options.backgroundColor ?? 0x1a1a1a; } // 尝试更新引擎背景色 if (this.engine && typeof this.engine.setBackgroundColor === 'function') { this.engine.setBackgroundColor(backgroundColor); } else if (this.engine && this.engine.scene) { if (this.engine.scene.background) { this.engine.scene.background.setHex(backgroundColor); } } } ``` --- ## 9. 使用示例 ### 9.1 基本使用(通过 EngineManager) ```typescript import { BimEngine } from 'iflow-engine'; const engine = new BimEngine('container'); // 初始化 3D 引擎(延迟初始化) const success = engine.initEngine({ backgroundColor: 0x333333, version: 'v1', showStats: true, showViewCube: true }); if (success) { console.log('3D 引擎初始化成功'); } // 加载模型 engine.engine.loadModel('/model/building.glb', { position: [0, 0, 0], rotation: [0, 0, 0], scale: [1, 1, 1] }); ``` ### 9.2 高级使用 ```typescript // 检查引擎是否已初始化 if (engine.engine.isInitialized()) { // 加载模型 engine.engine.loadModel('/model/model.glb'); } // 获取原始引擎实例,调用第三方 API const rawEngine = engine.engine.getEngine(); if (rawEngine) { // 调用第三方 SDK 的其他方法 rawEngine.someOtherMethod(); } ``` ### 9.3 主题切换 ```typescript // 切换主题会自动更新 3D 场景背景色 engine.setTheme('dark'); // 深色背景 engine.setTheme('light'); // 浅色背景 ``` --- ## 10. 实现细节(供 AI 重现) ### 10.1 关键算法 #### 容器 ID 生成算法 ```typescript function generateContainerId(): string { const timestamp = Date.now(); const random = Math.random().toString(36).substr(2, 9); return `engine-container-${timestamp}-${random}`; } ``` #### 主题背景色选择算法 ```typescript function selectBackgroundColor(theme: ThemeConfig, defaultColor: number): number { if (theme.name === 'dark') { return 0x1a1a1a; // 深色背景 } else if (theme.name === 'light') { return 0xf5f5f5; // 浅色背景 } else { return defaultColor; // 自定义主题,使用配置值 } } ``` #### 引擎背景色更新算法 ```typescript function updateEngineBackground(engine: any, color: number): void { // 方法 1: 如果引擎有 setBackgroundColor 方法 if (engine && typeof engine.setBackgroundColor === 'function') { engine.setBackgroundColor(color); return; } // 方法 2: 如果引擎有 scene.background if (engine && engine.scene && engine.scene.background) { engine.scene.background.setHex(color); return; } // 方法 3: 无法更新(引擎可能不支持) } ``` ### 10.2 性能优化点 1. **延迟初始化**: - 引擎不自动初始化,由用户主动调用 - 减少不必要的资源消耗 2. **状态检查**: - 初始化前检查状态,避免重复初始化 - 销毁后禁止初始化,避免错误 3. **错误处理**: - 所有操作都有错误检查 - 提供有意义的错误信息 ### 10.3 注意事项和边界情况 1. **容器 ID 唯一性**: - 容器 ID 必须唯一 - 如果容器已有 id,使用现有 id - 如果容器没有 id,生成唯一 id 2. **延迟初始化**: - 引擎不会自动初始化 - 用户必须主动调用 `init()` 或 `initialize()` - 初始化前调用其他方法会报错 3. **引擎实例管理**: - 引擎实例由第三方 SDK 创建 - 组件不负责销毁引擎实例本身 - 只负责清理订阅和容器 4. **主题更新兼容性**: - 不同第三方 SDK 的 API 可能不同 - 需要尝试多种方式更新背景色 - 如果都不支持,静默失败 5. **模型加载**: - 模型 URL 必须是可访问的 - 模型格式由第三方 SDK 支持 - 加载选项由第三方 SDK 处理 6. **错误处理**: - 初始化失败时,标记为未初始化 - 提供有意义的错误信息 - 不抛出未捕获的异常 7. **第三方 SDK 依赖**: - 依赖 `iflow-engine-base` npm 包 - 通过 npm 包导入 - 需要确保依赖已安装 --- ## 11. 类型定义 ### 11.1 EngineOptions ```typescript interface EngineOptions { container: HTMLElement; // 容器元素(必需) backgroundColor?: number; // 背景颜色(可选,默认 0x1a1a1a) version?: 'v1' | 'v2'; // WebGL 版本(可选,默认 'v1') showStats?: boolean; // 是否显示性能统计(可选,默认 false) showViewCube?: boolean; // 是否显示视图立方体(可选,默认 true) } ``` ### 11.2 ModelLoadOptions ```typescript interface ModelLoadOptions { position?: [number, number, number]; // 模型位置 [x, y, z](可选) rotation?: [number, number, number]; // 模型旋转(弧度)[x, y, z](可选) scale?: [number, number, number]; // 模型缩放 [x, y, z](可选) id?: string; // 模型 ID(可选) } ``` --- ## 12. 文件清单 ### 12.1 相关文件 - `src/components/engine/index.ts` - 主组件类 - `src/components/engine/types.ts` - 类型定义 - `src/managers/engine-manager.ts` - 管理器类 - `iflow-engine-base` - 第三方 SDK(npm 依赖) ### 12.2 依赖文件 - `src/types/component.ts` - IBimComponent 接口 - `src/themes/types.ts` - ThemeConfig 类型 - `src/services/theme.ts` - ThemeManager --- ## 13. 更新记录 | 日期 | 修改内容 | 修改人 | |------|---------|--------| | 2024-XX-XX | 初始创建 | AI Assistant | --- **重要提醒**: 本文档必须与组件代码保持同步。任何组件修改都必须更新本文档!