Files
esengine/src/ECS/Core/EventBus.ts

497 lines
14 KiB
TypeScript
Raw Normal View History

import {
IEventBus,
IEventListenerConfig,
IEventStats,
IEventData,
IEntityEventData,
IComponentEventData,
ISystemEventData,
ISceneEventData,
IPerformanceEventData
} from '../../Types';
import {
TypeSafeEventSystem,
EventListenerConfig,
EventStats
} from './EventSystem';
import {
ECSEventType,
EventPriority,
EVENT_TYPES,
EventTypeValidator
} from '../CoreEvents';
/**
* 线
* TypeSafeEventSystem
*/
export class EventBus implements IEventBus {
private eventSystem: TypeSafeEventSystem;
private eventIdCounter = 0;
private isDebugMode = false;
constructor(debugMode: boolean = false) {
this.eventSystem = new TypeSafeEventSystem();
this.isDebugMode = debugMode;
}
/**
*
* @param eventType
* @param data
*/
public emit<T>(eventType: string, data: T): void {
this.validateEventType(eventType);
// 增强事件数据
const enhancedData = this.enhanceEventData(eventType, data);
if (this.isDebugMode) {
console.log(`[EventBus] Emitting event: ${eventType}`, enhancedData);
}
this.eventSystem.emitSync(eventType, enhancedData);
}
/**
*
* @param eventType
* @param data
*/
public async emitAsync<T>(eventType: string, data: T): Promise<void> {
this.validateEventType(eventType);
// 增强事件数据
const enhancedData = this.enhanceEventData(eventType, data);
if (this.isDebugMode) {
console.log(`[EventBus] Emitting async event: ${eventType}`, enhancedData);
}
await this.eventSystem.emit(eventType, enhancedData);
}
/**
*
* @param eventType
* @param handler
* @param config
* @returns ID
*/
public on<T>(
eventType: string,
handler: (data: T) => void,
config: IEventListenerConfig = {}
): string {
this.validateEventType(eventType);
const eventConfig: EventListenerConfig = {
once: config.once || false,
priority: config.priority || EventPriority.NORMAL,
async: config.async || false,
context: config.context
};
if (this.isDebugMode) {
console.log(`[EventBus] Adding listener for: ${eventType}`, eventConfig);
}
return this.eventSystem.on(eventType, handler, eventConfig);
}
/**
*
* @param eventType
* @param handler
* @param config
* @returns ID
*/
public once<T>(
eventType: string,
handler: (data: T) => void,
config: IEventListenerConfig = {}
): string {
return this.on(eventType, handler, { ...config, once: true });
}
/**
*
* @param eventType
* @param handler
* @param config
* @returns ID
*/
public onAsync<T>(
eventType: string,
handler: (data: T) => Promise<void>,
config: IEventListenerConfig = {}
): string {
return this.on(eventType, handler as any, { ...config, async: true });
}
/**
*
* @param eventType
* @param listenerId ID
*/
public off(eventType: string, listenerId: string): boolean {
if (this.isDebugMode) {
console.log(`[EventBus] Removing listener: ${listenerId} for event: ${eventType}`);
}
return this.eventSystem.off(eventType, listenerId);
}
/**
*
* @param eventType
*/
public offAll(eventType: string): void {
if (this.isDebugMode) {
console.log(`[EventBus] Removing all listeners for event: ${eventType}`);
}
this.eventSystem.offAll(eventType);
}
/**
*
* @param eventType
*/
public hasListeners(eventType: string): boolean {
return this.eventSystem.hasListeners(eventType);
}
/**
*
* @param eventType
*/
public getStats(eventType?: string): IEventStats | Map<string, IEventStats> {
const stats = this.eventSystem.getStats(eventType);
if (stats instanceof Map) {
// 转换Map中的每个EventStats为IEventStats
const result = new Map<string, IEventStats>();
stats.forEach((stat, key) => {
result.set(key, this.convertEventStats(stat));
});
return result;
} else {
return this.convertEventStats(stats);
}
}
/**
*
*/
public clear(): void {
if (this.isDebugMode) {
console.log('[EventBus] Clearing all listeners');
}
this.eventSystem.clear();
}
/**
*
* @param enabled
*/
public setEnabled(enabled: boolean): void {
this.eventSystem.setEnabled(enabled);
}
/**
*
* @param debug
*/
public setDebugMode(debug: boolean): void {
this.isDebugMode = debug;
}
/**
*
* @param max
*/
public setMaxListeners(max: number): void {
this.eventSystem.setMaxListeners(max);
}
/**
*
* @param eventType
*/
public getListenerCount(eventType: string): number {
return this.eventSystem.getListenerCount(eventType);
}
/**
*
* @param eventType
* @param batchSize
* @param delay
*/
public setBatchConfig(eventType: string, batchSize: number, delay: number): void {
this.eventSystem.setBatchConfig(eventType, {
batchSize,
delay,
enabled: true
});
}
/**
*
* @param eventType
*/
public flushBatch(eventType: string): void {
this.eventSystem.flushBatch(eventType);
}
/**
*
* @param eventType
*/
public resetStats(eventType?: string): void {
this.eventSystem.resetStats(eventType);
}
// 便捷方法发射预定义的ECS事件
/**
*
* @param entityData
*/
public emitEntityCreated(entityData: IEntityEventData): void {
this.emit(ECSEventType.ENTITY_CREATED, entityData);
}
/**
*
* @param entityData
*/
public emitEntityDestroyed(entityData: IEntityEventData): void {
this.emit(ECSEventType.ENTITY_DESTROYED, entityData);
}
/**
*
* @param componentData
*/
public emitComponentAdded(componentData: IComponentEventData): void {
this.emit(ECSEventType.COMPONENT_ADDED, componentData);
}
/**
*
* @param componentData
*/
public emitComponentRemoved(componentData: IComponentEventData): void {
this.emit(ECSEventType.COMPONENT_REMOVED, componentData);
}
/**
*
* @param systemData
*/
public emitSystemAdded(systemData: ISystemEventData): void {
this.emit(ECSEventType.SYSTEM_ADDED, systemData);
}
/**
*
* @param systemData
*/
public emitSystemRemoved(systemData: ISystemEventData): void {
this.emit(ECSEventType.SYSTEM_REMOVED, systemData);
}
/**
*
* @param sceneData
*/
public emitSceneChanged(sceneData: ISceneEventData): void {
2025-06-12 09:43:57 +08:00
this.emit(ECSEventType.SCENE_ACTIVATED, sceneData);
}
/**
*
* @param performanceData
*/
public emitPerformanceWarning(performanceData: IPerformanceEventData): void {
this.emit(ECSEventType.PERFORMANCE_WARNING, performanceData);
}
// 便捷方法监听预定义的ECS事件
/**
*
* @param handler
* @param config
*/
public onEntityCreated(
handler: (data: IEntityEventData) => void,
config?: IEventListenerConfig
): string {
return this.on(ECSEventType.ENTITY_CREATED, handler, config);
}
/**
*
* @param handler
* @param config
*/
public onComponentAdded(
handler: (data: IComponentEventData) => void,
config?: IEventListenerConfig
): string {
return this.on(ECSEventType.COMPONENT_ADDED, handler, config);
}
/**
*
* @param handler
* @param config
*/
public onSystemError(
handler: (data: ISystemEventData) => void,
config?: IEventListenerConfig
): string {
return this.on(ECSEventType.SYSTEM_ERROR, handler, config);
}
/**
*
* @param handler
* @param config
*/
public onPerformanceWarning(
handler: (data: IPerformanceEventData) => void,
config?: IEventListenerConfig
): string {
return this.on(ECSEventType.PERFORMANCE_WARNING, handler, config);
}
// 私有方法
/**
*
* @param eventType
*/
private validateEventType(eventType: string): void {
if (!EventTypeValidator.isValid(eventType)) {
if (this.isDebugMode) {
console.warn(`[EventBus] Unknown event type: ${eventType}`);
}
// 在调试模式下添加自定义事件类型
if (this.isDebugMode) {
EventTypeValidator.addCustomType(eventType);
}
}
}
/**
*
* @param eventType
* @param data
*/
private enhanceEventData<T>(eventType: string, data: T): T & IEventData {
const enhanced = data as T & IEventData;
// 如果数据还没有基础事件属性,添加它们
if (!enhanced.timestamp) {
enhanced.timestamp = Date.now();
}
if (!enhanced.eventId) {
enhanced.eventId = `${eventType}_${++this.eventIdCounter}`;
}
if (!enhanced.source) {
enhanced.source = 'EventBus';
}
return enhanced;
}
/**
* EventStats为IEventStats
* @param stats EventStats实例
*/
private convertEventStats(stats: EventStats): IEventStats {
return {
eventType: stats.eventType,
listenerCount: stats.listenerCount,
triggerCount: stats.triggerCount,
totalExecutionTime: stats.totalExecutionTime,
averageExecutionTime: stats.averageExecutionTime,
lastTriggerTime: stats.lastTriggerTime
};
}
}
/**
* 线
* 访线
*/
export class GlobalEventBus {
private static instance: EventBus;
/**
* 线
* @param debugMode
*/
public static getInstance(debugMode: boolean = false): EventBus {
if (!this.instance) {
this.instance = new EventBus(debugMode);
}
return this.instance;
}
/**
* 线
* @param debugMode
*/
public static reset(debugMode: boolean = false): EventBus {
if (this.instance) {
this.instance.clear();
}
this.instance = new EventBus(debugMode);
return this.instance;
}
}
/**
*
*
*/
export function EventHandler(eventType: string, config: IEventListenerConfig = {}) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
// 在类实例化时自动注册监听器
const initMethod = target.constructor.prototype.initEventListeners || function() {};
target.constructor.prototype.initEventListeners = function() {
initMethod.call(this);
const eventBus = GlobalEventBus.getInstance();
eventBus.on(eventType, originalMethod.bind(this), config);
};
return descriptor;
};
}
/**
*
*
*/
export function AsyncEventHandler(eventType: string, config: IEventListenerConfig = {}) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
const initMethod = target.constructor.prototype.initEventListeners || function() {};
target.constructor.prototype.initEventListeners = function() {
initMethod.call(this);
const eventBus = GlobalEventBus.getInstance();
eventBus.onAsync(eventType, originalMethod.bind(this), config);
};
return descriptor;
};
}