Module activation and main program start

This commit is contained in:
Tony Garnock-Jones 2018-11-01 23:30:17 +00:00
parent 2002d0975e
commit e4782b8406
4 changed files with 93 additions and 14 deletions

View File

@ -74,6 +74,6 @@ new Ground(() => {
return [Syndicate.Observe(BoxState(_$)), handler];
});
});
}).start().stopHandler = () => {
}).start().addStopHandler(() => {
console.timeEnd('box-and-client-' + N.toString());
};
});

View File

@ -38,20 +38,26 @@ const PRIORITY = Object.freeze({
_count: 6
});
function Dataspace(bootProc) {
function Dataspace(container, bootProc) {
this.nextId = 0;
this.container = container;
this.index = new Skeleton.Index();
this.dataflow = new Dataflow.Graph();
this.runnable = Immutable.List();
this.pendingActions = Immutable.List([
new ActionGroup(null, Immutable.List([new Spawn(null, bootProc, Immutable.Set())]))]);
this.activatedModules = Immutable.Set();
}
// Parameters
Dataspace._currentFacet = null;
Dataspace._inScript = true;
Dataspace.currentFacet = function () { return Dataspace._currentFacet; };
Dataspace.BootSteps = Symbol('SyndicateBootSteps');
Dataspace.currentFacet = function () {
return Dataspace._currentFacet;
};
Dataspace.withNonScriptContext = function (thunk) {
let savedInScript = Dataspace._inScript;
@ -84,11 +90,36 @@ Dataspace.wrap = function (f) {
return function () {
let actuals = arguments;
return Dataspace.withCurrentFacet(savedFacet, function () {
return f.apply(f.fields, actuals);
return f.apply(savedFacet.fields, actuals);
});
};
};
Dataspace.wrapExternal = function (f) {
let savedFacet = Dataspace._currentFacet;
let ac = savedFacet.actor;
return function () {
let actuals = arguments;
ac.dataspace.container.start();
ac.pushScript(function () {
Dataspace.withCurrentFacet(savedFacet, function () {
f.apply(this, actuals);
});
});
};
};
Dataspace.backgroundTask = function (k) {
let ground = Dataspace._currentFacet.actor.dataspace.container;
let active = true;
ground.backgroundTaskCount++;
return k(() => {
if (active) {
ground.backgroundTaskCount--;
active = false;
}
});
};
Dataspace.referenceField = function (obj, prop) {
if (!(prop in obj)) {
@ -162,7 +193,7 @@ Dataspace.prototype.addActor = function (name, bootProc, initialAssertions) {
ac.addFacet(null, () => {
// Root facet is a dummy "system" facet that exists to hold
// one-or-more "user" "root" facets.
ac.addFacet(Dataspace.currentFacet(), bootProc);
ac.addFacet(Dataspace._currentFacet, bootProc);
// ^ The "true root", user-visible facet.
initialAssertions.forEach((a) => { ac.adhocRetract(a); });
});
@ -326,7 +357,7 @@ Message.prototype.perform = function (ds, ac) {
};
Dataspace.send = function (body) {
Dataspace._currentFacet.actor.enqueueScriptAction(new Message(body));
Dataspace._currentFacet.enqueueScriptAction(new Message(body));
};
function Spawn(name, bootProc, initialAssertions) {
@ -340,8 +371,7 @@ Spawn.prototype.perform = function (ds, ac) {
};
Dataspace.spawn = function (name, bootProc, initialAssertions) {
let a = new Spawn(name, bootProc, initialAssertions);
Dataspace._currentFacet.actor.enqueueScriptAction(a);
Dataspace._currentFacet.enqueueScriptAction(new Spawn(name, bootProc, initialAssertions));
};
function Quit() { // TODO: rename? Perhaps to Cleanup?
@ -361,7 +391,28 @@ DeferredTurn.prototype.perform = function (ds, ac) {
};
Dataspace.deferTurn = function (continuation) {
Dataspace._currentFacet.actor.enqueueScriptAction(new DeferredTurn(Dataspace.wrap(continuation)));
Dataspace._currentFacet.enqueueScriptAction(new DeferredTurn(Dataspace.wrap(continuation)));
};
function Activation(mod) {
this.mod = mod;
}
Activation.prototype.perform = function (ds, ac) {
if (!ds.activatedModules.includes(this.mod)) {
ds.activatedModules = ds.activatedModules.add(this.mod);
this.mod.exports[Dataspace.BootSteps].steps.forEach((a) => {
a.perform(ds, ac);
});
}
};
Dataspace.activate = function (modExports) {
let { module } = modExports[Dataspace.BootSteps] || {};
if (module) {
Dataspace._currentFacet.enqueueScriptAction(new Activation(module));
}
return modExports;
};
function ActionGroup(actor, actions) {
@ -473,6 +524,10 @@ Facet.prototype.addDataflow = function (subjectFun, priority) {
});
};
Facet.prototype.enqueueScriptAction = function (action) {
this.actor.enqueueScriptAction(action);
};
Facet.prototype.toString = function () {
let s = 'Facet(' + this.actor.id;
if (this.actor.name !== void 0) s = s + ',' + JSON.stringify(this.actor.name);
@ -485,6 +540,14 @@ Facet.prototype.toString = function () {
return s + ')';
};
function ActionCollector() {
this.actions = [];
}
ActionCollector.prototype.enqueueScriptAction = function (a) {
this.actions.push(a);
};
function Endpoint(facet, isDynamic, updateFun) {
if (Dataspace._inScript) {
throw new Error("Cannot add endpoint in script; are you missing a `react { ... }`?");
@ -536,3 +599,4 @@ Endpoint.prototype.toString = function () {
///////////////////////////////////////////////////////////////////////////
module.exports.Dataspace = Dataspace;
module.exports.ActionCollector = ActionCollector;

View File

@ -7,8 +7,9 @@ function Ground(bootProc) {
this.stepperId = null;
this.stepping = false;
this.startingFuel = 1000;
this.dataspace = new Dataspace(bootProc);
this.stopHandler = function () {};
this.dataspace = new Dataspace(this, bootProc);
this.stopHandlers = [];
this.backgroundTaskCount = 0;
}
Ground.prototype.start = function () {
@ -32,8 +33,9 @@ Ground.prototype._step = function () {
if (stillBusy) {
this.start();
} else {
if (this.stopHandler) {
this.stopHandler(this);
if (!this.backgroundTaskCount) {
this.stopHandlers.forEach((h) => h());
this.stopHandlers = [];
}
}
} finally {
@ -48,4 +50,15 @@ Ground.prototype.stop = function () {
}
};
Ground.prototype.addStopHandler = function (h) {
this.stopHandlers.push(h);
};
function bootModule(mod) {
let g = new Ground(() => {
Dataspace.activate(mod.exports);
}).start();
}
module.exports.Ground = Ground;
module.exports.bootModule = bootModule;

View File

@ -41,3 +41,5 @@ module.exports.Observe = Assertions.Observe;
module.exports.Seal = Assertions.Seal;
module.exports.Inbound = Assertions.Inbound;
module.exports.Outbound = Assertions.Outbound;
module.exports.bootModule = Ground.bootModule;