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.

121 lines
3.3 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. package wow.doge.mygame.launcher
  2. import cats.effect.Resource
  3. import cats.effect.concurrent.Deferred
  4. import cats.kernel.Eq
  5. import javafx.application.Platform
  6. import monix.bio.Task
  7. import monix.bio.UIO
  8. import monix.catnap.CancelableF
  9. import monix.execution.CancelablePromise
  10. import monix.reactive.Observable
  11. import monix.{eval => me}
  12. import scalafx.Includes._
  13. import scalafx.application.JFXApp
  14. import scalafx.application.JFXApp.PrimaryStage
  15. import scalafx.scene.control.Button
  16. import scalafx.stage.StageStyle
  17. import wow.doge.mygame.executors.Schedulers.FxScheduler
  18. import wow.doge.mygame.implicits.JavaFXMonixObservables._
  19. import wow.doge.mygame.utils.IOUtils._
  20. object Launcher {
  21. sealed trait LauncherResult
  22. object LauncherResult {
  23. case object LaunchGame extends LauncherResult
  24. case object Exit extends LauncherResult
  25. implicit val eqForLR = Eq.fromUniversalEquals[LauncherResult]
  26. }
  27. class Props(
  28. // val schedulers: Schedulers,
  29. val fxScheduler: FxScheduler,
  30. val signal: Deferred[Task, LauncherResult]
  31. ) {
  32. val create = UIO(new Launcher(this))
  33. }
  34. }
  35. class Launcher private (props: Launcher.Props) {
  36. import Launcher._
  37. private lazy val launchButton = new Button {
  38. text = "Launch"
  39. }
  40. private lazy val launchAction =
  41. launchButton
  42. .observableAction()
  43. .doOnNext(_ => toTask(props.signal.complete(LauncherResult.LaunchGame)))
  44. private lazy val exitButton = new Button {
  45. text = "Exit"
  46. }
  47. private lazy val exitAction =
  48. exitButton
  49. .observableAction()
  50. .doOnNext(_ => toTask(props.signal.complete(LauncherResult.Exit)))
  51. private lazy val _scene =
  52. DefaultUI.scene(launchButton, exitButton)
  53. private lazy val _stage = new PrimaryStage {
  54. scene = _scene
  55. }
  56. private def internal(startSignal: CancelablePromise[Unit]) =
  57. new JFXApp {
  58. stage = _stage
  59. stage.initStyle(StageStyle.Undecorated)
  60. // ResizeHelper.addResizeListener(stage)
  61. startSignal.success(())
  62. }
  63. private lazy val sceneDragObservable = {
  64. val mpo = _scene.observableMousePressed()
  65. val mdo = _scene.observableMouseDragged()
  66. mpo.concatMap(pressEvent =>
  67. mdo.doOnNext(dragEvent =>
  68. me.Task(pprint.log("emitted")) >>
  69. me.Task(
  70. _stage.setX(dragEvent.screenX - pressEvent.sceneX)
  71. ) >>
  72. me.Task(
  73. _stage.setY(
  74. dragEvent.screenY - pressEvent.sceneY
  75. )
  76. )
  77. )
  78. )
  79. }
  80. def init =
  81. Resource.make(for {
  82. _ <- Task(Platform.setImplicitExit(false))
  83. startSignal <- Task(CancelablePromise[Unit]())
  84. delegate <- Task(internal(startSignal))
  85. combinedFib <-
  86. Task
  87. .parZip2(
  88. Task(delegate.main(Array.empty)),
  89. Task.fromCancelablePromise(startSignal) >> toIO(
  90. me.Task.parSequence(
  91. List(
  92. sceneDragObservable.completedL,
  93. Observable(launchAction, exitAction).merge
  94. .doOnNext(_ =>
  95. me.Task(delegate.stage.close())
  96. .executeOn(props.fxScheduler.value)
  97. )
  98. .completedL
  99. )
  100. )
  101. )
  102. )
  103. .start
  104. _ <- Task.fromCancelablePromise(startSignal)
  105. c <- CancelableF[Task](combinedFib.cancel)
  106. } yield c)(_.cancel)
  107. }