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);
}