diff --git a/src/java/com/threerings/parlor/game/GameManager.java b/src/java/com/threerings/parlor/game/GameManager.java index 5a065a287..227951203 100644 --- a/src/java/com/threerings/parlor/game/GameManager.java +++ b/src/java/com/threerings/parlor/game/GameManager.java @@ -1,5 +1,5 @@ // -// $Id: GameManager.java,v 1.17 2001/12/14 00:11:18 mdb Exp $ +// $Id: GameManager.java,v 1.18 2002/02/12 06:57:29 mdb Exp $ package com.threerings.parlor.game; @@ -65,6 +65,14 @@ public class GameManager _playerOids = new int[players.length]; } + /** + * Returns an array of the usernames of the players in this game. + */ + public String[] getPlayers () + { + return _players; + } + // documentation inherited protected void didStartup () { diff --git a/src/java/com/threerings/parlor/turn/TurnGameController.java b/src/java/com/threerings/parlor/turn/TurnGameController.java index ed8c5652f..75af4b903 100644 --- a/src/java/com/threerings/parlor/turn/TurnGameController.java +++ b/src/java/com/threerings/parlor/turn/TurnGameController.java @@ -1,30 +1,16 @@ // -// $Id: TurnGameController.java,v 1.2 2001/10/18 20:53:23 mdb Exp $ +// $Id: TurnGameController.java,v 1.3 2002/02/12 06:57:30 mdb Exp $ package com.threerings.parlor.turn; -import com.threerings.presents.dobj.*; -import com.threerings.crowd.data.BodyObject; - -import com.threerings.parlor.Log; -import com.threerings.parlor.game.GameController; - /** - * Extends the basic game controller with support for turn-based games. + * Games that wish to make use of the turn game services should have their + * controller implement this interface and create an instance of {@link + * TurnGameControllerDelegate}, calling out to it at the appropriate + * times. */ -public abstract class TurnGameController extends GameController +public interface TurnGameController { - // documentation inherited - public void attributeChanged (AttributeChangedEvent event) - { - super.attributeChanged(event); - - // handle turn changes - if (event.getName().equals(TurnGameObject.TURN_HOLDER)) { - turnDidChange((String)event.getValue()); - } - } - /** * Called when the turn changed. This indicates the start of a turn * and the user interface should adjust itself accordingly (activating @@ -32,20 +18,5 @@ public abstract class TurnGameController extends GameController * * @param turnHolder the username of the new holder of the turn. */ - protected void turnDidChange (String turnHolder) - { - Log.info("Turn changed [holder=" + turnHolder + "]."); - } - - /** - * Returns true if the game is in progress and it is our turn; false - * otherwise. - */ - protected boolean isOurTurn () - { - TurnGameObject turnGame = (TurnGameObject)_gobj; - BodyObject self = (BodyObject)_ctx.getClient().getClientObject(); - return (turnGame.state == TurnGameObject.IN_PLAY && - turnGame.turnHolder.equals(self.username)); - } + public void turnDidChange (String turnHolder); } diff --git a/src/java/com/threerings/parlor/turn/TurnGameControllerDelegate.java b/src/java/com/threerings/parlor/turn/TurnGameControllerDelegate.java new file mode 100644 index 000000000..e8b2fa74c --- /dev/null +++ b/src/java/com/threerings/parlor/turn/TurnGameControllerDelegate.java @@ -0,0 +1,104 @@ +// +// $Id: TurnGameControllerDelegate.java,v 1.1 2002/02/12 06:57:30 mdb Exp $ + +package com.threerings.parlor.turn; + +import com.threerings.presents.dobj.AttributeChangedEvent; +import com.threerings.presents.dobj.AttributeChangeListener; + +import com.threerings.crowd.data.BodyObject; +import com.threerings.crowd.util.CrowdContext; + +import com.threerings.parlor.game.GameController; +import com.threerings.parlor.game.GameObject; + +/** + * Performs the client-side processing for a turn-based game. Games which + * wish to make use of these services must construct a delegate and call + * out to it at the appropriate times (see the method documentation for + * which methods should be called when). The game's controller must also + * implement the {@link TurnGameController} interface so that it can be + * notified when turn-based game events take place. + */ +public class TurnGameControllerDelegate + implements AttributeChangeListener +{ + /** + * Constructs a delegate which will call back to the supplied {@link + * TurnGameController} implementation wen turn-based game related + * things happen. + */ + public TurnGameControllerDelegate (TurnGameController tgctrl) + { + _tgctrl = tgctrl; + } + + /** + * This must be called from {@link GameController#init}. + */ + public void init (CrowdContext ctx) + { + _ctx = ctx; + } + + /** + * Returns true if the game is in progress and it is our turn; false + * otherwise. + */ + public boolean isOurTurn () + { + BodyObject self = (BodyObject)_ctx.getClient().getClientObject(); + return (_gameObj.state == GameObject.IN_PLAY && + _turnGame.getTurnHolder().equals(self.username)); + } + + /** + * This must be called from {@link GameController#willEnterPlace}. + */ + public void willEnterPlace (GameObject gobj) + { + // get a casted reference to the object + _gameObj = gobj; + _turnGame = (TurnGameObject)gobj; + _thfield = _turnGame.getTurnHolderFieldName(); + + // and add ourselves as a listener + gobj.addListener(this); + } + + /** + * This must be called from {@link GameController#didLeavePlace}. + */ + public void didLeavePlace (GameObject gobj) + { + // remove our listenership + gobj.removeListener(this); + + // clean up + _turnGame = null; + } + + // documentation inherited + public void attributeChanged (AttributeChangedEvent event) + { + // handle turn changes + if (event.getName().equals(_thfield)) { + _tgctrl.turnDidChange((String)event.getValue()); + } + } + + /** A reference to our client context. */ + protected CrowdContext _ctx; + + /** The turn game controller for whom we are delegating. */ + protected TurnGameController _tgctrl; + + /** A reference to our game object. */ + protected GameObject _gameObj; + + /** A casted reference to our game object as a turn game. */ + protected TurnGameObject _turnGame; + + /** The name of the turn holder field. */ + protected String _thfield; +} diff --git a/src/java/com/threerings/parlor/turn/TurnGameManager.java b/src/java/com/threerings/parlor/turn/TurnGameManager.java index 6866e1aaf..d90054c22 100644 --- a/src/java/com/threerings/parlor/turn/TurnGameManager.java +++ b/src/java/com/threerings/parlor/turn/TurnGameManager.java @@ -1,169 +1,48 @@ // -// $Id: TurnGameManager.java,v 1.4 2001/10/19 21:07:06 mdb Exp $ +// $Id: TurnGameManager.java,v 1.5 2002/02/12 06:57:30 mdb Exp $ package com.threerings.parlor.turn; -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.server.CrowdServer; - -import com.threerings.parlor.Log; import com.threerings.parlor.game.GameManager; -import com.threerings.parlor.util.MathUtil; /** - * Extends the basic game manager with support for turn-based games. + * A game manager that wishes to make use of the turn game services should + * implement this interface and create a {@link TurnGameManagerDelegate} + * which will perform the basic turn game processing and call back to the + * main manager via this interface. * *

