use different models for tournament statuses

This commit is contained in:
Thibault Duplessis 2012-09-09 15:17:51 +02:00
parent 4b601b3227
commit a86b3ad953
8 changed files with 110 additions and 25 deletions

View file

@ -2,6 +2,7 @@ package controllers
import lila._
import views._
import tournament.{ Created }
import http.Context
import scalaz.effects._
@ -20,7 +21,10 @@ object Tournament extends LilaController {
}
def show(id: String) = Open { implicit ctx
Ok(id)
IOptionOk(repo byId id) {
case t: Created html.tournament.show.created(t)
case _ throw new Exception("oups")
}
}
def form = Auth { implicit ctx
@ -34,7 +38,7 @@ object Tournament extends LilaController {
implicit val req = ctx.body
forms.create.bindFromRequest.fold(
err io(BadRequest(html.message.form(err))),
data api.makeTournament(data, me).map(tournament
setup api.createTournament(setup, me).map(tournament
Redirect(routes.Tournament.show(tournament.id))
))
}

View file

@ -10,9 +10,11 @@ final class DataForm {
import lila.core.Form._
val create = Form(mapping(
"minutes" -> numberIn(Tournament.minuteChoices)
"minutes" -> numberIn(Tournament.minuteChoices),
"minUsers" -> numberIn(Tournament.minUserChoices)
)(TournamentSetup.apply)(TournamentSetup.unapply)) fill TournamentSetup()
}
case class TournamentSetup(
minutes: Int = Tournament.minuteDefault)
minutes: Int = Tournament.minuteDefault,
minUsers: Int = Tournament.minUserDefault)

View file

@ -15,10 +15,9 @@ object Status {
case object Created extends Status(10)
case object Started extends Status(20)
case object Aborted extends Status(25) // from this point the game is finished
case object Finished extends Status(30)
val all = List(Created, Started, Aborted, Finished)
val all = List(Created, Started, Finished)
val byId = all map { v (v.id, v) } toMap

View file

@ -6,25 +6,77 @@ import org.scala_tools.time.Imports._
import com.novus.salat.annotations.Key
import ornicar.scalalib.OrnicarRandom
case class Tournament(
@Key("_id") id: String = OrnicarRandom nextString 8,
createdBy: String,
startsAt: DateTime,
case class Data(
minutes: Int,
finished: Boolean = false,
createdAt: DateTime = DateTime.now,
users: List[String] = Nil) {
minUsers: Int,
createdAt: DateTime,
createdBy: String,
users: List[String]) {
lazy val duration = new Duration(minutes * 60 * 1000)
lazy val endsAt = DateTime.now + duration
def missingUsers = minUsers - users.size
}
sealed trait Tournament {
def id: String
def encode: RawTournament
def showClock = "2 + 0"
}
case class Created(
id: String,
data: Data) extends Tournament {
def encode = RawTournament.created(id, data)
}
case class RawTournament(
@Key("_id") id: String,
status: Int,
data: Data) {
def created: Option[Created] = (status == Status.Created.id) option Created(
id = id,
data = data)
def any: Option[Tournament] = created
}
object RawTournament {
def created(id: String, data: Data) = {
new RawTournament(
id = id,
status = Status.Created.id,
data = data)
}
}
object Tournament {
import lila.core.Form._
def apply(
createdBy: String,
minutes: Int,
minUsers: Int): Created = Created(
id = OrnicarRandom nextString 8,
data = Data(
createdBy = createdBy,
createdAt = DateTime.now,
minutes = minutes,
minUsers = minUsers,
users = List(createdBy))
)
val minutes = 5 to 30 by 5
val minuteDefault = 10
val minuteChoices = options(minutes, "%d minute{s}")
val minUsers = 5 to 30 by 5
val minUserDefault = 10
val minUserChoices = options(minUsers, "%d players{s}")
}

View file

@ -3,17 +3,18 @@ package tournament
import org.joda.time.DateTime
import org.scala_tools.time.Imports._
import scalaz.effects._
import user.User
final class TournamentApi(
repo: TournamentRepo) {
def makeTournament(data: TournamentSetup, me: User) = {
def createTournament(setup: TournamentSetup, me: User): IO[Created] = {
val tournament = Tournament(
createdBy = me.id,
startsAt = DateTime.now,
minutes = data.minutes)
minutes = setup.minutes,
minUsers = setup.minUsers)
for {
_ repo saveIO tournament
} yield tournament

View file

@ -10,20 +10,20 @@ import org.joda.time.DateTime
import org.scala_tools.time.Imports._
class TournamentRepo(collection: MongoCollection)
extends SalatDAO[Tournament, String](collection) {
extends SalatDAO[RawTournament, String](collection) {
def byId(id: String): IO[Option[Tournament]] = io {
findOneById(id)
findOneById(id) flatMap (_.any)
}
def created: IO[List[Tournament]] = io {
find(DBObject("status" -> Status.Created))
def created: IO[List[Created]] = io {
find(DBObject("status" -> Status.Created.id))
.sort(DBObject("createdAt" -> -1))
.toList
.toList.map(_.created).flatten
}
def saveIO(tournament: Tournament): IO[Unit] = io {
save(tournament)
save(tournament.encode)
}
private def idSelector(id: String): DBObject = DBObject("_id" -> id)

View file

@ -9,12 +9,20 @@ title = "New tournament") {
<table>
<tr>
<th>
<label for="@form("maxUsers").id">Total duration</label>
<label for="@form("minutes").id">Total duration</label>
</th>
<td>
@base.select(form("minutes"), Tournament.minuteChoices)
</td>
</tr>
<tr>
<th>
<label for="@form("minUsers").id">Number of Players</label>
</th>
<td>
@base.select(form("minUsers"), Tournament.minUserChoices)
</td>
</tr>
<tr>
<th></th>
<td>

View file

@ -0,0 +1,19 @@
@(tour: lila.tournament.Created)(implicit ctx: Context)
@import tour.data._
@title = @{ tour.showClock + " tournament" }
@tournament.layout(
title = title) {
<h1>@title pending</h1>
<div>
Waiting for @missingUsers players
</div>
<div>
Players: @users.map { user =>
@userIdLink(user.some)
}
</div>
}