type Listener = { callback: (...args: unknown[]) => void; context?: unknown; }; type EventMeta = { type: string; description: string; listeners: Listener[]; }; /** * 基础事件发射器 */ export class Emitter { private _events: Record = {}; on(name: string, callback: (...args: unknown[]) => void, context?: unknown): this { if (!this._events[name]) { this._events[name] = []; } this._events[name].push({ callback, context }); return this; } once(name: string, callback: (...args: unknown[]) => void, context?: unknown): this { const onceWrapper = (...args: unknown[]) => { this.off(name, onceWrapper); callback.apply(context, args); }; return this.on(name, onceWrapper, context); } off(name?: string, callback?: (...args: unknown[]) => void): this { if (!name) { this._events = {}; return this; } if (!this._events[name]) return this; if (!callback) { delete this._events[name]; return this; } this._events[name] = this._events[name].filter( listener => listener.callback !== callback ); return this; } removeAllListeners(): this { this._events = {}; return this; } emit(name: string, ...args: unknown[]): this { if (!this._events[name]) return this; this._events[name].forEach(listener => { listener.callback.apply(listener.context, args); }); return this; } listenerCount(name: string): number { return this._events[name]?.length ?? 0; } } /** * 全局事件管理器 */ export class EventManager extends Emitter { private eventMap: Map; constructor() { super(); this.eventMap = new Map(); } registerEvent(type: string, description: string): void { this.eventMap.set(type, { type, description, listeners: [] }); } getRegisteredEvents(): EventMeta[] { return Array.from(this.eventMap.values()); } } // 创建全局事件管理器实例 export const eventManager = new EventManager(); // 注册标准事件类型(描述使用英文,避免编码问题) eventManager.registerEvent('load', 'resource load complete'); eventManager.registerEvent('load-progress', 'resource load progress'); eventManager.registerEvent('load-error', 'resource load error'); eventManager.registerEvent('animation-start', 'animation start'); eventManager.registerEvent('animation-end', 'animation end'); eventManager.registerEvent('animation-loop', 'animation loop'); eventManager.registerEvent('model-change', 'model change'); eventManager.registerEvent('camera-change', 'camera change'); eventManager.registerEvent('scene-ready', 'scene ready'); eventManager.registerEvent('dispose', 'component disposed'); // 导出便捷函数 export function on(eventName: string, callback: (...args: unknown[]) => void, context?: unknown): Emitter { return eventManager.on(eventName, callback, context); } export function off(eventName?: string, callback?: (...args: unknown[]) => void): Emitter { return eventManager.off(eventName, callback); } export function once(eventName: string, callback: (...args: unknown[]) => void, context?: unknown): Emitter { return eventManager.once(eventName, callback, context); } export function emit(eventName: string, ...args: unknown[]): Emitter { return eventManager.emit(eventName, ...args); } export function removeAllListeners(eventName?: string): Emitter { if (eventName) return eventManager.off(eventName); return eventManager.removeAllListeners(); }