Testing out JmonkeyEngine to make a game in Scala with Akka Actors within a pure FP layer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
4.2 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. package wow.doge.mygame.game
  2. import com.jme3.app.SimpleApplication
  3. import com.jme3.app.state.AppState
  4. import monix.execution.{CancelablePromise => Promise}
  5. import monix.execution.CancelableFuture
  6. import monix.bio.Task
  7. import monix.execution.Scheduler
  8. import wow.doge.mygame.executors.GUIExecutorService
  9. import monix.reactive.subjects.ConcurrentSubject
  10. import monix.reactive.MulticastStrategy
  11. import monix.reactive.Observable
  12. import monix.execution.atomic.Atomic
  13. import scala.collection.immutable.Queue
  14. class GameApp(
  15. // actorSystem: ActorSystem[SpawnProtocol.Command],
  16. appStates: AppState*
  17. ) extends SimpleApplication(appStates: _*) {
  18. import GameApp._
  19. // implicit val timeout = Timeout(10.seconds)
  20. // implicit val scheduler = actorSystem.scheduler
  21. // private lazy val taskQueueS = new ConcurrentLinkedQueue[MyTask[_]]()
  22. private lazy val taskQueue2 = Atomic(Queue.empty[MyTask[_]])
  23. private val tickSubject =
  24. ConcurrentSubject[Float](multicast = MulticastStrategy.publish)(
  25. monix.execution.Scheduler.Implicits.global
  26. )
  27. // (scheduler)
  28. override def simpleInitApp(): Unit = {
  29. println("gameapp" + Thread.currentThread().getName())
  30. // val ship = ed.createEntity()
  31. // val mbState = stateManager().state[EntityDataState]().map(_.getEntityData())
  32. // val mbState = Try(
  33. // stateManager()
  34. // .state[TestAppState]()
  35. // .entity
  36. // ).toOption.flatten.toRight(println("empty"))
  37. // // .flatMap(_.entity)
  38. // val x = mbState.flatMap(
  39. // _.query
  40. // .filter[TestComponent]("name", new Object())
  41. // // .filterOr[TestEntity](
  42. // // Filters
  43. // // .fieldEquals(classOf[TestEntity], "", null)
  44. // // )
  45. // .component[Tag]()
  46. // .component[TestComponent]()
  47. // .result
  48. // .toRight(println("failed"))
  49. // )
  50. // rootNode
  51. // .child(geom)
  52. // .child(geom)
  53. // .child(geom)
  54. // .child(geom)
  55. // .child(geom)
  56. // .child(geom)
  57. // .child(geom)
  58. // .child(geom)
  59. // Future(println("hello"))(jmeEC(this))
  60. // val wbActor: Future[ActorRef[Greeter.Greet]] = actorSystem.ask(
  61. // SpawnProtocol.Spawn(
  62. // behavior = Greeter(),
  63. // name = "listener",
  64. // DispatcherSelector.fromConfig("jme-dispatcher"),
  65. // _
  66. // )
  67. // )
  68. // wbActor.map(a => a.ask(Greeter.Greet("hello", _)).map(println))
  69. }
  70. def tickObservable: Observable[Float] = tickSubject
  71. override def simpleUpdate(tpf: Float): Unit = {
  72. // val rot2 = rot.fromAngleAxis(FastMath.PI, new Vector3f(0, 0, 1))
  73. // val rotation = geom.getLocalRotation()
  74. // rotation.add(rot2)
  75. // geom.rotate(rot2)
  76. // geom.updateModelBound()
  77. // geom.updateGeometricState()
  78. tickSubject.onNext(tpf)
  79. }
  80. override def stop(): Unit = {
  81. tickSubject.onComplete()
  82. super.stop()
  83. }
  84. def enqueueScala[T](cb: () => T): CancelableFuture[T] = {
  85. val p = Promise[T]()
  86. // p.success(cb())
  87. // taskQueueS.add(MyTask(p, cb))
  88. taskQueue2.transform(_ :+ MyTask(p, cb))
  89. p.future
  90. }
  91. // taskQueue2.transform(_ :+ MyTask(p, cb))
  92. // p
  93. def enqueueL[T](cb: () => T): Task[T] =
  94. // Task(Promise[T]()).flatMap { p =>
  95. // Task(taskQueue2.transform(_ :+ MyTask(p, cb))) >>
  96. // Task.fromCancelablePromise(p)
  97. // }
  98. // Task.fromCancelablePromise {
  99. // val p = Promise[T]()
  100. // taskQueue2.transform(_ :+ MyTask(p, cb))
  101. // p
  102. // }
  103. Task.deferFuture(enqueueScala(cb))
  104. // taskQueueS.add(MyTask(p, cb))
  105. override protected def runQueuedTasks(): Unit = {
  106. // Option(taskQueueS.poll()).foreach {
  107. // case MyTask(p, cb) =>
  108. // p.success(cb())
  109. // }
  110. taskQueue2.transform { current =>
  111. current.dequeueOption.fold(current) {
  112. case (MyTask(p, cb), updated) =>
  113. p.success(cb())
  114. updated
  115. }
  116. }
  117. super.runQueuedTasks()
  118. }
  119. object JMEExecutorService extends GUIExecutorService {
  120. override def execute(command: Runnable) =
  121. enqueue(command)
  122. // new SingleThreadEventExecutor()
  123. // sys.addShutdownHook(JMEExecutorService.shutdown())
  124. }
  125. lazy val scheduler = Scheduler(JMEExecutorService)
  126. }
  127. object GameApp {
  128. private[game] case class MyTask[T](p: Promise[T], cb: () => T)
  129. }