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) }