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.

132 lines
3.4 KiB

  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 SimpleAppExt(
  16. schedulers: Schedulers,
  17. appStates: AppState*
  18. ) extends SimpleApplication(appStates: _*) {
  19. import SimpleAppExt._
  20. /**
  21. * A non blocking synchronized queue using an immutable scala queue and monix's atomic class
  22. */
  23. private lazy val taskQueue2 = Atomic(Queue.empty[MyTask[_]])
  24. private val tickSubject =
  25. ConcurrentSubject[Float](multicast = MulticastStrategy.publish)(
  26. schedulers.async
  27. )
  28. def tickObservable: Observable[Float] = tickSubject
  29. override def simpleInitApp(): Unit = {}
  30. override def simpleUpdate(tpf: Float): Unit = {
  31. tickSubject.onNext(tpf)
  32. }
  33. override def stop(): Unit = {
  34. tickSubject.onComplete()
  35. super.stop()
  36. }
  37. def enqueueScala[T](cb: () => T): CancelableFuture[T] = {
  38. val p = Promise[T]()
  39. taskQueue2.transform(_ :+ MyTask(p, cb))
  40. p.future
  41. }
  42. def enqueueL[T](cb: () => T): Task[T] =
  43. Task.deferFuture(enqueueScala(cb))
  44. override protected def runQueuedTasks(): Unit = {
  45. taskQueue2.transform { current =>
  46. current.dequeueOption.fold(current) {
  47. case (MyTask(p, cb), updated) =>
  48. p.success(cb())
  49. updated
  50. }
  51. }
  52. super.runQueuedTasks()
  53. }
  54. object JMEExecutorService extends GUIExecutorService {
  55. override def execute(command: Runnable): Unit =
  56. enqueueScala(() => command.run())
  57. // enqueue(command)
  58. // new SingleThreadEventExecutor()
  59. // sys.addShutdownHook(JMEExecutorService.shutdown())
  60. }
  61. lazy val scheduler = Scheduler(JMEExecutorService)
  62. }
  63. object SimpleAppExt {
  64. private[game] case class MyTask[T](p: Promise[T], cb: () => T)
  65. }
  66. // val ship = ed.createEntity()
  67. // val mbState = stateManager().state[EntityDataState]().map(_.getEntityData())
  68. // val mbState = Try(
  69. // stateManager()
  70. // .state[TestAppState]()
  71. // .entity
  72. // ).toOption.flatten.toRight(println("empty"))
  73. // // .flatMap(_.entity)
  74. // val x = mbState.flatMap(
  75. // _.query
  76. // .filter[TestComponent]("name", new Object())
  77. // // .filterOr[TestEntity](
  78. // // Filters
  79. // // .fieldEquals(classOf[TestEntity], "", null)
  80. // // )
  81. // .component[Tag]()
  82. // .component[TestComponent]()
  83. // .result
  84. // .toRight(println("failed"))
  85. // )
  86. // rootNode
  87. // .child(geom)
  88. // .child(geom)
  89. // .child(geom)
  90. // .child(geom)
  91. // .child(geom)
  92. // .child(geom)
  93. // .child(geom)
  94. // .child(geom)
  95. // Future(println("hello"))(jmeEC(this))
  96. // val wbActor: Future[ActorRef[Greeter.Greet]] = actorSystem.ask(
  97. // SpawnProtocol.Spawn(
  98. // behavior = Greeter(),
  99. // name = "listener",
  100. // DispatcherSelector.fromConfig("jme-dispatcher"),
  101. // _
  102. // )
  103. // )
  104. // wbActor.map(a => a.ask(Greeter.Greet("hello", _)).map(println))
  105. // Task(Promise[T]()).flatMap { p =>
  106. // Task(taskQueue2.transform(_ :+ MyTask(p, cb))) >>
  107. // Task.fromCancelablePromise(p)
  108. // }
  109. // Task.fromCancelablePromise {
  110. // val p = Promise[T]()
  111. // taskQueue2.transform(_ :+ MyTask(p, cb))
  112. // p
  113. // }