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-effect" % "2.1.4",
|
||||
"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-generic" % "0.13.0",
|
||||
"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",
|
||||
"com.typesafe.scala-logging" %% "scala-logging" % "3.9.2",
|
||||
"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
|
||||
|
||||
@ -104,12 +106,20 @@ lazy val root = (project in file(".")).settings(
|
||||
"UTF-8",
|
||||
"-deprecation",
|
||||
"-feature",
|
||||
"-language:existentials",
|
||||
"-language:experimental.macros",
|
||||
"-language:higherKinds",
|
||||
"-language:implicitConversions",
|
||||
"-unchecked",
|
||||
"-Xlint",
|
||||
"-Ywarn-numeric-widen",
|
||||
"-Ymacro-annotations",
|
||||
"-Xlint:byname-implicit",
|
||||
// "-Xlint:byname-implicit",
|
||||
// "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.
|
||||
),
|
||||
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
|
||||
// documentation at http://www.scala-sbt.org/documentation.html
|
||||
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
|
||||
|
||||
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.
|
||||
|
@ -1,13 +1,12 @@
|
||||
package com.jme3
|
||||
|
||||
|
||||
/**
|
||||
* Created by Brandon Barker on 6/21/17.
|
||||
*/
|
||||
package object syntax {
|
||||
|
||||
@specialized def discard[A](evaluateForSideEffectOnly: A): Unit = {
|
||||
val _: A = evaluateForSideEffectOnly
|
||||
val _ = evaluateForSideEffectOnly
|
||||
() //Return unit to prevent warning due to discarding value
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,22 @@
|
||||
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.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.slf4j.OdinLoggerBinder
|
||||
import io.odin.syntax._
|
||||
|
||||
//effect type should be specified inbefore
|
||||
//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
|
||||
|
||||
import cats.effect.Resource
|
||||
import io.odin.syntax._
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import _root_.monix.bio.Task
|
||||
import akka.util.Timeout
|
||||
import cats.effect.ExitCode
|
||||
import cats.implicits._
|
||||
import com.softwaremill.macwire._
|
||||
import scala.concurrent.duration._
|
||||
import monix.bio.BIOApp
|
||||
import monix.bio.UIO
|
||||
import io.odin._
|
||||
import wow.doge.mygame.game.GameAppResource
|
||||
import io.odin.json.Formatter
|
||||
import wow.doge.mygame.game.GameSystemsInitializer
|
||||
import wow.doge.mygame.subsystems.events.EventsModule2
|
||||
import wow.doge.mygame.implicits._
|
||||
import com.jme3.bullet.BulletAppState
|
||||
import akka.util.Timeout
|
||||
import io.odin.syntax._
|
||||
import wow.doge.mygame.game.GameAppResource
|
||||
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 {
|
||||
import java.util.logging.{Logger => JLogger, Level}
|
||||
JLogger.getLogger("").setLevel(Level.SEVERE)
|
||||
@ -41,19 +38,36 @@ object Main extends BIOApp with MainModule {
|
||||
// akkaScheduler = actorSystemResource2.scheduler
|
||||
// consoleTextArea <- Resource.liftF(Task(new TextArea()))
|
||||
// consoleStream <- wireWith(JFXConsoleStream.textAreaStream _)
|
||||
(gameApp, gameAppFib) <- {
|
||||
(gameApp) <- {
|
||||
// new BulletAppState()
|
||||
// bas.setThreadingType(Thr)
|
||||
// gameAppResource(new StatsAppState())
|
||||
wire[GameAppResource].get
|
||||
wire[GameAppResource].get2
|
||||
}
|
||||
app = gameApp
|
||||
inputManager = gameApp.inputManager
|
||||
assetManager = gameApp.assetManager
|
||||
bulletAppState = new BulletAppState()
|
||||
(playerMovementEventBus, playerCameraEventBus) <- new EventsModule2(
|
||||
actorSystem
|
||||
).resource
|
||||
_ <- Resource.liftF(
|
||||
new MainApp(logger, gameApp, actorSystem, jmeScheduler)(
|
||||
timeout,
|
||||
actorSystem.scheduler
|
||||
).gameInit
|
||||
)
|
||||
// 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
|
||||
// b2 = playerCameraEventBus
|
||||
|
||||
@ -67,62 +81,15 @@ object Main extends BIOApp with MainModule {
|
||||
// )
|
||||
// }
|
||||
|
||||
// _ <- Resource.liftF(IO(JMERunner.runner = gameApp))
|
||||
// _ <- Resource.liftF(IO {
|
||||
// new ActorSystemModule {}
|
||||
// })
|
||||
// actorSystem <- wireWith(actorSystemResource _)
|
||||
// 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))
|
||||
|
||||
// rootActor <- rootActorResource(logger, gameApp, schedulers, as2)
|
||||
// _ <- 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)
|
||||
} yield ()
|
||||
|
||||
// def createPlayerController(
|
||||
// playerMovementEventBus: ActorRef[
|
||||
@ -145,7 +112,7 @@ object Main extends BIOApp with MainModule {
|
||||
// )
|
||||
// )(())
|
||||
appResource
|
||||
.use(_.join)
|
||||
.use(_ => Task.unit)
|
||||
.onErrorHandle(_.printStackTrace())
|
||||
.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
|
||||
import akka.actor.typed.scaladsl.Behaviors
|
||||
import wow.doge.mygame.game.GameApp
|
||||
import akka.actor.typed.Behavior
|
||||
import wow.doge.mygame.game.GameAppActor
|
||||
import cats.effect.Resource
|
||||
import akka.actor.typed.ActorSystem
|
||||
import monix.bio.Task
|
||||
import wow.doge.mygame.game.GameModule
|
||||
import io.odin._
|
||||
import io.odin.syntax._
|
||||
import wow.doge.mygame.executors.ExecutorsModule
|
||||
import akka.actor.typed.scaladsl.ActorContext
|
||||
import wow.doge.mygame.executors.Schedulers
|
||||
import com.softwaremill.macwire._
|
||||
import akka.actor.typed.SpawnProtocol
|
||||
import akka.actor.typed.Scheduler
|
||||
import wow.doge.mygame.utils.AkkaUtils
|
||||
import scala.concurrent.duration._
|
||||
import akka.actor.typed.ActorRef
|
||||
import wow.doge.mygame.implicits._
|
||||
import cats.effect.Resource
|
||||
import io.odin.Logger
|
||||
import monix.bio.Task
|
||||
import wow.doge.mygame.executors.ExecutorsModule
|
||||
import wow.doge.mygame.game.GameModule
|
||||
|
||||
trait MainModule extends GameModule with ExecutorsModule {
|
||||
def actorSystemResource(
|
||||
logger: Logger[Task],
|
||||
app: GameApp,
|
||||
schedulers: Schedulers
|
||||
): Resource[Task, ActorSystem[RootActor.Command]] =
|
||||
Resource.make(logger.info("Creating Actor System") >> Task {
|
||||
ActorSystem(
|
||||
wire[RootActor.Props].create(RootActor.State.empty),
|
||||
name = "GameActorSystem"
|
||||
)
|
||||
})(sys =>
|
||||
logger.info("Shutting down actor system") >> Task(
|
||||
sys.terminate()
|
||||
)
|
||||
)
|
||||
|
||||
def actorSystemResource2(
|
||||
logger: Logger[Task]
|
||||
@ -43,93 +15,11 @@ trait MainModule extends GameModule with ExecutorsModule {
|
||||
Resource.make(logger.info("Creating Actor System") >> Task {
|
||||
ActorSystem(
|
||||
SpawnProtocol(),
|
||||
name = "GameActorSystem2"
|
||||
name = "GameActorSystem"
|
||||
)
|
||||
})(sys =>
|
||||
logger.info("Shutting down actor system") >> Task(
|
||||
sys.terminate()
|
||||
)
|
||||
)
|
||||
|
||||
def rootActorResource(
|
||||
loggerL: Logger[Task],
|
||||
app: GameApp,
|
||||
schedulers: Schedulers,
|
||||
spawnProtocol: ActorSystem[SpawnProtocol.Command]
|
||||
): Resource[Task, ActorRef[RootActor.Command]] =
|
||||
Resource.make(
|
||||
loggerL.info("Creating Root Actor") >>
|
||||
AkkaUtils.spawnActorL(
|
||||
behavior = RootActor(app, schedulers, logger = loggerL),
|
||||
actorName = "RootActor",
|
||||
spawnProtocol = spawnProtocol
|
||||
)(1.seconds, spawnProtocol.scheduler)
|
||||
)(actor =>
|
||||
loggerL.info("Shutting down root actor") >> (actor !! RootActor.Stop)
|
||||
)
|
||||
}
|
||||
|
||||
object RootActor {
|
||||
sealed trait Command
|
||||
final case class Start(akkaScheduler: Scheduler) extends Command
|
||||
final case object Stop extends Command
|
||||
|
||||
final case class Props(
|
||||
app: GameApp,
|
||||
schedulers: Schedulers,
|
||||
logger: Logger[Task]
|
||||
) {
|
||||
def create(state: State): Behavior[Command] =
|
||||
Behaviors.setup { ctx =>
|
||||
ctx.log.info("Hello from root actor")
|
||||
wire[RootActor].receive(State.empty)
|
||||
}
|
||||
}
|
||||
|
||||
final case class State(initialized: Boolean = false)
|
||||
object State {
|
||||
val empty = State()
|
||||
}
|
||||
def apply(
|
||||
app: GameApp,
|
||||
schedulers: Schedulers,
|
||||
state: State = State.empty,
|
||||
logger: Logger[Task]
|
||||
): Behavior[Command] =
|
||||
Behaviors.setup { ctx =>
|
||||
ctx.log.info("Hello from root actor")
|
||||
wire[RootActor].receive(state)
|
||||
}
|
||||
}
|
||||
|
||||
class RootActor(
|
||||
ctx: ActorContext[RootActor.Command],
|
||||
app: GameApp,
|
||||
schedulers: Schedulers,
|
||||
logger: Logger[Task]
|
||||
) {
|
||||
import RootActor._
|
||||
def receive(state: State): Behavior[Command] =
|
||||
Behaviors.receiveMessage(msg =>
|
||||
msg match {
|
||||
case Start(akkaScheduler) =>
|
||||
if (!state.initialized) {
|
||||
ctx.log.info("Starting GameAppActor")
|
||||
val spawnProtocol = ctx.spawn(SpawnProtocol(), "spawnProtocol")
|
||||
val _ = ctx.spawn(
|
||||
wire[GameAppActor.Props].create,
|
||||
"gameAppActor"
|
||||
// DispatcherSelector.fromConfig("jme-dispatcher")
|
||||
)
|
||||
receive(state.copy(initialized = true))
|
||||
} else {
|
||||
ctx.log.warn("Already Initialized")
|
||||
Behaviors.same
|
||||
}
|
||||
case Stop =>
|
||||
ctx.log.info("Stopping")
|
||||
Behaviors.stopped
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package wow.doge.mygame.executors
|
||||
|
||||
import monix.bio.Task
|
||||
import cats.effect.Resource
|
||||
import monix.bio.Task
|
||||
import monix.execution.Scheduler
|
||||
|
||||
trait ExecutorsModule {
|
||||
|
@ -1,23 +1,21 @@
|
||||
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.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 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 monix.execution.Scheduler
|
||||
import scala.concurrent.ExecutionContext
|
||||
import java.util.concurrent.Executor
|
||||
|
||||
// First we wrap invokeLater/runLater as an ExecutorService
|
||||
trait GUIExecutorService extends AbstractExecutorService {
|
||||
|
@ -1,8 +1,8 @@
|
||||
package wow.doge.mygame.executors
|
||||
|
||||
import com.typesafe.scalalogging.Logger
|
||||
import monix.execution.Scheduler
|
||||
import monix.execution.UncaughtExceptionReporter
|
||||
import com.typesafe.scalalogging.Logger
|
||||
|
||||
final case class Schedulers(
|
||||
blockingIO: Scheduler = Scheduler
|
||||
|
@ -1,18 +1,18 @@
|
||||
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 monix.execution.{CancelablePromise => Promise}
|
||||
import monix.execution.CancelableFuture
|
||||
import monix.bio.Task
|
||||
import monix.execution.CancelableFuture
|
||||
import monix.execution.Scheduler
|
||||
import wow.doge.mygame.executors.GUIExecutorService
|
||||
import monix.reactive.subjects.ConcurrentSubject
|
||||
import monix.execution.atomic.Atomic
|
||||
import monix.execution.{CancelablePromise => Promise}
|
||||
import monix.reactive.MulticastStrategy
|
||||
import monix.reactive.Observable
|
||||
import monix.execution.atomic.Atomic
|
||||
import scala.collection.immutable.Queue
|
||||
import monix.reactive.subjects.ConcurrentSubject
|
||||
import wow.doge.mygame.executors.GUIExecutorService
|
||||
import wow.doge.mygame.executors.Schedulers
|
||||
|
||||
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
|
||||
|
||||
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.Scheduler
|
||||
import akka.actor.typed.SpawnProtocol
|
||||
import akka.actor.typed.scaladsl.Behaviors
|
||||
import io.odin.Logger
|
||||
import monix.bio.Task
|
||||
import akka.actor.typed.Scheduler
|
||||
import scala.util.Failure
|
||||
import scala.util.Success
|
||||
import com.jme3.app.StatsAppState
|
||||
import wow.doge.mygame.events.Events
|
||||
import wow.doge.mygame.executors.Schedulers
|
||||
|
||||
object GameAppActor {
|
||||
import Methods._
|
||||
|
||||
sealed trait Command
|
||||
case object ApplicationStarted extends Command
|
||||
@ -39,22 +27,6 @@ object GameAppActor {
|
||||
Behaviors.setup[Command] { ctx =>
|
||||
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 =>
|
||||
msg match {
|
||||
case Stop =>
|
||||
|
@ -1,28 +1,28 @@
|
||||
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.SpawnProtocol
|
||||
import wow.doge.mygame.game.subsystems.input.GameInputHandler
|
||||
import monix.bio.IO
|
||||
import monix.bio.Fiber
|
||||
import monix.execution.Scheduler
|
||||
import cats.effect.Resource
|
||||
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.game.subsystems.input.GameInputHandler
|
||||
class GameAppResource(
|
||||
logger: Logger[Task],
|
||||
jmeScheduler: Scheduler,
|
||||
schedulers: Schedulers
|
||||
) {
|
||||
def get: Resource[Task, (GameApp, Fiber[Throwable, Unit])] =
|
||||
def get: Resource[Task, (GameApp2, Fiber[Throwable, Unit])] =
|
||||
Resource.make(
|
||||
for {
|
||||
_ <- logger.info("Creating game app")
|
||||
app <- Task(new GameApp(schedulers, new StatsAppState()))
|
||||
_ <- Task {
|
||||
app2 <- Task {
|
||||
val settings = new AppSettings(true)
|
||||
settings.setVSync(true)
|
||||
settings.setUseInput(true)
|
||||
@ -30,11 +30,31 @@ class GameAppResource(
|
||||
// settings.setFrameRate(250)
|
||||
app.setSettings(settings)
|
||||
// JMERunner.runner = app
|
||||
app
|
||||
// app
|
||||
new GameApp2(app)
|
||||
}
|
||||
fib <- Task(app.start()).executeOn(jmeScheduler).start
|
||||
} yield (app -> fib)
|
||||
fib <- app2.start.executeOn(jmeScheduler).start
|
||||
} yield (app2 -> fib)
|
||||
)(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 {
|
||||
|
@ -3,30 +3,34 @@ package wow.doge.mygame.game
|
||||
import scala.concurrent.duration._
|
||||
|
||||
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 monix.reactive.Consumer
|
||||
import wow.doge.mygame.events.EventBus
|
||||
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.game.subsystems.level.DefaultGameLevel
|
||||
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.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(
|
||||
spawnProtocol: ActorSystem[SpawnProtocol.Command],
|
||||
@ -35,15 +39,22 @@ class GameSystemsInitializer(
|
||||
playerMovementEventBus: ActorRef[
|
||||
EventBus.Command[EntityMovementEvent.PlayerMovementEvent]
|
||||
],
|
||||
playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]]
|
||||
)(app: GameApp) {
|
||||
playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]],
|
||||
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)
|
||||
|
||||
import GameSystemsInitializer._
|
||||
|
||||
implicit val akkaScheduler: Scheduler = spawnProtocol.scheduler
|
||||
lazy val inputManager = app.inputManager
|
||||
lazy val assetManager = app.assetManager
|
||||
// lazy val inputManager = app.inputManager
|
||||
// lazy val assetManager = app.assetManager
|
||||
lazy val bulletAppState = new BulletAppState()
|
||||
// lazy val playerMovementEventBus = eventBuses.playerMovementEventBusTask
|
||||
|
||||
@ -51,15 +62,16 @@ class GameSystemsInitializer(
|
||||
for {
|
||||
_ <- loggerL.info("Initializing Systems")
|
||||
// playerMovementEventBus <- playerMovementEventBusTask
|
||||
_ <- Task(app.stateManager.attach(bulletAppState))
|
||||
_ <- Task(stateManager.attach(bulletAppState))
|
||||
_ <- Task(
|
||||
app.assetManager.registerLocator(
|
||||
assetManager.registerLocator(
|
||||
// "src/main/resources/assets/town.zip",
|
||||
(os.rel / "src" / "main" / "resources" / "assets" / "town.zip"),
|
||||
(os.rel / "assets" / "town.zip"),
|
||||
classOf[ZipLocator]
|
||||
)
|
||||
)
|
||||
_ <- app.enqueueL(() => DefaultGameLevel(app, bulletAppState))
|
||||
|
||||
// _ <- app.enqueueL(() => DefaultGameLevel(app, bulletAppState))
|
||||
_ <- wireWith(createPlayerController _).startAndForget
|
||||
_ <- wire[GameInputHandler.Props].begin
|
||||
|
||||
@ -71,8 +83,11 @@ class GameSystemsInitializer(
|
||||
// ],
|
||||
// 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
|
||||
}
|
||||
|
@ -3,11 +3,11 @@ package wow.doge.mygame.state
|
||||
import com.jme3.app.Application
|
||||
import com.jme3.app.SimpleApplication
|
||||
import com.jme3.app.state.AppState
|
||||
import com.jme3.scene.Node
|
||||
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.base.DefaultEntityData
|
||||
import com.jme3.scene.Spatial
|
||||
|
||||
trait MyBaseState extends BaseAppState {
|
||||
|
||||
|
@ -2,18 +2,16 @@ package wow.doge.mygame.state
|
||||
|
||||
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.KeyInput
|
||||
import com.jme3.input.controls.KeyTrigger
|
||||
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 akka.actor.typed.scaladsl.TimerScheduler
|
||||
|
||||
import wow.doge.mygame.implicits._
|
||||
import wow.doge.mygame.subsystems.movement.ImMovementActor
|
||||
|
||||
|
@ -1,17 +1,18 @@
|
||||
package wow.doge.mygame.state
|
||||
|
||||
import ammonite.runtime.Storage.Folder
|
||||
import ammonite.main.Defaults
|
||||
import ammonite.Main
|
||||
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.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.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(
|
||||
sse: ScalaScriptingEngine,
|
||||
|
@ -1,13 +1,13 @@
|
||||
package wow.doge.mygame.state
|
||||
|
||||
import wow.doge.mygame.implicits._
|
||||
import wow.doge.mygame.components.TestComponent
|
||||
import com.jme3.scene.shape.Box
|
||||
import com.jme3.scene.Geometry
|
||||
import com.jme3.asset.AssetManager
|
||||
import com.jme3.material.Material
|
||||
import com.jme3.math.ColorRGBA
|
||||
import com.jme3.asset.AssetManager
|
||||
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(
|
||||
// private var _entity: Option[EntityData] = Some(new DefaultEntityData())
|
||||
) extends MyBaseState {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package wow.doge.mygame.components
|
||||
|
||||
import com.simsilica.es.EntityComponent;
|
||||
import com.simsilica.es.EntityComponent
|
||||
import wow.doge.mygame.math.ImVector3f
|
||||
|
||||
final case class Position(location: ImVector3f) extends EntityComponent
|
||||
|
@ -1,30 +1,29 @@
|
||||
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 akka.actor.typed.ActorRef
|
||||
import akka.actor.typed.Behavior
|
||||
import akka.actor.typed.LogOptions
|
||||
import org.slf4j.event.Level
|
||||
import com.typesafe.scalalogging.Logger
|
||||
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 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.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 {
|
||||
sealed trait Command
|
||||
|
||||
final case class Props(
|
||||
app: GameApp,
|
||||
enqueueR: Function1[() => Unit, Unit],
|
||||
camNode: CameraNode,
|
||||
playerMovementEventBus: ActorRef[
|
||||
EventBus.Command[PlayerMovementEvent]
|
||||
@ -47,7 +46,7 @@ object PlayerActorSupervisor {
|
||||
Behaviors
|
||||
.supervise(
|
||||
ImMovementActor
|
||||
.Props(app, movable, playerMovementEventBus)
|
||||
.Props(enqueueR, movable, playerMovementEventBus)
|
||||
.create
|
||||
)
|
||||
.onFailure[Exception](SupervisorStrategy.restart),
|
||||
@ -70,7 +69,7 @@ object PlayerActorSupervisor {
|
||||
ctx.spawn(
|
||||
Behaviors
|
||||
.supervise(
|
||||
PlayerCameraEventListener(camNode, app.enqueueR)
|
||||
PlayerCameraEventListener(camNode, enqueueR)
|
||||
)
|
||||
.onFailure[Exception](SupervisorStrategy.restart),
|
||||
"playerCameraHandler"
|
||||
|
@ -1,7 +1,7 @@
|
||||
package wow.doge.mygame.game.nodes
|
||||
|
||||
import akka.actor.typed.scaladsl.Behaviors
|
||||
import akka.actor.typed.scaladsl.ActorContext
|
||||
import akka.actor.typed.scaladsl.Behaviors
|
||||
|
||||
object PlayerCameraActor {
|
||||
sealed trait Command
|
||||
|
@ -1,33 +1,34 @@
|
||||
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.Geometry
|
||||
import com.jme3.renderer.Camera
|
||||
import com.jme3.asset.AssetManager
|
||||
import wow.doge.mygame.state.MyMaterial
|
||||
import com.jme3.scene.Node
|
||||
import com.jme3.scene.control.CameraControl.ControlDirection
|
||||
import com.jme3.scene.shape.Box
|
||||
import com.jme3.bullet.control.BetterCharacterControl
|
||||
import com.jme3.bullet.BulletAppState
|
||||
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.GameApp
|
||||
import wow.doge.mygame.implicits._
|
||||
import wow.doge.mygame.math.ImVector3f
|
||||
import com.jme3.math.FastMath
|
||||
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.state.MyMaterial
|
||||
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.movement.ImMovementActor
|
||||
import wow.doge.mygame.utils.AkkaUtils
|
||||
|
||||
// class PlayerNode(val name: String) extends Node(name) {}
|
||||
@ -39,7 +40,9 @@ object PlayerController {
|
||||
case class GenericError(reason: String) extends Error
|
||||
|
||||
class Props(
|
||||
app: GameApp,
|
||||
enqueueR: Function1[() => Unit, Unit],
|
||||
rootNode: Ref[Task, Node],
|
||||
camera: Camera,
|
||||
loggerL: Logger[Task],
|
||||
assetManager: AssetManager,
|
||||
bulletAppState: BulletAppState,
|
||||
@ -52,15 +55,15 @@ object PlayerController {
|
||||
playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]],
|
||||
_playerPhysicsControl: Option[BetterCharacterControl],
|
||||
_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) {
|
||||
import Defaults._
|
||||
import Methods._
|
||||
val create: IO[Error, Unit] =
|
||||
// IO.raiseError(GenericError("not implemented yet"))
|
||||
(for {
|
||||
camNode <- IO(
|
||||
_cameraNode.getOrElse(defaultCamerNode(app.camera, initialPlayerPos))
|
||||
_cameraNode.getOrElse(defaultCamerNode(camera, initialPlayerPos))
|
||||
)
|
||||
playerPhysicsControl <- IO(
|
||||
_playerPhysicsControl
|
||||
@ -82,7 +85,7 @@ object PlayerController {
|
||||
spawnProtocol,
|
||||
"playerActorSupervisor",
|
||||
new PlayerActorSupervisor.Props(
|
||||
app,
|
||||
enqueueR,
|
||||
camNode,
|
||||
playerMovementEventBus,
|
||||
playerCameraEventBus
|
||||
@ -92,11 +95,10 @@ object PlayerController {
|
||||
bulletAppState.physicsSpace += playerNode
|
||||
bulletAppState.physicsSpace += playerPhysicsControl
|
||||
}
|
||||
_ <- IO(app.rootNode += playerNode)
|
||||
_ <- rootNode.update(_ :+ playerNode)
|
||||
} yield ())
|
||||
.onErrorHandleWith(e => IO.raiseError(GenericError(e.getMessage())))
|
||||
.executeOn(app.scheduler)
|
||||
|
||||
.executeOn(appScheduler)
|
||||
}
|
||||
|
||||
def apply(
|
||||
@ -175,7 +177,7 @@ object Defaults {
|
||||
|
||||
object Methods {
|
||||
def spawnMovementActor(
|
||||
app: GameApp,
|
||||
enqueueR: Function1[() => Unit, Unit],
|
||||
spawnProtocol: ActorRef[SpawnProtocol.Command],
|
||||
movable: BetterCharacterControl @@ Player,
|
||||
playerMovementEventBus: ActorRef[
|
||||
@ -185,7 +187,7 @@ object Methods {
|
||||
)(implicit timeout: Timeout, scheduler: Scheduler) =
|
||||
spawnProtocol.askL[ActorRef[ImMovementActor.Command]](
|
||||
SpawnProtocol.Spawn(
|
||||
ImMovementActor.Props(app, movable, playerMovementEventBus).create,
|
||||
ImMovementActor.Props(enqueueR, movable, playerMovementEventBus).create,
|
||||
"imMovementActor",
|
||||
Props.empty,
|
||||
_
|
||||
|
@ -1,18 +1,16 @@
|
||||
package wow.doge.mygame.game.nodes
|
||||
|
||||
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 wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
||||
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 akka.actor.typed.scaladsl.Behaviors
|
||||
import com.jme3.scene.CameraNode
|
||||
import wow.doge.mygame.game.GameApp
|
||||
import wow.doge.mygame.implicits._
|
||||
import com.typesafe.scalalogging.Logger
|
||||
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 {
|
||||
import PlayerMovementEvent._
|
||||
|
@ -1,23 +1,19 @@
|
||||
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 com.jme3.input.controls.MouseAxisTrigger
|
||||
import com.jme3.input.MouseInput
|
||||
import wow.doge.mygame.subsystems.events.PlayerCameraEvent
|
||||
|
||||
// class GameInputHandler(
|
||||
// inputManager: InputManager
|
||||
// // inputEventBus: InputEventBus
|
||||
// ) {}
|
||||
import akka.actor.typed.ActorRef
|
||||
import com.jme3.input.InputManager
|
||||
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 {
|
||||
|
||||
@ -30,6 +26,7 @@ object GameInputHandler {
|
||||
) {
|
||||
def begin =
|
||||
for {
|
||||
_ <- UIO(setupMovementKeys(inputManager))
|
||||
_ <- UIO(setupKeys(inputManager))
|
||||
_ <- toIO(
|
||||
generateMovementInputEvents(
|
||||
@ -49,40 +46,49 @@ object GameInputHandler {
|
||||
playerCameraEventBus
|
||||
).completedL.startAndForget
|
||||
)
|
||||
_ <- toIO(
|
||||
myTest(
|
||||
inputManager
|
||||
).completedL.startAndForget
|
||||
)
|
||||
} 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) =
|
||||
inputManager
|
||||
.withMapping(
|
||||
PlayerMovementInput.WalkLeft.entryName,
|
||||
new KeyTrigger(KeyInput.KEY_A)
|
||||
// new KeyTrigger(KeyInput.KEY_LEFT)
|
||||
)
|
||||
.withMapping(
|
||||
PlayerMovementInput.WalkRight.entryName,
|
||||
new KeyTrigger(KeyInput.KEY_D)
|
||||
// new KeyTrigger(KeyInput.KEY_RIGHT)
|
||||
)
|
||||
.withMapping(
|
||||
PlayerMovementInput.WalkForward.entryName,
|
||||
new KeyTrigger(KeyInput.KEY_W)
|
||||
// new KeyTrigger(KeyInput.KEY_UP)
|
||||
)
|
||||
.withMapping(
|
||||
PlayerMovementInput.WalkBackward.entryName,
|
||||
new KeyTrigger(KeyInput.KEY_S)
|
||||
// new KeyTrigger(KeyInput.KEY_DOWN)
|
||||
)
|
||||
.withMapping(
|
||||
"Jump",
|
||||
new KeyTrigger(KeyInput.KEY_SPACE)
|
||||
)
|
||||
// .withMapping(
|
||||
// PlayerMovementInput.WalkLeft.entryName,
|
||||
// new KeyTrigger(KeyInput.KEY_A)
|
||||
// // new KeyTrigger(KeyInput.KEY_LEFT)
|
||||
// )
|
||||
// .withMapping(
|
||||
// PlayerMovementInput.WalkRight.entryName,
|
||||
// new KeyTrigger(KeyInput.KEY_D)
|
||||
// // new KeyTrigger(KeyInput.KEY_RIGHT)
|
||||
// )
|
||||
// .withMapping(
|
||||
// PlayerMovementInput.WalkForward.entryName,
|
||||
// new KeyTrigger(KeyInput.KEY_W)
|
||||
// // new KeyTrigger(KeyInput.KEY_UP)
|
||||
// )
|
||||
// .withMapping(
|
||||
// PlayerMovementInput.WalkBackward.entryName,
|
||||
// new KeyTrigger(KeyInput.KEY_S)
|
||||
// // new KeyTrigger(KeyInput.KEY_DOWN)
|
||||
// )
|
||||
// .withMapping(
|
||||
// PlayerMovementInput.Jump.entryName,
|
||||
// new KeyTrigger(KeyInput.KEY_SPACE)
|
||||
// )
|
||||
.withMapping(
|
||||
PlayerAnalogInput.TurnRight.entryName,
|
||||
new KeyTrigger(KeyInput.KEY_RIGHT),
|
||||
@ -145,31 +151,17 @@ object GameInputHandler {
|
||||
name
|
||||
)
|
||||
)
|
||||
// case "Jump" if action.value =>
|
||||
// toTask(
|
||||
// playerMovementEventBus !! EventBus.Publish(
|
||||
// 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"))
|
||||
}
|
||||
case PlayerMovementInput.Jump =>
|
||||
if (action.value) {
|
||||
toTask(
|
||||
playerMovementEventBus !! EventBus.Publish(
|
||||
PlayerMovementEvent.PlayerJumped,
|
||||
name
|
||||
)
|
||||
)
|
||||
} else monix.eval.Task.unit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def generateRotateEvents(
|
||||
@ -182,7 +174,7 @@ object GameInputHandler {
|
||||
inputManager
|
||||
.enumAnalogObservable(PlayerAnalogInput)
|
||||
.sample(1.millis)
|
||||
.map(e => e)
|
||||
// .map(e => e)
|
||||
.doOnNext(analogEvent =>
|
||||
analogEvent.binding match {
|
||||
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
|
||||
import enumeratum._
|
||||
import enumeratum.EnumEntry._
|
||||
import enumeratum._
|
||||
|
||||
sealed trait PlayerMovementInput extends EnumEntry with UpperSnakecase
|
||||
object PlayerMovementInput extends Enum[PlayerMovementInput] {
|
||||
@ -9,6 +9,7 @@ object PlayerMovementInput extends Enum[PlayerMovementInput] {
|
||||
case object WalkRight extends PlayerMovementInput
|
||||
case object WalkLeft extends PlayerMovementInput
|
||||
case object WalkBackward extends PlayerMovementInput
|
||||
case object Jump extends PlayerMovementInput
|
||||
}
|
||||
|
||||
sealed trait PlayerAnalogInput extends EnumEntry with UpperSnakecase
|
||||
|
@ -1,36 +1,20 @@
|
||||
package wow.doge.mygame.game.subsystems.level
|
||||
import com.jme3.bullet.BulletAppState
|
||||
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape
|
||||
import com.jme3.bullet.control.CharacterControl
|
||||
import com.jme3.asset.AssetManager
|
||||
import com.jme3.bullet.control.RigidBodyControl
|
||||
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.DirectionalLight
|
||||
import com.jme3.math.ColorRGBA
|
||||
import com.jme3.math.Vector3f
|
||||
import com.jme3.renderer.ViewPort
|
||||
import com.jme3.scene.Spatial
|
||||
object DefaultGameLevel {
|
||||
|
||||
// lazy valbulletAppState: BulletAppState
|
||||
// bulletAppState.setThreadingType(ThreadingType.SEQUENTIAL)
|
||||
|
||||
// We set up collision detection for the scene by creating a
|
||||
// compound collision shape and a static RigidBodyControl with mass zero.
|
||||
|
||||
// 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")
|
||||
def apply(
|
||||
assetManager: AssetManager,
|
||||
viewPort: ViewPort
|
||||
) = {
|
||||
lazy val sceneModel: Spatial = assetManager.loadModel("main.scene")
|
||||
lazy val sceneShape = CollisionShapeFactory.createMeshShape(
|
||||
sceneModel.toNode match {
|
||||
case util.Right(node) => node
|
||||
@ -41,23 +25,26 @@ object DefaultGameLevel {
|
||||
lazy val landscape: RigidBodyControl =
|
||||
new RigidBodyControl(sceneShape, 0)
|
||||
|
||||
// // discard { app.stateManager.attach(bulletAppState) }
|
||||
|
||||
app.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f))
|
||||
viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f))
|
||||
sceneModel.setLocalScale(2f)
|
||||
sceneModel.addControl(landscape)
|
||||
discard { app.rootNode.attachChild(sceneModel) }
|
||||
bulletAppState.getPhysicsSpace.add(landscape)
|
||||
bulletAppState.getPhysicsSpace.add(player)
|
||||
// discard { rootNode.attachChild(sceneModel) }
|
||||
// bulletAppState.getPhysicsSpace.add(landscape)
|
||||
// bulletAppState.getPhysicsSpace.add(player)
|
||||
|
||||
val al = new AmbientLight();
|
||||
al.setColor(ColorRGBA.White.mult(1.3f));
|
||||
app.rootNode.addLight(al);
|
||||
// app.rootNode.addLight(al);
|
||||
|
||||
val dl = new DirectionalLight();
|
||||
dl.setColor(ColorRGBA.White);
|
||||
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.Quaternion
|
||||
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.typesafe.scalalogging.LazyLogging
|
||||
import wow.doge.mygame.implicits._
|
||||
import wow.doge.mygame.math.ImVector3f
|
||||
import wow.doge.mygame.subsystems.movement.RotateDir
|
||||
|
||||
trait CanMove[-A] {
|
||||
// def getDirection(cam: Camera, cardinalDir: CardinalDirection): ImVector3f
|
||||
|
@ -1,19 +1,17 @@
|
||||
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.scaladsl.ActorContext
|
||||
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.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.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
||||
import wow.doge.mygame.game.subsystems.movement.CanMove
|
||||
import com.softwaremill.quicklens._
|
||||
|
||||
sealed trait RotateDir
|
||||
object RotateDir {
|
||||
@ -36,7 +34,7 @@ object ImMovementActor {
|
||||
final case object RotateLeft extends Movement
|
||||
|
||||
final case class Props[T: CanMove](
|
||||
app: GameApp,
|
||||
enqueueR: Function1[() => Unit, Unit],
|
||||
movable: T,
|
||||
playerMovementEventBus: ActorRef[
|
||||
EventBus.Command[PlayerMovementEvent]
|
||||
@ -90,25 +88,25 @@ class ImMovementActor[T](
|
||||
case m: Movement =>
|
||||
m match {
|
||||
case MovedLeft(pressed) =>
|
||||
props.app.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
||||
props.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
||||
receive(state = state.modify(_.cardinalDir.left).setTo(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))
|
||||
case MovedRight(pressed) =>
|
||||
props.app.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
||||
props.enqueueR(() => stopIfNotPressed(pressed, props.movable))
|
||||
receive(state = state.modify(_.cardinalDir.right).setTo(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))
|
||||
case Jump =>
|
||||
props.app.enqueueR(() => cm.jump(props.movable))
|
||||
props.enqueueR(() => cm.jump(props.movable))
|
||||
Behaviors.same
|
||||
case RotateLeft =>
|
||||
props.app.enqueueR(() => cm.rotate(props.movable, RotateDir.Left))
|
||||
props.enqueueR(() => cm.rotate(props.movable, RotateDir.Left))
|
||||
Behaviors.same
|
||||
case RotateRight =>
|
||||
props.app.enqueueR(() => cm.rotate(props.movable, RotateDir.Right))
|
||||
props.enqueueR(() => cm.rotate(props.movable, RotateDir.Right))
|
||||
Behaviors.same
|
||||
}
|
||||
|
||||
@ -117,7 +115,7 @@ class ImMovementActor[T](
|
||||
getDirection(state.cardinalDir, ctx.log.trace)
|
||||
if (walkDir != ImVector3f.ZERO) {
|
||||
val tmp = walkDir * 25f * (1f / 144)
|
||||
props.app.enqueueR { () =>
|
||||
props.enqueueR { () =>
|
||||
cm.move(props.movable, tmp)
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
package wow.doge.mygame.implicits
|
||||
|
||||
import scala.reflect.ClassTag
|
||||
import scala.util.Try
|
||||
|
||||
import com.simsilica.es.ComponentFilter
|
||||
import com.simsilica.es.EntityComponent
|
||||
import com.simsilica.es.EntityData
|
||||
import com.simsilica.es.EntitySet
|
||||
import com.simsilica.es.Filters
|
||||
import scala.reflect.ClassTag
|
||||
import scala.util.Try
|
||||
|
||||
class EntityQuery(ed: EntityData) {
|
||||
private var cfilter: Option[ComponentFilter[_ <: EntityComponent]] = None
|
||||
|
@ -1,52 +1,54 @@
|
||||
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.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.scene.SceneGraphVisitor
|
||||
import monix.reactive.Observable
|
||||
import com.jme3.asset.AssetManager
|
||||
import com.jme3.app.SimpleApplication
|
||||
import com.jme3.app.state.AppState
|
||||
import com.jme3.app.state.AppStateManager
|
||||
import com.jme3.asset.AssetLocator
|
||||
import com.jme3.input.controls.ActionListener
|
||||
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.asset.AssetManager
|
||||
import com.jme3.bullet.BulletAppState
|
||||
import wow.doge.mygame.state.MyBaseState
|
||||
import monix.bio.UIO
|
||||
import com.jme3.bullet.PhysicsSpace
|
||||
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.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.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.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 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 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 {
|
||||
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 {
|
||||
|
||||
/**
|
||||
@ -139,6 +175,11 @@ package object implicits {
|
||||
def observableChildren =
|
||||
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)
|
||||
|
||||
/**
|
||||
@ -147,12 +188,24 @@ package object implicits {
|
||||
* @param lst
|
||||
*/
|
||||
def withChildren(lst: Spatial*): Node = {
|
||||
for (c <- lst) n.withChild(c)
|
||||
for (c <- lst) n.attachChild(c)
|
||||
n
|
||||
}
|
||||
|
||||
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) =
|
||||
n.depthFirstTraversal(new SceneGraphVisitor() {
|
||||
override def visit(s: Spatial) = cb(s)
|
||||
@ -333,6 +386,16 @@ package object implicits {
|
||||
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] = {
|
||||
|
||||
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] = {
|
||||
|
||||
Observable.create(OverflowStrategy.DropOld(50)) { sub =>
|
||||
@ -509,60 +566,60 @@ package object implicits {
|
||||
//TODO Create a typeclass for this
|
||||
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)
|
||||
space
|
||||
}
|
||||
|
||||
implicit class AssetManagerExt(private val am: AssetManager) extends AnyVal {
|
||||
def registerLocator(
|
||||
assetPath: os.RelPath,
|
||||
locator: Class[_ <: AssetLocator]
|
||||
): Unit = {
|
||||
am.registerLocator(assetPath.toString(), locator)
|
||||
def :-(spatial: Spatial) = {
|
||||
space.removeAll(spatial)
|
||||
space
|
||||
}
|
||||
|
||||
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 {
|
||||
//TODO add more operations
|
||||
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 += 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: ImVector3f) = v.subtractLocal(that.x, that.y, that.z)
|
||||
def -=:(that: ImVector3f) = v *= that
|
||||
def /=(that: Vector3f) = v.divideLocal(that)
|
||||
def /=(that: ImVector3f) = v.divideLocal(that.mutable)
|
||||
def /=:(that: ImVector3f) = v *= that
|
||||
def unary_- = v.negateLocal()
|
||||
def immutable = ImVector3f(v.x, v.y, v.z)
|
||||
}
|
||||
|
||||
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 +(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 *(f: Float): ImVector3f =
|
||||
v.copy(v.x * f, v.y * f, v.z * f)
|
||||
// v * ImVector3f(f, f, f)
|
||||
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 /(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_-(that: ImVector3f) = this.copy(this.x, this.y, this.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
|
||||
|
||||
import scala.reflect.ClassTag
|
||||
|
||||
import akka.actor.typed.ActorRef
|
||||
import akka.actor.typed.Behavior
|
||||
import akka.actor.typed.scaladsl.Behaviors
|
||||
import scala.reflect.ClassTag
|
||||
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.SpawnProtocol
|
||||
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.ActorSystem
|
||||
import akka.actor.typed.LogOptions
|
||||
import com.typesafe.scalalogging.{Logger => SLLogger}
|
||||
import wow.doge.mygame.events.EventBus
|
||||
import akka.actor.typed.scaladsl.Behaviors
|
||||
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent
|
||||
import akka.actor.typed.Props
|
||||
import akka.actor.typed.SpawnProtocol
|
||||
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 {
|
||||
def spawnProtocol: ActorRef[SpawnProtocol.Command]
|
||||
implicit def akkaScheduler: Scheduler
|
||||
implicit def timeout: Timeout
|
||||
def eventBusLogger = SLLogger[EventBus[_]]
|
||||
class EventsModule2(
|
||||
spawnProtocol: ActorSystem[SpawnProtocol.Command]
|
||||
) {
|
||||
implicit lazy val s = spawnProtocol.scheduler
|
||||
|
||||
lazy val tickEventBusTask = createEventBus[Events.Tick]("tickEventBus")
|
||||
implicit lazy val timeout = Timeout(1.second)
|
||||
|
||||
lazy val eventBusLogger = SLLogger[EventBus[_]]
|
||||
|
||||
lazy val playerMovementEventBusTask =
|
||||
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.Spawn[EventBus.Command[T]](
|
||||
Behaviors.logMessages(
|
||||
logOptions = LogOptions().withLogger(eventBusLogger.underlying),
|
||||
logOptions = LogOptions()
|
||||
.withLevel(logLevel)
|
||||
.withLogger(eventBusLogger.underlying),
|
||||
Behaviors
|
||||
.supervise(EventBus[T]())
|
||||
.onFailure[Exception](SupervisorStrategy.restart)
|
||||
@ -39,17 +49,17 @@ trait EventsModule {
|
||||
_
|
||||
)
|
||||
)
|
||||
}
|
||||
object EventTypes {
|
||||
type EventBus[T] = ActorRef[EventBus.Command[T]]
|
||||
}
|
||||
|
||||
// val subscribingActor =
|
||||
// spawnProtocol.askT(
|
||||
// SpawnProtocol.Spawn[Events.PhysicsTick.type](
|
||||
// SubscribingActor(),
|
||||
// "subscriber-1",
|
||||
// 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,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
|
||||
import java.io.FileNotFoundException
|
||||
import java.nio.file.NoSuchFileException
|
||||
|
||||
import scala.collection.View
|
||||
import scala.collection.immutable.ArraySeq
|
||||
@ -11,7 +12,9 @@ import io.circe.generic.semiauto._
|
||||
import io.circe.parser._
|
||||
import monix.bio.IO
|
||||
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
|
||||
|
||||
@JsonCodec
|
||||
@ -20,6 +23,9 @@ final case class Test1(hello1: String, hello2: String)
|
||||
final case class Test2(hello1: String)
|
||||
final case class Plugin(name: String, priority: Int)
|
||||
object Plugin {
|
||||
// @annotation.nowarn(
|
||||
// "msg=Block result was adapted via implicit conversion"
|
||||
// )
|
||||
implicit val pluginFormat: Decoder[Plugin] = deriveDecoder
|
||||
}
|
||||
|
||||
@ -90,16 +96,29 @@ object ModdingSystem {
|
||||
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)]) = {
|
||||
plugins.foldLeft(Json.fromString("empty")) {
|
||||
case (json, that) =>
|
||||
that match {
|
||||
case (p, io.circe.Json.Null) => json //ignore null values
|
||||
case (p, value) => json.deepMerge(value)
|
||||
}
|
||||
foldMerge(plugins.map {
|
||||
case (p, json) => json
|
||||
})
|
||||
}
|
||||
|
||||
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 =
|
||||
// for {
|
||||
// filePaths <- Task(findPluginFiles(os.pwd))
|
||||
@ -118,7 +137,16 @@ object ModdingSystem {
|
||||
plugins <- IO.fromTryEither(readPluginsList(wd))
|
||||
(readFailures, readSuccesses) <- UIO(findAndReadPluginFiles(wd, plugins))
|
||||
(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 {
|
||||
println(s"Read Successes = ${readSuccesses.to(Seq)}")
|
||||
println(s"Read Failures = ${readFailures.to(Seq)}")
|
||||
@ -138,5 +166,4 @@ object ModdingSystem {
|
||||
// def test3(wd: os.Path = os.pwd) = {
|
||||
// (readPluginsList(os.pwd).toValidatedNec)
|
||||
// }
|
||||
;
|
||||
}
|
||||
|
@ -1,21 +1,22 @@
|
||||
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.ScriptEngineManager
|
||||
import groovy.util.GroovyScriptEngine
|
||||
import cats.implicits._
|
||||
|
||||
import akka.actor.typed.ActorRef
|
||||
import akka.actor.typed.Behavior
|
||||
import akka.actor.typed.LogOptions
|
||||
import org.slf4j.event.Level
|
||||
import com.typesafe.scalalogging.Logger
|
||||
import akka.actor.typed.scaladsl.ActorContext
|
||||
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.typesafe.scalalogging.Logger
|
||||
import groovy.util.GroovyScriptEngine
|
||||
import org.slf4j.event.Level
|
||||
|
||||
object ScriptActor {
|
||||
trait Kotlin
|
||||
|
@ -1,19 +1,20 @@
|
||||
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.PoolRouter
|
||||
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 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 org.slf4j.event.Level
|
||||
import wow.doge.mygame.state.ScriptActor
|
||||
|
||||
object ScriptCachingActor {
|
||||
|
||||
|
@ -1,23 +1,65 @@
|
||||
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.Scheduler
|
||||
import akka.actor.typed.SpawnProtocol
|
||||
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(
|
||||
path: os.Path,
|
||||
spawnProtocol: ActorRef[SpawnProtocol.Command]
|
||||
spawnProtocol: ActorRef[SpawnProtocol.Command],
|
||||
mode: ScriptInitMode = ScriptInitMode.Lazy
|
||||
)(implicit timeout: Timeout, scheduler: Scheduler) {
|
||||
def make =
|
||||
Resource.liftF(
|
||||
AkkaUtils.spawnActorL(
|
||||
val make = {
|
||||
// throw new Exception("boom")
|
||||
findScriptFiles(os.pwd / "assets" / "scripts")
|
||||
|
||||
lazy val scriptCacheActor = AkkaUtils.spawnActorL(
|
||||
spawnProtocol,
|
||||
"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
|
||||
|
||||
import akka.actor.typed.Props
|
||||
import akka.util.Timeout
|
||||
import akka.actor.typed.Scheduler
|
||||
import akka.actor.typed.ActorRef
|
||||
import akka.actor.typed.SpawnProtocol
|
||||
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._
|
||||
|
||||
object AkkaUtils {
|
||||
|
@ -1,11 +1,12 @@
|
||||
package wow.doge.mygame.utils
|
||||
|
||||
import java.io.PrintStream
|
||||
import java.io.OutputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import scalafx.scene.control.TextArea
|
||||
import java.io.OutputStream
|
||||
import java.io.PrintStream
|
||||
|
||||
import cats.effect.Resource
|
||||
import monix.bio.Task
|
||||
import scalafx.scene.control.TextArea
|
||||
|
||||
trait JFXConsoleStreamable[T] {
|
||||
def println(inst: T, text: String): Unit
|
||||
|
Loading…
Reference in New Issue
Block a user