Support risingEdge transition events

This commit is contained in:
Tony Garnock-Jones 2016-03-19 13:48:49 -04:00
parent e7de06c2d2
commit d87118f686
3 changed files with 72 additions and 37 deletions

View File

@ -60,6 +60,24 @@ function buildOnEvent(isTerminal, eventType, subscription, projection, bindings,
', (function(' + bindings.join(', ') + ') ' + body + '))';
}
function buildCaseEvent(eventPattern, body) {
if (eventPattern.eventType === 'risingEdge') {
return buildOnEvent(true,
eventPattern.eventType,
'function() { return (' + eventPattern.asES5 + '); }',
'null',
[],
body);
} else {
return buildOnEvent(true,
eventPattern.eventType,
eventPattern.subscription,
eventPattern.projection,
eventPattern.bindings,
body);
}
}
var modifiedSourceActions = {
ActorStatement_noConstructor: function(_actor, block) {
return buildActor('Object()', block);
@ -166,20 +184,10 @@ var modifiedSourceActions = {
},
FacetStateTransition_withContinuation: function(_case, eventPattern, block) {
return buildOnEvent(true,
eventPattern.eventType,
eventPattern.subscription,
eventPattern.projection,
eventPattern.bindings,
block.asES5);
return buildCaseEvent(eventPattern, block.asES5);
},
FacetStateTransition_noContinuation: function(_case, eventPattern, _sc) {
return buildOnEvent(true,
eventPattern.eventType,
eventPattern.subscription,
eventPattern.projection,
eventPattern.bindings,
'');
return buildCaseEvent(eventPattern, '');
}
};
@ -197,7 +205,10 @@ semantics.addAttribute('asSyndicateStructureArguments', {
semantics.addAttribute('eventType', {
FacetEventPattern_messageEvent: function(_kw, _pattern) { return 'message'; },
FacetEventPattern_assertedEvent: function(_kw, _pattern) { return 'asserted'; },
FacetEventPattern_retractedEvent: function(_kw, _pattern) { return 'retracted'; }
FacetEventPattern_retractedEvent: function(_kw, _pattern) { return 'retracted'; },
FacetTransitionEventPattern_facetEvent: function (pattern) { return pattern.eventType; },
FacetTransitionEventPattern_risingEdge: function (expr) { return 'risingEdge'; }
});
function buildSubscription(children, patchMethod, mode) {
@ -247,6 +258,8 @@ semantics.addAttribute('metalevel', {
FacetEventPattern_assertedEvent: function(_kw, p) { return p.metalevel; },
FacetEventPattern_retractedEvent: function(_kw, p) { return p.metalevel; },
FacetTransitionEventPattern_facetEvent: function (pattern) { return pattern.metalevel; },
FacetPattern_withMetalevel: function(_expr, _kw, metalevel) {
return metalevel.interval.contents;
},
@ -266,6 +279,10 @@ semantics.addOperation('buildSubscription(acc,mode)', {
pattern.buildSubscription(this.args.acc, this.args.mode);
},
FacetTransitionEventPattern_facetEvent: function (pattern) {
pattern.buildSubscription(this.args.acc, this.args.mode);
},
FacetPattern: function (v) {
v.children[0].buildSubscription(this.args.acc, this.args.mode); // both branches!
},

View File

@ -50,9 +50,13 @@ Syndicate <: ES5 {
| asserted FacetPattern -- assertedEvent
| retracted FacetPattern -- retractedEvent
FacetTransitionEventPattern
= FacetEventPattern -- facetEvent
| Expression<withIn> -- risingEdge
FacetStateTransition
= case FacetEventPattern Block -- withContinuation
| case FacetEventPattern #(sc) -- noContinuation
= case FacetTransitionEventPattern Block -- withContinuation
| case FacetTransitionEventPattern #(sc) -- noContinuation
FacetPattern
= LeftHandSideExpression metalevel decimalIntegerLiteral -- withMetalevel

View File

@ -67,13 +67,13 @@ Facet.prototype.addAssertion = function(assertionFn) {
Facet.prototype.onEvent = function(isTerminal, eventType, subscriptionFn, projectionFn, handlerFn) {
var facet = this;
return this.addEndpoint(new Endpoint(subscriptionFn, function(e) {
var proj = projectionFn.call(facet.actor.state);
var spec = Patch.prependAtMeta(proj.assertion, proj.metalevel);
switch (eventType) {
switch (e.type) {
case 'message':
if (eventType === 'message') {
case 'message':
return this.addEndpoint(new Endpoint(subscriptionFn, function(e) {
if (e.type === 'message') {
var proj = projectionFn.call(facet.actor.state);
var spec = Patch.prependAtMeta(proj.assertion, proj.metalevel);
var match = Route.matchPattern(e.message, spec);
// console.log(match);
if (match) {
@ -81,29 +81,43 @@ Facet.prototype.onEvent = function(isTerminal, eventType, subscriptionFn, projec
Util.kwApply(handlerFn, facet.actor.state, match);
}
}
break;
case 'stateChange':
{
var objects;
switch (eventType) {
case 'asserted':
objects = Route.projectObjects(e.patch.added, Route.compileProjection(spec));
break;
case 'retracted':
objects = Route.projectObjects(e.patch.removed, Route.compileProjection(spec));
break;
default:
break;
}
}));
case 'asserted': /* fall through */
case 'retracted':
return this.addEndpoint(new Endpoint(subscriptionFn, function(e) {
if (e.type === 'stateChange') {
var proj = projectionFn.call(facet.actor.state);
var spec = Patch.prependAtMeta(proj.assertion, proj.metalevel);
var compiledSpec = Route.compileProjection(spec);
var objects = Route.projectObjects(eventType === 'asserted'
? e.patch.added
: e.patch.removed,
compiledSpec);
if (objects) {
if (isTerminal) { facet.terminate(); }
// console.log(objects.toArray());
objects.forEach(function (o) { Util.kwApply(handlerFn, facet.actor.state, o); });
}
}
}
}));
}));
case 'risingEdge':
var endpoint = new Endpoint(function() { return Patch.emptyPatch; },
function(e) {
var newValue = subscriptionFn.call(facet.actor.state);
if (newValue && !this.currentValue) {
if (isTerminal) { facet.terminate(); }
handlerFn.call(facet.actor.state);
}
this.currentValue = newValue;
});
endpoint.currentValue = false;
return this.addEndpoint(endpoint);
default:
throw new Error("Unsupported Facet eventType: " + eventType);
}
};
Facet.prototype.addEndpoint = function(endpoint) {