diff --git a/src/main/scala/nova/monadic_sfx/Main.scala b/src/main/scala/nova/monadic_sfx/Main.scala index 8bc2aca..6bea7a9 100644 --- a/src/main/scala/nova/monadic_sfx/Main.scala +++ b/src/main/scala/nova/monadic_sfx/Main.scala @@ -30,6 +30,7 @@ import io.odin.syntax._ // import io.odin._ import io.odin.monix._ import nova.monadic_sfx.pages.HomePage +import monix.execution.Callback object Main extends JFXApp with MainModule { @@ -60,9 +61,10 @@ object Main extends JFXApp with MainModule { stage = appStage } // wait 2 seconds before showing home screen - d <- deps - fib1 <- d.send().start + // d <- deps + // fib1 <- d.send().start _ <- Task.sleep(2.seconds) + loginScene <- LoginPage(appStage, backend, actorSystem) _ <- Task { // appStage.maximized = true appStage.height = 800 @@ -70,24 +72,28 @@ object Main extends JFXApp with MainModule { appStage .scene() .setRoot( - LoginPage(appStage, backend, actorSystem) + loginScene ) } // _ <- fib1.join } yield () - application.timed.runToFuture - .onComplete(res => - res match { - case Failure(exception) => { - println("Application start failed. Reason -") - exception.printStackTrace() - } - case Success((duration, _)) => - println( - s"Application started successfully in ${duration.toSeconds} seconds" - ) + application.timed.runAsync( + new Callback[Throwable, (FiniteDuration, Unit)] { + + override def onSuccess(value: (FiniteDuration, Unit)): Unit = { + val (duration, _) = value + println( + s"Application started successfully in ${duration.toSeconds} seconds" + ) } - ) + + override def onError(e: Throwable): Unit = { + println("Application start failed. Reason -") + e.printStackTrace() + } + + } + ) // Task // .suspend { diff --git a/src/main/scala/nova/monadic_sfx/pages/LoginPage.scala b/src/main/scala/nova/monadic_sfx/pages/LoginPage.scala index 66a1c7a..cb76bfc 100644 --- a/src/main/scala/nova/monadic_sfx/pages/LoginPage.scala +++ b/src/main/scala/nova/monadic_sfx/pages/LoginPage.scala @@ -7,6 +7,9 @@ import scalafx.scene.Node import scalafx.Includes._ import scalafx.scene.Parent import scalafx.application.JFXApp.PrimaryStage +import nova.monadic_sfx.http.requests.DummyRequest +import monix.eval.Task +import monix.execution.Scheduler // import io.odin.syntax._ // import _root_.monix.eval.Task // import io.odin.monix._ @@ -18,33 +21,75 @@ class LoginPage( system: akka.actor.ActorSystem ) { + val dummyRequester = new DummyRequest(backend) + //pure function callbacks, but with side effects still - private def onLogout(stage: PrimaryStage) = { - println("logging out") - stage.scene().setRoot(render) - } - private def onLogin(stage: PrimaryStage) = { - println("logging in") - stage - .scene() - .setRoot(HomePage(backend, system, () => onLogout(appStage))) - } - private lazy val root = new VBox { - children = Seq( - new TextField { - text = "username" - editable = true - }, - new TextField { - text = "password" - }, - new Button { - text = "Login" - onAction = () => onLogin(appStage) + private def onLogout(stage: PrimaryStage) = + for { + _ <- Task { println("logging out") } + root <- render + _ <- Task(stage.scene().setRoot(root)) + } yield () + + private def onLogin(stage: PrimaryStage) = + Task.deferAction { implicit Scheduler => + for { + _ <- Task(println("logging in")) + root <- Task { + stage + .scene() + .setRoot( + HomePage( + backend, + system, + () => runFxTask(onLogout(appStage)) + ) + ) + } + } yield () + } + + private lazy val root = Task.deferAction(implicit scheduler => + Task { + new VBox { + children = Seq( + new Label { + text = "username" + }, + new TextField(), + new Label { + text = "password" + }, + new TextField(), + new Button { + text = "Login" + onAction = () => + runFxTask { + Task + .parZip2( + dummyRequester + .send(), + // .executeOn(Scheduler.global) + onLogin(appStage) + ) + } + } + ) } - ) + } + ) + def render: Task[Parent] = root + + /** + * Implicitly runs monix task as fire and forget. \ + * For use in ScalaFX callbacks. + * + * @param task + * @param s + */ + def runFxTask[T](task: => Task[T])(implicit s: Scheduler) = { + task.runAsyncAndForget } - def render: Parent = root }