Commit 1
This commit is contained in:
parent
45ab129790
commit
3881aac350
0
.attach_pid12833
Normal file
0
.attach_pid12833
Normal file
0
.attach_pid19972
Normal file
0
.attach_pid19972
Normal file
@ -95,7 +95,8 @@ lazy val root = (project in file(".")).settings(
|
|||||||
// "com.github.Oshan96" % "CustomStage" % "v1.3.1",
|
// "com.github.Oshan96" % "CustomStage" % "v1.3.1",
|
||||||
"com.badlogicgames.gdx" % "gdx-ai" % "1.8.2",
|
"com.badlogicgames.gdx" % "gdx-ai" % "1.8.2",
|
||||||
"org.recast4j" % "recast" % "1.2.5",
|
"org.recast4j" % "recast" % "1.2.5",
|
||||||
"org.recast4j" % "detour" % "1.2.5"
|
"org.recast4j" % "detour" % "1.2.5",
|
||||||
|
"com.lihaoyi" %% "pprint" % "0.6.0"
|
||||||
),
|
),
|
||||||
// Determine OS version of JavaFX binaries
|
// Determine OS version of JavaFX binaries
|
||||||
|
|
||||||
@ -155,10 +156,6 @@ lazy val root = (project in file(".")).settings(
|
|||||||
// val oldStrategy = (assemblyMergeStrategy in assembly).value
|
// val oldStrategy = (assemblyMergeStrategy in assembly).value
|
||||||
// oldStrategy(x)
|
// oldStrategy(x)
|
||||||
}
|
}
|
||||||
// scalaVersion := "2.13.2", // 2.11.12, or 2.13.3
|
|
||||||
// semanticdbEnabled := true, // enable SemanticDB
|
|
||||||
// semanticdbVersion := scalafixSemanticdb.revision // use Scalafix compatible version
|
|
||||||
// semanticdbVersion := "4.3.24",
|
|
||||||
)
|
)
|
||||||
initialCommands in (console) := """ammonite.Main.main(Array.empty)"""
|
initialCommands in (console) := """ammonite.Main.main(Array.empty)"""
|
||||||
|
|
||||||
|
@ -47,6 +47,10 @@ class StaticLoggerBinder extends OdinLoggerBinder[IO] {
|
|||||||
.allocated
|
.allocated
|
||||||
.unsafeRunSync()
|
.unsafeRunSync()
|
||||||
|
|
||||||
|
val mainFileLogger2 = mainFileLogger.contramap(lm =>
|
||||||
|
lm.copy(message = lm.message.map(s => fansi.Str(s).plainText))
|
||||||
|
)
|
||||||
|
|
||||||
private lazy val (eventBusFileLogger, release3) =
|
private lazy val (eventBusFileLogger, release3) =
|
||||||
fileLogger[IO](
|
fileLogger[IO](
|
||||||
"eventbus.log",
|
"eventbus.log",
|
||||||
@ -72,15 +76,22 @@ class StaticLoggerBinder extends OdinLoggerBinder[IO] {
|
|||||||
case s if s.startsWith("com.jayfella.jme.jfx.util.JfxPlatform") =>
|
case s if s.startsWith("com.jayfella.jme.jfx.util.JfxPlatform") =>
|
||||||
defaultConsoleLogger.withMinimalLevel(Level.Info)
|
defaultConsoleLogger.withMinimalLevel(Level.Info)
|
||||||
|
|
||||||
// case s
|
case s
|
||||||
// if s.startsWith(
|
if s.startsWith(
|
||||||
// "wow.doge.mygame.subsystems.movement.PlayerMovementEventHandler"
|
"wow.doge.mygame.subsystems.movement.PlayerMovementEventHandler"
|
||||||
// ) =>
|
) =>
|
||||||
|
defaultConsoleLogger.withMinimalLevel(Level.Info)
|
||||||
|
case s
|
||||||
|
if s.startsWith(
|
||||||
|
"wow.doge.mygame.game.entities.NpcMovementActor"
|
||||||
|
) =>
|
||||||
|
defaultConsoleLogger.withMinimalLevel(Level.Trace) |+| mainFileLogger2
|
||||||
|
.withMinimalLevel(Level.Trace)
|
||||||
// defaultConsoleLogger.withMinimalLevel( Level.Trace) //selectively turn on trace logging for specific classes
|
// defaultConsoleLogger.withMinimalLevel( Level.Trace) //selectively turn on trace logging for specific classes
|
||||||
case s if s.startsWith("wow.doge.mygame.subsystems.events.EventBus") =>
|
case s if s.startsWith("wow.doge.mygame.subsystems.events.EventBus") =>
|
||||||
defaultConsoleLogger.withMinimalLevel(Level.Debug) |+| eventBusFileLogger
|
defaultConsoleLogger.withMinimalLevel(Level.Debug) |+| eventBusFileLogger
|
||||||
case s if s.startsWith("akka.actor") || s.startsWith("wow.doge.mygame") =>
|
case s if s.startsWith("akka.actor") || s.startsWith("wow.doge.mygame") =>
|
||||||
defaultConsoleLogger.withMinimalLevel(Level.Debug) |+| mainFileLogger
|
defaultConsoleLogger.withMinimalLevel(Level.Debug) |+| mainFileLogger2
|
||||||
case _ => //if wildcard case isn't provided, default logger is no-op
|
case _ => //if wildcard case isn't provided, default logger is no-op
|
||||||
defaultConsoleLogger.withMinimalLevel(Level.Debug)
|
defaultConsoleLogger.withMinimalLevel(Level.Debug)
|
||||||
}
|
}
|
||||||
|
@ -5,16 +5,16 @@ import scala.concurrent.duration._
|
|||||||
import _root_.monix.bio.BIOApp
|
import _root_.monix.bio.BIOApp
|
||||||
import _root_.monix.bio.Task
|
import _root_.monix.bio.Task
|
||||||
import _root_.monix.bio.UIO
|
import _root_.monix.bio.UIO
|
||||||
|
import akka.actor.typed.ActorSystem
|
||||||
|
import akka.actor.typed.SpawnProtocol
|
||||||
import akka.util.Timeout
|
import akka.util.Timeout
|
||||||
import cats.effect.ExitCode
|
import cats.effect.ExitCode
|
||||||
import cats.effect.Resource
|
import cats.effect.Resource
|
||||||
import cats.implicits._
|
import cats.implicits._
|
||||||
import com.softwaremill.macwire._
|
|
||||||
import io.odin._
|
import io.odin._
|
||||||
import io.odin.json.Formatter
|
import io.odin.json.Formatter
|
||||||
import io.odin.syntax._
|
import io.odin.syntax._
|
||||||
import scalafx.scene.control.TextArea
|
import scalafx.scene.control.TextArea
|
||||||
import wow.doge.mygame.game.GameAppResource
|
|
||||||
import wow.doge.mygame.utils.GenericConsoleStream
|
import wow.doge.mygame.utils.GenericConsoleStream
|
||||||
|
|
||||||
object Main extends BIOApp with MainModule {
|
object Main extends BIOApp with MainModule {
|
||||||
@ -34,25 +34,23 @@ object Main extends BIOApp with MainModule {
|
|||||||
Formatter.json
|
Formatter.json
|
||||||
).withAsync(timeWindow = 1.milliseconds, maxBufferSize = Some(2000))
|
).withAsync(timeWindow = 1.milliseconds, maxBufferSize = Some(2000))
|
||||||
jmeScheduler <- jMESchedulerResource
|
jmeScheduler <- jMESchedulerResource
|
||||||
actorSystem <- actorSystemResource(logger)
|
implicit0(actorSystem: ActorSystem[SpawnProtocol.Command]) <-
|
||||||
gameApp <- {
|
actorSystemResource(logger)
|
||||||
// new BulletAppState()
|
// gameApp <- {
|
||||||
// bas.setThreadingType(Thr)
|
// // new BulletAppState()
|
||||||
// gameAppResource(new StatsAppState())
|
// // bas.setThreadingType(Thr)
|
||||||
wire[GameAppResource].get
|
// // gameAppResource(new StatsAppState())
|
||||||
}
|
// wire[GameAppResource].get
|
||||||
|
// }
|
||||||
_ <- Resource.liftF(
|
_ <- Resource.liftF(
|
||||||
new MainApp(
|
new MainApp(
|
||||||
logger,
|
logger,
|
||||||
gameApp,
|
// gameApp,
|
||||||
actorSystem,
|
// actorSystem,
|
||||||
jmeScheduler,
|
jmeScheduler,
|
||||||
schedulers,
|
schedulers,
|
||||||
consoleStream
|
consoleStream
|
||||||
)(
|
)(actorSystem, timeout, actorSystem.scheduler).program
|
||||||
timeout,
|
|
||||||
actorSystem.scheduler
|
|
||||||
).program
|
|
||||||
)
|
)
|
||||||
|
|
||||||
} yield ()
|
} yield ()
|
||||||
@ -63,7 +61,7 @@ object Main extends BIOApp with MainModule {
|
|||||||
Console.withOut(consoleStream)(
|
Console.withOut(consoleStream)(
|
||||||
appResource(consoleStream)
|
appResource(consoleStream)
|
||||||
.use(_ => Task.unit >> Task(consoleStream.close()))
|
.use(_ => Task.unit >> Task(consoleStream.close()))
|
||||||
.onErrorHandle(_.printStackTrace())
|
.onErrorHandleWith(ex => UIO(ex.printStackTrace()))
|
||||||
.as(ExitCode.Success)
|
.as(ExitCode.Success)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import akka.actor.typed.ActorSystem
|
|||||||
import akka.actor.typed.Scheduler
|
import akka.actor.typed.Scheduler
|
||||||
import akka.actor.typed.SpawnProtocol
|
import akka.actor.typed.SpawnProtocol
|
||||||
import akka.util.Timeout
|
import akka.util.Timeout
|
||||||
|
import cats.effect.Resource
|
||||||
import cats.effect.concurrent.Deferred
|
import cats.effect.concurrent.Deferred
|
||||||
import com.jme3.app.state.AppStateManager
|
import com.jme3.app.state.AppStateManager
|
||||||
import com.jme3.asset.AssetManager
|
import com.jme3.asset.AssetManager
|
||||||
@ -46,98 +47,80 @@ import wow.doge.mygame.subsystems.scriptsystem.ScriptInitMode
|
|||||||
import wow.doge.mygame.subsystems.scriptsystem.ScriptSystemResource
|
import wow.doge.mygame.subsystems.scriptsystem.ScriptSystemResource
|
||||||
import wow.doge.mygame.utils.AkkaUtils
|
import wow.doge.mygame.utils.AkkaUtils
|
||||||
import wow.doge.mygame.utils.GenericConsoleStream
|
import wow.doge.mygame.utils.GenericConsoleStream
|
||||||
import wow.doge.mygame.utils.IOUtils
|
import cats.syntax.eq._
|
||||||
|
|
||||||
import EventsModule.GameEventBus
|
import wow.doge.mygame.subsystems.events.EventsModule.GameEventBus
|
||||||
|
|
||||||
class MainApp(
|
class MainApp(
|
||||||
logger: Logger[Task],
|
logger: Logger[Task],
|
||||||
gameApp: GameApp,
|
|
||||||
implicit val spawnProtocol: ActorSystem[SpawnProtocol.Command],
|
|
||||||
jmeThread: monix.execution.Scheduler,
|
jmeThread: monix.execution.Scheduler,
|
||||||
schedulers: Schedulers,
|
schedulers: Schedulers,
|
||||||
consoleStream: GenericConsoleStream[TextArea]
|
consoleStream: GenericConsoleStream[TextArea]
|
||||||
)(implicit
|
)(implicit
|
||||||
|
spawnProtocol: ActorSystem[SpawnProtocol.Command],
|
||||||
@annotation.unused timeout: Timeout,
|
@annotation.unused timeout: Timeout,
|
||||||
@annotation.unused scheduler: Scheduler
|
@annotation.unused scheduler: Scheduler
|
||||||
) {
|
) {
|
||||||
|
|
||||||
lazy val scriptSystemInit =
|
val scriptSystemInit =
|
||||||
new ScriptSystemResource(os.pwd, spawnProtocol, ScriptInitMode.Eager).init
|
new ScriptSystemResource(os.pwd, ScriptInitMode.Eager).init
|
||||||
|
|
||||||
def gameInit: Task[Fiber[Throwable, Unit]] =
|
val eventsModule = new EventsModule(spawnProtocol)
|
||||||
for {
|
|
||||||
eventsModule <- Task(new EventsModule(spawnProtocol))
|
|
||||||
playerEventBus <- eventsModule.playerEventBusTask
|
|
||||||
mainEventBus <- eventsModule.mainEventBusTask
|
|
||||||
tickEventBus <- eventsModule.tickEventBusTask
|
|
||||||
gameAppActor <- AkkaUtils.spawnActorL2(
|
|
||||||
GameAppActor.Props(tickEventBus).behavior,
|
|
||||||
"gameAppActor"
|
|
||||||
)
|
|
||||||
_ <- gameAppActor !! GameAppActor.Start
|
|
||||||
gameAppFib <- gameApp.start.executeOn(jmeThread).start
|
|
||||||
/**
|
|
||||||
* schedule a task to run on the JME thread and wait for it's completion
|
|
||||||
* before proceeding forward, as a signal that the JME thread has been
|
|
||||||
* initialized, otherwise we'll get NPEs trying to access the fields
|
|
||||||
* of the game app
|
|
||||||
*/
|
|
||||||
res <- gameApp.enqueueL(() => "done")
|
|
||||||
_ <- logger.info(s"Result = $res")
|
|
||||||
/**
|
|
||||||
* JME Thread has been initialized at this point. We can now access the
|
|
||||||
* field of the game application
|
|
||||||
*/
|
|
||||||
inputManager <- gameApp.inputManager
|
|
||||||
assetManager <- gameApp.assetManager
|
|
||||||
stateManager <- gameApp.stateManager
|
|
||||||
camera <- gameApp.camera
|
|
||||||
rootNode <- gameApp.rootNode
|
|
||||||
enqueueR <- Task(gameApp.enqueue _)
|
|
||||||
viewPort <- gameApp.viewPort
|
|
||||||
_ <- logger.info("before")
|
|
||||||
// jfxUI <- gameApp.jfxUI
|
|
||||||
consoleTextArea <- Task(new TextArea {
|
|
||||||
text = "hello \n"
|
|
||||||
editable = false
|
|
||||||
wrapText = true
|
|
||||||
// maxHeight = 150
|
|
||||||
// maxWidth = 300
|
|
||||||
})
|
|
||||||
// _ <- Task(consoleStream := consoleTextArea)
|
|
||||||
// _ <- Task(jfxUI += consoleTextArea)
|
|
||||||
_ <- logger.info("after")
|
|
||||||
bulletAppState <- Task(new BulletAppState())
|
|
||||||
_ <- Task(stateManager.attach(bulletAppState))
|
|
||||||
_ <- logger.info("Initializing console stream")
|
|
||||||
_ <- wire[MainAppDelegate].init(gameApp.scheduler)
|
|
||||||
} yield (gameAppFib)
|
|
||||||
|
|
||||||
lazy val program = for {
|
def gameInit: Resource[Task, Fiber[Throwable, Unit]] =
|
||||||
|
GameApp.resource(logger, jmeThread, schedulers).evalMap {
|
||||||
|
case gameApp -> gameAppFib =>
|
||||||
|
for {
|
||||||
|
playerEventBus <- eventsModule.playerEventBusTask
|
||||||
|
mainEventBus <- eventsModule.mainEventBusTask
|
||||||
|
tickEventBus <- eventsModule.tickEventBusTask
|
||||||
|
gameAppActor <- AkkaUtils.spawnActorL(
|
||||||
|
GameAppActor.Props(tickEventBus).behavior,
|
||||||
|
"gameAppActor"
|
||||||
|
)
|
||||||
|
_ <- gameAppActor !! GameAppActor.Start
|
||||||
|
inputManager <- gameApp.inputManager
|
||||||
|
assetManager <- gameApp.assetManager
|
||||||
|
stateManager <- gameApp.stateManager
|
||||||
|
camera <- gameApp.camera
|
||||||
|
rootNode <- gameApp.rootNode
|
||||||
|
enqueueR <- Task(gameApp.enqueue _)
|
||||||
|
viewPort <- gameApp.viewPort
|
||||||
|
_ <- logger.info("before")
|
||||||
|
// jfxUI <- gameApp.jfxUI
|
||||||
|
consoleTextArea <- Task(new TextArea {
|
||||||
|
text = "hello \n"
|
||||||
|
editable = false
|
||||||
|
wrapText = true
|
||||||
|
// maxHeight = 150
|
||||||
|
// maxWidth = 300
|
||||||
|
})
|
||||||
|
// _ <- Task(consoleStream := consoleTextArea)
|
||||||
|
// _ <- Task(jfxUI += consoleTextArea)
|
||||||
|
_ <- logger.info("after")
|
||||||
|
bulletAppState <- Task(new BulletAppState())
|
||||||
|
_ <- Task(stateManager.attach(bulletAppState))
|
||||||
|
_ <- logger.info("Initializing console stream")
|
||||||
|
_ <- wire[MainAppDelegate].init(gameApp.scheduler)
|
||||||
|
} yield gameAppFib
|
||||||
|
}
|
||||||
|
|
||||||
|
val program = for {
|
||||||
scriptSystem <- scriptSystemInit
|
scriptSystem <- scriptSystemInit
|
||||||
/**
|
|
||||||
* Signal for synchronization between the JavaFX launcher and the in-game JavaFX GUI
|
|
||||||
* Without this, we get a "Toolkit already initialized" exception. The launch button
|
|
||||||
* in the launcher completes the signal. The game init process which listens for this
|
|
||||||
* signal can then continue
|
|
||||||
*/
|
|
||||||
launchSignal <- Deferred[Task, Launcher.LauncherResult]
|
launchSignal <- Deferred[Task, Launcher.LauncherResult]
|
||||||
launcher <- new Launcher.Props(schedulers, launchSignal).create
|
launcher <- new Launcher.Props(schedulers, launchSignal).create
|
||||||
cancelToken <- launcher.init()
|
launchResult <- launcher.init.use(_ => launchSignal.get)
|
||||||
launchResult <- launchSignal.get
|
|
||||||
_ <- cancelToken.cancel
|
|
||||||
_ <-
|
_ <-
|
||||||
/**
|
/**
|
||||||
* User chose to quit
|
* User chose to quit
|
||||||
*/
|
*/
|
||||||
if (launchResult == LauncherResult.Exit)
|
if (launchResult === LauncherResult.Exit)
|
||||||
logger.info("Exiting")
|
logger.info("Exiting")
|
||||||
/**
|
/**
|
||||||
* User chose launch. Wait for game window to close
|
* User chose launch. Wait for game window to close
|
||||||
*/
|
*/
|
||||||
else
|
else
|
||||||
gameInit.flatMap(_.join)
|
gameInit.use(_.join)
|
||||||
} yield ()
|
} yield ()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +129,6 @@ class MainApp(
|
|||||||
*/
|
*/
|
||||||
class MainAppDelegate(
|
class MainAppDelegate(
|
||||||
gameApp: GameApp,
|
gameApp: GameApp,
|
||||||
implicit val spawnProtocol: ActorSystem[SpawnProtocol.Command],
|
|
||||||
loggerL: Logger[Task],
|
loggerL: Logger[Task],
|
||||||
playerEventBus: GameEventBus[PlayerEvent],
|
playerEventBus: GameEventBus[PlayerEvent],
|
||||||
tickEventBus: GameEventBus[TickEvent],
|
tickEventBus: GameEventBus[TickEvent],
|
||||||
@ -159,10 +141,11 @@ class MainAppDelegate(
|
|||||||
rootNode: Node @@ GameAppTags.RootNode,
|
rootNode: Node @@ GameAppTags.RootNode,
|
||||||
bulletAppState: BulletAppState
|
bulletAppState: BulletAppState
|
||||||
)(implicit
|
)(implicit
|
||||||
|
spawnProtocol: ActorSystem[SpawnProtocol.Command],
|
||||||
@annotation.unused timeout: Timeout,
|
@annotation.unused timeout: Timeout,
|
||||||
@annotation.unused scheduler: Scheduler
|
@annotation.unused scheduler: Scheduler
|
||||||
) {
|
) {
|
||||||
lazy val physicsSpace = bulletAppState.physicsSpace
|
val physicsSpace = bulletAppState.physicsSpace
|
||||||
def init(
|
def init(
|
||||||
appScheduler: monix.execution.Scheduler
|
appScheduler: monix.execution.Scheduler
|
||||||
// consoleStream: GenericConsoleStream[TextArea]
|
// consoleStream: GenericConsoleStream[TextArea]
|
||||||
@ -190,19 +173,21 @@ class MainAppDelegate(
|
|||||||
// johnActor <- createTestNpc(appScheduler, "John").executeOn(appScheduler)
|
// johnActor <- createTestNpc(appScheduler, "John").executeOn(appScheduler)
|
||||||
// _ <- johnActor !! NpcActorSupervisor.Move(ImVector3f(0, 0, 20))
|
// _ <- johnActor !! NpcActorSupervisor.Move(ImVector3f(0, 0, 20))
|
||||||
|
|
||||||
// _ <- (johnActor !! NpcActorSupervisor.Move(
|
// _ <-
|
||||||
// ImVector3f(-80, 0, 100)
|
// (johnActor !! NpcActorSupervisor.Move(
|
||||||
// )).executeAsync.delayExecution(2.seconds)
|
// ImVector3f(-30, 0, 10)
|
||||||
_ <-
|
// )).executeAsync
|
||||||
IOUtils
|
// .delayExecution(2.seconds)
|
||||||
.toIO(
|
// _ <-
|
||||||
rootNode
|
// IOUtils
|
||||||
.observableBreadthFirst()
|
// .toIO(
|
||||||
.doOnNext(spat => IOUtils.toTask(loggerL.debug(spat.getName())))
|
// rootNode
|
||||||
.completedL
|
// .observableBreadthFirst()
|
||||||
)
|
// .doOnNext(spat => IOUtils.toTask(loggerL.debug(spat.getName())))
|
||||||
.executeOn(appScheduler)
|
// .completedL
|
||||||
.startAndForget
|
// )
|
||||||
|
// .executeOn(appScheduler)
|
||||||
|
// .startAndForget
|
||||||
} yield ()
|
} yield ()
|
||||||
|
|
||||||
def createPlayerController(
|
def createPlayerController(
|
||||||
@ -210,14 +195,14 @@ class MainAppDelegate(
|
|||||||
): IO[PlayerController.Error, Unit] = {
|
): IO[PlayerController.Error, Unit] = {
|
||||||
val playerPos = ImVector3f.ZERO
|
val playerPos = ImVector3f.ZERO
|
||||||
val modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o"
|
val modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o"
|
||||||
lazy val playerPhysicsControl =
|
val playerPhysicsControl =
|
||||||
PlayerController.Defaults.defaultPlayerPhysicsControl
|
PlayerController.Defaults.defaultPlayerPhysicsControl
|
||||||
.taggedWith[PlayerControllerTags.PlayerTag]
|
.taggedWith[PlayerControllerTags.PlayerTag]
|
||||||
// lazy val camNode =
|
// lazy val camNode =
|
||||||
// PlayerController.Defaults
|
// PlayerController.Defaults
|
||||||
// .defaultCamerNode(camera, playerPos)
|
// .defaultCamerNode(camera, playerPos)
|
||||||
// .taggedWith[PlayerControllerTags.PlayerCameraNode]
|
// .taggedWith[PlayerControllerTags.PlayerCameraNode]
|
||||||
lazy val mbPlayerNode = PlayerController.Defaults
|
val mbPlayerNode = PlayerController.Defaults
|
||||||
.defaultPlayerNode(
|
.defaultPlayerNode(
|
||||||
assetManager,
|
assetManager,
|
||||||
modelPath,
|
modelPath,
|
||||||
@ -225,7 +210,7 @@ class MainAppDelegate(
|
|||||||
// camNode
|
// camNode
|
||||||
playerPhysicsControl
|
playerPhysicsControl
|
||||||
)
|
)
|
||||||
lazy val cameraPivotNode = new Node(EntityIds.CameraPivot.value)
|
val cameraPivotNode = new Node(EntityIds.CameraPivot.value)
|
||||||
.taggedWith[PlayerControllerTags.PlayerCameraPivotNode]
|
.taggedWith[PlayerControllerTags.PlayerCameraPivotNode]
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -258,11 +243,11 @@ class MainAppDelegate(
|
|||||||
) =
|
) =
|
||||||
// : IO[PlayerController.Error, Unit] =
|
// : IO[PlayerController.Error, Unit] =
|
||||||
{
|
{
|
||||||
val initialPos = ImVector3f(100, 0, 0)
|
val initialPos = ImVector3f(50, 5, 0)
|
||||||
// val modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o"
|
// val modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o"
|
||||||
lazy val npcPhysicsControl =
|
val npcPhysicsControl = new BetterCharacterControl(1.5f, 6f, 1f)
|
||||||
new BetterCharacterControl(1f, 2.1f, 10f)
|
// (1f, 2.1f, 10f)
|
||||||
// .withJumpForce(ImVector3f(0, 5f, 0))
|
.withJumpForce(ImVector3f(0, 5f, 0))
|
||||||
// val npcMovementActor = AkkaUtils.spawnActorL2(
|
// val npcMovementActor = AkkaUtils.spawnActorL2(
|
||||||
// new NpcMovementActor2.Props(
|
// new NpcMovementActor2.Props(
|
||||||
// initialPos,
|
// initialPos,
|
||||||
@ -271,13 +256,13 @@ class MainAppDelegate(
|
|||||||
// ).behavior,
|
// ).behavior,
|
||||||
// s"${npcName}-npcMovementActor"
|
// s"${npcName}-npcMovementActor"
|
||||||
// )
|
// )
|
||||||
lazy val mbNpcNode = PlayerController.Defaults.defaultNpcNode(
|
val mbNpcNode = PlayerController.Defaults.defaultNpcNode(
|
||||||
assetManager,
|
assetManager,
|
||||||
initialPos,
|
initialPos,
|
||||||
npcPhysicsControl,
|
npcPhysicsControl,
|
||||||
npcName
|
npcName
|
||||||
)
|
)
|
||||||
val npcActorTask = AkkaUtils.spawnActorL2(
|
val npcActorTask = AkkaUtils.spawnActorL(
|
||||||
NpcActorSupervisor
|
NpcActorSupervisor
|
||||||
.Props(
|
.Props(
|
||||||
new NpcMovementActor.Props(
|
new NpcMovementActor.Props(
|
||||||
@ -302,7 +287,7 @@ class MainAppDelegate(
|
|||||||
physicsSpace += npcNode
|
physicsSpace += npcNode
|
||||||
rootNode += npcNode
|
rootNode += npcNode
|
||||||
}
|
}
|
||||||
} yield (npcActor)
|
} yield npcActor
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,15 +11,14 @@ trait MainModule extends ExecutorsModule {
|
|||||||
def actorSystemResource(
|
def actorSystemResource(
|
||||||
logger: Logger[Task]
|
logger: Logger[Task]
|
||||||
): Resource[Task, ActorSystem[SpawnProtocol.Command]] =
|
): Resource[Task, ActorSystem[SpawnProtocol.Command]] =
|
||||||
Resource.make(logger.info("Creating Actor System") >> Task {
|
Resource.make(
|
||||||
ActorSystem(
|
logger.info("Creating Actor System") >> Task(
|
||||||
SpawnProtocol(),
|
ActorSystem(SpawnProtocol(), name = "GameActorSystem")
|
||||||
name = "GameActorSystem"
|
|
||||||
)
|
)
|
||||||
})(sys =>
|
)(sys =>
|
||||||
for {
|
for {
|
||||||
_ <- Task(sys.terminate())
|
_ <- Task(sys.terminate())
|
||||||
_ <- Task.fromFuture(sys.whenTerminated)
|
_ <- Task.deferFuture(sys.whenTerminated)
|
||||||
_ <- logger.info("Actor System Terminated")
|
_ <- logger.info("Actor System Terminated")
|
||||||
} yield ()
|
} yield ()
|
||||||
)
|
)
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package wow.doge.mygame.game
|
package wow.doge.mygame.game
|
||||||
|
|
||||||
|
import cats.effect.Resource
|
||||||
import cats.effect.concurrent.Deferred
|
import cats.effect.concurrent.Deferred
|
||||||
import com.jme3.app.state.AppStateManager
|
import com.jme3.app.state.AppStateManager
|
||||||
import com.jme3.asset.AssetManager
|
import com.jme3.asset.AssetManager
|
||||||
import com.jme3.input.InputManager
|
import com.jme3.input.InputManager
|
||||||
import com.jme3.scene.Node
|
import com.jme3.scene.Node
|
||||||
import com.jme3.scene.Spatial
|
import com.jme3.scene.Spatial
|
||||||
|
import com.jme3.system.AppSettings
|
||||||
import com.softwaremill.tagging._
|
import com.softwaremill.tagging._
|
||||||
import com.typesafe.scalalogging.{Logger => SLogger}
|
import com.typesafe.scalalogging.{Logger => SLogger}
|
||||||
import io.odin.Logger
|
import io.odin.Logger
|
||||||
@ -15,7 +17,13 @@ import monix.catnap.ConcurrentChannel
|
|||||||
import monix.catnap.ConsumerF
|
import monix.catnap.ConsumerF
|
||||||
import monix.catnap.Semaphore
|
import monix.catnap.Semaphore
|
||||||
import monix.eval.Coeval
|
import monix.eval.Coeval
|
||||||
|
import monix.execution.CancelablePromise
|
||||||
|
import monix.execution.Scheduler
|
||||||
|
import wow.doge.mygame.executors.Schedulers
|
||||||
import wow.doge.mygame.game.subsystems.ui.JFxUI
|
import wow.doge.mygame.game.subsystems.ui.JFxUI
|
||||||
|
import wow.doge.mygame.implicits._
|
||||||
|
import monix.execution.annotations.UnsafeBecauseImpure
|
||||||
|
import monix.reactive.Observable
|
||||||
|
|
||||||
sealed trait Error
|
sealed trait Error
|
||||||
case object FlyCamNotExists extends Error
|
case object FlyCamNotExists extends Error
|
||||||
@ -40,6 +48,8 @@ class GameApp(logger: Logger[Task], val app: SimpleAppExt) {
|
|||||||
def camera = Task(app.getCamera())
|
def camera = Task(app.getCamera())
|
||||||
def viewPort = Task(app.getViewPort())
|
def viewPort = Task(app.getViewPort())
|
||||||
def rootNode = Task(app.getRootNode().taggedWith[GameAppTags.RootNode])
|
def rootNode = Task(app.getRootNode().taggedWith[GameAppTags.RootNode])
|
||||||
|
def rootNode2 =
|
||||||
|
WrappedNode(app.getRootNode()).taggedWith[GameAppTags.RootNode]
|
||||||
// def rootNode2 = SynchedObject(app.getRootNode())
|
// def rootNode2 = SynchedObject(app.getRootNode())
|
||||||
def addToRootNode = rootNode.flatMap(rn => Task(new AddToNode(rn)))
|
def addToRootNode = rootNode.flatMap(rn => Task(new AddToNode(rn)))
|
||||||
def enqueue(cb: () => Unit) =
|
def enqueue(cb: () => Unit) =
|
||||||
@ -55,12 +65,57 @@ class GameApp(logger: Logger[Task], val app: SimpleAppExt) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class WrappedNode private (node: Node) {
|
||||||
|
|
||||||
|
// def +=(spat: Spatial) = lock.withPermit(Task(node.attachChild(spat)))
|
||||||
|
def children: Observable[Spatial] = node.observableChildren
|
||||||
|
def attachChild(n: Node): Task[Unit] = Task(node.attachChild(node))
|
||||||
|
def add(wn: WrappedNode): Task[Unit] =
|
||||||
|
Task(node.attachChild(wn.unsafeDelegate))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the underlying wrapped value
|
||||||
|
*/
|
||||||
|
@UnsafeBecauseImpure
|
||||||
|
def unsafeDelegate = node
|
||||||
|
}
|
||||||
|
object WrappedNode {
|
||||||
|
|
||||||
|
def apply(name: String) = new WrappedNode(new Node(name))
|
||||||
|
def apply(n: Node) = new WrappedNode(n)
|
||||||
|
implicit class WrappedNodeOps(private val wn: WrappedNode) extends AnyVal {
|
||||||
|
def +=(n: Node) = wn.attachChild(n)
|
||||||
|
def +=(wn: WrappedNode) = wn.add(wn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object GameApp {
|
object GameApp {
|
||||||
|
|
||||||
class WrappedNode(node: Node, lock: Semaphore[Task]) {
|
def resource(
|
||||||
|
logger: Logger[Task],
|
||||||
|
jmeScheduler: Scheduler,
|
||||||
|
schedulers: Schedulers
|
||||||
|
) =
|
||||||
|
Resource.make(
|
||||||
|
for {
|
||||||
|
startSignal <- Task(CancelablePromise[Unit]())
|
||||||
|
app <- Task(new SimpleAppExt(schedulers, startSignal))
|
||||||
|
_ <- Task {
|
||||||
|
val settings = new AppSettings(true)
|
||||||
|
settings.setVSync(true)
|
||||||
|
|
||||||
def +=(spat: Spatial) = lock.withPermit(Task(node.attachChild(spat)))
|
/**
|
||||||
}
|
* disables the launcher
|
||||||
|
* We'll be making our own launcher anyway
|
||||||
|
*/
|
||||||
|
app.setShowSettings(false)
|
||||||
|
app.setSettings(settings)
|
||||||
|
}
|
||||||
|
gameApp <- Task(new GameApp(logger, app))
|
||||||
|
fib <- gameApp.start.executeOn(jmeScheduler).start
|
||||||
|
_ <- Task.fromCancelablePromise(startSignal)
|
||||||
|
} yield gameApp -> fib
|
||||||
|
)(_._2.cancel)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronization wrapper for a mutable object
|
* Synchronization wrapper for a mutable object
|
||||||
|
@ -6,6 +6,7 @@ import akka.actor.typed.SupervisorStrategy
|
|||||||
import akka.actor.typed.scaladsl.Behaviors
|
import akka.actor.typed.scaladsl.Behaviors
|
||||||
import wow.doge.mygame.game.TickGenerator.Send
|
import wow.doge.mygame.game.TickGenerator.Send
|
||||||
import wow.doge.mygame.game.entities.GenericTimerActor
|
import wow.doge.mygame.game.entities.GenericTimerActor
|
||||||
|
import wow.doge.mygame.implicits._
|
||||||
import wow.doge.mygame.subsystems.events.EventBus
|
import wow.doge.mygame.subsystems.events.EventBus
|
||||||
import wow.doge.mygame.subsystems.events.EventsModule.GameEventBus
|
import wow.doge.mygame.subsystems.events.EventsModule.GameEventBus
|
||||||
import wow.doge.mygame.subsystems.events.TickEvent
|
import wow.doge.mygame.subsystems.events.TickEvent
|
||||||
@ -28,7 +29,7 @@ object GameAppActor {
|
|||||||
) {
|
) {
|
||||||
def behavior =
|
def behavior =
|
||||||
Behaviors.setup[Command] { ctx =>
|
Behaviors.setup[Command] { ctx =>
|
||||||
ctx.log.info("Hello from GameAppActor")
|
ctx.log.infoP("Hello from GameAppActor")
|
||||||
val renderTickGenerator =
|
val renderTickGenerator =
|
||||||
ctx.spawn(
|
ctx.spawn(
|
||||||
Behaviors
|
Behaviors
|
||||||
@ -78,7 +79,7 @@ object TickGenerator {
|
|||||||
object SubscribingActor {
|
object SubscribingActor {
|
||||||
def apply() =
|
def apply() =
|
||||||
Behaviors.receive[PhysicsTick.type] { (ctx, msg) =>
|
Behaviors.receive[PhysicsTick.type] { (ctx, msg) =>
|
||||||
ctx.log.debug(s"received event $msg")
|
ctx.log.debugP(s"received event $msg")
|
||||||
Behaviors.same
|
Behaviors.same
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,30 @@
|
|||||||
package wow.doge.mygame.game
|
package wow.doge.mygame.game
|
||||||
|
|
||||||
import cats.effect.Resource
|
|
||||||
import com.jme3.app.StatsAppState
|
|
||||||
import com.jme3.system.AppSettings
|
|
||||||
import io.odin.Logger
|
|
||||||
import monix.bio.Task
|
|
||||||
import monix.execution.Scheduler
|
|
||||||
import wow.doge.mygame.executors.Schedulers
|
|
||||||
class GameAppResource(
|
|
||||||
logger: Logger[Task],
|
|
||||||
jmeScheduler: Scheduler,
|
|
||||||
schedulers: Schedulers
|
|
||||||
) {
|
|
||||||
|
|
||||||
def get: Resource[Task, GameApp] =
|
// class GameAppResource(
|
||||||
Resource.make(
|
// logger: Logger[Task],
|
||||||
for {
|
// jmeScheduler: Scheduler,
|
||||||
_ <- logger.info("Creating game app")
|
// schedulers: Schedulers
|
||||||
appExt <- Task(new SimpleAppExt(schedulers, new StatsAppState()))
|
// ) {
|
||||||
app <- Task {
|
|
||||||
val settings = new AppSettings(true)
|
|
||||||
settings.setVSync(true)
|
|
||||||
|
|
||||||
/**
|
// def get: Resource[Task, GameApp] =
|
||||||
* disables the launcher
|
// Resource.make(
|
||||||
* We'll be making our own launcher anyway
|
// for {
|
||||||
*/
|
// _ <- logger.info("Creating game app")
|
||||||
appExt.setShowSettings(false)
|
// appExt <- Task(new SimpleAppExt(schedulers, new StatsAppState()))
|
||||||
appExt.setSettings(settings)
|
// app <- Task {
|
||||||
// JMERunner.runner = app
|
// val settings = new AppSettings(true)
|
||||||
new GameApp(logger, appExt)
|
// settings.setVSync(true)
|
||||||
}
|
|
||||||
} yield (app)
|
// /**
|
||||||
)(_ => logger.info("Closing game app"))
|
// * disables the launcher
|
||||||
}
|
// * We'll be making our own launcher anyway
|
||||||
|
// */
|
||||||
|
// appExt.setShowSettings(false)
|
||||||
|
// appExt.setSettings(settings)
|
||||||
|
// // JMERunner.runner = app
|
||||||
|
// new GameApp(logger, appExt)
|
||||||
|
// }
|
||||||
|
// } yield (app)
|
||||||
|
// )(_ => logger.info("Closing game app"))
|
||||||
|
// }
|
||||||
|
@ -6,17 +6,15 @@ import com.jme3.app.SimpleApplication
|
|||||||
import com.jme3.app.state.AppState
|
import com.jme3.app.state.AppState
|
||||||
import monix.bio.Task
|
import monix.bio.Task
|
||||||
import monix.execution.CancelableFuture
|
import monix.execution.CancelableFuture
|
||||||
|
import monix.execution.CancelablePromise
|
||||||
import monix.execution.Scheduler
|
import monix.execution.Scheduler
|
||||||
import monix.execution.atomic.Atomic
|
import monix.execution.atomic.Atomic
|
||||||
import monix.execution.{CancelablePromise => Promise}
|
|
||||||
import monix.reactive.MulticastStrategy
|
|
||||||
import monix.reactive.Observable
|
|
||||||
import monix.reactive.subjects.ConcurrentSubject
|
|
||||||
import wow.doge.mygame.executors.GUIExecutorService
|
import wow.doge.mygame.executors.GUIExecutorService
|
||||||
import wow.doge.mygame.executors.Schedulers
|
import wow.doge.mygame.executors.Schedulers
|
||||||
|
|
||||||
class SimpleAppExt(
|
class SimpleAppExt(
|
||||||
schedulers: Schedulers,
|
schedulers: Schedulers,
|
||||||
|
startSignal: CancelablePromise[Unit],
|
||||||
appStates: AppState*
|
appStates: AppState*
|
||||||
) extends SimpleApplication(appStates: _*) {
|
) extends SimpleApplication(appStates: _*) {
|
||||||
import SimpleAppExt._
|
import SimpleAppExt._
|
||||||
@ -26,32 +24,26 @@ class SimpleAppExt(
|
|||||||
*/
|
*/
|
||||||
private lazy val taskQueue2 = Atomic(Queue.empty[MyTask[_]])
|
private lazy val taskQueue2 = Atomic(Queue.empty[MyTask[_]])
|
||||||
|
|
||||||
private val tickSubject =
|
// def tickObservable: Observable[Float] = tickSubject
|
||||||
ConcurrentSubject[Float](multicast = MulticastStrategy.publish)(
|
|
||||||
schedulers.async
|
|
||||||
)
|
|
||||||
|
|
||||||
def tickObservable: Observable[Float] = tickSubject
|
override def simpleInitApp(): Unit = {
|
||||||
|
startSignal.success(())
|
||||||
override def simpleInitApp(): Unit = {}
|
|
||||||
|
|
||||||
override def simpleUpdate(tpf: Float): Unit = {
|
|
||||||
tickSubject.onNext(tpf)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def simpleUpdate(tpf: Float): Unit = {}
|
||||||
|
|
||||||
override def stop(): Unit = {
|
override def stop(): Unit = {
|
||||||
tickSubject.onComplete()
|
|
||||||
super.stop()
|
super.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
def enqueueScala[T](cb: () => T): CancelableFuture[T] = {
|
def enqueueFuture[T](cb: () => T): CancelableFuture[T] = {
|
||||||
val p = Promise[T]()
|
val p = CancelablePromise[T]()
|
||||||
taskQueue2.transform(_ :+ MyTask(p, cb))
|
taskQueue2.transform(_ :+ MyTask(p, cb))
|
||||||
p.future
|
p.future
|
||||||
}
|
}
|
||||||
|
|
||||||
def enqueueL[T](cb: () => T): Task[T] =
|
def enqueueL[T](cb: () => T): Task[T] =
|
||||||
Task.deferFuture(enqueueScala(cb))
|
Task.deferFuture(enqueueFuture(cb))
|
||||||
|
|
||||||
override protected def runQueuedTasks(): Unit = {
|
override protected def runQueuedTasks(): Unit = {
|
||||||
taskQueue2.transform { current =>
|
taskQueue2.transform { current =>
|
||||||
@ -73,7 +65,7 @@ class SimpleAppExt(
|
|||||||
lazy val scheduler = Scheduler(JMEExecutorService)
|
lazy val scheduler = Scheduler(JMEExecutorService)
|
||||||
}
|
}
|
||||||
object SimpleAppExt {
|
object SimpleAppExt {
|
||||||
private[game] case class MyTask[T](p: Promise[T], cb: () => T)
|
private[game] case class MyTask[T](p: CancelablePromise[T], cb: () => T)
|
||||||
}
|
}
|
||||||
|
|
||||||
// val ship = ed.createEntity()
|
// val ship = ed.createEntity()
|
||||||
|
@ -36,11 +36,11 @@ object TestActor {
|
|||||||
// )
|
// )
|
||||||
// ) {
|
// ) {
|
||||||
// case Success(value) =>
|
// case Success(value) =>
|
||||||
// ctx.log.debug("Received Value")
|
// ctx.log.debugP("Received Value")
|
||||||
// ctx.log.debug(value.toString())
|
// ctx.log.debugP(value.toString())
|
||||||
// Done
|
// Done
|
||||||
// case Failure(exception) =>
|
// case Failure(exception) =>
|
||||||
// ctx.log.debug(s"Received Error ${exception.getMessage()}")
|
// ctx.log.debugP(s"Received Error ${exception.getMessage()}")
|
||||||
// Done
|
// Done
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
@ -60,24 +60,24 @@ object TestActor {
|
|||||||
// .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
|
// .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
|
||||||
// ) {
|
// ) {
|
||||||
// case Success(value) => {
|
// case Success(value) => {
|
||||||
// ctx.log.debug(value.toString())
|
// ctx.log.debugP(value.toString())
|
||||||
// ctx.ask(
|
// ctx.ask(
|
||||||
// scriptStorer,
|
// scriptStorer,
|
||||||
// ScriptStoringActor
|
// ScriptStoringActor
|
||||||
// .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
|
// .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
|
||||||
// ) {
|
// ) {
|
||||||
// case Success(value) => {
|
// case Success(value) => {
|
||||||
// ctx.log.debug(value.toString())
|
// ctx.log.debugP(value.toString())
|
||||||
// Done
|
// Done
|
||||||
// }
|
// }
|
||||||
// case Failure(exception) =>
|
// case Failure(exception) =>
|
||||||
// ctx.log.debug(exception.getMessage())
|
// ctx.log.debugP(exception.getMessage())
|
||||||
// Done
|
// Done
|
||||||
// }
|
// }
|
||||||
// Done
|
// Done
|
||||||
// }
|
// }
|
||||||
// case Failure(exception) =>
|
// case Failure(exception) =>
|
||||||
// ctx.log.debug(exception.getMessage())
|
// ctx.log.debugP(exception.getMessage())
|
||||||
// Done
|
// Done
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
@ -193,23 +193,23 @@ class MovementActor(
|
|||||||
// val walkDir = new Vector3f
|
// val walkDir = new Vector3f
|
||||||
val dir = state.cardinalDir
|
val dir = state.cardinalDir
|
||||||
if (dir.up) {
|
if (dir.up) {
|
||||||
ctx.log.debug("up")
|
ctx.log.debugP("up")
|
||||||
// ctx.log.debug(Thread.currentThread().getName())
|
// ctx.log.debugP(Thread.currentThread().getName())
|
||||||
// walkDir.addLocal(0, 0, -1)
|
// walkDir.addLocal(0, 0, -1)
|
||||||
walkDir += camDir
|
walkDir += camDir
|
||||||
}
|
}
|
||||||
if (dir.left) {
|
if (dir.left) {
|
||||||
ctx.log.debug("left")
|
ctx.log.debugP("left")
|
||||||
// walkDir.addLocal(-1, 0, 0)
|
// walkDir.addLocal(-1, 0, 0)
|
||||||
walkDir.addLocal(camLeft)
|
walkDir.addLocal(camLeft)
|
||||||
}
|
}
|
||||||
if (dir.right) {
|
if (dir.right) {
|
||||||
ctx.log.debug("right")
|
ctx.log.debugP("right")
|
||||||
// walkDir.addLocal(1, 0, 0)
|
// walkDir.addLocal(1, 0, 0)
|
||||||
walkDir.addLocal(camLeft.negateLocal())
|
walkDir.addLocal(camLeft.negateLocal())
|
||||||
}
|
}
|
||||||
if (dir.down) {
|
if (dir.down) {
|
||||||
ctx.log.debug("down")
|
ctx.log.debugP("down")
|
||||||
walkDir.addLocal(camDir.negateLocal())
|
walkDir.addLocal(camDir.negateLocal())
|
||||||
// walkDir.addLocal(0, 0, 1)
|
// walkDir.addLocal(0, 0, 1)
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,8 @@ object NpcActorSupervisor {
|
|||||||
private case class LogError(err: Throwable) extends Command
|
private case class LogError(err: Throwable) extends Command
|
||||||
private case object NoOp extends Command
|
private case object NoOp extends Command
|
||||||
|
|
||||||
|
private case class MovementFailed(err: Throwable) extends Command
|
||||||
|
|
||||||
final case class Props(
|
final case class Props(
|
||||||
npcMovementActorBehavior: Behavior[NpcMovementActor.Command],
|
npcMovementActorBehavior: Behavior[NpcMovementActor.Command],
|
||||||
npcName: String,
|
npcName: String,
|
||||||
@ -82,7 +84,7 @@ class NpcActorSupervisor(
|
|||||||
|
|
||||||
def idle(state: State): Behavior[NpcActorSupervisor.Command] =
|
def idle(state: State): Behavior[NpcActorSupervisor.Command] =
|
||||||
Behaviors.setup { _ =>
|
Behaviors.setup { _ =>
|
||||||
ctx.log.debug("Inside Idle State")
|
ctx.log.debugP("Inside Idle State")
|
||||||
Behaviors.receiveMessage[Command] {
|
Behaviors.receiveMessage[Command] {
|
||||||
case m @ Move(pos) =>
|
case m @ Move(pos) =>
|
||||||
ctx.ask(
|
ctx.ask(
|
||||||
@ -97,7 +99,7 @@ class NpcActorSupervisor(
|
|||||||
moving(state, move.pos, signal)
|
moving(state, move.pos, signal)
|
||||||
|
|
||||||
case LogError(err) =>
|
case LogError(err) =>
|
||||||
ctx.log.warn(err.getMessage())
|
ctx.log.warnP(err.getMessage())
|
||||||
Behaviors.same
|
Behaviors.same
|
||||||
case _ => Behaviors.unhandled
|
case _ => Behaviors.unhandled
|
||||||
}
|
}
|
||||||
@ -117,12 +119,16 @@ class NpcActorSupervisor(
|
|||||||
// )
|
// )
|
||||||
ctx.pipeToSelf(signal) {
|
ctx.pipeToSelf(signal) {
|
||||||
case Success(value) => DoneMoving
|
case Success(value) => DoneMoving
|
||||||
case Failure(exception) => LogError(exception)
|
case Failure(exception) => MovementFailed(exception)
|
||||||
}
|
}
|
||||||
Behaviors.receiveMessagePartial[Command] {
|
Behaviors.receiveMessagePartial[Command] {
|
||||||
case LogError(err) =>
|
case LogError(err) =>
|
||||||
ctx.log.error(err.getMessage())
|
ctx.log.error(err.getMessage())
|
||||||
Behaviors.same
|
Behaviors.same
|
||||||
|
case MovementFailed(err) =>
|
||||||
|
ctx.self ! LogError(err)
|
||||||
|
movementTimer ! GenericTimerActor.Stop
|
||||||
|
idle(state)
|
||||||
case m @ Move(pos) =>
|
case m @ Move(pos) =>
|
||||||
movementTimer ! GenericTimerActor.Stop
|
movementTimer ! GenericTimerActor.Stop
|
||||||
children.npcMovementActor ! NpcMovementActor.StopMoving
|
children.npcMovementActor ! NpcMovementActor.StopMoving
|
||||||
@ -132,7 +138,7 @@ class NpcActorSupervisor(
|
|||||||
NpcMovementActor.MoveTo(pos, _)
|
NpcMovementActor.MoveTo(pos, _)
|
||||||
) {
|
) {
|
||||||
case Success(signal) => InternalMove(m, signal)
|
case Success(signal) => InternalMove(m, signal)
|
||||||
case Failure(exception) => LogError(exception)
|
case Failure(exception) => MovementFailed(exception)
|
||||||
}
|
}
|
||||||
Behaviors.same
|
Behaviors.same
|
||||||
case InternalMove(move, signal) =>
|
case InternalMove(move, signal) =>
|
||||||
@ -190,12 +196,6 @@ class NpcMovementActor[T](
|
|||||||
case AskPosition(replyTo) =>
|
case AskPosition(replyTo) =>
|
||||||
replyTo ! location
|
replyTo ! location
|
||||||
Behaviors.same
|
Behaviors.same
|
||||||
case StopMoving =>
|
|
||||||
ctx.log.debug(
|
|
||||||
"Position at Stop = " + location.toString
|
|
||||||
)
|
|
||||||
props.enqueueR(() => cm.stop(props.movable))
|
|
||||||
receive(state)
|
|
||||||
case MoveTo(
|
case MoveTo(
|
||||||
target: ImVector3f,
|
target: ImVector3f,
|
||||||
replyTo: ActorRef[CancelableFuture[DoneMoving.type]]
|
replyTo: ActorRef[CancelableFuture[DoneMoving.type]]
|
||||||
@ -204,7 +204,6 @@ class NpcMovementActor[T](
|
|||||||
val p = CancelablePromise[DoneMoving.type]()
|
val p = CancelablePromise[DoneMoving.type]()
|
||||||
replyTo ! p.future
|
replyTo ! p.future
|
||||||
ticking(p, target, state)
|
ticking(p, target, state)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def ticking(
|
def ticking(
|
||||||
@ -214,7 +213,7 @@ class NpcMovementActor[T](
|
|||||||
): Behavior[NpcMovementActor.Command] =
|
): Behavior[NpcMovementActor.Command] =
|
||||||
Behaviors.receiveMessagePartial {
|
Behaviors.receiveMessagePartial {
|
||||||
case StopMoving =>
|
case StopMoving =>
|
||||||
ctx.log.debug(
|
ctx.log.debugP(
|
||||||
"Position at Stop = " + location.toString
|
"Position at Stop = " + location.toString
|
||||||
)
|
)
|
||||||
props.enqueueR(() => cm.stop(props.movable))
|
props.enqueueR(() => cm.stop(props.movable))
|
||||||
@ -225,12 +224,11 @@ class NpcMovementActor[T](
|
|||||||
if (dst <= 10f) {
|
if (dst <= 10f) {
|
||||||
ctx.self ! StopMoving
|
ctx.self ! StopMoving
|
||||||
reachDestination.success(DoneMoving)
|
reachDestination.success(DoneMoving)
|
||||||
receive(state)
|
|
||||||
} else {
|
} else {
|
||||||
ctx.log.trace("Difference = " + dst.toString())
|
ctx.log.traceP("Difference = " + dst.toString())
|
||||||
ctx.log.trace("Current pos = " + location.toString())
|
ctx.log.traceP("Current pos = " + location.toString())
|
||||||
Behaviors.same
|
|
||||||
}
|
}
|
||||||
|
Behaviors.same
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ object PlayerActorSupervisor {
|
|||||||
ctx.log.info("Hello from PlayerActor")
|
ctx.log.info("Hello from PlayerActor")
|
||||||
|
|
||||||
// spawn children actors
|
// spawn children actors
|
||||||
lazy val movementActor =
|
val movementActor =
|
||||||
ctx.spawn(
|
ctx.spawn(
|
||||||
Behaviors
|
Behaviors
|
||||||
.supervise(imMovementActorBehavior)
|
.supervise(imMovementActorBehavior)
|
||||||
|
@ -29,6 +29,7 @@ import wow.doge.mygame.subsystems.events.PlayerEvent
|
|||||||
import wow.doge.mygame.subsystems.events.TickEvent
|
import wow.doge.mygame.subsystems.events.TickEvent
|
||||||
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
||||||
import wow.doge.mygame.utils.AkkaUtils
|
import wow.doge.mygame.utils.AkkaUtils
|
||||||
|
import com.softwaremill.macwire._
|
||||||
|
|
||||||
object PlayerControllerTags {
|
object PlayerControllerTags {
|
||||||
sealed trait PlayerTag
|
sealed trait PlayerTag
|
||||||
@ -47,7 +48,6 @@ object PlayerController {
|
|||||||
loggerL: Logger[Task],
|
loggerL: Logger[Task],
|
||||||
physicsSpace: PhysicsSpace,
|
physicsSpace: PhysicsSpace,
|
||||||
initialPlayerPos: ImVector3f = ImVector3f.ZERO,
|
initialPlayerPos: ImVector3f = ImVector3f.ZERO,
|
||||||
spawnProtocol: ActorRef[SpawnProtocol.Command],
|
|
||||||
playerEventBus: GameEventBus[PlayerEvent],
|
playerEventBus: GameEventBus[PlayerEvent],
|
||||||
playerPhysicsControl: BetterCharacterControl,
|
playerPhysicsControl: BetterCharacterControl,
|
||||||
appScheduler: monix.execution.Scheduler,
|
appScheduler: monix.execution.Scheduler,
|
||||||
@ -56,29 +56,34 @@ object PlayerController {
|
|||||||
cameraPivotNode: Node @@ PlayerControllerTags.PlayerCameraPivotNode,
|
cameraPivotNode: Node @@ PlayerControllerTags.PlayerCameraPivotNode,
|
||||||
tickEventBus: GameEventBus[TickEvent],
|
tickEventBus: GameEventBus[TickEvent],
|
||||||
camera: Camera
|
camera: Camera
|
||||||
)(implicit timeout: Timeout, scheduler: Scheduler) {
|
)(implicit
|
||||||
|
spawnProtocol: ActorRef[SpawnProtocol.Command],
|
||||||
|
timeout: Timeout,
|
||||||
|
scheduler: Scheduler
|
||||||
|
) {
|
||||||
|
val playerActorBehavior = {
|
||||||
|
val movementActorBeh = new ImMovementActor.Props(
|
||||||
|
enqueueR,
|
||||||
|
playerPhysicsControl,
|
||||||
|
camera
|
||||||
|
).behavior
|
||||||
|
val cameraActorBeh = new PlayerCameraActor.Props(
|
||||||
|
cameraPivotNode,
|
||||||
|
enqueueR,
|
||||||
|
playerNode.getWorldTranslation _
|
||||||
|
).behavior
|
||||||
|
new PlayerActorSupervisor.Props(
|
||||||
|
playerEventBus,
|
||||||
|
tickEventBus,
|
||||||
|
movementActorBeh,
|
||||||
|
cameraActorBeh
|
||||||
|
).behavior(playerPhysicsControl)
|
||||||
|
}
|
||||||
val create: IO[Error, Unit] =
|
val create: IO[Error, Unit] =
|
||||||
(for {
|
(for {
|
||||||
playerActor <- AkkaUtils.spawnActorL(
|
playerActor <- AkkaUtils.spawnActorL(
|
||||||
spawnProtocol,
|
playerActorBehavior,
|
||||||
"playerActorSupervisor",
|
"playerActorSupervisor"
|
||||||
new PlayerActorSupervisor.Props(
|
|
||||||
playerEventBus,
|
|
||||||
// playerCameraEventBus,
|
|
||||||
tickEventBus,
|
|
||||||
new ImMovementActor.Props(
|
|
||||||
enqueueR,
|
|
||||||
playerPhysicsControl,
|
|
||||||
camera
|
|
||||||
).behavior,
|
|
||||||
// wireWith(PlayerCameraEventListener.apply _)
|
|
||||||
// PlayerCameraEventListener()
|
|
||||||
new PlayerCameraActor.Props(
|
|
||||||
cameraPivotNode,
|
|
||||||
enqueueR,
|
|
||||||
playerNode.getWorldTranslation _
|
|
||||||
).behavior
|
|
||||||
).behavior(playerPhysicsControl)
|
|
||||||
)
|
)
|
||||||
_ <- Task(rootNode += playerNode)
|
_ <- Task(rootNode += playerNode)
|
||||||
_ <- IO {
|
_ <- IO {
|
||||||
@ -88,9 +93,7 @@ object PlayerController {
|
|||||||
cameraPivotNode += cameraNode
|
cameraPivotNode += cameraNode
|
||||||
// playerNode += cameraPivotNode
|
// playerNode += cameraPivotNode
|
||||||
rootNode += cameraPivotNode
|
rootNode += cameraPivotNode
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} yield ())
|
} yield ())
|
||||||
.onErrorHandleWith(e => IO.raiseError(GenericError(e.getMessage())))
|
.onErrorHandleWith(e => IO.raiseError(GenericError(e.getMessage())))
|
||||||
.executeOn(appScheduler)
|
.executeOn(appScheduler)
|
||||||
@ -101,10 +104,10 @@ object PlayerController {
|
|||||||
modelPath: os.RelPath,
|
modelPath: os.RelPath,
|
||||||
cam: Camera
|
cam: Camera
|
||||||
)(assetManager: AssetManager, bulletAppState: BulletAppState) = {
|
)(assetManager: AssetManager, bulletAppState: BulletAppState) = {
|
||||||
lazy val playerPos = ImVector3f.ZERO
|
val playerPos = ImVector3f.ZERO
|
||||||
lazy val playerPhysicsControl = new BetterCharacterControl(1.5f, 6f, 1f)
|
val playerPhysicsControl = new BetterCharacterControl(1.5f, 6f, 1f)
|
||||||
.withJumpForce(ImVector3f(0, 5f, 0))
|
.withJumpForce(ImVector3f(0, 5f, 0))
|
||||||
lazy val playerNode = new Node("PlayerNode")
|
val playerNode = new Node("PlayerNode")
|
||||||
.withChildren(
|
.withChildren(
|
||||||
assetManager
|
assetManager
|
||||||
.loadModel(modelPath)
|
.loadModel(modelPath)
|
||||||
|
@ -18,10 +18,11 @@ import wow.doge.mygame.subsystems.events.PlayerCameraEvent
|
|||||||
import wow.doge.mygame.subsystems.events.PlayerEvent
|
import wow.doge.mygame.subsystems.events.PlayerEvent
|
||||||
import wow.doge.mygame.subsystems.events.PlayerMovementEvent
|
import wow.doge.mygame.subsystems.events.PlayerMovementEvent
|
||||||
import wow.doge.mygame.utils.IOUtils._
|
import wow.doge.mygame.utils.IOUtils._
|
||||||
|
import monix.bio.Task
|
||||||
|
|
||||||
object GameInputHandler {
|
object GameInputHandler {
|
||||||
|
|
||||||
final class Props(
|
class Props(
|
||||||
inputManager: InputManager,
|
inputManager: InputManager,
|
||||||
playerEventBus: GameEventBus[PlayerEvent]
|
playerEventBus: GameEventBus[PlayerEvent]
|
||||||
// playerCameraEventBus: GameEventBus[PlayerCameraEvent]
|
// playerCameraEventBus: GameEventBus[PlayerCameraEvent]
|
||||||
@ -29,44 +30,44 @@ object GameInputHandler {
|
|||||||
) {
|
) {
|
||||||
def begin =
|
def begin =
|
||||||
for {
|
for {
|
||||||
_ <- UIO(setupMovementKeys(inputManager))
|
_ <- Task(setupMovementKeys(inputManager))
|
||||||
// _ <- UIO(setupAnalogMovementKeys)
|
// _ <- UIO(setupAnalogMovementKeys)
|
||||||
_ <- UIO(setupCameraKeys())
|
_ <- Task(setupCameraKeys())
|
||||||
_ <- toIO(
|
_ <- toIO(
|
||||||
generateMovementInputEvents(
|
me.Task.parSequence(
|
||||||
inputManager,
|
Seq(
|
||||||
playerEventBus
|
generateMovementInputEvents(
|
||||||
).completedL.startAndForget
|
inputManager,
|
||||||
)
|
playerEventBus
|
||||||
_ <- toIO(
|
).completedL,
|
||||||
generateAnalogMovementEvents(
|
// generateAnalogMovementEvents(
|
||||||
inputManager,
|
// inputManager,
|
||||||
playerEventBus
|
// playerEventBus
|
||||||
).completedL.startAndForget
|
// ).completedL,
|
||||||
)
|
generateCameraEvents(
|
||||||
_ <- toIO(
|
inputManager,
|
||||||
generateCameraEvents(
|
playerEventBus
|
||||||
inputManager,
|
).completedL,
|
||||||
playerEventBus
|
Ref
|
||||||
).completedL.startAndForget
|
.of[me.Task, Boolean](false)
|
||||||
)
|
.flatMap(value => cursorToggle(value))
|
||||||
_ <- toIO(
|
)
|
||||||
Ref.of[me.Task, Boolean](false).flatMap(value => cursorToggle(value))
|
)
|
||||||
)
|
).startAndForget
|
||||||
} yield ()
|
} yield ()
|
||||||
|
|
||||||
def setupMovementKeys(inputManager: InputManager) =
|
def setupMovementKeys(inputManager: InputManager) =
|
||||||
inputManager.withEnumMappings(PlayerMovementInput) {
|
inputManager.withEnumMappings(PlayerMovementInput) {
|
||||||
case PlayerMovementInput.WalkRight =>
|
case PlayerMovementInput.WalkRight =>
|
||||||
Seq(new KeyTrigger(KeyInput.KEY_D))
|
new KeyTrigger(KeyInput.KEY_D) :: Nil
|
||||||
case PlayerMovementInput.WalkLeft =>
|
case PlayerMovementInput.WalkLeft =>
|
||||||
Seq(new KeyTrigger(KeyInput.KEY_A))
|
new KeyTrigger(KeyInput.KEY_A) :: Nil
|
||||||
case PlayerMovementInput.WalkForward =>
|
case PlayerMovementInput.WalkForward =>
|
||||||
Seq(new KeyTrigger(KeyInput.KEY_W))
|
new KeyTrigger(KeyInput.KEY_W) :: Nil
|
||||||
case PlayerMovementInput.WalkBackward =>
|
case PlayerMovementInput.WalkBackward =>
|
||||||
Seq(new KeyTrigger(KeyInput.KEY_S))
|
new KeyTrigger(KeyInput.KEY_S) :: Nil
|
||||||
case PlayerMovementInput.Jump =>
|
case PlayerMovementInput.Jump =>
|
||||||
Seq(new KeyTrigger(KeyInput.KEY_SPACE))
|
new KeyTrigger(KeyInput.KEY_SPACE) :: Nil
|
||||||
}
|
}
|
||||||
|
|
||||||
def setupAnalogMovementKeys() =
|
def setupAnalogMovementKeys() =
|
||||||
@ -124,7 +125,6 @@ object GameInputHandler {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
.completedL
|
.completedL
|
||||||
.startAndForget
|
|
||||||
} yield ()
|
} yield ()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,15 +14,15 @@ object DefaultGameLevel {
|
|||||||
assetManager: AssetManager,
|
assetManager: AssetManager,
|
||||||
viewPort: ViewPort
|
viewPort: ViewPort
|
||||||
) = {
|
) = {
|
||||||
lazy val sceneModel: Spatial = assetManager.loadModel("main.scene")
|
val sceneModel: Spatial = assetManager.loadModel("main.scene")
|
||||||
lazy val sceneShape = CollisionShapeFactory.createMeshShape(
|
val sceneShape = CollisionShapeFactory.createMeshShape(
|
||||||
sceneModel.toNode match {
|
sceneModel.toNode match {
|
||||||
case Right(node) => node
|
case Right(node) => node
|
||||||
case Left(ex) =>
|
case Left(ex) =>
|
||||||
throw new NotImplementedError("No fallback sceneshape")
|
throw new NotImplementedError("No fallback sceneshape")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
lazy val landscape: RigidBodyControl =
|
val landscape: RigidBodyControl =
|
||||||
new RigidBodyControl(sceneShape, 0)
|
new RigidBodyControl(sceneShape, 0)
|
||||||
|
|
||||||
viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f))
|
viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f))
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package wow.doge.mygame.game.subsystems.movement
|
package wow.doge.mygame.game.subsystems.movement
|
||||||
|
|
||||||
|
import cats.Id
|
||||||
import com.jme3.bullet.control.BetterCharacterControl
|
import com.jme3.bullet.control.BetterCharacterControl
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import com.jme3.math.Quaternion
|
import com.jme3.math.Quaternion
|
||||||
@ -8,7 +9,6 @@ import monix.eval.Coeval
|
|||||||
import wow.doge.mygame.implicits._
|
import wow.doge.mygame.implicits._
|
||||||
import wow.doge.mygame.math.ImVector3f
|
import wow.doge.mygame.math.ImVector3f
|
||||||
import wow.doge.mygame.subsystems.movement.RotateDir
|
import wow.doge.mygame.subsystems.movement.RotateDir
|
||||||
|
|
||||||
// experiment to see if it would be useful to use an effect wrapper for a typeclass like this
|
// experiment to see if it would be useful to use an effect wrapper for a typeclass like this
|
||||||
trait CanMove2[-A, F[_]] {
|
trait CanMove2[-A, F[_]] {
|
||||||
// def getDirection(cam: Camera, cardinalDir: CardinalDirection): ImVector3f
|
// def getDirection(cam: Camera, cardinalDir: CardinalDirection): ImVector3f
|
||||||
@ -19,7 +19,35 @@ trait CanMove2[-A, F[_]] {
|
|||||||
def rotate(inst: A, rotateDir: RotateDir): F[Unit]
|
def rotate(inst: A, rotateDir: RotateDir): F[Unit]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object Test {
|
||||||
|
val x = new BetterCharacterControl(4, 10, 5)
|
||||||
|
def test[T](x: T)(implicit cm: CanMove2[T, Id]) = {
|
||||||
|
cm.move(x, ImVector3f.ZERO)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object CanMove2 {
|
object CanMove2 {
|
||||||
|
implicit val testImpl = new CanMove2[BetterCharacterControl, Id] {
|
||||||
|
|
||||||
|
override def move(
|
||||||
|
inst: BetterCharacterControl,
|
||||||
|
direction: ImVector3f,
|
||||||
|
speedFactor: Float
|
||||||
|
): Id[Unit] = {}
|
||||||
|
|
||||||
|
override def location(inst: BetterCharacterControl): Id[ImVector3f] =
|
||||||
|
ImVector3f.ZERO
|
||||||
|
|
||||||
|
override def jump(inst: BetterCharacterControl): Id[Unit] = ???
|
||||||
|
|
||||||
|
override def stop(inst: BetterCharacterControl): Id[Unit] = ???
|
||||||
|
|
||||||
|
override def rotate(
|
||||||
|
inst: BetterCharacterControl,
|
||||||
|
rotateDir: RotateDir
|
||||||
|
): Id[Unit] = ???
|
||||||
|
|
||||||
|
}
|
||||||
implicit val implCanMoveForBetterCharacterControl =
|
implicit val implCanMoveForBetterCharacterControl =
|
||||||
new CanMove2[BetterCharacterControl, Coeval] {
|
new CanMove2[BetterCharacterControl, Coeval] {
|
||||||
override def move(
|
override def move(
|
||||||
|
@ -84,7 +84,7 @@ class ImMovementActor[T](
|
|||||||
|
|
||||||
case Tick =>
|
case Tick =>
|
||||||
val walkDir =
|
val walkDir =
|
||||||
getDirection2(state.cardinalDir, ctx.log.trace)
|
getDirection2(state.cardinalDir, ctx.log.traceP)
|
||||||
// if (walkDir != ImVector3f.ZERO) {
|
// if (walkDir != ImVector3f.ZERO) {
|
||||||
val tmp = walkDir * 25f * (1f / 144)
|
val tmp = walkDir * 25f * (1f / 144)
|
||||||
props.enqueueR { () =>
|
props.enqueueR { () =>
|
||||||
@ -94,7 +94,10 @@ class ImMovementActor[T](
|
|||||||
Behaviors.same
|
Behaviors.same
|
||||||
}
|
}
|
||||||
|
|
||||||
def getDirection2(cardinalDir: CardinalDirection, debug: String => Unit) = {
|
def getDirection2(
|
||||||
|
cardinalDir: CardinalDirection,
|
||||||
|
debug: sourcecode.Text[String] => sourcecode.Text[String]
|
||||||
|
) = {
|
||||||
val camDir =
|
val camDir =
|
||||||
props.camera.getDirection().clone().normalizeLocal.multLocal(0.6f)
|
props.camera.getDirection().clone().normalizeLocal.multLocal(0.6f)
|
||||||
val camLeft = props.camera.getLeft().clone().normalizeLocal.multLocal(0.4f)
|
val camLeft = props.camera.getLeft().clone().normalizeLocal.multLocal(0.4f)
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package wow.doge.mygame.implicits
|
package wow.doge.mygame.implicits
|
||||||
|
|
||||||
|
import javafx.beans.value.ObservableValue
|
||||||
|
import javafx.beans.{value => jfxbv}
|
||||||
import javafx.scene.{input => jfxsi}
|
import javafx.scene.{input => jfxsi}
|
||||||
import javafx.{event => jfxe}
|
import javafx.{event => jfxe}
|
||||||
import monix.execution.Ack
|
import monix.execution.Ack
|
||||||
import monix.execution.Cancelable
|
import monix.execution.Cancelable
|
||||||
import monix.reactive.Observable
|
import monix.reactive.Observable
|
||||||
import monix.reactive.OverflowStrategy
|
import monix.reactive.OverflowStrategy
|
||||||
|
import scalafx.beans.property.Property
|
||||||
import scalafx.scene.Scene
|
import scalafx.scene.Scene
|
||||||
import scalafx.scene.control.ButtonBase
|
import scalafx.scene.control.ButtonBase
|
||||||
|
|
||||||
@ -55,6 +58,35 @@ object JavaFXMonixObservables {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
implicit final class BindObs[A, B](private val prop: Property[A, B])
|
||||||
|
extends AnyVal {
|
||||||
|
def <--[T](op: Observable[(ObservableValue[_ <: B], B, B)] => T) = {
|
||||||
|
op(prop.observableChange())
|
||||||
|
}
|
||||||
|
|
||||||
|
def observableChange(): Observable[(ObservableValue[_ <: B], B, B)] = {
|
||||||
|
import monix.execution.cancelables.SingleAssignCancelable
|
||||||
|
Observable.create(OverflowStrategy.Unbounded) { sub =>
|
||||||
|
val c = SingleAssignCancelable()
|
||||||
|
|
||||||
|
val listener = new jfxbv.ChangeListener[B] {
|
||||||
|
override def changed(
|
||||||
|
observable: ObservableValue[_ <: B],
|
||||||
|
oldValue: B,
|
||||||
|
newValue: B
|
||||||
|
): Unit = {
|
||||||
|
sub.onNext((observable, oldValue, newValue))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prop.addListener(listener)
|
||||||
|
|
||||||
|
c := Cancelable(() => prop.removeListener(listener))
|
||||||
|
c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
implicit final class OnActionObservable(
|
implicit final class OnActionObservable(
|
||||||
private val button: ButtonBase
|
private val button: ButtonBase
|
||||||
) extends AnyVal {
|
) extends AnyVal {
|
||||||
|
@ -49,6 +49,7 @@ import monix.execution.cancelables.SingleAssignCancelable
|
|||||||
import monix.reactive.Observable
|
import monix.reactive.Observable
|
||||||
import monix.reactive.OverflowStrategy
|
import monix.reactive.OverflowStrategy
|
||||||
import monix.reactive.observers.Subscriber
|
import monix.reactive.observers.Subscriber
|
||||||
|
import org.slf4j.Logger
|
||||||
import wow.doge.mygame.math.ImVector3f
|
import wow.doge.mygame.math.ImVector3f
|
||||||
import wow.doge.mygame.state.MyBaseState
|
import wow.doge.mygame.state.MyBaseState
|
||||||
|
|
||||||
@ -794,4 +795,67 @@ package object implicits {
|
|||||||
def +=(node: scalafx.scene.Node) = jfxui.attachChild(node)
|
def +=(node: scalafx.scene.Node) = jfxui.attachChild(node)
|
||||||
def -=(node: scalafx.scene.Node) = jfxui.detachChild(node)
|
def -=(node: scalafx.scene.Node) = jfxui.detachChild(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
implicit class AkkaLoggerExt(private val logger: Logger) extends AnyVal {
|
||||||
|
def logP[T](
|
||||||
|
x: sourcecode.Text[T],
|
||||||
|
tag: String = "",
|
||||||
|
width: Int = 100,
|
||||||
|
height: Int = 500,
|
||||||
|
indent: Int = 2,
|
||||||
|
initialOffset: Int = 0
|
||||||
|
)(implicit line: sourcecode.Line, fileName: sourcecode.FileName) = {
|
||||||
|
|
||||||
|
// def joinSeq[T](seq: Seq[T], sep: T): Seq[T] = {
|
||||||
|
// seq.flatMap(x => Seq(x, sep)).dropRight(1)
|
||||||
|
// }
|
||||||
|
val tagStrs =
|
||||||
|
if (tag.isEmpty) Seq.empty
|
||||||
|
else Seq(fansi.Color.Cyan(tag), fansi.Str(" "))
|
||||||
|
val prefix = Seq(
|
||||||
|
fansi.Color.Magenta(fileName.value),
|
||||||
|
fansi.Str(":"),
|
||||||
|
fansi.Color.Green(line.value.toString),
|
||||||
|
fansi.Str(" "),
|
||||||
|
fansi.Color.Cyan(x.source),
|
||||||
|
fansi.Str(": ")
|
||||||
|
) ++ tagStrs
|
||||||
|
fansi.Str.join(
|
||||||
|
prefix ++ pprint.tokenize(x.value, width, height, indent).toSeq: _*
|
||||||
|
)
|
||||||
|
// x.value
|
||||||
|
}
|
||||||
|
|
||||||
|
def warnP[T](
|
||||||
|
s: sourcecode.Text[T]
|
||||||
|
)(implicit line: sourcecode.Line, fileName: sourcecode.FileName) = {
|
||||||
|
logger.warn(logP(s).render)
|
||||||
|
s
|
||||||
|
}
|
||||||
|
def errorP[T](
|
||||||
|
s: sourcecode.Text[T]
|
||||||
|
)(implicit line: sourcecode.Line, fileName: sourcecode.FileName) = {
|
||||||
|
logger.error(logP(s).render)
|
||||||
|
s
|
||||||
|
}
|
||||||
|
def infoP[T](
|
||||||
|
s: sourcecode.Text[T]
|
||||||
|
)(implicit line: sourcecode.Line, fileName: sourcecode.FileName) = {
|
||||||
|
logger.info(logP(s).render)
|
||||||
|
s
|
||||||
|
}
|
||||||
|
def debugP[T](
|
||||||
|
s: sourcecode.Text[T]
|
||||||
|
)(implicit line: sourcecode.Line, fileName: sourcecode.FileName) = {
|
||||||
|
logger.debug(logP(s).render)
|
||||||
|
s
|
||||||
|
}
|
||||||
|
def traceP[T](
|
||||||
|
s: sourcecode.Text[T]
|
||||||
|
)(implicit line: sourcecode.Line, fileName: sourcecode.FileName) = {
|
||||||
|
logger.trace(logP(s).render)
|
||||||
|
s
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,31 @@
|
|||||||
package wow.doge.mygame.launcher
|
package wow.doge.mygame.launcher
|
||||||
|
|
||||||
import scala.concurrent.duration.FiniteDuration
|
|
||||||
import scala.concurrent.duration._
|
|
||||||
|
|
||||||
import cats.effect.concurrent.Deferred
|
import cats.effect.concurrent.Deferred
|
||||||
import javafx.application.Platform
|
import javafx.application.Platform
|
||||||
|
import javafx.beans.value.ObservableValue
|
||||||
import monix.bio.Task
|
import monix.bio.Task
|
||||||
import monix.catnap.CancelableF
|
import monix.catnap.CancelableF
|
||||||
import monix.eval.{Task => ETask}
|
import monix.execution.CancelablePromise
|
||||||
import monix.reactive.Observable
|
import monix.reactive.Observable
|
||||||
|
import monix.{eval => me}
|
||||||
import scalafx.Includes._
|
import scalafx.Includes._
|
||||||
import scalafx.application.JFXApp
|
import scalafx.application.JFXApp
|
||||||
import scalafx.application.JFXApp.PrimaryStage
|
import scalafx.application.JFXApp.PrimaryStage
|
||||||
|
import scalafx.beans.property.StringProperty
|
||||||
import scalafx.scene.control.Button
|
import scalafx.scene.control.Button
|
||||||
import scalafx.stage.StageStyle
|
import scalafx.stage.StageStyle
|
||||||
import wow.doge.mygame.executors.Schedulers
|
import wow.doge.mygame.executors.Schedulers
|
||||||
import wow.doge.mygame.implicits.JavaFXMonixObservables._
|
import wow.doge.mygame.implicits.JavaFXMonixObservables._
|
||||||
import wow.doge.mygame.utils.IOUtils._
|
import wow.doge.mygame.utils.IOUtils._
|
||||||
|
import cats.effect.Resource
|
||||||
|
import cats.kernel.Eq
|
||||||
object Launcher {
|
object Launcher {
|
||||||
sealed trait LauncherResult
|
sealed trait LauncherResult
|
||||||
object LauncherResult {
|
object LauncherResult {
|
||||||
case object LaunchGame extends LauncherResult
|
case object LaunchGame extends LauncherResult
|
||||||
case object Exit extends LauncherResult
|
case object Exit extends LauncherResult
|
||||||
|
|
||||||
|
implicit val eqForLR = Eq.fromUniversalEquals[LauncherResult]
|
||||||
}
|
}
|
||||||
|
|
||||||
class Props(
|
class Props(
|
||||||
@ -44,10 +47,23 @@ class Launcher private (props: Launcher.Props) {
|
|||||||
.observableAction()
|
.observableAction()
|
||||||
.doOnNext(_ => toTask(props.signal.complete(LauncherResult.LaunchGame)))
|
.doOnNext(_ => toTask(props.signal.complete(LauncherResult.LaunchGame)))
|
||||||
|
|
||||||
|
def testChangeObs(
|
||||||
|
obs: Observable[(ObservableValue[_ <: String], String, String)]
|
||||||
|
) =
|
||||||
|
obs
|
||||||
|
.doOnNext {
|
||||||
|
case (x, y, z) => monix.eval.Task.unit
|
||||||
|
}
|
||||||
|
// .subscribe()
|
||||||
|
|
||||||
private lazy val exitButton = new Button {
|
private lazy val exitButton = new Button {
|
||||||
text = "Exit"
|
text = "Exit"
|
||||||
|
// text <-- testChangeObs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// exitButton.text.bind
|
||||||
|
StringProperty("") addListener ((_, _, _) => ())
|
||||||
|
|
||||||
private lazy val exitAction =
|
private lazy val exitAction =
|
||||||
exitButton
|
exitButton
|
||||||
.observableAction()
|
.observableAction()
|
||||||
@ -60,22 +76,25 @@ class Launcher private (props: Launcher.Props) {
|
|||||||
scene = _scene
|
scene = _scene
|
||||||
}
|
}
|
||||||
|
|
||||||
private lazy val internal = new JFXApp {
|
private def internal(startSignal: CancelablePromise[Unit]) =
|
||||||
stage = _stage
|
new JFXApp {
|
||||||
stage.initStyle(StageStyle.Undecorated)
|
stage = _stage
|
||||||
// ResizeHelper.addResizeListener(stage)
|
stage.initStyle(StageStyle.Undecorated)
|
||||||
}
|
// ResizeHelper.addResizeListener(stage)
|
||||||
|
startSignal.success(())
|
||||||
|
}
|
||||||
|
|
||||||
private lazy val sceneDragObservable = {
|
private lazy val sceneDragObservable = {
|
||||||
lazy val mpo = _scene.observableMousePressed()
|
val mpo = _scene.observableMousePressed()
|
||||||
lazy val mdo = _scene.observableMouseDragged()
|
val mdo = _scene.observableMouseDragged()
|
||||||
|
|
||||||
mpo.mergeMap(pressEvent =>
|
mpo.concatMap(pressEvent =>
|
||||||
mdo.doOnNext(dragEvent =>
|
mdo.doOnNext(dragEvent =>
|
||||||
ETask(
|
me.Task(pprint.log("emitted")) >>
|
||||||
_stage.setX(dragEvent.screenX - pressEvent.sceneX)
|
me.Task(
|
||||||
) >>
|
_stage.setX(dragEvent.screenX - pressEvent.sceneX)
|
||||||
ETask(
|
) >>
|
||||||
|
me.Task(
|
||||||
_stage.setY(
|
_stage.setY(
|
||||||
dragEvent.screenY - pressEvent.sceneY
|
dragEvent.screenY - pressEvent.sceneY
|
||||||
)
|
)
|
||||||
@ -84,21 +103,58 @@ class Launcher private (props: Launcher.Props) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def init(delay: FiniteDuration = 2000.millis) =
|
// import cats.syntax.all._
|
||||||
for {
|
|
||||||
_ <- Task(Platform.setImplicitExit(false))
|
|
||||||
|
|
||||||
fib <- Task(internal.main(Array.empty)).start
|
// def init(delay: FiniteDuration = 2000.millis) =
|
||||||
_ <- Task.sleep(500.millis)
|
// for {
|
||||||
sceneDragFib <- toIO(sceneDragObservable.completedL).start
|
// _ <- Task(Platform.setImplicitExit(false))
|
||||||
fib2 <- toIO(
|
// x <- (Task.unit.start, Task.unit.start).parTupled
|
||||||
Observable(launchAction, exitAction).merge
|
// fxAppStartFib <- Task(internal.main(Array.empty)).start
|
||||||
.doOnNext(_ =>
|
// _ <- Task.sleep(500.millis)
|
||||||
ETask(internal.stage.close()).executeOn(props.schedulers.fx)
|
// sceneDragFib <- toIO(sceneDragObservable.completedL).start
|
||||||
|
// buttonActionsComposedFib <- toIO(
|
||||||
|
// Observable(launchAction, exitAction).merge
|
||||||
|
// .doOnNext(_ =>
|
||||||
|
// me.Task(internal.stage.close()).executeOn(props.schedulers.fx)
|
||||||
|
// )
|
||||||
|
// .completedL
|
||||||
|
// ).start
|
||||||
|
// c <- CancelableF[Task](
|
||||||
|
// fxAppStartFib.cancel >> buttonActionsComposedFib.cancel >> sceneDragFib.cancel
|
||||||
|
// )
|
||||||
|
// } yield (c)
|
||||||
|
|
||||||
|
def init =
|
||||||
|
Resource.make(for {
|
||||||
|
_ <- Task(Platform.setImplicitExit(false))
|
||||||
|
startSignal <- Task(CancelablePromise[Unit]())
|
||||||
|
delegate <- Task(internal(startSignal))
|
||||||
|
combinedFib <-
|
||||||
|
Task
|
||||||
|
.parZip2(
|
||||||
|
Task(delegate.main(Array.empty)),
|
||||||
|
Task.fromCancelablePromise(startSignal) >> toIO(
|
||||||
|
me.Task.parSequence(
|
||||||
|
List(
|
||||||
|
sceneDragObservable.completedL,
|
||||||
|
Observable(launchAction, exitAction).merge
|
||||||
|
.doOnNext(_ =>
|
||||||
|
me.Task(delegate.stage.close())
|
||||||
|
.executeOn(props.schedulers.fx)
|
||||||
|
)
|
||||||
|
.completedL
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
.completedL
|
.start
|
||||||
).start
|
c <- CancelableF[Task](
|
||||||
c <- CancelableF[Task](fib.cancel >> fib2.cancel >> sceneDragFib.cancel)
|
// Task(println("Cancelling")) >>
|
||||||
} yield (c)
|
// combinedFib.cancel >>
|
||||||
|
// fxAppStartFib.cancel
|
||||||
|
// Task.unit
|
||||||
|
combinedFib.cancel
|
||||||
|
)
|
||||||
|
} yield c)(_.cancel)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,22 +18,22 @@ import wow.doge.mygame.subsystems.events.EventBus
|
|||||||
import wow.doge.mygame.subsystems.events.TickEvent
|
import wow.doge.mygame.subsystems.events.TickEvent
|
||||||
|
|
||||||
class EventsModule(spawnProtocol: ActorSystem[SpawnProtocol.Command]) {
|
class EventsModule(spawnProtocol: ActorSystem[SpawnProtocol.Command]) {
|
||||||
implicit lazy val s = spawnProtocol.scheduler
|
implicit val s = spawnProtocol.scheduler
|
||||||
|
|
||||||
implicit lazy val timeout = Timeout(1.second)
|
implicit val timeout = Timeout(1.second)
|
||||||
|
|
||||||
lazy val eventBusLogger = SLogger[EventBus[_]]
|
val eventBusLogger = SLogger[EventBus[_]]
|
||||||
|
|
||||||
lazy val playerEventBusTask =
|
val playerEventBusTask =
|
||||||
createEventBus[PlayerEvent]("playerEventBus")
|
createEventBus[PlayerEvent]("playerEventBus")
|
||||||
|
|
||||||
// lazy val playerCameraEventBusTask =
|
// val playerCameraEventBusTask =
|
||||||
// createEventBus[PlayerCameraEvent]("playerCameraEventBus", Level.DEBUG)
|
// createEventBus[PlayerCameraEvent]("playerCameraEventBus", Level.DEBUG)
|
||||||
|
|
||||||
lazy val tickEventBusTask =
|
val tickEventBusTask =
|
||||||
createEventBus[TickEvent]("tickEventBus", Level.TRACE)
|
createEventBus[TickEvent]("tickEventBus", Level.TRACE)
|
||||||
|
|
||||||
lazy val mainEventBusTask = createEventBus[Event]("mainEventBus")
|
val mainEventBusTask = createEventBus[Event]("mainEventBus")
|
||||||
|
|
||||||
def createEventBus[T](busName: String, logLevel: Level = Level.DEBUG) =
|
def createEventBus[T](busName: String, logLevel: Level = Level.DEBUG) =
|
||||||
spawnProtocol.askL(
|
spawnProtocol.askL(
|
||||||
|
@ -41,7 +41,7 @@ object ScriptActor {
|
|||||||
result: ActorRef[Map[os.Path, Either[Error, Any]]]
|
result: ActorRef[Map[os.Path, Either[Error, Any]]]
|
||||||
) extends Command
|
) extends Command
|
||||||
|
|
||||||
lazy val defaultScalaRunner =
|
val defaultScalaRunner =
|
||||||
ammonite
|
ammonite
|
||||||
.Main(
|
.Main(
|
||||||
storageBackend = new Folder(
|
storageBackend = new Folder(
|
||||||
@ -51,13 +51,13 @@ object ScriptActor {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
lazy val defaultKotlinRunner: KotlinScriptEngine = {
|
val defaultKotlinRunner: KotlinScriptEngine = {
|
||||||
val manager = new ScriptEngineManager()
|
val manager = new ScriptEngineManager()
|
||||||
val engine = manager.getEngineByExtension("main.kts")
|
val engine = manager.getEngineByExtension("main.kts")
|
||||||
engine.taggedWith[Kotlin]
|
engine.taggedWith[Kotlin]
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy val defaultGroovyRunner: GroovyScriptEngine =
|
val defaultGroovyRunner: GroovyScriptEngine =
|
||||||
new GroovyScriptEngine(os.pwd.toString)
|
new GroovyScriptEngine(os.pwd.toString)
|
||||||
|
|
||||||
def apply(
|
def apply(
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package wow.doge.mygame.scriptsystem
|
package wow.doge.mygame.scriptsystem
|
||||||
|
|
||||||
|
import scala.concurrent.duration._
|
||||||
import scala.util.Failure
|
import scala.util.Failure
|
||||||
import scala.util.Success
|
import scala.util.Success
|
||||||
|
|
||||||
@ -14,8 +15,9 @@ import akka.actor.typed.scaladsl.Routers
|
|||||||
import akka.util.Timeout
|
import akka.util.Timeout
|
||||||
import com.typesafe.scalalogging.Logger
|
import com.typesafe.scalalogging.Logger
|
||||||
import org.slf4j.event.Level
|
import org.slf4j.event.Level
|
||||||
|
import wow.doge.mygame.implicits._
|
||||||
import wow.doge.mygame.state.ScriptActor
|
import wow.doge.mygame.state.ScriptActor
|
||||||
import scala.concurrent.duration._
|
|
||||||
import ScriptActor.ScriptObject
|
import ScriptActor.ScriptObject
|
||||||
|
|
||||||
object ScriptCachingActor {
|
object ScriptCachingActor {
|
||||||
@ -188,10 +190,10 @@ class ScriptCachingActor(
|
|||||||
Behaviors.same
|
Behaviors.same
|
||||||
|
|
||||||
case Put(scriptPath, script) =>
|
case Put(scriptPath, script) =>
|
||||||
ctx.log.debug(s"Putting $script at path $scriptPath")
|
ctx.log.debugP(s"Putting $script at path $scriptPath")
|
||||||
val newState =
|
val newState =
|
||||||
state.modify(_.scriptsMap).using(_ + (scriptPath -> script))
|
state.modify(_.scriptsMap).using(_ + (scriptPath -> script))
|
||||||
ctx.log.trace(newState.toString())
|
ctx.log.traceP(newState.toString())
|
||||||
receiveMessage(state = newState)
|
receiveMessage(state = newState)
|
||||||
|
|
||||||
case NoOp => Behaviors.same
|
case NoOp => Behaviors.same
|
||||||
@ -224,14 +226,14 @@ private[scriptsystem] object Methods {
|
|||||||
scriptsMap
|
scriptsMap
|
||||||
.get(scriptPath)
|
.get(scriptPath)
|
||||||
.fold {
|
.fold {
|
||||||
ctx.log.debug("Delegating to child")
|
ctx.log.debugP("Delegating to child")
|
||||||
ctx.self ! DelegateToChild(
|
ctx.self ! DelegateToChild(
|
||||||
scriptActor,
|
scriptActor,
|
||||||
scriptPath,
|
scriptPath,
|
||||||
requester
|
requester
|
||||||
)
|
)
|
||||||
} { s =>
|
} { s =>
|
||||||
ctx.log.debug("Getting script from cache")
|
ctx.log.debugP("Getting script from cache")
|
||||||
requester ! Right(s)
|
requester ! Right(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import akka.actor.typed.ActorRef
|
|||||||
import akka.actor.typed.Scheduler
|
import akka.actor.typed.Scheduler
|
||||||
import akka.actor.typed.SpawnProtocol
|
import akka.actor.typed.SpawnProtocol
|
||||||
import akka.util.Timeout
|
import akka.util.Timeout
|
||||||
import cats.effect.Resource
|
|
||||||
import monix.bio.Task
|
import monix.bio.Task
|
||||||
import wow.doge.mygame.scriptsystem.ScriptCachingActor
|
import wow.doge.mygame.scriptsystem.ScriptCachingActor
|
||||||
import wow.doge.mygame.utils.AkkaUtils
|
import wow.doge.mygame.utils.AkkaUtils
|
||||||
@ -20,29 +19,18 @@ object ScriptInitMode {
|
|||||||
}
|
}
|
||||||
class ScriptSystemResource(
|
class ScriptSystemResource(
|
||||||
path: os.Path,
|
path: os.Path,
|
||||||
spawnProtocol: ActorRef[SpawnProtocol.Command],
|
|
||||||
mode: ScriptInitMode = ScriptInitMode.Lazy
|
mode: ScriptInitMode = ScriptInitMode.Lazy
|
||||||
)(implicit timeout: Timeout, scheduler: Scheduler) {
|
)(implicit
|
||||||
val make = {
|
spawnProtocol: ActorRef[SpawnProtocol.Command],
|
||||||
// throw new Exception("boom")
|
timeout: Timeout,
|
||||||
findScriptFiles(os.pwd / "assets" / "scripts")
|
scheduler: Scheduler
|
||||||
|
) {
|
||||||
lazy val scriptCacheActor = AkkaUtils.spawnActorL(
|
|
||||||
spawnProtocol,
|
|
||||||
"scriptCachingActor",
|
|
||||||
ScriptCachingActor()
|
|
||||||
)
|
|
||||||
|
|
||||||
Resource.liftF(scriptCacheActor)
|
|
||||||
}
|
|
||||||
// sys.ask(ref => ScriptCachingActor.GetAll(os.pwd/'assets/'scripts/'scala/"hello2.sc",ref, false))
|
|
||||||
|
|
||||||
val init = for {
|
val init = for {
|
||||||
scriptFiles <- Task(findScriptFiles(os.pwd / "assets" / "scripts"))
|
scriptFiles <- Task(findScriptFiles(os.pwd / "assets" / "scripts"))
|
||||||
scriptCacheActor <- AkkaUtils.spawnActorL(
|
scriptCacheActor <- AkkaUtils.spawnActorL(
|
||||||
spawnProtocol,
|
ScriptCachingActor(),
|
||||||
"scriptCachingActor",
|
"scriptCachingActor"
|
||||||
ScriptCachingActor()
|
|
||||||
)
|
)
|
||||||
} yield (scriptCacheActor)
|
} yield (scriptCacheActor)
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import akka.util.Timeout
|
|||||||
import wow.doge.mygame.implicits._
|
import wow.doge.mygame.implicits._
|
||||||
|
|
||||||
object AkkaUtils {
|
object AkkaUtils {
|
||||||
def spawnActorL[T](
|
def spawnActorOldL[T](
|
||||||
spawnProtocol: ActorRef[SpawnProtocol.Command],
|
spawnProtocol: ActorRef[SpawnProtocol.Command],
|
||||||
actorName: String,
|
actorName: String,
|
||||||
behavior: Behavior[T]
|
behavior: Behavior[T]
|
||||||
@ -22,7 +22,7 @@ object AkkaUtils {
|
|||||||
_
|
_
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
def spawnActorL2[T](
|
def spawnActorL[T](
|
||||||
behavior: Behavior[T],
|
behavior: Behavior[T],
|
||||||
actorName: String
|
actorName: String
|
||||||
)(implicit
|
)(implicit
|
||||||
|
@ -21,7 +21,7 @@ class GenericConsoleStream[T](
|
|||||||
)(implicit
|
)(implicit
|
||||||
cs: ConsoleStreamable[T]
|
cs: ConsoleStreamable[T]
|
||||||
) extends PrintStream(outputStream, true) {
|
) extends PrintStream(outputStream, true) {
|
||||||
private lazy val defaultOut = System.out
|
private val defaultOut = System.out
|
||||||
|
|
||||||
def printToStreamable(stble: Option[T], text: String) =
|
def printToStreamable(stble: Option[T], text: String) =
|
||||||
stble.foreach(s => cs.println(s, text))
|
stble.foreach(s => cs.println(s, text))
|
||||||
@ -57,7 +57,7 @@ object GenericConsoleStream {
|
|||||||
*/
|
*/
|
||||||
case class Config(exclusive: Boolean = false)
|
case class Config(exclusive: Boolean = false)
|
||||||
object Config {
|
object Config {
|
||||||
lazy val default = Config()
|
val default = Config()
|
||||||
}
|
}
|
||||||
|
|
||||||
implicit val implJFXConsoleStreamForTextArea =
|
implicit val implJFXConsoleStreamForTextArea =
|
||||||
|
Loading…
Reference in New Issue
Block a user