many changes

This commit is contained in:
Rohan Sircar 2020-11-13 19:44:57 +05:30
parent 1f55e08fa5
commit b0994bcdbe
41 changed files with 1494 additions and 413 deletions

4
.jvmopts Normal file
View File

@ -0,0 +1,4 @@
-Xms2G
-Xmx2G
-XX:+UseG1GC
-XX:MaxGCPauseMillis=50

View File

@ -66,10 +66,11 @@ lazy val root = (project in file(".")).settings(
"com.lihaoyi" % "ammonite" % "2.2.0" cross CrossVersion.full,
"org.jetbrains.kotlin" % "kotlin-main-kts" % "1.4.10",
"org.jetbrains.kotlin" % "kotlin-scripting-jsr223" % "1.4.10",
"org.codehaus.groovy" % "groovy-all" % "3.0.6" pomOnly (),
// "wow.doge" % "game" % "1.0-SNAPSHOT",
"org.scalafx" %% "scalafx" % "14-R19",
"com.typesafe.akka" %% "akka-actor-typed" % "2.6.10",
"ch.qos.logback" % "logback-classic" % "1.2.3",
// "ch.qos.logback" % "logback-classic" % "1.2.3",
"org.typelevel" %% "cats-core" % "2.1.1",
"org.typelevel" %% "cats-effect" % "2.1.4",
"io.monix" %% "monix" % "3.2.2",
@ -85,7 +86,8 @@ lazy val root = (project in file(".")).settings(
"com.softwaremill.macwire" %% "macros" % "2.3.6" % "provided",
"com.softwaremill.macwire" %% "macrosakka" % "2.3.6" % "provided",
"com.github.valskalla" %% "odin-slf4j" % "0.8.1",
"com.softwaremill.quicklens" %% "quicklens" % "1.6.1"
"com.softwaremill.quicklens" %% "quicklens" % "1.6.1",
"org.scala-lang.modules" %% "scala-parallel-collections" % "1.0.0-RC1"
),
// Determine OS version of JavaFX binaries
@ -102,6 +104,7 @@ lazy val root = (project in file(".")).settings(
"-Xlint",
"-Ywarn-numeric-widen",
"-Ymacro-annotations",
"-Xlint:byname-implicit",
// "utf-8", // Specify character encoding used by source files.
"-explaintypes" // Explain type errors in more detail.
),
@ -141,6 +144,7 @@ lazy val root = (project in file(".")).settings(
// semanticdbVersion := scalafixSemanticdb.revision // use Scalafix compatible version
// semanticdbVersion := "4.3.24",
)
initialCommands in (console) := """ammonite.Main.main(Array.empty)"""
// Here, `libraryDependencies` is a set of dependencies, and by using `+=`,
// we're adding the scala-parser-combinators dependency to the set of dependencies
@ -190,3 +194,4 @@ lazy val root = (project in file(".")).settings(
// 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")

3
launch.sh Normal file
View File

@ -0,0 +1,3 @@
# sdk use java 20.2.0.r11-grl
# java -J-Xms2G -J-Xmx2G -J-XX:+UseG1GC -J-XX:MaxGCPauseMillis=50 -jar target/scala-2.13/mygame-assembly-1.0-SNAPSHOT.jar
java -Xms2G -Xmx2G -XX:+UseG1GC -XX:MaxGCPauseMillis=50 -jar target/scala-2.13/mygame-assembly-1.0-SNAPSHOT.jar

BIN
lib/jme3-testdata.jar Normal file

Binary file not shown.

4
plugins.json Normal file
View File

@ -0,0 +1,4 @@
[
{ "name": "test", "priority": 1 },
{ "name": "test2", "priority": 2 }
]

View File

@ -1,2 +1,3 @@
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.23")
addCompilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.1")

View File

@ -0,0 +1,3 @@
println "hello"
this

View File

@ -1,4 +1,5 @@
#!/usr/bin/env amm
// scala 2.13.3
// import coursierapi.MavenRepository

View File

@ -0,0 +1,59 @@
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._
//effect type should be specified inbefore
//log line will be recorded right after the call with no suspension
class StaticLoggerBinder extends OdinLoggerBinder[IO] {
val ec: ExecutionContext = Scheduler.global
implicit val timer: Timer[IO] = IO.timer(ec)
implicit val clock: Clock[IO] = timer.clock
implicit val cs: ContextShift[IO] = IO.contextShift(ec)
implicit val F: Effect[IO] = IO.ioEffect
val monixToCats = new FunctionK[_root_.monix.bio.Task, IO] {
def apply[A](fa: _root_.monix.bio.Task[A]): IO[A] = fa.to[IO]
}
val (fLogger, release) =
// MainModule.DefaultFileLogger.mapK(monixToCats).allocated.unsafeRunSync()
fileLogger[IO](
"log2.log"
).withAsync(timeWindow = 1.seconds).allocated.unsafeRunSync()
// Runtime
// .getRuntime()
// .addShutdownHook(new Thread {
// release.unsafeRunSync()
// })
scala.sys.addShutdownHook(release.unsafeRunSync())
val loggers: PartialFunction[String, Logger[IO]] = {
case "some.external.package.SpecificClass" =>
consoleLogger[IO](minLevel = Level.Warn) //disable noisy external logs
case asyncHttpClient
if asyncHttpClient.startsWith("org.asynchttpclient.netty") =>
consoleLogger[IO](minLevel = Level.Warn)
case s if s.startsWith("akka.actor") || s.startsWith("wow.doge.mygame") =>
consoleLogger[IO]() |+| fLogger
case _ => //if wildcard case isn't provided, default logger is no-op
consoleLogger[IO]()
}
}
object StaticLoggerBinder extends StaticLoggerBinder {
var REQUESTED_API_VERSION: String = "1.7"
def getSingleton: StaticLoggerBinder = this
}

View File

@ -1,127 +1,105 @@
package wow.doge.mygame
import game.GameApp
import com.jme3.app.StatsAppState
import akka.actor.typed.ActorSystem
import akka.actor.typed.SpawnProtocol
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.Behavior
import akka.util.Timeout
import com.jme3.system.AppSettings
import wow.doge.mygame.game.GameAppActor
import wow.doge.mygame.scriptsystem.ScriptCachingActor
object Main extends App {
import java.util.logging.{Logger, Level}
Logger.getLogger("").setLevel(Level.SEVERE)
import monix.bio.Task
import cats.effect.Resource
import io.odin.syntax._
// runner.runCode("""|println("starting scala script engine")""".stripMargin)
val gameApp = new GameApp(
// new EntityDataState(),
// new TestAppState(),
// new PlayerMovementState(),
// new FlyCamAppState(),
new StatsAppState()
)
val settings = new AppSettings(true)
// settings.setVSync(true)
settings.setFrameRate(144)
gameApp.setSettings(settings)
val actorSystem = ActorSystem(RootActor(gameApp), "rootActor")
// actorSystem.eventStream
// gameApp.start()
println("here 1")
// actorSystem.terminate()
// JMEExecutorService.shutdown()
// println("here 2")
//FIXME remove this
// System.exit(0)
}
// import io.odin.monix._
import cats.effect.ExitCode
import cats.implicits._
import com.softwaremill.macwire._
import scala.concurrent.duration._
import monix.bio.BIOApp
import monix.bio.UIO
import monix.bio.IO
import io.odin._
import wow.doge.mygame.executors.JMERunner
import com.jme3.bullet.BulletAppState
import wow.doge.mygame.implicits._
object RootActor {
def apply(app: GameApp): Behavior[SpawnProtocol.Command] =
Behaviors.setup { ctx =>
ctx.log.debug("Starting root actor")
val testActor = ctx.spawn(TestActor(), "testActor")
val _ = ctx.spawn(GameAppActor(app), "gameAppActor")
// import wow.doge.mygame.implicits._
testActor ! TestActor.Test
SpawnProtocol()
}
}
// object Main extends App {
// import java.util.logging.{Logger, Level}
// Logger.getLogger("").setLevel(Level.SEVERE)
object TestActor {
sealed trait Command
case object Test extends Command
private case object Done extends Command
// sealed trait Result
// case object Done extends Result
// // runner.runCode("""|println("starting scala script engine")""".stripMargin)
// val gameApp = new GameApp(
// // new EntityDataState(),
// // new TestAppState(),
// // new PlayerMovementState(),
// // new FlyCamAppState(),
// new StatsAppState()
// )
// val settings = new AppSettings(true)
// // settings.setVSync(true)
// settings.setFrameRate(144)
// gameApp.setSettings(settings)
// val actorSystem = ActorSystem(RootActor(gameApp), "rootActor")
// // actorSystem.eventStream
// // gameApp.start()
// println("here 1")
// // actorSystem.terminate()
// // JMEExecutorService.shutdown()
// // println("here 2")
// //FIXME remove this
// // System.exit(0)
// }
import scala.concurrent.duration._
implicit val timeout = Timeout(15.seconds)
// implicit val scheduler =
object Main extends BIOApp with MainModule {
import java.util.logging.{Logger => JLogger, Level}
JLogger.getLogger("").setLevel(Level.SEVERE)
def apply(): Behavior[Command] =
Behaviors.setup { ctx =>
ctx.spawn(ScriptCachingActor(), "scriptCacher")
Behaviors.receiveMessage { msg =>
msg match {
case Test =>
// ctx.ask(
// router,
// ScriptActor.Compile(
// // os.pwd / "some.sc",
// os.pwd / "src" / "main" / "resources" / "hello2.main.kts",
// _
// )
// ) {
// case Success(value) =>
// ctx.log.debug("Received Value")
// ctx.log.debug(value.toString())
// Done
// case Failure(exception) =>
// ctx.log.debug(s"Received Error ${exception.getMessage()}")
// Done
// }
// val x = scriptStorer
// .askT(
// ScriptStoringActor
// .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
// )(timeout, ctx.system.scheduler)
def run(args: List[String]): UIO[ExitCode] = {
// ctx.ask(
// scriptStorer,
// ScriptStoringActor
// .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
// ) {
// case Success(value) => {
// ctx.log.debug(value.toString())
// ctx.ask(
// scriptStorer,
// ScriptStoringActor
// .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
// ) {
// case Success(value) => {
// ctx.log.debug(value.toString())
// Done
// }
// case Failure(exception) =>
// ctx.log.debug(exception.getMessage())
// Done
// }
// Done
// }
// case Failure(exception) =>
// ctx.log.debug(exception.getMessage())
// Done
// }
Behaviors.same
case Done => Behaviors.same
}
// SpawnProtocol()
// Behaviors.same
lazy val appResource = for {
logger <-
consoleLogger().withAsync(timeWindow = 1.seconds) |+| fileLogger(
"log.log"
).withAsync(timeWindow = 1.seconds)
jmeScheduler <- jMESchedulerResource
// consoleTextArea <- Resource.liftF(Task(new TextArea()))
// consoleStream <- wireWith(JFXConsoleStream.textAreaStream _)
gameApp <- {
new BulletAppState()
// bas.setThreadingType(Thr)
gameAppResource(new StatsAppState())
}
}
_ <- Resource.liftF(IO(JMERunner.runner = gameApp))
actorSystem <- wireWith(actorSystemResource _)
// _ <- Resource.liftF(
// Task(gameApp.start()).asyncBoundary
// .executeOn(Scheduler(JMEExecutorService))
// )
_ <- Resource.liftF(gameApp.enqueueT(actorSystem ! RootActor.Start))
_ <- Resource.liftF {
IO(gameApp.start())
.executeOn(jmeScheduler)
}
// (_ => IO(gameApp.stop(() => actorSystem ! RootActor.Stop)))
} yield ()
// Console.withOut(
// new JFXConsoleStream(
// new scalafx.scene.control.TextArea(),
// new ByteArrayOutputStream(35)
// )
// )(())
appResource
.use(_ =>
// Task(gameApp.start())
// .executeOn(Scheduler(JMEExecutorService))
// .asyncBoundary
// Task.never
Task.unit
// >>
// .executeOn(Scheduler(JMEExecutorService))
)
.onErrorHandle(_.printStackTrace())
.as(ExitCode.Success)
}
}

View File

@ -0,0 +1,87 @@
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._
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(RootActor(app, schedulers), name = "GameActorSystem")
})(sys =>
logger.info("Shutting down actor system") >> Task(
sys.terminate()
)
)
}
object MainModule {
// import cats.implicits._
import scala.concurrent.duration._
val DefaultFileLogger: Resource[Task, Logger[Task]] =
fileLogger[Task](
"log.log"
).withAsync(timeWindow = 1.seconds)
}
object RootActor {
sealed trait Command
final case object Start extends Command
final case object Stop extends Command
final case class State(initialized: Boolean = false)
def apply(
app: GameApp,
schedulers: Schedulers,
state: State = State()
): 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
) {
import RootActor._
def receive(state: State): Behavior[Command] =
Behaviors.receiveMessage(msg =>
msg match {
case Start =>
if (!state.initialized) {
ctx.log.info("Starting GameAppActor")
val _ = ctx.spawn(
wireWith(GameAppActor.apply _),
"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
}
)
}

View File

@ -1,5 +1,23 @@
package wow.doge.mygame.executors
import monix.bio.Task
import cats.effect.Resource
import monix.execution.Scheduler
trait ExecutorsModule {
lazy val schedulers = new Schedulers()
lazy val schedulers = Schedulers()
// Resource.make(
// Task(
// new Schedulers(
// jme = Scheduler
// .singleThread(name = "JME-Application-Thread", daemonic = false)
// )
// )
// )(s => Task(s.jme.shutdown()))
lazy val jMESchedulerResource = Resource.make(
Task(
Scheduler
.singleThread(name = "JME-Application-Thread", daemonic = false)
)
)(e => Task(e.shutdown()))
}

View File

@ -18,7 +18,6 @@ import javafx.application.Platform
import monix.execution.Scheduler
import scala.concurrent.ExecutionContext
import java.util.concurrent.Executor
import wow.doge.mygame.Main
// First we wrap invokeLater/runLater as an ExecutorService
trait GUIExecutorService extends AbstractExecutorService {
@ -44,7 +43,15 @@ object SwingExecutorService extends GUIExecutorService {
}
object JMEExecutorService extends GUIExecutorService {
override def execute(command: Runnable) = Main.gameApp.enqueue(command)
override def execute(command: Runnable) =
JMERunner.runner.enqueue(command)
// new SingleThreadEventExecutor()
sys.addShutdownHook(JMEExecutorService.shutdown())
}
object JMERunner {
var runner: com.jme3.app.Application = null
}
class JavaFXEventThreadExecutorServiceConfigurator(

View File

@ -4,7 +4,7 @@ import monix.execution.Scheduler
final case class Schedulers(
blockingIO: Scheduler = Scheduler.io(),
cpu: Scheduler = Scheduler.global,
fx: Scheduler = JFXExecutionContexts.fxScheduler,
jme: Option[Scheduler] = None
async: Scheduler = Scheduler.global,
fx: Scheduler = JFXExecutionContexts.fxScheduler
// jme: SchedulerService
)

View File

@ -3,23 +3,16 @@ package wow.doge.mygame.game
import com.jme3.app.SimpleApplication
import com.jme3.app.state.AppState
import akka.actor.typed.ActorRef
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.Behaviors
object Greeter {
final case class Greet(whom: String, replyTo: ActorRef[Greeted])
final case class Greeted(whom: String, from: ActorRef[Greet])
def apply(): Behavior[Greet] =
Behaviors.receive { (context, message) =>
// context.log.info("Hello {}!", message.whom)
//#greeter-send-messages
message.replyTo ! Greeted(message.whom, context.self)
//#greeter-send-messages
Behaviors.same
}
}
import com.jme3.bullet.BulletAppState
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape
import com.jme3.bullet.control.CharacterControl
import com.jme3.bullet.control.RigidBodyControl
import com.jme3.bullet.util.CollisionShapeFactory
import com.jme3.scene.Spatial
import com.jme3.syntax._
import com.jme3.asset.plugins.ZipLocator
import com.jme3.math.ColorRGBA
import wow.doge.mygame.implicits._
class GameApp(
// actorSystem: ActorSystem[SpawnProtocol.Command],
@ -27,8 +20,47 @@ class GameApp(
) extends SimpleApplication(appStates: _*) {
// implicit val timeout = Timeout(10.seconds)
// implicit val scheduler = actorSystem.scheduler
private lazy val sceneModel: Spatial = assetManager.loadModel("main.scene")
private lazy val bulletAppState: BulletAppState = new 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.
private lazy val sceneShape = CollisionShapeFactory.createMeshShape(
sceneModel.toNode match {
case util.Right(node) => node
case util.Left(ex) =>
throw new NotImplementedError("No fallback sceneshape")
}
)
private lazy val landscape: RigidBodyControl =
new RigidBodyControl(sceneShape, 0)
// 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.
protected lazy val capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1)
private lazy val player: CharacterControl =
new CharacterControl(capsuleShape, 0.05f)
override def simpleInitApp(): Unit = {
discard { stateManager.attach(bulletAppState) }
assetManager.registerLocator(
// "src/main/resources/assets/town.zip",
(os.rel / "src" / "main" / "resources" / "assets" / "town.zip"),
classOf[ZipLocator]
)
viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f))
sceneModel.setLocalScale(2f)
sceneModel.addControl(landscape)
discard { rootNode.attachChild(sceneModel) }
bulletAppState.getPhysicsSpace.add(landscape)
bulletAppState.getPhysicsSpace.add(player)
println("gameapp" + Thread.currentThread().getName())
// val ship = ed.createEntity()
// val mbState = stateManager().state[EntityDataState]().map(_.getEntityData())
@ -88,22 +120,23 @@ class GameApp(
// super.stop()
// }
}
object GameApp {
// def myExec(app: SimpleApplication, command: Runnable) = {
// app.enqueue(command)
// override def start(): Unit = {
// monix.eval.Task(super.start()).runToFuture(Scheduler(JMEExecutorService))
// }
// val javaFxExecutionContext: ExecutionContext =
// ExecutionContext.fromExecutor(new Executor {
// def execute(command: Runnable): Unit = {
// Platform.runLater(command)
// }
// })
// def jmeEC(app: SimpleApplication): ExecutionContext =
// ExecutionContext.fromExecutor(new Executor {
// override def execute(command: Runnable): Unit = app.enqueue(command)
// })
// def jmeScheduler(app: SimpleApplication) = Sch
// def start(system: ActorRef[RootActor.Command]) = {
// // system ! RootActor.Start
// super.start()
// }
// override def stop(): Unit = {
// println("stopping")
// }
def stop[T](cb: () => T): Unit = {
println("destroy")
cb()
super.stop()
}
// override def stop(): Unit = {}
}

View File

@ -1,63 +1,177 @@
package wow.doge.mygame.game
import akka.actor.typed.scaladsl.Behaviors
import wow.doge.mygame.state.MovementActor
import wow.doge.mygame.state.PlayerMovementState2
import wow.doge.mygame.state.MovementActorTimer
import com.jme3.scene.shape.Box
import wow.doge.mygame.state.PlayerMovementState
import com.jme3.scene.Geometry
import wow.doge.mygame.implicits._
import wow.doge.mygame.events.EventBus
import wow.doge.mygame.events.Events
import wow.doge.mygame.state.ImMovementActor
import com.jme3.scene.CameraNode
import com.jme3.scene.Node
import com.jme3.renderer.Camera
import wow.doge.mygame.executors.Schedulers
import wow.doge.mygame.game.nodes.PlayerNode
import com.softwaremill.macwire._
import wow.doge.mygame.implicits._
object GameAppActor {
import Methods._
sealed trait Command
def apply(app: GameApp) =
case object XD extends Command
case object Stop extends Command
def apply(app: GameApp, schedulers: Schedulers) =
Behaviors.setup[Command] { ctx =>
lazy val b = new Box(1, 1, 1)
lazy val geom = new Geometry("Box", b)
val movementActor =
ctx.spawn(
MovementActor(MovementActor.Props(app, geom)),
"movementActor"
// DispatcherSelector.fromConfig("jme-dispatcher")
)
val movementActorTimer = ctx.spawn(
MovementActorTimer(movementActor),
"movementActorTimer"
)
val imMovementActor = ctx.spawn(
ImMovementActor(ImMovementActor.Props(app, geom)),
"imMovementActor"
)
ctx.log.info("Hello from GameAppActor")
// lazy val b = new Box(1, 1, 1)
// lazy val geom = new Geometry("Box", b)
// lazy val playerNode = new Node("PlayerNode")
// lazy val camNode = new CameraNode("CameraNode", app.getCamera())
// lazy val players = createPlayer(geom, app.getCamera())
// ctx.pipeToSelf(
// app.enqueueF(() => ())(monix.execution.Scheduler.io("aege"))
// ) {
// case x =>
// println("SENDEDEEEEEd")
// XD
// }
// ctx.pipeToSelf(
// createPlayer(
// geom,
// app.getCamera(),
// schedulers.jme
// )
// ) {
// case x =>
// println(x)
// XD
// }
val subscribingActor = ctx.spawn(SubscribingActor(), "subscriber-1")
val eventBus =
val tickEventBus =
ctx.spawn(Behaviors.logMessages(EventBus[Events.Tick]()), "eventBus1")
eventBus ! EventBus.Subscribe(subscribingActor)
tickEventBus ! EventBus.Subscribe(subscribingActor)
eventBus ! EventBus.Publish(Events.PhysicsTick, ctx.self)
tickEventBus ! EventBus.Publish(Events.PhysicsTick, ctx.self)
// {
// app
// .getInputManager()
// .observableAction("Left")
// .map { action =>
// action.binding.name match {
// case "Left" => Task(println("Pressed left"))
// }
// }
// }
// binding match {
// case "Left" =>
def playerNodeFactory =
PlayerNode(
modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o",
cam = app.camera
) _
// (assetManager = app.assetManager)
{
lazy val playerNode = playerNodeFactory(app.assetManager)
lazy val actor = ctx.spawn(
ImMovementActor(ImMovementActor.Props(app, playerNode)),
"imMovementActor"
)
lazy val state = wire[PlayerMovementState]
app.stateManager.attach(state)
}
Thread.sleep(2000)
app
.getStateManager()
.attach(
new PlayerMovementState2(
movementActor,
movementActorTimer,
imMovementActor,
geom
)
.getRootNode()
.depthFirst(s =>
// s match {
// case node: Node =>
// println("node" + s.getName() + " children " + node.getChildren())
// case g: Geometry => println(s.getName())
// }
println(s.getName())
)
app.start()
Behaviors.stopped
println("----------------")
{
app
.getRootNode()
.observableDepthFirst()
.map(s => s.getName())
// .takeWhileInclusive(_.getName() != "level")
.onErrorHandle(e => e.getMessage())
.foreach(println)(schedulers.async)
}
println("----------------")
{
app
.getRootNode()
.observableBreadthFirst()
.map(s => s.getName())
// .takeWhileInclusive(_.getName() != "level")
.onErrorHandle(e => e.getMessage())
.foreach(println)(schedulers.async)
}
// app.start()
// Behaviors.same
Behaviors.receiveMessage { msg =>
msg match {
case XD =>
ctx.log.info("RECEEEEEIVED")
ctx.log.info(app.camera.toString())
Behaviors.same
case Stop =>
ctx.log.info("Received stop")
Behaviors.stopped
}
}
}
}
object Methods {
def createPlayer(
geom: Geometry,
cam: Camera
): Node = {
val playerNode = new Node("PlayerNode")
lazy val camNode = new CameraNode("CameraNode", cam)
playerNode
.child(camNode)
.child(geom)
playerNode
}
def old() = {
// val movementActor =
// ctx.spawn(
// MovementActor(MovementActor.Props(app, geom)),
// "movementActor"
// // DispatcherSelector.fromConfig("jme-dispatcher")
// )
// val movementActorTimer = ctx.spawn(
// MovementActorTimer(movementActor),
// "movementActorTimer"
// )
}
}
object SubscribingActor {
def apply() =
Behaviors.receive[Events.PhysicsTick.type] { (ctx, msg) =>
@ -65,3 +179,12 @@ object SubscribingActor {
Behaviors.same
}
}
// new PlayerMovementState(
// // movementActor,
// // movementActorTimer,
// imMovementActor,
// // geom,
// // camNode,
// playerNode
// // ctx.self
// )

View File

@ -0,0 +1,25 @@
package wow.doge.mygame.game
import cats.effect.Resource
import com.jme3.app.state.AppState
import com.jme3.system.AppSettings
import monix.bio.Task
// import wow.doge.mygame.executors.JMERunner
trait GameModule {
def gameAppResource(appStates: AppState*): Resource[Task, GameApp] =
Resource.liftF {
for {
app <- Task(new GameApp(appStates: _*))
_ <- Task {
val settings = new AppSettings(true)
// settings.setVSync(true)
settings.setFrameRate(144)
app.setSettings(settings)
// JMERunner.runner = app
app
}
} yield (app)
}
}

View File

@ -0,0 +1,13 @@
package wow.doge.mygame.game
import wow.doge.mygame.state.MyBaseState
class GameSystemsInitializer extends MyBaseState {
override protected def onEnable(): Unit = {}
override protected def onDisable(): Unit = {}
override protected def init(): Unit = {}
override def stop(): Unit = {}
}

View File

@ -0,0 +1,84 @@
package wow.doge.mygame.game
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.Behaviors
import akka.util.Timeout
import wow.doge.mygame.scriptsystem.ScriptCachingActor
object TestActor {
sealed trait Command
case object Test extends Command
private case object Done extends Command
import scala.concurrent.duration._
implicit val timeout = Timeout(15.seconds)
def apply(
// scriptCacheBehavior: Behavior[ScriptCachingActor.Command]
): Behavior[Command] =
Behaviors.setup { ctx =>
ctx.spawn(ScriptCachingActor(), "scriptCacher")
Behaviors.receiveMessage { msg =>
msg match {
case Test =>
Behaviors.same
case Done => Behaviors.same
}
}
}
def testKotlinScriptCompilation() = {
// ctx.ask(
// router,
// ScriptActor.Compile(
// // os.pwd / "some.sc",
// os.pwd / "src" / "main" / "resources" / "hello2.main.kts",
// _
// )
// ) {
// case Success(value) =>
// ctx.log.debug("Received Value")
// ctx.log.debug(value.toString())
// Done
// case Failure(exception) =>
// ctx.log.debug(s"Received Error ${exception.getMessage()}")
// Done
// }
}
def testTaskWrapper() = {
// val x = scriptStorer
// .askT(
// ScriptStoringActor
// .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
// )(timeout, ctx.system.scheduler)
}
def testScriptCaching() = {
// ctx.ask(
// scriptStorer,
// ScriptStoringActor
// .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
// ) {
// case Success(value) => {
// ctx.log.debug(value.toString())
// ctx.ask(
// scriptStorer,
// ScriptStoringActor
// .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
// ) {
// case Success(value) => {
// ctx.log.debug(value.toString())
// Done
// }
// case Failure(exception) =>
// ctx.log.debug(exception.getMessage())
// Done
// }
// Done
// }
// case Failure(exception) =>
// ctx.log.debug(exception.getMessage())
// Done
// }
}
}

View File

@ -1,4 +1,4 @@
package wow.doge.mygame.state;
package wow.doge.mygame.game.appstates;
import com.jme3.app.state.AbstractAppState;
import com.simsilica.es.EntityData;

View File

@ -8,9 +8,9 @@ import wow.doge.mygame.implicits._
import com.jme3.renderer.Camera
import wow.doge.mygame.math.ImVector3f
trait CanMove[T] {
trait CanMove[-A] {
def getDirection(cam: Camera, cardinalDir: CardinalDirection): ImVector3f
def move(inst: T, direction: ImVector3f): Unit
def move(inst: A, direction: ImVector3f): Unit
}
object ImMovementActor {
@ -40,7 +40,10 @@ object ImMovementActor {
)
def apply[T: CanMove](props: Props[T]): Behavior[Command] =
Behaviors.setup(ctx => new ImMovementActor(ctx, props).receive(State()))
Behaviors.setup(ctx => {
ctx.log.info("Hello from MovementActor")
new ImMovementActor(ctx, props).receive(State())
})
}
@ -71,12 +74,15 @@ class ImMovementActor[T](
val walkDir =
cm.getDirection(props.app.getCamera(), state.cardinalDir)
if (walkDir != ImVector3f.ZERO) {
val tmp = walkDir * 2f
props.app.enqueue(new Runnable {
override def run(): Unit = {
cm.move(props.movable, tmp)
}
})
val tmp = walkDir * 25f * tpf
// props.app.enqueue(new Runnable {
// override def run(): Unit = {
// cm.move(props.movable, tmp)
// }
// })
props.app.enqueueF {
cm.move(props.movable, tmp)
}
}
Behaviors.same
// receive(state = state.modify(_.walkDirection).setTo(walkDir))

View File

@ -7,6 +7,7 @@ import com.jme3.scene.Node
import com.jme3.app.state.BaseAppState
import com.simsilica.es.EntityData
import com.simsilica.es.base.DefaultEntityData
import com.jme3.scene.Spatial
trait MyBaseState extends BaseAppState {
@ -26,17 +27,22 @@ trait MyBaseState extends BaseAppState {
}
protected def init(): Unit
protected def stop(): Unit
override protected def cleanup(app: Application): Unit = {
entityData.close()
// stop()
}
protected def getOrCreateNode(parent: Node, id: String) =
Option(parent.getChild(id)).fold {
val node = new Node(id)
protected def getChildOption(parent: Node, id: String) =
Option(parent.getChild(id))
protected def getOrCreateSpatial(parent: Node, id: String): Spatial =
Option(parent.getChild(id)).getOrElse {
val node: Spatial = new Node(id)
parent.attachChild(node)
node
}(node => node.asInstanceOf[Node])
}
protected def enableStates(classes: Class[_ <: AppState]*) =
setEnabledToStates(true, classes: _*)

View File

@ -1,6 +1,5 @@
package wow.doge.mygame.state
import scala.concurrent.duration.DurationInt
import com.jme3.input.InputManager
@ -17,55 +16,64 @@ import com.jme3.scene.Geometry
import akka.actor.typed.scaladsl.TimerScheduler
import wow.doge.mygame.implicits._
import com.jme3.scene.Node
import com.jme3.syntax._
class PlayerMovementState2(
movementActor: ActorRef[MovementActor.Command],
movementActorTimer: ActorRef[MovementActorTimer.Command],
class PlayerMovementState(
// movementActor: ActorRef[MovementActor.Command],
// movementActorTimer: ActorRef[MovementActorTimer.Command],
imMovementActor: ActorRef[ImMovementActor.Command],
geom: Geometry
// geom: Geometry,
// camNode: CameraNode,
playerNode: Node
// gameAppActor: ActorRef[GameAppActor.Command]
) extends MyBaseState
with ActionListener {
protected lazy val mat = MyMaterial(
assetManager = assetManager,
path = "Common/MatDefs/Misc/Unshaded.j3md"
path = os.rel / "Common" / "MatDefs" / "Misc" / "Unshaded.j3md"
)
override protected[state] def onEnable(): Unit = {}
override protected[state] def onDisable(): Unit = {}
override protected def init(): Unit = {
setupKeys(inputManager)
geom.setMaterial(mat)
rootNode.attachChild(geom)
println("playermovementstate " + Thread.currentThread().getName())
// geom.setMaterial(mat)
// camNode.setControlDir(ControlDirection.SpatialToCamera)
// // lazy val camNode = new CameraNode("CameraNode", simpleApp.getCamera())
// // camNode.setCamera(simpleApp.getCamera())
// discard {
// playerNode
// .child(camNode)
// .child(geom)
// // playerNode.children(Seq(camNode, geom))
// }
discard { rootNode.child(playerNode) }
// camNode.setLocalTranslation(
// new Vector3f(0, 1.5f, 10)
// )
// camNode.lookAt(playerNode.getLocalTranslation(), Vector3f.UNIT_Y)
// movementActorTimer ! MovementActorTimer.Start(geom, cam)
// movementActorTimer ! MovementActorTimer.Start
}
// def system =
// simpleApp.getStateManager.getState(classOf[ActorSystemState]).system
// def player = system.actorSelection("/user/player") //.resolveOne(1.second)
var lastDir: Vector3f = Vector3f.UNIT_X
override def update(tpf: Float) = {
// val direction = new Vector3f()
// direction.multLocal(10 * tpf)
// if (direction.length() > 0f) {
// // player ! PlayerMove(direction)
// lastDir = direction.normalize
// }
// if (shoot) {
// shoot = false
// // player ! Shoot(lastDir)
// }
// movementActor ! MovementActor.Tick(tpf, geom, cam)
imMovementActor ! ImMovementActor.Tick(tpf)
// movementActorTimer ! MovementActorTimer.Update(tpf)
}
override def stop(): Unit = {}
// override protected def cleanup(app: Application): Unit = {
// // gameAppActor ! GameAppActor.Stop
// super.cleanup(app)
// }
def setupKeys(inputManager: InputManager) = {
inputManager
@ -79,33 +87,32 @@ class PlayerMovementState2(
// new KeyTrigger(KeyInput.KEY_D),
new KeyTrigger(KeyInput.KEY_RIGHT)
)
inputManager.addMapping(
"Up",
// new KeyTrigger(KeyInput.KEY_W),
new KeyTrigger(KeyInput.KEY_UP)
)
inputManager.addMapping(
"Down",
// new KeyTrigger(KeyInput.KEY_S),
new KeyTrigger(KeyInput.KEY_DOWN)
)
inputManager.addMapping(
"Space",
new KeyTrigger(KeyInput.KEY_SPACE),
new KeyTrigger(KeyInput.KEY_H)
)
inputManager.addMapping(
"Reset",
new KeyTrigger(KeyInput.KEY_R),
new KeyTrigger(KeyInput.KEY_RETURN)
)
inputManager
.withMapping(
"Up",
// new KeyTrigger(KeyInput.KEY_W),
new KeyTrigger(KeyInput.KEY_UP)
)
.withMapping(
"Down",
// new KeyTrigger(KeyInput.KEY_S),
new KeyTrigger(KeyInput.KEY_DOWN)
)
.withMapping(
"Space",
new KeyTrigger(KeyInput.KEY_SPACE),
new KeyTrigger(KeyInput.KEY_H)
)
.withMapping(
"Reset",
new KeyTrigger(KeyInput.KEY_R),
new KeyTrigger(KeyInput.KEY_RETURN)
)
.withListener(this, "Left")
.withListener(this, "Right")
inputManager.addListener(this, "Up")
inputManager.addListener(this, "Down")
inputManager.addListener(this, "Space")
inputManager.addListener(this, "Reset")
.withListener(this, "Up")
.withListener(this, "Down")
.withListener(this, "Space")
.withListener(this, "Reset")
}
def onAction(binding: String, value: Boolean, tpf: Float) =
@ -118,6 +125,10 @@ class PlayerMovementState2(
case _ =>
}
override protected def onEnable(): Unit = {}
override protected def onDisable(): Unit = {}
}
final case class CardinalDirection(

View File

@ -4,7 +4,6 @@ import ammonite.runtime.Storage.Folder
import ammonite.main.Defaults
import ammonite.Main
import javax.script.ScriptEngine
import com.jme3.app.Application
import com.jme3.app.state.AppState
import akka.actor.typed.scaladsl.AbstractBehavior
import akka.actor.typed.scaladsl.ActorContext
@ -31,10 +30,11 @@ class ScriptingEngineState(
// _
// )
// )
override def stop(): Unit = {}
override protected def cleanup(app: Application): Unit = {
// actorSystem.terminate()
}
// override protected def cleanup(app: Application): Unit = {
// // actorSystem.terminate()
// }
// override protected def initialize(app: Application): Unit = {
// super.initialize(app)

View File

@ -1,6 +1,5 @@
package wow.doge.mygame.state
import com.jme3.app.Application
import wow.doge.mygame.implicits._
import wow.doge.mygame.components.TestComponent
import com.jme3.scene.shape.Box
@ -32,7 +31,7 @@ class TestAppState(
val mat = MyMaterial(
assetManager = assetManager,
path = "Common/MatDefs/Misc/Unshaded.j3md"
path = os.rel / "Common" / "MatDefs" / "Misc" / "Unshaded.j3md"
)
geom.foreach(e => {
e.setMaterial(mat)
@ -45,14 +44,15 @@ class TestAppState(
geom.foreach(_.move(new Vector3f(0, 1 * tpf, 0)))
}
override def cleanup(app: Application): Unit = {
// _entity.map(_.close())
// _entity = None
}
// override def cleanup(app: Application): Unit = {
// // _entity.map(_.close())
// // _entity = None
// }
override def onEnable(): Unit = {}
override def onDisable(): Unit = {}
override def stop(): Unit = {}
}
@ -61,10 +61,10 @@ object MyMaterial {
color: String = "Color",
colorType: com.jme3.math.ColorRGBA = ColorRGBA.Blue,
assetManager: AssetManager,
path: String
path: os.RelPath
): Material = {
val mat =
new Material(assetManager, path)
new Material(assetManager, path.toString())
mat.setColor(color, colorType)
mat
}

View File

@ -0,0 +1,94 @@
package wow.doge.mygame.game.nodes
import com.jme3.scene.Node
import com.jme3.scene.CameraNode
import com.jme3.scene.Geometry
import com.jme3.renderer.Camera
import wow.doge.mygame.implicits._
import com.jme3.asset.AssetManager
import wow.doge.mygame.state.MyMaterial
import com.jme3.math.Vector3f
import com.jme3.scene.control.CameraControl.ControlDirection
import com.jme3.syntax._
import com.jme3.scene.shape.Box
// class PlayerNode(val name: String) extends Node(name) {}
object PlayerNode {
def defaultMesh() = {
lazy val b = new Box(1, 1, 1)
lazy val geom = new Geometry("playerMesh", b)
geom
}
def defaultTexture(assetManager: AssetManager) =
MyMaterial(
assetManager = assetManager,