Skip to content

Commit

Permalink
states dsl with flow for static compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
FrancisBourre committed Oct 5, 2017
1 parent 43185fc commit 8f7e033
Show file tree
Hide file tree
Showing 6 changed files with 340 additions and 8 deletions.
22 changes: 21 additions & 1 deletion src/hex/compiler/core/StaticCompileTimeContextFactory.hx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import hex.core.IApplicationContext;
import hex.core.ICoreFactory;
import hex.core.SymbolTable;
import hex.vo.ConstructorVO;
import hex.ioc.vo.TransitionVO;

/**
* ...
Expand Down Expand Up @@ -55,6 +56,25 @@ class StaticCompileTimeContextFactory
this._coreFactory.addListener( this );
}
}

override public function buildStateTransition( key : String ) : Array<TransitionVO>
{
var transitions : Array<TransitionVO> = null;

if ( this._stateTransitionVOLocator.isRegisteredWithKey( key ) )
{
var stateTransitionVO = this._stateTransitionVOLocator.locate( key );

hex.compiletime.util.ContextBuilder.getInstance( this )
.addField( key, ContextFactoryUtil.getComplexType( 'hex.state.State', stateTransitionVO.filePosition ), stateTransitionVO.filePosition );

stateTransitionVO.expressions = this._expressions;
transitions = hex.compiler.factory.StaticStateTransitionFactory.build( stateTransitionVO, this );
this._stateTransitionVOLocator.unregister( key );
}

return transitions;
}

override public function buildVO( constructorVO : ConstructorVO, ?id : String ) : Dynamic
{
Expand Down Expand Up @@ -103,7 +123,7 @@ class StaticCompileTimeContextFactory

if ( !constructorVO.lazy )
{
this._expressions.push( macro @:mergeBlock { $finalResult; /*coreFactory.register( $v { id }, $i { id } );*/ this.$id = $i { id }; } );
this._expressions.push( macro @:mergeBlock { $finalResult; coreFactory.register( $v { id }, $i { id } ); this.$id = $i { id }; } );
}

this._coreFactory.register( id, result );
Expand Down
2 changes: 1 addition & 1 deletion src/hex/compiler/factory/StateTransitionFactory.hx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class StateTransitionFactory
var ref = refs.shift();
var methodName = refs.shift();

var methodCall = macro function ( s : State )
var methodCall = macro function ( s : hex.state.State )
{
coreFactory.locate( $v{ref} ).$methodName( s );
}
Expand Down
164 changes: 164 additions & 0 deletions src/hex/compiler/factory/StaticStateTransitionFactory.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package hex.compiler.factory;

import haxe.macro.Context;
import haxe.macro.Expr;
import hex.compiletime.basic.IContextFactory;
import hex.control.command.CommandMapping;
import hex.ioc.di.ContextOwnerWrapper;
import hex.ioc.vo.CommandMappingVO;
import hex.ioc.vo.StateTransitionVO;
import hex.ioc.vo.TransitionVO;
import hex.state.State;
import hex.state.StateUnmapper;
import hex.util.MacroUtil;

