declare const __APP_VERSION__: string; import './bim-engine.css'; import { DialogManager } from './managers/dialog-manager'; import { EngineManager } from './managers/engine-manager'; import { RightKeyManager } from './managers/right-key-manager'; import { RadialToolbarManager } from './managers/radial-toolbar-manager'; import { BottomDockManager } from './managers/bottom-dock-manager'; import { MeasureDockManager } from './managers/measure-dock-manager'; import { SectionDockManager } from './managers/section-dock-manager'; import { WalkDockManager } from './managers/walk-dock-manager'; import { MeasureDialogManager } from './managers/measure-dialog-manager'; import { SectionPlaneDialogManager } from './managers/section-plane-dialog-manager'; import { SectionAxisDialogManager } from './managers/section-axis-dialog-manager'; import { SectionBoxDialogManager } from './managers/section-box-dialog-manager'; import { WalkControlManager } from './managers/walk-control-manager'; import { EngineInfoDialogManager } from './managers/engine-info-dialog-manager'; import { SettingDialogManager } from './managers/setting-dialog-manager'; import { ComponentDetailManager } from './managers/component-detail-manager'; import { AiChatManager } from './managers/ai-chat-manager'; import type { EngineOptions, ModelLoadOptions } from './components/engine'; import { localeManager } from './services/locale'; import { themeManager } from './services/theme'; import type { LocaleType } from './locales/types'; import type { ThemeType, ThemeConfig } from './themes/types'; import { ManagerRegistry } from './core/manager-registry'; import { EngineEvents } from './types/events'; export type { EngineOptions, ModelLoadOptions }; /** * CusBimEngine - 定制版 BIM 引擎 * 移除了 ButtonGroupManager、ConstructTreeManagerBtn 和 ToolbarManager */ export class CusBimEngine { public container: HTMLElement; private wrapper: HTMLElement | null = null; private sizeEl: HTMLElement | null = null; private resizeObserver: ResizeObserver | null = null; private lastSyncedWidth = -1; private lastSyncedHeight = -1; private unsubscribeTheme: (() => void) | null = null; private registry: ManagerRegistry; public dialog: DialogManager | null = null; public engine: EngineManager | null = null; public rightKey: RightKeyManager | null = null; public radialToolbar: RadialToolbarManager | null = null; public bottomDock: BottomDockManager | null = null; public measureDock: MeasureDockManager | null = null; public sectionDock: SectionDockManager | null = null; public walkDock: WalkDockManager | null = null; public measure: MeasureDialogManager | null = null; public sectionPlane: SectionPlaneDialogManager | null = null; public sectionAxis: SectionAxisDialogManager | null = null; public sectionBox: SectionBoxDialogManager | null = null; public walkControl: WalkControlManager | null = null; public engineInfo: EngineInfoDialogManager | null = null; public componentDetail: ComponentDetailManager | null = null; public aiChat: AiChatManager | null = null; public setting: SettingDialogManager | null = null; private readonly handleWindowResize = () => { this.updateClientSizeDisplay(); }; constructor( container: HTMLElement | string, options?: { locale?: LocaleType; theme?: ThemeType; } ) { const el = typeof container === 'string' ? document.getElementById(container) : container; if (!el) throw new Error('Container not found'); this.container = el; this.registry = new ManagerRegistry(); if (options?.locale) localeManager.setLocale(options.locale); if (options?.theme) { if (options.theme === 'custom') { console.warn('Custom theme should be set via setCustomTheme().'); } else { themeManager.setTheme(options.theme); } } this.init(); } public emit(event: K, payload: EngineEvents[K]) { this.registry.emit(event, payload); } /** * 订阅事件 * @param event 事件名称 * @param listener 事件监听器 * @returns 取消订阅函数 */ public on(event: K, listener: (payload: EngineEvents[K]) => void): () => void { return this.registry.on(event, listener); } public setLocale(locale: LocaleType) { localeManager.setLocale(locale); } public getLocale(): LocaleType { return localeManager.getLocale(); } public setTheme(theme: 'dark' | 'light') { themeManager.setTheme(theme); } public setCustomTheme(theme: ThemeConfig) { themeManager.setCustomTheme(theme); } private init() { this.container.innerHTML = ''; this.wrapper = document.createElement('div'); this.wrapper.className = 'bim-engine-wrapper'; this.container.appendChild(this.wrapper); const versionEl = document.createElement('div'); versionEl.className = 'bim-engine-version'; versionEl.textContent = `v${__APP_VERSION__}`; this.wrapper.appendChild(versionEl); this.sizeEl = document.createElement('div'); this.sizeEl.className = 'bim-engine-size'; this.wrapper.appendChild(this.sizeEl); this.updateClientSizeDisplay(); this.bindSizeObserver(); this.registry.container = this.container; this.registry.wrapper = this.wrapper; this.engine = new EngineManager(this.wrapper, this.registry); this.dialog = new DialogManager(this.wrapper, this.registry); this.rightKey = new RightKeyManager(this.wrapper, this.registry); this.bottomDock = new BottomDockManager(this.wrapper, this.registry); this.registry.bottomDock = this.bottomDock; this.registry.engine3d = this.engine; this.registry.dialog = this.dialog; this.registry.rightKey = this.rightKey; this.measureDock = new MeasureDockManager(this.registry); this.registry.measureDock = this.measureDock; this.measureDock.init(); this.sectionDock = new SectionDockManager(this.registry); this.registry.sectionDock = this.sectionDock; this.sectionDock.init(); this.walkDock = new WalkDockManager(this.registry); this.registry.walkDock = this.walkDock; this.walkDock.init(); this.radialToolbar = new RadialToolbarManager(this.wrapper, this.registry); this.measure = new MeasureDialogManager(this.registry); this.sectionPlane = new SectionPlaneDialogManager(this.registry); this.sectionAxis = new SectionAxisDialogManager(this.registry); this.sectionBox = new SectionBoxDialogManager(this.registry); this.walkControl = new WalkControlManager(this.registry); this.walkControl.init(); this.engineInfo = new EngineInfoDialogManager(this.registry); this.engineInfo.init(); this.registry.radialToolbar = this.radialToolbar; this.registry.measure = this.measure; this.registry.sectionPlane = this.sectionPlane; this.registry.sectionAxis = this.sectionAxis; this.registry.sectionBox = this.sectionBox; this.registry.walkControl = this.walkControl; this.registry.engineInfo = this.engineInfo; this.componentDetail = new ComponentDetailManager(this.registry); this.registry.componentDetail = this.componentDetail; this.componentDetail.init(); this.aiChat = new AiChatManager(this.registry); this.registry.aiChat = this.aiChat; this.aiChat.init(); this.setting = new SettingDialogManager(this.registry); this.registry.setting = this.setting; this.setting.init(); this.updateTheme(themeManager.getTheme()); this.unsubscribeTheme = themeManager.subscribe((theme) => { this.updateTheme(theme); }); } private updateTheme(theme: ThemeConfig) { if (this.wrapper) { this.wrapper.style.color = theme.textPrimary; } } private updateClientSizeDisplay(): void { const width = this.container.clientWidth; const height = this.container.clientHeight; if (this.sizeEl) { this.sizeEl.textContent = `${width}px x ${height}px`; } this.syncEngineSize(width, height); } private syncEngineSize(width: number, height: number): void { if (width <= 0 || height <= 0) { return; } if (width === this.lastSyncedWidth && height === this.lastSyncedHeight) { return; } this.lastSyncedWidth = width; this.lastSyncedHeight = height; this.engine?.getEngineComponent()?.resize(width, height); } private bindSizeObserver(): void { if (typeof ResizeObserver !== 'undefined') { this.resizeObserver = new ResizeObserver(() => { this.updateClientSizeDisplay(); }); this.resizeObserver.observe(this.container); return; } window.addEventListener('resize', this.handleWindowResize); } private unbindSizeObserver(): void { if (this.resizeObserver) { this.resizeObserver.disconnect(); this.resizeObserver = null; return; } window.removeEventListener('resize', this.handleWindowResize); } public destroy() { this.unbindSizeObserver(); if (this.unsubscribeTheme) { this.unsubscribeTheme(); this.unsubscribeTheme = null; } this.radialToolbar?.destroy(); this.measureDock?.destroy(); this.sectionDock?.destroy(); this.walkDock?.destroy(); this.bottomDock?.destroy(); this.engine?.destroy(); this.dialog?.destroy(); this.rightKey?.destroy(); this.measure?.destroy(); this.sectionPlane?.destroy(); this.sectionAxis?.destroy(); this.sectionBox?.destroy(); this.walkControl?.destroy(); this.aiChat?.destroy(); this.setting?.destroy(); this.sizeEl = null; this.lastSyncedWidth = -1; this.lastSyncedHeight = -1; this.container.innerHTML = ''; this.registry.reset(); } }