elm/core-js/runtime/Dispatcher.js

187 lines
5.3 KiB
JavaScript
Raw Normal View History

2012-04-20 03:10:25 +00:00
var Elm = function() {
var send = function(node, timestep, changed) {
var kids = node.kids;
for (var i = kids.length; i--; ) {
kids[i].recv(timestep, changed, node.id);
}
};
2012-04-20 03:10:25 +00:00
var input = function(base) {
this.id = Guid.guid();
this.value = base;
this.kids = [];
2012-08-31 06:42:33 +00:00
this.defaultNumberOfKids = 0;
this.recv = function(timestep, eid, v) {
2012-04-20 03:10:25 +00:00
var changed = eid === this.id;
if (changed) { this.value = v; }
send(this, timestep, changed);
2012-08-31 06:42:33 +00:00
return changed;
2012-04-20 03:10:25 +00:00
};
Dispatcher.inputs.push(this);
2012-04-20 03:10:25 +00:00
};
var lift = function(func,args) {
this.id = Guid.guid();
this.value = null;
this.kids = [];
this.count = 0;
this.changed = false;
2012-04-20 03:10:25 +00:00
args.reverse();
this.recalc = function() {
var f = func;
for (var i = args.length; i--; ) {
f = f(args[i].value);
}
this.value = f;
};
this.recalc();
this.recv = function(timestep, changed, parentID) {
this.count += 1;
if (changed) { this.changed = true; }
if (this.count == args.length) {
if (this.changed) { this.recalc() }
send(this, timestep, this.changed);
this.changed = false;
this.count = 0;
2012-04-20 03:10:25 +00:00
}
};
for (var i = args.length; i--; ) {
args[i].kids.push(this);
}
2012-04-20 03:10:25 +00:00
};
var fold = function(func,base,baseIsFunc,input) {
2012-04-20 03:10:25 +00:00
this.id = Guid.guid();
this.value = baseIsFunc ? base(input.value) : base;
this.kids = [];
this.recv = function(timestep, changed, parentID) {
2012-04-20 03:10:25 +00:00
if (changed) { this.value = func(input.value)(this.value); }
send(this, timestep, changed);
2012-04-20 03:10:25 +00:00
};
input.kids.push(this);
2012-04-20 03:10:25 +00:00
};
var dropIf = function(pred,base,input) {
this.id = Guid.guid();
this.value = pred(input.value) ? base : input.value;
this.kids = [];
this.recv = function(timestep, changed, parentID) {
var chng = changed && !pred(input.value);
if (chng) { this.value = input.value; }
send(this, timestep, chng);
};
input.kids.push(this);
};
var dropRepeats = function(input) {
this.id = Guid.guid();
this.value = input.value;
this.kids = [];
this.recv = function(timestep, changed, parentID) {
var chng = changed && !eq(this.value,input.value);
if (chng) { this.value = input.value; }
send(this, timestep, chng);
};
input.kids.push(this);
};
var dropWhen = function(s1) { return function(b) { return function(s2) {
var pairs = new lift(function(x){return function(y){return [x,y];};},[s1,s2]);
var dropped = new dropIf(function(p){return p[0];},[true,b],pairs);
return new lift(function(p){return p[1];},[dropped]); }; };
};
var sampleOn = function(s1,s2) {
this.id = Guid.guid();
this.value = s2.value;
this.kids = [];
this.count = 0;
2012-09-13 19:25:48 +00:00
this.changed = false;
this.recv = function(timestep, changed, parentID) {
2012-09-13 19:25:48 +00:00
if (parentID === s1.id) this.changed = changed;
this.count += 1;
if (this.count == 2) {
2012-09-13 19:25:48 +00:00
if (this.changed) { this.value = s2.value; }
send(this, timestep, this.changed);
this.count = 0;
2012-09-13 19:25:48 +00:00
this.changed = false;
}
};
s1.kids.push(this);
s2.kids.push(this);
};
2012-04-20 03:10:25 +00:00
return {Input: function(x) {return new input(x);},
Lift: function(f,xs){return new lift(f,xs);},
Fold: function(f,b,x){return new fold(f,b,false,x);},
Fold1: function(f,b,x){return new fold(f,b,true,x);},
keepIf : function(pred) { return function(base) { return function(sig) {
return new dropIf(function(x) { return !pred(x)},base,sig); }; }; },
dropIf : function(pred) { return function(base) { return function(sig) {
return new dropIf(pred,base,sig); }; }; },
keepWhen : function(s) { return dropWhen(new lift(function(b){return !b;},[s])); },
dropWhen : dropWhen,
dropRepeats : function(s) { return new dropRepeats(s);},
sampleOn : function(s1) { return function(s2) { return new sampleOn(s1,s2); }; }
2012-04-20 03:10:25 +00:00
};
}();
var Dispatcher = function() {
var program = null;
var timestep = 0;
var inputs = [];
2012-08-31 06:42:33 +00:00
var currentElement = null;
2012-04-20 03:10:25 +00:00
var initialize = function() {
program = ElmCode.main();
if (!program.hasOwnProperty('recv')) {
2012-04-20 03:10:25 +00:00
program = Elm.Input(program);
}
2012-08-31 06:42:33 +00:00
currentElement = program.value;
filterDeadInputs();
2012-04-20 03:10:25 +00:00
var content = document.getElementById('content');
2012-08-31 06:42:33 +00:00
content.appendChild(Render.render(currentElement));
2012-04-20 03:10:25 +00:00
var w = document.getElementById('widthChecker').offsetWidth;
if (w !== window.innerWidth) {
Dispatcher.notify(Window.dimensions.id, Value.Tuple(w, window.innerHeight));
}
program = Elm.Lift(function(value) {
var content = document.getElementById('content');
2012-08-31 06:42:33 +00:00
Render.update(content.firstChild,currentElement,value);
currentElement = value;
return value;
}, [program]);
2012-04-20 03:10:25 +00:00
};
var notify = function(id, v) {
timestep += 1;
2012-08-31 06:42:33 +00:00
//console.log(timestep);
var hasListener = false;
for (var i = inputs.length; i--; ) {
2012-08-31 06:42:33 +00:00
hasListener = inputs[i].recv(timestep, id, v) || hasListener;
2012-04-20 03:10:25 +00:00
}
2012-08-31 06:42:33 +00:00
return hasListener;
2012-04-20 03:10:25 +00:00
};
2012-08-31 06:42:33 +00:00
function isAlive(input) {
if (!input.hasOwnProperty('defaultNumberOfKids')) return true;
var len = input.kids.length;
if (len == 0) return false;
if (len > input.defaultNumberOfKids) return true;
var alive = false;
for (var i = len; i--; ) {
alive = alive || isAlive(input.kids[i]);
}
return alive;
}
function filterDeadInputs() {
var temp = [];
for (var i = inputs.length; i--; ) {
if (isAlive(inputs[i])) temp.push(inputs[i]);
}
inputs = temp;
}
return {initialize:initialize, notify:notify, inputs:inputs};
2012-04-20 03:10:25 +00:00
}();