/**
* ...
* @author Francis Bourre
*/
class StaticStateTransitionFactory
{
function new(){}

#if macro
static public function build( vo : StateTransitionVO, contextFactory : IContextFactory ) : Array<TransitionVO>
{
var stateExp : Expr = null;
if ( vo.staticReference != null )
{
stateExp = MacroUtil.getStaticVariable( vo.staticReference, vo.filePosition );
}
else if ( vo.instanceReference != null )
{
stateExp = macro coreFactory.locate( $v{ vo.instanceReference } );
}
else
{
var StateClass = MacroUtil.getTypePath( Type.getClassName( State ) );
stateExp = macro new $StateClass( $v{ vo.ID } );
}

var stateVarName = vo.ID;
vo.expressions.push( macro @:mergeBlock { var $stateVarName = $stateExp; coreFactory.register( $v { stateVarName }, $i{stateVarName} ); this.$stateVarName = $i { stateVarName }; } );

var StateUnmapperClass = MacroUtil.getPack( Type.getClassName( StateUnmapper ) );
var ContextOwnerWrapperClass = MacroUtil.getTypePath( Type.getClassName( ContextOwnerWrapper ) );
var CommandMappingClass = MacroUtil.getTypePath( Type.getClassName( CommandMapping ) );

vo.expressions.push( macro @:pos( vo.filePosition ) @:mergeBlock { var stateUnmapper = $p { StateUnmapperClass } .register( $i{stateVarName} ); } );

var enterList : Array<CommandMappingVO> = vo.enterList;
for ( enterVO in enterList )
{
if ( enterVO.methodRef != null )
{
if ( enterVO.fireOnce )
{
Context.error( "transition's method callback cannot be fired once", enterVO.filePosition );
}

var refs = enterVO.methodRef.split(".");
var ref = refs.shift();
var methodName = refs.shift();

var methodCall = macro function ( s : hex.state.State )
{
coreFactory.locate( $v{ref} ).$methodName( s );
}
vo.expressions.push( macro @:mergeBlock { $i{stateVarName}.addEnterHandler( $methodCall ); } );
}
else
{
var enterCommandClassName = MacroUtil.getPack( enterVO.commandClassName );
vo.expressions.push( macro @:pos( enterVO.filePosition ) @:mergeBlock { var enterMapping = new $CommandMappingClass( $p { enterCommandClassName } ); } );

if ( enterVO.contextOwner != null )
{
vo.expressions.push( macro @:pos( enterVO.filePosition ) @:mergeBlock { enterMapping.setContextOwner( new $ContextOwnerWrapperClass( coreFactory, $v{ enterVO.contextOwner } ) ); } );
}
else
{
vo.expressions.push( macro @:pos( enterVO.filePosition ) @:mergeBlock { enterMapping.setContextOwner( applicationContext ); } );
}

if ( enterVO.fireOnce )
{
vo.expressions.push( macro @:pos( enterVO.filePosition ) @:mergeBlock { enterMapping.once(); } );
}

vo.expressions.push( macro @:mergeBlock { $i{stateVarName}.addEnterCommandMapping( enterMapping ); } );
vo.expressions.push( macro @:mergeBlock { stateUnmapper.addEnterMapping( enterMapping ); } );
}
}

var exitList : Array<CommandMappingVO> = vo.exitList;
for ( exitVO in exitList )
{
if ( exitVO.methodRef != null )
{
if ( exitVO.fireOnce )
{
Context.error( "transition's method callback cannot be fired once", exitVO.filePosition );
}

var refs = exitVO.methodRef.split(".");
var ref = refs.shift();
var methodName = refs.shift();

var methodCall = macro function ( s : State )
{
coreFactory.locate( $v{ref} ).$methodName( s );
}
vo.expressions.push( macro @:mergeBlock { $i{stateVarName}.addExitHandler( $methodCall ); } );
}
else
{
var exitCommandClassName = MacroUtil.getPack( exitVO.commandClassName );
vo.expressions.push( macro @:pos( exitVO.filePosition ) @:mergeBlock { var exitMapping = new $CommandMappingClass( $p { exitCommandClassName } ); } );

if ( exitVO.contextOwner != null )
{
vo.expressions.push( macro @:pos( exitVO.filePosition ) @:mergeBlock { exitMapping.setContextOwner( new $ContextOwnerWrapperClass( coreFactory, $v{ exitVO.contextOwner } ) ); } );
}
else
{
vo.expressions.push( macro @:pos( exitVO.filePosition ) @:mergeBlock { exitMapping.setContextOwner( applicationContext ); } );
}

if ( exitVO.fireOnce )
{
vo.expressions.push( macro @:pos( exitVO.filePosition ) @:mergeBlock { exitMapping.once(); } );
}

vo.expressions.push( macro @:mergeBlock { $i{stateVarName}.addExitCommandMapping( exitMapping ); } );
vo.expressions.push( macro @:mergeBlock { stateUnmapper.addExitMapping( exitMapping ); } );
}
}

var transitions : Array<TransitionVO> = vo.transitionList;
for ( transition in transitions )
{
transition.stateVarName = stateVarName;
}

return transitions;
}

static public function flush( expressions : Array<Expr>, transitions: Array<TransitionVO> ) : Void
{
for ( transition in transitions )
{
var stateVarName = transition.stateVarName;

expressions.push( macro @:mergeBlock
{
$i{stateVarName}.addTransition
(
$i{transition.messageReference},
$i{transition.stateReference}
);
} );
}
}
#end
}
1 change: 1 addition & 0 deletions src/hex/compiler/parser/flow/StaticFlowCompiler.hx
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ class StaticParserCollection extends AbstractParserCollection<AbstractExprParser
this._parserCollection.push( new StaticContextParser( this._assemblerExpression ) );
this._parserCollection.push( new RuntimeParameterParser( this._runtimeParam ) );
this._parserCollection.push( new ImportContextParser( hex.compiletime.flow.parser.FlowExpressionParser.parser ) );
this._parserCollection.push( new StateParser( hex.compiletime.flow.parser.FlowExpressionParser.parser ) );//
this._parserCollection.push( new hex.compiler.parser.flow.ObjectParser( hex.compiletime.flow.parser.FlowExpressionParser.parser, this._runtimeParam ) );
this._parserCollection.push( new StaticLauncher( this._assemblerExpression, this._fileName, this._runtimeParam ) );
}
Expand Down
12 changes: 6 additions & 6 deletions test/context/flow/testBuildingStateTransitions.flow
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
@context( name = 'applicationContext' )
{
assemblingStart =
state( ref( applicationContext.state.ASSEMBLING_START ) )
state( ref( this.state.ASSEMBLING_START ) )
.enter( hex.ioc.parser.xml.assembler.mock.MockStateCommand )
.exit( hex.ioc.parser.xml.assembler.mock.MockStateCommand );

objectsBuilt =
state( ref( applicationContext.state.OBJECTS_BUILT ) )
state( ref( this.state.OBJECTS_BUILT ) )
.enter( hex.ioc.parser.xml.assembler.mock.MockStateCommand )
.exit( hex.ioc.parser.xml.assembler.mock.MockStateCommand );

domainListenersAssigned =
state( ref( applicationContext.state.DOMAIN_LISTENERS_ASSIGNED ) )
state( ref( this.state.DOMAIN_LISTENERS_ASSIGNED ) )
.enter( hex.ioc.parser.xml.assembler.mock.MockStateCommand )
.exit( hex.ioc.parser.xml.assembler.mock.MockStateCommand );

methodsCalled =
state( ref( applicationContext.state.METHODS_CALLED ) )
state( ref( this.state.METHODS_CALLED ) )
.enter( hex.ioc.parser.xml.assembler.mock.MockStateCommand )
.exit( hex.ioc.parser.xml.assembler.mock.MockStateCommand );

modulesInitialized =
state( ref( applicationContext.state.MODULES_INITIALIZED ) )
state( ref( this.state.MODULES_INITIALIZED ) )
.enter( hex.ioc.parser.xml.assembler.mock.MockStateCommand )
.exit( hex.ioc.parser.xml.assembler.mock.MockStateCommand );

assemblingEnd =
state( ref( applicationContext.state.ASSEMBLING_END ) )
state( ref( this.state.ASSEMBLING_END ) )
.enter( hex.ioc.parser.xml.assembler.mock.MockStateCommand )
.exit( hex.ioc.parser.xml.assembler.mock.MockStateCommand );
}
Loading

0 comments on commit 8f7e033

Please sign in to comment.