From fd87ec437aa78f027d9afb259d1dbbb0986b01d1 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Sun, 14 Apr 2002 00:26:05 +0000 Subject: [PATCH] Moved game reset processing into main game framework. Also modified game start processing on the server so that we don't want for the IN_PLAY attribute change to be processed before calling gameDidStart() because we don't want to do that when resetting the game (because someone could come along and end the game in between gameWillStart() and gameDidStart() which would be annoying and bad), so we need to be consistent and run straight through both when starting the game for the first time and when resetting it. This means that game managers that really need to wait until their events are processed and do some game start processing at that point will have to listen for the IN_PLAY transition themselves *and* they'll have to be aware that someone could have come along and ended the game in between the call to gameDidStart() and the dispatch of the IN_PLAY event. Sketchy, but unavoidable. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1235 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../parlor/game/GameController.java | 58 ++++++++++++++- .../parlor/game/GameControllerDelegate.java | 11 ++- .../threerings/parlor/game/GameManager.java | 70 ++++++++++++++++--- .../parlor/game/GameManagerDelegate.java | 20 +++++- 4 files changed, 145 insertions(+), 14 deletions(-) diff --git a/src/java/com/threerings/parlor/game/GameController.java b/src/java/com/threerings/parlor/game/GameController.java index d7db4ce4c..215d2d05f 100644 --- a/src/java/com/threerings/parlor/game/GameController.java +++ b/src/java/com/threerings/parlor/game/GameController.java @@ -1,5 +1,5 @@ // -// $Id: GameController.java,v 1.9 2002/02/13 03:21:28 mdb Exp $ +// $Id: GameController.java,v 1.10 2002/04/14 00:26:05 mdb Exp $ package com.threerings.parlor.game; @@ -87,6 +87,42 @@ public abstract class GameController extends PlaceController _gobj = null; } + /** + * Returns whether the game is over. + */ + public boolean isGameOver () + { + return (_gameOver || _gobj.state == GameObject.GAME_OVER); + } + + /** + * Sets the client game over override. This is used in situations + * where we determine that the game is over before the server has + * informed us of such. + */ + public void setGameOver (boolean gameOver) + { + _gameOver = gameOver; + } + + /** + * Calls {@link #gameWillReset}, ends the current game (locally, it + * does not tell the server to end the game), and waits to receive a + * reset notification (which is simply an event setting the game state + * to IN_PLAY even though it's already set to + * IN_PLAY) from the server which will start up a new + * game. Derived classes should override {@link #gameWillReset} to + * perform any game-specific animations. + */ + public void resetGame () + { + // let derived classes do their thing + gameWillReset(); + + // end the game until we receive a new board + setGameOver(true); + } + /** * Handles basic game controller action events. Derived classes should * be sure to call super.handleAction for events they @@ -164,6 +200,21 @@ public abstract class GameController extends PlaceController }); } + /** + * Called to give derived classes a chance to display animations, send + * a final packet, or do any other business they care to do when the + * game is about to reset. + */ + protected void gameWillReset () + { + // let our delegates do their business + applyToDelegates(new DelegateOp() { + public void apply (PlaceControllerDelegate delegate) { + ((GameControllerDelegate)delegate).gameWillReset(); + } + }); + } + /** A reference to the active parlor context. */ protected ParlorContext _ctx; @@ -173,4 +224,9 @@ public abstract class GameController extends PlaceController /** A reference to the game object for the game that we're * controlling. */ protected GameObject _gobj; + + /** A local flag overriding the game over state for situations where + * the client knows the game is over before the server has + * transitioned the game object accordingly. */ + protected boolean _gameOver; } diff --git a/src/java/com/threerings/parlor/game/GameControllerDelegate.java b/src/java/com/threerings/parlor/game/GameControllerDelegate.java index 60c004ef6..4dba3da31 100644 --- a/src/java/com/threerings/parlor/game/GameControllerDelegate.java +++ b/src/java/com/threerings/parlor/game/GameControllerDelegate.java @@ -1,5 +1,5 @@ // -// $Id: GameControllerDelegate.java,v 1.1 2002/02/13 03:21:28 mdb Exp $ +// $Id: GameControllerDelegate.java,v 1.2 2002/04/14 00:26:05 mdb Exp $ package com.threerings.parlor.game; @@ -44,4 +44,13 @@ public class GameControllerDelegate extends PlaceControllerDelegate public void gameWasCancelled () { } + + /** + * Called to give derived classes a chance to display animations, send + * a final packet, or do any other business they care to do when the + * game is about to reset. + */ + public void gameWillReset () + { + } } diff --git a/src/java/com/threerings/parlor/game/GameManager.java b/src/java/com/threerings/parlor/game/GameManager.java index daec9b8f8..492f7b225 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.23 2002/02/20 23:35:42 mdb Exp $ +// $Id: GameManager.java,v 1.24 2002/04/14 00:26:05 mdb Exp $ package com.threerings.parlor.game; @@ -173,10 +173,8 @@ public class GameManager extends PlaceManager // transition the game to started _gameobj.setState(GameObject.IN_PLAY); - // wait until we hear the game state transition on the game object - // to invoke our game did start code so that we can be sure that - // any events dispatched on the game object prior to or during the - // call to startGame() have been dispatched + // do post-start processing + gameDidStart(); } /** @@ -199,7 +197,7 @@ public class GameManager extends PlaceManager * Called after the game start notification was dispatched. Derived * classes can override this to put whatever wheels they might need * into motion now that the game is started (if anything other than - * issuing the game start notification is necessary). + * transitioning the game to IN_PLAY is necessary). */ protected void gameDidStart () { @@ -246,16 +244,66 @@ public class GameManager extends PlaceManager // calculate ratings and all that... } + /** + * Called when the game is to be reset to its starting state in + * preparation for a new game without actually ending the current + * game. It calls {@link #gameWillReset} and {@link #gameDidReset}. + * The standard game start processing ({@link #gameWillStart} and + * {@link gameDidStart}) will also be called (in between the calls to + * will and did reset). Derived classes should override one or both of + * the calldown functions (rather than this function) if they need to + * do things before or after the game resets. + */ + public void resetGame () + { + // let the derived class do its pre-reset stuff + gameWillReset(); + + // do the standard game start processing + gameWillStart(); + _gameobj.setState(GameObject.IN_PLAY); + gameDidStart(); + + // let the derived class do its post-reset stuff + gameDidReset(); + } + + /** + * Called when the game is about to reset, but before the board has + * been re-initialized or any other clearing out of game data has + * taken place. Derived classes should override this if they need to + * perform some pre-reset activities. + */ + protected void gameWillReset () + { + // let our delegates do their business + applyToDelegates(new DelegateOp() { + public void apply (PlaceManagerDelegate delegate) { + ((GameManagerDelegate)delegate).gameWillReset(); + } + }); + } + + /** + * Called after the game has been reset. Derived classes can override + * this to put whatever wheels they might need into motion now that + * the game is reset. + */ + protected void gameDidReset () + { + // let our delegates do their business + applyToDelegates(new DelegateOp() { + public void apply (PlaceManagerDelegate delegate) { + ((GameManagerDelegate)delegate).gameDidReset(); + } + }); + } + // documentation inherited public void attributeChanged (AttributeChangedEvent event) { if (event.getName().equals(GameObject.STATE)) { switch (event.getIntValue()) { - case GameObject.IN_PLAY: - // now we do our start of game processing - gameDidStart(); - break; - case GameObject.GAME_OVER: // now we do our end of game processing gameDidEnd(); diff --git a/src/java/com/threerings/parlor/game/GameManagerDelegate.java b/src/java/com/threerings/parlor/game/GameManagerDelegate.java index 5059b1bf3..c5d46f5ad 100644 --- a/src/java/com/threerings/parlor/game/GameManagerDelegate.java +++ b/src/java/com/threerings/parlor/game/GameManagerDelegate.java @@ -1,5 +1,5 @@ // -// $Id: GameManagerDelegate.java,v 1.1 2002/02/13 03:21:28 mdb Exp $ +// $Id: GameManagerDelegate.java,v 1.2 2002/04/14 00:26:05 mdb Exp $ package com.threerings.parlor.game; @@ -40,4 +40,22 @@ public class GameManagerDelegate extends PlaceManagerDelegate public void gameDidEnd () { } + + /** + * Called when the game is about to reset, but before any other + * clearing out of game data has taken place. Derived classes should + * override this if they need to perform some pre-reset activities. + */ + public void gameWillReset () + { + } + + /** + * Called after the game has been reset. Derived classes can override + * this to put whatever wheels they might need into motion now that + * the game is reset. + */ + public void gameDidReset () + { + } }