2016-02-03 02:11:50 +00:00
|
|
|
"use strict";
|
|
|
|
|
2016-02-03 02:02:55 +00:00
|
|
|
var Immutable = require('immutable');
|
2016-04-07 07:42:54 +00:00
|
|
|
var Dataspace = require('./dataspace.js').Dataspace;
|
2016-02-03 02:02:55 +00:00
|
|
|
|
|
|
|
function Ground(bootFn) {
|
|
|
|
var self = this;
|
|
|
|
this.stepperId = null;
|
2016-05-15 18:56:19 +00:00
|
|
|
this.stepping = false;
|
|
|
|
this.startingFuel = 100;
|
2016-04-07 07:42:54 +00:00
|
|
|
this.baseStack = Immutable.List.of({ dataspace: this, activePid: -1 });
|
|
|
|
Dataspace.withDataspaceStack(this.baseStack, function () {
|
|
|
|
self.dataspace = new Dataspace(bootFn);
|
2016-02-03 02:02:55 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
Ground.prototype.step = function () {
|
|
|
|
var self = this;
|
2016-04-07 07:42:54 +00:00
|
|
|
return Dataspace.withDataspaceStack(this.baseStack, function () {
|
|
|
|
return self.dataspace.step();
|
2016-02-03 02:02:55 +00:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
Ground.prototype.checkPid = function (pid) {
|
2016-02-06 11:22:13 +00:00
|
|
|
if (pid !== -1) console.error('Weird pid in Ground', pid);
|
2016-02-03 02:02:55 +00:00
|
|
|
};
|
|
|
|
|
2016-02-06 11:22:13 +00:00
|
|
|
Ground.prototype.markRunnable = function (pid) {
|
2016-02-03 02:02:55 +00:00
|
|
|
this.checkPid(pid);
|
|
|
|
this.startStepping();
|
|
|
|
};
|
|
|
|
|
|
|
|
Ground.prototype.startStepping = function () {
|
|
|
|
var self = this;
|
|
|
|
if (this.stepperId) return;
|
2016-05-15 18:56:19 +00:00
|
|
|
|
|
|
|
if (this.stepping) return;
|
|
|
|
this.stepping = true;
|
|
|
|
try {
|
|
|
|
var stillBusy = false;
|
|
|
|
for (var fuel = this.startingFuel; fuel > 0; fuel--) {
|
|
|
|
stillBusy = this.step();
|
|
|
|
if (!stillBusy) break;
|
|
|
|
}
|
|
|
|
if (stillBusy) {
|
|
|
|
this.stepperId = setTimeout(function () {
|
|
|
|
self.stepperId = null;
|
|
|
|
self.startStepping();
|
|
|
|
}, 0);
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
this.stepping = false;
|
|
|
|
throw e;
|
2016-02-03 02:02:55 +00:00
|
|
|
}
|
2016-05-15 18:56:19 +00:00
|
|
|
this.stepping = false;
|
|
|
|
|
2016-03-19 19:06:07 +00:00
|
|
|
return this; // because the syndicatec compiler chains startStepping after the ctor
|
2016-02-03 02:02:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Ground.prototype.stopStepping = function () {
|
|
|
|
if (this.stepperId) {
|
|
|
|
clearTimeout(this.stepperId);
|
|
|
|
this.stepperId = null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Ground.prototype.kill = function (pid, exn) {
|
|
|
|
this.checkPid(pid);
|
2016-04-07 07:42:54 +00:00
|
|
|
console.log("Ground dataspace terminated");
|
2016-02-03 02:02:55 +00:00
|
|
|
this.stopStepping();
|
|
|
|
};
|
|
|
|
|
|
|
|
Ground.prototype.enqueueAction = function (pid, action) {
|
|
|
|
this.checkPid(pid);
|
|
|
|
|
|
|
|
switch (action.type) {
|
|
|
|
case 'stateChange':
|
|
|
|
if (action.patch.isNonEmpty()) {
|
|
|
|
console.error('You have subscribed to a nonexistent event source.',
|
|
|
|
action.patch.pretty());
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'message':
|
|
|
|
console.error('You have sent a message into the outer void.', action);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
console.error('Internal error: unexpected action at ground level', action);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
module.exports.Ground = Ground;
|