export class InputCell { constructor(value) { this.value = value; this.computeCells = []; } setValue(value) { this.value = value; this.update(); this.runCallbacks(); } addCompute(cell) { this.computeCells.push(cell); } update() { this.computeCells.forEach((cell) => { cell.update(); }); } runCallbacks() { this.computeCells.forEach((cell) => { cell.runCallbacks(); }) } } export class ComputeCell { constructor(inputCells, fn) { this.fn = fn; this.valueChanged = false; this.computeCells = []; this.callbacks = []; this.addInputs(inputCells); this.update(); } addCompute(cell) { this.computeCells.push(cell); } addCallback(callback) { callback.lastRunValue = callback.fn(this); this.callbacks.push(callback); } removeCallback(callback) { const i = this.callbacks.indexOf(callback); if (i >= 0) { this.callbacks.splice(i, 1); } } runCallbacks() { this.computeCells.forEach((cell) => { cell.runCallbacks(); }); this.callbacks.forEach((callback, i) => { if (callback.lastRunValue !== this.value) { callback.update(this); callback.lastRunValue = this.value; } }); } addInputs(inputCells) { this.inputCells = inputCells; inputCells.forEach((cell) => { cell.addCompute(this); }); } update() { this.value = this.fn(this.inputCells); this.computeCells.forEach((cell) => { cell.update(); }); } } export class CallbackCell { constructor(fn) { this.fn = fn; this.values = []; } update(cell) { this.values.push(this.fn(cell)); } }