namespace drunk { import util = drunk . util ; export interface IEventListener { ( ... args ) : void ; __isOnce ? : boolean ; } let eventCache = { } ; let prefixKey = 'DRUNK-ONCE-EVENT-' ; function getCache ( emitter ) { let id = util . uniqueId ( emitter ) ; if ( ! eventCache [ id ] ) { eventCache [ id ] = { } ; } return eventCache [ id ] ; } /**
     * 事件管理类
     */ export class EventEmitter { param type param listener $addListener ( type , listener ) { let cache = getCache ( this ) ; if ( ! cache [ type ] ) { cache [ type ] = [ ] ; } util . addArrayItem ( cache [ type ] , listener ) ; return this ; } param type param listener $on ( type , listener ) { return this . $addListener ( type , listener ) ; } param type param listener $once ( type , listener ) { listener [ prefixKey + util . uniqueId ( this ) ] = true ; this . $addListener ( type , listener ) ; return this ; } param type param listener $removeListener ( type , listener ) { let cache = getCache ( this ) ; let listeners = cache [ type ] ; if ( ! listeners || ! listeners . length ) { return ; } util . removeArrayItem ( listeners , listener ) ; return this ; } param type $removeAllListeners ( type ? ) { if ( ! type ) { EventEmitter . cleanup ( this ) ; } else { getCache ( this ) [ type ] = null ; } return this ; } param type param . . args $emit ( type , ... args ) { let cache = getCache ( this ) ; let listeners = cache [ type ] ; let onceKey = prefixKey + util . uniqueId ( this ) ; if ( ! listeners || ! listeners . length ) { return ; } listeners . slice ( ) . forEach ( ( listener ) => { listener . apply ( this , args ) ; if ( listener [ onceKey ] ) { util . removeArrayItem ( listeners , listener ) ; delete listener [ onceKey ] ; } } ) ; return this ; } param type $listeners ( type ) { var listeners = getCache ( this ) [ type ] ; return listeners ? listeners . slice ( ) : [ ] ; } param emitter param type static listenerCount ( emitter , type ) { let cache = getCache ( emitter ) ; if ( ! cache [ type ] ) { return 0 ; } return cache [ type ] . length ; } param emitter static cleanup ( emitter ) { let id = util . uniqueId ( emitter ) ; eventCache [ id ] = null ; } } }