|
|
@ -1,19 +1,22 @@ |
|
|
|
package wow.doge.mygame |
|
|
|
|
|
|
|
import java.util.concurrent.TimeoutException |
|
|
|
|
|
|
|
import scala.concurrent.duration._ |
|
|
|
|
|
|
|
import akka.actor.typed.ActorRef |
|
|
|
import akka.actor.typed.ActorSystem |
|
|
|
import akka.actor.typed.Scheduler |
|
|
|
import akka.actor.typed.SpawnProtocol |
|
|
|
import akka.util.Timeout |
|
|
|
import cats.effect.Resource |
|
|
|
import cats.effect.concurrent.Deferred |
|
|
|
import cats.syntax.eq._ |
|
|
|
import com.jme3.app.state.AppStateManager |
|
|
|
import com.jme3.asset.plugins.ZipLocator |
|
|
|
import com.jme3.bullet.control.BetterCharacterControl |
|
|
|
import com.jme3.input.InputManager |
|
|
|
import com.jme3.material.Material |
|
|
|
import com.jme3.material.MaterialDef |
|
|
|
import com.jme3.math.ColorRGBA |
|
|
|
import com.jme3.math.FastMath |
|
|
|
import com.jme3.renderer.Camera |
|
|
|
import com.jme3.renderer.RenderManager |
|
|
@ -27,6 +30,8 @@ import monix.bio.Fiber |
|
|
|
import monix.bio.IO |
|
|
|
import monix.bio.Task |
|
|
|
import monix.bio.UIO |
|
|
|
import monix.eval.Coeval |
|
|
|
import monix.reactive.Observable |
|
|
|
import scalafx.scene.control.TextArea |
|
|
|
import wow.doge.mygame.executors.Schedulers |
|
|
|
import wow.doge.mygame.game.GameApp |
|
|
@ -45,23 +50,20 @@ import wow.doge.mygame.implicits._ |
|
|
|
import wow.doge.mygame.launcher.Launcher |
|
|
|
import wow.doge.mygame.launcher.Launcher.LauncherResult |
|
|
|
import wow.doge.mygame.math.ImVector3f |
|
|
|
import wow.doge.mygame.subsystems.events.EventBus.ObservableSubscription |
|
|
|
import wow.doge.mygame.subsystems.events.EventsModule |
|
|
|
import wow.doge.mygame.subsystems.events.EventsModule.GameEventBus |
|
|
|
import wow.doge.mygame.subsystems.events.PlayerEvent |
|
|
|
import wow.doge.mygame.subsystems.events.PlayerMovementEvent |
|
|
|
import wow.doge.mygame.subsystems.events.TickEvent |
|
|
|
import wow.doge.mygame.subsystems.scriptsystem.ScriptInitMode |
|
|
|
import wow.doge.mygame.subsystems.scriptsystem.ScriptSystemResource |
|
|
|
import wow.doge.mygame.utils.AkkaUtils |
|
|
|
import wow.doge.mygame.utils.GenericConsoleStream |
|
|
|
import wow.doge.mygame.utils.wrappers.jme.AppNode |
|
|
|
import wow.doge.mygame.utils.IOUtils |
|
|
|
import wow.doge.mygame.utils.wrappers.jme.AppNode2 |
|
|
|
import wow.doge.mygame.utils.wrappers.jme.AssetManager |
|
|
|
import wow.doge.mygame.utils.wrappers.jme.PhysicsSpace |
|
|
|
import wow.doge.mygame.subsystems.events.EventBus.ObservableSubscription |
|
|
|
import wow.doge.mygame.subsystems.events.PlayerMovementEvent |
|
|
|
import monix.reactive.Observable |
|
|
|
import monix.eval.Coeval |
|
|
|
import wow.doge.mygame.utils.IOUtils |
|
|
|
import com.jme3.math.ColorRGBA |
|
|
|
|
|
|
|
class MainApp( |
|
|
|
logger: Logger[Task], |
|
|
@ -84,53 +86,66 @@ class MainApp( |
|
|
|
tickEventBus: GameEventBus[TickEvent] |
|
|
|
) |
|
|
|
|
|
|
|
def gameInit: Resource[Task, Fiber[Throwable, Unit]] = |
|
|
|
wire[GameAppResource].resource.evalMap { |
|
|
|
case gameApp -> gameAppFib => |
|
|
|
for { |
|
|
|
playerEventBus <- eventsModule.playerEventBusTask |
|
|
|
mainEventBus <- eventsModule.mainEventBusTask |
|
|
|
tickEventBus <- eventsModule.tickEventBusTask |
|
|
|
obs <- playerEventBus.askL[Observable[PlayerMovementEvent]]( |
|
|
|
def eval(gameApp: GameApp, fib: Fiber[Nothing, Unit]) = |
|
|
|
for { |
|
|
|
// g <- UIO.pure(gameApp) |
|
|
|
playerEventBus <- eventsModule.playerEventBus |
|
|
|
mainEventBus <- eventsModule.mainEventBus |
|
|
|
tickEventBus <- eventsModule.tickEventBus |
|
|
|
obs <- |
|
|
|
playerEventBus |
|
|
|
.askL[Observable[PlayerMovementEvent]]( |
|
|
|
ObservableSubscription(_) |
|
|
|
) |
|
|
|
_ <- IOUtils.toIO( |
|
|
|
.onErrorHandleWith { |
|
|
|
case ex: TimeoutException => |
|
|
|
IO.raiseError(AppError.TimeoutError(ex.getMessage())) |
|
|
|
} |
|
|
|
_ <- |
|
|
|
IOUtils |
|
|
|
.toIO( |
|
|
|
obs |
|
|
|
.doOnNextF(pme => Coeval(pprint.log(s"Received event $pme")).void) |
|
|
|
.completedL |
|
|
|
.startAndForget |
|
|
|
) |
|
|
|
inputManager <- gameApp.inputManager |
|
|
|
assetManager <- UIO.pure(gameApp.assetManager) |
|
|
|
stateManager <- gameApp.stateManager |
|
|
|
camera <- gameApp.camera |
|
|
|
rootNode <- UIO.pure(gameApp.rootNode) |
|
|
|
enqueueR <- UIO(gameApp.enqueue _) |
|
|
|
viewPort <- gameApp.viewPort |
|
|
|
physicsSpace <- UIO.pure(gameApp.physicsSpace) |
|
|
|
_ <- logger.info("before") |
|
|
|
// jfxUI <- gameApp.jfxUI |
|
|
|
gameAppActor <- gameApp.spawnGameActor( |
|
|
|
GameAppActor.Props(tickEventBus).behavior, |
|
|
|
"gameAppActor" |
|
|
|
) |
|
|
|
_ <- gameAppActor !! GameAppActor.Start |
|
|
|
consoleTextArea <- Task(new TextArea { |
|
|
|
text = "hello \n" |
|
|
|
editable = false |
|
|
|
wrapText = true |
|
|
|
// maxHeight = 150 |
|
|
|
// maxWidth = 300 |
|
|
|
}) |
|
|
|
// _ <- Task(consoleStream := consoleTextArea) |
|
|
|
// _ <- Task(jfxUI += consoleTextArea) |
|
|
|
_ <- logger.info("after") |
|
|
|
_ <- logger.info("Initializing console stream") |
|
|
|
_ <- |
|
|
|
wire[MainAppDelegate] |
|
|
|
.init() |
|
|
|
.executeOn(gameApp.scheduler) |
|
|
|
} yield gameAppFib |
|
|
|
.hideErrors |
|
|
|
inputManager <- gameApp.inputManager |
|
|
|
assetManager <- UIO.pure(gameApp.assetManager) |
|
|
|
camera <- gameApp.camera |
|
|
|
rootNode <- UIO.pure(gameApp.rootNode) |
|
|
|
enqueueR <- UIO(gameApp.enqueue _) |
|
|
|
viewPort <- gameApp.viewPort |
|
|
|
physicsSpace <- UIO.pure(gameApp.physicsSpace) |
|
|
|
_ <- logger.infoU("before") |
|
|
|
// jfxUI <- gameApp.jfxUI |
|
|
|
gameAppActor <- gameApp.spawnGameActor( |
|
|
|
GameAppActor.Props(tickEventBus).behavior, |
|
|
|
"gameAppActor" |
|
|
|
) |
|
|
|
_ <- gameAppActor !! GameAppActor.Start |
|
|
|
consoleTextArea <- UIO(new TextArea { |
|
|
|
text = "hello \n" |
|
|
|
editable = false |
|
|
|
wrapText = true |
|
|
|
// maxHeight = 150 |
|
|
|
// maxWidth = 300 |
|
|
|
}) |
|
|
|
// _ <- Task(consoleStream := consoleTextArea) |
|
|
|
// _ <- Task(jfxUI += consoleTextArea) |
|
|
|
_ <- logger.infoU("after") |
|
|
|
_ <- logger.infoU("Initializing console stream") |
|
|
|
_ <- |
|
|
|
wire[MainAppDelegate] |
|
|
|
.init() |
|
|
|
.executeOn(gameApp.scheduler) |
|
|
|
} yield fib |
|
|
|
|
|
|
|
def gameInit: Resource[UIO, Either[AppError, Fiber[Nothing, Unit]]] = |
|
|
|
wire[GameAppResource].resource.evalMap { |
|
|
|
case Right(gameApp -> gameAppFib) => |
|
|
|
eval(gameApp, gameAppFib).attempt |
|
|
|
case Left(error) => IO.terminate(new Exception(error.toString)) |
|
|
|
} |
|
|
|
|
|
|
|
// val x: Task[Unit] = for { |
|
|
@ -141,21 +156,24 @@ class MainApp( |
|
|
|
// } yield () |
|
|
|
|
|
|
|
val program = for { |
|
|
|
scriptSystem <- scriptSystemInit |
|
|
|
launchSignal <- Deferred[Task, Launcher.LauncherResult] |
|
|
|
// scriptSystem <- scriptSystemInit |
|
|
|
launchSignal <- Deferred[Task, Launcher.LauncherResult].hideErrors |
|
|
|
launcher <- new Launcher.Props(schedulers, launchSignal).create |
|
|
|
launchResult <- launcher.init.use(_ => launchSignal.get) |
|
|
|
launchResult <- launcher.init.use(_ => launchSignal.get).hideErrors |
|
|
|
_ <- |
|
|
|
/** |
|
|
|
* User chose to quit |
|
|
|
*/ |
|
|
|
if (launchResult === LauncherResult.Exit) |
|
|
|
logger.info("Exiting") |
|
|
|
logger.infoU("Exiting") |
|
|
|
/** |
|
|
|
* User chose launch. Wait for game window to close |
|
|
|
*/ |
|
|
|
else |
|
|
|
gameInit.use(_.join) |
|
|
|
gameInit.use { |
|
|
|
case Right(fib) => fib.join >> Task.unit |
|
|
|
case Left(error) => IO.terminate(new Exception(error.toString)) |
|
|
|
}.hideErrors |
|
|
|
|
|
|
|
} yield () |
|
|
|
} |
|
|
@ -170,12 +188,11 @@ class MainAppDelegate( |
|
|
|
tickEventBus: GameEventBus[TickEvent], |
|
|
|
inputManager: InputManager, |
|
|
|
assetManager: AssetManager, |
|
|
|
stateManager: AppStateManager, |
|
|
|
physicsSpace: PhysicsSpace[Task], |
|
|
|
physicsSpace: PhysicsSpace, |
|
|
|
camera: Camera, |
|
|
|
viewPort: ViewPort, |
|
|
|
enqueueR: Function1[() => Unit, Unit], |
|
|
|
rootNode: AppNode[Task] @@ GameAppTags.RootNode |
|
|
|
rootNode: AppNode2 @@ GameAppTags.RootNode |
|
|
|
)(implicit |
|
|
|
spawnProtocol: ActorRef[SpawnProtocol.Command], |
|
|
|
timeout: Timeout, |
|
|
@ -185,31 +202,28 @@ class MainAppDelegate( |
|
|
|
def init( |
|
|
|
// appScheduler: monix.execution.Scheduler |
|
|
|
// consoleStream: GenericConsoleStream[TextArea] |
|
|
|
) = |
|
|
|
): IO[AppError, Unit] = |
|
|
|
for { |
|
|
|
_ <- loggerL.info("Initializing Systems") |
|
|
|
_ <- loggerL.infoU("Initializing Systems") |
|
|
|
_ <- assetManager.registerLocator( |
|
|
|
os.rel / "assets" / "town.zip", |
|
|
|
classOf[ZipLocator] |
|
|
|
) |
|
|
|
_ <- loggerL.info("test") |
|
|
|
_ <- loggerL.infoU("test") |
|
|
|
// _ <- Task(consoleStream.println("text")) |
|
|
|
_ <- DefaultGameLevel(assetManager, viewPort) |
|
|
|
.flatMap(_.addToGame(rootNode, physicsSpace).hideErrors) |
|
|
|
.onErrorHandleWith(e => loggerL.error(e.toString)) |
|
|
|
level <- DefaultGameLevel(assetManager, viewPort) |
|
|
|
_ <- level.addToGame(rootNode, physicsSpace) |
|
|
|
_ <- createPlayerController() |
|
|
|
.onErrorHandleWith(e => loggerL.error(e.toString)) |
|
|
|
// .onErrorRestart(3) |
|
|
|
_ <- wire[GameInputHandler.Props].begin |
|
|
|
// .onErrorRestart(3) |
|
|
|
johnActor <- createTestNpc("John") |
|
|
|
.onErrorHandleWith(e => IO.raiseError(new Throwable(e.toString))) |
|
|
|
// _ <- johnActor !! NpcActorSupervisor.Move(ImVector3f(0, 0, 20)) |
|
|
|
|
|
|
|
// _ <- |
|
|
|
// johnActor |
|
|
|
// .tellL(NpcActorSupervisor.Move(ImVector3f(-30, 0, 10))) |
|
|
|
// .delayExecution(2.seconds) |
|
|
|
_ <- |
|
|
|
johnActor |
|
|
|
.tellL(NpcActorSupervisor.Move(ImVector3f(-30, 0, 10))) |
|
|
|
.delayExecution(2.seconds) |
|
|
|
// _ <- |
|
|
|
// IOUtils |
|
|
|
// .toIO( |
|
|
@ -224,8 +238,8 @@ class MainAppDelegate( |
|
|
|
|
|
|
|
def createPlayerController( |
|
|
|
// appScheduler: monix.execution.Scheduler |
|
|
|
): IO[PlayerController.Error, ActorRef[PlayerActorSupervisor.Command]] = { |
|
|
|
val playerPos = ImVector3f.ZERO |
|
|
|
): IO[AppError, ActorRef[PlayerActorSupervisor.Command]] = { |
|
|
|
val playerPos = ImVector3f.Zero |
|
|
|
val modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o" |
|
|
|
val playerPhysicsControl = |
|
|
|
PlayerController.Defaults.defaultPlayerPhysicsControl |
|
|
@ -235,7 +249,7 @@ class MainAppDelegate( |
|
|
|
assetManager |
|
|
|
.loadModelAs[Node](modelPath) |
|
|
|
.map(_.withRotate(0, FastMath.PI, 0)) |
|
|
|
.mapError(PlayerController.CouldNotCreatePlayerModel) |
|
|
|
.mapError(AppError.AssetManagerError) |
|
|
|
playerNode <- UIO( |
|
|
|
PlayerController.Defaults |
|
|
|
.defaultPlayerNode( |
|
|
@ -261,7 +275,7 @@ class MainAppDelegate( |
|
|
|
def createTestNpc( |
|
|
|
// appScheduler: monix.execution.Scheduler, |
|
|
|
npcName: String |
|
|
|
) = { |
|
|
|
): IO[AppError, ActorRef[NpcActorSupervisor.Command]] = { |
|
|
|
val initialPos = ImVector3f(50, 5, 0) |
|
|
|
val npcPhysicsControl = new BetterCharacterControl(1.5f, 6f, 1f) |
|
|
|
// (1f, 2.1f, 10f) |
|
|
@ -284,10 +298,13 @@ class MainAppDelegate( |
|
|
|
s"${npcName}-npcActorSupervisor" |
|
|
|
) |
|
|
|
|
|
|
|
for { |
|
|
|
materialDef <- assetManager.loadAssetAs[MaterialDef]( |
|
|
|
os.rel / "Common" / "MatDefs" / "Misc" / "Unshaded.j3md" |
|
|
|
) |
|
|
|
(for { |
|
|
|
materialDef <- |
|
|
|
assetManager |
|
|
|
.loadAssetAs[MaterialDef]( |
|
|
|
os.rel / "Common" / "MatDefs" / "Misc" / "Unshaded.j3md" |
|
|
|
) |
|
|
|
.mapError(AppError.AssetManagerError) |
|
|
|
material = new Material(materialDef) |
|
|
|
_ = material.setColor("Color", ColorRGBA.Blue) |
|
|
|
mesh = PlayerController.Defaults.defaultMesh.withMaterial(material) |
|
|
@ -297,13 +314,13 @@ class MainAppDelegate( |
|
|
|
npcPhysicsControl, |
|
|
|
npcName |
|
|
|
) |
|
|
|
npcActor <- npcActorTask.hideErrors |
|
|
|
_ <- (for { |
|
|
|
_ <- physicsSpace += npcPhysicsControl |
|
|
|
_ <- physicsSpace += npcNode |
|
|
|
_ <- rootNode += npcNode |
|
|
|
} yield ()).hideErrors |
|
|
|
} yield npcActor |
|
|
|
} yield ()).mapError(AppError.AppNodeError) |
|
|
|
npcActor <- npcActorTask |
|
|
|
} yield npcActor) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|