From eec3ad81cad42232032c4d901f8aab16b40be661 Mon Sep 17 00:00:00 2001 From: Andy Janata Date: Mon, 23 Jan 2012 13:20:15 -0800 Subject: [PATCH] - make currentGames be a list instead of a single object, just in case I do multiple games later - add event handlers for leave and start game buttons - leave game button works --- WebContent/js/cah.ajax.handlers.js | 14 ++++++- WebContent/js/cah.constants.js | 5 +++ WebContent/js/cah.game.js | 42 ++++++++++++++++--- WebContent/js/cah.js | 7 ++-- src/net/socialgamer/cah/Constants.java | 4 ++ src/net/socialgamer/cah/data/Game.java | 13 ++++-- .../socialgamer/cah/handlers/Handlers.java | 1 + .../cah/handlers/LeaveGameHandler.java | 39 +++++++++++++++++ 8 files changed, 112 insertions(+), 13 deletions(-) create mode 100644 src/net/socialgamer/cah/handlers/LeaveGameHandler.java diff --git a/WebContent/js/cah.ajax.handlers.js b/WebContent/js/cah.ajax.handlers.js index 6bc1501..e8010b3 100644 --- a/WebContent/js/cah.ajax.handlers.js +++ b/WebContent/js/cah.ajax.handlers.js @@ -86,5 +86,17 @@ cah.ajax.SuccessHandlers[cah.$.AjaxOperation.JOIN_GAME] = function(data) { cah.ajax.SuccessHandlers[cah.$.AjaxOperation.CREATE_GAME] = cah.ajax.SuccessHandlers[cah.$.AjaxOperation.JOIN_GAME]; cah.ajax.SuccessHandlers[cah.$.AjaxOperation.GET_GAME_INFO] = function(data) { - cah.currentGame.updateGameStatus(data); + var game = cah.currentGames[data[cah.$.AjaxResponse.GAME_INFO][cah.$.GameInfo.ID]]; + if (game) { + game.updateGameStatus(data); + } +}; + +cah.ajax.SuccessHandlers[cah.$.AjaxOperation.LEAVE_GAME] = function(data) { + var game = cah.currentGames[data[cah.$.AjaxResponse.GAME_ID]]; + if (game) { + game.dispose(); + } + cah.GameList.instance.show(); + cah.GameList.instance.update(); }; diff --git a/WebContent/js/cah.constants.js b/WebContent/js/cah.constants.js index 9069c0f..648952b 100644 --- a/WebContent/js/cah.constants.js +++ b/WebContent/js/cah.constants.js @@ -15,6 +15,7 @@ cah.$.AjaxOperation.REGISTER = "register"; cah.$.AjaxOperation.CREATE_GAME = "create_game"; cah.$.AjaxOperation.CHAT = "chat"; cah.$.AjaxOperation.NAMES = "names"; +cah.$.AjaxOperation.LEAVE_GAME = "leave_game"; cah.$.AjaxRequest = function() { // pass @@ -110,6 +111,7 @@ cah.$.GamePlayerStatus = function() { // pass }; cah.$.GamePlayerStatus.prototype.dummy = undefined; +cah.$.GamePlayerStatus.HOST = "host"; cah.$.GamePlayerStatus.IDLE = "idle"; cah.$.GamePlayerStatus.PLAYING = "playing"; cah.$.GamePlayerStatus.JUDGE = "judge"; @@ -118,6 +120,7 @@ cah.$.GamePlayerStatus_msg = {}; cah.$.GamePlayerStatus_msg['playing'] = "Playing"; cah.$.GamePlayerStatus_msg['idle'] = ""; cah.$.GamePlayerStatus_msg['judging'] = "Judging"; +cah.$.GamePlayerStatus_msg['host'] = "Host"; cah.$.GamePlayerStatus_msg['judge'] = "Judge"; cah.$.GameState = function() { @@ -136,8 +139,10 @@ cah.$.LongPollEvent = function() { cah.$.LongPollEvent.prototype.dummy = undefined; cah.$.LongPollEvent.NOOP = "noop"; cah.$.LongPollEvent.GAME_REFRESH = "game_refresh"; +cah.$.LongPollEvent.GAME_PLAYER_LEAVE = "game_player_leave"; cah.$.LongPollEvent.NEW_PLAYER = "new_player"; cah.$.LongPollEvent.PLAYER_LEAVE = "player_leave"; +cah.$.LongPollEvent.GAME_PLAYER_JOIN = "game_player_join"; cah.$.LongPollEvent.CHAT = "chat"; cah.$.LongPollResponse = function() { diff --git a/WebContent/js/cah.game.js b/WebContent/js/cah.game.js index 8caf502..b375155 100644 --- a/WebContent/js/cah.game.js +++ b/WebContent/js/cah.game.js @@ -54,6 +54,9 @@ cah.Game = function(id) { * @private */ this.hand_ = Array(); + + $("#leave_game").click(cah.bind(this, this.leaveGameClick_)); + $("#start_game").click(cah.bind(this, this.startGameClick_)); }; /** @@ -65,8 +68,9 @@ cah.Game = function(id) { cah.Game.joinGame = function(gameId) { cah.Ajax.build(cah.$.AjaxOperation.GET_GAME_INFO).withGameId(gameId).run(); cah.GameList.instance.hide(); - cah.currentGame = new cah.Game(gameId); - cah.currentGame.insertIntoDocument(); + var game = new cah.Game(gameId); + cah.currentGames[gameId] = game; + game.insertIntoDocument(); }; /** @@ -106,7 +110,7 @@ cah.Game.prototype.dealtCard = function(card) { cah.Game.prototype.insertIntoDocument = function() { $("#main_holder").empty().append(this.element_); $("#info_area").empty().append(this.scoreboardElement_); - $("#leave_game").removeClass("hide"); + $("#leave_game").show(); // TODO display a loading animation }; @@ -119,9 +123,9 @@ cah.Game.prototype.insertIntoDocument = function() { cah.Game.prototype.updateGameStatus = function(data) { if (data[cah.$.AjaxResponse.GAME_INFO][cah.$.GameInfo.HOST] == cah.nickname && data[cah.$.AjaxResponse.GAME_INFO][cah.$.GameInfo.STATE] == cah.$.GameState.LOBBY) { - $("#start_game").removeClass("hide"); + $("#start_game").show(); } else { - $("#start_game").addClass("hide"); + $("#start_game").hide(); } var playerInfos = data[cah.$.AjaxResponse.PLAYER_INFO]; @@ -139,6 +143,34 @@ cah.Game.prototype.updateGameStatus = function(data) { } }; +/** + * Event handler for leave game button. + * + * @private + */ +cah.Game.prototype.leaveGameClick_ = function() { + cah.Ajax.build(cah.$.AjaxOperation.LEAVE_GAME).withGameId(this.id_).run(); +}; + +/** + * Event handler for start game button. + * + * @private + */ +cah.Game.prototype.startGameClick_ = function() { + // TODO +}; + +/** + * Free resources used by this game and remove from the document. + */ +cah.Game.prototype.dispose = function() { + $(this.element_).remove(); + $(this.scoreboardElement_).remove(); + $("#leave_game").hide(); + $("#start_game").hide(); +}; + // /** // * Remove a card from the hand. // * diff --git a/WebContent/js/cah.js b/WebContent/js/cah.js index a0e0b09..d4b4467 100644 --- a/WebContent/js/cah.js +++ b/WebContent/js/cah.js @@ -10,12 +10,11 @@ cah.DEBUG = true; cah.nickname = ""; /** - * The current game this client is playing in. This may be a list later if I expand to multiple - * concurrent game support. + * The games this client is playing in. Key is game id. * - * @type {cah.Game} + * @type {Object} */ -cah.currentGame = undefined; +cah.currentGames = {}; /** * Binds a function to a "this object". Result is a new function that will do the right thing across diff --git a/src/net/socialgamer/cah/Constants.java b/src/net/socialgamer/cah/Constants.java index 70438a8..f44d427 100644 --- a/src/net/socialgamer/cah/Constants.java +++ b/src/net/socialgamer/cah/Constants.java @@ -58,6 +58,7 @@ public class Constants { GAME_LIST("games"), GET_GAME_INFO("get_game_info"), JOIN_GAME("join_game"), + LEAVE_GAME("leave_game"), LOG_OUT("logout"), NAMES("names"), REGISTER("register"); @@ -167,6 +168,8 @@ public class Constants { public enum LongPollEvent { CHAT("chat"), + GAME_PLAYER_JOIN("game_player_join"), + GAME_PLAYER_LEAVE("game_player_leave"), GAME_REFRESH("game_refresh"), NEW_PLAYER("new_player"), NOOP("noop"), @@ -270,6 +273,7 @@ public class Constants { } public enum GamePlayerStatus implements Localizable { + HOST("host", "Host"), IDLE("idle", ""), JUDGE("judge", "Judge"), JUDGING("judging", "Judging"), diff --git a/src/net/socialgamer/cah/data/Game.java b/src/net/socialgamer/cah/data/Game.java index e2978b2..d4bd38d 100644 --- a/src/net/socialgamer/cah/data/Game.java +++ b/src/net/socialgamer/cah/data/Game.java @@ -10,6 +10,7 @@ import net.socialgamer.cah.Constants.GameInfo; import net.socialgamer.cah.Constants.GamePlayerInfo; import net.socialgamer.cah.Constants.GamePlayerStatus; import net.socialgamer.cah.Constants.GameState; +import net.socialgamer.cah.Constants.LongPollEvent; import net.socialgamer.cah.Constants.LongPollResponse; import net.socialgamer.cah.Constants.ReturnableData; import net.socialgamer.cah.data.GameManager.GameId; @@ -73,15 +74,17 @@ public class Game { } final HashMap data = new HashMap(); - data.put(LongPollResponse.EVENT, "game_player_join"); + data.put(LongPollResponse.EVENT, LongPollEvent.GAME_PLAYER_JOIN.toString()); data.put(LongPollResponse.GAME_ID, id); data.put(LongPollResponse.NICKNAME, user.getNickname()); broadcastToPlayers(MessageType.GAME_PLAYER_EVENT, data); } /** + * Remove a player from the game. * * @param user + * Player to remove from the game. * @return True if {@code user} was the last player in the game. */ public boolean removePlayer(final User user) { @@ -93,7 +96,7 @@ public class Game { iterator.remove(); user.leaveGame(this); final HashMap data = new HashMap(); - data.put(LongPollResponse.EVENT, "game_player_leave"); + data.put(LongPollResponse.EVENT, LongPollEvent.GAME_PLAYER_LEAVE.toString()); data.put(LongPollResponse.GAME_ID, id); data.put(LongPollResponse.NICKNAME, user.getNickname()); broadcastToPlayers(MessageType.GAME_PLAYER_EVENT, data); @@ -160,7 +163,11 @@ public class Game { playerInfo.put(GamePlayerInfo.NAME, player.getUser().getNickname()); playerInfo.put(GamePlayerInfo.SCORE, player.getScore()); // TODO fix this once we actually have gameplay logic - playerInfo.put(GamePlayerInfo.STATUS, GamePlayerStatus.PLAYING.toString()); + if (state == GameState.LOBBY && host == player) { + playerInfo.put(GamePlayerInfo.STATUS, GamePlayerStatus.HOST.toString()); + } else { + playerInfo.put(GamePlayerInfo.STATUS, GamePlayerStatus.IDLE.toString()); + } info.add(playerInfo); } } diff --git a/src/net/socialgamer/cah/handlers/Handlers.java b/src/net/socialgamer/cah/handlers/Handlers.java index 0e2a2c1..45805cd 100644 --- a/src/net/socialgamer/cah/handlers/Handlers.java +++ b/src/net/socialgamer/cah/handlers/Handlers.java @@ -16,6 +16,7 @@ public class Handlers { LIST.put(GameListHandler.OP, GameListHandler.class); LIST.put(GetGameInfoHandler.OP, GetGameInfoHandler.class); LIST.put(JoinGameHandler.OP, JoinGameHandler.class); + LIST.put(LeaveGameHandler.OP, LeaveGameHandler.class); LIST.put(LogoutHandler.OP, LogoutHandler.class); LIST.put(NamesHandler.OP, NamesHandler.class); LIST.put(RegisterHandler.OP, RegisterHandler.class); diff --git a/src/net/socialgamer/cah/handlers/LeaveGameHandler.java b/src/net/socialgamer/cah/handlers/LeaveGameHandler.java new file mode 100644 index 0000000..1b1edc0 --- /dev/null +++ b/src/net/socialgamer/cah/handlers/LeaveGameHandler.java @@ -0,0 +1,39 @@ +package net.socialgamer.cah.handlers; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpSession; + +import net.socialgamer.cah.Constants.AjaxOperation; +import net.socialgamer.cah.Constants.AjaxResponse; +import net.socialgamer.cah.Constants.ReturnableData; +import net.socialgamer.cah.RequestWrapper; +import net.socialgamer.cah.data.Game; +import net.socialgamer.cah.data.GameManager; +import net.socialgamer.cah.data.User; + +import com.google.inject.Inject; + + +public class LeaveGameHandler extends GameHandler { + + public static final String OP = AjaxOperation.LEAVE_GAME.toString(); + + @Inject + public LeaveGameHandler(final GameManager gameManager) { + super(gameManager); + } + + @Override + public Map handle(final RequestWrapper request, + final HttpSession session, final User user, final Game game) { + final Map data = new HashMap(); + + game.removePlayer(user); + // Return the game ID back to the client. It should in theory be able to figure out which leave + // was successfull but whatever. + data.put(AjaxResponse.GAME_ID, game.getId()); + return data; + } +}