95 lines
2.6 KiB
TypeScript
95 lines
2.6 KiB
TypeScript
import type { IEventBuilder, IEventMap } from '@/core/events/IEventBuilder.ts'
|
|
|
|
interface HandlerWrapper<T extends (...args: any[]) => any> {
|
|
fn: T
|
|
once: boolean
|
|
}
|
|
|
|
export class EventBuilderImpl<Events extends IEventMap>
|
|
implements IEventBuilder<Events>
|
|
{
|
|
private _eventHandlers = new Map<keyof Events, Set<HandlerWrapper<Events[keyof Events]>>>()
|
|
|
|
/**
|
|
* 添加事件监听器
|
|
* @param eventName 事件名称
|
|
* @param handler 监听器
|
|
* @param options { immediate: 立即执行一次 immediateArgs: 立即执行的参数 once: 只监听一次 }
|
|
* @example
|
|
* eventBus.addEventListener('noArgs', () => {})
|
|
* eventBus.addEventListener('greet', name => {}, { immediate: true, immediateArgs: ['abc'] })
|
|
* eventBus.addEventListener('onResize', (w, h) => {}, { immediate: true, immediateArgs: [1, 2] })
|
|
*/
|
|
addEventListener<E extends keyof Events, F extends Events[E]>(
|
|
eventName: E,
|
|
handler: F,
|
|
options?: {
|
|
immediate?: boolean;
|
|
immediateArgs?: Parameters<F>;
|
|
once?: boolean;
|
|
},
|
|
) {
|
|
if (!handler) return
|
|
if (!this._eventHandlers.has(eventName)) {
|
|
this._eventHandlers.set(eventName, new Set<HandlerWrapper<F>>())
|
|
}
|
|
|
|
const set = this._eventHandlers.get(eventName)!
|
|
if (![...set].some((wrapper) => wrapper.fn === handler)) {
|
|
set.add({ fn: handler, once: options?.once ?? false })
|
|
}
|
|
|
|
if (options?.immediate) {
|
|
try {
|
|
handler(...(options.immediateArgs ?? []))
|
|
} catch (e) {
|
|
console.error(e)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 移除事件监听器
|
|
* @param eventName 事件名称
|
|
* @param handler 监听器
|
|
* @example
|
|
* eventBus.removeEventListener('noArgs', () => {})
|
|
*/
|
|
removeEventListener<E extends keyof Events, F extends Events[E]>(eventName: E, handler: F) {
|
|
const set = this._eventHandlers.get(eventName)
|
|
if (!set) return
|
|
|
|
for (const wrapper of set) {
|
|
if (wrapper.fn === handler) {
|
|
set.delete(wrapper)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 通知事件
|
|
* @param eventName 事件名称
|
|
* @param args 参数
|
|
* @example
|
|
* eventBus.notifyEvent('noArgs')
|
|
* eventBus.notifyEvent('greet', 'Alice')
|
|
* eventBus.notifyEvent('onResize', 1, 2)
|
|
*/
|
|
notifyEvent<E extends keyof Events, F extends Events[E]>(eventName: E, ...args: Parameters<F>) {
|
|
if (!this._eventHandlers.has(eventName)) return
|
|
|
|
const set = this._eventHandlers.get(eventName)!
|
|
for (const wrapper of set) {
|
|
try {
|
|
wrapper.fn(...args)
|
|
} catch (e) {
|
|
console.error(e)
|
|
}
|
|
|
|
if (wrapper.once) {
|
|
set.delete(wrapper)
|
|
}
|
|
}
|
|
}
|
|
}
|