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.

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