Skip to content

Instantly share code, notes, and snippets.

@sthalik
Created September 24, 2013 08:46
Show Gist options
  • Save sthalik/6682047 to your computer and use it in GitHub Desktop.
Save sthalik/6682047 to your computer and use it in GitHub Desktop.
cells-js 20130924_2
//noinspection JSUnusedGlobalSymbols
var Sheet = (function () {
"use strict";
var CellStack = [];
function BaseCell() {
this._cached_value = null;
this._fresh = false;
this._deps = [];
}
//noinspection JSUnusedGlobalSymbols
BaseCell.prototype.value = function () {
if (CellStack.length > 0) {
var c = CellStack[CellStack.length - 1];
if (!(this in c.deps)) {
c.deps.push(this);
}
}
if (this._fresh) {
return this._cached_value;
}
else {
var deps = {deps: []};
CellStack.push(deps);
var ret = this._formula();
CellStack.pop();
// XXX do some circularity checks to avoid stack overflow -sh
this._cached_value = ret;
this._deps = deps.deps;
this._fresh = true;
if (this._filter_value(ret)) {
this._pre_update();
for (var x in deps) {
//noinspection JSUnfilteredForInLoop
x.invalidate();
}
this._post_update();
}
return ret;
}
};
BaseCell.prototype.invalidate = function () {
self._fresh = false;
for (var x in self._deps) {
// NB all are derived from BaseCell -sh
//noinspection JSUnfilteredForInLoop
x.invalidate();
}
};
//noinspection JSUnusedLocalSymbols
BaseCell.prototype._filter_value = function (datum) {
// for fsensitivity -sh
return true;
};
BaseCell.prototype._pre_update = function () {
// for events -sh
};
BaseCell.prototype._post_update = function () {
// NB this is for events
// typical usage, invalidate deps,
// optionally force them to recompute,
// revert back to null value -sh
};
BaseCell.prototype.set_cached_value = function (datum, freshp) {
// for subclasses only, not user api -sh
this._cached_value = datum;
// fresh=true without invalidation is dangerous, be careful out there -sh
this._fresh |= !!freshp;
};
function InputCell() {
//noinspection JSPotentiallyInvalidUsageOfThis
this.prototype = new BaseCell();
}
//noinspection JSUnusedGlobalSymbols
InputCell.prototype.set = function (value) {
if (this._filter_value(value)) {
this.set_cached_value(value);
this.invalidate();
}
};
InputCell.prototype._formula = function() {
return this._cached_value;
};
function Formula(fun) {
this.prototype = new BaseCell();
this._fun = fun;
}
Formula.prototype._formula = function() {
return this._fun();
};
function Event(defval) {
this.prototype = new InputCell();
this._default = defval;
this.set_cached_value(defval, true);
}
Event.prototype._post_update = function() {
this.set_cached_value(this._default, true);
};
Event.prototype._formula = function() {
return this._cached_value;
};
// XXX todo fsensitivity cell -sh
// XXX todo allow cells to fire immediately
// upon input in strict/eager manner -sh
// XXX maybe wrappers for collections -sh
return {
formula: Formula,
event: Event,
input: InputCell,
base: BaseCell // for inheritance -sh
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment