From 02c4e2f2f3cd8612621f77c2368705537d592317 Mon Sep 17 00:00:00 2001 From: Rohan Sircar Date: Sat, 29 Aug 2020 21:07:19 +0530 Subject: [PATCH] Converted Main class to Task/Resource Converted Main class to TaskApp with resources created using Resource monad --- src/main/scala/nova/monadic_sfx/Main.scala | 309 +++++++++------------ 1 file changed, 125 insertions(+), 184 deletions(-) diff --git a/src/main/scala/nova/monadic_sfx/Main.scala b/src/main/scala/nova/monadic_sfx/Main.scala index 6bea7a9..b8372eb 100644 --- a/src/main/scala/nova/monadic_sfx/Main.scala +++ b/src/main/scala/nova/monadic_sfx/Main.scala @@ -31,198 +31,139 @@ import io.odin.syntax._ import io.odin.monix._ import nova.monadic_sfx.pages.HomePage import monix.execution.Callback - -object Main extends JFXApp with MainModule { - - val logger = consoleLogger().withAsyncUnsafe() - - lazy val schedulers: Schedulers = new Schedulers() - - implicit lazy val defaultScheduler: Scheduler = schedulers.fx - - lazy val backendTask = AsyncHttpClientMonixBackend() - lazy val actorSystemTask = Task { - classic.ActorSystem( - name = "FXActorSystem" - ) - } - - lazy val application = for { - _ <- logger.info("Starting application..") - backend <- backendTask - actorSystem <- actorSystemTask - // to spawn child actors - // _ <- Task { actorSystem.spawn() } - appStage <- Task { makePrimaryStage(backend, actorSystem) } - // splash screen - _ <- Task { - // this stage refers to implicit jfx stage - // makes this impure, but I can't think of a better way right now - stage = appStage - } - // wait 2 seconds before showing home screen - // d <- deps - // fib1 <- d.send().start - _ <- Task.sleep(2.seconds) - loginScene <- LoginPage(appStage, backend, actorSystem) - _ <- Task { - // appStage.maximized = true - appStage.height = 800 - appStage.width = 800 - appStage - .scene() - .setRoot( - loginScene - ) - } - // _ <- fib1.join - } yield () - 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" +import monix.eval.TaskApp +import cats.effect.ExitCode +import scalafx.scene.layout.HBox +import scalafx.scene.Scene +import cats.implicits._ +import cats.effect.Clock +import cats.effect.Sync + +object Main extends TaskApp { + + // lazy val schedulers: Schedulers = new Schedulers() + // override implicit def scheduler: Scheduler = schedulers.fx + override def run(args: List[String]): Task[ExitCode] = { + // val logger = consoleLogger().withAsyncUnsafe() + + // lazy val backendTask = AsyncHttpClientMonixBackend() + // lazy val actorSystemTask = Task { + // classic.ActorSystem( + // name = "FXActorSystem" + // ) + // } + + // implicit lazy val FSync = Sync[Task] + // implicit lazy val FClock = Clock[Task] + // val startTime = Task.clock + // .monotonic(scala.concurrent.duration.MILLISECONDS) + // .map(Duration.fromNanos(_)) + lazy val appResource = for { + // clock <- Resource.liftF(Task(Task.clock)) + logger <- consoleLogger().withAsync() + backend <- AsyncHttpClientMonixBackend.resource() + actorSystem <- + Resource.make(logger.info("Creating Actor System") >> Task { + classic.ActorSystem( + name = "FXActorSystem" + ) + })(sys => + logger.info("Shutting down actor system") >> Task.fromFuture( + sys.terminate() + ) >> logger.info("Actor System terminated") ) - } - - override def onError(e: Throwable): Unit = { - println("Application start failed. Reason -") - e.printStackTrace() - } - - } - ) - - // Task - // .suspend { - // val program = Task { - // stage = new PrimaryStage { - // // initStyle(StageStyle.Unified) - // title = "ScalaFX Hello World" - // scene = defaultUI.scene - - // } - // } - - // val backendResource = AsyncHttpClientMonixBackend - // .resource() - // .use { implicit backend => - // Task - // .suspend( - // (for { - // req <- - // basicRequest - // .get(uri"https://httpbin.org/get") - // .response(asJson[HttpBinResponse]) - // .send() - // } yield println(req)) >> - // Task(println(Thread.currentThread().getName())) - // ) - // // .delayExecution(1.second) - // } - // .executeOn(Scheduler.global) - // val akkaResource = Resource - // .make(Task { - // classic.ActorSystem( - // name = "FXActorSystem" - // ) - // })(sys => Task(println("Shutting down actor system")) >> Task(sys.terminate())) - // .use { implicit system => - // // system.spa - // // system.typed - // // val javaFxActor = system.actorOf( - // // Props[JavaFxActor]().withDispatcher("javafx-dispatcher"), - // // "javaFxActor" - // // ) - // // val swingActor = system.actorOf( - // // Props[SwingActor]().withDispatcher("swing-dispatcher"), - // // "swingActor" - // // ) - // Task.unit - // } - // .delayExecution(1.second) - // backendResource.start >> akkaResource.start >> - // program.to[Task].asyncBoundary >> - // Task(println(Thread.currentThread().getName())) - // .executeOn(Scheduler.global) - // Task.parZip3( - // program.to[Task].executeOn(defaultScheduler), - // // backendResource, - // // dummyRequester.send(), - // // akkaResource, - // Task(println(Thread.currentThread().getName())) - // .executeOn(schedulers.cpu) - // ) - // } - // .runToFuture - // .onComplete(res => - // res match { - // case Failure(exception) => { - // println("Application start failed. Reason -") - // exception.printStackTrace() - // } - // case Success(value) => println("Application started Successfully") - // } - // ) - - // new TaskApp { - // override protected def scheduler: Scheduler = - // JFXExecutionContexts.javaFxScheduler - // override def run(args: List[String]): Task[ExitCode] = - // Task.suspend { - // Task { - // AsyncHttpClientMonixBackend().flatMap(implicit backend => { - // val req = RequestPayload("").asJson - // basicRequest.get(uri"").body(req).send() - // }) - // } >> - // program.to[Task].executeOn(JFXExecutionContexts.javaFxScheduler) >> - // Task(println(Thread.currentThread().getName())) - // .executeOn(Scheduler.global) >> - // // Task.unit.asyncBoundary >> - // Task.pure(ExitCode.Success) - // } - // } -// } - -// Task.sleep(3.seconds).flatMap { _ => -// -// (for { -// req <- -// basicRequest -// .get(uri"https://httpbin.org/get") -// .response(asJson[HttpBinResponse]) -// .send() -// } yield println(req)) >> Task( -// println(Thread.currentThread().getName()) -// ) >> -// backend.close() -// } -// - def test(stage: Stage) = { - stage.scene().setRoot(new FlowPane()) + // _ <- Resource.liftF(logger.info(Thread.currentThread().getName())) + fxApp <- Resource.make(logger.info("Creating FX Application") >> Task { + // val appStage = makePrimaryStage(backend, actorSystem) + // stage = appStage + // val stage2 = new PrimaryStage { + // scene = new Scene(new HBox()) + // } + val app: JFXApp = new JFXApp { + lazy val schedulers: Schedulers = new Schedulers() + + implicit lazy val defaultScheduler: Scheduler = schedulers.fx + + val application = + for { + appStage <- logger.info("Inside JFX application stage") >> Task( + makePrimaryStage(backend, actorSystem) + ) + _ <- Task { stage = appStage } + _ <- Task.sleep(2.seconds) + loginScene <- LoginPage(appStage, backend, actorSystem) + _ <- Task { + // appStage.maximized = true + appStage.height = 800 + appStage.width = 800 + appStage + .scene() + .setRoot( + loginScene + ) + } + } yield () + 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() + } + + } + ) + + override def stopApp() = { + Platform.exit() + // System.exit(0) + } + } + app + })(app => logger.info("Stopping FX Application") >> Task(app.stopApp())) + // _ <- Resource.liftF(Task.unit.executeOn(defaultScheduler)) + _ <- Resource.liftF(logger.info(Thread.currentThread().getName())) + } yield (fxApp) +// >> logger.info("test") + appResource + .use(fxApp => Task(fxApp.main(args.toArray))) + .as(ExitCode.Success) } + def makePrimaryStage( backend: AppTypes.HttpBackend, actorSystem: classic.ActorSystem ) = { new PrimaryStage { scene = new DefaultUI().scene - onCloseRequest = () => { - val f2 = actorSystem.terminate() - val f1 = backend.close().runToFuture - - println("Closing backend") - Await.result(f1, 3.seconds) - println("Closing actor system") - println(Thread.currentThread().getName()) - Await.result(f2, 3.seconds) - println("Actor system closed") - Platform.exit() - System.exit(0) - } + // onCloseRequest = () => { + // val f2 = actorSystem.terminate() + // val f1 = backend.close().runToFuture + + // println("Closing backend") + // Await.result(f1, 3.seconds) + // println("Closing actor system") + // println(Thread.currentThread().getName()) + // Await.result(f2, 3.seconds) + // println("Actor system closed") + // Platform.exit() + // System.exit(0) + // } } } } + +// class MyFxApp extends javafx.application.Application { + +// override def start(stage: javafx.stage.Stage): Unit = { +// stage.show() +// } + +// }