Skip to content

Instantly share code, notes, and snippets.

@tmpvar
Created December 16, 2013 18:10
Show Gist options
  • Save tmpvar/7991574 to your computer and use it in GitHub Desktop.
Save tmpvar/7991574 to your computer and use it in GitHub Desktop.
experiments with value relationships
function ValueReference(src, dest, forward) {
if (!forward) {
this.src = src;
this.dest = dest;
} else {
this.src = dest;
this.dest = src;
}
this.operations = [];
}
ValueReference.prototype = {
value : null,
operations : null,
addOperation : function(apply, revert) {
this.operations.push({
apply: apply,
revert: revert
});
},
change : function(value) {
var val = this.src.value();
var dest = this.dest;
this.operations.forEach(function(operation) {
dest.apply(operation.apply(val));
});
}
};
function Value(primitive) {
this._refs = [];
this._value = primitive;
this._history = [];
}
Value.prototype = {
_refs : null,
_value : null,
_history : null,
refs : function(value, forward) {
if (forward) {
this._refs.push(new ValueReference(this, value));
return this;
} else {
return value.refs(this, true);
}
},
unrefs : function(value) {
this._refs = _refs.filter(function(i) {
return value !== i;
});
return this;
},
value : function() {
return this._value;
},
apply: function(primitive) {
// todo: handle functions?
this._history.push(this._value);
this._value = primitive;
this.notify();
return this;
},
revert : function() {
this._value = this._history.pop();
this.notify();
return this;
},
notify : function() {
console.log('notify', this._value);
var that = this;
this._refs.forEach(function(ref) {
ref.change(that);
});
},
add : function(value) {
// todo handle another Value or function
var ref = this._refs[this._refs.length-1];
ref.addOperation(function(a) {
return a + value;
}, function(a) {
return a - value;
});
return this;
},
multiply : function(value) {
var ref = this._refs[this._refs.length-1];
ref.addOperation(function(a) {
return a * value;
}, function(b) {
return a / value;
});
}
};
var v = function(initial) {
return new Value(initial);
};
var a = v(0);
var b = v(0);
var c = v(0);
b.refs(a).add(1);
c.refs(b).multiply(10);
a.apply(1);
console.log('a', a.value(), 'b', b.value(), 'c', c.value());
console.log(b.value() === 2);
a.apply(2);
console.log('a', a.value(), 'b', b.value(), 'c', c.value());
console.log(b.value() === 3, c.value() === 30);
a.revert();
console.log(b.value() === 2, c.value() === 20);
a.revert();
console.log(b.value() === 2, c.value() === 10);
// todo: unref
// todo: track history for undo state
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment