export enum EventTypes { MOUSE_LEFT_BUTTON_PRESSED = 'MOUSE_LEFT_BUTTON_PRESSED' , MOUSE_WHEEL = 'MOUSE_WHEEL' , MOUSE_MOTION = 'MOUSE_MOTION' } export class EventManager < E > { private propagate = ( name , eventData , rootListener ) : boolean => { if ( rootListener . listenerCount <= 0 ) { return false ; } const handled = rootListener . children . some ( child => this . propagate ( name , eventData , child ) ) ; if ( handled ) { return true ; } const handler = rootListener . listeners [ name ] ; const validator = rootListener . validator ; if ( typeof handler === 'function' && ( ! validator || validator ( name , eventData ) ) ) { return Boolean ( handler ( eventData ) ) ; } return false ; } ; propagateEvent ( name , eventData , rootListener ) { return this . propagate ( name , eventData , rootListener ) ; } } export type EventHandler < E > = ( eventData : E ) => boolean ; export type EventValidator < E > = ( eventName : EventTypes , eventData : E ) => boolean ; export class EventListener < E > { parent ? : EventListener < E > ; children : EventListener < E > [ ] = [ ] ; listeners : { [ eventName ] : EventHandler < E > | undefined ; } = { } ; validator : EventValidator < E > | undefined ; listenerCount : number = 0 ; private updateListenerCount ( value ) { this . listenerCount += value ; if ( this . parent ) { this . parent . updateListenerCount ( value ) ; } } addChild ( child ) { child . parent = this ; this . children . push ( child ) ; this . updateListenerCount ( child . listenerCount ) ; } findChild ( child ) { return this . children . indexOf ( child ) ; } removeChild ( child ) { child . parent = undefined ; const index = this . findChild ( child ) ; this . children . splice ( index , 1 ) ; this . updateListenerCount ( - child . listenerCount ) ; } private setListener ( eventName , listener ? ) { if ( this . listeners [ eventName ] === listener ) { return ; } if ( this . listeners [ eventName ] && listener ) { this . listeners [ eventName ] = listener ; } else { this . updateListenerCount ( listener ? 1 : - 1 ) ; this . listeners [ eventName ] = listener ; } } setOnClickListener ( listener ? ) { this . setListener ( EventTypes . MOUSE_LEFT_BUTTON_PRESSED , listener ) ; } setValidator ( validator ? ) { this . validator = validator ; } setOnWheelListener ( listener ? ) { this . setListener ( EventTypes . MOUSE_WHEEL , listener ) ; } setOnMouseMoveListener ( listener ? ) { this . setListener ( EventTypes . MOUSE_MOTION , listener ) ; } }