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/06/12 21:34:24 UTC
svn commit: r954053 -
/commons/sandbox/gsoc/2010/scxml-js/trunk/test/xslt/AbstractStatechartGenerator.xsl
Author: jbeard
Date: Sat Jun 12 19:34:24 2010
New Revision: 954053
URL: http://svn.apache.org/viewvc?rev=954053&view=rev
Log:
Intermediate commit. AbstractStatechartGenerator.xsl might be close to being hooked up.
Modified:
commons/sandbox/gsoc/2010/scxml-js/trunk/test/xslt/AbstractStatechartGenerator.xsl
Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/test/xslt/AbstractStatechartGenerator.xsl
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/test/xslt/AbstractStatechartGenerator.xsl?rev=954053&r1=954052&r2=954053&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/test/xslt/AbstractStatechartGenerator.xsl (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/test/xslt/AbstractStatechartGenerator.xsl Sat Jun 12 19:34:24 2010
@@ -1,6 +1,7 @@
<?xml version="1.0"?>
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:s="http://www.w3.org/2005/07/scxml"
+ xmlns:c="https://svn.apache.org/repos/asf/commons/sandbox/gsoc/2010/scxml-js/trunk/"
version="1.0">
<output method="text"/>
@@ -9,6 +10,27 @@
<param name="noMap" select="true()"/>
<param name="name"/>
+ <!-- these params get overridden by subclasses -->
+ <param name="dispatchInvocation"/>
+ <param name="currentConfigurationExpression"/>
+ <param name="defaultEventLiteral"/>
+
+ <!--//*[(self::state or self::parallel or self::final or self::initial or self::scxml or self::history) and not(.//*[(self::state or self::parallel or self::final or self::initial or self::scxml or self::history)])]-->
+ <!--TODO: hook up namespaces -->
+ <variable name="allStates" select="//*[(self::state or self::parallel or self::final or self::initial or self::scxml or self::history)]"/>
+ <variable name="states" select="//s:state"/>
+ <variable name="parallels" select="//s:parallel"/>
+ <variable name="finals" select="//s:final"/>
+ <variable name="initials" select="//s:initial"/>
+ <variable name="transitions" select="//s:transition"/>
+ <variable name="defaultTransitions" select="//s:transition[not(@event)]"/>
+ <variable name="nonDefaultTransitions" select="//s:transition[@event]"/>
+
+ <variable name="basicStates" select="$allStates[not(.//*[(self::state or self::parallel or self::final or self::initial or self::scxml or self::history)])]"/>
+ <variable name="compositeStates" select="$allStates[.//*[(self::state or self::parallel or self::final or self::initial or self::scxml or self::history)]]"/>
+ <variable name="parallelRegions" select="$parallels/s:state"/>
+
+
<template match="/s:scxml">
<if test="$noIndexOf">
@@ -30,34 +52,40 @@
</call-template>
//states
- <for-each select=".//s:state | .//s:initial | .//s:parallel ">
+ <for-each select="$allStates">
<call-template name="genState">
<with-param name="state" select="."/>
</call-template>
</for-each>
- <!--
//states enum for glass-box unit testing
- {self.genStatesEnum(conf.basicStates)}
+ <for-each select="$basicStates">
+ <call-template name="genStatesEnum">
+ <with-param name="state" select="."/>
+ </call-template>
+ </for-each>
//trigger methods for synchronous interaction
- {util.foreach(conf.nonDefaultTransitions,self.genExternalTriggerDispatcher)}
+ <for-each select="$nonDefaultTransitions">
+ <call-template name="genExternalTriggerDispatcher">
+ <with-param name="t" select="."/>
+ </call-template>
+ </for-each>
- {self.genContextHooks()}
+ <call-template name="genContextHooks"/>
//initialization script
- {conf.scxml.script.toString()}
+ <value-of select="script"/>
//initialization method
- {self.genInitialization()}
+ <call-template name="genInitialization"/>
//internal runtime functions
- {self.genInternalRuntimeFunctions()}
+ <call-template name="genInternalRuntimeFunctions"/>
//start static boilerplate code
- {self.genBoilerplateDispatchCode(conf.dispatchInvocation)}
- -->
+ <call-template name="genBoilerplateDispatchCode"/>
}
@@ -84,6 +112,7 @@
<variable name="parentName">
<choose>
+ <!-- FIXME: probably want to refine this query, as we may not be able to assume that all states have ids?-->
<when test="$state/../@id">
<value-of select="$state/../@id"/>
</when>
@@ -112,8 +141,8 @@
this.initial = null;
- <!--FIXME-->
- this.depth = {self.computeDepth(state)};
+ <!--FIXME: we add depth attribute to state-->
+ this.depth = <value-of select="$state/@c:depth"/>;
this.historyState = null;
@@ -150,17 +179,17 @@
this.historyState.lastConfiguration = currentConfiguration.slice();
</if>
+ }
+ }
<for-each select="$state/onexit/*">
- <call-template name="genExecutableContent">
- <with-param name="executableNode" select="."/>
- </call-template>
+ <apply-templates select="s:if | s:raise | s:log | s:script | s:send | s:cancel | s:invoke | s:finalize | s:datamodel | s:data | s:assign | s:validate | s:param"/>
</for-each>
}
<call-template name="genStateHooks">
- <with-param name="state" select="."/>
+ <with-param name="state" select="$state"/>
</call-template>
@@ -171,10 +200,113 @@
</template>
- <template name="genExecutableContent">
- <param name="executableNode"/>
- //executable content goes here
+ <template name="genStatesEnum">
+ <param name="states"/>
+
+ this._states = {
+ <for-each select="$states">
+ <value-of select="@id"/> : <value-of select="@id"/>
+ <if test="not(position() = last())">,</if>
+ </for-each>
+ }
+ </template>
+
+ <!-- executable content section-->
+
+ <!-- base profile -->
+
+ <!-- TODO: transform DOM to this intermediate format -->
+ <!--
+ <s:if cond="">
+ <c:executableContent>
+ ...
+ </c:executableContent>
+ <s:elseif cond="">
+ <c:executableContent>
+ ...
+ </c:executableContent>
+ </s:elseif>
+ ...
+ <s:else>
+ <c:executableContent>
+ ...
+ </c:executableContent>
+ </s:else>
+ </s:if>
+ -->
+ <template match="s:if">
+ if (<value-of select="@cond"/>) {
+ <apply-templates select="c:executableContent/*"> <!--TODO:some filtering here?-->
+ }
+ <apply-templates select="s:elseif"/>
+ <apply-templates select="s:else"/>
+ </template>
+
+ <template match="s:elseif">
+ else if (<value-of select="@cond"/>) {
+ <apply-templates select="c:executableContent/*"> <!--TODO:some filtering here?-->
+ }
+ </template>
+
+ <template match="s:else">
+ else {
+ <apply-templates select="c:executableContent/*"> <!--TODO:some filtering here?-->
+ }
+ </template>
+
+ <template match="s:log">
+ console.log(' <value-of select="@label"/> : ' + <value-of select="@expr"/> );
+ </template>
+
+ <template match="s:raise">
+ <!--TODO-->
+ </template>
+
+ <!-- script module -->
+
+ <template match="s:script">
+ <value-of select="."/>
+ </template>
+
+ <!-- external communications module -->
+
+ <template match="s:send">
+ <!--TODO-->
+ </template>
+
+ <template match="s:cancel">
+ <!--TODO-->
+ </template>
+
+ <template match="s:invoke">
+ <!--TODO-->
+ </template>
+
+ <template match="s:finalize">
+ <!--TODO-->
+ </template>
+
+ <!-- data module -->
+
+ <template match="s:datamodel">
+ <!--TODO-->
+ </template>
+
+ <template match="s:data">
+ <!--TODO-->
+ </template>
+
+ <template match="s:assign">
+ <!--TODO-->
+ </template>
+
+ <template match="s:validate">
+ <!--TODO-->
+ </template>
+
+ <template match="s:param">
+ <!--TODO-->
</template>
<template name="genStateHooks">
@@ -209,5 +341,116 @@
}
</template>
+
+ <!-- abstract templates that we expect to be refined in subclasses -->
+
+ <template name="genInternalRuntimeFunctions">
+ function sortByDepthDeepToShallow(a,b){
+ return b.depth - a.depth;
+ }
+ </template>
+
+
+ <template name="genBoilerplateDispatchCode">
+ //static private member variables
+ var currentConfiguration = []; //current configuration
+ var innerEventQueue = []; //inner event queue
+ var outerEventQueue = []; //outer event queue
+ var isInStableState = true;
+ var isPreempted = false;
+ var hasTakenDefaultTransition = false;
+ var destroyed = false;
+ var mainLoopCallback = null;
+
+ //static private member functions
+ function mainLoop() {
+
+ if(!destroyed){
+ //take an event from the current outer event queue
+ if (outerEventQueue.length && isInStableState) {
+ runToCompletion(outerEventQueue.shift());
+ }
+ //call back
+ mainLoopCallback = window.setTimeout(function() {
+ mainLoop(); //FIXME: note that when calling mainloop this way, we won't have access to the "this" object.
+ //I don't think we ever use it though. Everything we need is private in function scope.
+ },
+ 100);
+ }
+ }
+
+ function runToCompletion(e){
+ isInStableState = false;
+
+ if(e){
+ innerEventQueue.push(e);
+ }
+
+ do{
+ //take any available default transitions
+ microstep(<value-of name="defaultEventLiteral"/>});
+
+ if(!hasTakenDefaultTransition){
+
+ if(!innerEventQueue.length){
+ //we have no more generated events, and no default transitions fired, so
+ //we are done, and have run to completion
+ break;
+ }else{
+ //microstep, then dequeue next event sending in event
+ microstep(innerEventQueue.shift());
+ }
+ }else{
+ //he has taken a default transition, so reset the global variable to false and loop again
+ hasTakenDefaultTransition = false;
+ }
+
+ }while(true)
+
+ isInStableState = true;
+ }
+
+ function microstep(e){
+ currentConfiguration.forEach(function(state){
+ if(!isPreempted)
+ <value-of select="$dispatchInvocation"/>
+ });
+
+ //reset the isPreempted flag
+ isPreempted = false;
+ }
+
+
+ this.destroy = function(){
+ //right now, this only disables timer and sets global destroyed variable to prevent future callbacks
+ window.clearTimeout(mainLoopCallback);
+ mainLoopCallback = null;
+ destroyed = true;
+ }
+
+
+ //this is for async communication
+ this.GEN = function(e){
+ outerEventQueue.push(e);
+ }
+
+ //this may or may not be something we want to expose, but for right now, we at least need it for testing
+ this.getCurrentConfiguration = function(){
+ //slice it to return a copy of the configuration rather than the conf itself
+ //this saves us all kinds of confusion involving references and stuff
+ return <value-of select="$currentConfigurationExpression"/>;
+ }
+
+ //end static boilerplate code
+ </template>
+
+ <template name="genContextHooks"/>
+ <template name="genStateHooks"/>
+ <template name="genExternalTriggerDispatcher"/>
+ <template name="genParallelSubstateConfigurationSetString"/>
+ <template name="genNonParallelSubstateConfigurationSetString"/>
+ <template name="genInitialization"/>
+ <template name="genTriggerDispatcherContext"/>
+
</stylesheet>