gameClient/assets/pkg/mvc/EventManager.ts
2025-07-01 00:00:42 +08:00

100 lines
2.8 KiB
TypeScript

type EventCallback = (data?: any) => void
class CallbackAndContext {
public callback: EventCallback = null
public context: any = null
public constructor(callback: EventCallback, context: any) {
this.callback = callback
this.context = context
}
}
export class EventManager {
private static instance: EventManager = null
private listeners: { [eventName: string]: Array<CallbackAndContext> }
public static Instance(): EventManager {
if (!this.instance) {
this.instance = new EventManager()
}
return this.instance
}
public On(eventName: string, callback: EventCallback, context?: any): void {
if (!this.listeners[eventName]) {
this.listeners[eventName] = []
}
if (!callback) return
if (this.IsExsit(eventName, callback, context)) return
this.listeners[eventName].push(new CallbackAndContext(callback, context))
}
private IsExsit(eventName: string, callback: EventCallback, context?: any): boolean {
const listeners = this.listeners[eventName]
if (!listeners) return false
for (let i = listeners.length - 1; i >= 0; i--) {
const listener = listeners[i]
if (listener.callback === callback && (!context || listener.context === context)) {
return true
}
}
return false
}
// 取消事件监听
public Off(eventName: string, callback?: EventCallback, context?: any): void {
const listeners = this.listeners[eventName]
if (!listeners) return
// 如果没有提供回调,则移除该事件的所有监听
if (!callback) {
delete this.listeners[eventName]
return
}
for (let i = listeners.length - 1; i >= 0; i--) {
const listener = listeners[i]
if (listener.callback === callback && (!context || listener.context === context)) {
listeners.splice(i, 1)
}
}
if (listeners.length === 0) {
delete this.listeners[eventName]
}
}
// 触发事件
public Emit(eventName: string, data?: any): void {
const listener = this.listeners[eventName]
if (!listener) return
// 创建副本,防止回调中修改原始数组
const copy = [...listener]
copy.forEach((listener) => {
try {
listener.callback.call(listener.context, data)
} catch (error) {
console.error(`事件回调错误,事件名: ${eventName}:`, error)
}
})
}
// 一次性监听(触发后自动移除)
public Once(eventName: string, callback: EventCallback, context?: any): void {
const wrapper = (data: any) => {
callback.call(context, data)
this.Off(eventName, wrapper, context)
}
this.On(eventName, wrapper, context)
}
// 移除所有事件监听
public ClearAll(): void {
this.listeners = {}
}
// 获取某个事件的监听者数量
public ListenerCount(eventName: string): number {
return this.listeners[eventName]?.length || 0
}
}