New World stack mechanism; bug fixes
This commit is contained in:
parent
5265f42beb
commit
35f17da335
12
index.js
12
index.js
|
@ -25,7 +25,6 @@ JQueryDriver.prototype.updateHandlerMap = function (routes) {
|
||||||
handler = (function (selector, eventName) { // JS is broken
|
handler = (function (selector, eventName) { // JS is broken
|
||||||
return World.wrap(function (e) {
|
return World.wrap(function (e) {
|
||||||
World.send(["jQuery", selector, eventName, e]);
|
World.send(["jQuery", selector, eventName, e]);
|
||||||
World.current.startStepping();
|
|
||||||
});
|
});
|
||||||
})(selector, eventName);
|
})(selector, eventName);
|
||||||
console.log("jQuery", "installing", selector, eventName);
|
console.log("jQuery", "installing", selector, eventName);
|
||||||
|
@ -35,7 +34,7 @@ JQueryDriver.prototype.updateHandlerMap = function (routes) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (var key in this.handlerMap) {
|
for (var key in this.handlerMap) {
|
||||||
if (hasOwnProperty(this.handlerMap, key) && !hasOwnProperty(newMap, key)) {
|
if (this.handlerMap.hasOwnProperty(key) && !(key in newMap)) {
|
||||||
var keyArray = JSON.parse(key);
|
var keyArray = JSON.parse(key);
|
||||||
var handler = this.handlerMap[key];
|
var handler = this.handlerMap[key];
|
||||||
var selector = keyArray[0];
|
var selector = keyArray[0];
|
||||||
|
@ -58,7 +57,7 @@ JQueryDriver.prototype.handleEvent = function (e) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var g = new Ground(function () {
|
var g = new Ground(function () {
|
||||||
console.log('here');
|
console.log('starting ground boot');
|
||||||
World.spawn(new Spy());
|
World.spawn(new Spy());
|
||||||
World.spawn(new JQueryDriver());
|
World.spawn(new JQueryDriver());
|
||||||
World.spawn({
|
World.spawn({
|
||||||
|
@ -70,7 +69,12 @@ var g = new Ground(function () {
|
||||||
World.send({msg: 'hello inner world'}, 0);
|
World.send({msg: 'hello inner world'}, 0);
|
||||||
},
|
},
|
||||||
handleEvent: function (e) {
|
handleEvent: function (e) {
|
||||||
console.log('dummy handleEvent', e);
|
if (e.type === "send" && e.message[0] === "jQuery") {
|
||||||
|
console.log("got a click");
|
||||||
|
World.updateRoutes([]);
|
||||||
|
} else {
|
||||||
|
console.log('dummy handleEvent', e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -146,7 +146,7 @@ function filterEvent(e, routes) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result.length ? updateRoutes(result) : null;
|
return updateRoutes(result);
|
||||||
case "send":
|
case "send":
|
||||||
for (var i = 0; i < routes.length; i++) {
|
for (var i = 0; i < routes.length; i++) {
|
||||||
var r = routes[i];
|
var r = routes[i];
|
||||||
|
@ -180,22 +180,51 @@ function World(bootFn) {
|
||||||
|
|
||||||
/* Class state / methods */
|
/* Class state / methods */
|
||||||
|
|
||||||
World.current = null; // parameter
|
World.stack = [];
|
||||||
|
|
||||||
|
World.current = function () {
|
||||||
|
return World.stack[World.stack.length - 1];
|
||||||
|
};
|
||||||
|
|
||||||
World.send = function (m, metaLevel, isFeedback) {
|
World.send = function (m, metaLevel, isFeedback) {
|
||||||
World.current.enqueueAction(sendMessage(m, metaLevel, isFeedback));
|
World.current().enqueueAction(sendMessage(m, metaLevel, isFeedback));
|
||||||
};
|
};
|
||||||
|
|
||||||
World.updateRoutes = function (routes) {
|
World.updateRoutes = function (routes) {
|
||||||
World.current.enqueueAction(updateRoutes(routes));
|
World.current().enqueueAction(updateRoutes(routes));
|
||||||
};
|
};
|
||||||
|
|
||||||
World.spawn = function (behavior, initialRoutes) {
|
World.spawn = function (behavior, initialRoutes) {
|
||||||
World.current.enqueueAction(spawn(behavior, initialRoutes));
|
World.current().enqueueAction(spawn(behavior, initialRoutes));
|
||||||
|
};
|
||||||
|
|
||||||
|
World.withWorldStack = function (stack, f) {
|
||||||
|
var oldStack = World.stack;
|
||||||
|
World.stack = stack;
|
||||||
|
var result = null;
|
||||||
|
try {
|
||||||
|
result = f();
|
||||||
|
} catch (e) {
|
||||||
|
World.stack = oldStack;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
World.stack = oldStack;
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
World.wrap = function (f) {
|
World.wrap = function (f) {
|
||||||
return World.current.wrap(f);
|
var savedStack = World.stack.slice();
|
||||||
|
var savedPid = World.current().activePid;
|
||||||
|
return function () {
|
||||||
|
var actuals = arguments;
|
||||||
|
return World.withWorldStack(savedStack, function () {
|
||||||
|
var result = World.current().asChild(savedPid, function () {
|
||||||
|
return f.apply(null, actuals);
|
||||||
|
});
|
||||||
|
World.stack[0].startStepping();
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Instance methods */
|
/* Instance methods */
|
||||||
|
@ -204,12 +233,6 @@ World.prototype.enqueueAction = function (action) {
|
||||||
this.processActions.push([this.activePid, action]);
|
this.processActions.push([this.activePid, action]);
|
||||||
};
|
};
|
||||||
|
|
||||||
World.prototype.enqueueActions = function (pid, actions) {
|
|
||||||
for (var i = 0; i < actions.length; i++) {
|
|
||||||
this.processActions.push([pid, actions[i]]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
World.prototype.isQuiescent = function () {
|
World.prototype.isQuiescent = function () {
|
||||||
return this.eventQueue.length === 0 && this.processActions.length === 0;
|
return this.eventQueue.length === 0 && this.processActions.length === 0;
|
||||||
};
|
};
|
||||||
|
@ -239,9 +262,8 @@ World.prototype.stopStepping = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
World.prototype.asChild = function (pid, f) {
|
World.prototype.asChild = function (pid, f) {
|
||||||
var oldWorld = World.current;
|
World.stack.push(this);
|
||||||
var result = null;
|
var result = null;
|
||||||
World.current = this;
|
|
||||||
this.activePid = pid;
|
this.activePid = pid;
|
||||||
try {
|
try {
|
||||||
result = f();
|
result = f();
|
||||||
|
@ -249,24 +271,17 @@ World.prototype.asChild = function (pid, f) {
|
||||||
this.kill(pid, e);
|
this.kill(pid, e);
|
||||||
}
|
}
|
||||||
this.activePid = null;
|
this.activePid = null;
|
||||||
World.current = oldWorld;
|
if (World.stack.pop() !== this) {
|
||||||
|
throw { message: "Internal error: World stack imbalance" };
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
World.prototype.wrap = function (f) {
|
|
||||||
var savedWorld = this;
|
|
||||||
var savedPid = this.activePid;
|
|
||||||
return function () {
|
|
||||||
var actuals = arguments;
|
|
||||||
return savedWorld.asChild(savedPid, function () { return f.apply(null, actuals) });
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
World.prototype.kill = function (pid, exn) {
|
World.prototype.kill = function (pid, exn) {
|
||||||
if (exn && exn.stack) {
|
if (exn && exn.stack) {
|
||||||
console.log("Killed process", pid, exn, exn.stack);
|
console.log("Killed process", pid, exn, exn.stack);
|
||||||
} else {
|
} else {
|
||||||
console.log("Killed process", pid);
|
console.log("Killed process", pid, exn);
|
||||||
}
|
}
|
||||||
delete this.processTable[pid];
|
delete this.processTable[pid];
|
||||||
this.issueRoutingUpdate();
|
this.issueRoutingUpdate();
|
||||||
|
@ -311,7 +326,11 @@ World.prototype.performAction = function (pid, action) {
|
||||||
this.issueRoutingUpdate();
|
this.issueRoutingUpdate();
|
||||||
break;
|
break;
|
||||||
case "routes":
|
case "routes":
|
||||||
this.processTable[pid].routes = action.routes;
|
if (pid in this.processTable) {
|
||||||
|
// it may not be: this might be the routing update from a
|
||||||
|
// kill of the process
|
||||||
|
this.processTable[pid].routes = action.routes;
|
||||||
|
}
|
||||||
this.issueRoutingUpdate();
|
this.issueRoutingUpdate();
|
||||||
break;
|
break;
|
||||||
case "send":
|
case "send":
|
||||||
|
@ -373,33 +392,16 @@ World.prototype.handleEvent = function (e) {
|
||||||
function Ground(bootFn) {
|
function Ground(bootFn) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.stepperId = null;
|
this.stepperId = null;
|
||||||
this.wrap(function () {
|
World.withWorldStack([this], function () {
|
||||||
self.world = new World(bootFn);
|
self.world = new World(bootFn);
|
||||||
})();
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Ground.prototype.wrap = function (f) {
|
|
||||||
var self = this;
|
|
||||||
return function () {
|
|
||||||
var oldWorld = World.current;
|
|
||||||
var result = null;
|
|
||||||
World.current = self;
|
|
||||||
try {
|
|
||||||
result = f();
|
|
||||||
} catch (e) {
|
|
||||||
World.current = oldWorld;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
World.current = oldWorld;
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
Ground.prototype.step = function () {
|
Ground.prototype.step = function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
return this.wrap(function () {
|
return World.withWorldStack([this], function () {
|
||||||
return self.world.step();
|
return self.world.step();
|
||||||
})();
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Ground.prototype.startStepping = World.prototype.startStepping;
|
Ground.prototype.startStepping = World.prototype.startStepping;
|
||||||
|
|
Loading…
Reference in New Issue