package wow.doge.mygame.game import scala.concurrent.duration._ import akka.actor.typed.ActorRef import akka.actor.typed.PostStop import akka.actor.typed.SpawnProtocol import akka.actor.typed.SupervisorStrategy import akka.actor.typed.scaladsl.Behaviors import monix.execution.CancelableFuture import monix.execution.CancelablePromise import wow.doge.mygame.game.TickGenerator.Send import wow.doge.mygame.implicits._ import wow.doge.mygame.subsystems.events.EventBus import wow.doge.mygame.subsystems.events.EventsModule.GameEventBus import wow.doge.mygame.subsystems.events.TickEvent import wow.doge.mygame.utils.GenericTimerActor object GameAppActor { sealed trait Command case object Start extends Command case object Pause extends Command case object Ping extends Command case class Stop(stopSignal: ActorRef[CancelableFuture[Unit]]) extends Command case class GetSpawnProtocol( replyTo: ActorRef[ActorRef[SpawnProtocol.Command]] ) extends Command case class Props(tickEventBus: GameEventBus[TickEvent]) { def behavior = Behaviors.setup[Command] { ctx => ctx.log.infoP("Hello from GameAppActor") val renderTickGenerator = ctx.spawnN( Behaviors .supervise(renderTickGeneratorBehavior) .onFailure[Exception]( SupervisorStrategy.restart.withLimit(2, 100.millis) ) ) val tickGeneratorTimer = ctx.spawnN( GenericTimerActor .Props(renderTickGenerator, TickGenerator.Send, 10.millis) .behavior ) val sp = ctx.spawn(SpawnProtocol(), "gameSpawnProtocol") ctx.spawn( GenericTimerActor .Props(ctx.self, Ping, 1000.millis) .behavior, "pingTimer" ) ! GenericTimerActor.Start val stopPromise = CancelablePromise[Unit]() Behaviors .receiveMessage[Command] { case Start => tickGeneratorTimer ! GenericTimerActor.Start Behaviors.same case Pause => tickGeneratorTimer ! GenericTimerActor.Stop Behaviors.same case Stop(replyTo) => ctx.log.infoP("Received stop") tickGeneratorTimer ! GenericTimerActor.Stop replyTo ! stopPromise.future Behaviors.stopped case Ping => ctx.log.debugP("ping") Behaviors.same case GetSpawnProtocol(replyTo) => replyTo ! sp Behaviors.same } .receiveSignal { case (_, PostStop) => stopPromise.success(()) Behaviors.same } } val renderTickGeneratorBehavior = Behaviors.receiveMessage[TickGenerator.Command] { case Send => tickEventBus ! EventBus.Publish( TickEvent.RenderTick, "tickGeneratorActor" ) Behaviors.same } } } object TickGenerator { sealed trait Command case object Send extends Command }