You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by jb...@apache.org on 2010/08/17 18:45:19 UTC
svn commit: r986382 -
/commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractStatechartGenerator.xsl
Author: jbeard
Date: Tue Aug 17 16:45:19 2010
New Revision: 986382
URL: http://svn.apache.org/viewvc?rev=986382&view=rev
Log:
Intermediate commit. Removing functional methods (forEach,map,filter and some) and replacing them with for loops, which are faster.
This commit will break support for IE only.
Modified:
commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractStatechartGenerator.xsl
Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractStatechartGenerator.xsl
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractStatechartGenerator.xsl?rev=986382&r1=986381&r2=986382&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractStatechartGenerator.xsl (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/src/xslt/backends/js/AbstractStatechartGenerator.xsl Tue Aug 17 16:45:19 2010
@@ -23,11 +23,6 @@
<param name="log" select="false()"/>
<param name="genListenerHooks" select="true()"/>
- <param name="noIndexOf" select="false()"/>
- <param name="noMap" select="false()"/>
- <param name="noForEach" select="false()"/>
- <param name="noSome" select="false()"/>
- <param name="noFilter" select="false()"/>
<!-- these variables get overridden by subclasses -->
<variable name="enumeratedEventDispatchInvocation"/>
@@ -67,6 +62,37 @@
<variable name="abstractStateName" select="'AbstractState'"/>
+ <variable name="defaultIteratorVarName" select="concat(generate-id(),'_iterator')"/>
+ <variable name="defaultHoistVarName" select="concat(generate-id(),'_hoist')"/>
+
+ <template name="genForEach">
+ <param name="var"/>
+ <param name="in"/>
+ <param name="when"/>
+ <param name="do"/>
+ <param name="iteratorVarName" select="$defaultIteratorVarName"/>
+ <param name="hoistVarName" select="$defaultHoistVarName"/>
+
+ for(var <value-of select="$iteratorVarName"/>=0,
+ <value-of select="$hoistVarName"/>=<value-of select="$in"/>.length;
+ <value-of select="$iteratorVarName"/> < <value-of select="$hoistVarName"/>;
+ <value-of select="$iteratorVarName"/>++){
+ <value-of select="$var"/> = <value-of select="$in"/>[<value-of select="$iteratorVarName"/>];
+
+ <choose>
+ <when test="$when">
+ if(<value-of select="$when"/>){
+ <value-of select="$do"/>
+ }
+ </when>
+ <otherwise>
+ <value-of select="$do"/>
+ </otherwise>
+ </choose>
+ }
+
+ </template>
+
<!-- helper template to safely get a state's parent's name -->
<template name="getParentNameFromState">
<param name="s"/>
@@ -83,26 +109,6 @@
<template match="/s:scxml">
- <if test="$noIndexOf">
- <call-template name="genNoIndexOfArrayPrototypeExtension"/>
- </if>
-
- <if test="$noMap">
- <call-template name="genNoMapArrayPrototypeExtension"/>
- </if>
-
- <if test="$noForEach">
- <call-template name="genNoForEachArrayPrototypeExtension"/>
- </if>
-
- <if test="$noSome">
- <call-template name="genNoSomeArrayPrototypeExtension"/>
- </if>
-
- <if test="$noFilter">
- <call-template name="genNoFilterArrayPrototypeExtension"/>
- </if>
-
function <value-of select="@name"/>StatechartExecutionContext(){
var self = this; //used in the rare occasions we call public functions from inside this class
@@ -558,31 +564,39 @@
function microstep(e,data,isEnumeratedEvent){
if(isEnumeratedEvent){
//e does not contain a dot, so dispatch as an enumerated event
- currentConfiguration.forEach(function(state){
- if(!isPreempted){
- //we set the event as a global, rather than passing it into the function invocation as a parameter,
- //because in cases of default events, the event object will be populated with previous event's data
- if(e !== <value-of select="$defaultEventLiteral"/> ){
- _event.name=<value-of select="$eventToNameMap"/>;
- _event.data=data;
+ <call-template name="genForEach">
+ <with-param name="var" select="'state'"/>
+ <with-param name="in" select="'currentConfiguration'"/>
+ <with-param name="do">
+ if(!isPreempted){
+ //we set the event as a global, rather than passing it into the function invocation as a parameter,
+ //because in cases of default events, the event object will be populated with previous event's data
+ if(e !== <value-of select="$defaultEventLiteral"/> ){
+ _event.name=<value-of select="$eventToNameMap"/>;
+ _event.data=data;
+ }
+ <value-of select="$enumeratedEventDispatchInvocation"/>
}
- <value-of select="$enumeratedEventDispatchInvocation"/>
- }
- });
+ </with-param>
+ </call-template>
}else{
//e contains a dot, so dispatch as a prefix event
- currentConfiguration.forEach(function(state){
- if(!isPreempted){
- //we set the event as a global, rather than passing it into the function invocation as a parameter,
- //because in cases of default events, the event object will be populated with previous event's data
- //NOTE: e will always be a string here, even in enumerated techniques
- if(e !== <value-of select="$defaultEventLiteral"/> ){
- _event.name=e;
- _event.data=data;
+ <call-template name="genForEach">
+ <with-param name="var" select="'state'"/>
+ <with-param name="in" select="'currentConfiguration'"/>
+ <with-param name="do">
+ if(!isPreempted){
+ //we set the event as a global, rather than passing it into the function invocation as a parameter,
+ //because in cases of default events, the event object will be populated with previous event's data
+ //NOTE: e will always be a string here, even in enumerated techniques
+ if(e !== <value-of select="$defaultEventLiteral"/> ){
+ _event.name=e;
+ _event.data=data;
+ }
+ <value-of select="$prefixEventDispatchInvocation"/>
}
- <value-of select="$prefixEventDispatchInvocation"/>
- }
- });
+ </with-param>
+ </call-template>
}
//reset the isPreempted flag
@@ -652,15 +666,19 @@
<apply-templates select="$t/*[self::s:if or self::s:raise or self::s:log or self::s:script or self::s:send or self::s:cancel or self::s:invoke or self::s:finalize or self::s:assign or self::s:validate ]"/>
<if test="$genListenerHooks">
- listeners.forEach(function(l){
- //transition id
- <for-each select="$t/c:targets/c:target">
- l.onTransition(
- "<value-of select="../../../@id"/>",
- "<value-of select="c:targetState"/>",
- "<value-of select="@c:id"/>" );
- </for-each>
- });
+ <call-template name="genForEach">
+ <with-param name="var" select="'l'"/>
+ <with-param name="in" select="'listeners'"/>
+ <with-param name="do">
+ //transition id
+ <for-each select="$t/c:targets/c:target">
+ l.onTransition(
+ "<value-of select="../../../@id"/>",
+ "<value-of select="c:targetState"/>",
+ "<value-of select="@c:id"/>" );
+ </for-each>
+ </with-param>
+ </call-template>
</if>
@@ -689,17 +707,22 @@
var historyStateParent = <value-of select="$historyStateReference"/>.parent;
- <value-of select="$historyStateReference"/>.lastConfiguration
- .filter(function(state){
- return <value-of select="$genHistoryTriggerDispatcherInnerForEachStateReference"/>
- .ancestors.indexOf(historyStateParent)!=-1
- })
- .forEach(function(state){
+ <call-template name="genForEach">
+ <with-param name="var" select="'state'"/>
+ <with-param name="in">
+ <value-of select="$historyStateReference"/>.lastConfiguration
+ </with-param>
+ <with-param name="do">
<call-template name="genHistoryTriggerDispatcherInnerForEach">
<with-param name="isDeep" select="$isDeep"/>
<with-param name="isChildOfParallel" select="$isChildOfParallel"/>
</call-template>
- });
+ </with-param>
+ <with-param name="when">
+ <value-of select="$genHistoryTriggerDispatcherInnerForEachStateReference"/>
+ .ancestors.indexOf(historyStateParent)!=-1
+ </with-param>
+ </call-template>
<choose>
<when test="$isDeep">
@@ -771,30 +794,48 @@
var statesExited = [];
var lca = <value-of select="$t/c:lca"/>;
- <value-of select="$genNonBasicTriggerDispatcherExitBlockIteratorExpression"/>
- .filter(function(state){return state.ancestors.indexOf(lca) !== -1})
- .forEach(function(state){
- do{
- statesExited.push(state);
- }while((state = state.parent) &&
- state != lca &&
- statesExited.indexOf(state) == -1)
- });
+
+ <call-template name="genForEach">
+ <with-param name="var" select="'state'"/>
+ <with-param name="in" select="$genNonBasicTriggerDispatcherExitBlockIteratorExpression"/>
+ <with-param name="do">
+ do{
+ statesExited.push(state);
+ }while((state = state.parent) &&
+ state != lca &&
+ statesExited.indexOf(state) == -1)
+ </with-param>
+ <with-param name="when">
+ state.ancestors.indexOf(lca) !== -1
+ </with-param>
+ </call-template>
//sort by depth
statesExited.sort(sortByDepthDeepToShallow);
//execute actions for each of these states
- statesExited.forEach(function(state){
- state.exitAction();
- <if test="$genListenerHooks">
- listeners.forEach(function(l){
- //from
- l.onExit(state.toString());
- });
- </if>
- });
+ <call-template name="genForEach">
+ <with-param name="var" select="'state'"/>
+ <with-param name="in" select="'statesExited'"/>
+ <with-param name="do">
+ state.exitAction();
+
+ <if test="$genListenerHooks">
+ <call-template name="genForEach">
+ <with-param name="var" select="'listener'"/>
+ <with-param name="in" select="'listeners'"/>
+ <with-param name="do">
+ //from
+ listener.onExit(state.toString());
+ </with-param>
+ <!-- inner loop; assign these so we don't have a collision -->
+ <with-param name="iteratorVarName" select="concat(generate-id(),'_iterator')"/>
+ <with-param name="hoistVarName" select="concat(generate-id(),'_hoist')"/>
+ </call-template>
+ </if>
+ </with-param>
+ </call-template>
</template>
<template name="genTriggerDispatcherContents">
@@ -863,12 +904,14 @@
<for-each select="$t/c:exitpath/c:state">
<value-of select="."/>.exitAction();
- <if test="$genListenerHooks">
- listeners.forEach(function(l){
+ <call-template name="genForEach">
+ <with-param name="var" select="'listener'"/>
+ <with-param name="in" select="'listeners'"/>
+ <with-param name="do">
//from
- l.onExit("<value-of select="."/>");
- });
- </if>
+ listener.onExit("<value-of select="."/>");
+ </with-param>
+ </call-template>
</for-each>
</when>
<otherwise>
@@ -881,15 +924,20 @@
//transition action
<apply-templates select="$t/*[self::s:if or self::s:raise or self::s:log or self::s:script or self::s:send or self::s:cancel or self::s:invoke or self::s:finalize or self::s:assign or self::s:validate ]"/>
<if test="$genListenerHooks">
- listeners.forEach(function(l){
- //transition id
- <for-each select="$t/c:targets/c:target">
- l.onTransition(
- "<value-of select="../../../@id"/>",
- "<value-of select="c:targetState"/>",
- "<value-of select="@c:id"/>" );
- </for-each>
- });
+
+ <call-template name="genForEach">
+ <with-param name="var" select="'listener'"/>
+ <with-param name="in" select="'listeners'"/>
+ <with-param name="do">
+ //transition id
+ <for-each select="$t/c:targets/c:target">
+ listener.onTransition(
+ "<value-of select="../../../@id"/>",
+ "<value-of select="c:targetState"/>",
+ "<value-of select="@c:id"/>" );
+ </for-each>
+ </with-param>
+ </call-template>
</if>
//enter states
@@ -899,10 +947,15 @@
<value-of select="."/>.enterAction();
<if test="$genListenerHooks">
- listeners.forEach(function(l){
- //to
- l.onEntry("<value-of select="."/>");
- });
+
+ <call-template name="genForEach">
+ <with-param name="var" select="'listener'"/>
+ <with-param name="in" select="'listeners'"/>
+ <with-param name="do">
+ //to
+ listener.onEntry("<value-of select="."/>");
+ </with-param>
+ </call-template>
</if>
</for-each>
@@ -937,65 +990,6 @@
return;
</template>
- <template name="genNoForEachArrayPrototypeExtension">
- if(!Array.forEach){
- Array.prototype.forEach = function(fn){
- for(var i=0; i < this.length; i++){
- fn(this[i]);
- }
- return undefined;
- }
- }
- </template>
-
- <template name="genNoIndexOfArrayPrototypeExtension">
- if(!Array.indexOf){
- Array.prototype.indexOf = function(obj){
- for(var i=0; i < this.length; i++){
- if(this[i]==obj){
- return i;
- }
- }
- return -1;
- }
- }
- </template>
-
- <template name="genNoMapArrayPrototypeExtension">
- if(!Array.map){
- Array.prototype.map = function(fn){
- var toReturn = [];
- for(var i=0; i < this.length; i++){
- toReturn[i]=fn(this[i]);
- }
- return toReturn;
- }
- }
- </template>
-
- <template name="genNoSomeArrayPrototypeExtension">
- if(!Array.some){
- Array.prototype.some = function(fn){
- for(var i=0; i < this.length; i++){
- if(fn(this[i])) return true;
- }
- return false;
- }
- }
- </template>
-
- <template name="genNoFilterArrayPrototypeExtension">
- if(!Array.filter){
- Array.prototype.filter = function(fn){
- var toReturn = [];
- for(var i=0; i < this.length; i++){
- if(fn(this[i])) toReturn.push(this[i]);
- }
- return toReturn;
- }
- }
- </template>
-
<variable name="genInPredicateFunction">
function In(state){
state = typeof state == "string" ? self._states[state] : state;