The basic flow of a turn-based game is as follows: *

- * gameWillStart()
- * gameDidStart()
- *   setFirstTurnHolder()
- *   startTurn()
+ * GameManager.gameWillStart()
+ * GameManager.gameDidStart()
+ *   TurnGameManagerDelegate.setFirstTurnHolder()
+ *   TurnGameManagerDelegate.startTurn()
+ *     TurnGameManager.turnWillStart()
+ *   TurnGameManagerDelegate.endTurn()
+ *     TurnGameManager.turnDidEnd()
+ *   TurnGameManagerDelegate.setNextTurnHolder()
+ *   TurnGameManagerDelegate.startTurn()
+ *     ...
+ * GameManager.endGame()
  * 
*/ -public class TurnGameManager extends GameManager +public interface TurnGameManager { - // documentation inherited - protected void didStartup () - { - super.didStartup(); - - // obtain a casted reference to our turn game object - _turnGame = (TurnGameObject)_plobj; - } - - // documentation inherited - protected void gameDidStart () - { - super.gameDidStart(); - - // figure out who will be first - setFirstTurnHolder(); - - // and start the first turn if we should apparently do so - if (_turnIdx != -1) { - startTurn(); - } - } + /** + * Extending {@link GameManager} should automatically handle + * implementing this method. + */ + public String[] getPlayers (); /** - * This is called to determine whichi player will take the first - * turn. The default implementation chooses a player at random. + * Called when we are about to start the next turn. Implementations + * can do whatever pre-turn activities need to be done. */ - protected void setFirstTurnHolder () - { - // TODO: sort out a better random number generator and make it - // available via the parlor services - _turnIdx = MathUtil.random(_players.length); - } + public void turnWillStart (); /** - * Called to start the next turn. It calls the derived class to allow - * it to perform any pre-turn processing and then sets the turn holder - * that was configured either when the game started or when finishing - * up the last turn. This assumes that a valid turn holder has been - * assigned. If some pre-game preparation needs take place in a - * non-turn-based manner, this function should not be called until it - * is time to start the first turn. + * Called when the turn was ended. Implementations can perform any + * post-turn processing (like updating scores, etc.). */ - protected void startTurn () - { - // sanity check - if (_turnIdx < 0 || _turnIdx >= _players.length) { - Log.warning("startTurn() called with invalid turn index " + - "[turnIdx=" + _turnIdx + "]."); - // abort, abort - return; - } - - // let the derived class do their thing - turnWillStart(); - - // and set the turn indicator accordingly - _turnGame.setTurnHolder(_players[_turnIdx]); - } - - /** - * Called when we are about to start the next turn. Derived classes - * should override this and do whatever pre-turn activities need to be - * done. - */ - protected void turnWillStart () - { - } - - /** - * Called to end the turn. Whatever indication a game manager has that - * the turn has ended (probably the submission of a valid move of some - * sort by the turn holding player), it should call this function to - * cause this turn to end and the next to begin. - * - *

If the next turn should not be started immediately after this - * turn, the game manager should arrange for {@link - * #setNextTurnHolder} to set the {@link #_turnIdx} field to -1 which - * will cause us not to start the next turn. It can then call {@link - * #endGame} if the game is over or do whatever else it needs to do - * outside the context of the turn flow. To start things back up - * again it would set {@link #_turnIdx} to the next turn holder and - * call {@link #startTurn} itself. - */ - protected void endTurn () - { - // let the derived class know that the turn is over - turnDidEnd(); - - // figure out whose up next - setNextTurnHolder(); - - // and start the next turn if desired - if (_turnIdx != -1) { - startTurn(); - } - } - - /** - * Called when the turn was ended. Derived classes should override - * this and perform any post-turn processing (like updating scores, - * etc.). - */ - protected void turnDidEnd () - { - } - - /** - * This is called to determine which player will next hold the turn. - * The default implementation simply rotates through the players in - * order, but some games may need to mess with the turn from time to - * time. This should update the _turnIdx field, not set - * the turn holder field in the game object directly. - */ - protected void setNextTurnHolder () - { - // next! - _turnIdx = (_turnIdx + 1) % _players.length; - } - - /** - * Returns the index of the current turn holder as configured in the - * game object. - * - * @return the index into the players array of the current turn holder - * or -1 if there is no current turn holder. - */ - protected int getTurnHolderIndex () - { - for (int i = 0; i < _players.length; i++) { - if (_players[i].equals(_turnGame.turnHolder)) { - return i; - } - } - return -1; - } - - /** A reference to our game object. */ - protected TurnGameObject _turnGame; - - /** The offset into the _players array of the current turn holder or - * -1 if it's no one's turn. */ - protected int _turnIdx = -1; + public void turnDidEnd (); } diff --git a/src/java/com/threerings/parlor/turn/TurnGameManagerDelegate.java b/src/java/com/threerings/parlor/turn/TurnGameManagerDelegate.java new file mode 100644 index 000000000..ea99bfffa --- /dev/null +++ b/src/java/com/threerings/parlor/turn/TurnGameManagerDelegate.java @@ -0,0 +1,174 @@ +// +// $Id: TurnGameManagerDelegate.java,v 1.1 2002/02/12 06:57:30 mdb Exp $ + +package com.threerings.parlor.turn; + +import com.threerings.parlor.Log; +import com.threerings.parlor.game.GameManager; +import com.threerings.parlor.util.MathUtil; + +/** + * Performs the server-side turn-based game processing for a turn based + * game. Games which wish to make use of the turn services must call the + * following methods on the delegate at the appropriate times: + * + *

+ * init()
+ * gameDidStart()
+ * startTurn()
+ * endTurn()
+ * 
+ * + * They must also implement the {@link TurnGameManager} interface. + */ +public class TurnGameManagerDelegate +{ + /** + * Constructs a delegate that will manage the turn game state and call + * back to the supplied {@link TurnGameManager} implementation to let + * it in on the progression of the game. + */ + public TurnGameManagerDelegate (TurnGameManager tgmgr) + { + _tgmgr = tgmgr; + } + + /** + * This should be called from {@link GameManager#didStartup} to + * initialize the delegate. + */ + public void init (TurnGameObject turnGame) + { + _turnGame = turnGame; + } + + /** + * This should be called from {@link GameManager#gameDidStart} to let + * the turn delegate perform start of game processing. + */ + public void gameDidStart () + { + // grab the players array + _players = _tgmgr.getPlayers(); + + // figure out who will be first + setFirstTurnHolder(); + + // and start the first turn if we should apparently do so + if (_turnIdx != -1) { + startTurn(); + } + } + + /** + * This is called to determine whichi player will take the first + * turn. The default implementation chooses a player at random. + */ + protected void setFirstTurnHolder () + { + // TODO: sort out a better random number generator and make it + // available via the parlor services + _turnIdx = MathUtil.random(_players.length); + } + + /** + * Called to start the next turn. It calls {@link + * TurnGameManager#turnWillStart} to allow our owning manager to + * perform any pre-turn processing and then sets the turn holder that + * was configured either when the game started or when finishing up + * the last turn. This assumes that a valid turn holder has been + * assigned. If some pre-game preparation needs take place in a + * non-turn-based manner, this function should not be called until it + * is time to start the first turn. + */ + public void startTurn () + { + // sanity check + if (_turnIdx < 0 || _turnIdx >= _players.length) { + Log.warning("startTurn() called with invalid turn index " + + "[turnIdx=" + _turnIdx + "]."); + // abort, abort + return; + } + + // let the derived class do their thing + _tgmgr.turnWillStart(); + + // and set the turn indicator accordingly + _turnGame.setTurnHolder(_players[_turnIdx]); + } + + /** + * Called to end the turn. Whatever indication a game manager has that + * the turn has ended (probably the submission of a valid move of some + * sort by the turn holding player), it should call this function to + * cause this turn to end and the next to begin. + * + *

If the next turn should not be started immediately after this + * turn, the game manager should arrange for {@link + * #setNextTurnHolder} to set the {@link #_turnIdx} field to -1 which + * will cause us not to start the next turn. It can then call {@link + * #endGame} if the game is over or do whatever else it needs to do + * outside the context of the turn flow. To start things back up + * again it would set {@link #_turnIdx} to the next turn holder and + * call {@link #startTurn} itself. + */ + public void endTurn () + { + // let the manager know that the turn is over + _tgmgr.turnDidEnd(); + + // figure out whose up next + setNextTurnHolder(); + + // and start the next turn if desired + if (_turnIdx != -1) { + startTurn(); + } + } + + /** + * This is called to determine which player will next hold the turn. + * The default implementation simply rotates through the players in + * order, but some games may need to mess with the turn from time to + * time. This should update the _turnIdx field, not set + * the turn holder field in the game object directly. + */ + protected void setNextTurnHolder () + { + // next! + _turnIdx = (_turnIdx + 1) % _players.length; + } + + /** + * Returns the index of the current turn holder as configured in the + * game object. + * + * @return the index into the players array of the current turn holder + * or -1 if there is no current turn holder. + */ + protected int getTurnHolderIndex () + { + String holder = _turnGame.getTurnHolder(); + for (int i = 0; i < _players.length; i++) { + if (_players[i].equals(holder)) { + return i; + } + } + return -1; + } + + /** The game manager for which we are delegating. */ + protected TurnGameManager _tgmgr; + + /** A reference to our game object. */ + protected TurnGameObject _turnGame; + + /** Our own happy copy of the game manager's players array. I *love* + * not having fucking multiple inheritance. */ + protected String[] _players; + + /** The offset into the _players array of the current turn holder or + * -1 if it's no one's turn. */ + protected int _turnIdx = -1; +} diff --git a/src/java/com/threerings/parlor/turn/TurnGameObject.dobj b/src/java/com/threerings/parlor/turn/TurnGameObject.dobj deleted file mode 100644 index c8657fba0..000000000 --- a/src/java/com/threerings/parlor/turn/TurnGameObject.dobj +++ /dev/null @@ -1,17 +0,0 @@ -// -// $Id: TurnGameObject.dobj,v 1.4 2002/02/08 23:55:25 mdb Exp $ - -package com.threerings.parlor.turn; - -import com.threerings.parlor.game.GameObject; - -/** - * Extends the basic game object with support for turn-based games. - */ -public class TurnGameObject extends GameObject -{ - /** The username of the player who is currently taking their turn in - * this turn-based game or null if no user currently holds the - * turn. */ - public String turnHolder; -} diff --git a/src/java/com/threerings/parlor/turn/TurnGameObject.java b/src/java/com/threerings/parlor/turn/TurnGameObject.java index c20847269..670440fa4 100644 --- a/src/java/com/threerings/parlor/turn/TurnGameObject.java +++ b/src/java/com/threerings/parlor/turn/TurnGameObject.java @@ -1,41 +1,31 @@ // -// $Id: TurnGameObject.java,v 1.1 2002/02/08 23:55:25 mdb Exp $ +// $Id: TurnGameObject.java,v 1.2 2002/02/12 06:57:30 mdb Exp $ package com.threerings.parlor.turn; -import com.threerings.parlor.game.GameObject; - /** - * Extends the basic game object with support for turn-based games. + * Games that wish to support turn-based play must implement this + * interface with their {@link GameObject}. */ -public class TurnGameObject extends GameObject +public interface TurnGameObject { - /** The field name of the turnHolder field. */ - public static final String TURN_HOLDER = "turnHolder"; + /** + * Returns the distributed object field name of the + * turnHolder field in the object that implements this + * interface. + */ + public String getTurnHolderFieldName (); - /** The username of the player who is currently taking their turn in - * this turn-based game or null if no user currently holds the - * turn. */ - public String turnHolder; + /** + * Returns the username of the player who is currently taking their + * turn in this turn-based game or null if no user currently holds the + * turn. + */ + public String getTurnHolder (); /** * Requests that the turnHolder field be set to the specified * value. */ - public void setTurnHolder (String turnHolder) - { - requestAttributeChange(TURN_HOLDER, turnHolder); - } - - /** - * Requests that the turnHolder field be set to the - * specified value and immediately updates the state of the object - * to reflect the change. This should only be called on the - * server and only then if you know what you're doing. - */ - public void setTurnHolderImmediate (String turnHolder) - { - this.turnHolder = turnHolder; - requestAttributeChange(TURN_HOLDER, turnHolder); - } + public void setTurnHolder (String turnHolder); }