-
Notifications
You must be signed in to change notification settings - Fork 21
/
SudokuProgressTracker.scala
61 lines (53 loc) · 2.34 KB
/
SudokuProgressTracker.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package org.lunatechlabs.dotty.sudoku
import akka.actor.typed.scaladsl.{ ActorContext, Behaviors }
import akka.actor.typed.{ ActorRef, Behavior }
object SudokuProgressTracker:
sealed trait Command
final case class NewUpdatesInFlight(count: Int) extends Command
final case class SudokuDetailState(index: Int, state: ReductionSet) extends Command
// My responses
sealed trait Response
final case class Result(sudoku: Sudoku) extends Response
def apply(rowDetailProcessors: Map[Int, ActorRef[SudokuDetailProcessor.Command]],
sudokuSolver: ActorRef[Response]
): Behavior[Command] =
Behaviors.setup { context =>
new SudokuProgressTracker(rowDetailProcessors, context, sudokuSolver)
.trackProgress(updatesInFlight = 0)
}
class SudokuProgressTracker private (
rowDetailProcessors: Map[Int, ActorRef[SudokuDetailProcessor.Command]],
context: ActorContext[SudokuProgressTracker.Command],
sudokuSolver: ActorRef[SudokuProgressTracker.Response]
):
import SudokuProgressTracker._
def trackProgress(updatesInFlight: Int): Behavior[Command] =
Behaviors.receiveMessage {
case NewUpdatesInFlight(updateCount) if updatesInFlight - 1 == 0 =>
rowDetailProcessors.foreach ((_, processor) =>
processor ! SudokuDetailProcessor.GetSudokuDetailState(context.self)
)
collectEndState()
case NewUpdatesInFlight(updateCount) =>
trackProgress(updatesInFlight + updateCount)
case msg: SudokuDetailState =>
context.log.error("Received unexpected message in state 'trackProgress': {}", msg)
Behaviors.same
}
def collectEndState(remainingRows: Int = 9,
endState: Vector[SudokuDetailState] = Vector.empty[SudokuDetailState]
): Behavior[Command] =
Behaviors.receiveMessage {
case detail: SudokuDetailState if remainingRows == 1 =>
sudokuSolver ! Result(
(detail +: endState).sortBy { case SudokuDetailState(idx, _) => idx }.map {
case SudokuDetailState(_, state) => state
}
)
trackProgress(updatesInFlight = 0)
case detail: SudokuDetailState =>
collectEndState(remainingRows = remainingRows - 1, detail +: endState)
case msg: NewUpdatesInFlight =>
context.log.error("Received unexpected message in state 'collectEndState': {}", msg)
Behaviors.same
}