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.
 
 

153 lines
4.5 KiB

package wow.doge.mygame.launcher
import scala.concurrent.duration.FiniteDuration
import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import wow.doge.mygame.executors.Schedulers
import cats.effect.Resource
import monix.bio.Task
import scala.concurrent.duration._
import javafx.application.Platform
import scalafx.scene.control.Button
import cats.effect.concurrent.Deferred
import wow.doge.mygame.utils.IOUtils._
import monix.eval.{Task => ETask}
import monix.reactive.Observable
import monix.bio.Fiber
import scalafx.stage.StageStyle
import scalafx.Includes._
import wow.doge.mygame.utils.ResizeHelper
import scalafx.scene.Scene
import scalafx.scene.layout.VBox
import wow.doge.mygame.implicits.JavaFXMonixObservables._
import monix.catnap.cancelables.SingleAssignCancelableF
import monix.catnap.CancelableF
// import wow.doge.mygame.implicits.JavaFXMonixObservables._
// import scala.language.implicitConversions
// object Stage {
// implicit def sfxStage2jfx(v: Stage): jfxs.Stage = if (v != null) v.delegate else null
// }
object Launcher {
sealed trait LauncherResult
object LauncherResult {
case object LaunchGame extends LauncherResult
case object Exit extends LauncherResult
}
class Props(
val schedulers: Schedulers,
val signal: Deferred[Task, LauncherResult]
) {
// val resource2
// : Resource[Task, (LauncherApp, Task[Ref[Task, Stage]], Fiber[Unit])] =
// Resource.make(for {
// app <- Task(new LauncherApp(this))
// fib <- app.init.start
// } yield ((app, app.stageRef, fib)))(_._3.cancel)
val create = Task(new Launcher(this))
val resource: Resource[Task, Launcher] =
Resource.make(for {
app <- Task(new Launcher(this))
// fib <- app.init.start
} yield (app))(_ => Task.unit)
}
}
class Launcher private (props: Launcher.Props) {
import Launcher._
private lazy val launchButton = new Button {
text = "Launch"
}
// private lazy val launchButtonObs =
private lazy val launchAction =
launchButton
.observableAction()
.doOnNext(_ => toTask(props.signal.complete(LauncherResult.LaunchGame)))
private lazy val exitButton = new Button {
text = "Exit"
}
// private lazy val exitButtonObs =
private lazy val exitAction =
exitButton
.observableAction()
.doOnNext(_ => toTask(props.signal.complete(LauncherResult.Exit)))
private lazy val _scene =
// new Scene {
// content = new VBox
// }
DefaultUI.scene(launchButton, exitButton)
private lazy val _stage = new PrimaryStage {
scene = _scene
}
private lazy val internal = new JFXApp {
stage = _stage
stage.initStyle(StageStyle.Undecorated)
// ResizeHelper.addResizeListener(stage)
}
private lazy val sceneDragObservable = {
lazy val mpo = _scene.observableMousePressed()
lazy val mdo = _scene.observableMouseDragged()
mpo.mergeMap(pressEvent =>
mdo.doOnNext(dragEvent =>
ETask(
_stage.setX(dragEvent.screenX - pressEvent.sceneX)
) >>
ETask(
_stage.setY(
dragEvent.screenY - pressEvent.sceneY
)
)
)
)
}
// var stage = internal.stage
// lazy val stageRef = Ref.of[Task, Stage](internal.stage)
// stage: => PrimaryStage
def init(delay: FiniteDuration = 2000.millis) =
for {
_ <- Task(Platform.setImplicitExit(false))
fib <- Task(internal.main(Array.empty)).start
_ <- Task.sleep(500.millis)
// _ <- Task {
// // lazy val _stage = new CustomStageBuilder()
// // .setWindowTitle("CustomStage example")
// // .setWindowColor("rgb(34,54,122)")
// // .build()
// internal.stage.scene =
// DefaultUI.scene(internal.stage, launchButton, exitButton)
// // _stage.setScene(DefaultUI.scene(launchButton, exitButton))
// // JFXApp.Stage = _stage
// }.executeOn(props.schedulers.fx)
// c <- SingleAssignCancelableF[Task]
sceneDragFib <- toIO(sceneDragObservable.completedL).start
fib2 <- toIO(
Observable(launchAction, exitAction).merge
.doOnNext(_ =>
ETask(internal.stage.close()).executeOn(props.schedulers.fx)
)
// .doOnNext(_ => toTask(fib.cancel))
.completedL
).start
c <- CancelableF[Task](fib.cancel >> fib2.cancel >> sceneDragFib.cancel)
// _ <- Task {
// internal.stage = stage
// }.executeOn(props.schedulers.fx)
// .delayExecution(delay)
} yield (c)
}