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

View File

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

View File

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