tell round actor, don't ask

This commit is contained in:
Thibault Duplessis 2013-05-18 09:10:56 -03:00
parent 88917c54ff
commit 10c6109377
6 changed files with 45 additions and 39 deletions

View file

@ -20,13 +20,13 @@ final class ActorMap[A <: Actor](mkActor: String ⇒ A) extends Actor {
}
}
case Count sender ! actors.size
case Count sender ! actors.size
case Ask(id, msg) get(id) flatMap { _ ? msg } pipeTo sender
case Ask(id, msg) get(id) flatMap { _ ? msg } pipeTo sender
case Tell(id, msg) get(id) foreach { _ forward msg }
case Tell(id, msg, _) get(id) foreach { _ forward msg }
case Stop(id) actors get id foreach context.stop
case Stop(id) actors get id foreach context.stop
case Terminated(actor) actors find (_._2 == actor) foreach {
case (id, _) actors = actors - id

View file

@ -25,7 +25,10 @@ case class NbMembers(nb: Int)
package map {
case class Get(id: String)
case class Ask(id: String, msg: Any)
case class Tell(id: String, msg: Any)
case class Tell(
id: String,
msg: Any,
onFailure: Throwable Unit = _ ())
case object Count
case class Stop(id: String)
}

View file

@ -46,6 +46,7 @@ final class Env(
takeback = takeback,
ai = ai,
finisher = finisher,
notifyMove = notifyMove,
socketHub = socketHub,
moretimeDuration = Moretime)
)), name = ActorMapName)
@ -62,7 +63,6 @@ final class Env(
roundMap = roundMap,
socketHub = socketHub,
messenger = messenger,
notifyMove = notifyMove,
flood = flood,
hijack = hijack)

View file

