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.

104 lines
2.7 KiB

  1. package wow.doge.mygame.launcher
  2. import scala.concurrent.duration.FiniteDuration
  3. import scala.concurrent.duration._
  4. import cats.effect.concurrent.Deferred
  5. import javafx.application.Platform
  6. import monix.bio.Task
  7. import monix.catnap.CancelableF
  8. import monix.eval.{Task => ETask}
  9. import monix.reactive.Observable
  10. import scalafx.Includes._
  11. import scalafx.application.JFXApp
  12. import scalafx.application.JFXApp.PrimaryStage
  13. import scalafx.scene.control.Button
  14. import scalafx.stage.StageStyle
  15. import wow.doge.mygame.executors.Schedulers
  16. import wow.doge.mygame.implicits.JavaFXMonixObservables._
  17. import wow.doge.mygame.utils.IOUtils._
  18. object Launcher {
  19. sealed trait LauncherResult
  20. object LauncherResult {
  21. case object LaunchGame extends LauncherResult
  22. case object Exit extends LauncherResult
  23. }
  24. class Props(
  25. val schedulers: Schedulers,
  26. val signal: Deferred[Task, LauncherResult]
  27. ) {
  28. val create = Task(new Launcher(this))
  29. }
  30. }
  31. class Launcher private (props: Launcher.Props) {
  32. import Launcher._
  33. private lazy val launchButton = new Button {
  34. text = "Launch"
  35. }
  36. private lazy val launchAction =
  37. launchButton
  38. .observableAction()
  39. .doOnNext(_ => toTask(props.signal.complete(LauncherResult.LaunchGame)))
  40. private lazy val exitButton = new Button {
  41. text = "Exit"
  42. }
  43. private lazy val exitAction =
  44. exitButton
  45. .observableAction()
  46. .doOnNext(_ => toTask(props.signal.complete(LauncherResult.Exit)))
  47. private lazy val _scene =
  48. DefaultUI.scene(launchButton, exitButton)
  49. private lazy val _stage = new PrimaryStage {
  50. scene = _scene
  51. }
  52. private lazy val internal = new JFXApp {
  53. stage = _stage
  54. stage.initStyle(StageStyle.Undecorated)
  55. // ResizeHelper.addResizeListener(stage)
  56. }
  57. private lazy val sceneDragObservable = {
  58. lazy val mpo = _scene.observableMousePressed()
  59. lazy val mdo = _scene.observableMouseDragged()
  60. mpo.mergeMap(pressEvent =>
  61. mdo.doOnNext(dragEvent =>
  62. ETask(
  63. _stage.setX(dragEvent.screenX - pressEvent.sceneX)
  64. ) >>
  65. ETask(
  66. _stage.setY(
  67. dragEvent.screenY - pressEvent.sceneY
  68. )
  69. )
  70. )
  71. )
  72. }
  73. def init(delay: FiniteDuration = 2000.millis) =
  74. for {
  75. _ <- Task(Platform.setImplicitExit(false))
  76. fib <- Task(internal.main(Array.empty)).start
  77. _ <- Task.sleep(500.millis)
  78. sceneDragFib <- toIO(sceneDragObservable.completedL).start
  79. fib2 <- toIO(
  80. Observable(launchAction, exitAction).merge
  81. .doOnNext(_ =>
  82. ETask(internal.stage.close()).executeOn(props.schedulers.fx)
  83. )
  84. .completedL
  85. ).start
  86. c <- CancelableF[Task](fib.cancel >> fib2.cancel >> sceneDragFib.cancel)
  87. } yield (c)
  88. }