Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions modules/round/src/main/ApiMoveStream.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import akka.stream.scaladsl.*
import chess.format.Fen
import chess.{ Centis, Replay }
import play.api.libs.json.*
import scala.util.chaining.*

import lila.common.Bus
import lila.common.Json.given
Expand All @@ -18,15 +19,11 @@ final class ApiMoveStream(

def apply(game: Game, delayMoves: Boolean): Source[JsObject, ?] =
Source futureSource {
val hasMoveDelay = delayMoves && game.hasClock
val delayMovesBy = hasMoveDelay ?? 3
val delayKeepsFirstMoves = hasMoveDelay ?? 5
for
initialFen <- gameRepo.initialFen(game)
lightUsers <- lightUserApi.asyncManyOptions(game.players.map(_.userId))
yield
val buffer = scala.collection.mutable.Queue.empty[JsObject]
var moves = 0
def makeGameJson(g: Game) =
gameJsonView.base(g, initialFen) ++ Json.obj(
"players" -> JsObject(g.players zip lightUsers map { (p, user) =>
Expand All @@ -36,13 +33,6 @@ final class ApiMoveStream(
Source(List(makeGameJson(game))) concat
Source
.queue[JsObject]((game.ply.value + 3) atLeast 16, akka.stream.OverflowStrategy.dropHead)
.statefulMapConcat { () => js =>
moves += 1
if (game.finished || moves <= delayKeepsFirstMoves) List(js)
else
buffer.enqueue(js)
(buffer.size > delayMovesBy) ?? List(buffer.dequeue())
}
.mapMaterializedValue { queue =>
val clocks = for
clk <- game.clock
Expand Down Expand Up @@ -83,9 +73,19 @@ final class ApiMoveStream(
Bus.unsubscribe(sub, chans)
}
}
.pipe: source =>
if delayMoves
then source.delay(delayMovesBy(game), akka.stream.DelayOverflowStrategy.emitEarly)
else source
}
end apply

private def delayMovesBy(game: Game): FiniteDuration =
game.clock
.fold(60): clock =>
(clock.config.estimateTotalSeconds / 60) atLeast 3 atMost 60
.seconds

private def toJson(game: Game, fen: Fen.Epd, lastMoveUci: Option[String]): JsObject =
toJson(
fen,
Expand Down