export class EventLimit { private lastTriggerValue:T = null; private handlers:Array> = []; public on(limit:T, handler:{ (data?:T): void }) { this.handlers.push(new EventLimitHandler(limit, handler)); if (this.lastTriggerValue != null) { this.trigger(this.lastTriggerValue); } } public onSingle(limit:T, handler:{ (data?:T): void }) { this.handlers.push(new SingleFireEventLimitHandler(limit, handler)); if (this.lastTriggerValue != null) { this.trigger(this.lastTriggerValue); } } public off(limit:T, handler:{ (data?:T): void }) { this.handlers = this.handlers.filter(h => h.handler !== handler && h.limit !== limit); } public allOff() { this.handlers = []; } public trigger = (data?:T) => { if (this.handlers) { this.handlers.slice(0).forEach(h => { if (h.limit <= data && (h.lastTriggerValue < h.limit || h.lastTriggerValue == null)) { h.fire(data); } h.lastTriggerValue = data; }); this.handlers = this.handlers.filter(h => h.isValid()); } this.lastTriggerValue = data; }; } class EventLimitHandler { public lastTriggerValue:T = null; constructor(public limit:T, public handler:{ (data?:T): void }) { } public fire(data?: T){ this.handler(data); } public isValid():boolean{ return true; } } class SingleFireEventLimitHandler extends EventLimitHandler{ public fired = false; constructor(public limit:T, public handler:{ (data?:T): void }) { super(limit,handler); } public fire(data?: T){ if(this.fired == false) { this.handler(data); } this.fired = true } public isValid():boolean{ return this.fired === false; } }