///
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
}
}
}