Revision: 430 http://skycastle.svn.sourceforge.net/skycastle/?rev=430&view=rev Author: zzorn Date: 2008-04-02 20:54:46 -0700 (Wed, 02 Apr 2008) Log Message: ----------- Now both immediate and long duration actions work with the UnitTestingGameContext. Modified Paths: -------------- trunk/skycastle/modules/client/src/test/java/org/skycastle/client/model/clientside/ClientSideGameModelTest.java trunk/skycastle/modules/core/src/main/java/org/skycastle/core/ClientContext.java trunk/skycastle/modules/core/src/main/java/org/skycastle/core/DefaultGameObject.java trunk/skycastle/modules/core/src/main/java/org/skycastle/core/GameContext.java trunk/skycastle/modules/core/src/main/java/org/skycastle/core/GameObjectContext.java trunk/skycastle/modules/core/src/main/java/org/skycastle/core/MessagingFacadeImpl.java trunk/skycastle/modules/core/src/main/java/org/skycastle/core/ServerSideContext.java trunk/skycastle/modules/core/src/main/java/org/skycastle/core/UnitTestingContext.java trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/Act.java trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/ActEvent.java trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/ActionFacadeImpl.java trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/ActionImpl.java trunk/skycastle/modules/core/src/main/java/org/skycastle/core/property/PropertyFacade.java trunk/skycastle/modules/core/src/main/java/org/skycastle/core/property/PropertyFacadeImpl.java trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/ModificationMessage.java trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/RemovePropertyMessage.java trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/property/AddPropertyMessage.java trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/property/SetPropertyMessage.java trunk/skycastle/modules/core/src/test/java/org/skycastle/core/AbstractGameObjectActionsTest.java trunk/skycastle/modules/core/src/test/java/org/skycastle/core/AbstractGameObjectPropertiesTest.java trunk/skycastle/modules/core/src/test/java/org/skycastle/core/geometry/space/grid/GridTest.java trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/parameters/ParameterValidationException.java Removed Paths: ------------- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/AbstractGameObject.java trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/InvocationType.java Modified: trunk/skycastle/modules/client/src/test/java/org/skycastle/client/model/clientside/ClientSideGameModelTest.java =================================================================== --- trunk/skycastle/modules/client/src/test/java/org/skycastle/client/model/clientside/ClientSideGameModelTest.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/client/src/test/java/org/skycastle/client/model/clientside/ClientSideGameModelTest.java 2008-04-03 03:54:46 UTC (rev 430) @@ -4,7 +4,9 @@ import org.skycastle.connection.ClientConnectionHandler; import org.skycastle.connection.ConnectionHandler; import org.skycastle.connection.PassThroughConnectionHandlers; +import org.skycastle.core.GameContext; import org.skycastle.core.GameObjectId; +import org.skycastle.core.UnitTestingContext; import org.skycastle.messaging.updates.object.GameObjectAddedMessage; import org.skycastle.messaging.updates.object.GameObjectRemovedMessage; @@ -61,6 +63,8 @@ protected void setUp() throws Exception { + GameContext.setGameObjectContext( new UnitTestingContext() ); + final PassThroughConnectionHandlers connectionHandlers = new PassThroughConnectionHandlers(); myClientHandler = connectionHandlers.getClientSideConnectionHandler(); myServerHandler = connectionHandlers.getServerSideConnectionHandler(); Deleted: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/AbstractGameObject.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/AbstractGameObject.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/AbstractGameObject.java 2008-04-03 03:54:46 UTC (rev 430) @@ -1,287 +0,0 @@ -package org.skycastle.core; - -import org.skycastle.core.acting.Action; -import org.skycastle.core.acting.ActionFacade; -import org.skycastle.core.acting.ActionFacadeImpl; -import org.skycastle.core.property.PropertyFacade; -import org.skycastle.core.property.PropertyFacadeImpl; -import org.skycastle.messaging.Message; -import org.skycastle.messaging.MessageListener; -import org.skycastle.messaging.modifications.action.InvokeActionMessage; -import org.skycastle.messaging.updates.UpdateMessage; -import org.skycastle.util.ParameterChecker; -import org.skycastle.util.parameters.ParameterMetadata; -import org.skycastle.util.parameters.ValidationError; -import org.skycastle.util.parameters.validators.ParameterValidator; - -import java.io.Serializable; -import java.util.Set; - -/** - * Common functionality for all/most implementations of GameObject. - */ -// IDEA: Create some kind of GameObject specific debug stream listening system? -// An admin readable mostRecentError field? - -// It would make sense to make the action invocation validity checks twice, once before queying, and once before executing, at least for direct requests.. -// Or alternatively clear the action queue whenever access privilegies are changed? Or re-screen it? -// Or just re-check action access privilegies before invocation? -public abstract class AbstractGameObject - implements GameObject -{ - - //====================================================================== - // Private Fields - - private final GameObjectContext myGameObjectContext; - - private final PropertyFacade myPropertyFacade; - private final ActionFacadeImpl myActionFacade; - private final MessagingFacade myMessagingFacade; - - private GameObjectId myId; - - //====================================================================== - // Public Methods - - //---------------------------------------------------------------------- - // ActionFacade Implementation - - public void startAction( final InvokeActionMessage invokeActionMessage ) - { - myActionFacade.startAction( invokeActionMessage ); - } - - - public long startAction( final GameObjectId callerId, final String actionIdentifier ) - { - return myActionFacade.startAction( callerId, actionIdentifier ); - } - - - public long startAction( final GameObjectId callerId, final String actionIdentifier, final Object... parameters ) - { - return myActionFacade.startAction( callerId, actionIdentifier, parameters ); - } - - - public void stopAction( final String actionIdentifier, final long actId ) - { - myActionFacade.stopAction( actionIdentifier, actId ); - } - - - public ActionMetadata getActionMetadata( final String actionIdentifier ) - { - return myActionFacade.getActionMetadata( actionIdentifier ); - } - - - public void addAction( final Action action ) - { - myActionFacade.addAction( action ); - } - - - public void removeAction( final String actionIdentifier ) - { - myActionFacade.removeAction( actionIdentifier ); - } - - - public boolean hasAction( final String actionIdentifier ) - { - return myActionFacade.hasAction( actionIdentifier ); - } - - - public Set<String> getActionIdentifiers() - { - return myActionFacade.getActionIdentifiers(); - } - - //---------------------------------------------------------------------- - // GameObject Implementation - - public final GameObjectId getId() - { - // Lazy init - if ( myId == null ) - { - myId = myGameObjectContext.createGameObjectId( this ); - } - - return myId; - } - - //---------------------------------------------------------------------- - // MessageListener Implementation - - public final void onMessage( final Message message ) - { - myMessagingFacade.onMessage( message ); - } - - //---------------------------------------------------------------------- - // MessagingFacade Implementation - - public void addIndirectUpdateListener( final UpdateListenerFilter filter, final GameObjectId observerId ) - { - myMessagingFacade.addIndirectUpdateListener( filter, observerId ); - } - - - public void removeIndirectUpdateListener( final UpdateListenerFilter filter, - final GameObjectId observerId ) - { - myMessagingFacade.removeIndirectUpdateListener( filter, observerId ); - } - - - public void addDirectUpdateListener( final UpdateListenerFilter filter, final MessageListener listener ) - { - myMessagingFacade.addDirectUpdateListener( filter, listener ); - } - - - public void removeDirectUpdateListener( final UpdateListenerFilter filter, - final MessageListener messageListener ) - { - myMessagingFacade.removeDirectUpdateListener( filter, messageListener ); - } - - - public void sendUpdateToObservers( final UpdateMessage updateMessage ) - { - myMessagingFacade.sendUpdateToObservers( updateMessage ); - } - - //---------------------------------------------------------------------- - // PropertyFacade Implementation - - public <T> T getPropertyValue( final String propertyIdentifier, final T defaultValue ) - { - return myPropertyFacade.getPropertyValue( propertyIdentifier, defaultValue ); - } - - - public ValidationError setPropertyValue( final String propertyIdentifier, final Serializable value ) - { - return myPropertyFacade.setPropertyValue( propertyIdentifier, value ); - } - - - public boolean hasProperty( final String propertyIdentifier ) - { - return myPropertyFacade.hasProperty( propertyIdentifier ); - } - - - public Set<String> getPropertyIdentifiers() - { - return myPropertyFacade.getPropertyIdentifiers(); - } - - - public ParameterMetadata getPropertyMetadata( final String propertyIdentifier ) - { - return myPropertyFacade.getPropertyMetadata( propertyIdentifier ); - } - - - public ValidationError addProperty( final String propertyIdentifier, final Serializable initialValue ) - { - return myPropertyFacade.addProperty( propertyIdentifier, initialValue ); - } - - - public ValidationError addProperty( final String propertyIdentifier, - final Serializable initialValue, - final String description, final ParameterValidator... validators ) - { - return myPropertyFacade.addProperty( propertyIdentifier, initialValue, description, validators ); - } - - - public <T extends Serializable> ValidationError addProperty( final String propertyIdentifier, - final T initialValue, - final Class<T> type, - final String description, - final ParameterValidator... validators ) - { - return myPropertyFacade.addProperty( propertyIdentifier, - initialValue, - type, - description, - validators ); - } - - - public ValidationError addProperty( final String propertyIdentifier, - final Serializable initialValue, - final ParameterMetadata propertyMetadata ) - { - return myPropertyFacade.addProperty( propertyIdentifier, initialValue, propertyMetadata ); - } - - - public ValidationError removeProperty( final String propertyIdentifier ) - { - return myPropertyFacade.removeProperty( propertyIdentifier ); - } - - //---------------------------------------------------------------------- - // Task Implementation - - public void run() throws Exception - { - myActionFacade.runScheduledActs( myGameObjectContext.getCurrentGameTime_ms() ); - } - - //---------------------------------------------------------------------- - // Other Public Methods - - /** - * @return an interface that provides property related operations for this {@link GameObject}. - */ - public final PropertyFacade getPropertyFacade() - { - return myPropertyFacade; - } - - - /** - * @return an interface that provides action related operations for this {@link GameObject}. - */ - public final ActionFacade getActionFacade() - { - return myActionFacade; - } - - - /** - * @return an interface that provides messaging related operations for this {@link GameObject}. - */ - public final MessagingFacade getMessagingFacade() - { - return myMessagingFacade; - } - - //====================================================================== - // Protected Methods - - //---------------------------------------------------------------------- - // Protected Constructors - - protected AbstractGameObject( final GameObjectContext gameObjectContext ) - { - ParameterChecker.checkNotNull( gameObjectContext, "gameObjectContext" ); - - myGameObjectContext = gameObjectContext; - - myPropertyFacade = new PropertyFacadeImpl( this, myGameObjectContext ); - myActionFacade = new ActionFacadeImpl( this, myGameObjectContext ); - myMessagingFacade = new MessagingFacadeImpl( this, myGameObjectContext ); - } - -} Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/ClientContext.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/ClientContext.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/ClientContext.java 2008-04-03 03:54:46 UTC (rev 430) @@ -1,6 +1,5 @@ package org.skycastle.core; -import org.skycastle.core.acting.InvocationType; import org.skycastle.core.clientside.GameModel; import org.skycastle.util.ParameterChecker; @@ -52,12 +51,6 @@ } - public InvocationType getActionInvocationType() - { - return InvocationType.LATER_IN_SWING_THREAD; - } - - public GameObject getGameObjectById( final GameObjectId gameObjectId, final boolean forModification ) { return myGameModel.getGameObject( gameObjectId ); Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/DefaultGameObject.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/DefaultGameObject.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/DefaultGameObject.java 2008-04-03 03:54:46 UTC (rev 430) @@ -11,7 +11,7 @@ import org.skycastle.messaging.updates.UpdateMessage; import org.skycastle.util.ParameterChecker; import org.skycastle.util.parameters.ParameterMetadata; -import org.skycastle.util.parameters.ValidationError; +import org.skycastle.util.parameters.ParameterValidationException; import org.skycastle.util.parameters.validators.ParameterValidator; import java.io.Serializable; @@ -168,9 +168,10 @@ } - public ValidationError setPropertyValue( final String propertyIdentifier, final Serializable value ) + public void setPropertyValue( final String propertyIdentifier, final Serializable value ) + throws ParameterValidationException { - return myPropertyFacade.setPropertyValue( propertyIdentifier, value ); + myPropertyFacade.setPropertyValue( propertyIdentifier, value ); } @@ -192,50 +193,51 @@ } - public ValidationError addProperty( final String propertyIdentifier, final Serializable initialValue ) + public void addProperty( final String propertyIdentifier, final Serializable initialValue ) + throws ParameterValidationException { - return myPropertyFacade.addProperty( propertyIdentifier, initialValue ); + myPropertyFacade.addProperty( propertyIdentifier, initialValue ); } - public ValidationError addProperty( final String propertyIdentifier, - final Serializable initialValue, - final String description, final ParameterValidator... validators ) + public void addProperty( final String propertyIdentifier, final Serializable initialValue, final ParameterMetadata propertyMetadata ) + throws ParameterValidationException { - return myPropertyFacade.addProperty( propertyIdentifier, initialValue, description, validators ); + myPropertyFacade.addProperty( propertyIdentifier, initialValue, propertyMetadata ); } - public <T extends Serializable> ValidationError addProperty( final String propertyIdentifier, - final T initialValue, - final Class<T> type, - final String description, - final ParameterValidator... validators ) + public void addProperty( final String propertyIdentifier, + final Serializable initialValue, final String description, final ParameterValidator... validators ) + throws ParameterValidationException { - return myPropertyFacade.addProperty( propertyIdentifier, - initialValue, - type, - description, - validators ); + myPropertyFacade.addProperty( propertyIdentifier, initialValue, description, validators ); } - public ValidationError addProperty( final String propertyIdentifier, - final Serializable initialValue, - final ParameterMetadata propertyMetadata ) + public <T extends Serializable> void addProperty( final String propertyIdentifier, + final T initialValue, + final Class<T> type, + final String description, + final ParameterValidator... validators ) + throws ParameterValidationException { - return myPropertyFacade.addProperty( propertyIdentifier, initialValue, propertyMetadata ); + myPropertyFacade.addProperty( propertyIdentifier, initialValue, type, description, validators ); } - public ValidationError removeProperty( final String propertyIdentifier ) + public void removeProperty( final String propertyIdentifier ) + throws ParameterValidationException { - return myPropertyFacade.removeProperty( propertyIdentifier ); + myPropertyFacade.removeProperty( propertyIdentifier ); } //---------------------------------------------------------------------- // Task Implementation +//---------------------------------------------------------------------- + // Task Implementation + public void run() throws Exception { myActionFacade.runScheduledActs( getGameObjectContext().getCurrentGameTime_ms() ); Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/GameContext.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/GameContext.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/GameContext.java 2008-04-03 03:54:46 UTC (rev 430) @@ -27,10 +27,19 @@ */ public static GameObjectContext getGameObjectContext() { + if ( myGameObjectContext == null ) + { + throw new IllegalStateException( "No GameObjectContext has been specified yet for GameContext" ); + } + return myGameObjectContext; } - static void setGameObjectContext( GameObjectContext gameObjectContext ) + /** + * @param gameObjectContext the {@link GameObjectContext} to use for the current environment. + */ + // TODO: Remove this method, and instead use the static initializer to determine the GameObjectContext?? + public static void setGameObjectContext( GameObjectContext gameObjectContext ) { ParameterChecker.checkNotNull( gameObjectContext, "gameObjectContext" ); Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/GameObjectContext.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/GameObjectContext.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/GameObjectContext.java 2008-04-03 03:54:46 UTC (rev 430) @@ -1,9 +1,5 @@ package org.skycastle.core; -import org.skycastle.core.acting.InvocationType; - -import java.io.Serializable; - /** * Provides various functionality for a {@link GameObject} that depends on the environment it is running in * (client / server / unit test). @@ -11,7 +7,6 @@ * @author Hans Häggström */ public interface GameObjectContext - extends Serializable { /** @@ -29,12 +24,6 @@ */ void addTaskCallback( final long timeOfCallback_ms, GameObject gameObject ); - /** - * @return how actions should be invoked - directly, later in the swing thread, or as SGS Tasks. - * <p/> - * Allows the inheriting object to be either client side, server side, or for unit testing. - */ - InvocationType getActionInvocationType(); /** * Method for getting a {@link GameObject} based on its {@link GameObjectId}. The server and client side Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/MessagingFacadeImpl.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/MessagingFacadeImpl.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/MessagingFacadeImpl.java 2008-04-03 03:54:46 UTC (rev 430) @@ -148,7 +148,16 @@ // We are the target, check permissions for modification if ( isModificationPermitted( modificationMessage ) ) { - modificationMessage.applyModificationToTarget( getGameObject() ); + try + { + modificationMessage.applyModificationToTarget( getGameObject() ); + } + catch ( Exception e ) + { + // TODO: Add a way to report exceptions to a game object, that can log them, and possibly provide some in-game error inspection on a per object basis. + System.out.println( "Exception when applying message '" + message + "': " + e.getMessage() ); + e.printStackTrace(); + } } } } Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/ServerSideContext.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/ServerSideContext.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/ServerSideContext.java 2008-04-03 03:54:46 UTC (rev 430) @@ -3,7 +3,6 @@ import com.sun.sgs.app.AppContext; import com.sun.sgs.app.DataManager; import com.sun.sgs.app.ManagedReference; -import org.skycastle.core.acting.InvocationType; /** * @author Hans Häggström @@ -42,12 +41,6 @@ } - public InvocationType getActionInvocationType() - { - return InvocationType.TASK; - } - - public final GameObject getGameObjectById( final GameObjectId gameObjectId, final boolean forModification ) { Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/UnitTestingContext.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/UnitTestingContext.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/UnitTestingContext.java 2008-04-03 03:54:46 UTC (rev 430) @@ -1,6 +1,7 @@ package org.skycastle.core; -import org.skycastle.core.acting.InvocationType; +import java.util.PriorityQueue; +import java.util.Queue; /** * A {@link GameObjectContext} used for unit testing. @@ -12,6 +13,13 @@ { //====================================================================== + // Private Fields + + private final Queue<CallbackEvent> myEvents = new PriorityQueue<CallbackEvent>(); + + private long myInGameClock_ms = 0; + + //====================================================================== // Public Methods //---------------------------------------------------------------------- @@ -23,27 +31,95 @@ } - public void addTaskCallback( final long timeToNextInvocation_ms, final GameObject gameObject ) + public void addTaskCallback( final long timeOfCallback_ms, final GameObject gameObject ) { + myEvents.add( new CallbackEvent( gameObject, timeOfCallback_ms ) ); + } + + + public GameObject getGameObjectById( final GameObjectId gameObjectId, final boolean forModification ) + { throw new UnsupportedOperationException( "This method has not yet been implemented." ); // IMPLEMENT } - public InvocationType getActionInvocationType() + public long getCurrentGameTime_ms() { - return InvocationType.DIRECT; + return myInGameClock_ms; } + //---------------------------------------------------------------------- + // Other Public Methods - public GameObject getGameObjectById( final GameObjectId gameObjectId, final boolean forModification ) + public void advanceTimeAndCallCallbacks( final long timeIntervallToAdvance_ms ) throws Exception { - throw new UnsupportedOperationException( "This method has not yet been implemented." ); // IMPLEMENT + myInGameClock_ms += timeIntervallToAdvance_ms; + + while ( myEvents.peek() != null && + myEvents.peek().getTime() <= myInGameClock_ms ) + { + myEvents.poll().getGameObject().run(); + } } + //====================================================================== + // Inner Classes - public long getCurrentGameTime_ms() + private class CallbackEvent + implements Comparable<CallbackEvent> { - throw new UnsupportedOperationException( "This method has not yet been implemented." ); // IMPLEMENT + + //====================================================================== + // Private Fields + + private final long myTime; + private final GameObject myGameObject; + + //====================================================================== + // Public Methods + + //---------------------------------------------------------------------- + // Comparable Implementation + + public int compareTo( final CallbackEvent o ) + { + if ( myTime < o.getTime() ) + { + return -1; + } + else if ( myTime > o.getTime() ) + { + return 1; + } + else + { + return 0; + } + } + + //---------------------------------------------------------------------- + // Other Public Methods + + public long getTime() + { + return myTime; + } + + + public GameObject getGameObject() + { + return myGameObject; + } + + //====================================================================== + // Private Methods + + private CallbackEvent( final GameObject gameObject, final long time ) + { + myGameObject = gameObject; + myTime = time; + } + } } Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/Act.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/Act.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/Act.java 2008-04-03 03:54:46 UTC (rev 430) @@ -33,11 +33,14 @@ * * @return the number of in-game milliseconds before the doStep method should be called. If a negative * number is returned, the doStep is not called, and the {@link Act} is considered finished. + * + * @throws Exception if there was some problem when starting the Act and the Act should be terminated. */ long start( GameObject hostObject, MessageListener messageHandler, ParameterSet actParameters, - ParameterSet configurationParameters ); + ParameterSet configurationParameters ) + throws Exception; /** @@ -54,13 +57,17 @@ * <p/> * If a negative number is returned, the act is not repeated, and the {@link Act} is considered * finished. + * + * @throws Exception if there was some problem when running the step and the Act should be terminated. */ long doStep( GameObject hostObject, MessageListener messageHandler, ParameterSet parameters, ParameterSet configurationParameters, - long timeSinceLastCall_ms ); + long timeSinceLastCall_ms ) + throws Exception; + /** * Called when the action is stopped by the user, or interrupted for some other reason. * <p/> @@ -77,11 +84,14 @@ * @param messageHandler a listener that can handle messages sent out by this {@link Act}. * @param parameters the parameters that the act was called with. * @param configurationParameters the parameters that the action is configured with. + * + * @throws Exception if there was some problem when stopping the act. */ void stop( GameObject hostObject, MessageListener messageHandler, final ParameterSet parameters, ParameterSet configurationParameters, - long timeSinceLastCall_ms ); + long timeSinceLastCall_ms ) + throws Exception; } Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/ActEvent.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/ActEvent.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/ActEvent.java 2008-04-03 03:54:46 UTC (rev 430) @@ -132,7 +132,7 @@ * finished. */ public boolean invoke( GameObject hostObject, - long currentTime_ms ) + long currentTime_ms ) throws Exception { final long timeUntilNextCall = callAct( hostObject, currentTime_ms ); @@ -159,6 +159,7 @@ */ public void stopAct( GameObject hostObject, long currentTime_ms ) + throws Exception { final long timeSinceLastCall = currentTime_ms - myLastCallTime_ms; @@ -187,7 +188,7 @@ * Invoke either start or doStep depending on if this is the first or a subsequent call for this act. */ private long callAct( final GameObject hostObject, - final long currentTime_ms ) + final long currentTime_ms ) throws Exception { final long timeSinceLastCall = currentTime_ms - myLastCallTime_ms; Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/ActionFacadeImpl.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/ActionFacadeImpl.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/ActionFacadeImpl.java 2008-04-03 03:54:46 UTC (rev 430) @@ -155,7 +155,16 @@ { final ActEvent nextEvent = myActQueue.poll(); - final boolean reinsert = nextEvent.invoke( getGameObject(), currentTime_ms ); + boolean reinsert = false; + try + { + reinsert = nextEvent.invoke( getGameObject(), currentTime_ms ); + } + catch ( Exception e ) + { + // TODO: Log exception with game object? + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } if ( reinsert ) { @@ -231,7 +240,15 @@ if ( event.hasActId( actionId, actId ) ) { myActQueue.remove( event ); - event.stopAct( getGameObject(), currentTime_ms ); + try + { + event.stopAct( getGameObject(), currentTime_ms ); + } + catch ( Exception e ) + { + // TODO: Log error with game object + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } return; } } Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/ActionImpl.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/ActionImpl.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/ActionImpl.java 2008-04-03 03:54:46 UTC (rev 430) @@ -148,12 +148,10 @@ // Other Public Methods public final void doAction( final GameObject hostObject, - final ParameterSet parameters, - final InvocationType invocationType ) + final ParameterSet parameters ) { ParameterChecker.checkNotNull( hostObject, "hostObject" ); ParameterChecker.checkNotNull( parameters, "parameters" ); - ParameterChecker.checkNotNull( invocationType, "invocationType" ); final Class<? extends Act> actClass = getActClass(); Deleted: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/InvocationType.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/InvocationType.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/acting/InvocationType.java 2008-04-03 03:54:46 UTC (rev 430) @@ -1,56 +0,0 @@ -package org.skycastle.core.acting; - -import com.sun.sgs.app.AppContext; -import com.sun.sgs.app.ManagedReference; -import com.sun.sgs.app.Task; -import org.skycastle.core.GameObject; - -/** - * Determines how an action is executed. - * - * @author Hans H�ggstr�m - */ -public enum InvocationType -{ - - /** - * Runs the action directly in the same thread as the call came. Useful for unit testing. - */ - DIRECT, - - /** - * Runs the action in a separate {@link Task}. - */ - TASK, - - /** - * Runs the action with invoke later in the swing event handling thread. Suitable for use on the client. - */ - LATER_IN_SWING_THREAD; - - public Object storeGameObject( final GameObject gameObject ) - { - if ( this == TASK ) - { - return AppContext.getDataManager().createReference( gameObject ); - } - else - { - return gameObject; - } - } - - - public GameObject retrieveGameObject( final Object storedGameObject ) - { - if ( this == TASK ) - { - return ( (ManagedReference) storedGameObject ).getForUpdate( GameObject.class ); - } - else - { - return (GameObject) storedGameObject; - } - } - -} Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/property/PropertyFacade.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/property/PropertyFacade.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/property/PropertyFacade.java 2008-04-03 03:54:46 UTC (rev 430) @@ -1,7 +1,8 @@ package org.skycastle.core.property; +import org.skycastle.core.GameObject; import org.skycastle.util.parameters.ParameterMetadata; -import org.skycastle.util.parameters.ValidationError; +import org.skycastle.util.parameters.ParameterValidationException; import org.skycastle.util.parameters.validators.ParameterValidator; import java.io.Serializable; @@ -14,6 +15,9 @@ extends Serializable { + //====================================================================== + // Public Methods + /** * @param propertyIdentifier identifier of the property to get. * @param defaultValue the default value of the property. @@ -30,16 +34,15 @@ * @param propertyIdentifier identifier of the property to set. * @param value value to set the property to. * - * @return a {@link org.skycastle.util.parameters.ValidationError} describing the error if there was a - * problem with setting the property value, null on success. + * @throws ParameterValidationException describing the error if there was a + * problem with setting the property value. */ - // TODO: Throw error instead of returning a code - ValidationError setPropertyValue( String propertyIdentifier, Serializable value ); + void setPropertyValue( String propertyIdentifier, Serializable value ) throws ParameterValidationException; /** * @param propertyIdentifier the name of the property to check for. * - * @return true if this {@link org.skycastle.core.GameObject} has a property with the specified + * @return true if this {@link GameObject} has a property with the specified * identifier. */ boolean hasProperty( String propertyIdentifier ); @@ -58,21 +61,37 @@ /** * Adds a new property with the specified metadata and initial value to this {@link - * org.skycastle.core.GameObject}. + * GameObject}. * <p/> * The type of the property is infered from the initialValue. * * @param propertyIdentifier a Java style identifier for the property. * @param initialValue initial value for the property. * - * @return a {@link ValidationError} describing the error if there was a problem with adding the property - * or setting the initial property value, null on success. + * @throws ParameterValidationException a {@link org.skycastle.util.parameters.ParameterValidationException} describing the error if there was a problem with adding the property + * or setting the initial property value */ - // TODO: Throw error instead of returning a code - ValidationError addProperty( String propertyIdentifier, - Serializable initialValue ); + void addProperty( String propertyIdentifier, + Serializable initialValue ) + throws ParameterValidationException; /** + * Adds a new property with the specified metadata and initial value to this {@link + * GameObject}. + * + * @param propertyIdentifier a Java style identifier for the property. + * @param initialValue initial value for the property. + * @param propertyMetadata metadata for the property. + * + * @throws ParameterValidationException a {@link org.skycastle.util.parameters.ParameterValidationException} describing the error if there was a problem with adding the property + * or setting the initial property value + */ + void addProperty( String propertyIdentifier, + Serializable initialValue, + ParameterMetadata propertyMetadata ) + throws ParameterValidationException; + + /** * Adds a new property with the specified metadata and initial value to this {@link GameObject}. * <p/> * The type of the property is infered from the initialValue. @@ -83,18 +102,19 @@ * @param validators an array / variable length list with validators to use for restricting the * possible property values. * - * @return a {@link ValidationError} describing the error if there was a problem with adding the property - * or setting the initial property value, null on success. + * @throws ParameterValidationException a {@link org.skycastle.util.parameters.ParameterValidationException} describing the error if there was a problem with adding the property + * or setting the initial property value */ - // TODO: Throw error instead of returning a code - ValidationError addProperty( String propertyIdentifier, - Serializable initialValue, - String description, - ParameterValidator... validators ); + void addProperty( String propertyIdentifier, + Serializable initialValue, + String description, + ParameterValidator... validators ) + throws ParameterValidationException; + /** * Adds a new property with the specified metadata and initial value to this {@link - * org.skycastle.core.GameObject}. + * GameObject}. * * @param propertyIdentifier a Java style identifier for the property. * @param initialValue initial value for the property. @@ -103,40 +123,27 @@ * @param validators an array / variable length list with validators to use for restricting the * possible property values. * - * @return a {@link ValidationError} describing the error if there was a problem with adding the property - * or setting the initial property value, null on success. + * @throws ParameterValidationException a {@link org.skycastle.util.parameters.ParameterValidationException} describing the error if there was a problem with adding the property + * or setting the initial property value */ - // TODO: Throw error instead of returning a code - <T extends Serializable> ValidationError addProperty( String propertyIdentifier, - T initialValue, - Class<T> type, - String description, - ParameterValidator... validators ); + <T extends Serializable> void addProperty( String propertyIdentifier, + T initialValue, + Class<T> type, + String description, + ParameterValidator... validators ) + throws ParameterValidationException; /** - * Adds a new property with the specified metadata and initial value to this {@link - * org.skycastle.core.GameObject}. - * - * @param propertyIdentifier a Java style identifier for the property. - * @param initialValue initial value for the property. - * @param propertyMetadata metadata for the property. - * - * @return a {@link ValidationError} describing the error if there was a problem with adding the property - * or setting the initial property value, null on success. - */ - // TODO: Throw error instead of returning a code - ValidationError addProperty( String propertyIdentifier, - Serializable initialValue, - ParameterMetadata propertyMetadata ); - - /** * Attempts to remove the specified property. * * @param propertyIdentifier the identifier of the property to remove. * - * @return null on success, an error description if there was some problem. + * @throws ParameterValidationException a {@link org.skycastle.util.parameters.ParameterValidationException} describing the error if there was a problem with adding the property + * or setting the initial property value + * @throws ParameterValidationException a {@link org.skycastle.util.parameters.ParameterValidationException} describing the error if there was a problem with adding the property + * or setting the initial property value */ - // TODO: Throw error instead of returning a code - ValidationError removeProperty( String propertyIdentifier ); + void removeProperty( String propertyIdentifier ) + throws ParameterValidationException; } Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/core/property/PropertyFacadeImpl.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/core/property/PropertyFacadeImpl.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/core/property/PropertyFacadeImpl.java 2008-04-03 03:54:46 UTC (rev 430) @@ -11,6 +11,7 @@ import org.skycastle.util.listenable.map.ListenableLinkedMap; import org.skycastle.util.parameters.ParameterMetadata; import org.skycastle.util.parameters.ParameterMetadataImpl; +import org.skycastle.util.parameters.ParameterValidationException; import org.skycastle.util.parameters.ValidationError; import org.skycastle.util.parameters.validators.ParameterValidator; @@ -25,7 +26,6 @@ extends AbstractFacade implements PropertyFacade { - private static final long serialVersionUID = 1L; //====================================================================== // Private Fields @@ -39,6 +39,14 @@ private final ListenableLinkedMap<String, ParameterMetadata> myPropertyMetadata = new ListenableLinkedMap<String, ParameterMetadata>(); //====================================================================== + // Private Constants + + private static final long serialVersionUID = 1L; + private static final String COULD_NOT_SET_PROPERTY_VALUE = "Could not set property value"; + private static final String PROBLEM_WHEN_ADDING_PROPERTY = "Problem when adding property"; + private static final String PROBLEM_WHEN_REMOVING_PROPERTY = "Problem when removing property"; + + //====================================================================== // Public Methods //---------------------------------------------------------------------- @@ -55,7 +63,6 @@ //---------------------------------------------------------------------- // PropertyFacade Implementation - public <T> T getPropertyValue( final String propertyIdentifier, final T defaultValue ) { if ( myPropertyValues.containsKey( propertyIdentifier ) ) @@ -69,38 +76,34 @@ } - public ValidationError setPropertyValue( final String propertyIdentifier, final Serializable value ) + public void setPropertyValue( final String propertyIdentifier, final Serializable value ) + throws ParameterValidationException { ParameterChecker.checkIsIdentifier( propertyIdentifier, "propertyIdentifier" ); final ParameterMetadata propertyMetadata = getPropertyMetadata( propertyIdentifier ); // Make sure there is a property with that name - ValidationError validationError = null; if ( propertyMetadata == null ) { - validationError = new ValidationError( propertyIdentifier, - "No field called '" + propertyIdentifier + "' exists." ); + throw new ParameterValidationException( COULD_NOT_SET_PROPERTY_VALUE, + new ValidationError( propertyIdentifier, + "No field called '" + propertyIdentifier + "' exists." ) ); } // Check that the vaue is acceptable - if ( validationError == null ) + ValidationError validationError = propertyMetadata.validateParameter( value, propertyIdentifier ); + if ( validationError != null ) { - validationError = propertyMetadata.validateParameter( value, - propertyIdentifier ); + throw new ParameterValidationException( COULD_NOT_SET_PROPERTY_VALUE, validationError ); } // Set value - if ( validationError == null ) - { - myPropertyValues.put( propertyIdentifier, value ); + myPropertyValues.put( propertyIdentifier, value ); - getGameObject().sendUpdateToObservers( new PropertyChangedMessage( getId(), - propertyIdentifier, - value ) ); - } - - return validationError; + getGameObject().sendUpdateToObservers( new PropertyChangedMessage( getId(), + propertyIdentifier, + value ) ); } @@ -122,74 +125,37 @@ } - public ValidationError addProperty( final String propertyIdentifier, final Serializable initialValue ) + public void addProperty( final String propertyIdentifier, final Serializable initialValue ) + throws ParameterValidationException { - return addProperty( propertyIdentifier, initialValue, (String) null ); + addProperty( propertyIdentifier, initialValue, (String) null ); } - public ValidationError addProperty( final String propertyIdentifier, - final Serializable initialValue, - final String description, - final ParameterValidator... validators ) + public void addProperty( final String propertyIdentifier, + final Serializable initialValue, + final ParameterMetadata propertyMetadata ) throws ParameterValidationException { - // Infer type of property from initial value - Class type = Object.class; - if ( initialValue != null ) - { - type = initialValue.getClass(); - } - - //noinspection unchecked - return addProperty( propertyIdentifier, initialValue, type, description, validators ); - } - - - public <T extends Serializable> ValidationError addProperty( final String propertyIdentifier, - final T initialValue, - final Class<T> type, - final String description, - final ParameterValidator... validators ) - { - // Create metadata - final ParameterMetadataImpl propertyMetadata = - new ParameterMetadataImpl( type, - false, - StringUtilities.camelCaseToUserReadableString( propertyIdentifier ), - description ); - - // Add validators to metadata - for ( final ParameterValidator validator : validators ) - { - propertyMetadata.addParameterValidator( validator ); - } - - return addProperty( propertyIdentifier, initialValue, propertyMetadata ); - } - - - public ValidationError addProperty( final String propertyIdentifier, - final Serializable initialValue, - final ParameterMetadata propertyMetadata ) - { ParameterChecker.checkNotNull( propertyIdentifier, "propertyIdentifier" ); ParameterChecker.checkNotNull( propertyMetadata, "propertyMetadata" ); // Check that the identifier is correct if ( !StringUtilities.isIdentifier( propertyIdentifier ) ) { - return new ValidationError( "", - "The name for the new property is not following the " + - "identifier syntax (letter + letter, numbers, and underscores), " + - "instead it was '" + propertyIdentifier + "' " ); + throw new ParameterValidationException( PROBLEM_WHEN_ADDING_PROPERTY, + new ValidationError( "", + "The name for the new property is not following the " + + "identifier syntax (letter + letter, numbers, and underscores), " + + "instead it was '" + propertyIdentifier + "' " ) ); } // Check that we don't already have this property if ( myPropertyMetadata.containsKey( propertyIdentifier ) ) { - return new ValidationError( "", - "There is already a property called '" + propertyIdentifier + "' " + - "registered, can not add a new one with the same name" ); + throw new ParameterValidationException( PROBLEM_WHEN_ADDING_PROPERTY, + new ValidationError( "", + "There is already a property called '" + propertyIdentifier + "' " + + "registered, can not add a new one with the same name" ) ); } // Check that the initial vaue is acceptable @@ -197,7 +163,7 @@ propertyIdentifier ); if ( validationError != null ) { - return validationError; + throw new ParameterValidationException( PROBLEM_WHEN_ADDING_PROPERTY, validationError ); } // Add property @@ -209,17 +175,57 @@ propertyIdentifier, initialValue, propertyMetadata ) ); + } - return null; + + public void addProperty( final String propertyIdentifier, + final Serializable initialValue, + final String description, + final ParameterValidator... validators ) + throws ParameterValidationException + { + // Infer type of property from initial value + Class type = Object.class; + if ( initialValue != null ) + { + type = initialValue.getClass(); + } + + //noinspection unchecked + addProperty( propertyIdentifier, initialValue, type, description, validators ); } - public ValidationError removeProperty( final String propertyIdentifier ) + public <T extends Serializable> void addProperty( final String propertyIdentifier, + final T initialValue, + final Class<T> type, + final String description, + final ParameterValidator... validators ) throws ParameterValidationException { + // Create metadata + final ParameterMetadataImpl propertyMetadata = + new ParameterMetadataImpl( type, + false, + StringUtilities.camelCaseToUserReadableString( propertyIdentifier ), + description ); + + // Add validators to metadata + for ( final ParameterValidator validator : validators ) + { + propertyMetadata.addParameterValidator( validator ); + } + + addProperty( propertyIdentifier, initialValue, propertyMetadata ); + } + + + public void removeProperty( final String propertyIdentifier ) throws ParameterValidationException + { if ( !hasProperty( propertyIdentifier ) ) { - return new ValidationError( propertyIdentifier, - "Could not remove property, as no such property was found." ); + throw new ParameterValidationException( PROBLEM_WHEN_REMOVING_PROPERTY, + new ValidationError( propertyIdentifier, + "Could not remove property, as no such property was found." ) ); } myPropertyMetadata.remove( propertyIdentifier ); @@ -227,8 +233,6 @@ getGameObject().sendUpdateToObservers( new PropertyRemovedMessage( getId(), propertyIdentifier ) ); - - return null; } } Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/ModificationMessage.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/ModificationMessage.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/ModificationMessage.java 2008-04-03 03:54:46 UTC (rev 430) @@ -29,7 +29,9 @@ * Applies the modification of this message to the target {@link GameObject}. * * @param target the target object. Should have the id of getTargetId(). + * + * @throws Exception if there was some problem with applying the modification. */ - void applyModificationToTarget( GameObject target ); + void applyModificationToTarget( GameObject target ) throws Exception; } Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/RemovePropertyMessage.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/RemovePropertyMessage.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/RemovePropertyMessage.java 2008-04-03 03:54:46 UTC (rev 430) @@ -3,6 +3,7 @@ import org.skycastle.core.GameObject; import org.skycastle.core.GameObjectId; import org.skycastle.messaging.Message; +import org.skycastle.util.parameters.ParameterValidationException; /** * Removes a property from the target {@link GameObject}. @@ -41,7 +42,7 @@ //---------------------------------------------------------------------- // ModificationMessage Implementation - public void applyModificationToTarget( final GameObject target ) + public void applyModificationToTarget( final GameObject target ) throws ParameterValidationException { target.removeProperty( getMemberIdentifier() ); } Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/property/AddPropertyMessage.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/property/AddPropertyMessage.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/property/AddPropertyMessage.java 2008-04-03 03:54:46 UTC (rev 430) @@ -6,6 +6,7 @@ import org.skycastle.messaging.modifications.MemberModificationMessage; import org.skycastle.util.ParameterChecker; import org.skycastle.util.parameters.ParameterMetadata; +import org.skycastle.util.parameters.ParameterValidationException; import org.skycastle.util.parameters.ValidationError; import java.io.Serializable; @@ -83,7 +84,7 @@ //---------------------------------------------------------------------- // ModificationMessage Implementation - public void applyModificationToTarget( final GameObject target ) + public void applyModificationToTarget( final GameObject target ) throws ParameterValidationException { target.addProperty( getMemberIdentifier(), myInitialValue, myPropertyMetadata ); } Modified: trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/property/SetPropertyMessage.java =================================================================== --- trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/property/SetPropertyMessage.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/modifications/property/SetPropertyMessage.java 2008-04-03 03:54:46 UTC (rev 430) @@ -4,6 +4,7 @@ import org.skycastle.core.GameObjectId; import org.skycastle.messaging.AbstractMessage; import org.skycastle.messaging.modifications.MemberModificationMessage; +import org.skycastle.util.parameters.ParameterValidationException; import org.skycastle.util.parameters.ValidationError; import java.io.Serializable; @@ -72,6 +73,7 @@ // ModificationMessage Implementation public void applyModificationToTarget( final GameObject target ) + throws ParameterValidationException { target.setPropertyValue( getMemberIdentifier(), myValue ); } Modified: trunk/skycastle/modules/core/src/test/java/org/skycastle/core/AbstractGameObjectActionsTest.java =================================================================== --- trunk/skycastle/modules/core/src/test/java/org/skycastle/core/AbstractGameObjectActionsTest.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/test/java/org/skycastle/core/AbstractGameObjectActionsTest.java 2008-04-03 03:54:46 UTC (rev 430) @@ -11,7 +11,7 @@ /** * @author Hans Haggstrom */ -@SuppressWarnings( { "JavaDoc" } ) +@SuppressWarnings( { "JavaDoc", "MagicNumber" } ) public class AbstractGameObjectActionsTest extends TestCase { @@ -20,12 +20,18 @@ // Private Fields private GameObject myGameObject; - private ActionImpl myTestAction; + private GameObjectId myCallerId; + private UnitTestingContext myUnitTestingContext; + //====================================================================== + // Private Constants + private static final String ACTION_INVOKED = "actionInvoked"; private static final String TEST_ACTION_NAME = "testAction"; - private GameObjectId myCallerId; - private UnitTestingContext myUnitTestingContext; + private static final String STEPS_CALLED = "stepsCalled"; + private static final String STOP_CALLED = "stopCalled"; + private static final String REPEAT_INTERVALL = "repeatIntervall"; + private static final String NUMBER_OF_STEPS = "numberOfSteps"; //====================================================================== // Public Methods @@ -51,17 +57,7 @@ myGameObject.hasAction( actionName ) ); } - public void testRemoveAction() throws Exception - { - assertTrue( myGameObject.hasAction( TEST_ACTION_NAME ) ); - myGameObject.removeAction( TEST_ACTION_NAME ); - assertFalse( "Action should be removed", - myGameObject.hasAction( TEST_ACTION_NAME ) ); - - } - - public void testImmediatelyInvokeAction() throws Exception { myGameObject.startAction( myCallerId, TEST_ACTION_NAME ); @@ -70,16 +66,50 @@ myGameObject.getPropertyValue( ACTION_INVOKED, false ) ); } + public void testProlongedAction() throws Exception { + myGameObject.setPropertyValue( REPEAT_INTERVALL, 100 ); + myGameObject.setPropertyValue( NUMBER_OF_STEPS, 3 ); + myGameObject.startAction( myCallerId, TEST_ACTION_NAME ); assertTrue( "Action should have been invoked", myGameObject.getPropertyValue( ACTION_INVOKED, false ) ); + assertEquals( 0, (int) myGameObject.getPropertyValue( STEPS_CALLED, 0 ) ); + myUnitTestingContext.advanceTimeAndCallCallbacks( 100 ); + assertEquals( "Callback should have been called", + 1, (int) myGameObject.getPropertyValue( STEPS_CALLED, 0 ) ); + assertEquals( 1, (int) myGameObject.getPropertyValue( STEPS_CALLED, 0 ) ); + assertFalse( "Stop should not have been called", + myGameObject.getPropertyValue( STOP_CALLED, false ) ); + + myUnitTestingContext.advanceTimeAndCallCallbacks( 100 ); + assertEquals( 2, (int) myGameObject.getPropertyValue( STEPS_CALLED, 0 ) ); + myUnitTestingContext.advanceTimeAndCallCallbacks( 100 ); + assertEquals( "Callback should have been called", + 3, (int) myGameObject.getPropertyValue( STEPS_CALLED, 0 ) ); + + assertFalse( "Stop should not have been called", + myGameObject.getPropertyValue( STOP_CALLED, false ) ); + + myUnitTestingContext.advanceTimeAndCallCallbacks( 100 ); + assertEquals( "Callback should not have been called anymore", + 3, (int) myGameObject.getPropertyValue( STEPS_CALLED, 0 ) ); } + + public void testRemoveAction() throws Exception + { + assertTrue( myGameObject.hasAction( TEST_ACTION_NAME ) ); + + myGameObject.removeAction( TEST_ACTION_NAME ); + assertFalse( "Action should be removed", + myGameObject.hasAction( TEST_ACTION_NAME ) ); + } + //====================================================================== // Protected Methods @@ -87,62 +117,99 @@ protected void setUp() throws Exception { myUnitTestingContext = new UnitTestingContext(); + GameContext.setGameObjectContext( myUnitTestingContext ); - myGameObject = new DefaultGameObject( myUnitTestingContext ); + myGameObject = new DefaultGameObject(); myGameObject.addProperty( ACTION_INVOKED, false ); + myGameObject.addProperty( REPEAT_INTERVALL, -1 ); + myGameObject.addProperty( NUMBER_OF_STEPS, 0 ); + myGameObject.addProperty( STEPS_CALLED, 0 ); - myTestAction = new ActionImpl( TEST_ACTION_NAME, - new ParameterSetMetadataImpl(), - DummyAct.class, - null, - true, - true ); + final Action testAction = new ActionImpl( TEST_ACTION_NAME, + new ParameterSetMetadataImpl(), + DummyAct.class, + null, + true, + true ); - myGameObject.addAction( myTestAction ); - assertTrue( "Action should be added", 2 - myGameObject.hasAction( TEST_ACTION_NAME )); + myGameObject.addAction( testAction ); + assertTrue( "Action should be added", + myGameObject.hasAction( TEST_ACTION_NAME ) ); myCallerId = new GameObjectId( "someSender" ); } + //====================================================================== + // Inner Classes + + @SuppressWarnings( { "PublicInnerClass" } ) + // Needs to be public to allow reflection to create an instance of it public static class DummyAct implements Act { - private static final String TIMES_CALLED = "timesCalled"; - private static final String STOP_CALLED = "stopCalled"; - private static final String REPEAT_INTERVALL = "repeatIntervall"; + //====================================================================== + // Private Constants + + private static final long serialVersionUID = 1L; + + //====================================================================== + // Public Methods + + //---------------------------------------------------------------------- + // Act Implementation + public long start( final GameObject hostObject, final MessageListener messageHandler, final ParameterSet actParameters, final ParameterSet configurationParameters ) + throws Exception { hostObject.setPropertyValue( ACTION_INVOKED, true ); - return actParameters.getLong( REPEAT_INTERVALL, -1 ); + return calculateTimeUntilNextInvocation( hostObject ); } + + public long doStep( final GameObject hostObject, + final MessageListener messageHandler, + final ParameterSet parameters, + final ParameterSet configurationParameters, + final long timeSinceLastCall_ms ) + throws Exception + { + final int timesCalled = hostObject.getPropertyValue( STEPS_CALLED, 0 ) + 1; + hostObject.setPropertyValue( STEPS_CALLED, timesCalled ); + + return calculateTimeUntilNextInvocation( hostObject ); + } + + public void stop( final GameObject hostObject, final MessageListener messageHandler, final ParameterSet parameters, final ParameterSet configurationParameters, final long timeSinceLastCall_ms ) + throws Exception { hostObject.setPropertyValue( STOP_CALLED, true ); } - public long doStep( final GameObject hostObject, - final MessageListener messageHandler, - final ParameterSet parameters, - final ParameterSet configurationParameters, - final long timeSinceLastCall_ms ) + //====================================================================== + // Private Methods + + @SuppressWarnings( { "MethodMayBeStatic" } ) + private long calculateTimeUntilNextInvocation( final GameObject hostObject ) { - final int value = hostObject.getPropertyValue( TIMES_CALLED, 0 ) + 1; - hostObject.setPropertyValue( TIMES_CALLED, value ); + long timeUntilNextCallback_ms = -1; + if ( hostObject.getPropertyValue( STEPS_CALLED, 0 ) < hostObject.getPropertyValue( NUMBER_OF_STEPS, 0 ) ) + { + timeUntilNextCallback_ms = hostObject.getPropertyValue( REPEAT_INTERVALL, -1 ); + } - return parameters.getLong( REPEAT_INTERVALL, -1 ); + return timeUntilNextCallback_ms; } + } - } Modified: trunk/skycastle/modules/core/src/test/java/org/skycastle/core/AbstractGameObjectPropertiesTest.java =================================================================== --- trunk/skycastle/modules/core/src/test/java/org/skycastle/core/AbstractGameObjectPropertiesTest.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/test/java/org/skycastle/core/AbstractGameObjectPropertiesTest.java 2008-04-03 03:54:46 UTC (rev 430) @@ -1,7 +1,6 @@ package org.skycastle.core; import junit.framework.TestCase; -import org.skycastle.core.acting.InvocationType; import org.skycastle.messaging.Message; import org.skycastle.messaging.MessageListener; import org.skycastle.messaging.modifications.RemovePropertyMessage; @@ -11,7 +10,7 @@ import org.skycastle.messaging.updates.property.PropertyChangedMessage; import org.skycastle.messaging.updates.property.PropertyRemovedMessage; import org.skycastle.util.parameters.ParameterMetadataImpl; -import org.skycastle.util.parameters.ValidationError; +import org.skycastle.util.parameters.ParameterValidationException; import org.skycastle.util.parameters.validators.notnull.NotNullValidator; import java.util.ArrayList; @@ -41,26 +40,49 @@ public void testAddingAlreadyContainedProperty() throws Exception { - assertNull( myGameObject.addProperty( "lunch", "Onion Soup" ) ); + myGameObject.addProperty( "lunch", "Onion Soup" ); assertEquals( 1, getNumberOfProperties() ); - assertNotNull( myGameObject.addProperty( "lunch", "French Toast" ) ); + try + { + myGameObject.addProperty( "lunch", "French Toast" ); + fail( "Should throw exception" ); + } + catch ( ParameterValidationException e ) + { + } assertEquals( 1, getNumberOfProperties() ); } public void testAddingPropertyWithInvalidIdentifier() throws Exception { - assertNotNull( myGameObject.addProperty( "spaces! for the win!", "no space no identifier" ) ); + try + { + myGameObject.addProperty( "spaces! for the win!", "no space no identifier" ); + fail( "Should throw exception" ); + } + catch ( ParameterValidationException e ) + { + } + assertEquals( 0, getNumberOfProperties() ); } public void testAddingPropertyWithInvalidInitialValue() throws Exception { - assertNotNull( myGameObject.addProperty( "lunch", - 42, - new ParameterMetadataImpl( String.class ) ) ); + try + { + myGameObject.addProperty( "lunch", + 42, + new ParameterMetadataImpl( String.class ) ); + fail( "Should throw exception" ); + } + catch ( ParameterValidationException e ) + { + } + assertEquals( 0, getNumberOfProperties() ); } @@ -151,14 +173,12 @@ public void testPropertySetAndGet() throws Exception { - final ValidationError error = myGameObject.addProperty( "dinner", - "Broccoli Soup", - new ParameterMetadataImpl( String.class ) + myGameObject.addProperty( "dinner", + "Broccoli Soup", + new ParameterMetadataImpl( String.class ) ); - assertNull( "There should be no validation error", error ); - final ValidationError validationError = myGameObject.setPropertyValue( "dinner", "Noodles" ); - assertNull( "There should be no validation error", validationError ); + myGameObject.setPropertyValue( "dinner", "Noodles" ); assertEquals( "Noodles", myGameObject.getPropertyValue( "dinner", null ) ); } @@ -180,21 +200,35 @@ public void testRemovingNonExistingProperty() throws Exception { - assertNotNull( myGameObject.removeProperty( "brunch" ) ); + try + { + myGameObject.removeProperty( "brunch" ); + fail( "Should throw exception" ); + } + catch ( ParameterValidationException e ) + { + } } public void testSetBoolean() throws Exception { - assertNull( myGameObject.addProperty( "lunchtime", false ) ); - assertNull( myGameObject.setPropertyValue( "lunchtime", true ) ); + myGameObject.addProperty( "lunchtime", false ); + myGameObject.setPropertyValue( "lunchtime", true ); assertTrue( myGameObject.getPropertyValue( "lunchtime", false ) ); } public void testSettingNonExistingProperty() throws Exception { - assertNotNull( myGameObject.setPropertyValue( "brunch", "Croissant" ) ); + try + { + myGameObject.setPropertyValue( "brunch", "Croissant" ); + fail( "Should have thrown an exception" ); + } + catch ( ParameterValidationException e ) + { + } } //====================================================================== @@ -203,19 +237,10 @@ @Override protected void setUp() throws Exception { - myGameObject = new DefaultGameObject( new UnitTestingContext() ) - { + GameContext.setGameObjectContext( new UnitTestingContext() ); - protected InvocationType getActionInvocationType() - { - return InvocationType.DIRECT; - } + myGameObject = new DefaultGameObject(); - - private static final long serialVersionUID = 1L; - - }; - // Keep the messages sent by the game object mySentMessages = new ArrayList<Message>( 10 ); myGameObject.addDirectUpdateListener( new AllMessagesFilter(), @@ -263,7 +288,7 @@ } - private void setupTodaysMenu() + private void setupTodaysMenu() throws ParameterValidationException { myGameObject.addProperty( "breakfast", "Porridge" ); myGameObject.addProperty( "secondBreakfast", "Ham and eggs" ); Modified: trunk/skycastle/modules/core/src/test/java/org/skycastle/core/geometry/space/grid/GridTest.java =================================================================== --- trunk/skycastle/modules/core/src/test/java/org/skycastle/core/geometry/space/grid/GridTest.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/core/src/test/java/org/skycastle/core/geometry/space/grid/GridTest.java 2008-04-03 03:54:46 UTC (rev 430) @@ -1,7 +1,9 @@ package org.skycastle.core.geometry.space.grid; import junit.framework.TestCase; +import org.skycastle.core.GameContext; import org.skycastle.core.GameObject; +import org.skycastle.core.UnitTestingContext; import org.skycastle.core.pojo.PojoGameObject; import java.util.ArrayList; @@ -72,6 +74,7 @@ @Override protected void setUp() throws Exception { + GameContext.setGameObjectContext( new UnitTestingContext() ); myGridSpace = new GridSpace( 10, 10 ); } Modified: trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/parameters/ParameterValidationException.java =================================================================== --- trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/parameters/ParameterValidationException.java 2008-04-02 19:55:19 UTC (rev 429) +++ trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/parameters/ParameterValidationException.java 2008-04-03 03:54:46 UTC (rev 430) @@ -1,5 +1,6 @@ package org.skycastle.util.parameters; +import java.util.Collections; import java.util.List; /** @@ -32,6 +33,14 @@ myValidationErrors = validationErrors; } + /** + * Creates a new {@link org.skycastle.util.parameters.ParameterValidationException}. + */ + public ParameterValidationException( String contextMessage, ValidationError validationError ) + { + this( contextMessage, Collections.singletonList( validationError ) ); + } + //---------------------------------------------------------------------- // Other Public Methods This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.