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.
 
 

121 lines
3.3 KiB

package wow.doge.mygame.launcher
import cats.effect.Resource
import cats.effect.concurrent.Deferred
import cats.kernel.Eq
import javafx.application.Platform
import monix.bio.Task
import monix.bio.UIO
import monix.catnap.CancelableF
import monix.execution.CancelablePromise
import monix.reactive.Observable
import monix.{eval => me}
import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.scene.control.Button
import scalafx.stage.StageStyle
import wow.doge.mygame.executors.Schedulers.FxScheduler
import wow.doge.mygame.implicits.JavaFXMonixObservables._
import wow.doge.mygame.utils.IOUtils._
object Launcher {
sealed trait LauncherResult
object LauncherResult {
case object LaunchGame extends LauncherResult
case object Exit extends LauncherResult
implicit val eqForLR = Eq.fromUniversalEquals[LauncherResult]
}
class Props(
// val schedulers: Schedulers,
val fxScheduler: FxScheduler,
val signal: Deferred[Task, LauncherResult]
) {
val create = UIO(new Launcher(this))
}
}
class Launcher private (props: Launcher.Props) {
import Launcher._
private lazy val launchButton = new Button {
text = "Launch"
}
private lazy val launchAction =
launchButton
.observableAction()
.doOnNext(_ => toTask(props.signal.complete(LauncherResult.LaunchGame)))
private lazy val exitButton = new Button {
text = "Exit"
}
private lazy val exitAction =
exitButton
.observableAction()
.doOnNext(_ => toTask(props.signal.complete(LauncherResult.Exit)))
private lazy val _scene =
DefaultUI.scene(launchButton, exitButton)
private lazy val _stage = new PrimaryStage {
scene = _scene
}
private def internal(startSignal: CancelablePromise[Unit]) =
new JFXApp {
stage = _stage
stage.initStyle(StageStyle.Undecorated)
// ResizeHelper.addResizeListener(stage)
startSignal.success(())
}
private lazy val sceneDragObservable = {
val mpo = _scene.observableMousePressed()
val mdo = _scene.observableMouseDragged()
mpo.concatMap(pressEvent =>
mdo.doOnNext(dragEvent =>
me.Task(pprint.log("emitted")) >>
me.Task(
_stage.setX(dragEvent.screenX - pressEvent.sceneX)
) >>
me.Task(
_stage.setY(
dragEvent.screenY - pressEvent.sceneY
)
)
)
)
}
def init =
Resource.make(for {
_ <- Task(Platform.setImplicitExit(false))
startSignal <- Task(CancelablePromise[Unit]())
delegate <- Task(internal(startSignal))
combinedFib <-
Task
.parZip2(
Task(delegate.main(Array.empty)),
Task.fromCancelablePromise(startSignal) >> toIO(
me.Task.parSequence(
List(
sceneDragObservable.completedL,
Observable(launchAction, exitAction).merge
.doOnNext(_ =>
me.Task(delegate.stage.close())
.executeOn(props.fxScheduler.value)
)
.completedL
)
)
)
)
.start
_ <- Task.fromCancelablePromise(startSignal)
c <- CancelableF[Task](combinedFib.cancel)
} yield c)(_.cancel)
}