package wow.doge.mygame.game.entities.player import scala.concurrent.duration._ import akka.actor.typed.ActorRef import akka.actor.typed.Behavior import akka.actor.typed.LogOptions import akka.actor.typed.PostStop import akka.actor.typed.SupervisorStrategy import akka.actor.typed.scaladsl.ActorContext import akka.actor.typed.scaladsl.Behaviors import com.typesafe.scalalogging.Logger import org.slf4j.event.Level import wow.doge.mygame.Dispatchers import wow.doge.mygame.game.entities.PlayerCameraActor import wow.doge.mygame.game.entities.PlayerCameraEventListener import wow.doge.mygame.game.entities.PlayerMovementEventListener 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.PlayerEvent import wow.doge.mygame.subsystems.events.TickEvent import wow.doge.mygame.subsystems.events.TickEvent.RenderTick import wow.doge.mygame.subsystems.movement.ImMovementActor object PlayerActorSupervisor2 { sealed trait Command case object Tick extends Command sealed trait Movement extends Command final case class MoveLeft(pressed: Boolean) extends Movement final case class MoveUp(pressed: Boolean) extends Movement final case class MoveRight(pressed: Boolean) extends Movement final case class MoveDown(pressed: Boolean) extends Movement case object Jump extends Movement sealed trait Camera case object RotateLeft extends Camera case object RotateRight extends Camera case object RotateUp extends Camera case object RotateDown extends Camera class Props( val playerEventBus: GameEventBus[PlayerEvent], val tickEventBus: GameEventBus[TickEvent], val imMovementActorBehavior: Behavior[ImMovementActor.Command], val playerCameraActorBehavior: Behavior[PlayerCameraActor.Command] ) { def behavior = Behaviors.logMessages( LogOptions() .withLevel(Level.TRACE) .withLogger( Logger[PlayerActorSupervisor2].underlying ), Behaviors .setup[Command] { ctx => ctx.log.infoP("Starting PlayerActor") // spawn children actors val movementActor = ctx.spawn( Behaviors .supervise(imMovementActorBehavior) .onFailure[Exception]( SupervisorStrategy.restart.withLimit(2, 100.millis) ), "playerMovementActor", Dispatchers.jmeDispatcher ) val playerCameraActor = ctx.spawn( playerCameraActorBehavior, "playerCameraActor", Dispatchers.jmeDispatcher ) val playerCameraEl = ctx.spawn( PlayerCameraEventListener(playerCameraActor), "playerCameraActorEl" ) val playerMovementEl = ctx.spawn( Behaviors .supervise(PlayerMovementEventListener(movementActor)) .onFailure[Exception]( SupervisorStrategy.restart.withLimit(2, 100.millis) ), "playerMovementEventHandler" ) val renderTickEl = { val behavior: Behavior[RenderTick.type] = Behaviors.setup(ctx => Behaviors .receiveMessage[RenderTick.type] { case RenderTick => movementActor ! ImMovementActor.Tick // playerCameraActor ! PlayerCameraActor.Tick Behaviors.same } .receiveSignal { case (_, PostStop) => ctx.log.infoP("stopped") Behaviors.same } ) ctx.spawn(behavior, "playerMovementTickListener") } //init listeners playerEventBus ! EventBus.Subscribe(playerMovementEl) tickEventBus ! EventBus.Subscribe(renderTickEl) playerEventBus ! EventBus.Subscribe(playerCameraEl) new PlayerActorSupervisor2( ctx, this, Children(movementActor) ).receive } ) } case class Children( movementActor: ActorRef[ImMovementActor.Command] ) } class PlayerActorSupervisor2( ctx: ActorContext[PlayerActorSupervisor2.Command], props: PlayerActorSupervisor2.Props, children: PlayerActorSupervisor2.Children ) { import PlayerActorSupervisor2._ def receive = Behaviors .receiveMessage[Command] { case m @ MoveDown(pressed) => // children.movementActor ! m Behaviors.same case _ => // children.movementActor ! ImMovementActor.MovedDown(true) Behaviors.same } .receiveSignal { case (_, PostStop) => ctx.log.infoP("stopped") Behaviors.same } }