import type { IEventBuilder, IEventMap } from '@/core/events/IEventBuilder.ts' interface HandlerWrapper any> { fn: T once: boolean } export class EventBuilderImpl implements IEventBuilder { private _eventHandlers = new Map>>() /** * 添加事件监听器 * @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( eventName: E, handler: F, options?: { immediate?: boolean; immediateArgs?: Parameters; once?: boolean; }, ) { if (!handler) return if (!this._eventHandlers.has(eventName)) { this._eventHandlers.set(eventName, new Set>()) } 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(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(eventName: E, ...args: Parameters) { 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) } } } }