/**
 * Lightweight implementation of Signal
 */ export class Signal < Handler extends ( ... args : any [ ] ) => any > { private readonly handlers : SignalHandler < Handler > [ ] = [ ] ; return { boolean } public get hasHandlers ( ) : boolean { return this . handlers . length > 0 ; } return { number } public get handlersAmount ( ) : number { return this . handlers . length ; } param { Handler } handler param priority public connect ( handler , priority = 0 ) { const existingHandler = this . handlers . find ( ( it ) => it . equals ( handler ) ) ; let needResort ; if ( existingHandler !== undefined ) { needResort = existingHandler . priority !== priority ; existingHandler . priority = priority ; } else { const lastHandler = this . handlers [ this . handlers . length - 1 ] ; this . handlers . push ( new SignalHandler ( handler , priority ) ) ; needResort = ( lastHandler !== undefined && lastHandler . priority > priority ) ; } if ( needResort ) { this . handlers . sort ( ( a , b ) => a . priority - b . priority ) ; } } param { Handler } handler public disconnect ( handler ) { const existingHandlerIndex = this . handlers . findIndex ( ( it ) => it . equals ( handler ) ) ; if ( existingHandlerIndex >= 0 ) { this . handlers . splice ( existingHandlerIndex , 1 ) ; } } param { Handler } handler public disconnectAll ( ) { this . handlers . length = 0 ; } param { any } args public emit ( ... args ) { for ( const handler of this . handlers ) { handler . handle ( ... args ) ; } } } class SignalHandler < Handler extends ( ... args : any [ ] ) => any > { public constructor ( public readonly handler , public priority ) { } public equals ( handler ) { return this . handler === handler ; } public handle ( ... args ) { this . handler ( ... args ) ; } }