Skip to content

Instantly share code, notes, and snippets.

@Yuffster
Last active December 29, 2016 01:18
Show Gist options
  • Save Yuffster/4d708b3443259c3deb5e664f9c2f79dc to your computer and use it in GitHub Desktop.
Save Yuffster/4d708b3443259c3deb5e664f9c2f79dc to your computer and use it in GitHub Desktop.
var __contexts = 0; // Just for debugging.
class Context {
constructor(parent, transaction=false) {
this._data = {};
this._children = [];
this._parent = parent;
this._transaction = transaction;
this._revision = __contexts++;
}
get(k) {
if (this._data[k] !== undefined) return this._data[k];
if (this._parent) return this._parent.get(k);
}
set(k, v) {
var fork = (this._transaction) ? this : this.fork();
if (v == undefined && k instanceof Object) {
for (let j in k) fork._data[j] = k[j];
} else fork._data[k] = v;
return fork;
}
sub(k, n=1) {
if (this.get(k) < n) this.raise("Insufficient " + k);
return this.add(k, n*-1);
}
add(k, n=1) {
return this.set(k, this.get(k)+n);
}
transfer(a, b, n=1) {
if (n < 0) return this.transfer(b, a, n);
if (this.get(a) < n) this.raise("Insufficient " + a);
var fork = (this._transaction) ? this : this.fork();
fork._data[a] = this.get(a) - n;
fork._data[b] = this.get(b) + n;
return fork;
}
transaction() {
return this.fork(true);
}
commit() {
if (!this._transaction) throw "Not a transaction.";
this._transaction = false;
return this;
}
fork(transaction=false) {
var child = new this.constructor(this, transaction);
this._children.push(child);
return child;
}
tree(depth=0) {
var d = JSON.parse(JSON.stringify(this._data));
if (this._transaction) d['___TRANSACTION__'] = true;
var str = '-'+this._revision+":"+JSON.stringify(d)+"\n";
for (let c of this._children) {
for (let i=0;i<=depth;i++) str += "-";
str += c.tree(depth+1);
}
return str;
}
dump() {
var d = {};
for (let k in this._data) d[k] = this._data[k];
if (this._parent) {
let p = this._parent.dump();
for (let k in p) if (d[k] === undefined) d[k] = p[k];
}
return JSON.parse(JSON.stringify(d));
}
}
var a = new Context(),
b = a.set('foo', 1),
c = b.set('foo', 2),
d = a.set('foo', 3),
e = a.set('bar', 4),
f = e.set('foo', 5),
g = f.set({'bizz':3, 'foo':6});
var h = a.transaction();
h.set('foo', 7);
h.set('bar', 1);
h.transfer('foo', 'bar', 3);
console.log(a.tree());
/*
-0:{}
--1:{"foo":1}
---2:{"foo":2}
--3:{"foo":3}
--4:{"bar":4}
---5:{"foo":5}
----6:{"bizz":3,"foo":6}
--7:{"foo":4,"bar":4,"___TRANSACTION__":true}
*/
h.commit();
var i = h.set('foo', 1),
j = i.transfer('foo', 'bar', 1);
console.log(a.tree());
/*
-0:{}
--1:{"foo":1}
---2:{"foo":2}
--3:{"foo":3}
--4:{"bar":4}
---5:{"foo":5}
----6:{"bizz":3,"foo":6}
--7:{"foo":4,"bar":4}
---8:{"foo":1,"bar"}
----9:{"foo":0,"bar":5}
*/
console.log('b', b.dump()) // {foo: 1}
console.log('f', f.dump()) // {foo: 3, bar: 5}
console.log('g', g.dump()); // {bizz: 3, foo: 6, bar: 5}
console.log('h', h.dump()); // {foo: 4, bar: 4}
console.log('i', i.dump()); // {foo: 1, bar: 4}
console.log('j', j.dump()); // {foo: 0, bar: 5}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment