Skip to content

Commit

Permalink
Merge pull request #19 from neilmanuell/DynamicComponentProvider
Browse files Browse the repository at this point in the history
DynamicComponentProvider
  • Loading branch information
richardlord committed Apr 22, 2013
2 parents cc94f55 + a0cb7b9 commit b0283e6
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 30 deletions.
27 changes: 27 additions & 0 deletions src/ash/fsm/DynamicComponentProvider.as
@@ -0,0 +1,27 @@
/**
* User: revisual.co.uk
* Date: 16/04/13
* Time: 22:04
*/
package ash.fsm
{
public class DynamicComponentProvider implements IComponentProvider
{
private var _closure:Function;

public function DynamicComponentProvider( closure:Function)
{
_closure = closure;
}

public function getComponent():*
{
return _closure();
}

public function get identifier():*
{
return _closure;
}
}
}
55 changes: 35 additions & 20 deletions src/ash/fsm/StateComponentMapping.as
Expand Up @@ -50,26 +50,41 @@ package ash.fsm
setProvider( new ComponentTypeProvider( type ) );
return this;
}

/**
* Creates a mapping for the component type to a single instance of the provided type.
* The instance is not created until it is first requested. The type should be the same
* as or extend the type for this mapping. A ComponentSingletonProvider is used for
* the mapping.
*
* @param The type of the single instance to be created. If omitted, the type of the
* mapping is used.
* @return This ComponentMapping, so more modifications can be applied
*/
public function withSingleton( type : Class = null ) : StateComponentMapping
{
if( !type )
{
type = componentType;
}
setProvider( new ComponentSingletonProvider( type ) );
return this;
}

/**
* Creates a mapping for the component type to a single instance of the provided type.
* The instance is not created until it is first requested. The type should be the same
* as or extend the type for this mapping. A ComponentSingletonProvider is used for
* the mapping.
*
* @param The type of the single instance to be created. If omitted, the type of the
* mapping is used.
* @return This ComponentMapping, so more modifications can be applied
*/
public function withSingleton( type : Class = null ) : StateComponentMapping
{
if( !type )
{
type = componentType;
}
setProvider( new ComponentSingletonProvider( type ) );
return this;
}


/**
* Creates a mapping for the component type to a method call. A
* DynamicComponentProvider is used for the mapping.
*
* @param method The method to return the component instance
* @return This ComponentMapping, so more modifications can be applied
*/

public function withMethod( method : Function ) : StateComponentMapping
{
setProvider( new DynamicComponentProvider( method ) );
return this;
}

/**
* Creates a mapping for the component type to any ComponentProvider.
Expand Down
4 changes: 3 additions & 1 deletion test/src/ash/AllTests.as
Expand Up @@ -9,7 +9,8 @@ package ash
import ash.fsm.ComponentInstanceProviderTests;
import ash.fsm.ComponentSingletonProviderTests;
import ash.fsm.ComponentTypeProviderTests;
import ash.fsm.EntityStateMachineTests;
import ash.fsm.DynamicComponentProviderTests;
import ash.fsm.EntityStateMachineTests;
import ash.fsm.EntityStateTests;
import ash.signals.SignalTest;
import ash.tools.ComponentPoolTest;
Expand All @@ -32,5 +33,6 @@ package ash
public var componentInstanceProviderTests : ComponentInstanceProviderTests;
public var componentTypeProviderTests : ComponentTypeProviderTests;
public var componentSingletonProviderTests : ComponentSingletonProviderTests;
public var dynamicComponentProviderTests : DynamicComponentProviderTests
}
}
60 changes: 60 additions & 0 deletions test/src/ash/fsm/DynamicComponentProviderTests.as
@@ -0,0 +1,60 @@
package ash.fsm
{
import org.hamcrest.assertThat;
import org.hamcrest.core.not;
import org.hamcrest.object.equalTo;
import org.hamcrest.object.sameInstance;

public class DynamicComponentProviderTests
{
[Test]
public function providerReturnsTheInstance():void
{
var instance:MockComponent = new MockComponent();
var providerMethod:Function = function ():*
{
return instance;
}
var provider:DynamicComponentProvider = new DynamicComponentProvider( providerMethod );
assertThat( provider.getComponent(), sameInstance( instance ) );
}

[Test]
public function providersWithSameMethodHaveSameIdentifier():void
{
var instance:MockComponent = new MockComponent();
var providerMethod:Function = function ():*
{
return instance;
}

var provider1:DynamicComponentProvider = new DynamicComponentProvider( providerMethod );
var provider2:DynamicComponentProvider = new DynamicComponentProvider( providerMethod );
assertThat( provider1.identifier, equalTo( provider2.identifier ) );
}

[Test]
public function providersWithDifferentMethodsHaveDifferentIdentifier():void
{
var instance:MockComponent = new MockComponent();
var providerMethod1:Function = function ():*
{
return instance;
}

var providerMethod2:Function = function ():*
{
return instance;
}

var provider1:ComponentInstanceProvider = new ComponentInstanceProvider( providerMethod1 );
var provider2:ComponentInstanceProvider = new ComponentInstanceProvider( providerMethod2 );
assertThat( provider1.identifier, not( provider2.identifier ) );
}
}
}

class MockComponent
{
public var value:int;
}
31 changes: 22 additions & 9 deletions test/src/ash/fsm/EntityStateTests.as
Expand Up @@ -47,15 +47,28 @@ package ash.fsm
assertThat( provider, instanceOf( ComponentInstanceProvider ) );
assertThat( provider.getComponent(), equalTo( component ) );
}

[Test]
public function addWithSingletonQualifierCreatesSingletonProvider() : void
{
state.add( MockComponent ).withSingleton( MockComponent );
var provider : IComponentProvider = state.providers[MockComponent];
assertThat( provider, instanceOf( ComponentSingletonProvider ) );
assertThat( provider.getComponent(), instanceOf( MockComponent ) );
}

[Test]
public function addWithSingletonQualifierCreatesSingletonProvider() : void
{
state.add( MockComponent ).withSingleton( MockComponent );
var provider : IComponentProvider = state.providers[MockComponent];
assertThat( provider, instanceOf( ComponentSingletonProvider ) );
assertThat( provider.getComponent(), instanceOf( MockComponent ) );
}

[Test]
public function addWithMethodQualifierCreatesDynamicProvider() : void
{
const dynamicProvider:Function = function():*
{
return new MockComponent();
}
state.add( MockComponent ).withMethod( dynamicProvider );
var provider : IComponentProvider = state.providers[MockComponent];
assertThat( provider, instanceOf( DynamicComponentProvider ) );
assertThat( provider.getComponent(), instanceOf( MockComponent ) );
}
}
}

Expand Down

0 comments on commit b0283e6

Please sign in to comment.