Split out Ground, Codec
This commit is contained in:
parent
f46fd52239
commit
e78696c621
|
@ -0,0 +1,33 @@
|
||||||
|
// Wire protocol representation of events and actions
|
||||||
|
|
||||||
|
var Route = require("./route.js");
|
||||||
|
|
||||||
|
function _encode(e) {
|
||||||
|
switch (e.type) {
|
||||||
|
case "routes":
|
||||||
|
return ["routes", e.gestalt.serialize(function (v) { return true; })];
|
||||||
|
case "message":
|
||||||
|
return ["message", e.message, e.metaLevel, e.isFeedback];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _decode(what) {
|
||||||
|
return function (j) {
|
||||||
|
switch (j[0]) {
|
||||||
|
case "routes":
|
||||||
|
return Minimart.updateRoutes([
|
||||||
|
Route.deserializeGestalt(j[1], function (v) { return true; })]);
|
||||||
|
case "message":
|
||||||
|
return Minimart.sendMessage(j[1], j[2], j[3]);
|
||||||
|
default:
|
||||||
|
throw { message: "Invalid JSON-encoded " + what + ": " + JSON.stringify(j) };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
module.exports.encodeEvent = _encode;
|
||||||
|
module.exports.decodeEvent = _decode("event");
|
||||||
|
module.exports.encodeAction = _encode;
|
||||||
|
module.exports.decodeAction = _decode("action");
|
|
@ -0,0 +1,61 @@
|
||||||
|
/* Ground interface */
|
||||||
|
var Minimart = require("./minimart.js");
|
||||||
|
var World = Minimart.World;
|
||||||
|
|
||||||
|
function Ground(bootFn) {
|
||||||
|
var self = this;
|
||||||
|
this.stepperId = null;
|
||||||
|
World.withWorldStack([[this, -1]], function () {
|
||||||
|
self.world = new World(bootFn);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ground.prototype.step = function () {
|
||||||
|
var self = this;
|
||||||
|
return World.withWorldStack([[this, -1]], function () {
|
||||||
|
return self.world.step();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Ground.prototype.checkPid = function (pid) {
|
||||||
|
if (pid !== -1) console.error("Weird pid in Ground markPidRunnable", pid);
|
||||||
|
};
|
||||||
|
|
||||||
|
Ground.prototype.markPidRunnable = function (pid) {
|
||||||
|
this.checkPid(pid);
|
||||||
|
this.startStepping();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ground.prototype.startStepping = function () {
|
||||||
|
var self = this;
|
||||||
|
if (this.stepperId) return;
|
||||||
|
if (this.step()) {
|
||||||
|
this.stepperId = setTimeout(function () {
|
||||||
|
self.stepperId = null;
|
||||||
|
self.startStepping();
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ground.prototype.stopStepping = function () {
|
||||||
|
if (this.stepperId) {
|
||||||
|
clearTimeout(this.stepperId);
|
||||||
|
this.stepperId = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ground.prototype.enqueueAction = function (pid, action) {
|
||||||
|
this.checkPid(pid);
|
||||||
|
if (action.type === 'routes') {
|
||||||
|
if (!action.gestalt.isEmpty()) {
|
||||||
|
console.error("You have subscribed to a nonexistent event source.",
|
||||||
|
action.gestalt.pretty());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error("You have sent a message into the outer void.", action);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
module.exports.Ground = Ground;
|
|
@ -6,6 +6,7 @@ module.exports.RoutingTableWidget = require("./routing-table-widget.js");
|
||||||
module.exports.WebSocket = require("./websocket-driver.js");
|
module.exports.WebSocket = require("./websocket-driver.js");
|
||||||
module.exports.Reflect = require("./reflect.js");
|
module.exports.Reflect = require("./reflect.js");
|
||||||
|
|
||||||
|
module.exports.Ground = require("./ground.js").Ground;
|
||||||
|
module.exports.Actor = require("./actor.js").Actor;
|
||||||
module.exports.Spy = require("./spy.js").Spy;
|
module.exports.Spy = require("./spy.js").Spy;
|
||||||
module.exports.WakeDetector = require("./wake-detector.js").WakeDetector;
|
module.exports.WakeDetector = require("./wake-detector.js").WakeDetector;
|
||||||
module.exports.Actor = require("./actor.js").Actor;
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
var Route = require("./route.js");
|
var Route = require("./route.js");
|
||||||
|
var Util = require("./util.js");
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -390,7 +391,7 @@ World.prototype.clearTombstones = function () {
|
||||||
/* Utilities: matching demand for some service */
|
/* Utilities: matching demand for some service */
|
||||||
|
|
||||||
function DemandMatcher(projection, metaLevel, options) {
|
function DemandMatcher(projection, metaLevel, options) {
|
||||||
options = $.extend({
|
options = Util.extend({
|
||||||
demandLevel: 0,
|
demandLevel: 0,
|
||||||
supplyLevel: 0,
|
supplyLevel: 0,
|
||||||
demandSideIsSubscription: false
|
demandSideIsSubscription: false
|
||||||
|
@ -481,63 +482,6 @@ Deduplicator.prototype.expireMessages = function () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/* Ground interface */
|
|
||||||
|
|
||||||
function Ground(bootFn) {
|
|
||||||
var self = this;
|
|
||||||
this.stepperId = null;
|
|
||||||
World.withWorldStack([[this, -1]], function () {
|
|
||||||
self.world = new World(bootFn);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Ground.prototype.step = function () {
|
|
||||||
var self = this;
|
|
||||||
return World.withWorldStack([[this, -1]], function () {
|
|
||||||
return self.world.step();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Ground.prototype.checkPid = function (pid) {
|
|
||||||
if (pid !== -1) console.error("Weird pid in Ground markPidRunnable", pid);
|
|
||||||
};
|
|
||||||
|
|
||||||
Ground.prototype.markPidRunnable = function (pid) {
|
|
||||||
this.checkPid(pid);
|
|
||||||
this.startStepping();
|
|
||||||
};
|
|
||||||
|
|
||||||
Ground.prototype.startStepping = function () {
|
|
||||||
var self = this;
|
|
||||||
if (this.stepperId) return;
|
|
||||||
if (this.step()) {
|
|
||||||
this.stepperId = setTimeout(function () {
|
|
||||||
self.stepperId = null;
|
|
||||||
self.startStepping();
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ground.prototype.stopStepping = function () {
|
|
||||||
if (this.stepperId) {
|
|
||||||
clearTimeout(this.stepperId);
|
|
||||||
this.stepperId = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ground.prototype.enqueueAction = function (pid, action) {
|
|
||||||
this.checkPid(pid);
|
|
||||||
if (action.type === 'routes') {
|
|
||||||
if (!action.gestalt.isEmpty()) {
|
|
||||||
console.error("You have subscribed to a nonexistent event source.",
|
|
||||||
action.gestalt.pretty());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.error("You have sent a message into the outer void.", action);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
module.exports.__ = __;
|
module.exports.__ = __;
|
||||||
|
@ -553,5 +497,4 @@ module.exports.shutdownWorld = shutdownWorld;
|
||||||
module.exports.World = World;
|
module.exports.World = World;
|
||||||
module.exports.DemandMatcher = DemandMatcher;
|
module.exports.DemandMatcher = DemandMatcher;
|
||||||
module.exports.Deduplicator = Deduplicator;
|
module.exports.Deduplicator = Deduplicator;
|
||||||
module.exports.Ground = Ground;
|
|
||||||
module.exports.Route = Route;
|
module.exports.Route = Route;
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
// Minimal jQueryish utilities. Reimplemented because jQuery needs
|
||||||
|
// window to exist, and we want to run in Web Worker context as well.
|
||||||
|
|
||||||
|
function extend(what, _with) {
|
||||||
|
for (var prop in _with) {
|
||||||
|
if (_with.hasOwnProperty(prop)) {
|
||||||
|
what[prop] = _with[prop];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return what;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.extend = extend;
|
|
@ -1,4 +1,5 @@
|
||||||
var Minimart = require("./minimart.js");
|
var Minimart = require("./minimart.js");
|
||||||
|
var Codec = require("./codec.js");
|
||||||
var Route = Minimart.Route;
|
var Route = Minimart.Route;
|
||||||
var World = Minimart.World;
|
var World = Minimart.World;
|
||||||
var sub = Minimart.sub;
|
var sub = Minimart.sub;
|
||||||
|
@ -97,7 +98,7 @@ WebSocketConnection.prototype.safeSend = function (m) {
|
||||||
|
|
||||||
WebSocketConnection.prototype.sendLocalRoutes = function () {
|
WebSocketConnection.prototype.sendLocalRoutes = function () {
|
||||||
var newLocalRoutesMessage =
|
var newLocalRoutesMessage =
|
||||||
JSON.stringify(encodeEvent(Minimart.updateRoutes([this.localGestalt])));
|
JSON.stringify(Codec.encodeEvent(Minimart.updateRoutes([this.localGestalt])));
|
||||||
if (this.prevLocalRoutesMessage !== newLocalRoutesMessage) {
|
if (this.prevLocalRoutesMessage !== newLocalRoutesMessage) {
|
||||||
this.prevLocalRoutesMessage = newLocalRoutesMessage;
|
this.prevLocalRoutesMessage = newLocalRoutesMessage;
|
||||||
this.safeSend(newLocalRoutesMessage);
|
this.safeSend(newLocalRoutesMessage);
|
||||||
|
@ -138,7 +139,7 @@ WebSocketConnection.prototype.handleEvent = function (e) {
|
||||||
var m = e.message;
|
var m = e.message;
|
||||||
if (m.length && m.length === 3 && m[0] === this.label)
|
if (m.length && m.length === 3 && m[0] === this.label)
|
||||||
{
|
{
|
||||||
var encoded = JSON.stringify(encodeEvent(
|
var encoded = JSON.stringify(Codec.encodeEvent(
|
||||||
Minimart.sendMessage(m[2], m[1], e.isFeedback)));
|
Minimart.sendMessage(m[2], m[1], e.isFeedback)));
|
||||||
if (this.deduplicator.accept(encoded)) {
|
if (this.deduplicator.accept(encoded)) {
|
||||||
this.safeSend(encoded);
|
this.safeSend(encoded);
|
||||||
|
@ -227,32 +228,6 @@ WebSocketConnection.prototype.onclose = function (e) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Wire protocol representation of events and actions
|
|
||||||
|
|
||||||
function encodeEvent(e) {
|
|
||||||
switch (e.type) {
|
|
||||||
case "routes":
|
|
||||||
return ["routes", e.gestalt.serialize(function (v) { return true; })];
|
|
||||||
case "message":
|
|
||||||
return ["message", e.message, e.metaLevel, e.isFeedback];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function decodeAction(j) {
|
|
||||||
switch (j[0]) {
|
|
||||||
case "routes":
|
|
||||||
return Minimart.updateRoutes([
|
|
||||||
Route.deserializeGestalt(j[1], function (v) { return true; })]);
|
|
||||||
case "message":
|
|
||||||
return Minimart.sendMessage(j[1], j[2], j[3]);
|
|
||||||
default:
|
|
||||||
throw { message: "Invalid JSON-encoded action: " + JSON.stringify(j) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
module.exports.WebSocketConnection = WebSocketConnection;
|
module.exports.WebSocketConnection = WebSocketConnection;
|
||||||
module.exports.encodeEvent = encodeEvent;
|
|
||||||
module.exports.decodeAction = decodeAction;
|
|
||||||
|
|
Loading…
Reference in New Issue