forked from nova/jmonkey-test
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.8 KiB
135 lines
3.8 KiB
package wow.doge.mygame
|
|
import akka.actor.typed.scaladsl.Behaviors
|
|
import wow.doge.mygame.game.GameApp
|
|
import akka.actor.typed.Behavior
|
|
import wow.doge.mygame.game.GameAppActor
|
|
import cats.effect.Resource
|
|
import akka.actor.typed.ActorSystem
|
|
import monix.bio.Task
|
|
import wow.doge.mygame.game.GameModule
|
|
import io.odin._
|
|
import io.odin.syntax._
|
|
import wow.doge.mygame.executors.ExecutorsModule
|
|
import akka.actor.typed.scaladsl.ActorContext
|
|
import wow.doge.mygame.executors.Schedulers
|
|
import com.softwaremill.macwire._
|
|
import akka.actor.typed.SpawnProtocol
|
|
import akka.actor.typed.Scheduler
|
|
import wow.doge.mygame.utils.AkkaUtils
|
|
import scala.concurrent.duration._
|
|
import akka.actor.typed.ActorRef
|
|
import wow.doge.mygame.implicits._
|
|
|
|
trait MainModule extends GameModule with ExecutorsModule {
|
|
def actorSystemResource(
|
|
logger: Logger[Task],
|
|
app: GameApp,
|
|
schedulers: Schedulers
|
|
): Resource[Task, ActorSystem[RootActor.Command]] =
|
|
Resource.make(logger.info("Creating Actor System") >> Task {
|
|
ActorSystem(
|
|
wire[RootActor.Props].create(RootActor.State.empty),
|
|
name = "GameActorSystem"
|
|
)
|
|
})(sys =>
|
|
logger.info("Shutting down actor system") >> Task(
|
|
sys.terminate()
|
|
)
|
|
)
|
|
|
|
def actorSystemResource2(
|
|
logger: Logger[Task]
|
|
): Resource[Task, ActorSystem[SpawnProtocol.Command]] =
|
|
Resource.make(logger.info("Creating Actor System") >> Task {
|
|
ActorSystem(
|
|
SpawnProtocol(),
|
|
name = "GameActorSystem2"
|
|
)
|
|
})(sys =>
|
|
logger.info("Shutting down actor system") >> Task(
|
|
sys.terminate()
|
|
)
|
|
)
|
|
|
|
def rootActorResource(
|
|
loggerL: Logger[Task],
|
|
app: GameApp,
|
|
schedulers: Schedulers,
|
|
spawnProtocol: ActorSystem[SpawnProtocol.Command]
|
|
): Resource[Task, ActorRef[RootActor.Command]] =
|
|
Resource.make(
|
|
loggerL.info("Creating Root Actor") >>
|
|
AkkaUtils.spawnActorL(
|
|
behavior = RootActor(app, schedulers, logger = loggerL),
|
|
actorName = "RootActor",
|
|
spawnProtocol = spawnProtocol
|
|
)(1.seconds, spawnProtocol.scheduler)
|
|
)(actor =>
|
|
loggerL.info("Shutting down root actor") >> (actor !! RootActor.Stop)
|
|
)
|
|
}
|
|
|
|
object RootActor {
|
|
sealed trait Command
|
|
final case class Start(akkaScheduler: Scheduler) extends Command
|
|
final case object Stop extends Command
|
|
|
|
final case class Props(
|
|
app: GameApp,
|
|
schedulers: Schedulers,
|
|
logger: Logger[Task]
|
|
) {
|
|
def create(state: State): Behavior[Command] =
|
|
Behaviors.setup { ctx =>
|
|
ctx.log.info("Hello from root actor")
|
|
wire[RootActor].receive(State.empty)
|
|
}
|
|
}
|
|
|
|
final case class State(initialized: Boolean = false)
|
|
object State {
|
|
val empty = State()
|
|
}
|
|
def apply(
|
|
app: GameApp,
|
|
schedulers: Schedulers,
|
|
state: State = State.empty,
|
|
logger: Logger[Task]
|
|
): Behavior[Command] =
|
|
Behaviors.setup { ctx =>
|
|
ctx.log.info("Hello from root actor")
|
|
wire[RootActor].receive(state)
|
|
}
|
|
}
|
|
|
|
class RootActor(
|
|
ctx: ActorContext[RootActor.Command],
|
|
app: GameApp,
|
|
schedulers: Schedulers,
|
|
logger: Logger[Task]
|
|
) {
|
|
import RootActor._
|
|
def receive(state: State): Behavior[Command] =
|
|
Behaviors.receiveMessage(msg =>
|
|
msg match {
|
|
case Start(akkaScheduler) =>
|
|
if (!state.initialized) {
|
|
ctx.log.info("Starting GameAppActor")
|
|
val spawnProtocol = ctx.spawn(SpawnProtocol(), "spawnProtocol")
|
|
val _ = ctx.spawn(
|
|
wire[GameAppActor.Props].create,
|
|
"gameAppActor"
|
|
// DispatcherSelector.fromConfig("jme-dispatcher")
|
|
)
|
|
receive(state.copy(initialized = true))
|
|
} else {
|
|
ctx.log.warn("Already Initialized")
|
|
Behaviors.same
|
|
}
|
|
case Stop =>
|
|
ctx.log.info("Stopping")
|
|
Behaviors.stopped
|
|
|
|
}
|
|
)
|
|
}
|