Redirect when hook is biten

This commit is contained in:
Thibault Duplessis 2012-04-06 21:36:38 +02:00
parent 2e9e718b0f
commit 22f7a5f816
10 changed files with 78 additions and 30 deletions

View file

@ -10,7 +10,7 @@ object DataForm {
val moveForm = Form(tuple(
"from" -> nonEmptyText,
"to" -> nonEmptyText,
"promotion" -> optional(text),
"promotion" -> optional(nonEmptyText),
"b" -> optional(number)
))
@ -31,10 +31,12 @@ object DataForm {
"entry" -> nonEmptyText
))
type LobbyJoinData = (MessagesData, EntryData)
type LobbyJoinData = (MessagesData, EntryData, String, Option[String])
val lobbyJoinForm = Form(tuple(
"entry" -> nonEmptyText,
"messages" -> nonEmptyText
"messages" -> nonEmptyText,
"hook" -> nonEmptyText,
"myHook" -> optional(nonEmptyText)
))
type RematchData = (String, String, EntryData, MessagesData)

View file

@ -43,7 +43,7 @@ object LobbyC extends LilaController {
def join(gameId: String, color: String) = Action { implicit request
FormValidIOk[LobbyJoinData](lobbyJoinForm)(join
api.join(gameId, color, join._1, join._2)
api.join(gameId, color, join._1, join._2, join._3, join._4)
)
}

View file

@ -18,14 +18,17 @@ final class Api(
def cancel(ownerId: String): IO[Unit] = for {
hook hookRepo ownedHook ownerId
_ hook.fold(fisherman.-, io())
_ hook.fold(fisherman.delete, io())
} yield ()
def join(
gameId: String,
colorName: String,
entryData: String,
messageString: String): IO[Unit] = for {
messageString: String,
hookOwnerId: String,
myHookOwnerId: Option[String]): IO[Unit] = for {
hook hookRepo ownedHook hookOwnerId
color ioColor(colorName)
game gameRepo game gameId
g2 messenger.systemMessages(game, messageString)
@ -33,6 +36,12 @@ final class Api(
_ save(game, g3)
_ aliveMemo.put(gameId, color)
_ aliveMemo.put(gameId, !color)
_ hook.fold(h fisherman.bite(h, g3), io())
_ myHookOwnerId.fold(
ownerId hookRepo ownedHook ownerId flatMap { myHook
myHook.fold(fisherman.delete, io())
},
io())
} yield ()
def create(hookOwnerId: String): IO[Unit] = for {

View file

@ -3,7 +3,7 @@ package lobby
import db.HookRepo
import memo.HookMemo
import model.Hook
import model.{ Hook, DbGame }
import scalaz.effects._
@ -13,16 +13,26 @@ final class Fisherman(
socket: Lobby) {
// DO delete in db
def -(hook: Hook): IO[Unit] = for {
def delete(hook: Hook): IO[Unit] = for {
_ hide(hook)
_ hookRepo removeId hook.id
_ hookMemo remove hook.ownerId
} yield ()
// DO NOT delete in db
def hide(hook: Hook): IO[Unit] = for {
_ socket removeHook hook
_ hookMemo remove hook.ownerId
} yield ()
// DO NOT insert in db (done on php side)
def +(hook: Hook): IO[Unit] = for {
_ shake(hook)
_ socket addHook hook
_ shake(hook)
} yield ()
def bite(hook: Hook, game: DbGame): IO[Unit] = for {
_ hide(hook)
_ socket.biteHook(hook, game)
} yield ()
// mark the hook as active, once
@ -30,6 +40,6 @@ final class Fisherman(
def cleanup: IO[Unit] = for {
hooks hookRepo unmatchedNotInOwnerIds hookMemo.keys
_ (hooks map this.-).sequence
_ (hooks map delete).sequence
} yield ()
}

View file

@ -10,16 +10,16 @@ import play.api.libs.iteratee._
final class Hub(messageRepo: MessageRepo, history: History) extends Actor {
private var members = Map.empty[String, LilaEnumerator[JsValue]]
private var members = Map.empty[String, Member]
def receive = {
case Join(uid, version) {
case Join(uid, version, hookOwnerId) {
// Create an Enumerator to write to this socket
//val channel = Enumerator.imperative[JsValue]()
val messages = history since version
val channel = new LilaEnumerator[JsValue](messages)
members = members + (uid -> channel)
members = members + (uid -> Member(channel, hookOwnerId))
sender ! Connected(channel)
}
@ -49,13 +49,24 @@ final class Hub(messageRepo: MessageRepo, history: History) extends Actor {
case RemoveHook(hook) notifyAll("hook_remove", JsString(hook.id))
case Quit(uid) { members = members - uid }
case BiteHook(hook, game) notifyMember(
"redirect", JsString(game fullIdOf game.creatorColor)
) _ |> { fn
members.values filter (_ ownsHook hook) foreach fn
}
case Quit(uid) { members = members - uid }
}
def notifyMember(t: String, data: JsValue)(member: Member) {
val msg = JsObject(Seq("t" -> JsString(t), "d" -> data))
member.channel push msg
}
def notifyAll(t: String, data: JsValue) {
val msg = JsObject(Seq("t" -> JsString(t), "d" -> data))
val vmsg = history += msg
members.foreach { case (_, channel) channel.push(vmsg) }
members.values.foreach(_.channel push vmsg)
}
def notifyAll(t: String, data: Seq[(String, JsValue)]) {
notifyAll(t, JsObject(data))

View file

@ -20,7 +20,7 @@ final class Lobby(hub: ActorRef, hookPool: ActorRef) {
implicit val timeout = Timeout(1 second)
def join(uid: String, version: Int, hook: Option[String]): PromiseType =
(hub ? Join(uid, version)).asPromise map {
(hub ? Join(uid, version, hook)).asPromise map {
case Connected(enumerator)
hook foreach { h hookPool ! HookPool.Register(h) }
val iteratee = Iteratee.foreach[JsValue] { event
@ -48,4 +48,8 @@ final class Lobby(hub: ActorRef, hookPool: ActorRef) {
def addHook(hook: model.Hook): IO[Unit] = io {
hub ! AddHook(hook)
}
def biteHook(hook: model.Hook, game: model.DbGame): IO[Unit] = io {
hub ! BiteHook(hook, game)
}
}

View file

@ -21,6 +21,7 @@ final class Preload(
chat: Boolean,
myHookId: Option[String]): IO[Response] = for {
myHook myHookId.fold(hookRepo.ownedHook, io(none))
// TODO redirect -> / if my hook disapeared
_ myHook.fold(fisherman.shake, io())
hooks auth.fold(hookRepo.allOpen, hookRepo.allOpenCasual)
res {

View file

@ -1,13 +0,0 @@
package lila
package lobby
import play.api.libs.iteratee.Enumerator
import play.api.libs.json.JsValue
case class AddHook(hook: model.Hook)
case class RemoveHook(hook: model.Hook)
case class Entry(entry: model.Entry)
case class Join(uid: String, version: Int)
case class Quit(uid: String)
case class Talk(txt: String, u: String)
case class Connected(enumerator: Enumerator[JsValue])

16
app/lobby/model.scala Normal file
View file

@ -0,0 +1,16 @@
package lila
package lobby
case class Member(channel: Channel, hookOwnerId: Option[String]) {
def ownsHook(hook: model.Hook) = Some(hook.ownerId) == hookOwnerId
}
case class AddHook(hook: model.Hook)
case class RemoveHook(hook: model.Hook)
case class BiteHook(hook: model.Hook, game: model.DbGame)
case class Entry(entry: model.Entry)
case class Join(uid: String, version: Int, hookOwnerId: Option[String])
case class Quit(uid: String)
case class Talk(txt: String, u: String)
case class Connected(channel: Channel)

8
app/lobby/package.scala Normal file
View file

@ -0,0 +1,8 @@
package lila
import play.api.libs.json.JsValue
package object lobby {
type Channel = LilaEnumerator[JsValue]
}