SourceForge: tilescape/tilescape: changeset 21:d70676016431
Create/Join/Leave
author"Juha Litola <juha.litola@iki.fi>"
Wed Apr 01 22:00:38 2009 +0300 (7 months ago)
changeset 21d70676016431
parent 2072985b11b0df
child 226a6d2069d68c
child 23c901f4bf86cc
Create/Join/Leave
src/main/scala/net/inapt/tilescape/comet/Chat.scala
src/main/scala/net/inapt/tilescape/comet/GameActor.scala
src/main/scala/net/inapt/tilescape/comet/GameServer.scala
src/main/scala/net/inapt/tilescape/model/Game.scala
src/main/scala/net/inapt/tilescape/model/User.scala
src/main/webapp/game.html
     1.1 --- a/src/main/scala/net/inapt/tilescape/comet/Chat.scala	Sun Mar 29 23:16:41 2009 +0300
     1.2 +++ b/src/main/scala/net/inapt/tilescape/comet/Chat.scala	Wed Apr 01 22:00:38 2009 +0300
     1.3 @@ -43,6 +43,9 @@
     1.4  
     1.5    private lazy val infoId = uniqueId + "_info"
     1.6  
     1.7 +	private lazy val user = {
     1.8 +		User.currentUser.open_!
     1.9 +	}
    1.10    private lazy val server = {
    1.11      val ret = ChatServer
    1.12      ret ! ChatServerAdd(this)
     2.1 --- a/src/main/scala/net/inapt/tilescape/comet/GameActor.scala	Sun Mar 29 23:16:41 2009 +0300
     2.2 +++ b/src/main/scala/net/inapt/tilescape/comet/GameActor.scala	Wed Apr 01 22:00:38 2009 +0300
     2.3 @@ -29,8 +29,13 @@
     2.4  
     2.5    private lazy val usersId = uniqueId + "_users"
     2.6    private lazy val gamesId = uniqueId + "_games"
     2.7 +  private lazy val statusId = uniqueId + "_status"
     2.8 +  private lazy val errorId = "game_errors"
     2.9  
    2.10 -	lazy val user = User.currentUser.open_!
    2.11 +
    2.12 +	private var _user : User = _
    2.13 +
    2.14 +	def user = _user
    2.15  
    2.16    private lazy val server = {
    2.17      val ret = GameServer
    2.18 @@ -46,9 +51,27 @@
    2.19  			partialUpdate(AppendHtml(usersId, userLine(u)))
    2.20  		case AnnounceNewGame(g) =>
    2.21  			partialUpdate(AppendHtml(gamesId, gameLine(g)))
    2.22 -			Log.info("There is new game "+g)
    2.23 +			sendChatMessage(g.chatRoom, user.email.is+" created new game '"+g.name+"'")
    2.24 +			updateStatus
    2.25 +		case AnnounceNewPlayer(g, user) =>
    2.26 +			sendChatMessage(g.chatRoom, user.email.is+" joined '"+g.name+"'")
    2.27 +			updateStatus
    2.28 +		case AnnounceLeftPlayer(g, user) =>
    2.29 +			sendChatMessage(g.chatRoom, user.email.is+" left '"+g.name+"'")
    2.30 +			updateStatus
    2.31 +		case GameServerError(msg) =>
    2.32 +			partialUpdate(SetHtml(errorId, <div id="error">{msg}</div>))
    2.33    }
    2.34  
    2.35 +	private def updateStatus {
    2.36 +		partialUpdate(SetHtml(statusId, gameStatus))
    2.37 +	}
    2.38 +
    2.39 +	private def sendChatMessage(name : String, msg: String) {
    2.40 +		Log.info("Sending message "+msg+" to chat server")
    2.41 +		ChatServer ! ChatServerMsg(name, msg)
    2.42 +	}
    2.43 +
    2.44  	private def invocationFunction(s : String) = "tilescapeReceiveServerMessage('"+urlEncode(s)+"')"
    2.45  
    2.46    override lazy val fixedRender: Box[NodeSeq] = {
    2.47 @@ -58,14 +81,21 @@
    2.48  	override def render = {
    2.49  		bind("userList" -> userList,
    2.50  				 "gameList" -> gameList,
    2.51 -					"create" -> a(Text("Create game")) {
    2.52 -						Log.info("Create pressed")
    2.53 -						server ! CreateGame(this, "Test game")
    2.54 -						Noop
    2.55 -				 }
    2.56 -				 )
    2.57 +				 "status" -> gameStatus,
    2.58 +				 "create" -> a(Text("Create game")) {
    2.59 +				server ! CreateGame(this, "Test game")
    2.60 +				Noop
    2.61 +			}
    2.62 +		)
    2.63  	}
    2.64  
    2.65 +	private def gameStatus = {
    2.66 +		user.currentGame match {
    2.67 +			case Some(game) =>
    2.68 +				<span id={statusId}>You are playing {game} {a("(Leave)"){ jsLeaveGame(game) } }</span>
    2.69 +			case None => <span id={statusId}>You are not currently playing.</span>
    2.70 +		}
    2.71 +	}
    2.72  	private def userList = {
    2.73  		server !? GetUserList match {
    2.74  			case g : UserList =>
    2.75 @@ -82,20 +112,31 @@
    2.76  		}
    2.77  	}
    2.78  
    2.79 -	private def gameLine(game : Game) = (<li>{game.name}</li>)
    2.80 +	private def gameLine(game : Game) = (
    2.81 +		<li>{a(Text(game.name)) {jsJoinGame(game)}}</li>
    2.82 +	)
    2.83  
    2.84  	override def localSetup() {
    2.85 -		user.register(this)
    2.86 +		User.currentUser match {
    2.87 +			case Full(x) => _user = x
    2.88 +			case _ =>
    2.89 +		}
    2.90  		super.localSetup()
    2.91  	}
    2.92  
    2.93    override def localShutdown() {
    2.94      GameServer ! GameServerRemove(this)
    2.95 -		user.unregister(this)
    2.96      super.localShutdown()
    2.97    }
    2.98 +	private def errorToJS(e : GameServerError) = {
    2.99 +		AppendHtml(errorId, Text(e.msg))
   2.100 +	}
   2.101  
   2.102  	def jsSendMessage(msg: String) = { sendMessage(msg); Noop }
   2.103  
   2.104    def sendMessage(msg: String) = server ! GameServerMsg(this, msg.trim)
   2.105 +
   2.106 +	def jsJoinGame(game : Game) = { server ! JoinGame(this, game) ; Noop }
   2.107 +
   2.108 +	def jsLeaveGame(game : Game) = { server ! LeaveGame(this, game) ; Noop }
   2.109  }
   2.110 \ No newline at end of file
     3.1 --- a/src/main/scala/net/inapt/tilescape/comet/GameServer.scala	Sun Mar 29 23:16:41 2009 +0300
     3.2 +++ b/src/main/scala/net/inapt/tilescape/comet/GameServer.scala	Wed Apr 01 22:00:38 2009 +0300
     3.3 @@ -27,7 +27,6 @@
     3.4  				val m = GameMessage(sender, msg)
     3.5  				messages ::= m
     3.6  				listeners.foreach (_ ! GameServerUpdate(List(m)))
     3.7 -				Log.info("Passing message "+msg)
     3.8  
     3.9  			case GetUserList =>
    3.10  				reply(UserList(listeners.map(_.user)))
    3.11 @@ -36,9 +35,28 @@
    3.12  				reply(GameList(games))
    3.13  
    3.14  			case CreateGame(sender, name) =>
    3.15 -				val g = new Game(name, new ClientRuleSet, sender.user)
    3.16 -				games ::= g
    3.17 -				listeners.foreach (_ ! AnnounceNewGame(g))
    3.18 +				if (sender.user.isPlaying) {
    3.19 +					sender ! GameServerError("You are already in game")
    3.20 +				} else {
    3.21 +					val g = new Game(name, new ClientRuleSet, sender.user)
    3.22 +					sender.user.register(g)
    3.23 +					games ::= g
    3.24 +					listeners.foreach (_ ! AnnounceNewGame(g))
    3.25 +				}
    3.26 +
    3.27 +			case JoinGame(sender, game) =>
    3.28 +				if (sender.user.isPlaying) {
    3.29 +					sender ! GameServerError("You are already in game")
    3.30 +				} else {
    3.31 +					game.join(sender.user)
    3.32 +					sender.user.register(game)
    3.33 +					listeners.foreach (_ ! AnnounceNewPlayer(game, sender.user))
    3.34 +				}
    3.35 +
    3.36 +			case LeaveGame(sender, game) =>
    3.37 +				game.leave(sender.user)
    3.38 +				sender.user.unregister(game)
    3.39 +				listeners.foreach (_ ! AnnounceLeftPlayer(game, sender.user) )
    3.40  
    3.41        case GameServerAdd(me) =>
    3.42  				me ! GameServerUpdate(messages)
    3.43 @@ -55,6 +73,7 @@
    3.44    this.start
    3.45  }
    3.46  
    3.47 +case class GameServerError(msg: String)
    3.48  case class GameMessage(sender : Actor, msg: String)
    3.49  case class GameServerMsg(sender: GameActor, msg: String)
    3.50  case class GameServerUpdate(msg: List[GameMessage])
    3.51 @@ -67,6 +86,8 @@
    3.52  case class GetGameList
    3.53  case class CreateGame(sender : GameActor, name : String)
    3.54  case class AnnounceNewGame(game : Game)
    3.55 +case class AnnounceNewPlayer(game : Game, user : User)
    3.56 +case class AnnounceLeftPlayer(game : Game, user : User)
    3.57  case class JoinGame(sender : GameActor, game: Game)
    3.58  case class LeaveGame(sender : GameActor, game: Game)
    3.59  
     4.1 --- a/src/main/scala/net/inapt/tilescape/model/Game.scala	Sun Mar 29 23:16:41 2009 +0300
     4.2 +++ b/src/main/scala/net/inapt/tilescape/model/Game.scala	Wed Apr 01 22:00:38 2009 +0300
     4.3 @@ -28,6 +28,7 @@
     4.4  class Game (val name : String, val ruleset : RuleSet, var initiator : User) {
     4.5  	private var players = List[User]()
     4.6  	private var status = GameStatus.PreGame
     4.7 +	val chatRoom = "game"
     4.8  
     4.9  	def join(player : User) { players ::= player }
    4.10  
     5.1 --- a/src/main/scala/net/inapt/tilescape/model/User.scala	Sun Mar 29 23:16:41 2009 +0300
     5.2 +++ b/src/main/scala/net/inapt/tilescape/model/User.scala	Wed Apr 01 22:00:38 2009 +0300
     5.3 @@ -4,6 +4,8 @@
     5.4  import _root_.net.liftweb.util._
     5.5  
     5.6  import net.inapt.tilescape.comet.GameActor
     5.7 +import net.inapt.tilescape.comet.Chat
     5.8 +import net.inapt.tilescape.comet.ChatLine
     5.9  
    5.10  /**
    5.11   * The singleton that has methods for accessing the database
    5.12 @@ -26,10 +28,20 @@
    5.13  class User extends MegaProtoUser[User] {
    5.14    def getSingleton = User // what's the "meta" server
    5.15  
    5.16 -	private var games = List[GameActor]()
    5.17 +	private var game : Option[Game] = None
    5.18  
    5.19 -	def register(game : GameActor) { games ::= game }
    5.20 +	private var chats = List[Chat]()
    5.21  
    5.22 -	def unregister(game : GameActor) { games -= game }
    5.23 +	def register(g : Game) { 
    5.24 +		Log.info("Registering "+game+" to "+this)
    5.25 +		game = Full(g)
    5.26 +	}
    5.27  
    5.28 -}
    5.29 +	def currentGame = game
    5.30 +
    5.31 +	def isPlaying = ! game.isEmpty
    5.32 +
    5.33 +	def unregister(g : Game) { 
    5.34 +		game = None
    5.35 +	}
    5.36 +}
    5.37 \ No newline at end of file
     6.1 --- a/src/main/webapp/game.html	Sun Mar 29 23:16:41 2009 +0300
     6.2 +++ b/src/main/webapp/game.html	Wed Apr 01 22:00:38 2009 +0300
     6.3 @@ -1,5 +1,6 @@
     6.4  <lift:surround with="default" at="content">
     6.5    <body> 
     6.6 +	  <div id="game_errors"></div>
     6.7  		<div class="widget">
     6.8  			<lift:Util.in>
     6.9  			<center><b>Chat</b></center><br />
    6.10 @@ -12,6 +13,9 @@
    6.11  			<lift:Util.in>
    6.12  			<lift:comet type="GameActor">
    6.13  				<div>
    6.14 +					<game:status>Here should be game status</game:status>
    6.15 +				</div>
    6.16 +				<div>
    6.17  					<b>Users online</b>
    6.18  					<game:userList>Here should be userlist</game:userList>
    6.19  				</div>