Skip to content

Commit

Permalink
study refactors
Browse files Browse the repository at this point in the history
  • Loading branch information
ornicar committed Dec 27, 2024
1 parent 1c88f5b commit 3da70d7
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 65 deletions.
2 changes: 1 addition & 1 deletion app/controllers/Study.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import lila.core.study.Order
import lila.study.JsonView.JsData
import lila.study.PgnDump.WithFlags
import lila.study.Study.WithChapter
import lila.study.actorApi.{ BecomeStudyAdmin, Who }
import lila.study.{ BecomeStudyAdmin, Who }
import lila.study.{ Chapter, Orders, Settings, Study as StudyModel, StudyForm }
import lila.tree.Node.partitionTreeJsonWriter
import com.fasterxml.jackson.core.JsonParseException
Expand Down
2 changes: 1 addition & 1 deletion modules/practice/src/main/Env.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ final class Env(

def getStudies: lila.core.practice.GetStudies = api.structure.getStudies

lila.common.Bus.subscribeFun("study") { case lila.study.actorApi.SaveStudy(study) =>
lila.common.Bus.subscribeFun("study") { case lila.study.SaveStudy(study) =>
api.structure.onSave(study)
}
8 changes: 4 additions & 4 deletions modules/relay/src/main/Env.scala
Original file line number Diff line number Diff line change
Expand Up @@ -144,19 +144,19 @@ final class Env(
"study" -> { case lila.core.study.RemoveStudy(studyId) =>
api.onStudyRemove(studyId)
},
"relayToggle" -> { case lila.study.actorApi.RelayToggle(id, v, who) =>
"relayToggle" -> { case lila.study.RelayToggle(id, v, who) =>
studyApi
.isContributor(id, who.u)
.foreach:
_.so(api.requestPlay(id.into(RelayRoundId), v, "manual toggle"))
},
"kickStudy" -> { case lila.study.actorApi.Kick(studyId, userId, who) =>
"kickStudy" -> { case lila.study.Kick(studyId, userId, who) =>
roundRepo.tourIdByStudyId(studyId).flatMapz(api.kickBroadcast(userId, _, who))
},
"adminStudy" -> { case lila.study.actorApi.BecomeStudyAdmin(studyId, me) =>
"adminStudy" -> { case lila.study.BecomeStudyAdmin(studyId, me) =>
api.becomeStudyAdmin(studyId, me)
},
"isOfficialRelay" -> { case lila.study.actorApi.IsOfficialRelay(studyId, promise) =>
"isOfficialRelay" -> { case lila.study.IsOfficialRelay(studyId, promise) =>
promise.completeWith(api.isOfficial(studyId.into(RelayRoundId)))
}
)
Expand Down
2 changes: 1 addition & 1 deletion modules/relay/src/main/RelayPlayerEnrich.scala
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,6 @@ private final class RelayPlayerEnrich(
chapterId = chapter.id,
tags = enriched,
newName = newName.filter(_ != chapter.name)
)(lila.study.actorApi.Who(chapter.ownerId, Sri("")))
)(lila.study.Who(chapter.ownerId, Sri("")))
.runWith(Sink.ignore)
yield ()
37 changes: 19 additions & 18 deletions modules/relay/src/main/RelaySync.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import chess.format.pgn.{ Tag, Tags }
import lila.core.socket.Sri
import lila.study.*
import lila.tree.Branch
import lila.study.AddNode

final private class RelaySync(
studyApi: StudyApi,
Expand Down Expand Up @@ -91,20 +92,19 @@ final private class RelaySync(
studyId = study.id,
position = Position(chapter, path).ref,
toMainline = true
)(by) >> chapterRepo.setRelayPath(chapter.id, path)
)(using by) >> chapterRepo.setRelayPath(chapter.id, path)
_ <- newNode match
case Some(newNode) =>
newNode.mainline
.foldM(Position(chapter, path).ref): (position, n) =>
studyApi
.addNode(
studyId = study.id,
position = position,
node = n,
opts = moveOpts,
relay = makeRelayFor(game, position.path + n.id).some
)(by)
.inject(position + n)
val node = AddNode(
studyId = study.id,
positionRef = position,
node = n,
opts = moveOpts,
relay = makeRelayFor(game, position.path + n.id).some
)(using by)
studyApi.addNode(node).inject(position + n)
case None =>
// the chapter already has all the game moves,
// but its relayPath might be out of sync. This can happen if the broadcast
Expand All @@ -121,13 +121,14 @@ final private class RelaySync(
game.root.children
.nodeAt(gameMainlinePath)
.so: lastMainlineNode =>
studyApi.addNode(
studyId = study.id,
position = Position(chapter, gameMainlinePath.parent).ref,
node = lastMainlineNode,
opts = moveOpts,
relay = makeRelayFor(game, gameMainlinePath).some
)(by)
studyApi.addNode:
AddNode(
studyId = study.id,
positionRef = Position(chapter, gameMainlinePath.parent).ref,
node = lastMainlineNode,
opts = moveOpts,
relay = makeRelayFor(game, gameMainlinePath).some
)(using by)
yield newNode.so(_.mainline.size)

private def updateChapterTags(
Expand Down Expand Up @@ -212,7 +213,7 @@ final private class RelaySync(
)

private val sri = Sri("")
private def who(userId: UserId) = actorApi.Who(userId, sri)
private def who(userId: UserId) = Who(userId, sri)

private def vs(tags: Tags) = s"${tags(_.White) | "?"} - ${tags(_.Black) | "?"}"

Expand Down
2 changes: 1 addition & 1 deletion modules/study/src/main/Env.scala
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ final class Env(

private lazy val chapterMaker = wire[ChapterMaker]

private lazy val explorerGame = wire[ExplorerGame]
private lazy val explorerGame = wire[ExplorerGameApi]

private lazy val studyMaker = wire[StudyMaker]

Expand Down
2 changes: 1 addition & 1 deletion modules/study/src/main/ExplorerGame.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import chess.format.{ Fen, UciPath }
import lila.tree.Node.Comment
import lila.tree.{ Branch, Node, Root }

final private class ExplorerGame(
final private class ExplorerGameApi(
explorer: lila.core.game.Explorer,
namer: lila.core.game.Namer,
lightUserApi: lila.core.user.LightUserApi,
Expand Down
2 changes: 1 addition & 1 deletion modules/study/src/main/JsonView.scala
Original file line number Diff line number Diff line change
Expand Up @@ -218,5 +218,5 @@ object JsonView:

private[study] given Writes[Chapter.ServerEval] = Json.writes

private[study] given OWrites[actorApi.Who] = OWrites: w =>
private[study] given OWrites[Who] = OWrites: w =>
Json.obj("u" -> w.u, "s" -> w.sri)
36 changes: 14 additions & 22 deletions modules/study/src/main/StudyApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,14 @@ import lila.core.timeline.{ Propagate, StudyLike }
import lila.tree.Branch
import lila.tree.Node.{ Comment, Gamebook, Shapes }

import actorApi.Who

final class StudyApi(
studyRepo: StudyRepo,
chapterRepo: ChapterRepo,
sequencer: StudySequencer,
studyMaker: StudyMaker,
chapterMaker: ChapterMaker,
inviter: StudyInvite,
explorerGameHandler: ExplorerGame,
explorerGameHandler: ExplorerGameApi,
topicApi: StudyTopicApi,
lightUserApi: lila.core.user.LightUserApi,
chatApi: lila.core.chat.ChatApi,
Expand Down Expand Up @@ -225,27 +223,21 @@ final class StudyApi(
yield sendTo(study.id)(_.setPath(position, who))
case _ => funit

def addNode(
studyId: StudyId,
position: Position.Ref,
node: Branch,
opts: MoveOpts,
relay: Option[Chapter.Relay] = None
)(who: Who): Funit =
sequenceStudyWithChapter(studyId, position.chapterId):
def addNode(args: AddNode): Funit =
import args.{ *, given }
sequenceStudyWithChapter(studyId, positionRef.chapterId):
case Study.WithChapter(study, chapter) =>
Contribute(who.u, study):
doAddNode(study, Position(chapter, position.path), node, opts, relay)(who)
doAddNode(args, study, Position(chapter, positionRef.path))
.flatMapz { _() }

private def doAddNode(
args: AddNode,
study: Study,
position: Position,
rawNode: Branch,
opts: MoveOpts,
relay: Option[Chapter.Relay]
)(who: Who): Fu[Option[() => Funit]] =
val singleNode = rawNode.withoutChildren
position: Position
): Fu[Option[() => Funit]] =
import args.{ *, given }
val singleNode = args.node.withoutChildren
def failReload() = reloadSriBecauseOf(study, who.sri, position.chapter.id)
if position.chapter.isOverweight then
logger.info(s"Overweight chapter ${study.id}/${position.chapter.id}")
Expand All @@ -272,7 +264,7 @@ final class StudyApi(
isMainline = newPosition.path.isMainline(chapter.root)
promoteToMainline = opts.promoteToMainline && !isMainline
yield promoteToMainline.option: () =>
promote(study.id, position.ref + node, toMainline = true)(who)
promote(study.id, position.ref + node, toMainline = true)
}
}

Expand Down Expand Up @@ -326,7 +318,7 @@ final class StudyApi(
yield onChapterChange(study.id, chapter.id, who)

// rewrites the whole chapter because of `forceVariation`. Very inefficient.
def promote(studyId: StudyId, position: Position.Ref, toMainline: Boolean)(who: Who): Funit =
def promote(studyId: StudyId, position: Position.Ref, toMainline: Boolean)(using who: Who): Funit =
sequenceStudyWithChapter(studyId, position.chapterId):
case Study.WithChapter(study, chapter) =>
Contribute(who.u, study):
Expand Down Expand Up @@ -441,7 +433,7 @@ final class StudyApi(
reloadSriBecauseOf(sc.study, who.sri, position.chapterId)
fufail(s"Invalid setClock $position $clock")

def setTag(studyId: StudyId, setTag: actorApi.SetTag)(who: Who) =
def setTag(studyId: StudyId, setTag: SetTag)(who: Who) =
sequenceStudyWithChapter(studyId, setTag.chapterId):
case Study.WithChapter(study, chapter) =>
Contribute(who.u, study):
Expand Down Expand Up @@ -545,7 +537,7 @@ final class StudyApi(
reloadSriBecauseOf(study, who.sri, chapter.id)
fufail(s"Invalid setGamebook $studyId $position")

def explorerGame(studyId: StudyId, data: actorApi.ExplorerGame)(who: Who) =
def explorerGame(studyId: StudyId, data: ExplorerGame)(who: Who) =
sequenceStudyWithChapter(studyId, data.position.chapterId):
case Study.WithChapter(study, chapter) =>
Contribute(who.u, study):
Expand Down
26 changes: 12 additions & 14 deletions modules/study/src/main/StudySocket.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import lila.tree.Branch
import lila.tree.Node.{ Comment, Gamebook, Shape, Shapes }
import lila.tree.Node.minimalNodeJsonWriter

import actorApi.Who

final private class StudySocket(
api: StudyApi,
jsonView: JsonView,
Expand Down Expand Up @@ -75,13 +73,13 @@ final private class StudySocket(
AnaMove
.parse(o)
.foreach: move =>
applyWho(moveOrDrop(studyId, move, MoveOpts.parse(o)))
applyWho(moveOrDrop(studyId, move, MoveOpts.parse(o))(using _))

case "anaDrop" =>
AnaDrop
.parse(o)
.foreach: drop =>
applyWho(moveOrDrop(studyId, drop, MoveOpts.parse(o)))
applyWho(moveOrDrop(studyId, drop, MoveOpts.parse(o))(using _))

case "deleteNode" =>
reading[AtPosition](o): position =>
Expand All @@ -96,7 +94,7 @@ final private class StudySocket(
(o \ "d" \ "toMainline")
.asOpt[Boolean]
.foreach: toMainline =>
applyWho(api.promote(studyId, position.ref, toMainline))
applyWho(api.promote(studyId, position.ref, toMainline)(using _))

case "forceVariation" =>
reading[AtPosition](o): position =>
Expand All @@ -114,7 +112,7 @@ final private class StudySocket(
.foreach: username =>
applyWho: w =>
api.kick(studyId, username.id, w.myId)
Bus.publish(actorApi.Kick(studyId, username.id, w.myId), "kickStudy")
Bus.publish(Kick(studyId, username.id, w.myId), "kickStudy")

case "leave" =>
who.foreach: w =>
Expand Down Expand Up @@ -177,7 +175,7 @@ final private class StudySocket(
applyWho(api.editStudy(studyId, data))

case "setTag" =>
reading[actorApi.SetTag](o): setTag =>
reading[SetTag](o): setTag =>
applyWho(api.setTag(studyId, setTag))

case "setComment" =>
Expand Down Expand Up @@ -216,7 +214,7 @@ final private class StudySocket(
applyWho(api.setTopics(studyId, topics))

case "explorerGame" =>
reading[actorApi.ExplorerGame](o): data =>
reading[ExplorerGame](o): data =>
applyWho(api.explorerGame(studyId, data))

case "requestAnalysis" =>
Expand All @@ -235,7 +233,7 @@ final private class StudySocket(

case "relaySync" =>
applyWho: w =>
Bus.publish(actorApi.RelayToggle(studyId, ~(o \ "d").asOpt[Boolean], w), "relayToggle")
Bus.publish(RelayToggle(studyId, ~(o \ "d").asOpt[Boolean], w), "relayToggle")

case t => logger.warn(s"Unhandled study socket message: $t")

Expand All @@ -246,18 +244,18 @@ final private class StudySocket(
_ => _ => none, // the "talk" event is handled by the study API
localTimeout = Some { (roomId, modId, suspectId) =>
api.isContributor(roomId, modId) >>& api.isMember(roomId, suspectId).not >>&
Bus.ask("isOfficialRelay") { actorApi.IsOfficialRelay(roomId, _) }.not
Bus.ask("isOfficialRelay") { IsOfficialRelay(roomId, _) }.not
},
chatBusChan = _.study
)

private def moveOrDrop(studyId: StudyId, m: AnaAny, opts: MoveOpts)(who: Who) =
private def moveOrDrop(studyId: StudyId, m: AnaAny, opts: MoveOpts)(using Who) =
m.branch.foreach: branch =>
if branch.ply < Node.MAX_PLIES then
m.chapterId
.ifTrue(opts.write)
.foreach: chapterId =>
api.addNode(studyId, Position.Ref(chapterId, m.path), branch, opts)(who)
api.addNode(AddNode(studyId, Position.Ref(chapterId, m.path), branch, opts))

private lazy val send = socketKit.send("study-out")

Expand Down Expand Up @@ -458,9 +456,9 @@ object StudySocket:
given Reads[ChapterMaker.EditData] = Json.reads
given Reads[ChapterMaker.DescData] = Json.reads
given studyDataReads: Reads[Study.Data] = Json.reads
given Reads[actorApi.SetTag] = Json.reads
given Reads[SetTag] = Json.reads
given Reads[Gamebook] = Json.reads
given Reads[actorApi.ExplorerGame] = Json.reads
given Reads[ExplorerGame] = Json.reads

object Out:
def getIsPresent(reqId: Int, studyId: StudyId, userId: UserId) =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package lila.study
package actorApi

import chess.format.UciPath
import lila.tree.Branch

case class SaveStudy(study: Study)
case class SetTag(chapterId: StudyChapterId, name: String, value: String):
Expand All @@ -16,3 +16,11 @@ case class RelayToggle(studyId: StudyId, v: Boolean, who: Who)
case class Kick(studyId: StudyId, userId: UserId, who: MyId)
case class BecomeStudyAdmin(studyId: StudyId, me: Me)
case class IsOfficialRelay(studyId: StudyId, promise: Promise[Boolean])

case class AddNode(
studyId: StudyId,
positionRef: Position.Ref,
node: Branch,
opts: MoveOpts,
relay: Option[Chapter.Relay] = None
)(using val who: Who)

0 comments on commit 3da70d7

Please sign in to comment.