Permalink
Browse files

Added support for wildcard ("*") event in optimized transition select…

…ors. Tested and works.
  • Loading branch information...
1 parent 7830329 commit 465321ef651a27d019f95aa0a467c6208558405a @jbeard4 committed Feb 21, 2012
@@ -14,7 +14,26 @@
define ["optimization/initializer","lib/beautify"],(initializer,js_beautify)->
(scxmlJson,beautify=true,asyncModuleDef=true) ->
- DEFAULT_EVENT_NAME = "*"
+
+ #the SCXML spec states that events must be alphanumeric, so picking out special strings to use as event names is technically safe
+ WILDCARD_EVENT_NAME = "*"
+ DEFAULT_EVENT_NAME = " "
+
+ generateMethod = (eventName,transitions,parent) ->
+ """
+ this['#{eventName}'] = function(evaluator){
+ var toReturn = [];
+ var transitions = #{initializer.arrayToIdentifierListString transitions};
+ for(var i = 0,l=transitions.length; i < l; i++){
+ var transition = transitions[i];
+ if(!transition.cond || evaluator(transition)){
+ toReturn.push(transition);
+ }
+ }
+
+ return toReturn.length ? toReturn : #{if parent then "instances['#{parent.id}']['#{eventName}'](evaluator)" else "null"};
+ };
+ """
generateStateClassString = (state) ->
classStr = """
@@ -23,46 +42,30 @@ define ["optimization/initializer","lib/beautify"],(initializer,js_beautify)->
"#{state.id}" : function(){
"""
if state.parent
+
+ parent = state.parent
+
+ #NOTE: scxmlJson.events will not contain wildcard ("*") event,
+ #and will normalize events like "foo.bat.*" to "foo.bat"
for own eventName,event of scxmlJson.events
- transitionsForEvent = (initializer.transitionToVarLabel transition for transition in state.transitions when not transition.event or transition.event == event.name)
+ transitionsForEvent = (initializer.transitionToVarLabel transition for transition in state.transitions when transition.event == event.name)
if transitionsForEvent.length
- classStr += """
- this['#{event.name}'] = function(evaluator){
- var toReturn = [];
- var transitions = #{initializer.arrayToIdentifierListString transitionsForEvent};
- for(var i = 0,l=transitions.length; i < l; i++){
- var transition = transitions[i];
- if(!transition.cond || evaluator(transition)){
- toReturn.push(transition);
- }
- }
-
- return toReturn.length ? toReturn : #{if state.parent then "instances['#{state.parent.id}']['#{event.name}'](evaluator)" else "null"};
- };
- """
+ classStr += generateMethod event.name,transitionsForEvent,parent
defaultTransitionsForEvent = (initializer.transitionToVarLabel transition for transition in state.transitions when not transition.event)
if defaultTransitionsForEvent.length
- classStr += """
- this['#{DEFAULT_EVENT_NAME}'] = function(evaluator){
- var toReturn = [];
- var transitions = #{initializer.arrayToIdentifierListString defaultTransitionsForEvent };
- for(var i = 0,l=transitions.length; i < l; i++){
- var transition = transitions[i];
- if(!transition.cond || evaluator(transition)){
- toReturn.push(transition);
- }
- }
-
- return toReturn.length ? toReturn : #{if state.parent then "instances['#{state.parent.id}']['#{DEFAULT_EVENT_NAME}'](evaluator)" else "null"};
- };
- """
+ classStr += generateMethod DEFAULT_EVENT_NAME,defaultTransitionsForEvent,parent
+
+ wildcardTransitionsForEvent = (initializer.transitionToVarLabel transition for transition in state.transitions when transition.event is "*")
+ if wildcardTransitionsForEvent.length
+ classStr += generateMethod WILDCARD_EVENT_NAME,wildcardTransitionsForEvent,parent
else
#root state
for eventName,event of scxmlJson.events
classStr += "this['#{event.name}'] = function(){return null;};\n"
classStr += "this['#{DEFAULT_EVENT_NAME}'] = function(){return null;};\n"
+ classStr += "this['#{WILDCARD_EVENT_NAME}'] = function(){return null;};\n"
classStr += """
}
@@ -90,6 +93,7 @@ define ["optimization/initializer","lib/beautify"],(initializer,js_beautify)->
var toReturn = [];
if(eventNames.length){
+ //named events
for(var j = 0; j < eventNames.length; j++){
var eventName = eventNames[j];
@@ -101,10 +105,13 @@ define ["optimization/initializer","lib/beautify"],(initializer,js_beautify)->
}
}
}
- }else{
- //default events
- toReturn = toReturn.concat(stateClassNameList[state.documentOrder]['#{DEFAULT_EVENT_NAME}'](evaluator) || []);
+
+ //wildcard event
+ toReturn = toReturn.concat(stateClassNameList[state.documentOrder]['#{WILDCARD_EVENT_NAME}'](evaluator) || []);
}
+
+ //default events
+ toReturn = toReturn.concat(stateClassNameList[state.documentOrder]['#{DEFAULT_EVENT_NAME}'](evaluator) || []);
return toReturn;
};
"""
@@ -69,11 +69,15 @@ define ["optimization/initializer","lib/beautify"],(initializer,js_beautify)->
return toReturn
(scxmlJson,beautify=true,asyncModuleDef=true) ->
- stateTransitionTable = (((initializer.transitionToVarLabel transition for transition in state.transitions when not transition.event or transition.event == event.name) for eventName,event of scxmlJson.events ) for state in scxmlJson.states)
+ #NOTE: scxmlJson.events will not contain wildcard ("*") event,
+ #and will normalize events like "foo.bat.*" to "foo.bat"
+ stateTransitionTable = (((initializer.transitionToVarLabel transition for transition in state.transitions when transition.event == event.name) for eventName,event of scxmlJson.events ) for state in scxmlJson.states)
+ wildcardTransitionsForStates = ((initializer.transitionToVarLabel transition for transition in state.transitions when transition.event is "*") for state in scxmlJson.states)
defaultTransitionsForStates = ((initializer.transitionToVarLabel transition for transition in state.transitions when not transition.event) for state in scxmlJson.states)
toReturn = initializer.genOuterInitializerStr scxmlJson,"""
- var stateTransitionTable = #{tableToString stateTransitionTable};
- var defaultTransitionTable = #{defaultTableToString defaultTransitionsForStates};
+ var stateTransitionTable = #{tableToString stateTransitionTable},
+ wildcardTransitionTable = #{defaultTableToString wildcardTransitionsForStates},
+ defaultTransitionTable = #{defaultTableToString defaultTransitionsForStates};
return function(state,eventNames,evaluator){
var transitions = [];
@@ -87,10 +91,11 @@ define ["optimization/initializer","lib/beautify"],(initializer,js_beautify)->
transitions = transitions.concat(stateTransitionTable[state.documentOrder][eventId] || []);
}
}
- }else{
- //default events
- transitions = transitions.concat(defaultTransitionTable[state.documentOrder] || []);
+
+ transitions = transitions.concat(wildcardTransitionTable[state.documentOrder] || []);
}
+ //default events
+ transitions = transitions.concat(defaultTransitionTable[state.documentOrder] || []);
#{initializer.transitionFilterString}
};
@@ -19,57 +19,64 @@ define ["optimization/initializer","lib/beautify"],(initializer,js_beautify)->
return function(state,eventNames,evaluator){
var transitions=[];
- if(eventNames.length){
- for(var j = 0; j < eventNames.length; j++){
- var eventName = eventNames[j];
-
- switch(state.id){
+ switch(state.id){
"""
for state in scxmlJson.states when state.transitions.length
+
+ wildcardTransitions = (initializer.transitionToVarLabel transition for transition in state.transitions when transition.event is "*" )
+ defaultTransitions= (initializer.transitionToVarLabel transition for transition in state.transitions when not transition.event)
+
toReturn += """
- case "#{state.id}":
- switch(eventName){\n
+ case "#{state.id}":
+ """
+
+
+ if defaultTransitions.length
+ toReturn +=
+ """
+ //default transitions
+ transitions = transitions.concat(#{initializer.arrayToIdentifierListString defaultTransitions});
+ """
+
+ if wildcardTransitions.length
+ toReturn +=
+ """
+ if(eventNames.length){
+ //wildcard event
+ transitions = transitions.concat(#{initializer.arrayToIdentifierListString wildcardTransitions});
+ }
+ """
+
+ toReturn += """
+ for(var j = 0; j < eventNames.length; j++){
+ var eventName = eventNames[j];
+
+ switch(eventName){
"""
for eventName,event of scxmlJson.events
- transitionsForEvent = (initializer.transitionToVarLabel transition for transition in state.transitions when not transition.event or transition.event == event.name)
+ #NOTE: scxmlJson.events will not contain wildcard ("*") event,
+ #and will normalize events like "foo.bat.*" to "foo.bat"
+ transitionsForEvent = (initializer.transitionToVarLabel transition for transition in state.transitions when transition.event == event.name)
if transitionsForEvent.length
toReturn += """
- case "#{event.name}":
- transitions = transitions.concat(#{initializer.arrayToIdentifierListString transitionsForEvent});\n
- break;
+ case "#{event.name}":
+ transitions = transitions.concat(#{initializer.arrayToIdentifierListString transitionsForEvent});
+ break;
"""
toReturn += """
- default : break;
- }
- break;\n
+ default: break;
+ }
+ }
+ break;
"""
toReturn += """
- default : break;
- }
- }
- }else{
- //default events
- switch(state.id){
- """
- for state in scxmlJson.states when state.transitions.length
- defaultTransitionsForEvent = (initializer.transitionToVarLabel transition for transition in state.transitions when not transition.event)
- if defaultTransitionsForEvent.length
- toReturn += """
- case "#{state.id}":
- transitions = transitions.concat(#{initializer.arrayToIdentifierListString defaultTransitionsForEvent });
- break;\n
- """
-
-
- toReturn += """
- default : break;
- }
-
+ //should throw an error here for unrecognized state
+ default : break;
}
#{initializer.transitionFilterString}
@@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-define ["scxml/json2model","scxml/json2extra-model", "test-harness/harness", "scxml/async-for","util/set/ArraySet","util/set/BitVector","util/set/BooleanArray","util/set/ObjectSet", "tests/loaders/spartan-loader-for-all-tests", "tests/loaders/class-transition-lookup-optimization-loader", "tests/loaders/switch-transition-lookup-optimization-loader", "tests/loaders/table-transition-lookup-optimization-loader","scxml/model","scxml/extra-model","scxml/default-transition-selector"],(json2model,json2ExtraModel,harness,asyncForEach,ArraySet,BitVectorInitializer,BooleanArrayInitializer,ObjectSetInitializer,testTuples,classTransitionOpts,switchTransitionOpts,tableTransitionOpts,m,extraModel,defaultTransitionSelector) ->
+define ["scxml/json2model","scxml/json2extra-model", "test-harness/harness", "scxml/async-for","util/set/ArraySet","util/set/BitVector","util/set/BooleanArray","util/set/ObjectSet", "tests/loaders/spartan-loader-for-all-tests", "tests/loaders/class-transition-lookup-optimization-loader", "tests/loaders/switch-transition-lookup-optimization-loader", "tests/loaders/table-transition-lookup-optimization-loader","scxml/model","scxml/extra-model","scxml/scxml-dynamic-name-match-transition-selector"],(json2model,json2ExtraModel,harness,asyncForEach,ArraySet,BitVectorInitializer,BooleanArrayInitializer,ObjectSetInitializer,testTuples,classTransitionOpts,switchTransitionOpts,tableTransitionOpts,m,extraModel,defaultTransitionSelector) ->
+
@@ -161,10 +161,16 @@ define ["scxml/state-kinds-enum"],(stateKinds) ->
return [tagName,attributes,children]
+ stripStarFromEventNameRe = /^([a-zA-Z0-9.]+)(\.\*)?$/
+
transformTransitionNode = (transitionNode,parentState,genDepth,genAncestors,genDescendants,genLCA) ->
[tagName,attributes,children] = deconstructNode transitionNode,true
- if attributes?.event then uniqueEvents[attributes.event] = true #track unique events
+ #transform event attribute
+ #TODO: split up space-delimited events
+ #if attributes.event [all,attributes.event] = attributes.event.match stripStar
+
+ if attributes.event and attributes.event isnt "*" then uniqueEvents[attributes.event] = true #track unique events
transition =
documentOrder : transitions.length

0 comments on commit 465321e

Please sign in to comment.