init
This commit is contained in:
123
src/utils/event.ts
Normal file
123
src/utils/event.ts
Normal file
@ -0,0 +1,123 @@
|
||||
type Listener = {
|
||||
callback: (...args: unknown[]) => void;
|
||||
context?: unknown;
|
||||
};
|
||||
|
||||
type EventMeta = {
|
||||
type: string;
|
||||
description: string;
|
||||
listeners: Listener[];
|
||||
};
|
||||
|
||||
/**
|
||||
* 基础事件发射器
|
||||
*/
|
||||
export class Emitter {
|
||||
private _events: Record<string, Listener[]> = {};
|
||||
|
||||
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<string, EventMeta>;
|
||||
|
||||
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();
|
||||
}
|
||||
Reference in New Issue
Block a user