UNPKG

lazy-widgets

Version:

Typescript retained mode GUI for the HTML canvas API

83 lines 2.76 kB
// HACK: I extends Iterable<Observable<U>> | [Observable<U>] instead of just // extending Iterable<Observable<U>> because this forces typescript to // prefer tuples over arrays, which is more helpful for the transformer // user callback. /** * An {@link Observable} which transforms a list of input Observables into a * single value efficiently. * * @category State Management */ export class ObservableTransformer { /** * The current value. * * Evaluated when needed. Values are cached. */ get value() { if (this.dirty) { this.cache = this.transformer(this.inputs); this.dirty = false; } return this.cache; } /** * @param inputs - The list of observables to use as inputs for this transformer. * @param transformer - The actual transformer function. Takes in a list of input observables, and outputs a single value. * @param decider - Decides whether the transformer's output value needs to be updated or not. If `undefined` (the default), then the value is always assumed to need to be updated whenever an input watcher is invoked. */ constructor(inputs, transformer, decider) { this.inputs = inputs; this.transformer = transformer; this.decider = decider; this.dirty = true; /** The function callbacks called when the value is changed */ this.callbacks = new Array(); this.watcher = (_source, group) => { if (this.decider === undefined || this.decider(this.inputs)) { this.dirty = true; for (const callback of this.callbacks) { callback(this, group); } } }; for (const input of this.inputs) { input.watch(this.watcher); } } destroy() { if (this.watcher === null) { return; } for (const input of this.inputs) { input.unwatch(this.watcher); } this.watcher = null; } watch(callback, callNow = false, group) { this.callbacks.push(callback); if (callNow) { this.doCallback(callback, group); } return this; } unwatch(callback) { const i = this.callbacks.indexOf(callback); if (i === -1) { console.warn('unwatch called, but watcher was not registered'); } else { this.callbacks.splice(i, 1); } return this; } doCallback(callback, group) { try { callback(this, group); } catch (e) { console.error('Exception in watcher:', e); } } } //# sourceMappingURL=ObservableTransformer.js.map