package nova.monadic_sfx.ui import scala.concurrent.duration._ import cats.effect.Resource import io.odin.Logger import monix.bio.Fiber import monix.bio.Task import monix.execution.CancelablePromise import nova.monadic_sfx.executors.Schedulers import nova.monadic_sfx.ui.DefaultUI import scalafx.application.JFXApp3 import scalafx.application.JFXApp3.PrimaryStage class MyFxApp(val schedulers: Schedulers)(implicit logger: Logger[Task]) { private def internal( startSignal: CancelablePromise[Unit], stopSignal: CancelablePromise[Unit] ) = new JFXApp3 { def start(): Unit = { stage = new PrimaryStage { scene = DefaultUI.scene } startSignal.success(()) } override def stopApp(): Unit = { stopSignal.success(()) } } } object MyFxApp { def resource( schedulers: Schedulers, stage: => PrimaryStage, transitionDelay: FiniteDuration = 500.millis )(implicit logger: Logger[Task] ): Resource[Task, (Task[Unit], Fiber[Throwable, Unit])] = Resource.make(for { _ <- logger.info("Starting FX App") fxApp <- Task(new MyFxApp(schedulers)) startSignal <- Task(CancelablePromise[Unit]()) stopSignal <- Task(CancelablePromise[Unit]()) delegate <- Task(fxApp.internal(startSignal, stopSignal)) fib <- Task(delegate.main(Array.empty)).start.executeOn(schedulers.blocking) _ <- Task.fromCancelablePromise(startSignal) _ <- Task.sleep(transitionDelay) _ <- Task(delegate.stage = stage) .executeOn(schedulers.fx) .delayExecution(transitionDelay) } yield Task.fromCancelablePromise(stopSignal) -> fib) { case _ -> fib => fib.cancel } }