package wow.doge.mygame.game.entities import akka.actor.typed.ActorRef import akka.actor.typed.Behavior import akka.actor.typed.LogOptions 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.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 PlayerActorSupervisor { sealed trait Command final case class Props( playerEventBus: GameEventBus[PlayerEvent], tickEventBus: GameEventBus[TickEvent], imMovementActorBehavior: Behavior[ImMovementActor.Command], playerCameraActorBehavior: Behavior[PlayerCameraActor.Command] ) { def behavior = Behaviors.logMessages( LogOptions() .withLevel(Level.TRACE) .withLogger( Logger[PlayerActorSupervisor].underlying ), Behaviors.setup[Command] { ctx => ctx.log.infoP("Starting PlayerActor") // spawn children actors val movementActor = ctx.spawn( Behaviors .supervise(imMovementActorBehavior) .onFailure[Exception](SupervisorStrategy.restart), "playerMovementActor" ) val playerCameraActor = ctx.spawn(playerCameraActorBehavior, "playerCameraActor") val playerCameraEl = ctx.spawn( PlayerCameraEventListener(playerCameraActor), "playerCameraActorEl" ) val playerMovementEl = ctx.spawn( Behaviors .supervise(PlayerMovementEventListener(movementActor)) .onFailure[Exception](SupervisorStrategy.restart), "playerMovementEventHandler" ) val renderTickEl = { val behavior = Behaviors.receiveMessage[RenderTick.type] { case RenderTick => movementActor ! ImMovementActor.Tick // playerCameraActor ! PlayerCameraActor.Tick Behaviors.same } ctx.spawn(behavior, "playerMovementTickListener") } //init listeners playerEventBus ! EventBus.Subscribe(playerMovementEl) tickEventBus ! EventBus.Subscribe(renderTickEl) playerEventBus ! EventBus.Subscribe(playerCameraEl) new PlayerActorSupervisor( ctx, this, Children(movementActor) ).receive } ) } case class Children( movementActor: ActorRef[ImMovementActor.Command] ) } class PlayerActorSupervisor( ctx: ActorContext[PlayerActorSupervisor.Command], props: PlayerActorSupervisor.Props, children: PlayerActorSupervisor.Children ) { import PlayerActorSupervisor._ def receive = Behaviors .receiveMessage[Command] { case _ => // children.movementActor ! ImMovementActor.MovedDown(true) Behaviors.same } } object PlayerMovementActor { sealed trait Command final case class Props( movementActor: ActorRef[ImMovementActor.Command], playerCameraActor: ActorRef[PlayerCameraActor.Command], playerEventBus: GameEventBus[PlayerEvent], tickEventBus: GameEventBus[TickEvent] ) { def behavior: Behavior[Command] = Behaviors.setup { ctx => val playerMovementEl = ctx.spawn( Behaviors .supervise(PlayerMovementEventListener(movementActor)) .onFailure[Exception](SupervisorStrategy.restart), "playerMovementEventHandler" ) val renderTickEl = { val behavior = Behaviors.receiveMessage[RenderTick.type] { case RenderTick => movementActor ! ImMovementActor.Tick // playerCameraActor ! PlayerCameraActor.Tick Behaviors.same } ctx.spawn(behavior, "playerMovementTickListener") } playerEventBus ! EventBus.Subscribe(playerMovementEl) tickEventBus ! EventBus.Subscribe(renderTickEl) Behaviors.receiveMessage { msg => Behaviors.same } } } }