forked from nova/jmonkey-test
many changes
This commit is contained in:
parent
a2a328d078
commit
c93d0704b5
17
build.sbt
17
build.sbt
@ -74,7 +74,8 @@ lazy val root = (project in file(".")).settings(
|
|||||||
"org.typelevel" %% "cats-core" % "2.1.1",
|
"org.typelevel" %% "cats-core" % "2.1.1",
|
||||||
"org.typelevel" %% "cats-effect" % "2.1.4",
|
"org.typelevel" %% "cats-effect" % "2.1.4",
|
||||||
"io.monix" %% "monix" % "3.2.2",
|
"io.monix" %% "monix" % "3.2.2",
|
||||||
"io.monix" %% "monix-bio" % "1.0.0",
|
// "io.monix" %% "monix-bio" % "1.0.0",
|
||||||
|
"io.monix" %% "monix-bio" % "1.1.0",
|
||||||
"io.circe" %% "circe-core" % "0.13.0",
|
"io.circe" %% "circe-core" % "0.13.0",
|
||||||
"io.circe" %% "circe-generic" % "0.13.0",
|
"io.circe" %% "circe-generic" % "0.13.0",
|
||||||
"com.softwaremill.sttp.client" %% "core" % "2.2.5",
|
"com.softwaremill.sttp.client" %% "core" % "2.2.5",
|
||||||
@ -91,7 +92,8 @@ lazy val root = (project in file(".")).settings(
|
|||||||
"org.scala-lang.modules" %% "scala-parallel-collections" % "1.0.0-RC1",
|
"org.scala-lang.modules" %% "scala-parallel-collections" % "1.0.0-RC1",
|
||||||
"com.typesafe.scala-logging" %% "scala-logging" % "3.9.2",
|
"com.typesafe.scala-logging" %% "scala-logging" % "3.9.2",
|
||||||
"io.circe" %% "circe-config" % "0.8.0",
|
"io.circe" %% "circe-config" % "0.8.0",
|
||||||
"com.beachape" %% "enumeratum-circe" % "1.6.1"
|
"com.beachape" %% "enumeratum-circe" % "1.6.1",
|
||||||
|
"com.lihaoyi" %% "os-lib" % "0.7.1"
|
||||||
),
|
),
|
||||||
// Determine OS version of JavaFX binaries
|
// Determine OS version of JavaFX binaries
|
||||||
|
|
||||||
@ -104,12 +106,20 @@ lazy val root = (project in file(".")).settings(
|
|||||||
"UTF-8",
|
"UTF-8",
|
||||||
"-deprecation",
|
"-deprecation",
|
||||||
"-feature",
|
"-feature",
|
||||||
|
"-language:existentials",
|
||||||
|
"-language:experimental.macros",
|
||||||
|
"-language:higherKinds",
|
||||||
|
"-language:implicitConversions",
|
||||||
"-unchecked",
|
"-unchecked",
|
||||||
"-Xlint",
|
"-Xlint",
|
||||||
"-Ywarn-numeric-widen",
|
"-Ywarn-numeric-widen",
|
||||||
"-Ymacro-annotations",
|
"-Ymacro-annotations",
|
||||||
"-Xlint:byname-implicit",
|
// "-Xlint:byname-implicit",
|
||||||
// "utf-8", // Specify character encoding used by source files.
|
// "utf-8", // Specify character encoding used by source files.
|
||||||
|
//silence warnings for by-name implicits
|
||||||
|
"-Wconf:cat=lint-byname-implicit:s",
|
||||||
|
//give errors on non exhaustive matches
|
||||||
|
"-Wconf:msg=match may not be exhaustive:e",
|
||||||
"-explaintypes" // Explain type errors in more detail.
|
"-explaintypes" // Explain type errors in more detail.
|
||||||
),
|
),
|
||||||
javacOptions ++= Seq("-source", "11", "-target", "11"),
|
javacOptions ++= Seq("-source", "11", "-target", "11"),
|
||||||
@ -199,3 +209,4 @@ initialCommands in (console) := """ammonite.Main.main(Array.empty)"""
|
|||||||
// To learn more about multi-project builds, head over to the official sbt
|
// To learn more about multi-project builds, head over to the official sbt
|
||||||
// documentation at http://www.scala-sbt.org/documentation.html
|
// documentation at http://www.scala-sbt.org/documentation.html
|
||||||
addCompilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.1")
|
addCompilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.1")
|
||||||
|
ThisBuild / scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.4.3"
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
// println("hello from dep")
|
|
||||||
class Test(x: Int)
|
|
@ -1,3 +0,0 @@
|
|||||||
println "hello"
|
|
||||||
|
|
||||||
this
|
|
@ -1,36 +0,0 @@
|
|||||||
// @file:Import("src/main/resources/hello2.main.kts")
|
|
||||||
@file:DependsOn("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.0-M1")
|
|
||||||
@file:DependsOn("/home/rohan/.m2/repository/wow/doge/game/1.0-SNAPSHOT/game-1.0-SNAPSHOT.jar")
|
|
||||||
@file:DependsOn("/home/rohan/.ivy2/local/wow.doge/mygame_2.13/1.0-SNAPSHOT/jars/mygame_2.13.jar")
|
|
||||||
|
|
||||||
import wow.doge.game.types.GameScript
|
|
||||||
|
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import kotlin.random.Random
|
|
||||||
|
|
||||||
import wow.doge.mygame.components.Test
|
|
||||||
|
|
||||||
|
|
||||||
//println(x * 2)
|
|
||||||
|
|
||||||
println("hello from main script")
|
|
||||||
|
|
||||||
class GameScriptImpl : GameScript {
|
|
||||||
override fun start() = runBlocking {
|
|
||||||
for(x in 0 until 5) {
|
|
||||||
launch {
|
|
||||||
val del = Random.nextLong(20, 100)
|
|
||||||
|
|
||||||
delay(del)
|
|
||||||
println("hello from start $x, delay is $del")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
override fun stop() {println("hello from stop")}
|
|
||||||
}
|
|
||||||
|
|
||||||
GameScriptImpl()
|
|
||||||
|
|
||||||
class MyTest : Test()
|
|
@ -1,35 +0,0 @@
|
|||||||
// #!/usr/bin/env amm
|
|
||||||
|
|
||||||
// import coursierapi.MavenRepository
|
|
||||||
|
|
||||||
// interp.repositories.update(
|
|
||||||
// interp.repositories() ::: List(
|
|
||||||
// MavenRepository.of("file://home/rohan/.m2/repository")
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
|
|
||||||
// @
|
|
||||||
// import $repo.`https://jcenter.bintray.com`
|
|
||||||
// // import $repo.`https://bintray.com/jmonkeyengine/com.jme3`
|
|
||||||
// import $file.dep
|
|
||||||
// import $ivy.`org.jmonkeyengine:jme3-core:3.2.4-stable`
|
|
||||||
// import $ivy.`wow.doge:game:1.0-SNAPSHOT`
|
|
||||||
// import wow.doge.game.types.GameScript
|
|
||||||
// import com.jme3.scene.control.Control
|
|
||||||
|
|
||||||
// println("hello from script")
|
|
||||||
|
|
||||||
// class Scr extends GameScript {
|
|
||||||
// def start(): Unit = println("hello from start")
|
|
||||||
|
|
||||||
// def stop(): Unit = println("hello from stop")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // class SomeClass extends Control {}
|
|
||||||
|
|
||||||
// @main
|
|
||||||
// def main(): GameScript = new Scr()
|
|
||||||
import $file.dep
|
|
||||||
import dep.Test
|
|
||||||
|
|
||||||
new Test(1)
|
|
@ -1,5 +0,0 @@
|
|||||||
println("hello from dep")
|
|
||||||
|
|
||||||
class Test(val x: Int)
|
|
||||||
|
|
||||||
var x = 2
|
|
@ -1,108 +0,0 @@
|
|||||||
#!/usr/bin/env amm
|
|
||||||
// scala 2.13.3
|
|
||||||
|
|
||||||
// import coursierapi.MavenRepository
|
|
||||||
|
|
||||||
// interp.repositories.update(
|
|
||||||
// interp.repositories() ::: List(
|
|
||||||
// MavenRepository.of("file://home/rohan/.m2/repository")
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
|
|
||||||
// @
|
|
||||||
import $repo.`https://jcenter.bintray.com`
|
|
||||||
// import $repo.`https://bintray.com/jmonkeyengine/com.jme3`
|
|
||||||
// import $file.dep
|
|
||||||
import $ivy.`org.jmonkeyengine:jme3-core:3.2.4-stable`
|
|
||||||
// import $ivy.`wow.doge:game:1.0-SNAPSHOT`
|
|
||||||
import $ivy.`wow.doge::mygame:1.0-SNAPSHOT`
|
|
||||||
// import wow.doge.game.types.GameScript
|
|
||||||
import com.jme3.scene.control.Control
|
|
||||||
|
|
||||||
// println("hello from script")
|
|
||||||
|
|
||||||
// class Scr extends GameScript {
|
|
||||||
// def start(): Unit = println("hello from start")
|
|
||||||
|
|
||||||
// def stop(): Unit = println("hello from stop")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // class SomeClass extends Control {}
|
|
||||||
|
|
||||||
// @main
|
|
||||||
// def main(): GameScript = new Scr()
|
|
||||||
import com.simsilica.es.base.DefaultEntityData
|
|
||||||
import com.simsilica.es.EntityData
|
|
||||||
import com.jme3.app.Application
|
|
||||||
import wow.doge.mygame.game.Implicits._
|
|
||||||
import wow.doge.mygame.components.TestComponent
|
|
||||||
import com.jme3.scene.shape.Box
|
|
||||||
import com.jme3.scene.Geometry
|
|
||||||
import com.jme3.material.Material
|
|
||||||
import com.jme3.math.ColorRGBA
|
|
||||||
import com.jme3.asset.AssetManager
|
|
||||||
import com.jme3.math.Vector3f
|
|
||||||
import wow.doge.mygame.state._
|
|
||||||
class TestAppState(
|
|
||||||
// private var _entity: Option[EntityData] = Some(new DefaultEntityData())
|
|
||||||
) extends MyBaseState {
|
|
||||||
protected lazy val b = new Box(1, 1, 1)
|
|
||||||
protected lazy val geom = new Geometry("Box", b)
|
|
||||||
protected lazy val mat = Material(
|
|
||||||
assetManager = assetManager,
|
|
||||||
path = "Common/MatDefs/Misc/Unshaded.j3md"
|
|
||||||
)
|
|
||||||
|
|
||||||
// def entity = _entity
|
|
||||||
// override def initialize(app: Application): Unit = {
|
|
||||||
// super.initialize(app)
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
override def init() = {
|
|
||||||
entityData
|
|
||||||
.createEntity()
|
|
||||||
.withComponents(TestComponent())
|
|
||||||
// entityData.setComponents(x, TestComponent())
|
|
||||||
val es = entityData.getEntities(classOf[TestComponent])
|
|
||||||
println(es)
|
|
||||||
geom.setMaterial(mat)
|
|
||||||
rootNode.attachChild(geom)
|
|
||||||
|
|
||||||
// geom.foreach(e => {
|
|
||||||
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
|
|
||||||
override def update(tpf: Float) = {
|
|
||||||
geom.rotate(0, 0.5f * tpf, 0)
|
|
||||||
geom.move(new Vector3f(0, 1 * tpf, 0))
|
|
||||||
}
|
|
||||||
|
|
||||||
override def cleanup(app: Application): Unit = {
|
|
||||||
// _entity.map(_.close())
|
|
||||||
// _entity = None
|
|
||||||
}
|
|
||||||
|
|
||||||
override def onEnable(): Unit = {}
|
|
||||||
|
|
||||||
override def onDisable(): Unit = {}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
object Material {
|
|
||||||
def apply(
|
|
||||||
color: String = "Color",
|
|
||||||
colorType: com.jme3.math.ColorRGBA = ColorRGBA.Blue,
|
|
||||||
assetManager: AssetManager,
|
|
||||||
path: String
|
|
||||||
): Material = {
|
|
||||||
val mat =
|
|
||||||
new Material(assetManager, path)
|
|
||||||
mat.setColor(color, colorType)
|
|
||||||
mat
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@main
|
|
||||||
def main(): MyBaseState = new TestAppState()
|
|
@ -1,6 +1,7 @@
|
|||||||
package com.jme3
|
package com.jme3
|
||||||
|
|
||||||
import com.jme3.input.controls.{InputListener, Trigger}
|
import com.jme3.input.controls.InputListener
|
||||||
|
import com.jme3.input.controls.Trigger
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Brandon Barker on 6/21/17.
|
* Created by Brandon Barker on 6/21/17.
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
package com.jme3
|
package com.jme3
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Brandon Barker on 6/21/17.
|
* Created by Brandon Barker on 6/21/17.
|
||||||
*/
|
*/
|
||||||
package object syntax {
|
package object syntax {
|
||||||
|
|
||||||
@specialized def discard[A](evaluateForSideEffectOnly: A): Unit = {
|
@specialized def discard[A](evaluateForSideEffectOnly: A): Unit = {
|
||||||
val _: A = evaluateForSideEffectOnly
|
val _ = evaluateForSideEffectOnly
|
||||||
() //Return unit to prevent warning due to discarding value
|
() //Return unit to prevent warning due to discarding value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
package org.slf4j.impl
|
package org.slf4j.impl
|
||||||
|
|
||||||
import cats.effect.{ContextShift, Clock, Effect, IO, Timer}
|
|
||||||
import io.odin._
|
|
||||||
import io.odin.slf4j.OdinLoggerBinder
|
|
||||||
import cats.implicits._
|
|
||||||
|
|
||||||
import scala.concurrent.ExecutionContext
|
|
||||||
import _root_.monix.execution.Scheduler
|
|
||||||
import cats.arrow.FunctionK
|
|
||||||
import _root_.monix.execution.Scheduler.Implicits.global
|
|
||||||
import io.odin.syntax._
|
|
||||||
import scala.concurrent.duration._
|
|
||||||
import scala.collection.immutable.ArraySeq
|
import scala.collection.immutable.ArraySeq
|
||||||
|
import scala.concurrent.ExecutionContext
|
||||||
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
|
import _root_.monix.execution.Scheduler
|
||||||
|
import _root_.monix.execution.Scheduler.Implicits.global
|
||||||
|
import cats.arrow.FunctionK
|
||||||
|
import cats.effect.Clock
|
||||||
|
import cats.effect.ContextShift
|
||||||
|
import cats.effect.Effect
|
||||||
|
import cats.effect.IO
|
||||||
|
import cats.effect.Timer
|
||||||
|
import cats.implicits._
|
||||||
|
import io.odin._
|
||||||
import io.odin.json.Formatter
|
import io.odin.json.Formatter
|
||||||
|
import io.odin.slf4j.OdinLoggerBinder
|
||||||
|
import io.odin.syntax._
|
||||||
|
|
||||||
//effect type should be specified inbefore
|
//effect type should be specified inbefore
|
||||||
//log line will be recorded right after the call with no suspension
|
//log line will be recorded right after the call with no suspension
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
package wow.doge.mygame
|
|
||||||
|
|
||||||
import akka.actor.typed.ActorSystem
|
|
||||||
import cats.effect.Resource
|
|
||||||
import monix.bio.Task
|
|
||||||
import io.odin.Logger
|
|
||||||
import wow.doge.mygame.game.GameApp
|
|
||||||
import wow.doge.mygame.executors.Schedulers
|
|
||||||
|
|
||||||
trait ActorSystemModule {
|
|
||||||
|
|
||||||
def logger: Logger[Task]
|
|
||||||
def app: GameApp
|
|
||||||
def schedulers: Schedulers
|
|
||||||
|
|
||||||
lazy val actorsResource =
|
|
||||||
Resource.make(logger.info("Creating Actor System") >> Task {
|
|
||||||
ActorSystem(
|
|
||||||
RootActor(app, schedulers, logger = logger),
|
|
||||||
name = "GameActorSystem"
|
|
||||||
)
|
|
||||||
})(sys =>
|
|
||||||
logger.info("Shutting down actor system") >> Task(
|
|
||||||
sys.terminate()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,24 +1,21 @@
|
|||||||
package wow.doge.mygame
|
package wow.doge.mygame
|
||||||
|
|
||||||
import cats.effect.Resource
|
import scala.concurrent.duration._
|
||||||
import io.odin.syntax._
|
|
||||||
|
|
||||||
|
import _root_.monix.bio.Task
|
||||||
|
import akka.util.Timeout
|
||||||
import cats.effect.ExitCode
|
import cats.effect.ExitCode
|
||||||
import cats.implicits._
|
import cats.implicits._
|
||||||
import com.softwaremill.macwire._
|
import com.softwaremill.macwire._
|
||||||
import scala.concurrent.duration._
|
|
||||||
import monix.bio.BIOApp
|
|
||||||
import monix.bio.UIO
|
|
||||||
import io.odin._
|
import io.odin._
|
||||||
import wow.doge.mygame.game.GameAppResource
|
|
||||||
import io.odin.json.Formatter
|
import io.odin.json.Formatter
|
||||||
import wow.doge.mygame.game.GameSystemsInitializer
|
import io.odin.syntax._
|
||||||
import wow.doge.mygame.subsystems.events.EventsModule2
|
import wow.doge.mygame.game.GameAppResource
|
||||||
import wow.doge.mygame.implicits._
|
|
||||||
import com.jme3.bullet.BulletAppState
|
|
||||||
import akka.util.Timeout
|
|
||||||
import wow.doge.mygame.subsystems.scriptsystem.ScriptSystemResource
|
import wow.doge.mygame.subsystems.scriptsystem.ScriptSystemResource
|
||||||
import ammonite.runtime.tools.time
|
import _root_.monix.bio.BIOApp
|
||||||
|
import _root_.monix.bio.UIO
|
||||||
|
import cats.effect.Resource
|
||||||
|
|
||||||
object Main extends BIOApp with MainModule {
|
object Main extends BIOApp with MainModule {
|
||||||
import java.util.logging.{Logger => JLogger, Level}
|
import java.util.logging.{Logger => JLogger, Level}
|
||||||
JLogger.getLogger("").setLevel(Level.SEVERE)
|
JLogger.getLogger("").setLevel(Level.SEVERE)
|
||||||
@ -41,19 +38,36 @@ object Main extends BIOApp with MainModule {
|
|||||||
// akkaScheduler = actorSystemResource2.scheduler
|
// akkaScheduler = actorSystemResource2.scheduler
|
||||||
// consoleTextArea <- Resource.liftF(Task(new TextArea()))
|
// consoleTextArea <- Resource.liftF(Task(new TextArea()))
|
||||||
// consoleStream <- wireWith(JFXConsoleStream.textAreaStream _)
|
// consoleStream <- wireWith(JFXConsoleStream.textAreaStream _)
|
||||||
(gameApp, gameAppFib) <- {
|
(gameApp) <- {
|
||||||
// new BulletAppState()
|
// new BulletAppState()
|
||||||
// bas.setThreadingType(Thr)
|
// bas.setThreadingType(Thr)
|
||||||
// gameAppResource(new StatsAppState())
|
// gameAppResource(new StatsAppState())
|
||||||
wire[GameAppResource].get
|
wire[GameAppResource].get2
|
||||||
}
|
}
|
||||||
app = gameApp
|
_ <- Resource.liftF(
|
||||||
inputManager = gameApp.inputManager
|
new MainApp(logger, gameApp, actorSystem, jmeScheduler)(
|
||||||
assetManager = gameApp.assetManager
|
timeout,
|
||||||
bulletAppState = new BulletAppState()
|
actorSystem.scheduler
|
||||||
(playerMovementEventBus, playerCameraEventBus) <- new EventsModule2(
|
).gameInit
|
||||||
actorSystem
|
)
|
||||||
).resource
|
// fib <- Resource.liftF(
|
||||||
|
// gameApp
|
||||||
|
// .enqueueL(() =>
|
||||||
|
// new MainApp(logger, gameApp, actorSystem, jmeScheduler)(
|
||||||
|
// timeout,
|
||||||
|
// actorSystem.scheduler
|
||||||
|
// )
|
||||||
|
// )
|
||||||
|
// .start
|
||||||
|
// )
|
||||||
|
// _ <- Resource.liftF(fib.join.flatMap(_.gameInit)
|
||||||
|
// app = gameApp
|
||||||
|
// inputManager = gameApp.inputManager
|
||||||
|
// assetManager = gameApp.assetManager
|
||||||
|
// bulletAppState = new BulletAppState()
|
||||||
|
// (playerMovementEventBus, playerCameraEventBus) <- new EventsModule2(
|
||||||
|
// actorSystem
|
||||||
|
// ).resource
|
||||||
// b1 = playerMovementEventBus
|
// b1 = playerMovementEventBus
|
||||||
// b2 = playerCameraEventBus
|
// b2 = playerCameraEventBus
|
||||||
|
|
||||||
@ -67,62 +81,15 @@ object Main extends BIOApp with MainModule {
|
|||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// _ <- Resource.liftF(IO(JMERunner.runner = gameApp))
|
// gameSystemsInitializerFib <- Resource.make(
|
||||||
// _ <- Resource.liftF(IO {
|
// logger.info("creating game systems initializer") >>
|
||||||
// new ActorSystemModule {}
|
// gameApp
|
||||||
// })
|
// .enqueueL(() => wire[GameSystemsInitializer])
|
||||||
// actorSystem <- wireWith(actorSystemResource _)
|
// .start
|
||||||
|
// )(c => logger.info("destroying game systems initializer") >> c.cancel)
|
||||||
|
// _ <- Resource.liftF(gameSystemsInitializerFib.join.flatMap(_.init))
|
||||||
|
|
||||||
// rootActor <- rootActorResource(logger, gameApp, schedulers, as2)
|
} yield ()
|
||||||
// _ <- Resource.liftF(
|
|
||||||
// gameApp.enqueueT(actorSystem ! RootActor.Start(actorSystem.scheduler))
|
|
||||||
// )
|
|
||||||
// gameSystemsInitializer = new GameSystemsInitializer(
|
|
||||||
// actorSystem,
|
|
||||||
// logger,
|
|
||||||
// playerMovementEventBus,
|
|
||||||
// playerCameraEventBus
|
|
||||||
// )(gameApp)
|
|
||||||
|
|
||||||
gameSystemsInitializerFib <- Resource.make(
|
|
||||||
logger.info("creating game systems initializer") >>
|
|
||||||
gameApp
|
|
||||||
.enqueueL(() => wire[GameSystemsInitializer])
|
|
||||||
.start
|
|
||||||
)(c => logger.info("destroying game systems initializer") >> c.cancel)
|
|
||||||
_ <- Resource.liftF(gameSystemsInitializerFib.join.flatMap(_.init))
|
|
||||||
|
|
||||||
// .runAsync {
|
|
||||||
// case Left(err) => println(err)
|
|
||||||
// case _ =>
|
|
||||||
// }(schedulers.async)
|
|
||||||
|
|
||||||
// _ <- Resource.liftF {
|
|
||||||
// Task {
|
|
||||||
// implicit val sched = actorSystem.scheduler
|
|
||||||
// implicit val timeout = Timeout(2.seconds)
|
|
||||||
// // val module = new EventsModule {}
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// actorSystem <- wireWith(actorSystemResource2 _)
|
|
||||||
// (tickEventBus, playerMovementEventBus) <- wireWith(eventBusesResource _)
|
|
||||||
// rootActor <- wireWith(rootActorResource _)
|
|
||||||
// inputSystemHandler <- {
|
|
||||||
// inputHandlerSystemResource(
|
|
||||||
// GameInputHandler.Props(gameApp.inputManager, playerMovementEventBus)
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// gameSystemsInitializer <-
|
|
||||||
// gameSystemsResource(actorSystem, inputSystemHandler)
|
|
||||||
// _ <- Resource.liftF(
|
|
||||||
// gameApp.enqueueT(rootActor ! RootActor.Start(actorSystem.scheduler))
|
|
||||||
// )
|
|
||||||
// _ <- Resource.liftF {
|
|
||||||
// IO(gameApp.start())
|
|
||||||
// .executeOn(jmeScheduler)
|
|
||||||
// }
|
|
||||||
// (_ => IO(gameApp.stop(() => actorSystem ! RootActor.Stop)))
|
|
||||||
} yield (gameAppFib)
|
|
||||||
|
|
||||||
// def createPlayerController(
|
// def createPlayerController(
|
||||||
// playerMovementEventBus: ActorRef[
|
// playerMovementEventBus: ActorRef[
|
||||||
@ -145,7 +112,7 @@ object Main extends BIOApp with MainModule {
|
|||||||
// )
|
// )
|
||||||
// )(())
|
// )(())
|
||||||
appResource
|
appResource
|
||||||
.use(_.join)
|
.use(_ => Task.unit)
|
||||||
.onErrorHandle(_.printStackTrace())
|
.onErrorHandle(_.printStackTrace())
|
||||||
.as(ExitCode.Success)
|
.as(ExitCode.Success)
|
||||||
}
|
}
|
||||||
|
139
src/main/scala/wow/doge/mygame/MainApp.scala
Normal file
139
src/main/scala/wow/doge/mygame/MainApp.scala
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
package wow.doge.mygame
|
||||||
|
|
||||||
|
import akka.actor.typed.ActorRef
|
||||||
|
import akka.actor.typed.ActorSystem
|
||||||
|
import akka.actor.typed.Scheduler
|
||||||
|
import akka.actor.typed.SpawnProtocol
|
||||||
|
import akka.util.Timeout
|
||||||
|
import cats.effect.concurrent.Ref
|
||||||
|
import com.jme3.app.state.AppStateManager
|
||||||
|
import com.jme3.asset.AssetManager
|
||||||
|
import com.jme3.asset.plugins.ZipLocator
|
||||||
|
import com.jme3.bullet.BulletAppState
|
||||||
|
import com.jme3.input.InputManager
|
||||||
|
import com.jme3.renderer.Camera
|
||||||
|
import com.jme3.scene.Node
|
||||||
|
import com.softwaremill.macwire._
|
||||||
|
import com.softwaremill.tagging._
|
||||||
|
import io.odin.Logger
|
||||||
|
import monix.bio.IO
|
||||||
|
import monix.bio.Task
|
||||||
|
import wow.doge.mygame.events.EventBus
|
||||||
|
import wow.doge.mygame.game.GameApp2
|
||||||
|
import wow.doge.mygame.game.nodes.Player
|
||||||
|
import wow.doge.mygame.game.nodes.PlayerController
|
||||||
|
import wow.doge.mygame.game.subsystems.input.GameInputHandler
|
||||||
|
import wow.doge.mygame.implicits._
|
||||||
|
import wow.doge.mygame.math.ImVector3f
|
||||||
|
import wow.doge.mygame.subsystems.events.EntityMovementEvent
|
||||||
|
import wow.doge.mygame.subsystems.events.EventsModule2
|
||||||
|
import wow.doge.mygame.subsystems.events.PlayerCameraEvent
|
||||||
|
import wow.doge.mygame.game.subsystems.level.DefaultGameLevel
|
||||||
|
import com.jme3.renderer.ViewPort
|
||||||
|
import wow.doge.mygame.subsystems.scriptsystem.ScriptSystemResource
|
||||||
|
import wow.doge.mygame.subsystems.scriptsystem.ScriptInitMode
|
||||||
|
|
||||||
|
class MainApp(
|
||||||
|
logger: Logger[Task],
|
||||||
|
gameApp: GameApp2,
|
||||||
|
spawnProtocol: ActorSystem[SpawnProtocol.Command],
|
||||||
|
jmeThread: monix.execution.Scheduler
|
||||||
|
)(implicit
|
||||||
|
@annotation.unused timeout: Timeout,
|
||||||
|
@annotation.unused scheduler: Scheduler
|
||||||
|
) {
|
||||||
|
|
||||||
|
lazy val scriptSystemInit =
|
||||||
|
new ScriptSystemResource(os.pwd, spawnProtocol, ScriptInitMode.Eager).init
|
||||||
|
|
||||||
|
lazy val gameInit: Task[Unit] = for {
|
||||||
|
eventsModule <- Task(new EventsModule2(spawnProtocol))
|
||||||
|
playerMovementEventBus <- eventsModule.playerMovementEventBusTask
|
||||||
|
playerCameraEventBus <- eventsModule.playerCameraEventBusTask
|
||||||
|
gameAppFib <- gameApp.start.executeOn(jmeThread).start
|
||||||
|
/**
|
||||||
|
* schedule a fiber to run on the JME thread and wait for it's completion
|
||||||
|
* before proceeding forward, as a signal that JME thread has been
|
||||||
|
* initialized, otherwise we'll get NPEs trying to access the fields
|
||||||
|
* of the game app
|
||||||
|
*/
|
||||||
|
initFib <- gameApp.enqueueL(() => Task("done")).start
|
||||||
|
_ <- initFib.join
|
||||||
|
inputManager <- gameApp.inputManager
|
||||||
|
assetManager <- gameApp.assetManager
|
||||||
|
stateManager <- gameApp.stateManager
|
||||||
|
camera <- gameApp.camera
|
||||||
|
rootNode <- gameApp.rootNode
|
||||||
|
enqueueR <- Task(gameApp.enqueue _)
|
||||||
|
viewPort <- gameApp.viewPort
|
||||||
|
bulletAppState <- Task(new BulletAppState())
|
||||||
|
appScheduler <- Task(gameApp.scheduler)
|
||||||
|
// enqueueL <- Task(gameApp.enqueueL _)
|
||||||
|
_ <- wire[MainAppDelegate].init(gameApp.scheduler)
|
||||||
|
_ <- gameAppFib.join
|
||||||
|
} yield ()
|
||||||
|
|
||||||
|
lazy val program = for {
|
||||||
|
scriptSystem <- scriptSystemInit
|
||||||
|
game <- gameInit
|
||||||
|
} yield ()
|
||||||
|
}
|
||||||
|
|
||||||
|
class MainAppDelegate(
|
||||||
|
gameApp: GameApp2,
|
||||||
|
spawnProtocol: ActorSystem[SpawnProtocol.Command],
|
||||||
|
loggerL: Logger[Task],
|
||||||
|
// eventBuses: EventsModule2
|
||||||
|
playerMovementEventBus: ActorRef[
|
||||||
|
EventBus.Command[EntityMovementEvent.PlayerMovementEvent]
|
||||||
|
],
|
||||||
|
playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]],
|
||||||
|
inputManager: InputManager,
|
||||||
|
assetManager: AssetManager,
|
||||||
|
stateManager: AppStateManager,
|
||||||
|
camera: Camera,
|
||||||
|
viewPort: ViewPort,
|
||||||
|
enqueueR: Function1[() => Unit, Unit],
|
||||||
|
rootNode: Ref[Task, Node],
|
||||||
|
bulletAppState: BulletAppState
|
||||||
|
)(implicit
|
||||||
|
@annotation.unused timeout: Timeout,
|
||||||
|
@annotation.unused scheduler: Scheduler
|
||||||
|
) {
|
||||||
|
|
||||||
|
def init(appScheduler: monix.execution.Scheduler) =
|
||||||
|
for {
|
||||||
|
_ <- loggerL.info("Initializing Systems")
|
||||||
|
_ <- Task(stateManager.attach(bulletAppState))
|
||||||
|
_ <- Task(
|
||||||
|
assetManager.registerLocator(
|
||||||
|
(os.rel / "assets" / "town.zip"),
|
||||||
|
classOf[ZipLocator]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_ <- DefaultGameLevel(assetManager, viewPort)
|
||||||
|
.addToGame(
|
||||||
|
rootNode,
|
||||||
|
bulletAppState.physicsSpace
|
||||||
|
)
|
||||||
|
.executeOn(appScheduler)
|
||||||
|
_ <- createPlayerController(appScheduler).startAndForget.onErrorRestart(3)
|
||||||
|
_ <- wire[GameInputHandler.Props].begin.onErrorRestart(3)
|
||||||
|
} yield ()
|
||||||
|
|
||||||
|
def createPlayerController(
|
||||||
|
appScheduler: monix.execution.Scheduler
|
||||||
|
// playerMovementEventBus: ActorRef[
|
||||||
|
// EventBus.Command[PlayerMovementEvent]
|
||||||
|
// ],
|
||||||
|
// playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]]
|
||||||
|
): IO[PlayerController.Error, Unit] = {
|
||||||
|
@annotation.unused
|
||||||
|
val playerPos = ImVector3f.ZERO
|
||||||
|
@annotation.unused
|
||||||
|
val playerNode = None.taggedWith[Player]
|
||||||
|
@annotation.unused
|
||||||
|
val modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o"
|
||||||
|
wire[PlayerController.Props].create
|
||||||
|
}
|
||||||
|
}
|
@ -1,41 +1,13 @@
|
|||||||
package wow.doge.mygame
|
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 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.SpawnProtocol
|
||||||
import akka.actor.typed.Scheduler
|
import cats.effect.Resource
|
||||||
import wow.doge.mygame.utils.AkkaUtils
|
import io.odin.Logger
|
||||||
import scala.concurrent.duration._
|
import monix.bio.Task
|
||||||
import akka.actor.typed.ActorRef
|
import wow.doge.mygame.executors.ExecutorsModule
|
||||||
import wow.doge.mygame.implicits._
|
import wow.doge.mygame.game.GameModule
|
||||||
|
|
||||||
trait MainModule extends GameModule with ExecutorsModule {
|
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(
|
def actorSystemResource2(
|
||||||
logger: Logger[Task]
|
logger: Logger[Task]
|
||||||
@ -43,93 +15,11 @@ trait MainModule extends GameModule with ExecutorsModule {
|
|||||||
Resource.make(logger.info("Creating Actor System") >> Task {
|
Resource.make(logger.info("Creating Actor System") >> Task {
|
||||||
ActorSystem(
|
ActorSystem(
|
||||||
SpawnProtocol(),
|
SpawnProtocol(),
|
||||||
name = "GameActorSystem2"
|
name = "GameActorSystem"
|
||||||
)
|
)
|
||||||
})(sys =>
|
})(sys =>
|
||||||
logger.info("Shutting down actor system") >> Task(
|
logger.info("Shutting down actor system") >> Task(
|
||||||
sys.terminate()
|
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
|
|
||||||
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package wow.doge.mygame.executors
|
package wow.doge.mygame.executors
|
||||||
|
|
||||||
import monix.bio.Task
|
|
||||||
import cats.effect.Resource
|
import cats.effect.Resource
|
||||||
|
import monix.bio.Task
|
||||||
import monix.execution.Scheduler
|
import monix.execution.Scheduler
|
||||||
|
|
||||||
trait ExecutorsModule {
|
trait ExecutorsModule {
|
||||||
|
@ -1,23 +1,21 @@
|
|||||||
package wow.doge.mygame.executors
|
package wow.doge.mygame.executors
|
||||||
|
|
||||||
import akka.dispatch.{
|
|
||||||
DispatcherPrerequisites,
|
|
||||||
ExecutorServiceFactory,
|
|
||||||
ExecutorServiceConfigurator
|
|
||||||
}
|
|
||||||
import com.typesafe.config.Config
|
|
||||||
import java.util.concurrent.{
|
|
||||||
ExecutorService,
|
|
||||||
AbstractExecutorService,
|
|
||||||
ThreadFactory,
|
|
||||||
TimeUnit
|
|
||||||
}
|
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
|
import java.util.concurrent.AbstractExecutorService
|
||||||
|
import java.util.concurrent.Executor
|
||||||
|
import java.util.concurrent.ExecutorService
|
||||||
|
import java.util.concurrent.ThreadFactory
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
import javax.swing.SwingUtilities
|
import javax.swing.SwingUtilities
|
||||||
|
|
||||||
|
import scala.concurrent.ExecutionContext
|
||||||
|
|
||||||
|
import akka.dispatch.DispatcherPrerequisites
|
||||||
|
import akka.dispatch.ExecutorServiceConfigurator
|
||||||
|
import akka.dispatch.ExecutorServiceFactory
|
||||||
|
import com.typesafe.config.Config
|
||||||
import javafx.application.Platform
|
import javafx.application.Platform
|
||||||
import monix.execution.Scheduler
|
import monix.execution.Scheduler
|
||||||
import scala.concurrent.ExecutionContext
|
|
||||||
import java.util.concurrent.Executor
|
|
||||||
|
|
||||||
// First we wrap invokeLater/runLater as an ExecutorService
|
// First we wrap invokeLater/runLater as an ExecutorService
|
||||||
trait GUIExecutorService extends AbstractExecutorService {
|
trait GUIExecutorService extends AbstractExecutorService {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package wow.doge.mygame.executors
|
package wow.doge.mygame.executors
|
||||||
|
|
||||||
|
import com.typesafe.scalalogging.Logger
|
||||||
import monix.execution.Scheduler
|
import monix.execution.Scheduler
|
||||||
import monix.execution.UncaughtExceptionReporter
|
import monix.execution.UncaughtExceptionReporter
|
||||||
import com.typesafe.scalalogging.Logger
|
|
||||||
|
|
||||||
final case class Schedulers(
|
final case class Schedulers(
|
||||||
blockingIO: Scheduler = Scheduler
|
blockingIO: Scheduler = Scheduler
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
package wow.doge.mygame.game
|
package wow.doge.mygame.game
|
||||||
|
|
||||||
import com.jme3.app.SimpleApplication
|
import scala.collection.immutable.Queue
|
||||||
|
|
||||||
|
import com.jme3.app.SimpleApplication
|
||||||
import com.jme3.app.state.AppState
|
import com.jme3.app.state.AppState
|
||||||
import monix.execution.{CancelablePromise => Promise}
|
|
||||||
import monix.execution.CancelableFuture
|
|
||||||
import monix.bio.Task
|
import monix.bio.Task
|
||||||
|
import monix.execution.CancelableFuture
|
||||||
import monix.execution.Scheduler
|
import monix.execution.Scheduler
|
||||||
import wow.doge.mygame.executors.GUIExecutorService
|
import monix.execution.atomic.Atomic
|
||||||
import monix.reactive.subjects.ConcurrentSubject
|
import monix.execution.{CancelablePromise => Promise}
|
||||||
import monix.reactive.MulticastStrategy
|
import monix.reactive.MulticastStrategy
|
||||||
import monix.reactive.Observable
|
import monix.reactive.Observable
|
||||||
import monix.execution.atomic.Atomic
|
import monix.reactive.subjects.ConcurrentSubject
|
||||||
import scala.collection.immutable.Queue
|
import wow.doge.mygame.executors.GUIExecutorService
|
||||||
import wow.doge.mygame.executors.Schedulers
|
import wow.doge.mygame.executors.Schedulers
|
||||||
|
|
||||||
class GameApp(
|
class GameApp(
|
||||||
|
35
src/main/scala/wow/doge/mygame/game/GameApp2.scala
Normal file
35
src/main/scala/wow/doge/mygame/game/GameApp2.scala
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package wow.doge.mygame.game
|
||||||
|
|
||||||
|
import cats.effect.concurrent.Ref
|
||||||
|
import com.jme3.app.state.AppStateManager
|
||||||
|
import com.jme3.asset.AssetManager
|
||||||
|
import com.jme3.input.InputManager
|
||||||
|
import monix.bio.IO
|
||||||
|
import monix.bio.Task
|
||||||
|
|
||||||
|
sealed trait Error
|
||||||
|
case object FlyCamNotExists extends Error
|
||||||
|
|
||||||
|
class GameApp2(app: GameApp) {
|
||||||
|
def stateManager: Task[AppStateManager] = Task(app.getStateManager())
|
||||||
|
def inputManager: Task[InputManager] = Task(app.getInputManager())
|
||||||
|
def assetManager: Task[AssetManager] = Task(app.getAssetManager())
|
||||||
|
def guiNode = Ref[Task].of(app.getGuiNode())
|
||||||
|
def flyCam =
|
||||||
|
IO(app.getFlyByCamera()).onErrorHandleWith(_ =>
|
||||||
|
IO.raiseError(FlyCamNotExists)
|
||||||
|
)
|
||||||
|
def camera = Task(app.getCamera())
|
||||||
|
def viewPort = Task(app.getViewPort())
|
||||||
|
def rootNode = Ref[Task].of(app.getRootNode())
|
||||||
|
def enqueue(cb: () => Unit) =
|
||||||
|
app.enqueue(new Runnable {
|
||||||
|
override def run() = cb()
|
||||||
|
})
|
||||||
|
def enqueueL[T](cb: () => T): Task[T] = app.enqueueL(cb)
|
||||||
|
|
||||||
|
def start = Task(app.start())
|
||||||
|
def stop = Task(app.stop())
|
||||||
|
def scheduler = app.scheduler
|
||||||
|
|
||||||
|
}
|
@ -1,27 +1,15 @@
|
|||||||
package wow.doge.mygame.game
|
package wow.doge.mygame.game
|
||||||
|
|
||||||
import akka.actor.typed.scaladsl.Behaviors
|
|
||||||
import com.jme3.scene.Geometry
|
|
||||||
|
|
||||||
import wow.doge.mygame.events.Events
|
|
||||||
import com.jme3.scene.CameraNode
|
|
||||||
import com.jme3.scene.Node
|
|
||||||
import com.jme3.renderer.Camera
|
|
||||||
import wow.doge.mygame.executors.Schedulers
|
|
||||||
import com.softwaremill.macwire._
|
|
||||||
|
|
||||||
import wow.doge.mygame.implicits._
|
|
||||||
import akka.actor.typed.SpawnProtocol
|
|
||||||
import akka.actor.typed.ActorRef
|
import akka.actor.typed.ActorRef
|
||||||
|
import akka.actor.typed.Scheduler
|
||||||
|
import akka.actor.typed.SpawnProtocol
|
||||||
|
import akka.actor.typed.scaladsl.Behaviors
|
||||||
import io.odin.Logger
|
import io.odin.Logger
|
||||||
import monix.bio.Task
|
import monix.bio.Task
|
||||||
import akka.actor.typed.Scheduler
|
import wow.doge.mygame.events.Events
|
||||||
import scala.util.Failure
|
import wow.doge.mygame.executors.Schedulers
|
||||||
import scala.util.Success
|
|
||||||
import com.jme3.app.StatsAppState
|
|
||||||
|
|
||||||
object GameAppActor {
|
object GameAppActor {
|
||||||
import Methods._
|
|
||||||
|
|
||||||
sealed trait Command
|
sealed trait Command
|
||||||
case object ApplicationStarted extends Command
|
case object ApplicationStarted extends Command
|
||||||
@ -39,22 +27,6 @@ object GameAppActor {
|
|||||||
Behaviors.setup[Command] { ctx =>
|
Behaviors.setup[Command] { ctx =>
|
||||||
ctx.log.info("Hello from GameAppActor")
|
ctx.log.info("Hello from GameAppActor")
|
||||||
|
|
||||||
// {
|
|
||||||
// implicit val s = schedulers.async
|
|
||||||
|
|
||||||
// val initializer: GameSystemsInitializer = wire[GameSystemsInitializer]
|
|
||||||
|
|
||||||
// schedulers.async.execute(() => initializer.init.runAsyncAndForget)
|
|
||||||
|
|
||||||
// // ctx.pipeToSelf(application.timed.runToFuture) {
|
|
||||||
// // case Failure(exception) =>
|
|
||||||
// // ApplicationStartFailed(exception.getMessage())
|
|
||||||
// // case Success(value) =>
|
|
||||||
// // println("here applications started")
|
|
||||||
// // ApplicationStarted
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
|
|
||||||
Behaviors.receiveMessage { msg =>
|
Behaviors.receiveMessage { msg =>
|
||||||
msg match {
|
msg match {
|
||||||
case Stop =>
|
case Stop =>
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
package wow.doge.mygame.game
|
package wow.doge.mygame.game
|
||||||
|
|
||||||
import cats.effect.Resource
|
|
||||||
import com.jme3.system.AppSettings
|
|
||||||
import monix.bio.Task
|
|
||||||
import io.odin.Logger
|
|
||||||
import akka.actor.typed.ActorRef
|
import akka.actor.typed.ActorRef
|
||||||
import akka.actor.typed.SpawnProtocol
|
import akka.actor.typed.SpawnProtocol
|
||||||
import wow.doge.mygame.game.subsystems.input.GameInputHandler
|
import cats.effect.Resource
|
||||||
import monix.bio.IO
|
|
||||||
import monix.bio.Fiber
|
|
||||||
import monix.execution.Scheduler
|
|
||||||
import com.jme3.app.StatsAppState
|
import com.jme3.app.StatsAppState
|
||||||
|
import com.jme3.system.AppSettings
|
||||||
|
import io.odin.Logger
|
||||||
|
import monix.bio.Fiber
|
||||||
|
import monix.bio.IO
|
||||||
|
import monix.bio.Task
|
||||||
|
import monix.execution.Scheduler
|
||||||
import wow.doge.mygame.executors.Schedulers
|
import wow.doge.mygame.executors.Schedulers
|
||||||
|
import wow.doge.mygame.game.subsystems.input.GameInputHandler
|
||||||
class GameAppResource(
|
class GameAppResource(
|
||||||
logger: Logger[Task],
|
logger: Logger[Task],
|
||||||
jmeScheduler: Scheduler,
|
jmeScheduler: Scheduler,
|
||||||
schedulers: Schedulers
|
schedulers: Schedulers
|
||||||
) {
|
) {
|
||||||
def get: Resource[Task, (GameApp, Fiber[Throwable, Unit])] =
|
def get: Resource[Task, (GameApp2, Fiber[Throwable, Unit])] =
|
||||||
Resource.make(
|
Resource.make(
|
||||||
for {
|
for {
|
||||||
_ <- logger.info("Creating game app")
|
_ <- logger.info("Creating game app")
|
||||||
app <- Task(new GameApp(schedulers, new StatsAppState()))
|
app <- Task(new GameApp(schedulers, new StatsAppState()))
|
||||||
_ <- Task {
|
app2 <- Task {
|
||||||
val settings = new AppSettings(true)
|
val settings = new AppSettings(true)
|
||||||
settings.setVSync(true)
|
settings.setVSync(true)
|
||||||
settings.setUseInput(true)
|
settings.setUseInput(true)
|
||||||
@ -30,11 +30,31 @@ class GameAppResource(
|
|||||||
// settings.setFrameRate(250)
|
// settings.setFrameRate(250)
|
||||||
app.setSettings(settings)
|
app.setSettings(settings)
|
||||||
// JMERunner.runner = app
|
// JMERunner.runner = app
|
||||||
app
|
// app
|
||||||
|
new GameApp2(app)
|
||||||
}
|
}
|
||||||
fib <- Task(app.start()).executeOn(jmeScheduler).start
|
fib <- app2.start.executeOn(jmeScheduler).start
|
||||||
} yield (app -> fib)
|
} yield (app2 -> fib)
|
||||||
)(logger.info("Closing game app") >> _._2.cancel)
|
)(logger.info("Closing game app") >> _._2.cancel)
|
||||||
|
|
||||||
|
def get2: Resource[Task, GameApp2] =
|
||||||
|
Resource.make(
|
||||||
|
for {
|
||||||
|
_ <- logger.info("Creating game app")
|
||||||
|
app <- Task(new GameApp(schedulers, new StatsAppState()))
|
||||||
|
app2 <- Task {
|
||||||
|
val settings = new AppSettings(true)
|
||||||
|
settings.setVSync(true)
|
||||||
|
settings.setUseInput(true)
|
||||||
|
// new FlyCamAppState
|
||||||
|
// settings.setFrameRate(250)
|
||||||
|
app.setSettings(settings)
|
||||||
|
// JMERunner.runner = app
|
||||||
|
new GameApp2(app)
|
||||||
|
}
|
||||||
|
// fib <- app2.start.executeOn(jmeScheduler).start
|
||||||
|
} yield (app2)
|
||||||
|
)(_ => logger.info("Closing game app"))
|
||||||
}
|
}
|
||||||
|
|
||||||
trait GameModule {
|
trait GameModule {
|
||||||
|
@ -3,30 +3,34 @@ package wow.doge.mygame.game
|
|||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
import akka.actor.typed.ActorRef
|
import akka.actor.typed.ActorRef
|
||||||
|
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.concurrent.Ref
|
||||||
|
import com.jme3.app.state.AppStateManager
|
||||||
|
import com.jme3.asset.AssetManager
|
||||||
import com.jme3.asset.plugins.ZipLocator
|
import com.jme3.asset.plugins.ZipLocator
|
||||||
import com.jme3.bullet.BulletAppState
|
import com.jme3.bullet.BulletAppState
|
||||||
|
import com.jme3.input.InputManager
|
||||||
|
import com.jme3.renderer.Camera
|
||||||
|
import com.jme3.scene.Node
|
||||||
import com.softwaremill.macwire._
|
import com.softwaremill.macwire._
|
||||||
import com.softwaremill.tagging._
|
import com.softwaremill.tagging._
|
||||||
import io.odin.Logger
|
import io.odin.Logger
|
||||||
|
import monix.bio.IO
|
||||||
import monix.bio.Task
|
import monix.bio.Task
|
||||||
import monix.reactive.Consumer
|
import monix.reactive.Consumer
|
||||||
import wow.doge.mygame.events.EventBus
|
import wow.doge.mygame.events.EventBus
|
||||||
import wow.doge.mygame.game.nodes.Player
|
import wow.doge.mygame.game.nodes.Player
|
||||||
import wow.doge.mygame.game.nodes.PlayerController
|
import wow.doge.mygame.game.nodes.PlayerController
|
||||||
import wow.doge.mygame.game.subsystems.input.GameInputHandler
|
import wow.doge.mygame.game.subsystems.input.GameInputHandler
|
||||||
import wow.doge.mygame.game.subsystems.level.DefaultGameLevel
|
|
||||||
import wow.doge.mygame.implicits._
|
import wow.doge.mygame.implicits._
|
||||||
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
import wow.doge.mygame.math.ImVector3f
|
||||||
|
import wow.doge.mygame.subsystems.events.EntityMovementEvent
|
||||||
|
import wow.doge.mygame.subsystems.events.PlayerCameraEvent
|
||||||
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
||||||
import wow.doge.mygame.utils.IOUtils
|
import wow.doge.mygame.utils.IOUtils
|
||||||
import wow.doge.mygame.math.ImVector3f
|
|
||||||
import monix.bio.IO
|
|
||||||
import wow.doge.mygame.subsystems.events.EntityMovementEvent
|
|
||||||
import akka.actor.typed.ActorSystem
|
|
||||||
import wow.doge.mygame.subsystems.events.PlayerCameraEvent
|
|
||||||
|
|
||||||
class GameSystemsInitializer(
|
class GameSystemsInitializer(
|
||||||
spawnProtocol: ActorSystem[SpawnProtocol.Command],
|
spawnProtocol: ActorSystem[SpawnProtocol.Command],
|
||||||
@ -35,15 +39,22 @@ class GameSystemsInitializer(
|
|||||||
playerMovementEventBus: ActorRef[
|
playerMovementEventBus: ActorRef[
|
||||||
EventBus.Command[EntityMovementEvent.PlayerMovementEvent]
|
EventBus.Command[EntityMovementEvent.PlayerMovementEvent]
|
||||||
],
|
],
|
||||||
playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]]
|
playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]],
|
||||||
)(app: GameApp) {
|
inputManager: InputManager,
|
||||||
|
assetManager: AssetManager,
|
||||||
|
stateManager: AppStateManager,
|
||||||
|
camera: Camera,
|
||||||
|
enqueueR: Function1[() => Unit, Unit],
|
||||||
|
appScheduler: monix.execution.Scheduler,
|
||||||
|
rootNode: Ref[Task, Node]
|
||||||
|
) {
|
||||||
implicit val timeout: Timeout = Timeout(1.second)
|
implicit val timeout: Timeout = Timeout(1.second)
|
||||||
|
|
||||||
import GameSystemsInitializer._
|
import GameSystemsInitializer._
|
||||||
|
|
||||||
implicit val akkaScheduler: Scheduler = spawnProtocol.scheduler
|
implicit val akkaScheduler: Scheduler = spawnProtocol.scheduler
|
||||||
lazy val inputManager = app.inputManager
|
// lazy val inputManager = app.inputManager
|
||||||
lazy val assetManager = app.assetManager
|
// lazy val assetManager = app.assetManager
|
||||||
lazy val bulletAppState = new BulletAppState()
|
lazy val bulletAppState = new BulletAppState()
|
||||||
// lazy val playerMovementEventBus = eventBuses.playerMovementEventBusTask
|
// lazy val playerMovementEventBus = eventBuses.playerMovementEventBusTask
|
||||||
|
|
||||||
@ -51,15 +62,16 @@ class GameSystemsInitializer(
|
|||||||
for {
|
for {
|
||||||
_ <- loggerL.info("Initializing Systems")
|
_ <- loggerL.info("Initializing Systems")
|
||||||
// playerMovementEventBus <- playerMovementEventBusTask
|
// playerMovementEventBus <- playerMovementEventBusTask
|
||||||
_ <- Task(app.stateManager.attach(bulletAppState))
|
_ <- Task(stateManager.attach(bulletAppState))
|
||||||
_ <- Task(
|
_ <- Task(
|
||||||
app.assetManager.registerLocator(
|
assetManager.registerLocator(
|
||||||
// "src/main/resources/assets/town.zip",
|
// "src/main/resources/assets/town.zip",
|
||||||
(os.rel / "src" / "main" / "resources" / "assets" / "town.zip"),
|
(os.rel / "assets" / "town.zip"),
|
||||||
classOf[ZipLocator]
|
classOf[ZipLocator]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
_ <- app.enqueueL(() => DefaultGameLevel(app, bulletAppState))
|
|
||||||
|
// _ <- app.enqueueL(() => DefaultGameLevel(app, bulletAppState))
|
||||||
_ <- wireWith(createPlayerController _).startAndForget
|
_ <- wireWith(createPlayerController _).startAndForget
|
||||||
_ <- wire[GameInputHandler.Props].begin
|
_ <- wire[GameInputHandler.Props].begin
|
||||||
|
|
||||||
@ -71,8 +83,11 @@ class GameSystemsInitializer(
|
|||||||
// ],
|
// ],
|
||||||
// playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]]
|
// playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]]
|
||||||
): IO[PlayerController.Error, Unit] = {
|
): IO[PlayerController.Error, Unit] = {
|
||||||
|
@annotation.unused
|
||||||
val playerPos = ImVector3f.ZERO
|
val playerPos = ImVector3f.ZERO
|
||||||
|
@annotation.unused
|
||||||
val playerNode = None.taggedWith[Player]
|
val playerNode = None.taggedWith[Player]
|
||||||
|
@annotation.unused
|
||||||
val modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o"
|
val modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o"
|
||||||
wire[PlayerController.Props].create
|
wire[PlayerController.Props].create
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,11 @@ package wow.doge.mygame.state
|
|||||||
import com.jme3.app.Application
|
import com.jme3.app.Application
|
||||||
import com.jme3.app.SimpleApplication
|
import com.jme3.app.SimpleApplication
|
||||||
import com.jme3.app.state.AppState
|
import com.jme3.app.state.AppState
|
||||||
import com.jme3.scene.Node
|
|
||||||
import com.jme3.app.state.BaseAppState
|
import com.jme3.app.state.BaseAppState
|
||||||
|
import com.jme3.scene.Node
|
||||||
|
import com.jme3.scene.Spatial
|
||||||
import com.simsilica.es.EntityData
|
import com.simsilica.es.EntityData
|
||||||
import com.simsilica.es.base.DefaultEntityData
|
import com.simsilica.es.base.DefaultEntityData
|
||||||
import com.jme3.scene.Spatial
|
|
||||||
|
|
||||||
trait MyBaseState extends BaseAppState {
|
trait MyBaseState extends BaseAppState {
|
||||||
|
|
||||||
|
@ -2,18 +2,16 @@ package wow.doge.mygame.state
|
|||||||
|
|
||||||
import scala.concurrent.duration.DurationInt
|
import scala.concurrent.duration.DurationInt
|
||||||
|
|
||||||
|
import akka.actor.typed.ActorRef
|
||||||
|
import akka.actor.typed.Behavior
|
||||||
|
import akka.actor.typed.scaladsl.ActorContext
|
||||||
|
import akka.actor.typed.scaladsl.Behaviors
|
||||||
|
import akka.actor.typed.scaladsl.TimerScheduler
|
||||||
import com.jme3.input.InputManager
|
import com.jme3.input.InputManager
|
||||||
import com.jme3.input.KeyInput
|
import com.jme3.input.KeyInput
|
||||||
import com.jme3.input.controls.KeyTrigger
|
import com.jme3.input.controls.KeyTrigger
|
||||||
import com.jme3.math.Vector3f
|
import com.jme3.math.Vector3f
|
||||||
|
|
||||||
import akka.actor.typed.scaladsl.ActorContext
|
|
||||||
import akka.actor.typed.scaladsl.Behaviors
|
|
||||||
import akka.actor.typed.Behavior
|
|
||||||
import akka.actor.typed.ActorRef
|
|
||||||
import com.jme3.scene.Geometry
|
import com.jme3.scene.Geometry
|
||||||
import akka.actor.typed.scaladsl.TimerScheduler
|
|
||||||
|
|
||||||
import wow.doge.mygame.implicits._
|
import wow.doge.mygame.implicits._
|
||||||
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
||||||
|
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
package wow.doge.mygame.state
|
package wow.doge.mygame.state
|
||||||
|
|
||||||
import ammonite.runtime.Storage.Folder
|
|
||||||
import ammonite.main.Defaults
|
|
||||||
import ammonite.Main
|
|
||||||
import javax.script.ScriptEngine
|
import javax.script.ScriptEngine
|
||||||
import com.jme3.app.state.AppState
|
|
||||||
|
import akka.actor.typed.ActorRef
|
||||||
|
import akka.actor.typed.Behavior
|
||||||
|
import akka.actor.typed.SpawnProtocol
|
||||||
import akka.actor.typed.scaladsl.AbstractBehavior
|
import akka.actor.typed.scaladsl.AbstractBehavior
|
||||||
import akka.actor.typed.scaladsl.ActorContext
|
import akka.actor.typed.scaladsl.ActorContext
|
||||||
import akka.actor.typed.Behavior
|
|
||||||
import akka.actor.typed.ActorRef
|
|
||||||
import ammonite.util.Res.Success
|
|
||||||
import akka.actor.typed.scaladsl.Behaviors
|
import akka.actor.typed.scaladsl.Behaviors
|
||||||
import akka.actor.typed.SpawnProtocol
|
import ammonite.Main
|
||||||
|
import ammonite.main.Defaults
|
||||||
|
import ammonite.runtime.Storage.Folder
|
||||||
|
import ammonite.util.Res.Success
|
||||||
|
import com.jme3.app.state.AppState
|
||||||
|
|
||||||
class ScriptingEngineState(
|
class ScriptingEngineState(
|
||||||
sse: ScalaScriptingEngine,
|
sse: ScalaScriptingEngine,
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package wow.doge.mygame.state
|
package wow.doge.mygame.state
|
||||||
|
|
||||||
import wow.doge.mygame.implicits._
|
import com.jme3.asset.AssetManager
|
||||||
import wow.doge.mygame.components.TestComponent
|
|
||||||
import com.jme3.scene.shape.Box
|
|
||||||
import com.jme3.scene.Geometry
|
|
||||||
import com.jme3.material.Material
|
import com.jme3.material.Material
|
||||||
import com.jme3.math.ColorRGBA
|
import com.jme3.math.ColorRGBA
|
||||||
import com.jme3.asset.AssetManager
|
|
||||||
import com.jme3.math.Vector3f
|
import com.jme3.math.Vector3f
|
||||||
|
import com.jme3.scene.Geometry
|
||||||
|
import com.jme3.scene.shape.Box
|
||||||
|
import wow.doge.mygame.components.TestComponent
|
||||||
|
import wow.doge.mygame.implicits._
|
||||||
class TestAppState(
|
class TestAppState(
|
||||||
// private var _entity: Option[EntityData] = Some(new DefaultEntityData())
|
// private var _entity: Option[EntityData] = Some(new DefaultEntityData())
|
||||||
) extends MyBaseState {
|
) extends MyBaseState {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package wow.doge.mygame.components
|
package wow.doge.mygame.components
|
||||||
|
|
||||||
import com.simsilica.es.EntityComponent;
|
import com.simsilica.es.EntityComponent
|
||||||
import wow.doge.mygame.math.ImVector3f
|
import wow.doge.mygame.math.ImVector3f
|
||||||
|
|
||||||
final case class Position(location: ImVector3f) extends EntityComponent
|
final case class Position(location: ImVector3f) extends EntityComponent
|
||||||
|
@ -1,30 +1,29 @@
|
|||||||
package wow.doge.mygame.game.nodes
|
package wow.doge.mygame.game.nodes
|
||||||
|
|
||||||
import akka.actor.typed.scaladsl.Behaviors
|
|
||||||
import akka.actor.typed.scaladsl.ActorContext
|
|
||||||
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
|
||||||
import wow.doge.mygame.game.GameApp
|
|
||||||
import akka.actor.typed.ActorRef
|
|
||||||
import wow.doge.mygame.events.EventBus
|
|
||||||
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
|
||||||
import wow.doge.mygame.subsystems.events.EntityMovementEvent
|
|
||||||
import akka.actor.typed.scaladsl.TimerScheduler
|
|
||||||
import akka.actor.typed.Behavior
|
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
|
import akka.actor.typed.ActorRef
|
||||||
|
import akka.actor.typed.Behavior
|
||||||
import akka.actor.typed.LogOptions
|
import akka.actor.typed.LogOptions
|
||||||
import org.slf4j.event.Level
|
|
||||||
import com.typesafe.scalalogging.Logger
|
|
||||||
import akka.actor.typed.SupervisorStrategy
|
import akka.actor.typed.SupervisorStrategy
|
||||||
|
import akka.actor.typed.scaladsl.ActorContext
|
||||||
|
import akka.actor.typed.scaladsl.Behaviors
|
||||||
|
import akka.actor.typed.scaladsl.TimerScheduler
|
||||||
import com.jme3.scene.CameraNode
|
import com.jme3.scene.CameraNode
|
||||||
import wow.doge.mygame.subsystems.events.PlayerCameraEvent
|
import com.typesafe.scalalogging.Logger
|
||||||
|
import org.slf4j.event.Level
|
||||||
|
import wow.doge.mygame.events.EventBus
|
||||||
import wow.doge.mygame.game.subsystems.movement.CanMove
|
import wow.doge.mygame.game.subsystems.movement.CanMove
|
||||||
import wow.doge.mygame.implicits._
|
import wow.doge.mygame.subsystems.events.EntityMovementEvent
|
||||||
|
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
||||||
|
import wow.doge.mygame.subsystems.events.PlayerCameraEvent
|
||||||
|
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
||||||
|
|
||||||
object PlayerActorSupervisor {
|
object PlayerActorSupervisor {
|
||||||
sealed trait Command
|
sealed trait Command
|
||||||
|
|
||||||
final case class Props(
|
final case class Props(
|
||||||
app: GameApp,
|
enqueueR: Function1[() => Unit, Unit],
|
||||||
camNode: CameraNode,
|
camNode: CameraNode,
|
||||||
playerMovementEventBus: ActorRef[
|
playerMovementEventBus: ActorRef[
|
||||||
EventBus.Command[PlayerMovementEvent]
|
EventBus.Command[PlayerMovementEvent]
|
||||||
@ -47,7 +46,7 @@ object PlayerActorSupervisor {
|
|||||||
Behaviors
|
Behaviors
|
||||||
.supervise(
|
.supervise(
|
||||||
ImMovementActor
|
ImMovementActor
|
||||||
.Props(app, movable, playerMovementEventBus)
|
.Props(enqueueR, movable, playerMovementEventBus)
|
||||||
.create
|
.create
|
||||||
)
|
)
|
||||||
.onFailure[Exception](SupervisorStrategy.restart),
|
.onFailure[Exception](SupervisorStrategy.restart),
|
||||||
@ -70,7 +69,7 @@ object PlayerActorSupervisor {
|
|||||||
ctx.spawn(
|
ctx.spawn(
|
||||||
Behaviors
|
Behaviors
|
||||||
.supervise(
|
.supervise(
|
||||||
PlayerCameraEventListener(camNode, app.enqueueR)
|
PlayerCameraEventListener(camNode, enqueueR)
|
||||||
)
|
)
|
||||||
.onFailure[Exception](SupervisorStrategy.restart),
|
.onFailure[Exception](SupervisorStrategy.restart),
|
||||||
"playerCameraHandler"
|
"playerCameraHandler"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package wow.doge.mygame.game.nodes
|
package wow.doge.mygame.game.nodes
|
||||||
|
|
||||||
import akka.actor.typed.scaladsl.Behaviors
|
|
||||||
import akka.actor.typed.scaladsl.ActorContext
|
import akka.actor.typed.scaladsl.ActorContext
|
||||||
|
import akka.actor.typed.scaladsl.Behaviors
|
||||||
|
|
||||||
object PlayerCameraActor {
|
object PlayerCameraActor {
|
||||||
sealed trait Command
|
sealed trait Command
|
||||||
|
@ -1,33 +1,34 @@
|
|||||||
package wow.doge.mygame.game.nodes
|
package wow.doge.mygame.game.nodes
|
||||||
|
|
||||||
import com.jme3.scene.Node
|
import akka.actor.typed.ActorRef
|
||||||
|
import akka.actor.typed.Props
|
||||||
|
import akka.actor.typed.Scheduler
|
||||||
|
import akka.actor.typed.SpawnProtocol
|
||||||
|
import akka.util.Timeout
|
||||||
|
import cats.effect.concurrent.Ref
|
||||||
|
import cats.implicits._
|
||||||
|
import com.jme3.asset.AssetManager
|
||||||
|
import com.jme3.bullet.BulletAppState
|
||||||
|
import com.jme3.bullet.control.BetterCharacterControl
|
||||||
|
import com.jme3.math.FastMath
|
||||||
|
import com.jme3.renderer.Camera
|
||||||
import com.jme3.scene.CameraNode
|
import com.jme3.scene.CameraNode
|
||||||
import com.jme3.scene.Geometry
|
import com.jme3.scene.Geometry
|
||||||
import com.jme3.renderer.Camera
|
import com.jme3.scene.Node
|
||||||
import com.jme3.asset.AssetManager
|
|
||||||
import wow.doge.mygame.state.MyMaterial
|
|
||||||
import com.jme3.scene.control.CameraControl.ControlDirection
|
import com.jme3.scene.control.CameraControl.ControlDirection
|
||||||
import com.jme3.scene.shape.Box
|
import com.jme3.scene.shape.Box
|
||||||
import com.jme3.bullet.control.BetterCharacterControl
|
import com.softwaremill.tagging._
|
||||||
import com.jme3.bullet.BulletAppState
|
import io.odin.Logger
|
||||||
|
import monix.bio.IO
|
||||||
|
import monix.bio.Task
|
||||||
|
import wow.doge.mygame.events.EventBus
|
||||||
import wow.doge.mygame.game.GameApp
|
import wow.doge.mygame.game.GameApp
|
||||||
import wow.doge.mygame.implicits._
|
import wow.doge.mygame.implicits._
|
||||||
import wow.doge.mygame.math.ImVector3f
|
import wow.doge.mygame.math.ImVector3f
|
||||||
import com.jme3.math.FastMath
|
import wow.doge.mygame.state.MyMaterial
|
||||||
import monix.bio.IO
|
|
||||||
import cats.implicits._
|
|
||||||
import akka.actor.typed.ActorRef
|
|
||||||
import wow.doge.mygame.events.EventBus
|
|
||||||
import akka.actor.typed.SpawnProtocol
|
|
||||||
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
||||||
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
|
||||||
import io.odin.Logger
|
|
||||||
import akka.util.Timeout
|
|
||||||
import monix.bio.Task
|
|
||||||
import akka.actor.typed.Scheduler
|
|
||||||
import akka.actor.typed.Props
|
|
||||||
import com.softwaremill.tagging._
|
|
||||||
import wow.doge.mygame.subsystems.events.PlayerCameraEvent
|
import wow.doge.mygame.subsystems.events.PlayerCameraEvent
|
||||||
|
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
||||||
import wow.doge.mygame.utils.AkkaUtils
|
import wow.doge.mygame.utils.AkkaUtils
|
||||||
|
|
||||||
// class PlayerNode(val name: String) extends Node(name) {}
|
// class PlayerNode(val name: String) extends Node(name) {}
|
||||||
@ -39,7 +40,9 @@ object PlayerController {
|
|||||||
case class GenericError(reason: String) extends Error
|
case class GenericError(reason: String) extends Error
|
||||||
|
|
||||||
class Props(
|
class Props(
|
||||||
app: GameApp,
|
enqueueR: Function1[() => Unit, Unit],
|
||||||
|
rootNode: Ref[Task, Node],
|
||||||
|
camera: Camera,
|
||||||
loggerL: Logger[Task],
|
loggerL: Logger[Task],
|
||||||
assetManager: AssetManager,
|
assetManager: AssetManager,
|
||||||
bulletAppState: BulletAppState,
|
bulletAppState: BulletAppState,
|
||||||
@ -52,15 +55,15 @@ object PlayerController {
|
|||||||
playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]],
|
playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]],
|
||||||
_playerPhysicsControl: Option[BetterCharacterControl],
|
_playerPhysicsControl: Option[BetterCharacterControl],
|
||||||
_playerNode: Option[Node with Player] = None,
|
_playerNode: Option[Node with Player] = None,
|
||||||
_cameraNode: Option[CameraNode with PlayerCameraNode] = None
|
_cameraNode: Option[CameraNode with PlayerCameraNode] = None,
|
||||||
|
appScheduler: monix.execution.Scheduler
|
||||||
)(implicit timeout: Timeout, scheduler: Scheduler) {
|
)(implicit timeout: Timeout, scheduler: Scheduler) {
|
||||||
import Defaults._
|
import Defaults._
|
||||||
import Methods._
|
|
||||||
val create: IO[Error, Unit] =
|
val create: IO[Error, Unit] =
|
||||||
// IO.raiseError(GenericError("not implemented yet"))
|
// IO.raiseError(GenericError("not implemented yet"))
|
||||||
(for {
|
(for {
|
||||||
camNode <- IO(
|
camNode <- IO(
|
||||||
_cameraNode.getOrElse(defaultCamerNode(app.camera, initialPlayerPos))
|
_cameraNode.getOrElse(defaultCamerNode(camera, initialPlayerPos))
|
||||||
)
|
)
|
||||||
playerPhysicsControl <- IO(
|
playerPhysicsControl <- IO(
|
||||||
_playerPhysicsControl
|
_playerPhysicsControl
|
||||||
@ -82,7 +85,7 @@ object PlayerController {
|
|||||||
spawnProtocol,
|
spawnProtocol,
|
||||||
"playerActorSupervisor",
|
"playerActorSupervisor",
|
||||||
new PlayerActorSupervisor.Props(
|
new PlayerActorSupervisor.Props(
|
||||||
app,
|
enqueueR,
|
||||||
camNode,
|
camNode,
|
||||||
playerMovementEventBus,
|
playerMovementEventBus,
|
||||||
playerCameraEventBus
|
playerCameraEventBus
|
||||||
@ -92,11 +95,10 @@ object PlayerController {
|
|||||||
bulletAppState.physicsSpace += playerNode
|
bulletAppState.physicsSpace += playerNode
|
||||||
bulletAppState.physicsSpace += playerPhysicsControl
|
bulletAppState.physicsSpace += playerPhysicsControl
|
||||||
}
|
}
|
||||||
_ <- IO(app.rootNode += playerNode)
|
_ <- rootNode.update(_ :+ playerNode)
|
||||||
} yield ())
|
} yield ())
|
||||||
.onErrorHandleWith(e => IO.raiseError(GenericError(e.getMessage())))
|
.onErrorHandleWith(e => IO.raiseError(GenericError(e.getMessage())))
|
||||||
.executeOn(app.scheduler)
|
.executeOn(appScheduler)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def apply(
|
def apply(
|
||||||
@ -175,7 +177,7 @@ object Defaults {
|
|||||||
|
|
||||||
object Methods {
|
object Methods {
|
||||||
def spawnMovementActor(
|
def spawnMovementActor(
|
||||||
app: GameApp,
|
enqueueR: Function1[() => Unit, Unit],
|
||||||
spawnProtocol: ActorRef[SpawnProtocol.Command],
|
spawnProtocol: ActorRef[SpawnProtocol.Command],
|
||||||
movable: BetterCharacterControl @@ Player,
|
movable: BetterCharacterControl @@ Player,
|
||||||
playerMovementEventBus: ActorRef[
|
playerMovementEventBus: ActorRef[
|
||||||
@ -185,7 +187,7 @@ object Methods {
|
|||||||
)(implicit timeout: Timeout, scheduler: Scheduler) =
|
)(implicit timeout: Timeout, scheduler: Scheduler) =
|
||||||
spawnProtocol.askL[ActorRef[ImMovementActor.Command]](
|
spawnProtocol.askL[ActorRef[ImMovementActor.Command]](
|
||||||
SpawnProtocol.Spawn(
|
SpawnProtocol.Spawn(
|
||||||
ImMovementActor.Props(app, movable, playerMovementEventBus).create,
|
ImMovementActor.Props(enqueueR, movable, playerMovementEventBus).create,
|
||||||
"imMovementActor",
|
"imMovementActor",
|
||||||
Props.empty,
|
Props.empty,
|
||||||
_
|
_
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
package wow.doge.mygame.game.nodes
|
package wow.doge.mygame.game.nodes
|
||||||
|
|
||||||
import akka.actor.typed.ActorRef
|
import akka.actor.typed.ActorRef
|
||||||
import akka.actor.typed.scaladsl.Behaviors
|
|
||||||
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
|
||||||
import org.slf4j.event.Level
|
|
||||||
import akka.actor.typed.LogOptions
|
import akka.actor.typed.LogOptions
|
||||||
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
import akka.actor.typed.scaladsl.Behaviors
|
||||||
import com.typesafe.scalalogging.Logger
|
|
||||||
import wow.doge.mygame.subsystems.events.PlayerCameraEvent
|
|
||||||
import wow.doge.mygame.subsystems.events.PlayerCameraEvent.CameraMovedUp
|
|
||||||
import wow.doge.mygame.subsystems.events.PlayerCameraEvent.CameraMovedDown
|
|
||||||
import com.jme3.scene.CameraNode
|
import com.jme3.scene.CameraNode
|
||||||
import wow.doge.mygame.game.GameApp
|
import com.typesafe.scalalogging.Logger
|
||||||
import wow.doge.mygame.implicits._
|
import org.slf4j.event.Level
|
||||||
|
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
||||||
|
import wow.doge.mygame.subsystems.events.PlayerCameraEvent
|
||||||
|
import wow.doge.mygame.subsystems.events.PlayerCameraEvent.CameraMovedDown
|
||||||
|
import wow.doge.mygame.subsystems.events.PlayerCameraEvent.CameraMovedUp
|
||||||
|
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
||||||
|
|
||||||
object PlayerMovementEventListener {
|
object PlayerMovementEventListener {
|
||||||
import PlayerMovementEvent._
|
import PlayerMovementEvent._
|
||||||
|
@ -1,23 +1,19 @@
|
|||||||
package wow.doge.mygame.game.subsystems.input
|
package wow.doge.mygame.game.subsystems.input
|
||||||
|
|
||||||
import com.jme3.input.InputManager
|
|
||||||
import wow.doge.mygame.implicits._
|
|
||||||
import akka.actor.typed.ActorRef
|
|
||||||
import wow.doge.mygame.events.EventBus
|
|
||||||
import com.jme3.input.KeyInput
|
|
||||||
import com.jme3.input.controls.KeyTrigger
|
|
||||||
import monix.bio.UIO
|
|
||||||
import wow.doge.mygame.utils.IOUtils._
|
|
||||||
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
import com.jme3.input.controls.MouseAxisTrigger
|
|
||||||
import com.jme3.input.MouseInput
|
|
||||||
import wow.doge.mygame.subsystems.events.PlayerCameraEvent
|
|
||||||
|
|
||||||
// class GameInputHandler(
|
import akka.actor.typed.ActorRef
|
||||||
// inputManager: InputManager
|
import com.jme3.input.InputManager
|
||||||
// // inputEventBus: InputEventBus
|
import com.jme3.input.KeyInput
|
||||||
// ) {}
|
import com.jme3.input.MouseInput
|
||||||
|
import com.jme3.input.controls.KeyTrigger
|
||||||
|
import com.jme3.input.controls.MouseAxisTrigger
|
||||||
|
import monix.bio.UIO
|
||||||
|
import wow.doge.mygame.events.EventBus
|
||||||
|
import wow.doge.mygame.implicits._
|
||||||
|
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
||||||
|
import wow.doge.mygame.subsystems.events.PlayerCameraEvent
|
||||||
|
import wow.doge.mygame.utils.IOUtils._
|
||||||
|
|
||||||
object GameInputHandler {
|
object GameInputHandler {
|
||||||
|
|
||||||
@ -30,6 +26,7 @@ object GameInputHandler {
|
|||||||
) {
|
) {
|
||||||
def begin =
|
def begin =
|
||||||
for {
|
for {
|
||||||
|
_ <- UIO(setupMovementKeys(inputManager))
|
||||||
_ <- UIO(setupKeys(inputManager))
|
_ <- UIO(setupKeys(inputManager))
|
||||||
_ <- toIO(
|
_ <- toIO(
|
||||||
generateMovementInputEvents(
|
generateMovementInputEvents(
|
||||||
@ -49,40 +46,49 @@ object GameInputHandler {
|
|||||||
playerCameraEventBus
|
playerCameraEventBus
|
||||||
).completedL.startAndForget
|
).completedL.startAndForget
|
||||||
)
|
)
|
||||||
_ <- toIO(
|
|
||||||
myTest(
|
|
||||||
inputManager
|
|
||||||
).completedL.startAndForget
|
|
||||||
)
|
|
||||||
} yield ()
|
} yield ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def setupMovementKeys(inputManager: InputManager) =
|
||||||
|
inputManager.withEnumMappings(PlayerMovementInput) {
|
||||||
|
case PlayerMovementInput.WalkRight =>
|
||||||
|
Seq(new KeyTrigger(KeyInput.KEY_D))
|
||||||
|
case PlayerMovementInput.WalkLeft =>
|
||||||
|
Seq(new KeyTrigger(KeyInput.KEY_A))
|
||||||
|
case PlayerMovementInput.WalkForward =>
|
||||||
|
Seq(new KeyTrigger(KeyInput.KEY_W))
|
||||||
|
case PlayerMovementInput.WalkBackward =>
|
||||||
|
Seq(new KeyTrigger(KeyInput.KEY_S))
|
||||||
|
case PlayerMovementInput.Jump =>
|
||||||
|
Seq(new KeyTrigger(KeyInput.KEY_SPACE))
|
||||||
|
}
|
||||||
|
|
||||||
def setupKeys(inputManager: InputManager) =
|
def setupKeys(inputManager: InputManager) =
|
||||||
inputManager
|
inputManager
|
||||||
.withMapping(
|
// .withMapping(
|
||||||
PlayerMovementInput.WalkLeft.entryName,
|
// PlayerMovementInput.WalkLeft.entryName,
|
||||||
new KeyTrigger(KeyInput.KEY_A)
|
// new KeyTrigger(KeyInput.KEY_A)
|
||||||
// new KeyTrigger(KeyInput.KEY_LEFT)
|
// // new KeyTrigger(KeyInput.KEY_LEFT)
|
||||||
)
|
// )
|
||||||
.withMapping(
|
// .withMapping(
|
||||||
PlayerMovementInput.WalkRight.entryName,
|
// PlayerMovementInput.WalkRight.entryName,
|
||||||
new KeyTrigger(KeyInput.KEY_D)
|
// new KeyTrigger(KeyInput.KEY_D)
|
||||||
// new KeyTrigger(KeyInput.KEY_RIGHT)
|
// // new KeyTrigger(KeyInput.KEY_RIGHT)
|
||||||
)
|
// )
|
||||||
.withMapping(
|
// .withMapping(
|
||||||
PlayerMovementInput.WalkForward.entryName,
|
// PlayerMovementInput.WalkForward.entryName,
|
||||||
new KeyTrigger(KeyInput.KEY_W)
|
// new KeyTrigger(KeyInput.KEY_W)
|
||||||
// new KeyTrigger(KeyInput.KEY_UP)
|
// // new KeyTrigger(KeyInput.KEY_UP)
|
||||||
)
|
// )
|
||||||
.withMapping(
|
// .withMapping(
|
||||||
PlayerMovementInput.WalkBackward.entryName,
|
// PlayerMovementInput.WalkBackward.entryName,
|
||||||
new KeyTrigger(KeyInput.KEY_S)
|
// new KeyTrigger(KeyInput.KEY_S)
|
||||||
// new KeyTrigger(KeyInput.KEY_DOWN)
|
// // new KeyTrigger(KeyInput.KEY_DOWN)
|
||||||
)
|
// )
|
||||||
.withMapping(
|
// .withMapping(
|
||||||
"Jump",
|
// PlayerMovementInput.Jump.entryName,
|
||||||
new KeyTrigger(KeyInput.KEY_SPACE)
|
// new KeyTrigger(KeyInput.KEY_SPACE)
|
||||||
)
|
// )
|
||||||
.withMapping(
|
.withMapping(
|
||||||
PlayerAnalogInput.TurnRight.entryName,
|
PlayerAnalogInput.TurnRight.entryName,
|
||||||
new KeyTrigger(KeyInput.KEY_RIGHT),
|
new KeyTrigger(KeyInput.KEY_RIGHT),
|
||||||
@ -145,31 +151,17 @@ object GameInputHandler {
|
|||||||
name
|
name
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
// case "Jump" if action.value =>
|
case PlayerMovementInput.Jump =>
|
||||||
// toTask(
|
if (action.value) {
|
||||||
// playerMovementEventBus !! EventBus.Publish(
|
toTask(
|
||||||
// PlayerMovementEvent.PlayerJumped,
|
playerMovementEventBus !! EventBus.Publish(
|
||||||
// name
|
PlayerMovementEvent.PlayerJumped,
|
||||||
// )
|
name
|
||||||
// )
|
|
||||||
|
|
||||||
// case _ => monix.eval.Task.unit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def myTest(inputManager: InputManager) = {
|
|
||||||
inputManager
|
|
||||||
.enumObservableAction(PlayerMovementEnum)
|
|
||||||
.sample(1.millis)
|
|
||||||
.mapEval(action =>
|
|
||||||
action.binding match {
|
|
||||||
case PlayerMovementEnum.MOVE_RIGHT =>
|
|
||||||
monix.eval.Task(println("move right")) >> monix.eval.Task.unit
|
|
||||||
case PlayerMovementEnum.MOVE_LEFT =>
|
|
||||||
monix.eval.Task(println("move left"))
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
} else monix.eval.Task.unit
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def generateRotateEvents(
|
def generateRotateEvents(
|
||||||
@ -182,7 +174,7 @@ object GameInputHandler {
|
|||||||
inputManager
|
inputManager
|
||||||
.enumAnalogObservable(PlayerAnalogInput)
|
.enumAnalogObservable(PlayerAnalogInput)
|
||||||
.sample(1.millis)
|
.sample(1.millis)
|
||||||
.map(e => e)
|
// .map(e => e)
|
||||||
.doOnNext(analogEvent =>
|
.doOnNext(analogEvent =>
|
||||||
analogEvent.binding match {
|
analogEvent.binding match {
|
||||||
case PlayerAnalogInput.TurnRight =>
|
case PlayerAnalogInput.TurnRight =>
|
||||||
@ -231,17 +223,4 @@ object GameInputHandler {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// def bindMappings(inputManager: InputManager, mappings: ActionMapping*) = {
|
|
||||||
// inputManager
|
|
||||||
// .observableAction(mappings.map(_.name): _*)
|
|
||||||
// .doOnNext(action =>
|
|
||||||
// mappings.map(m =>
|
|
||||||
// if (action.binding.name == m.name) toTask(m.cb(action))
|
|
||||||
// else monix.eval.Task.unit
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// case class ActionMapping(name: String, cb: ActionEvent => Task[Unit])
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package wow.doge.mygame.game.subsystems.input
|
package wow.doge.mygame.game.subsystems.input
|
||||||
import enumeratum._
|
|
||||||
import enumeratum.EnumEntry._
|
import enumeratum.EnumEntry._
|
||||||
|
import enumeratum._
|
||||||
|
|
||||||
sealed trait PlayerMovementInput extends EnumEntry with UpperSnakecase
|
sealed trait PlayerMovementInput extends EnumEntry with UpperSnakecase
|
||||||
object PlayerMovementInput extends Enum[PlayerMovementInput] {
|
object PlayerMovementInput extends Enum[PlayerMovementInput] {
|
||||||
@ -9,6 +9,7 @@ object PlayerMovementInput extends Enum[PlayerMovementInput] {
|
|||||||
case object WalkRight extends PlayerMovementInput
|
case object WalkRight extends PlayerMovementInput
|
||||||
case object WalkLeft extends PlayerMovementInput
|
case object WalkLeft extends PlayerMovementInput
|
||||||
case object WalkBackward extends PlayerMovementInput
|
case object WalkBackward extends PlayerMovementInput
|
||||||
|
case object Jump extends PlayerMovementInput
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed trait PlayerAnalogInput extends EnumEntry with UpperSnakecase
|
sealed trait PlayerAnalogInput extends EnumEntry with UpperSnakecase
|
||||||
|
@ -1,36 +1,20 @@
|
|||||||
package wow.doge.mygame.game.subsystems.level
|
package wow.doge.mygame.game.subsystems.level
|
||||||
import com.jme3.bullet.BulletAppState
|
import com.jme3.asset.AssetManager
|
||||||
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape
|
|
||||||
import com.jme3.bullet.control.CharacterControl
|
|
||||||
import com.jme3.bullet.control.RigidBodyControl
|
import com.jme3.bullet.control.RigidBodyControl
|
||||||
import com.jme3.bullet.util.CollisionShapeFactory
|
import com.jme3.bullet.util.CollisionShapeFactory
|
||||||
import com.jme3.scene.Spatial
|
|
||||||
import wow.doge.mygame.implicits._
|
|
||||||
import wow.doge.mygame.game.GameApp
|
|
||||||
import com.jme3.syntax._
|
|
||||||
import com.jme3.math.ColorRGBA
|
|
||||||
import com.jme3.light.DirectionalLight
|
|
||||||
import com.jme3.math.Vector3f
|
|
||||||
import com.jme3.light.AmbientLight
|
import com.jme3.light.AmbientLight
|
||||||
|
import com.jme3.light.DirectionalLight
|
||||||
|
import com.jme3.math.ColorRGBA
|
||||||
|
import com.jme3.math.Vector3f
|
||||||
|
import com.jme3.renderer.ViewPort
|
||||||
|
import com.jme3.scene.Spatial
|
||||||
object DefaultGameLevel {
|
object DefaultGameLevel {
|
||||||
|
|
||||||
// lazy valbulletAppState: BulletAppState
|
def apply(
|
||||||
// bulletAppState.setThreadingType(ThreadingType.SEQUENTIAL)
|
assetManager: AssetManager,
|
||||||
|
viewPort: ViewPort
|
||||||
// We set up collision detection for the scene by creating a
|
) = {
|
||||||
// compound collision shape and a static RigidBodyControl with mass zero.
|
lazy val sceneModel: Spatial = assetManager.loadModel("main.scene")
|
||||||
|
|
||||||
// We set up collision detection for the player by creating
|
|
||||||
// a capsule collision shape and a CharacterControl.
|
|
||||||
// The CharacterControl offers extra settings for
|
|
||||||
// size, stepheight, jumping, falling, and gravity.
|
|
||||||
// We also put the player in its starting position.
|
|
||||||
lazy val capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1)
|
|
||||||
|
|
||||||
lazy val player: CharacterControl =
|
|
||||||
new CharacterControl(capsuleShape, 0.05f)
|
|
||||||
def apply(app: GameApp, bulletAppState: BulletAppState) = {
|
|
||||||
lazy val sceneModel: Spatial = app.assetManager.loadModel("main.scene")
|
|
||||||
lazy val sceneShape = CollisionShapeFactory.createMeshShape(
|
lazy val sceneShape = CollisionShapeFactory.createMeshShape(
|
||||||
sceneModel.toNode match {
|
sceneModel.toNode match {
|
||||||
case util.Right(node) => node
|
case util.Right(node) => node
|
||||||
@ -41,23 +25,26 @@ object DefaultGameLevel {
|
|||||||
lazy val landscape: RigidBodyControl =
|
lazy val landscape: RigidBodyControl =
|
||||||
new RigidBodyControl(sceneShape, 0)
|
new RigidBodyControl(sceneShape, 0)
|
||||||
|
|
||||||
// // discard { app.stateManager.attach(bulletAppState) }
|
viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f))
|
||||||
|
|
||||||
app.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f))
|
|
||||||
sceneModel.setLocalScale(2f)
|
sceneModel.setLocalScale(2f)
|
||||||
sceneModel.addControl(landscape)
|
sceneModel.addControl(landscape)
|
||||||
discard { app.rootNode.attachChild(sceneModel) }
|
// discard { rootNode.attachChild(sceneModel) }
|
||||||
bulletAppState.getPhysicsSpace.add(landscape)
|
// bulletAppState.getPhysicsSpace.add(landscape)
|
||||||
bulletAppState.getPhysicsSpace.add(player)
|
// bulletAppState.getPhysicsSpace.add(player)
|
||||||
|
|
||||||
val al = new AmbientLight();
|
val al = new AmbientLight();
|
||||||
al.setColor(ColorRGBA.White.mult(1.3f));
|
al.setColor(ColorRGBA.White.mult(1.3f));
|
||||||
app.rootNode.addLight(al);
|
// app.rootNode.addLight(al);
|
||||||
|
|
||||||
val dl = new DirectionalLight();
|
val dl = new DirectionalLight();
|
||||||
dl.setColor(ColorRGBA.White);
|
dl.setColor(ColorRGBA.White);
|
||||||
dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal());
|
dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal());
|
||||||
app.rootNode.addLight(dl);
|
// app.rootNode.addLight(dl);
|
||||||
|
new Level(
|
||||||
|
model = sceneModel,
|
||||||
|
physicsControl = landscape,
|
||||||
|
ambientLight = al,
|
||||||
|
directionalLight = dl
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
package wow.doge.mygame.game.subsystems.level
|
||||||
|
|
||||||
|
import com.jme3.bullet.control.RigidBodyControl
|
||||||
|
import com.jme3.light.AmbientLight
|
||||||
|
import com.jme3.light.DirectionalLight
|
||||||
|
import com.jme3.scene.Spatial
|
||||||
|
import com.jme3.bullet.PhysicsSpace
|
||||||
|
import cats.effect.concurrent.Ref
|
||||||
|
import monix.bio.Task
|
||||||
|
import com.jme3.scene.Node
|
||||||
|
import wow.doge.mygame.implicits._
|
||||||
|
|
||||||
|
class Level(
|
||||||
|
model: Spatial,
|
||||||
|
physicsControl: RigidBodyControl,
|
||||||
|
ambientLight: AmbientLight,
|
||||||
|
directionalLight: DirectionalLight
|
||||||
|
) {
|
||||||
|
def addToGame(rootNode: Ref[Task, Node], physicsSpace: PhysicsSpace) = {
|
||||||
|
for {
|
||||||
|
_ <- rootNode.update(_ :+ model)
|
||||||
|
_ <- rootNode.update { r =>
|
||||||
|
r.addLight(ambientLight)
|
||||||
|
r
|
||||||
|
}
|
||||||
|
_ <- rootNode.update { r =>
|
||||||
|
r.addLight(directionalLight)
|
||||||
|
r
|
||||||
|
}
|
||||||
|
_ <- Task(physicsSpace += model)
|
||||||
|
_ <- Task(physicsSpace += physicsControl)
|
||||||
|
} yield ()
|
||||||
|
}
|
||||||
|
}
|
@ -4,11 +4,11 @@ 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
|
||||||
import com.jme3.math.Vector3f
|
import com.jme3.math.Vector3f
|
||||||
import wow.doge.mygame.math.ImVector3f
|
|
||||||
import wow.doge.mygame.subsystems.movement.RotateDir
|
|
||||||
import wow.doge.mygame.implicits._
|
|
||||||
import com.jme3.scene.Spatial
|
import com.jme3.scene.Spatial
|
||||||
import com.typesafe.scalalogging.LazyLogging
|
import com.typesafe.scalalogging.LazyLogging
|
||||||
|
import wow.doge.mygame.implicits._
|
||||||
|
import wow.doge.mygame.math.ImVector3f
|
||||||
|
import wow.doge.mygame.subsystems.movement.RotateDir
|
||||||
|
|
||||||
trait CanMove[-A] {
|
trait CanMove[-A] {
|
||||||
// def getDirection(cam: Camera, cardinalDir: CardinalDirection): ImVector3f
|
// def getDirection(cam: Camera, cardinalDir: CardinalDirection): ImVector3f
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
package wow.doge.mygame.subsystems.movement
|
package wow.doge.mygame.subsystems.movement
|
||||||
|
|
||||||
import akka.actor.typed.scaladsl.ActorContext
|
import akka.actor.typed.ActorRef
|
||||||
import akka.actor.typed.Behavior
|
import akka.actor.typed.Behavior
|
||||||
|
import akka.actor.typed.scaladsl.ActorContext
|
||||||
import akka.actor.typed.scaladsl.Behaviors
|
import akka.actor.typed.scaladsl.Behaviors
|
||||||
|
import com.jme3.math.Vector3f
|
||||||
|
import com.softwaremill.quicklens._
|
||||||
|
import wow.doge.mygame.events.EventBus
|
||||||
|
import wow.doge.mygame.game.subsystems.movement.CanMove
|
||||||
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.game.GameApp
|
|
||||||
|
|
||||||
import akka.actor.typed.ActorRef
|
|
||||||
import wow.doge.mygame.events.EventBus
|
|
||||||
import com.jme3.math.Vector3f
|
|
||||||
import wow.doge.mygame.state.CardinalDirection
|
import wow.doge.mygame.state.CardinalDirection
|
||||||
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
||||||
import wow.doge.mygame.game.subsystems.movement.CanMove
|
|
||||||
import com.softwaremill.quicklens._
|
|
||||||
|
|
||||||
sealed trait RotateDir
|
sealed trait RotateDir
|
||||||
object RotateDir {
|
object RotateDir {
|
||||||
@ -36,7 +34,7 @@ object ImMovementActor {
|
|||||||
final case object RotateLeft extends Movement
|
final case object RotateLeft extends Movement
|
||||||
|
|
||||||
final case class Props[T: CanMove](
|
final case class Props[T: CanMove](
|
||||||
app: GameApp,
|
enqueueR: Function1[() => Unit, Unit],
|
||||||
movable: T,
|
movable: T,
|
||||||
playerMovementEventBus: ActorRef[
|
playerMovementEventBus: ActorRef[
|
||||||
EventBus.Command[PlayerMovementEvent]
|
EventBus.Command[PlayerMovementEvent]
|
||||||
@ -90,25 +88,25 @@ class ImMovementActor[T](
|
|||||||
case m: Movement =>
|
case m: Movement =>
|
||||||
m match {
|
m match {
|
||||||
case MovedLeft(pressed) =>
|
case MovedLeft(pressed) =>
|
||||||
props.app.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
props.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
||||||
receive(state = state.modify(_.cardinalDir.left).setTo(pressed))
|
receive(state = state.modify(_.cardinalDir.left).setTo(pressed))
|
||||||
case MovedUp(pressed) =>
|
case MovedUp(pressed) =>
|
||||||
props.app.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
props.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
||||||
receive(state = state.modify(_.cardinalDir.up).setTo(pressed))
|
receive(state = state.modify(_.cardinalDir.up).setTo(pressed))
|
||||||
case MovedRight(pressed) =>
|
case MovedRight(pressed) =>
|
||||||
props.app.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
props.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
||||||
receive(state = state.modify(_.cardinalDir.right).setTo(pressed))
|
receive(state = state.modify(_.cardinalDir.right).setTo(pressed))
|
||||||
case MovedDown(pressed) =>
|
case MovedDown(pressed) =>
|
||||||
props.app.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
props.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
||||||
receive(state = state.modify(_.cardinalDir.down).setTo(pressed))
|
receive(state = state.modify(_.cardinalDir.down).setTo(pressed))
|
||||||
case Jump =>
|
case Jump =>
|
||||||
props.app.enqueueR(() => cm.jump(props.movable))
|
props.enqueueR(() => cm.jump(props.movable))
|
||||||
Behaviors.same
|
Behaviors.same
|
||||||
case RotateLeft =>
|
case RotateLeft =>
|
||||||
props.app.enqueueR(() => cm.rotate(props.movable, RotateDir.Left))
|
props.enqueueR(() => cm.rotate(props.movable, RotateDir.Left))
|
||||||
Behaviors.same
|
Behaviors.same
|
||||||
case RotateRight =>
|
case RotateRight =>
|
||||||
props.app.enqueueR(() => cm.rotate(props.movable, RotateDir.Right))
|
props.enqueueR(() => cm.rotate(props.movable, RotateDir.Right))
|
||||||
Behaviors.same
|
Behaviors.same
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +115,7 @@ class ImMovementActor[T](
|
|||||||
getDirection(state.cardinalDir, ctx.log.trace)
|
getDirection(state.cardinalDir, ctx.log.trace)
|
||||||
if (walkDir != ImVector3f.ZERO) {
|
if (walkDir != ImVector3f.ZERO) {
|
||||||
val tmp = walkDir * 25f * (1f / 144)
|
val tmp = walkDir * 25f * (1f / 144)
|
||||||
props.app.enqueueR { () =>
|
props.enqueueR { () =>
|
||||||
cm.move(props.movable, tmp)
|
cm.move(props.movable, tmp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package wow.doge.mygame.implicits
|
package wow.doge.mygame.implicits
|
||||||
|
|
||||||
|
import scala.reflect.ClassTag
|
||||||
|
import scala.util.Try
|
||||||
|
|
||||||
import com.simsilica.es.ComponentFilter
|
import com.simsilica.es.ComponentFilter
|
||||||
import com.simsilica.es.EntityComponent
|
import com.simsilica.es.EntityComponent
|
||||||
import com.simsilica.es.EntityData
|
import com.simsilica.es.EntityData
|
||||||
import com.simsilica.es.EntitySet
|
import com.simsilica.es.EntitySet
|
||||||
import com.simsilica.es.Filters
|
import com.simsilica.es.Filters
|
||||||
import scala.reflect.ClassTag
|
|
||||||
import scala.util.Try
|
|
||||||
|
|
||||||
class EntityQuery(ed: EntityData) {
|
class EntityQuery(ed: EntityData) {
|
||||||
private var cfilter: Option[ComponentFilter[_ <: EntityComponent]] = None
|
private var cfilter: Option[ComponentFilter[_ <: EntityComponent]] = None
|
||||||
|
@ -1,52 +1,54 @@
|
|||||||
package wow.doge.mygame
|
package wow.doge.mygame
|
||||||
|
|
||||||
import com.jme3.app.SimpleApplication
|
|
||||||
import com.jme3.app.state.AppStateManager
|
|
||||||
import scala.reflect.ClassTag
|
|
||||||
import com.jme3.app.state.AppState
|
|
||||||
import com.jme3.scene.Node
|
|
||||||
import com.jme3.scene.Spatial
|
|
||||||
import com.simsilica.es.EntityData
|
|
||||||
import com.simsilica.es.EntityComponent
|
|
||||||
import com.simsilica.es.EntityId
|
|
||||||
import akka.actor.typed.ActorRef
|
|
||||||
import akka.util.Timeout
|
|
||||||
import akka.actor.typed.Scheduler
|
|
||||||
import monix.bio.Task
|
|
||||||
import com.jme3.input.InputManager
|
|
||||||
import com.jme3.input.controls.Trigger
|
|
||||||
import com.jme3.input.controls.InputListener
|
|
||||||
import com.jme3.math.Vector3f
|
|
||||||
import wow.doge.mygame.math.ImVector3f
|
|
||||||
import com.jme3.scene.Geometry
|
|
||||||
import scala.jdk.CollectionConverters._
|
import scala.jdk.CollectionConverters._
|
||||||
|
import scala.reflect.ClassTag
|
||||||
|
|
||||||
|
import akka.actor.typed.ActorRef
|
||||||
|
import akka.actor.typed.Scheduler
|
||||||
|
import akka.util.Timeout
|
||||||
|
import cats.effect.concurrent.Ref
|
||||||
import com.jme3.app.Application
|
import com.jme3.app.Application
|
||||||
import com.jme3.scene.SceneGraphVisitor
|
import com.jme3.app.SimpleApplication
|
||||||
import monix.reactive.Observable
|
import com.jme3.app.state.AppState
|
||||||
import com.jme3.asset.AssetManager
|
import com.jme3.app.state.AppStateManager
|
||||||
import com.jme3.asset.AssetLocator
|
import com.jme3.asset.AssetLocator
|
||||||
import com.jme3.input.controls.ActionListener
|
import com.jme3.asset.AssetManager
|
||||||
import monix.reactive.OverflowStrategy
|
|
||||||
import monix.execution.Ack
|
|
||||||
import monix.execution.Cancelable
|
|
||||||
import monix.execution.cancelables.SingleAssignCancelable
|
|
||||||
import com.jme3.input.Action
|
|
||||||
import com.jme3.bullet.PhysicsSpace
|
|
||||||
import com.jme3.bullet.collision.PhysicsCollisionListener
|
|
||||||
import com.jme3.bullet.collision.PhysicsCollisionEvent
|
|
||||||
import com.jme3.bullet.PhysicsTickListener
|
|
||||||
import monix.reactive.observers.Subscriber
|
|
||||||
import monix.execution.Ack.Continue
|
|
||||||
import monix.execution.Ack.Stop
|
|
||||||
import com.jme3.bullet.BulletAppState
|
import com.jme3.bullet.BulletAppState
|
||||||
import wow.doge.mygame.state.MyBaseState
|
import com.jme3.bullet.PhysicsSpace
|
||||||
import monix.bio.UIO
|
import com.jme3.bullet.PhysicsTickListener
|
||||||
|
import com.jme3.bullet.collision.PhysicsCollisionEvent
|
||||||
|
import com.jme3.bullet.collision.PhysicsCollisionListener
|
||||||
import com.jme3.bullet.control.BetterCharacterControl
|
import com.jme3.bullet.control.BetterCharacterControl
|
||||||
|
import com.jme3.input.Action
|
||||||
|
import com.jme3.input.InputManager
|
||||||
|
import com.jme3.input.controls.ActionListener
|
||||||
|
import com.jme3.input.controls.AnalogListener
|
||||||
|
import com.jme3.input.controls.InputListener
|
||||||
|
import com.jme3.input.controls.Trigger
|
||||||
|
import com.jme3.math.Vector3f
|
||||||
import com.jme3.scene.CameraNode
|
import com.jme3.scene.CameraNode
|
||||||
|
import com.jme3.scene.Geometry
|
||||||
|
import com.jme3.scene.Node
|
||||||
|
import com.jme3.scene.SceneGraphVisitor
|
||||||
|
import com.jme3.scene.Spatial
|
||||||
import com.jme3.scene.control.CameraControl.ControlDirection
|
import com.jme3.scene.control.CameraControl.ControlDirection
|
||||||
import com.jme3.scene.control.Control
|
import com.jme3.scene.control.Control
|
||||||
import com.jme3.input.controls.AnalogListener
|
import com.simsilica.es.EntityComponent
|
||||||
|
import com.simsilica.es.EntityData
|
||||||
|
import com.simsilica.es.EntityId
|
||||||
import enumeratum._
|
import enumeratum._
|
||||||
|
import monix.bio.Task
|
||||||
|
import monix.bio.UIO
|
||||||
|
import monix.execution.Ack
|
||||||
|
import monix.execution.Ack.Continue
|
||||||
|
import monix.execution.Ack.Stop
|
||||||
|
import monix.execution.Cancelable
|
||||||
|
import monix.execution.cancelables.SingleAssignCancelable
|
||||||
|
import monix.reactive.Observable
|
||||||
|
import monix.reactive.OverflowStrategy
|
||||||
|
import monix.reactive.observers.Subscriber
|
||||||
|
import wow.doge.mygame.math.ImVector3f
|
||||||
|
import wow.doge.mygame.state.MyBaseState
|
||||||
|
|
||||||
case class ActionEvent(binding: Action, value: Boolean, tpf: Float)
|
case class ActionEvent(binding: Action, value: Boolean, tpf: Float)
|
||||||
case class EnumActionEvent[T <: EnumEntry](
|
case class EnumActionEvent[T <: EnumEntry](
|
||||||
@ -76,10 +78,12 @@ package object implicits {
|
|||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
implicit class StateManagerExt(private val sm: AppStateManager)
|
implicit class StateManagerExt(private val asm: AppStateManager)
|
||||||
extends AnyVal {
|
extends AnyVal {
|
||||||
def state[S <: AppState]()(implicit c: ClassTag[S]): S =
|
def state[S <: AppState]()(implicit c: ClassTag[S]): S =
|
||||||
sm.getState(c.runtimeClass.asInstanceOf[Class[S]])
|
asm.getState(c.runtimeClass.asInstanceOf[Class[S]])
|
||||||
|
|
||||||
|
// def appStates = asm.getStates()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,6 +121,38 @@ package object implicits {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
implicit class AssetManagerExt(private val am: AssetManager) extends AnyVal {
|
||||||
|
def registerLocator(
|
||||||
|
assetPath: os.RelPath,
|
||||||
|
locator: Class[_ <: AssetLocator]
|
||||||
|
): Unit = {
|
||||||
|
am.registerLocator(assetPath.toString(), locator)
|
||||||
|
}
|
||||||
|
|
||||||
|
def loadModel(assetPath: os.RelPath): Spatial = {
|
||||||
|
am.loadModel(assetPath.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
implicit class BulletAppStateExt(private val bas: BulletAppState)
|
||||||
|
extends AnyVal {
|
||||||
|
def physicsSpace = bas.getPhysicsSpace()
|
||||||
|
def speed = bas.getSpeed()
|
||||||
|
}
|
||||||
|
|
||||||
|
implicit class BetterCharacterControlExt(
|
||||||
|
private val bcc: BetterCharacterControl
|
||||||
|
) {
|
||||||
|
def withJumpForce(force: ImVector3f) = {
|
||||||
|
bcc.setJumpForce(force.mutable)
|
||||||
|
bcc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
implicit class SpatialExt[T <: Spatial](private val spat: T) extends AnyVal {
|
||||||
|
def asRef = Ref[Task].of(spat)
|
||||||
|
}
|
||||||
|
|
||||||
implicit class NodeExt[T <: Node](private val n: T) extends AnyVal {
|
implicit class NodeExt[T <: Node](private val n: T) extends AnyVal {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,6 +175,11 @@ package object implicits {
|
|||||||
def observableChildren =
|
def observableChildren =
|
||||||
Observable.fromIterable(n.getChildren().asScala)
|
Observable.fromIterable(n.getChildren().asScala)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A copy of the list of children of this node as a lazy list
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
def children = LazyList.from(n.getChildren().asScala)
|
def children = LazyList.from(n.getChildren().asScala)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,12 +188,24 @@ package object implicits {
|
|||||||
* @param lst
|
* @param lst
|
||||||
*/
|
*/
|
||||||
def withChildren(lst: Spatial*): Node = {
|
def withChildren(lst: Spatial*): Node = {
|
||||||
for (c <- lst) n.withChild(c)
|
for (c <- lst) n.attachChild(c)
|
||||||
n
|
n
|
||||||
}
|
}
|
||||||
|
|
||||||
def +=(spatial: Spatial) = n.attachChild(spatial)
|
def +=(spatial: Spatial) = n.attachChild(spatial)
|
||||||
|
|
||||||
|
def :+(spatial: Spatial) = {
|
||||||
|
n += spatial
|
||||||
|
n
|
||||||
|
}
|
||||||
|
|
||||||
|
def -=(spatial: Spatial) = n.detachChild(spatial)
|
||||||
|
|
||||||
|
def :-(spatial: Spatial) = {
|
||||||
|
n -= spatial
|
||||||
|
n
|
||||||
|
}
|
||||||
|
|
||||||
def depthFirst(cb: Spatial => Unit) =
|
def depthFirst(cb: Spatial => Unit) =
|
||||||
n.depthFirstTraversal(new SceneGraphVisitor() {
|
n.depthFirstTraversal(new SceneGraphVisitor() {
|
||||||
override def visit(s: Spatial) = cb(s)
|
override def visit(s: Spatial) = cb(s)
|
||||||
@ -333,6 +386,16 @@ package object implicits {
|
|||||||
inputManager
|
inputManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def withEnumMappings[T <: EnumEntry](
|
||||||
|
mappingEnum: Enum[T]
|
||||||
|
)(mappingFn: T => Seq[Trigger]): InputManager = {
|
||||||
|
for (entry <- mappingEnum.values) {
|
||||||
|
val mappings = mappingFn(entry)
|
||||||
|
inputManager.addMapping(entry.entryName, mappings: _*)
|
||||||
|
}
|
||||||
|
inputManager
|
||||||
|
}
|
||||||
|
|
||||||
def observableAction(mappingNames: String*): Observable[ActionEvent] = {
|
def observableAction(mappingNames: String*): Observable[ActionEvent] = {
|
||||||
|
|
||||||
Observable.create(OverflowStrategy.DropOld(10)) { sub =>
|
Observable.create(OverflowStrategy.DropOld(10)) { sub =>
|
||||||
@ -388,12 +451,6 @@ package object implicits {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// def enumObservableAction[T <: enumeratum.EnumEntry](
|
|
||||||
// mappingNames: Enum[T]
|
|
||||||
// ): Observable[ActionEvent] = {
|
|
||||||
// observableAction2(mappingNames).doOnNext()
|
|
||||||
// }
|
|
||||||
|
|
||||||
def analogObservable(mappingNames: String*): Observable[AnalogEvent] = {
|
def analogObservable(mappingNames: String*): Observable[AnalogEvent] = {
|
||||||
|
|
||||||
Observable.create(OverflowStrategy.DropOld(50)) { sub =>
|
Observable.create(OverflowStrategy.DropOld(50)) { sub =>
|
||||||
@ -509,60 +566,60 @@ package object implicits {
|
|||||||
//TODO Create a typeclass for this
|
//TODO Create a typeclass for this
|
||||||
def +=(anyObject: Any) = space.add(anyObject)
|
def +=(anyObject: Any) = space.add(anyObject)
|
||||||
|
|
||||||
|
def :+(anyObject: Any) = {
|
||||||
|
space.add(anyObject)
|
||||||
|
space
|
||||||
|
}
|
||||||
|
def :-(anyObject: Any) = {
|
||||||
|
space.remove(anyObject)
|
||||||
|
space
|
||||||
|
}
|
||||||
|
|
||||||
def +=(spatial: Spatial) = space.addAll(spatial)
|
def +=(spatial: Spatial) = space.addAll(spatial)
|
||||||
|
|
||||||
|
def :+(spatial: Spatial) = {
|
||||||
|
space.addAll(spatial)
|
||||||
|
space
|
||||||
}
|
}
|
||||||
|
|
||||||
implicit class AssetManagerExt(private val am: AssetManager) extends AnyVal {
|
def :-(spatial: Spatial) = {
|
||||||
def registerLocator(
|
space.removeAll(spatial)
|
||||||
assetPath: os.RelPath,
|
space
|
||||||
locator: Class[_ <: AssetLocator]
|
|
||||||
): Unit = {
|
|
||||||
am.registerLocator(assetPath.toString(), locator)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def loadModel(assetPath: os.RelPath): Spatial = {
|
|
||||||
am.loadModel(assetPath.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
implicit class BulletAppStateExt(private val bas: BulletAppState)
|
|
||||||
extends AnyVal {
|
|
||||||
def physicsSpace = bas.getPhysicsSpace()
|
|
||||||
def speed = bas.getSpeed()
|
|
||||||
}
|
|
||||||
|
|
||||||
implicit class BetterCharacterControlExt(
|
|
||||||
private val bcc: BetterCharacterControl
|
|
||||||
) {
|
|
||||||
def withJumpForce(force: ImVector3f) = {
|
|
||||||
bcc.setJumpForce(force.mutable)
|
|
||||||
bcc
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
implicit class Vector3fExt(private val v: Vector3f) extends AnyVal {
|
implicit class Vector3fExt(private val v: Vector3f) extends AnyVal {
|
||||||
//TODO add more operations
|
//TODO add more operations
|
||||||
def +=(that: Vector3f) = v.addLocal(that)
|
def +=(that: Vector3f) = v.addLocal(that)
|
||||||
|
def +=(f: Float) = v.addLocal(f, f, f)
|
||||||
def +=(that: ImVector3f) = v.addLocal(that.x, that.y, that.z)
|
def +=(that: ImVector3f) = v.addLocal(that.x, that.y, that.z)
|
||||||
def +=:(that: ImVector3f) = v += that
|
def +=:(that: ImVector3f) = v += that
|
||||||
def *=(that: Vector3f) = v.multLocal(that)
|
def *=(that: Vector3f) = v.multLocal(that)
|
||||||
|
def *=(that: ImVector3f) = v.multLocal(that.x, that.y, that.z)
|
||||||
|
def *=:(that: ImVector3f) = v *= that
|
||||||
def -=(that: Vector3f) = v.subtractLocal(that)
|
def -=(that: Vector3f) = v.subtractLocal(that)
|
||||||
|
def -=(that: ImVector3f) = v.subtractLocal(that.x, that.y, that.z)
|
||||||
|
def -=:(that: ImVector3f) = v *= that
|
||||||
def /=(that: Vector3f) = v.divideLocal(that)
|
def /=(that: Vector3f) = v.divideLocal(that)
|
||||||
|
def /=(that: ImVector3f) = v.divideLocal(that.mutable)
|
||||||
|
def /=:(that: ImVector3f) = v *= that
|
||||||
def unary_- = v.negateLocal()
|
def unary_- = v.negateLocal()
|
||||||
def immutable = ImVector3f(v.x, v.y, v.z)
|
def immutable = ImVector3f(v.x, v.y, v.z)
|
||||||
}
|
}
|
||||||
|
|
||||||
implicit class ImVector3fExt(private val v: ImVector3f) extends AnyVal {
|
implicit class ImVector3fExt(private val v: ImVector3f) extends AnyVal {
|
||||||
def +(that: ImVector3f) = v.copy(v.x + that.x, v.y + that.y, v.z + that.z)
|
def +(that: ImVector3f) = v.copy(v.x + that.x, v.y + that.y, v.z + that.z)
|
||||||
|
def +(f: Float): ImVector3f = v.copy(v.x + f, v.y + f, v.z + f)
|
||||||
def *(that: ImVector3f) = v.copy(v.x * that.x, v.y * that.y, v.z * that.z)
|
def *(that: ImVector3f) = v.copy(v.x * that.x, v.y * that.y, v.z * that.z)
|
||||||
def *(f: Float): ImVector3f =
|
def *(f: Float): ImVector3f =
|
||||||
v.copy(v.x * f, v.y * f, v.z * f)
|
v.copy(v.x * f, v.y * f, v.z * f)
|
||||||
// v * ImVector3f(f, f, f)
|
// v * ImVector3f(f, f, f)
|
||||||
def -(that: ImVector3f) = v.copy(v.x - that.x, v.y - that.y, v.z - that.z)
|
def -(that: ImVector3f) = v.copy(v.x - that.x, v.y - that.y, v.z - that.z)
|
||||||
|
def -(f: Float): ImVector3f = v.copy(v.x - f, v.y - f, v.z - f)
|
||||||
def /(that: ImVector3f) = v.copy(v.x / that.x, v.y / that.y, v.z / that.z)
|
def /(that: ImVector3f) = v.copy(v.x / that.x, v.y / that.y, v.z / that.z)
|
||||||
|
def /(f: Float): ImVector3f = v.copy(v.x / f, v.y / f, v.z / f)
|
||||||
def unary_- = v.copy(-v.x, -v.y, -v.z)
|
def unary_- = v.copy(-v.x, -v.y, -v.z)
|
||||||
// def unary_-(that: ImVector3f) = this.copy(this.x, this.y, this.z)
|
|
||||||
def mutable = new Vector3f(v.x, v.y, v.z)
|
def mutable = new Vector3f(v.x, v.y, v.z)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -572,18 +629,3 @@ package object implicits {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Observable.create(OverflowStrategy.Unbounded) { sub =>
|
|
||||||
// // val c = SingleAssignCancelable()
|
|
||||||
// val visitor = new SceneGraphVisitor {
|
|
||||||
// override def visit(s: Spatial): Unit = {
|
|
||||||
// sub.onNext(s)
|
|
||||||
// // if (sub.onNext(s) == Ack.Stop)
|
|
||||||
// // c.cancel()
|
|
||||||
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// n.depthFirstTraversal(visitor)
|
|
||||||
// // c := Cancelable(() => ???)
|
|
||||||
// // c
|
|
||||||
// Cancelable.empty
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package wow.doge.mygame.events
|
package wow.doge.mygame.events
|
||||||
|
|
||||||
|
import scala.reflect.ClassTag
|
||||||
|
|
||||||
import akka.actor.typed.ActorRef
|
import akka.actor.typed.ActorRef
|
||||||
import akka.actor.typed.Behavior
|
import akka.actor.typed.Behavior
|
||||||
import akka.actor.typed.scaladsl.Behaviors
|
import akka.actor.typed.scaladsl.Behaviors
|
||||||
import scala.reflect.ClassTag
|
|
||||||
import akka.event.EventStream
|
import akka.event.EventStream
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,35 +1,45 @@
|
|||||||
package wow.doge.mygame.events
|
package wow.doge.mygame.subsystems.events
|
||||||
|
|
||||||
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
import akka.actor.typed.ActorRef
|
import akka.actor.typed.ActorRef
|
||||||
import akka.actor.typed.SpawnProtocol
|
import akka.actor.typed.ActorSystem
|
||||||
import wow.doge.mygame.implicits._
|
|
||||||
import akka.actor.typed.scaladsl.AskPattern._
|
|
||||||
import akka.actor.typed.Props
|
|
||||||
import akka.util.Timeout
|
|
||||||
import akka.actor.typed.Scheduler
|
|
||||||
import akka.actor.typed.LogOptions
|
import akka.actor.typed.LogOptions
|
||||||
import com.typesafe.scalalogging.{Logger => SLLogger}
|
import akka.actor.typed.Props
|
||||||
import wow.doge.mygame.events.EventBus
|
import akka.actor.typed.SpawnProtocol
|
||||||
import akka.actor.typed.scaladsl.Behaviors
|
|
||||||
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
|
||||||
import akka.actor.typed.SupervisorStrategy
|
import akka.actor.typed.SupervisorStrategy
|
||||||
|
import akka.actor.typed.scaladsl.Behaviors
|
||||||
|
import akka.util.Timeout
|
||||||
|
import cats.effect.Resource
|
||||||
|
import com.typesafe.scalalogging.{Logger => SLLogger}
|
||||||
|
import monix.bio.Task
|
||||||
|
import org.slf4j.event.Level
|
||||||
|
import wow.doge.mygame.events.EventBus
|
||||||
|
import wow.doge.mygame.implicits._
|
||||||
|
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
||||||
|
|
||||||
trait EventsModule {
|
class EventsModule2(
|
||||||
def spawnProtocol: ActorRef[SpawnProtocol.Command]
|
spawnProtocol: ActorSystem[SpawnProtocol.Command]
|
||||||
implicit def akkaScheduler: Scheduler
|
) {
|
||||||
implicit def timeout: Timeout
|
implicit lazy val s = spawnProtocol.scheduler
|
||||||
def eventBusLogger = SLLogger[EventBus[_]]
|
|
||||||
|
|
||||||
lazy val tickEventBusTask = createEventBus[Events.Tick]("tickEventBus")
|
implicit lazy val timeout = Timeout(1.second)
|
||||||
|
|
||||||
|
lazy val eventBusLogger = SLLogger[EventBus[_]]
|
||||||
|
|
||||||
lazy val playerMovementEventBusTask =
|
lazy val playerMovementEventBusTask =
|
||||||
createEventBus[PlayerMovementEvent]("movementEventBus")
|
createEventBus[PlayerMovementEvent]("movementEventBus")
|
||||||
|
|
||||||
def createEventBus[T](busName: String) =
|
lazy val playerCameraEventBusTask =
|
||||||
|
createEventBus[PlayerCameraEvent]("playerCameraEventBus", Level.DEBUG)
|
||||||
|
|
||||||
|
def createEventBus[T](busName: String, logLevel: Level = Level.DEBUG) =
|
||||||
spawnProtocol.askL(
|
spawnProtocol.askL(
|
||||||
SpawnProtocol.Spawn[EventBus.Command[T]](
|
SpawnProtocol.Spawn[EventBus.Command[T]](
|
||||||
Behaviors.logMessages(
|
Behaviors.logMessages(
|
||||||
logOptions = LogOptions().withLogger(eventBusLogger.underlying),
|
logOptions = LogOptions()
|
||||||
|
.withLevel(logLevel)
|
||||||
|
.withLogger(eventBusLogger.underlying),
|
||||||
Behaviors
|
Behaviors
|
||||||
.supervise(EventBus[T]())
|
.supervise(EventBus[T]())
|
||||||
.onFailure[Exception](SupervisorStrategy.restart)
|
.onFailure[Exception](SupervisorStrategy.restart)
|
||||||
@ -39,17 +49,17 @@ trait EventsModule {
|
|||||||
_
|
_
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
|
||||||
object EventTypes {
|
|
||||||
type EventBus[T] = ActorRef[EventBus.Command[T]]
|
|
||||||
}
|
|
||||||
|
|
||||||
// val subscribingActor =
|
type EventBuses = (
|
||||||
// spawnProtocol.askT(
|
ActorRef[
|
||||||
// SpawnProtocol.Spawn[Events.PhysicsTick.type](
|
EventBus.Command[EntityMovementEvent.PlayerMovementEvent],
|
||||||
// SubscribingActor(),
|
],
|
||||||
// "subscriber-1",
|
ActorRef[EventBus.Command[PlayerCameraEvent]]
|
||||||
// Props.empty,
|
)
|
||||||
// _
|
|
||||||
// )
|
val resource: Resource[Task, EventBuses] =
|
||||||
// )
|
Resource.liftF(for {
|
||||||
|
playerMovementEventBus <- playerMovementEventBusTask
|
||||||
|
playerCameraEventBus <- playerCameraEventBusTask
|
||||||
|
} yield (playerMovementEventBus, playerCameraEventBus))
|
||||||
|
}
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
package wow.doge.mygame.subsystems.events
|
|
||||||
|
|
||||||
import akka.actor.typed.ActorRef
|
|
||||||
import akka.actor.typed.SpawnProtocol
|
|
||||||
import wow.doge.mygame.implicits._
|
|
||||||
import akka.actor.typed.Props
|
|
||||||
import akka.actor.typed.LogOptions
|
|
||||||
import com.typesafe.scalalogging.{Logger => SLLogger}
|
|
||||||
import wow.doge.mygame.events.EventBus
|
|
||||||
import akka.actor.typed.scaladsl.Behaviors
|
|
||||||
import scala.concurrent.duration._
|
|
||||||
import akka.util.Timeout
|
|
||||||
import akka.actor.typed.SupervisorStrategy
|
|
||||||
import cats.effect.Resource
|
|
||||||
import akka.actor.typed.ActorSystem
|
|
||||||
import monix.bio.Task
|
|
||||||
import org.slf4j.event.Level
|
|
||||||
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
|
||||||
|
|
||||||
class EventsModule2(
|
|
||||||
spawnProtocol: ActorSystem[SpawnProtocol.Command]
|
|
||||||
) {
|
|
||||||
private implicit lazy val s = spawnProtocol.scheduler
|
|
||||||
|
|
||||||
private implicit lazy val timeout = Timeout(1.second)
|
|
||||||
|
|
||||||
private lazy val eventBusLogger = SLLogger[EventBus[_]]
|
|
||||||
|
|
||||||
private lazy val playerMovementEventBusTask =
|
|
||||||
createEventBus[PlayerMovementEvent]("movementEventBus")
|
|
||||||
|
|
||||||
private lazy val playerCameraEventBusTask =
|
|
||||||
createEventBus[PlayerCameraEvent]("playerCameraEventBus", Level.DEBUG)
|
|
||||||
|
|
||||||
def createEventBus[T](busName: String, logLevel: Level = Level.DEBUG) =
|
|
||||||
spawnProtocol.askL(
|
|
||||||
SpawnProtocol.Spawn[EventBus.Command[T]](
|
|
||||||
Behaviors.logMessages(
|
|
||||||
logOptions = LogOptions()
|
|
||||||
.withLevel(logLevel)
|
|
||||||
.withLogger(eventBusLogger.underlying),
|
|
||||||
Behaviors
|
|
||||||
.supervise(EventBus[T]())
|
|
||||||
.onFailure[Exception](SupervisorStrategy.restart)
|
|
||||||
),
|
|
||||||
busName,
|
|
||||||
Props.empty,
|
|
||||||
_
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
type EventBuses = (
|
|
||||||
ActorRef[
|
|
||||||
EventBus.Command[EntityMovementEvent.PlayerMovementEvent],
|
|
||||||
],
|
|
||||||
ActorRef[EventBus.Command[PlayerCameraEvent]]
|
|
||||||
)
|
|
||||||
|
|
||||||
val resource: Resource[Task, EventBuses] =
|
|
||||||
Resource.liftF(for {
|
|
||||||
playerMovementEventBus <- playerMovementEventBusTask
|
|
||||||
playerCameraEventBus <- playerCameraEventBusTask
|
|
||||||
} yield (playerMovementEventBus, playerCameraEventBus))
|
|
||||||
}
|
|
@ -1,5 +1,6 @@
|
|||||||
package wow.doge.mygame.subsystems.moddingsystem
|
package wow.doge.mygame.subsystems.moddingsystem
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
|
import java.nio.file.NoSuchFileException
|
||||||
|
|
||||||
import scala.collection.View
|
import scala.collection.View
|
||||||
import scala.collection.immutable.ArraySeq
|
import scala.collection.immutable.ArraySeq
|
||||||
@ -11,7 +12,9 @@ import io.circe.generic.semiauto._
|
|||||||
import io.circe.parser._
|
import io.circe.parser._
|
||||||
import monix.bio.IO
|
import monix.bio.IO
|
||||||
import monix.bio.UIO
|
import monix.bio.UIO
|
||||||
import java.nio.file.NoSuchFileException
|
import monix.reactive.Consumer
|
||||||
|
import monix.reactive.Observable
|
||||||
|
import wow.doge.mygame.utils.IOUtils
|
||||||
import io.circe.generic.JsonCodec
|
import io.circe.generic.JsonCodec
|
||||||
|
|
||||||
@JsonCodec
|
@JsonCodec
|
||||||
@ -20,6 +23,9 @@ final case class Test1(hello1: String, hello2: String)
|
|||||||
final case class Test2(hello1: String)
|
final case class Test2(hello1: String)
|
||||||
final case class Plugin(name: String, priority: Int)
|
final case class Plugin(name: String, priority: Int)
|
||||||
object Plugin {
|
object Plugin {
|
||||||
|
// @annotation.nowarn(
|
||||||
|
// "msg=Block result was adapted via implicit conversion"
|
||||||
|
// )
|
||||||
implicit val pluginFormat: Decoder[Plugin] = deriveDecoder
|
implicit val pluginFormat: Decoder[Plugin] = deriveDecoder
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,16 +96,29 @@ object ModdingSystem {
|
|||||||
case (p, Right(value)) => Right(p -> value)
|
case (p, Right(value)) => Right(p -> value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def foldMerge(iterable: Iterable[Json]) =
|
||||||
|
iterable.foldLeft(Json.fromString("empty")) {
|
||||||
|
case (json, io.circe.Json.Null) => json //ignore null values
|
||||||
|
case (json, value) => json.deepMerge(value)
|
||||||
|
}
|
||||||
|
|
||||||
def mergePluginData(plugins: View[(Plugin, Json)]) = {
|
def mergePluginData(plugins: View[(Plugin, Json)]) = {
|
||||||
plugins.foldLeft(Json.fromString("empty")) {
|
foldMerge(plugins.map {
|
||||||
case (json, that) =>
|
case (p, json) => json
|
||||||
that match {
|
})
|
||||||
case (p, io.circe.Json.Null) => json //ignore null values
|
|
||||||
case (p, value) => json.deepMerge(value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def mergePluginDataConsumer =
|
||||||
|
Consumer.foldLeft[Json, Json](Json.fromString("empty")) {
|
||||||
|
case (json, io.circe.Json.Null) => json
|
||||||
|
case (json, that) => json.deepMerge(that)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def loadBalancedPluginDataMerger =
|
||||||
|
Consumer
|
||||||
|
.loadBalance(parallelism = 2, mergePluginDataConsumer)
|
||||||
|
.map(foldMerge)
|
||||||
|
|
||||||
// def test =
|
// def test =
|
||||||
// for {
|
// for {
|
||||||
// filePaths <- Task(findPluginFiles(os.pwd))
|
// filePaths <- Task(findPluginFiles(os.pwd))
|
||||||
@ -118,7 +137,16 @@ object ModdingSystem {
|
|||||||
plugins <- IO.fromTryEither(readPluginsList(wd))
|
plugins <- IO.fromTryEither(readPluginsList(wd))
|
||||||
(readFailures, readSuccesses) <- UIO(findAndReadPluginFiles(wd, plugins))
|
(readFailures, readSuccesses) <- UIO(findAndReadPluginFiles(wd, plugins))
|
||||||
(parseFailures, parseSuccesses) <- UIO(parsePluginFiles(readSuccesses))
|
(parseFailures, parseSuccesses) <- UIO(parsePluginFiles(readSuccesses))
|
||||||
res <- UIO(mergePluginData(parseSuccesses))
|
// res <- UIO(mergePluginData(parseSuccesses))
|
||||||
|
res <-
|
||||||
|
IOUtils
|
||||||
|
.toIO(
|
||||||
|
Observable
|
||||||
|
.fromIterable(parseSuccesses)
|
||||||
|
.map { case (p, json) => json }
|
||||||
|
.consumeWith(loadBalancedPluginDataMerger)
|
||||||
|
)
|
||||||
|
.onErrorHandle(e => GenericError)
|
||||||
_ <- UIO {
|
_ <- UIO {
|
||||||
println(s"Read Successes = ${readSuccesses.to(Seq)}")
|
println(s"Read Successes = ${readSuccesses.to(Seq)}")
|
||||||
println(s"Read Failures = ${readFailures.to(Seq)}")
|
println(s"Read Failures = ${readFailures.to(Seq)}")
|
||||||
@ -138,5 +166,4 @@ object ModdingSystem {
|
|||||||
// def test3(wd: os.Path = os.pwd) = {
|
// def test3(wd: os.Path = os.pwd) = {
|
||||||
// (readPluginsList(os.pwd).toValidatedNec)
|
// (readPluginsList(os.pwd).toValidatedNec)
|
||||||
// }
|
// }
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,22 @@
|
|||||||
package wow.doge.mygame.state
|
package wow.doge.mygame.state
|
||||||
|
|
||||||
import akka.actor.typed.scaladsl.Behaviors
|
|
||||||
import ammonite.Main
|
|
||||||
import akka.actor.typed.ActorRef
|
|
||||||
import ammonite.runtime.Storage.Folder
|
|
||||||
import ammonite.main.Defaults
|
|
||||||
import akka.actor.typed.Behavior
|
|
||||||
import akka.actor.typed.scaladsl.ActorContext
|
|
||||||
import ammonite.util.Res.Success
|
|
||||||
import javax.script.ScriptEngine
|
import javax.script.ScriptEngine
|
||||||
import javax.script.ScriptEngineManager
|
import javax.script.ScriptEngineManager
|
||||||
import groovy.util.GroovyScriptEngine
|
|
||||||
import cats.implicits._
|
import akka.actor.typed.ActorRef
|
||||||
|
import akka.actor.typed.Behavior
|
||||||
import akka.actor.typed.LogOptions
|
import akka.actor.typed.LogOptions
|
||||||
import org.slf4j.event.Level
|
import akka.actor.typed.scaladsl.ActorContext
|
||||||
import com.typesafe.scalalogging.Logger
|
import akka.actor.typed.scaladsl.Behaviors
|
||||||
|
import ammonite.Main
|
||||||
|
import ammonite.main.Defaults
|
||||||
|
import ammonite.runtime.Storage.Folder
|
||||||
|
import ammonite.util.Res.Success
|
||||||
|
import cats.implicits._
|
||||||
import com.softwaremill.tagging._
|
import com.softwaremill.tagging._
|
||||||
|
import com.typesafe.scalalogging.Logger
|
||||||
|
import groovy.util.GroovyScriptEngine
|
||||||
|
import org.slf4j.event.Level
|
||||||
|
|
||||||
object ScriptActor {
|
object ScriptActor {
|
||||||
trait Kotlin
|
trait Kotlin
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
package wow.doge.mygame.scriptsystem
|
package wow.doge.mygame.scriptsystem
|
||||||
|
|
||||||
|
import scala.util.Failure
|
||||||
|
import scala.util.Success
|
||||||
|
|
||||||
|
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 akka.actor.typed.scaladsl.Behaviors
|
||||||
import akka.actor.typed.scaladsl.PoolRouter
|
import akka.actor.typed.scaladsl.PoolRouter
|
||||||
import akka.actor.typed.scaladsl.Routers
|
import akka.actor.typed.scaladsl.Routers
|
||||||
import wow.doge.mygame.state.ScriptActor
|
|
||||||
import akka.actor.typed.ActorRef
|
|
||||||
import akka.actor.typed.scaladsl.ActorContext
|
|
||||||
import akka.actor.typed.Behavior
|
|
||||||
import akka.util.Timeout
|
import akka.util.Timeout
|
||||||
import scala.util.Success
|
|
||||||
import scala.util.Failure
|
|
||||||
import akka.actor.typed.SupervisorStrategy
|
|
||||||
import akka.actor.typed.LogOptions
|
|
||||||
import org.slf4j.event.Level
|
|
||||||
import com.typesafe.scalalogging.Logger
|
import com.typesafe.scalalogging.Logger
|
||||||
|
import org.slf4j.event.Level
|
||||||
|
import wow.doge.mygame.state.ScriptActor
|
||||||
|
|
||||||
object ScriptCachingActor {
|
object ScriptCachingActor {
|
||||||
|
|
||||||
|
@ -1,23 +1,65 @@
|
|||||||
package wow.doge.mygame.subsystems.scriptsystem
|
package wow.doge.mygame.subsystems.scriptsystem
|
||||||
|
|
||||||
import wow.doge.mygame.utils.AkkaUtils
|
|
||||||
import cats.effect.Resource
|
|
||||||
import wow.doge.mygame.scriptsystem.ScriptCachingActor
|
|
||||||
import akka.actor.typed.ActorRef
|
import akka.actor.typed.ActorRef
|
||||||
|
import akka.actor.typed.Scheduler
|
||||||
import akka.actor.typed.SpawnProtocol
|
import akka.actor.typed.SpawnProtocol
|
||||||
import akka.util.Timeout
|
import akka.util.Timeout
|
||||||
import akka.actor.typed.Scheduler
|
import cats.effect.Resource
|
||||||
|
import wow.doge.mygame.scriptsystem.ScriptCachingActor
|
||||||
|
import wow.doge.mygame.utils.AkkaUtils
|
||||||
|
import monix.bio.Task
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scripts can either be searched and compiled at startup (Eager mode)
|
||||||
|
* or compiled on demand (Lazy mode)
|
||||||
|
*/
|
||||||
|
sealed trait ScriptInitMode
|
||||||
|
object ScriptInitMode {
|
||||||
|
case object Eager extends ScriptInitMode
|
||||||
|
case object Lazy extends ScriptInitMode
|
||||||
|
}
|
||||||
class ScriptSystemResource(
|
class ScriptSystemResource(
|
||||||
path: os.Path,
|
path: os.Path,
|
||||||
spawnProtocol: ActorRef[SpawnProtocol.Command]
|
spawnProtocol: ActorRef[SpawnProtocol.Command],
|
||||||
|
mode: ScriptInitMode = ScriptInitMode.Lazy
|
||||||
)(implicit timeout: Timeout, scheduler: Scheduler) {
|
)(implicit timeout: Timeout, scheduler: Scheduler) {
|
||||||
def make =
|
val make = {
|
||||||
Resource.liftF(
|
// throw new Exception("boom")
|
||||||
AkkaUtils.spawnActorL(
|
findScriptFiles(os.pwd / "assets" / "scripts")
|
||||||
|
|
||||||
|
lazy val scriptCacheActor = AkkaUtils.spawnActorL(
|
||||||
spawnProtocol,
|
spawnProtocol,
|
||||||
"scriptCachingActor",
|
"scriptCachingActor",
|
||||||
ScriptCachingActor()
|
ScriptCachingActor()
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
Resource.liftF(scriptCacheActor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val init = for {
|
||||||
|
scriptFiles <- Task(findScriptFiles(os.pwd / "assets" / "scripts"))
|
||||||
|
scriptCacheActor <- AkkaUtils.spawnActorL(
|
||||||
|
spawnProtocol,
|
||||||
|
"scriptCachingActor",
|
||||||
|
ScriptCachingActor()
|
||||||
|
)
|
||||||
|
} yield (scriptCacheActor)
|
||||||
|
|
||||||
|
def findScriptFiles(wd: os.Path) =
|
||||||
|
os.walk
|
||||||
|
.stream(wd)
|
||||||
|
.filter(p =>
|
||||||
|
os.isFile(p) &&
|
||||||
|
(p.ext == "sc" || (p.baseName + "." + p.ext)
|
||||||
|
.contains(".main.kts") || p.ext == "groovy")
|
||||||
|
)
|
||||||
|
.toList
|
||||||
|
|
||||||
|
// def findExternalScriptFiles =
|
||||||
|
// findScriptFiles(os.pwd / "assets" / "scripts")
|
||||||
|
// def findInternalScriptFiles =
|
||||||
|
// findScriptFiles((os.resource / "assets" / "scripts"))
|
||||||
|
|
||||||
|
// def finalInternalScriptFiles =
|
||||||
|
}
|
||||||
|
// pwd / 'src / 'main / 'resources / 'assets / 'scripts
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package wow.doge.mygame.utils
|
package wow.doge.mygame.utils
|
||||||
|
|
||||||
import akka.actor.typed.Props
|
|
||||||
import akka.util.Timeout
|
|
||||||
import akka.actor.typed.Scheduler
|
|
||||||
import akka.actor.typed.ActorRef
|
import akka.actor.typed.ActorRef
|
||||||
import akka.actor.typed.SpawnProtocol
|
|
||||||
import akka.actor.typed.Behavior
|
import akka.actor.typed.Behavior
|
||||||
|
import akka.actor.typed.Props
|
||||||
|
import akka.actor.typed.Scheduler
|
||||||
|
import akka.actor.typed.SpawnProtocol
|
||||||
|
import akka.util.Timeout
|
||||||
import wow.doge.mygame.implicits._
|
import wow.doge.mygame.implicits._
|
||||||
|
|
||||||
object AkkaUtils {
|
object AkkaUtils {
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package wow.doge.mygame.utils
|
package wow.doge.mygame.utils
|
||||||
|
|
||||||
import java.io.PrintStream
|
|
||||||
import java.io.OutputStream
|
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import scalafx.scene.control.TextArea
|
import java.io.OutputStream
|
||||||
|
import java.io.PrintStream
|
||||||
|
|
||||||
import cats.effect.Resource
|
import cats.effect.Resource
|
||||||
import monix.bio.Task
|
import monix.bio.Task
|
||||||
|
import scalafx.scene.control.TextArea
|
||||||
|
|
||||||
trait JFXConsoleStreamable[T] {
|
trait JFXConsoleStreamable[T] {
|
||||||
def println(inst: T, text: String): Unit
|
def println(inst: T, text: String): Unit
|
||||||
|
Loading…
Reference in New Issue
Block a user