UNPKG

alm

Version:

The best IDE for TypeScript

117 lines (98 loc) 3.02 kB
export interface Listener<T> { (event: T): any; } export interface Disposable { dispose(); } export class CompositeDisposible implements Disposable { private disposibles: Disposable[] = []; add = (disposible: Disposable) => { this.disposibles.push(disposible); } dispose = () => { this.disposibles.forEach(d=> d.dispose()); } } /** passes through events as they happen. You will not get events from before you start listening */ export class TypedEvent<T> { private listeners: Listener<T>[] = []; private listenersOncer: Listener<T>[] = []; on = (listener: Listener<T>): Disposable => { this.listeners.push(listener); return { dispose: () => this.off(listener) }; } once = (listener: Listener<T>): void => { this.listenersOncer.push(listener); } off = (listener: Listener<T>) => { var callbackIndex = this.listeners.indexOf(listener); if (callbackIndex > -1) this.listeners.splice(callbackIndex, 1); } emit = (event: T) => { /** Update any `current` listeners */ this._last = event; while (this._currentQueue.length) { let item = this._currentQueue.pop(); item.resolve(event); } /** Update any general listeners */ this.listeners.forEach((listener) => listener(event)); /** Clear the `once` queue */ this.listenersOncer.forEach((listener) => listener(event)); this.listenersOncer = []; } pipe = (te: TypedEvent<T>): Disposable => { return this.on((e)=>te.emit(e)); } /** * A promise that is resolved on first event * ... or immediately with the last value */ private _currentQueue:PromiseDeferred<T>[] = []; private _last: T = null; current = (): Promise<T> => { if (this._last != null){ return Promise.resolve(this._last); } else { const promise = new Promise<T>((resolve,reject)=>{ this._currentQueue.push({ promise, resolve, reject }); }) return promise; } } /** * Allows you to join in with the last value * So you don't need to do .current + .on */ join = (listener: Listener<T>) => { if (this._last != null) { listener(this._last); } return this.on(listener); } } /** single event listener queue */ export class SingleListenerQueue<T> { private listener: Listener<T> = null; private pending: T[] = []; pendingCount = () => this.pending.length; on(listener: Listener<T>) { this.listener = listener; // clear pending this.pending.forEach((evt) => this.listener(evt)); this.pending = []; } off() { this.listener = null; } emit(event: T) { if (!this.listener) { this.pending.push(event); } else { this.listener(event); } } }