DemandMatcher improvements from minimart
This commit is contained in:
parent
1a8cc0edac
commit
5d6cc2b503
22
index.js
22
index.js
|
@ -25,32 +25,22 @@ JQueryEventRouter.prototype.handleEvent = function (e) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function JQueryDriver() {
|
function spawnJQueryDriver() {
|
||||||
var self = this;
|
var d = new DemandMatcher(["jQuery", __, __, __]);
|
||||||
this.state = new DemandMatcher(true, function (r) {
|
d.onDemandIncrease = function (r) {
|
||||||
var selector = r.pattern[1];
|
var selector = r.pattern[1];
|
||||||
var eventName = r.pattern[2];
|
var eventName = r.pattern[2];
|
||||||
World.spawn(new JQueryEventRouter(selector, eventName),
|
World.spawn(new JQueryEventRouter(selector, eventName),
|
||||||
[pub(["jQuery", selector, eventName, __]),
|
[pub(["jQuery", selector, eventName, __]),
|
||||||
pub(["jQuery", selector, eventName, __], 0, 1)]);
|
pub(["jQuery", selector, eventName, __], 0, 1)]);
|
||||||
});
|
};
|
||||||
|
World.spawn(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
JQueryDriver.prototype.boot = function () {
|
|
||||||
World.updateRoutes([pub(["jQuery", __, __, __], 0, 1),
|
|
||||||
sub(["jQuery", __, __, __], 0, 1)]);
|
|
||||||
};
|
|
||||||
|
|
||||||
JQueryDriver.prototype.handleEvent = function (e) {
|
|
||||||
if (e.type === "routes") {
|
|
||||||
this.state.handleRoutes(e.routes);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var g = new Ground(function () {
|
var g = new Ground(function () {
|
||||||
console.log('starting ground boot');
|
console.log('starting ground boot');
|
||||||
World.spawn(new Spy());
|
World.spawn(new Spy());
|
||||||
World.spawn(new JQueryDriver());
|
spawnJQueryDriver();
|
||||||
World.spawn({
|
World.spawn({
|
||||||
// step: function () { console.log('dummy step'); },
|
// step: function () { console.log('dummy step'); },
|
||||||
boot: function () {
|
boot: function () {
|
||||||
|
|
|
@ -421,6 +421,12 @@ PresenceDetector.prototype._digestRoutes = function (routes) {
|
||||||
return newState;
|
return newState;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PresenceDetector.prototype.getRouteList = function () {
|
||||||
|
var rs = [];
|
||||||
|
for (var k in this.state) { rs.push(this.state[k]); }
|
||||||
|
return rs;
|
||||||
|
};
|
||||||
|
|
||||||
PresenceDetector.prototype.handleRoutes = function (routes) {
|
PresenceDetector.prototype.handleRoutes = function (routes) {
|
||||||
var added = [];
|
var added = [];
|
||||||
var removed = [];
|
var removed = [];
|
||||||
|
@ -456,32 +462,77 @@ PresenceDetector.prototype.presenceExistsFor = function (probeRoute) {
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Utilities: matching demand for some service */
|
/* Utilities: matching demand for some service */
|
||||||
|
|
||||||
function DemandMatcher(demandSideIsSubscription, demandIncreaseHandler, supplyDecreaseHandler) {
|
function DemandMatcher(pattern, metaLevel, options) {
|
||||||
this.demandSideIsSubscription = demandSideIsSubscription;
|
options = $.extend(options, {
|
||||||
this.demandIncreaseHandler = demandIncreaseHandler;
|
demandLevel: 0,
|
||||||
this.supplyDecreaseHandler = supplyDecreaseHandler || function (r) {
|
supplyLevel: 0,
|
||||||
console.error("Unexpected drop in supply for route", r);
|
demandSideIsSubscription: true
|
||||||
|
});
|
||||||
|
this.pattern = pattern;
|
||||||
|
this.metaLevel = metaLevel;
|
||||||
|
this.demandLevel = options.demandLevel;
|
||||||
|
this.supplyLevel = options.supplyLevel;
|
||||||
|
this.demandSideIsSubscription = options.demandSideIsSubscription;
|
||||||
|
this.onDemandIncrease = function (r) {
|
||||||
|
console.error("Unhandled increase in demand for route", r);
|
||||||
|
};
|
||||||
|
this.onSupplyDecrease = function (r) {
|
||||||
|
console.error("Unhandled decrease in supply for route", r);
|
||||||
};
|
};
|
||||||
this.state = new PresenceDetector();
|
this.state = new PresenceDetector();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DemandMatcher.prototype.boot = function () {
|
||||||
|
World.updateRoutes([this.computeDetector(true),
|
||||||
|
this.computeDetector(false)]);
|
||||||
|
};
|
||||||
|
|
||||||
|
DemandMatcher.prototype.handleEvent = function (e) {
|
||||||
|
if (e.type === "routes") {
|
||||||
|
this.handleRoutes(e.routes);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DemandMatcher.prototype.computeDetector = function (demandSide) {
|
||||||
|
var maxLevel = (this.demandLevel > this.supplyLevel ? this.demandLevel : this.supplyLevel);
|
||||||
|
return new Route(this.demandSideIsSubscription ? !demandSide : demandSide,
|
||||||
|
this.pattern,
|
||||||
|
this.metaLevel,
|
||||||
|
maxLevel + 1);
|
||||||
|
};
|
||||||
|
|
||||||
DemandMatcher.prototype.handleRoutes = function (routes) {
|
DemandMatcher.prototype.handleRoutes = function (routes) {
|
||||||
var changes = this.state.handleRoutes(routes);
|
var changes = this.state.handleRoutes(routes);
|
||||||
for (var i = 0; i < changes.added.length; i++) {
|
this.incorporateChanges(true, changes.added);
|
||||||
if (changes.added[i].isSubscription === this.demandSideIsSubscription
|
this.incorporateChanges(false, changes.removed);
|
||||||
&& !this.state.presenceExistsFor(changes.added[i]))
|
};
|
||||||
{
|
|
||||||
this.demandIncreaseHandler(changes.added[i]);
|
DemandMatcher.prototype.incorporateChanges = function (isArrivals, routeList) {
|
||||||
|
var relevantChangeDetector = this.computeDetector(isArrivals);
|
||||||
|
var expectedChangeLevel = isArrivals ? this.demandLevel : this.supplyLevel;
|
||||||
|
var expectedPeerLevel = isArrivals ? this.supplyLevel : this.demandLevel;
|
||||||
|
for (var i = 0; i < routeList.length; i++) {
|
||||||
|
var changed = routeList[i];
|
||||||
|
if (changed.level != expectedChangeLevel) continue;
|
||||||
|
var relevantChangedN = intersectRoutes([changed], [relevantChangeDetector]);
|
||||||
|
if (relevantChangedN.length === 0) continue;
|
||||||
|
var relevantChanged = relevantChangedN[0]; /* there can be only one */
|
||||||
|
var peerDetector = new Route(relevantChanged.isSubscription,
|
||||||
|
relevantChanged.pattern,
|
||||||
|
relevantChanged.metaLevel,
|
||||||
|
expectedPeerLevel + 1);
|
||||||
|
var peerRoutes = intersectRoutes(this.state.getRouteList(), [peerDetector]);
|
||||||
|
var peerExists = false;
|
||||||
|
for (var j = 0; j < peerRoutes.length; j++) {
|
||||||
|
if (peerRoutes[j].level == expectedPeerLevel) {
|
||||||
|
peerExists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (isArrivals && !peerExists) { this.onDemandIncrease(relevantChanged); }
|
||||||
|
if (!isArrivals && peerExists) { this.onSupplyDecrease(relevantChanged); }
|
||||||
}
|
}
|
||||||
for (var i = 0; i < changes.removed.length; i++) {
|
};
|
||||||
if (changes.removed[i].isSubscription === !this.demandSideIsSubscription
|
|
||||||
&& this.state.presenceExistsFor(changes.removed[i]))
|
|
||||||
{
|
|
||||||
this.supplyDecreaseHandler(changes.removed[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Ground interface */
|
/* Ground interface */
|
||||||
|
|
Loading…
Reference in New Issue