/// namespace Leaf { export type EventEmitterHandler = (data: T, ...args: any[]) => void export interface EventHandlerInfo { owner?: any once?: boolean handler: Function } export interface EventHandlers { [index: string]: EventHandlerInfo[] } export class EventEmitter{ private events: EventHandlers public readonly DECLARE: E constructor() { this.events = {} } public addEventListener(event: K, handler: (data: E[K], ...args: any[]) => void) { this.on(event, handler) return this } public addListener = this.addEventListener public off = this.removeEventListener public removeAllListeners() { this.removeEventListener() } public on(event: keyof E, handler: (data: E[K], ...args: any[]) => void) { let ehs = this.getOrCreateEventHandlers(event) ehs.push({ once: false, handler: handler }) return this } public once(event: keyof E, handler: (data: E[K], ...args: any[]) => void) { let ehs = this.getOrCreateEventHandlers(event) ehs.push({ once: true, handler: handler }) return this } public listenByOnce(who: any, event: K, handler: (data: E[K], ...args: any[]) => void) { let ehs = this.getOrCreateEventHandlers(event) ehs.push({ owner: who, once: true, handler: handler }) return this } public listenBy(who: any, event: K | K[], handler: (data: E[K], ...args: any[]) => void) { if (Array.isArray(event)) { for (let e of event) { this.listenBy(who, e, handler) } return this } let ehs = this.getOrCreateEventHandlers(event) ehs.push({ owner: who, once: false, handler: handler }) return this } public stopListenBy(who: any, event?: keyof E, handler?: (data: E[K], ...args: any[]) => void) { if (event) { let ehs = this.getOrCreateEventHandlers(event) ehs = ehs.filter((eh) => { if (eh.owner === who && (!handler || handler === eh.handler)) return false return true }) this.events[event as string] = ehs } else { if (!who) { return } for (let name in this.events) { let ehs = this.events[name] let change = false ehs = ehs.filter((eh) => { if (eh.owner === who && (!handler || handler === eh.handler)) { change = true return false } return true }) if (change) { this.events[name] = ehs } } } return this } public removeEventListener(event?: keyof E, handler?: (data: E[K], ...args: any[]) => void) { if (!event) { this.events = {} } if (!handler) { this.events[event as string] = [] return this } let ehs = this.getOrCreateEventHandlers(event) let change = false ehs = ehs.filter((eh) => { if (!eh.owner && (!handler || handler === eh.handler)) { change = true return false } return true }) if (change) { this.events[event as string] = ehs } return this } public emit(event: K, ...values: E[K][]) { let todo = [] let ehs = this.getOrCreateEventHandlers(event) let change: boolean = false ehs = ehs.filter((eh) => { if (eh.owner) todo.push(eh.handler.bind(eh.owner)) else todo.push(eh.handler) if (eh.once) { change = true return false } return true }) if (change) { this.events[event as string] = ehs } todo.forEach((handler) => { handler(...values) }) return this } private getOrCreateEventHandlers(event: keyof E): EventHandlerInfo[] { let ehs = this.events[event as string] if (!ehs) { ehs = this.events[event as string] = [] } return ehs } } }