@ -4,6 +4,7 @@ import actorApi._, round._
import lila.ai.Ai
import lila.game.{ Game, GameRepo, PgnRepo, Pov, PovRef, Handler, Event, Progress }
import lila.i18n.I18nKey.{ Select SelectI18nKey }
import lila.socket.actorApi.Forward
import chess.{ Status, Role, Color }
import chess.Pos.posAt
import chess.format.Forsyth
@ -19,6 +20,7 @@ private[round] final class Round(
takeback: Takeback,
ai: Ai,
finisher: Finisher,
notifyMove: (String, String, Option[String]) Unit,
socketHub: ActorRef,
moretimeDuration: Duration) extends Handler(gameId) with Actor {
@ -29,7 +31,10 @@ private[round] final class Round(
case ReceiveTimeout self ! PoisonPill
case Play(playerId, origS, destS, promS, blur, lag) sender ! blocking[PlayResult](playerId) {
// useful to get the game after all messages have been processed
case GetGame GameRepo game gameId pipeTo sender
case Play(playerId, origS, destS, promS, blur, lag) blocking[PlayResult](playerId) {
case Pov(g1, color) PgnRepo get g1.id flatMap { pgnString
(for {
g2 g1.validIf(g1 playableBy color, "Game not playable %s %s, on move %d".format(origS, destS, g1.toChess.fullMoveNumber))
@ -51,6 +56,7 @@ private[round] final class Round(
initialFen progress.game.variant.exotic ?? {
GameRepo initialFen progress.game.id
}
// TODO unblock AI
aiResult ai.play(progress.game.toChess, pgn, initialFen, ~progress.game.aiLevel)
eventsAndFen aiResult match {
case (newChessGame, move) {
@ -69,6 +75,11 @@ private[round] final class Round(
playResult(progress.events, progress)
})
}
} ~ {
case PlayResult(events, fen, lastMove) {
sendEvents(events)
notifyMove(gameId, fen, lastMove)
}
}
case Abort(playerId) sender ! blocking(playerId) { pov
@ -95,11 +106,11 @@ private[round] final class Round(
}
}
case Outoftime sender ! blocking { game
case Outoftime blocking { game
game.outoftimePlayer ?? { player
finisher(game, _.Outoftime, Some(!player.color) filter game.toChess.board.hasEnoughMaterialToMate)
}
}
} ~ sendEvents
case DrawClaim(playerId) sender ! blocking(playerId) { pov
(pov.game.playable &&
@ -118,7 +129,7 @@ private[round] final class Round(
case DrawOffer(playerId) sender ! blocking(playerId) {
case pov @ Pov(g1, color) (g1 playerCanOfferDraw color) ?? {
if (g1.player(!color).isOfferingDraw)
if (g1.player(!color).isOfferingDraw)
finisher(pov.game, _.Draw, None, Some(_.drawOfferAccepted))
else for {
p1 messenger.systemMessage(g1, _.drawOfferSent) map { es
@ -219,22 +230,22 @@ private[round] final class Round(
} yield p2.events)
}
case Moretime(playerRef) sender ! blocking(playerRef) { pov
case Moretime(playerRef) blocking(playerRef) { pov
pov.game.clock.filter(_ pov.game.moretimeable) ?? { clock
val color = !pov.color
val newClock = clock.giveTime(color, moretimeDuration.toSeconds)
val newClock = clock.giveTime(!pov.color, moretimeDuration.toSeconds)
val progress = pov.game withClock newClock
for {
events messenger.systemMessage(
progress.game, ((_.untranslated(
"%s + %d seconds".format(color, moretimeDuration.toSeconds)
)): SelectI18nKey)
)
progress2 = progress ++ (Event.Clock(newClock) :: events)
_ GameRepo save progress2
} yield progress2.events
messenger.systemMessage(progress.game, (_.untranslated(
"%s + %d seconds".format(!pov.color, moretimeDuration.toSeconds)
))) flatMap { events
val progress2 = progress ++ (Event.Clock(newClock) :: events)
GameRepo save progress2 inject progress2.events
}
}
}
} ~ sendEvents
}
private def sendEvents(events: List[Event]) {
if (events.nonEmpty) socketHub ! Forward(gameId, events)
}
private def moveFinish(game: Game, color: Color): Fu[List[Event]] = game.status match {

View file

@ -19,7 +19,6 @@ private[round] final class SocketHandler(
roundMap: ActorRef,
socketHub: ActorRef,
messenger: Messenger,
notifyMove: (String, String, Option[String]) Unit,
flood: Flood,
hijack: Hijack) {
@ -30,8 +29,6 @@ private[round] final class SocketHandler(
ref: PovRef,
member: Member): Handler.Controller = {
def askRound(msg: Any) = roundMap ? Ask(ref.gameId, msg)
member.playerIdOption.fold[Handler.Controller]({
case ("p", o) o int "v" foreach { v socket ! PingVersion(uid, v) }
case ("talk", o) for {
@ -55,21 +52,15 @@ private[round] final class SocketHandler(
case ("move", o) parseMove(o) foreach {
case (orig, dest, prom, blur, lag) {
socket ! Ack(uid)
askRound(Play(playerId, orig, dest, prom, blur, lag)) mapTo
manifest[PlayResult] effectFold (
e {
logwarn("[round socket] " + e.getMessage)
socket ! Resync(uid)
}, {
case PlayResult(events, fen, lastMove) {
socketHub ! Forward(ref.gameId, events)
notifyMove(ref.gameId, fen, lastMove)
}
})
roundMap ! Tell(
gameId,
Play(playerId, orig, dest, prom, blur, lag),
_ socket ! Resync(uid)
)
}
}
case ("moretime", o) askRound(Moretime(playerId)) pipeTo socket
case ("outoftime", o) askRound(Outoftime) pipeTo socket
case ("moretime", o) roundMap ! Tell(gameId, Moretime(playerId))
case ("outoftime", o) roundMap ! Tell(gameId, Outoftime)
}
}
}

View file

@ -76,6 +76,7 @@ package round {
case class PlayResult(events: Events, fen: String, lastMove: Option[String])
case object GetGame
case class Abort(playerId: String)
case object AbortForce
case class Resign(playerId: String)