forked from nova/jmonkey-test
Rohan Sircar
3 years ago
45 changed files with 1338 additions and 2125 deletions
-
39.ammonite/scala-2.12.12/amm-2.2.0-4-4bd225e/src/main/resources/dep/src/ammonite/$file/src/main/resources/dep.scala
-
45.ammonite/scala-2.12.12/amm-2.2.0-4-4bd225e/src/main/resources/hello/src/ammonite/$file/src/main/resources/hello.scala
-
134.ammonite/scala-2.12.12/amm-2.2.0-4-4bd225e/src/main/resources/hello2/src/ammonite/$file/src/main/resources/hello2.scala
-
4build.sbt
-
8src/main/scala/org/slf4j/impl/StaticLoggerBuilder.scala
-
23src/main/scala/wow/doge/mygame/Main.scala
-
224src/main/scala/wow/doge/mygame/MainApp.scala
-
13src/main/scala/wow/doge/mygame/MainModule.scala
-
281src/main/scala/wow/doge/mygame/game/GameApp.scala
-
71src/main/scala/wow/doge/mygame/game/GameApp2.scala
-
88src/main/scala/wow/doge/mygame/game/GameAppActor.scala
-
75src/main/scala/wow/doge/mygame/game/GameModule.scala
-
106src/main/scala/wow/doge/mygame/game/GameSystemsInitializer.scala
-
132src/main/scala/wow/doge/mygame/game/SimpleAppExt.scala
-
225src/main/scala/wow/doge/mygame/game/entities/NpcActorSupervisor.scala
-
139src/main/scala/wow/doge/mygame/game/entities/player/PlayerActorSupervisor.scala
-
2src/main/scala/wow/doge/mygame/game/entities/player/PlayerCameraActor.scala
-
248src/main/scala/wow/doge/mygame/game/entities/player/PlayerController.scala
-
6src/main/scala/wow/doge/mygame/game/entities/player/PlayerEventListeners.scala
-
222src/main/scala/wow/doge/mygame/game/nodes/PlayerController.scala
-
54src/main/scala/wow/doge/mygame/game/subsystems/ai/GdxAiTest.scala
-
26src/main/scala/wow/doge/mygame/game/subsystems/input/GameInputHandler.scala
-
9src/main/scala/wow/doge/mygame/game/subsystems/input/InputConstant.scala
-
8src/main/scala/wow/doge/mygame/game/subsystems/input/InputEnums.scala
-
18src/main/scala/wow/doge/mygame/game/subsystems/level/GameLevel.scala
-
9src/main/scala/wow/doge/mygame/game/subsystems/movement/CanMove.scala
-
34src/main/scala/wow/doge/mygame/game/subsystems/movement/MovementActor.scala
-
36src/main/scala/wow/doge/mygame/game/subsystems/ui/JmeJfx.scala
-
16src/main/scala/wow/doge/mygame/implicits/JavaFXMonixObservables.scala
-
15src/main/scala/wow/doge/mygame/implicits/observables/package.scala
-
76src/main/scala/wow/doge/mygame/implicits/package.scala
-
46src/main/scala/wow/doge/mygame/launcher/DefaultUI.scala
-
69src/main/scala/wow/doge/mygame/launcher/Launcher.scala
-
4src/main/scala/wow/doge/mygame/math/ImVector3f.scala
-
2src/main/scala/wow/doge/mygame/subsystems/events/EventBus.scala
-
30src/main/scala/wow/doge/mygame/subsystems/events/Events.scala
-
35src/main/scala/wow/doge/mygame/subsystems/events/EventsModule.scala
-
33src/main/scala/wow/doge/mygame/subsystems/events/MovementEvents.scala
-
7src/main/scala/wow/doge/mygame/subsystems/events/PlayerCameraEvents.scala
-
24src/main/scala/wow/doge/mygame/subsystems/events/PlayerEvents.scala
-
2src/main/scala/wow/doge/mygame/subsystems/moddingsystem/ModdingSystem.scala
-
2src/main/scala/wow/doge/mygame/subsystems/scriptsystem/ScriptSystemModule.scala
-
16src/main/scala/wow/doge/mygame/utils/AkkaUtils.scala
-
750src/main/scala/wow/doge/mygame/utils/BorderlessScene.scala
-
57src/main/scala/wow/doge/mygame/utils/GenericConsoleStream.scala
@ -1,39 +0,0 @@ |
|||||
|
|
||||
package ammonite |
|
||||
package $file.src.main.resources |
|
||||
import _root_.ammonite.interp.api.InterpBridge.{ |
|
||||
value => interp |
|
||||
} |
|
||||
import _root_.ammonite.interp.api.InterpBridge.value.{ |
|
||||
exit |
|
||||
} |
|
||||
import _root_.ammonite.interp.api.IvyConstructor.{ |
|
||||
ArtifactIdExt, |
|
||||
GroupIdExt |
|
||||
} |
|
||||
import _root_.ammonite.runtime.tools.{ |
|
||||
browse, |
|
||||
grep, |
|
||||
time, |
|
||||
tail |
|
||||
} |
|
||||
import _root_.ammonite.repl.tools.{ |
|
||||
desugar, |
|
||||
source |
|
||||
} |
|
||||
import _root_.ammonite.main.Router.{ |
|
||||
doc, |
|
||||
main |
|
||||
} |
|
||||
import _root_.ammonite.repl.tools.Util.{ |
|
||||
pathScoptRead |
|
||||
} |
|
||||
|
|
||||
|
|
||||
object dep{ |
|
||||
/*<script>*/class Test(x: Int) |
|
||||
/*</script>*/ /*<generated>*/ |
|
||||
def $main() = { scala.Iterator[String]() } |
|
||||
override def toString = "dep" |
|
||||
/*</generated>*/ |
|
||||
} |
|
@ -1,45 +0,0 @@ |
|||||
|
|
||||
package ammonite |
|
||||
package $file.src.main.resources |
|
||||
import _root_.ammonite.interp.api.InterpBridge.{ |
|
||||
value => interp |
|
||||
} |
|
||||
import _root_.ammonite.interp.api.InterpBridge.value.{ |
|
||||
exit |
|
||||
} |
|
||||
import _root_.ammonite.interp.api.IvyConstructor.{ |
|
||||
ArtifactIdExt, |
|
||||
GroupIdExt |
|
||||
} |
|
||||
import _root_.ammonite.runtime.tools.{ |
|
||||
browse, |
|
||||
grep, |
|
||||
time, |
|
||||
tail |
|
||||
} |
|
||||
import _root_.ammonite.repl.tools.{ |
|
||||
desugar, |
|
||||
source |
|
||||
} |
|
||||
import _root_.ammonite.main.Router.{ |
|
||||
doc, |
|
||||
main |
|
||||
} |
|
||||
import _root_.ammonite.repl.tools.Util.{ |
|
||||
pathScoptRead |
|
||||
} |
|
||||
import ammonite.$file.src.main.resources.{ |
|
||||
dep |
|
||||
} |
|
||||
|
|
||||
|
|
||||
object hello{ |
|
||||
/*<script>*/import $file.$ |
|
||||
import dep.Test |
|
||||
|
|
||||
/*<amm>*/val res_2 = /*</amm>*/new Test(1) |
|
||||
/*</script>*/ /*<generated>*/ |
|
||||
def $main() = { scala.Iterator[String]() } |
|
||||
override def toString = "hello" |
|
||||
/*</generated>*/ |
|
||||
} |
|
@ -1,134 +0,0 @@ |
|||||
|
|
||||
package ammonite |
|
||||
package $file.src.main.resources |
|
||||
import _root_.ammonite.interp.api.InterpBridge.{ |
|
||||
value => interp |
|
||||
} |
|
||||
import _root_.ammonite.interp.api.InterpBridge.value.{ |
|
||||
exit |
|
||||
} |
|
||||
import _root_.ammonite.interp.api.IvyConstructor.{ |
|
||||
ArtifactIdExt, |
|
||||
GroupIdExt |
|
||||
} |
|
||||
import _root_.ammonite.runtime.tools.{ |
|
||||
browse, |
|
||||
grep, |
|
||||
time, |
|
||||
tail |
|
||||
} |
|
||||
import _root_.ammonite.repl.tools.{ |
|
||||
desugar, |
|
||||
source |
|
||||
} |
|
||||
import _root_.ammonite.main.Router.{ |
|
||||
doc, |
|
||||
main |
|
||||
} |
|
||||
import _root_.ammonite.repl.tools.Util.{ |
|
||||
pathScoptRead |
|
||||
} |
|
||||
|
|
||||
|
|
||||
object hello2{ |
|
||||
/*<script>*/import $repo.$ |
|
||||
// import $repo.`https://bintray.com/jmonkeyengine/com.jme3` |
|
||||
// import $file.dep |
|
||||
import $ivy.$ |
|
||||
// import $ivy.`wow.doge:game:1.0-SNAPSHOT` |
|
||||
import $ivy.$ |
|
||||
// import wow.doge.game.types.GameScript |
|
||||
import com.jme3.scene.control.Control |
|
||||
|
|
||||
// println("hello from script") |
|
||||
|
|
||||
// class Scr extends GameScript { |
|
||||
// def start(): Unit = println("hello from start") |
|
||||
|
|
||||
// def stop(): Unit = println("hello from stop") |
|
||||
// } |
|
||||
|
|
||||
// // class SomeClass extends Control {} |
|
||||
|
|
||||
// @main |
|
||||
// def main(): GameScript = new Scr() |
|
||||
import com.simsilica.es.base.DefaultEntityData |
|
||||
import com.simsilica.es.EntityData |
|
||||
import com.jme3.app.Application |
|
||||
import wow.doge.mygame.game.Implicits._ |
|
||||
import wow.doge.mygame.components.TestComponent |
|
||||
import com.jme3.scene.shape.Box |
|
||||
import com.jme3.scene.Geometry |
|
||||
import com.jme3.material.Material |
|
||||
import com.jme3.math.ColorRGBA |
|
||||
import com.jme3.asset.AssetManager |
|
||||
import com.jme3.math.Vector3f |
|
||||
import wow.doge.mygame.state._ |
|
||||
class TestAppState( |
|
||||
// private var _entity: Option[EntityData] = Some(new DefaultEntityData()) |
|
||||
) extends MyBaseState { |
|
||||
protected lazy val b = new Box(1, 1, 1) |
|
||||
protected lazy val geom = new Geometry("Box", b) |
|
||||
protected lazy val mat = Material( |
|
||||
assetManager = assetManager, |
|
||||
path = "Common/MatDefs/Misc/Unshaded.j3md" |
|
||||
) |
|
||||
|
|
||||
// def entity = _entity |
|
||||
// override def initialize(app: Application): Unit = { |
|
||||
// super.initialize(app) |
|
||||
|
|
||||
// } |
|
||||
|
|
||||
override def init() = { |
|
||||
entityData |
|
||||
.createEntity() |
|
||||
.withComponents(TestComponent()) |
|
||||
// entityData.setComponents(x, TestComponent()) |
|
||||
val es = entityData.getEntities(classOf[TestComponent]) |
|
||||
println(es) |
|
||||
geom.setMaterial(mat) |
|
||||
rootNode.attachChild(geom) |
|
||||
|
|
||||
// geom.foreach(e => { |
|
||||
|
|
||||
// }) |
|
||||
} |
|
||||
|
|
||||
override def update(tpf: Float) = { |
|
||||
geom.rotate(0, 0.5f * tpf, 0) |
|
||||
geom.move(new Vector3f(0, 1 * tpf, 0)) |
|
||||
} |
|
||||
|
|
||||
override def cleanup(app: Application): Unit = { |
|
||||
// _entity.map(_.close()) |
|
||||
// _entity = None |
|
||||
} |
|
||||
|
|
||||
override def onEnable(): Unit = {} |
|
||||
|
|
||||
override def onDisable(): Unit = {} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
object Material { |
|
||||
def apply( |
|
||||
color: String = "Color", |
|
||||
colorType: com.jme3.math.ColorRGBA = ColorRGBA.Blue, |
|
||||
assetManager: AssetManager, |
|
||||
path: String |
|
||||
): Material = { |
|
||||
val mat = |
|
||||
new Material(assetManager, path) |
|
||||
mat.setColor(color, colorType) |
|
||||
mat |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@main |
|
||||
def main(): MyBaseState = new TestAppState() |
|
||||
/*</script>*/ /*<generated>*/ |
|
||||
def $main() = { scala.Iterator[String]() } |
|
||||
override def toString = "hello2" |
|
||||
/*</generated>*/ |
|
||||
} |
|
@ -1,132 +1,191 @@ |
|||||
package wow.doge.mygame.game |
package wow.doge.mygame.game |
||||
|
|
||||
import scala.collection.immutable.Queue |
|
||||
|
|
||||
import com.jme3.app.SimpleApplication |
|
||||
import com.jme3.app.state.AppState |
|
||||
|
import cats.effect.concurrent.Deferred |
||||
|
import com.jme3.app.state.AppStateManager |
||||
|
import com.jme3.asset.AssetManager |
||||
|
import com.jme3.input.InputManager |
||||
|
import com.jme3.scene.Node |
||||
|
import com.jme3.scene.Spatial |
||||
|
import com.softwaremill.tagging._ |
||||
|
import com.typesafe.scalalogging.{Logger => SLogger} |
||||
|
import io.odin.Logger |
||||
|
import monix.bio.IO |
||||
import monix.bio.Task |
import monix.bio.Task |
||||
import monix.execution.CancelableFuture |
|
||||
import monix.execution.Scheduler |
|
||||
import monix.execution.atomic.Atomic |
|
||||
import monix.execution.{CancelablePromise => Promise} |
|
||||
import monix.reactive.MulticastStrategy |
|
||||
import monix.reactive.Observable |
|
||||
import monix.reactive.subjects.ConcurrentSubject |
|
||||
import wow.doge.mygame.executors.GUIExecutorService |
|
||||
import wow.doge.mygame.executors.Schedulers |
|
||||
|
|
||||
class GameApp( |
|
||||
schedulers: Schedulers, |
|
||||
appStates: AppState* |
|
||||
) extends SimpleApplication(appStates: _*) { |
|
||||
import GameApp._ |
|
||||
|
|
||||
/** |
|
||||
* A non blocking synchronized queue using an immutable scala queue and monix's atomic class |
|
||||
*/ |
|
||||
private lazy val taskQueue2 = Atomic(Queue.empty[MyTask[_]]) |
|
||||
|
import monix.catnap.ConcurrentChannel |
||||
|
import monix.catnap.ConsumerF |
||||
|
import monix.catnap.Semaphore |
||||
|
import monix.eval.Coeval |
||||
|
import wow.doge.mygame.game.subsystems.ui.JFxUI |
||||
|
|
||||
|
sealed trait Error |
||||
|
case object FlyCamNotExists extends Error |
||||
|
|
||||
|
object GameAppTags { |
||||
|
sealed trait RootNode |
||||
|
sealed trait GuiNode |
||||
|
} |
||||
|
|
||||
private val tickSubject = |
|
||||
ConcurrentSubject[Float](multicast = MulticastStrategy.publish)( |
|
||||
schedulers.async |
|
||||
|
class GameApp(logger: Logger[Task], val app: SimpleAppExt) { |
||||
|
import Ops._ |
||||
|
|
||||
|
def stateManager: Task[AppStateManager] = Task(app.getStateManager()) |
||||
|
def inputManager: Task[InputManager] = Task(app.getInputManager()) |
||||
|
def assetManager: Task[AssetManager] = Task(app.getAssetManager()) |
||||
|
def guiNode = Task(app.getGuiNode().taggedWith[GameAppTags.GuiNode]) |
||||
|
def addToGuiNode = guiNode.flatMap(rn => Task(new AddToNode(rn))) |
||||
|
def flyCam = |
||||
|
IO(app.getFlyByCamera()).onErrorHandleWith(_ => |
||||
|
IO.raiseError(FlyCamNotExists) |
||||
) |
) |
||||
|
def camera = Task(app.getCamera()) |
||||
|
def viewPort = Task(app.getViewPort()) |
||||
|
def rootNode = Task(app.getRootNode().taggedWith[GameAppTags.RootNode]) |
||||
|
// def rootNode2 = SynchedObject(app.getRootNode()) |
||||
|
def addToRootNode = rootNode.flatMap(rn => Task(new AddToNode(rn))) |
||||
|
def enqueue(cb: () => Unit) = |
||||
|
app.enqueue(new Runnable { |
||||
|
override def run() = cb() |
||||
|
}) |
||||
|
def enqueueL[T](cb: () => T): Task[T] = app.enqueueL(cb) |
||||
|
|
||||
|
def start = Task(app.start()) |
||||
|
def stop = Task(app.stop()) |
||||
|
def scheduler = app.scheduler |
||||
|
def jfxUI = JFxUI(app) |
||||
|
|
||||
|
} |
||||
|
|
||||
def tickObservable: Observable[Float] = tickSubject |
|
||||
|
object GameApp { |
||||
|
|
||||
override def simpleInitApp(): Unit = {} |
|
||||
|
class WrappedNode(node: Node, lock: Semaphore[Task]) { |
||||
|
|
||||
override def simpleUpdate(tpf: Float): Unit = { |
|
||||
tickSubject.onNext(tpf) |
|
||||
|
def +=(spat: Spatial) = lock.withPermit(Task(node.attachChild(spat))) |
||||
} |
} |
||||
|
|
||||
override def stop(): Unit = { |
|
||||
tickSubject.onComplete() |
|
||||
super.stop() |
|
||||
|
/** |
||||
|
* Synchronization wrapper for a mutable object |
||||
|
* |
||||
|
* @param obj the mutable object |
||||
|
* @param lock lock for synchronization |
||||
|
*/ |
||||
|
class SynchedObject[A](obj: A, lock: Semaphore[Task]) { |
||||
|
def modify(f: A => Unit): Task[Unit] = |
||||
|
lock.withPermit(Task(f(obj))) |
||||
|
|
||||
|
def flatModify(f: A => Task[Unit]): Task[Unit] = |
||||
|
lock.withPermit(f(obj)) |
||||
|
|
||||
|
def get: Task[A] = lock.withPermit(Task(obj)) |
||||
} |
} |
||||
|
|
||||
def enqueueScala[T](cb: () => T): CancelableFuture[T] = { |
|
||||
val p = Promise[T]() |
|
||||
taskQueue2.transform(_ :+ MyTask(p, cb)) |
|
||||
p.future |
|
||||
|
object SynchedObject { |
||||
|
def apply[A](obj: A) = |
||||
|
Semaphore[Task](1).flatMap(lock => Task(new SynchedObject(obj, lock))) |
||||
} |
} |
||||
|
|
||||
def enqueueL[T](cb: () => T): Task[T] = |
|
||||
Task.deferFuture(enqueueScala(cb)) |
|
||||
|
} |
||||
|
|
||||
override protected def runQueuedTasks(): Unit = { |
|
||||
taskQueue2.transform { current => |
|
||||
current.dequeueOption.fold(current) { |
|
||||
case (MyTask(p, cb), updated) => |
|
||||
p.success(cb()) |
|
||||
updated |
|
||||
|
object Ops { |
||||
|
final class AddToNode[T <: Node](private val node: T) extends AnyVal { |
||||
|
|
||||
|
/** |
||||
|
* Pure version |
||||
|
*/ |
||||
|
def apply(spatial: Spatial)(implicit logger: Logger[Task]) = |
||||
|
logger.debug( |
||||
|
s"Request to add spatial with name ${spatial.getName()} to node ${node.getName()}" |
||||
|
) >> Task(node.attachChild(spatial)) |
||||
|
|
||||
|
/** |
||||
|
* Impure version |
||||
|
*/ |
||||
|
def apply(spatial: Spatial)(implicit logger: SLogger) = |
||||
|
Coeval { |
||||
|
logger.debug( |
||||
|
s"Request to add spatial with name ${spatial.getName()} to node ${node.getName()}" |
||||
|
) |
||||
|
node.attachChild(spatial) |
||||
} |
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
object SpawnSystem { |
||||
|
sealed trait Result |
||||
|
final case object Ok extends Result |
||||
|
|
||||
|
sealed trait Complete |
||||
|
final case object Complete extends Complete |
||||
|
|
||||
|
sealed trait SpawnRequest |
||||
|
final case class SpawnSpatial(node: Node) extends SpawnRequest |
||||
|
|
||||
|
final case class SpawnRequestWrapper( |
||||
|
spawnRequest: SpawnRequest, |
||||
|
result: Deferred[Task, Result] |
||||
|
) |
||||
|
|
||||
|
def apply(logger: Logger[Task]) = |
||||
|
for { |
||||
|
spawnChannel <- ConcurrentChannel[Task].of[Complete, SpawnRequestWrapper] |
||||
|
spawnSystem <- Task(new SpawnSystem(logger, spawnChannel)) |
||||
|
consumer <- |
||||
|
spawnChannel.consume |
||||
|
.use(consumer => spawnSystem.receive(consumer)) |
||||
|
.startAndForget |
||||
|
} yield (spawnSystem) |
||||
|
} |
||||
|
|
||||
|
class SpawnSystem( |
||||
|
logger: Logger[Task], |
||||
|
spawnChannel: ConcurrentChannel[ |
||||
|
Task, |
||||
|
SpawnSystem.Complete, |
||||
|
SpawnSystem.SpawnRequestWrapper |
||||
|
] |
||||
|
) { |
||||
|
import SpawnSystem._ |
||||
|
|
||||
|
for { |
||||
|
spawnSystem <- SpawnSystem(logger) |
||||
|
n <- spawnSystem.request(SpawnSpatial(new Node("Test"))) |
||||
|
} yield () |
||||
|
|
||||
|
// val spawnChannel = ConcurrentChannel[Task].of[Result, SpawnRequest] |
||||
|
|
||||
|
private def receive( |
||||
|
consumer: ConsumerF[Task, Complete, SpawnRequestWrapper] |
||||
|
): Task[Unit] = |
||||
|
consumer.pull.flatMap { |
||||
|
case Right(message) => |
||||
|
for { |
||||
|
_ <- |
||||
|
logger |
||||
|
.debug(s"Received spawn request $message") |
||||
|
_ <- handleSpawn(message) |
||||
|
} yield receive(consumer) |
||||
|
case Left(r) => |
||||
|
logger.info("Worker $$index is done!") |
||||
} |
} |
||||
|
|
||||
super.runQueuedTasks() |
|
||||
} |
|
||||
|
private def handleSpawn(spawnRequestWrapper: SpawnRequestWrapper) = |
||||
|
spawnRequestWrapper match { |
||||
|
case SpawnRequestWrapper(spawnRequest, result) => |
||||
|
spawnRequest match { |
||||
|
case SpawnSpatial(spatial) => |
||||
|
logger.debug( |
||||
|
s"Spawning spatial with name ${spatial.getName()}" |
||||
|
) >> result |
||||
|
.complete(Ok) |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
object JMEExecutorService extends GUIExecutorService { |
|
||||
override def execute(command: Runnable): Unit = |
|
||||
enqueueScala(() => command.run()) |
|
||||
// enqueue(command) |
|
||||
// new SingleThreadEventExecutor() |
|
||||
// sys.addShutdownHook(JMEExecutorService.shutdown()) |
|
||||
} |
|
||||
|
def request(spawnRequest: SpawnRequest) = |
||||
|
for { |
||||
|
d <- Deferred[Task, Result] |
||||
|
_ <- spawnChannel.push(SpawnRequestWrapper(spawnRequest, d)) |
||||
|
res <- d.get |
||||
|
} yield (res) |
||||
|
|
||||
lazy val scheduler = Scheduler(JMEExecutorService) |
|
||||
|
def stop = spawnChannel.halt(Complete) |
||||
} |
} |
||||
object GameApp { |
|
||||
private[game] case class MyTask[T](p: Promise[T], cb: () => T) |
|
||||
} |
|
||||
|
|
||||
// val ship = ed.createEntity() |
|
||||
// val mbState = stateManager().state[EntityDataState]().map(_.getEntityData()) |
|
||||
// val mbState = Try( |
|
||||
// stateManager() |
|
||||
// .state[TestAppState]() |
|
||||
// .entity |
|
||||
// ).toOption.flatten.toRight(println("empty")) |
|
||||
// // .flatMap(_.entity) |
|
||||
// val x = mbState.flatMap( |
|
||||
// _.query |
|
||||
// .filter[TestComponent]("name", new Object()) |
|
||||
// // .filterOr[TestEntity]( |
|
||||
// // Filters |
|
||||
// // .fieldEquals(classOf[TestEntity], "", null) |
|
||||
// // ) |
|
||||
// .component[Tag]() |
|
||||
// .component[TestComponent]() |
|
||||
// .result |
|
||||
// .toRight(println("failed")) |
|
||||
// ) |
|
||||
|
|
||||
// rootNode |
|
||||
// .child(geom) |
|
||||
// .child(geom) |
|
||||
// .child(geom) |
|
||||
// .child(geom) |
|
||||
// .child(geom) |
|
||||
// .child(geom) |
|
||||
// .child(geom) |
|
||||
// .child(geom) |
|
||||
// Future(println("hello"))(jmeEC(this)) |
|
||||
// val wbActor: Future[ActorRef[Greeter.Greet]] = actorSystem.ask( |
|
||||
// SpawnProtocol.Spawn( |
|
||||
// behavior = Greeter(), |
|
||||
// name = "listener", |
|
||||
// DispatcherSelector.fromConfig("jme-dispatcher"), |
|
||||
// _ |
|
||||
// ) |
|
||||
// ) |
|
||||
|
|
||||
// wbActor.map(a => a.ask(Greeter.Greet("hello", _)).map(println)) |
|
||||
|
|
||||
// Task(Promise[T]()).flatMap { p => |
|
||||
// Task(taskQueue2.transform(_ :+ MyTask(p, cb))) >> |
|
||||
// Task.fromCancelablePromise(p) |
|
||||
// } |
|
||||
// Task.fromCancelablePromise { |
|
||||
// val p = Promise[T]() |
|
||||
// taskQueue2.transform(_ :+ MyTask(p, cb)) |
|
||||
// p |
|
||||
// } |
|
@ -1,71 +0,0 @@ |
|||||
package wow.doge.mygame.game |
|
||||
|
|
||||
import cats.effect.concurrent.Ref |
|
||||
import com.jme3.app.state.AppStateManager |
|
||||
import com.jme3.asset.AssetManager |
|
||||
import com.jme3.input.InputManager |
|
||||
import monix.bio.IO |
|
||||
import monix.bio.Task |
|
||||
import com.jme3.scene.Node |
|
||||
import monix.catnap.Semaphore |
|
||||
import com.jme3.scene.Spatial |
|
||||
import wow.doge.mygame.game.GameApp2.SynchedObject |
|
||||
import wow.doge.mygame.game.subsystems.ui.JFxUI |
|
||||
|
|
||||
sealed trait Error |
|
||||
case object FlyCamNotExists extends Error |
|
||||
|
|
||||
class GameApp2(val app: GameApp) { |
|
||||
def stateManager: Task[AppStateManager] = Task(app.getStateManager()) |
|
||||
def inputManager: Task[InputManager] = Task(app.getInputManager()) |
|
||||
def assetManager: Task[AssetManager] = Task(app.getAssetManager()) |
|
||||
def guiNode = Ref[Task].of(app.getGuiNode()) |
|
||||
def flyCam = |
|
||||
IO(app.getFlyByCamera()).onErrorHandleWith(_ => |
|
||||
IO.raiseError(FlyCamNotExists) |
|
||||
) |
|
||||
def camera = Task(app.getCamera()) |
|
||||
def viewPort = Task(app.getViewPort()) |
|
||||
def rootNode = Ref[Task].of(app.getRootNode()) |
|
||||
def rootNode2 = SynchedObject(app.getRootNode()) |
|
||||
def enqueue(cb: () => Unit) = |
|
||||
app.enqueue(new Runnable { |
|
||||
override def run() = cb() |
|
||||
}) |
|
||||
def enqueueL[T](cb: () => T): Task[T] = app.enqueueL(cb) |
|
||||
|
|
||||
def start = Task(app.start()) |
|
||||
def stop = Task(app.stop()) |
|
||||
def scheduler = app.scheduler |
|
||||
def jfxUI = JFxUI(app) |
|
||||
|
|
||||
} |
|
||||
|
|
||||
object GameApp2 { |
|
||||
|
|
||||
class WrappedNode(node: Node, lock: Semaphore[Task]) { |
|
||||
|
|
||||
def +=(spat: Spatial) = lock.withPermit(Task(node.attachChild(spat))) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Synchronization wrapper for a mutable object |
|
||||
* |
|
||||
* @param obj the mutable object |
|
||||
* @param lock lock for synchronization |
|
||||
*/ |
|
||||
class SynchedObject[A](obj: A, lock: Semaphore[Task]) { |
|
||||
def modify(f: A => Unit): Task[Unit] = |
|
||||
lock.withPermit(Task(f(obj))) |
|
||||
|
|
||||
def flatModify(f: A => Task[Unit]): Task[Unit] = |
|
||||
lock.withPermit(f(obj)) |
|
||||
|
|
||||
def get: Task[A] = lock.withPermit(Task(obj)) |
|
||||
} |
|
||||
|
|
||||
object SynchedObject { |
|
||||
def apply[A](obj: A) = |
|
||||
Semaphore[Task](1).flatMap(lock => Task(new SynchedObject(obj, lock))) |
|
||||
} |
|
||||
} |
|
@ -1,106 +0,0 @@ |
|||||
package wow.doge.mygame.game |
|
||||
|
|
||||
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.concurrent.Ref |
|
||||
import com.jme3.app.state.AppStateManager |
|
||||
import com.jme3.asset.AssetManager |
|
||||
import com.jme3.asset.plugins.ZipLocator |
|
||||
import com.jme3.bullet.BulletAppState |
|
||||
import com.jme3.input.InputManager |
|
||||
import com.jme3.renderer.Camera |
|
||||
import com.jme3.scene.Node |
|
||||
import com.softwaremill.macwire._ |
|
||||
import com.softwaremill.tagging._ |
|
||||
import io.odin.Logger |
|
||||
import monix.bio.IO |
|
||||
import monix.bio.Task |
|
||||
import monix.reactive.Consumer |
|
||||
import wow.doge.mygame.events.EventBus |
|
||||
import wow.doge.mygame.game.nodes.PlayerTag |
|
||||
import wow.doge.mygame.game.nodes.PlayerController |
|
||||
import wow.doge.mygame.game.subsystems.input.GameInputHandler |
|
||||
import wow.doge.mygame.implicits._ |
|
||||
import wow.doge.mygame.math.ImVector3f |
|
||||
import wow.doge.mygame.subsystems.events.EntityMovementEvent |
|
||||
import wow.doge.mygame.subsystems.events.PlayerCameraEvent |
|
||||
import wow.doge.mygame.subsystems.movement.ImMovementActor |
|
||||
import wow.doge.mygame.utils.IOUtils |
|
||||
|
|
||||
class GameSystemsInitializer( |
|
||||
spawnProtocol: ActorSystem[SpawnProtocol.Command], |
|
||||
loggerL: Logger[Task], |
|
||||
// eventBuses: EventsModule2 |
|
||||
playerMovementEventBus: ActorRef[ |
|
||||
EventBus.Command[EntityMovementEvent.PlayerMovementEvent] |
|
||||
], |
|
||||
playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]], |
|
||||
inputManager: InputManager, |
|
||||
assetManager: AssetManager, |
|
||||
stateManager: AppStateManager, |
|
||||
camera: Camera, |
|
||||
enqueueR: Function1[() => Unit, Unit], |
|
||||
appScheduler: monix.execution.Scheduler, |
|
||||
rootNode: Ref[Task, Node] |
|
||||
) { |
|
||||
implicit val timeout: Timeout = Timeout(1.second) |
|
||||
|
|
||||
import GameSystemsInitializer._ |
|
||||
|
|
||||
implicit val akkaScheduler: Scheduler = spawnProtocol.scheduler |
|
||||
// lazy val inputManager = app.inputManager |
|
||||
// lazy val assetManager = app.assetManager |
|
||||
lazy val bulletAppState = new BulletAppState() |
|
||||
// lazy val playerMovementEventBus = eventBuses.playerMovementEventBusTask |
|
||||
|
|
||||
val init = |
|
||||
for { |
|
||||
_ <- loggerL.info("Initializing Systems") |
|
||||
// playerMovementEventBus <- playerMovementEventBusTask |
|
||||
_ <- Task(stateManager.attach(bulletAppState)) |
|
||||
_ <- Task( |
|
||||
assetManager.registerLocator( |
|
||||
// "src/main/resources/assets/town.zip", |
|
||||
(os.rel / "assets" / "town.zip"), |
|
||||
classOf[ZipLocator] |
|
||||
) |
|
||||
) |
|
||||
|
|
||||
// _ <- app.enqueueL(() => DefaultGameLevel(app, bulletAppState)) |
|
||||
_ <- wireWith(createPlayerController _).startAndForget |
|
||||
_ <- wire[GameInputHandler.Props].begin |
|
||||
|
|
||||
} yield () |
|
||||
|
|
||||
def createPlayerController( |
|
||||
// playerMovementEventBus: ActorRef[ |
|
||||
// EventBus.Command[PlayerMovementEvent] |
|
||||
// ], |
|
||||
// playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]] |
|
||||
): IO[PlayerController.Error, Unit] = { |
|
||||
@annotation.unused |
|
||||
val playerPos = ImVector3f.ZERO |
|
||||
@annotation.unused |
|
||||
val playerNode = None.taggedWith[PlayerTag] |
|
||||
@annotation.unused |
|
||||
val modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o" |
|
||||
wire[PlayerController.Props].create |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
object GameSystemsInitializer { |
|
||||
|
|
||||
def playerMovementActorTickConsumer( |
|
||||
playerMovementActor: ActorRef[ImMovementActor.Command] |
|
||||
) = |
|
||||
Consumer |
|
||||
.foreachTask[Float](tpf => |
|
||||
IOUtils.toTask(playerMovementActor !! ImMovementActor.Tick) |
|
||||
) |
|
||||
// .mapTask() |
|
||||
} |
|
@ -0,0 +1,132 @@ |
|||||
|
package wow.doge.mygame.game |
||||
|
|
||||
|
import scala.collection.immutable.Queue |
||||
|
|
||||
|
import com.jme3.app.SimpleApplication |
||||
|
import com.jme3.app.state.AppState |
||||
|
import monix.bio.Task |
||||
|
import monix.execution.CancelableFuture |
||||
|
import monix.execution.Scheduler |
||||
|
import monix.execution.atomic.Atomic |
||||
|
import monix.execution.{CancelablePromise => Promise} |
||||
|
import monix.reactive.MulticastStrategy |
||||
|
import monix.reactive.Observable |
||||
|
import monix.reactive.subjects.ConcurrentSubject |
||||
|
import wow.doge.mygame.executors.GUIExecutorService |
||||
|
import wow.doge.mygame.executors.Schedulers |
||||
|
|
||||
|
class SimpleAppExt( |
||||
|
schedulers: Schedulers, |
||||
|
appStates: AppState* |
||||
|
) extends SimpleApplication(appStates: _*) { |
||||
|
import SimpleAppExt._ |
||||
|
|
||||
|
/** |
||||
|
* A non blocking synchronized queue using an immutable scala queue and monix's atomic class |
||||
|
*/ |
||||
|
private lazy val taskQueue2 = Atomic(Queue.empty[MyTask[_]]) |
||||
|
|
||||
|
private val tickSubject = |
||||
|
ConcurrentSubject[Float](multicast = MulticastStrategy.publish)( |
||||
|
schedulers.async |
||||
|
) |
||||
|
|
||||
|
def tickObservable: Observable[Float] = tickSubject |
||||
|
|
||||
|
override def simpleInitApp(): Unit = {} |
||||
|
|
||||
|
override def simpleUpdate(tpf: Float): Unit = { |
||||
|
tickSubject.onNext(tpf) |
||||
|
} |
||||
|
|
||||
|
override def stop(): Unit = { |
||||
|
tickSubject.onComplete() |
||||
|
super.stop() |
||||
|
} |
||||
|
|
||||
|
def enqueueScala[T](cb: () => T): CancelableFuture[T] = { |
||||
|
val p = Promise[T]() |
||||
|
taskQueue2.transform(_ :+ MyTask(p, cb)) |
||||
|
p.future |
||||
|
} |
||||
|
|
||||
|
def enqueueL[T](cb: () => T): Task[T] = |
||||
|
Task.deferFuture(enqueueScala(cb)) |
||||
|
|
||||
|
override protected def runQueuedTasks(): Unit = { |
||||
|
taskQueue2.transform { current => |
||||
|
current.dequeueOption.fold(current) { |
||||
|
case (MyTask(p, cb), updated) => |
||||
|
p.success(cb()) |
||||
|
updated |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
super.runQueuedTasks() |
||||
|
} |
||||
|
|
||||
|
object JMEExecutorService extends GUIExecutorService { |
||||
|
override def execute(command: Runnable): Unit = |
||||
|
enqueueScala(() => command.run()) |
||||
|
// enqueue(command) |
||||
|
// new SingleThreadEventExecutor() |
||||
|
// sys.addShutdownHook(JMEExecutorService.shutdown()) |
||||
|
} |
||||
|
|
||||
|
lazy val scheduler = Scheduler(JMEExecutorService) |
||||
|
} |
||||
|
object SimpleAppExt { |
||||
|
private[game] case class MyTask[T](p: Promise[T], cb: () => T) |
||||
|
} |
||||
|
|
||||
|
// val ship = ed.createEntity() |
||||
|
// val mbState = stateManager().state[EntityDataState]().map(_.getEntityData()) |
||||
|
// val mbState = Try( |
||||
|
// stateManager() |
||||
|
// .state[TestAppState]() |
||||
|
// .entity |
||||
|
// ).toOption.flatten.toRight(println("empty")) |
||||
|
// // .flatMap(_.entity) |
||||
|
// val x = mbState.flatMap( |
||||
|
// _.query |
||||
|
// .filter[TestComponent]("name", new Object()) |
||||
|
// // .filterOr[TestEntity]( |
||||
|
// // Filters |
||||
|
// // .fieldEquals(classOf[TestEntity], "", null) |
||||
|
// // ) |
||||
|
// .component[Tag]() |
||||
|
// .component[TestComponent]() |
||||
|
// .result |
||||
|
// .toRight(println("failed")) |
||||
|
// ) |
||||
|
|
||||
|
// rootNode |
||||
|
// .child(geom) |
||||
|
// .child(geom) |
||||
|
// .child(geom) |
||||
|
// .child(geom) |
||||
|
// .child(geom) |
||||
|
// .child(geom) |
||||
|
// .child(geom) |
||||
|
// .child(geom) |
||||
|
// Future(println("hello"))(jmeEC(this)) |
||||
|
// val wbActor: Future[ActorRef[Greeter.Greet]] = actorSystem.ask( |
||||
|
// SpawnProtocol.Spawn( |
||||
|
// behavior = Greeter(), |
||||
|
// name = "listener", |
||||
|
// DispatcherSelector.fromConfig("jme-dispatcher"), |
||||
|
// _ |
||||
|
// ) |
||||
|
// ) |
||||
|
|
||||
|
// wbActor.map(a => a.ask(Greeter.Greet("hello", _)).map(println)) |
||||
|
|
||||
|
// Task(Promise[T]()).flatMap { p => |
||||
|
// Task(taskQueue2.transform(_ :+ MyTask(p, cb))) >> |
||||
|
// Task.fromCancelablePromise(p) |
||||
|
// } |
||||
|
// Task.fromCancelablePromise { |
||||
|
// val p = Promise[T]() |
||||
|
// taskQueue2.transform(_ :+ MyTask(p, cb)) |
||||
|
// p |
||||
|
// } |
@ -0,0 +1,225 @@ |
|||||
|
package wow.doge.mygame.game.entities |
||||
|
|
||||
|
import akka.actor.typed.ActorRef |
||||
|
import akka.actor.typed.Behavior |
||||
|
import akka.actor.typed.SupervisorStrategy |
||||
|
import akka.actor.typed.scaladsl.ActorContext |
||||
|
import akka.actor.typed.scaladsl.Behaviors |
||||
|
import wow.doge.mygame.subsystems.events.Event |
||||
|
import wow.doge.mygame.subsystems.events.EventBus |
||||
|
import wow.doge.mygame.subsystems.events.EventsModule.GameEventBus |
||||
|
import wow.doge.mygame.subsystems.events.TickEvent |
||||
|
import wow.doge.mygame.subsystems.events.TickEvent.RenderTick |
||||
|
import wow.doge.mygame.subsystems.movement.ImMovementActor |
||||
|
import wow.doge.mygame.subsystems.events.EntityMovementEvent |
||||
|
import wow.doge.mygame.subsystems.events.EntityMovementEvent.MovedLeft |
||||
|
import wow.doge.mygame.subsystems.events.EntityMovementEvent.MovedUp |
||||
|
import wow.doge.mygame.subsystems.events.EntityMovementEvent.MovedRight |
||||
|
import wow.doge.mygame.subsystems.events.EntityMovementEvent.MovedDown |
||||
|
import wow.doge.mygame.math.ImVector3f |
||||
|
import wow.doge.mygame.game.subsystems.movement.CanMove |
||||
|
import wow.doge.mygame.implicits._ |
||||
|
import akka.util.Timeout |
||||
|
import scala.concurrent.duration._ |
||||
|
import scala.util.Success |
||||
|
import scala.util.Failure |
||||
|
|
||||
|
object NpcActorSupervisor { |
||||
|
sealed trait Command |
||||
|
case class Move(pos: ImVector3f) extends Command |
||||
|
private case class UpdatePosition(pos: ImVector3f) extends Command |
||||
|
private case class LogError(err: Throwable) extends Command |
||||
|
case object MovementTick extends Command |
||||
|
|
||||
|
final case class Props( |
||||
|
npcMovementActorBehavior: Behavior[NpcMovementActor2.Command], |
||||
|
npcName: String, |
||||
|
initialPos: ImVector3f |
||||
|
) { |
||||
|
def create = |
||||
|
Behaviors.setup[Command] { ctx => |
||||
|
val npcMovementActor = ctx.spawn( |
||||
|
(npcMovementActorBehavior), |
||||
|
s"npc-${npcName}-NpcMovementActor" |
||||
|
) |
||||
|
|
||||
|
new NpcActorSupervisor(ctx, this) |
||||
|
.idle(State(npcMovementActor, initialPos)) |
||||
|
} |
||||
|
} |
||||
|
final case class State( |
||||
|
npcMovementActor: ActorRef[NpcMovementActor2.Command], |
||||
|
currentPos: ImVector3f |
||||
|
) |
||||
|
} |
||||
|
class NpcActorSupervisor( |
||||
|
ctx: ActorContext[NpcActorSupervisor.Command], |
||||
|
props: NpcActorSupervisor.Props |
||||
|
) { |
||||
|
import NpcActorSupervisor._ |
||||
|
implicit val timeout = Timeout(1.second) |
||||
|
def idle(state: State): Behavior[NpcActorSupervisor.Command] = |
||||
|
Behaviors.receiveMessage[Command] { |
||||
|
case Move(pos) => { |
||||
|
state.npcMovementActor ! NpcMovementActor2.Move(pos) |
||||
|
val movementTimer = ctx.spawn( |
||||
|
GenericTimerActor.Props(ctx.self, MovementTick, 100.millis).create, |
||||
|
s"npc-${props.npcName}-NpcActorTimer" |
||||
|
) |
||||
|
movementTimer ! GenericTimerActor.Start |
||||
|
moving(state, pos, movementTimer) |
||||
|
} |
||||
|
case LogError(err) => |
||||
|
ctx.log.warn(err.getMessage()) |
||||
|
Behaviors.same |
||||
|
case _ => Behaviors.unhandled |
||||
|
} |
||||
|
|
||||
|
def moving( |
||||
|
state: State, |
||||
|
targetPos: ImVector3f, |
||||
|
movementTimer: ActorRef[GenericTimerActor.Command] |
||||
|
): Behavior[NpcActorSupervisor.Command] = |
||||
|
Behaviors.receiveMessagePartial[Command] { |
||||
|
case LogError(err) => |
||||
|
ctx.log.warn(err.getMessage()) |
||||
|
Behaviors.same |
||||
|
case Move(pos) => moving(state, pos, movementTimer) |
||||
|
case UpdatePosition(pos) => |
||||
|
ctx.log.trace("Current pos = " + state.currentPos.toString()) |
||||
|
moving(state.copy(currentPos = pos), targetPos, movementTimer) |
||||
|
case MovementTick => |
||||
|
val dst = ImVector3f.dst(targetPos, state.currentPos) |
||||
|
if (dst <= 10f) { |
||||
|
state.npcMovementActor ! NpcMovementActor2.StopMoving |
||||
|
movementTimer ! GenericTimerActor.Stop |
||||
|
idle(state) |
||||
|
} else { |
||||
|
// ctx.log.debug("Difference = " + dst.toString()) |
||||
|
// ctx.log.debug("Current pos = " + state.currentPos.toString()) |
||||
|
|
||||
|
ctx.ask(state.npcMovementActor, NpcMovementActor2.AskPosition(_)) { |
||||
|
case Success(value) => |
||||
|
UpdatePosition(value) |
||||
|
case Failure(exception) => LogError(exception) |
||||
|
} |
||||
|
// Behaviors.same |
||||
|
moving(state, targetPos, movementTimer) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
object NpcMovementActor2 { |
||||
|
sealed trait Command |
||||
|
case class AskPosition(replyTo: ActorRef[ImVector3f]) extends Command |
||||
|
case object StopMoving extends Command |
||||
|
case class Move(target: ImVector3f) extends Command |
||||
|
|
||||
|
final class Props[T: CanMove]( |
||||
|
val enqueueR: Function1[() => Unit, Unit], |
||||
|
val initialPos: ImVector3f, |
||||
|
val tickEventBus: GameEventBus[TickEvent], |
||||
|
val movable: T |
||||
|
) { |
||||
|
def create = |
||||
|
Behaviors.setup[Command] { ctx => |
||||
|
new NpcMovementActor2(ctx, this).receive(State(initialPos)) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
final case class State(currentPos: ImVector3f) |
||||
|
} |
||||
|
class NpcMovementActor2[T]( |
||||
|
ctx: ActorContext[NpcMovementActor2.Command], |
||||
|
props: NpcMovementActor2.Props[T] |
||||
|
) { |
||||
|
import NpcMovementActor2._ |
||||
|
def receive( |
||||
|
state: State |
||||
|
)(implicit cm: CanMove[T]): Behavior[NpcMovementActor2.Command] = |
||||
|
Behaviors.receiveMessage[Command] { |
||||
|
case AskPosition(replyTo) => |
||||
|
replyTo ! cm.location(props.movable) |
||||
|
Behaviors.same |
||||
|
case Move(target: ImVector3f) => |
||||
|
props.enqueueR(() => |
||||
|
cm.move(props.movable, (target - state.currentPos) * 0.005f) |
||||
|
) |
||||
|
receive(state = state.copy(currentPos = cm.location(props.movable))) |
||||
|
case StopMoving => |
||||
|
ctx.log.debug( |
||||
|
"Position at Stop = " + cm.location(props.movable).toString |
||||
|
) |
||||
|
props.enqueueR(() => cm.stop(props.movable)) |
||||
|
receive(state = state.copy(currentPos = cm.location(props.movable))) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
object NpcMovementActor { |
||||
|
sealed trait Command |
||||
|
final case class Props( |
||||
|
imMovementActorBehavior: Behavior[ImMovementActor.Command], |
||||
|
npcName: String, |
||||
|
// movementActor: ActorRef[ImMovementActor.Command], |
||||
|
mainEventBus: ActorRef[ |
||||
|
EventBus.Command[Event] |
||||
|
], |
||||
|
tickEventBus: GameEventBus[TickEvent] |
||||
|
) { |
||||
|
|
||||
|
def create: Behavior[Command] = |
||||
|
Behaviors.setup { ctx => |
||||
|
val movementActor = ctx.spawn( |
||||
|
Behaviors |
||||
|
.supervise(imMovementActorBehavior) |
||||
|
.onFailure[Exception](SupervisorStrategy.restart), |
||||
|
s"npc-${npcName}-MovementActorChild" |
||||
|
) |
||||
|
val npcMovementElBehavior = Behaviors.receiveMessagePartial[Event] { |
||||
|
case event: EntityMovementEvent => |
||||
|
event match { |
||||
|
case MovedLeft(name, pressed) => |
||||
|
if (name == npcName) |
||||
|
movementActor ! ImMovementActor.MovedLeft(pressed) |
||||
|
Behaviors.same |
||||
|
case MovedUp(name, pressed) => |
||||
|
if (name == npcName) |
||||
|
movementActor ! ImMovementActor.MovedUp(pressed) |
||||
|
Behaviors.same |
||||
|
case MovedRight(name, pressed) => |
||||
|
if (name == npcName) |
||||
|
movementActor ! ImMovementActor.MovedRight(pressed) |
||||
|
Behaviors.same |
||||
|
case MovedDown(name, pressed) => |
||||
|
if (name == npcName) |
||||
|
movementActor ! ImMovementActor.MovedDown(pressed) |
||||
|
Behaviors.same |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
val npcMovementEl = ctx.spawn( |
||||
|
Behaviors |
||||
|
.supervise(npcMovementElBehavior) |
||||
|
.onFailure[Exception](SupervisorStrategy.restart), |
||||
|
s"npc-${npcName}-MovementEventHandler" |
||||
|
) |
||||
|
val renderTickElBehavior = |
||||
|
Behaviors.receiveMessage[RenderTick.type] { |
||||
|
case RenderTick => |
||||
|
movementActor ! ImMovementActor.Tick |
||||
|
Behaviors.same |
||||
|
} |
||||
|
|
||||
|
val renderTickEl = |
||||
|
ctx.spawn( |
||||
|
renderTickElBehavior, |
||||
|
s"npc-${npcName}-MovementTickListener" |
||||
|
) |
||||
|
|
||||
|
mainEventBus ! EventBus.Subscribe(npcMovementEl) |
||||
|
tickEventBus ! EventBus.Subscribe(renderTickEl) |
||||
|
Behaviors.receiveMessage { msg => Behaviors.same } |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
@ -1,4 +1,4 @@ |
|||||
package wow.doge.mygame.game.nodes |
|
||||
|
package wow.doge.mygame.game.entities |
||||
|
|
||||
import akka.actor.typed.scaladsl.ActorContext |
import akka.actor.typed.scaladsl.ActorContext |
||||
import akka.actor.typed.scaladsl.Behaviors |
import akka.actor.typed.scaladsl.Behaviors |
@ -0,0 +1,248 @@ |
|||||
|
package wow.doge.mygame.game.entities |
||||
|
|
||||
|
import akka.actor.typed.ActorRef |
||||
|
import akka.actor.typed.Props |
||||
|
import akka.actor.typed.Scheduler |
||||
|
import akka.actor.typed.SpawnProtocol |
||||
|
import akka.util.Timeout |
||||
|
import cats.implicits._ |
||||
|
import com.jme3.asset.AssetManager |
||||
|
import com.jme3.bullet.BulletAppState |
||||
|
import com.jme3.bullet.PhysicsSpace |
||||
|
import com.jme3.bullet.control.BetterCharacterControl |
||||
|
import com.jme3.math.FastMath |
||||
|
import com.jme3.renderer.Camera |
||||
|
import com.jme3.scene.CameraNode |
||||
|
import com.jme3.scene.Geometry |
||||
|
import com.jme3.scene.Node |
||||
|
import com.jme3.scene.control.CameraControl.ControlDirection |
||||
|
import com.jme3.scene.shape.Box |
||||
|
import com.softwaremill.macwire._ |
||||
|
import com.softwaremill.tagging._ |
||||
|
import io.odin.Logger |
||||
|
import monix.bio.IO |
||||
|
import monix.bio.Task |
||||
|
import wow.doge.mygame.game.GameAppTags |
||||
|
import wow.doge.mygame.game.SimpleAppExt |
||||
|
import wow.doge.mygame.implicits._ |
||||
|
import wow.doge.mygame.math.ImVector3f |
||||
|
import wow.doge.mygame.state.MyMaterial |
||||
|
import wow.doge.mygame.subsystems.events.EventBus |
||||
|
import wow.doge.mygame.subsystems.events.EventsModule.GameEventBus |
||||
|
import wow.doge.mygame.subsystems.events.PlayerCameraEvent |
||||
|
import wow.doge.mygame.subsystems.events.PlayerMovementEvent |
||||
|
import wow.doge.mygame.subsystems.events.TickEvent |
||||
|
import wow.doge.mygame.subsystems.movement.ImMovementActor |
||||
|
import wow.doge.mygame.utils.AkkaUtils |
||||
|
|
||||
|
object PlayerControllerTags { |
||||
|
sealed trait PlayerTag |
||||
|
sealed trait PlayerCameraNode |
||||
|
} |
||||
|
|
||||
|
object PlayerController { |
||||
|
sealed trait Error |
||||
|
case class CouldNotCreatePlayerNode(reason: String) extends Error |
||||
|
case class GenericError(reason: String) extends Error |
||||
|
|
||||
|
class Props( |
||||
|
enqueueR: Function1[() => Unit, Unit], |
||||
|
rootNode: Node @@ GameAppTags.RootNode, |
||||
|
loggerL: Logger[Task], |
||||
|
physicsSpace: PhysicsSpace, |
||||
|
initialPlayerPos: ImVector3f = ImVector3f.ZERO, |
||||
|
spawnProtocol: ActorRef[SpawnProtocol.Command], |
||||
|
playerMovementEventBus: ActorRef[ |
||||
|
EventBus.Command[PlayerMovementEvent] |
||||
|
], |
||||
|
playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]], |
||||
|
playerPhysicsControl: BetterCharacterControl, |
||||
|
appScheduler: monix.execution.Scheduler, |
||||
|
playerNode: Node @@ PlayerControllerTags.PlayerTag, |
||||
|
cameraNode: CameraNode @@ PlayerControllerTags.PlayerCameraNode, |
||||
|
tickEventBus: GameEventBus[TickEvent] |
||||
|
)(implicit timeout: Timeout, scheduler: Scheduler) { |
||||
|
val create: IO[Error, Unit] = |
||||
|
(for { |
||||
|
playerActor <- AkkaUtils.spawnActorL( |
||||
|
spawnProtocol, |
||||
|
"playerActorSupervisor", |
||||
|
new PlayerActorSupervisor.Props( |
||||
|
playerMovementEventBus, |
||||
|
playerCameraEventBus, |
||||
|
tickEventBus, |
||||
|
ImMovementActor |
||||
|
.Props(enqueueR, playerPhysicsControl) |
||||
|
.create, |
||||
|
wireWith(PlayerCameraEventListener.apply _) |
||||
|
).create(playerPhysicsControl) |
||||
|
) |
||||
|
_ <- IO { |
||||
|
physicsSpace += playerNode |
||||
|
physicsSpace += playerPhysicsControl |
||||
|
} |
||||
|
_ <- Task(rootNode += playerNode) |
||||
|
} yield ()) |
||||
|
.onErrorHandleWith(e => IO.raiseError(GenericError(e.getMessage()))) |
||||
|
.executeOn(appScheduler) |
||||
|
} |
||||
|
|
||||
|
def apply( |
||||
|
app: SimpleAppExt, |
||||
|
modelPath: os.RelPath, |
||||
|
cam: Camera |
||||
|
)(assetManager: AssetManager, bulletAppState: BulletAppState) = { |
||||
|
lazy val playerPos = ImVector3f.ZERO |
||||
|
lazy val playerPhysicsControl = new BetterCharacterControl(1.5f, 6f, 1f) |
||||
|
.withJumpForce(ImVector3f(0, 5f, 0)) |
||||
|
lazy val playerNode = new Node("PlayerNode") |
||||
|
.withChildren( |
||||
|
assetManager |
||||
|
.loadModel(modelPath) |
||||
|
.asInstanceOf[Node] |
||||
|
.withRotate(0, FastMath.PI, 0) |
||||
|
) |
||||
|
.withLocalTranslation(playerPos) |
||||
|
.withControl(playerPhysicsControl) |
||||
|
|
||||
|
{ |
||||
|
bulletAppState.physicsSpace += playerNode |
||||
|
bulletAppState.physicsSpace += playerPhysicsControl |
||||
|
} |
||||
|
|
||||
|
{ |
||||
|
app.rootNode += playerNode |
||||
|
} |
||||
|
|
||||
|
playerPhysicsControl |
||||
|
} |
||||
|
|
||||
|
object Defaults { |
||||
|
def defaultMesh = { |
||||
|
val b = Box(1, 1, 1) |
||||
|
val geom = Geometry("playerGeom", b) |
||||
|
geom |
||||
|
} |
||||
|
def defaultTexture(assetManager: AssetManager) = |
||||
|
MyMaterial( |
||||
|
assetManager = assetManager, |
||||
|
path = os.rel / "Common" / "MatDefs" / "Misc" / "Unshaded.j3md" |
||||
|
) |
||||
|
|
||||
|
def defaultCamerNode(cam: Camera, playerPos: ImVector3f) = |
||||
|
new CameraNode("CameraNode", cam) |
||||
|
.withControlDir(ControlDirection.SpatialToCamera) |
||||
|
.withLocalTranslation(ImVector3f(0, 1.5f, 10)) |
||||
|
.withLookAt(playerPos, ImVector3f.UNIT_Y) |
||||
|
|
||||
|
def defaultPlayerNode( |
||||
|
assetManager: AssetManager, |
||||
|
modelPath: os.RelPath, |
||||
|
playerPos: ImVector3f, |
||||
|
camNode: CameraNode, |
||||
|
playerPhysicsControl: BetterCharacterControl |
||||
|
) = |
||||
|
Either |
||||
|
.catchNonFatal( |
||||
|
Node("PlayerNode") |
||||
|
.withChildren( |
||||
|
camNode, |
||||
|
assetManager |
||||
|
.loadModel(modelPath) |
||||
|
.asInstanceOf[Node] |
||||
|
.withRotate(0, FastMath.PI, 0) |
||||
|
) |
||||
|
.withLocalTranslation(playerPos) |
||||
|
.withControl(playerPhysicsControl) |
||||
|
) |
||||
|
.map(_.taggedWith[PlayerControllerTags.PlayerTag]) |
||||
|
.leftMap(e => PlayerController.CouldNotCreatePlayerNode(e.getMessage())) |
||||
|
|
||||
|
def defaultNpcNode( |
||||
|
assetManager: AssetManager, |
||||
|
// modelPath: os.RelPath, |
||||
|
initialPos: ImVector3f, |
||||
|
npcPhysicsControl: BetterCharacterControl, |
||||
|
npcName: String |
||||
|
) = |
||||
|
Either |
||||
|
.catchNonFatal( |
||||
|
Node(npcName) |
||||
|
.withChildren( |
||||
|
// assetManager |
||||
|
// .loadModel(modelPath) |
||||
|
// .asInstanceOf[Node] |
||||
|
// .withRotate(0, FastMath.PI, 0) |
||||
|
defaultMesh.withMaterial(defaultTexture(assetManager)) |
||||
|
) |
||||
|
.withLocalTranslation(initialPos) |
||||
|
.withControl(npcPhysicsControl) |
||||
|
) |
||||
|
// .map(_.taggedWith[PlayerControllerTags.PlayerTag]) |
||||
|
// .leftMap(e => PlayerController.CouldNotCreatePlayerNode(e.getMessage())) |
||||
|
|
||||
|
def defaultPlayerPhysicsControl = |
||||
|
new BetterCharacterControl(1.5f, 6f, 1f) |
||||
|
.withJumpForce(ImVector3f(0, 5f, 0)) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
object Methods { |
||||
|
def spawnMovementActor( |
||||
|
enqueueR: Function1[() => Unit, Unit], |
||||
|
spawnProtocol: ActorRef[SpawnProtocol.Command], |
||||
|
movable: BetterCharacterControl @@ PlayerControllerTags.PlayerTag, |
||||
|
playerMovementEventBus: ActorRef[ |
||||
|
EventBus.Command[PlayerMovementEvent] |
||||
|
], |
||||
|
loggerL: Logger[Task] |
||||
|
)(implicit timeout: Timeout, scheduler: Scheduler) = |
||||
|
spawnProtocol.askL[ActorRef[ImMovementActor.Command]]( |
||||
|
SpawnProtocol.Spawn( |
||||
|
ImMovementActor.Props(enqueueR, movable).create, |
||||
|
"imMovementActor", |
||||
|
Props.empty, |
||||
|
_ |
||||
|
) |
||||
|
) |
||||
|
// def spawnPlayerActor( |
||||
|
// app: GameApp, |
||||
|
// spawnProtocol: ActorRef[SpawnProtocol.Command], |
||||
|
// movable: BetterCharacterControl @@ Player, |
||||
|
// playerMovementEventBus: ActorRef[ |
||||
|
// EventBus.Command[PlayerMovementEvent] |
||||
|
// ] |
||||
|
// )(implicit timeout: Timeout, scheduler: Scheduler) = |
||||
|
// spawnProtocol.askL[ActorRef[PlayerActorSupervisor.Command]]( |
||||
|
// SpawnProtocol.Spawn( |
||||
|
// new PlayerActorSupervisor.Props( |
||||
|
// app, |
||||
|
// movable, |
||||
|
// playerMovementEventBus |
||||
|
// ).create, |
||||
|
// "playerActor", |
||||
|
// Props.empty, |
||||
|
// _ |
||||
|
// ) |
||||
|
// ) |
||||
|
} |
||||
|
|
||||
|
// camNode <- IO( |
||||
|
// _cameraNode.getOrElse(defaultCamerNode(camera, initialPlayerPos)) |
||||
|
// ) |
||||
|
// playerPhysicsControl <- IO( |
||||
|
// _playerPhysicsControl |
||||
|
// .getOrElse(defaultPlayerPhysicsControl) |
||||
|
// .taggedWith[PlayerTag] |
||||
|
// ) |
||||
|
// playerNode <- IO.fromEither( |
||||
|
// _playerNode.fold( |
||||
|
// defaultPlayerNode( |
||||
|
// assetManager, |
||||
|
// modelPath, |
||||
|
// initialPlayerPos, |
||||
|
// camNode, |
||||
|
// playerPhysicsControl |
||||
|
// ) |
||||
|
// )(_.asRight) |
||||
|
// ) |
@ -1,222 +0,0 @@ |
|||||
package wow.doge.mygame.game.nodes |
|
||||
|
|
||||
import akka.actor.typed.ActorRef |
|
||||
import akka.actor.typed.Props |
|
||||
import akka.actor.typed.Scheduler |
|
||||
import akka.actor.typed.SpawnProtocol |
|
||||
import akka.util.Timeout |
|
||||
import cats.effect.concurrent.Ref |
|
||||
import cats.implicits._ |
|
||||
import com.jme3.asset.AssetManager |
|
||||
import com.jme3.bullet.BulletAppState |
|
||||
import com.jme3.bullet.control.BetterCharacterControl |
|
||||
import com.jme3.math.FastMath |
|
||||
import com.jme3.renderer.Camera |
|
||||
import com.jme3.scene.CameraNode |
|
||||
import com.jme3.scene.Geometry |
|
||||
import com.jme3.scene.Node |
|
||||
import com.jme3.scene.control.CameraControl.ControlDirection |
|
||||
import com.jme3.scene.shape.Box |
|
||||
import com.softwaremill.tagging._ |
|
||||
import io.odin.Logger |
|
||||
import monix.bio.IO |
|
||||
import monix.bio.Task |
|
||||
import wow.doge.mygame.events.EventBus |
|
||||
import wow.doge.mygame.game.GameApp |
|
||||
import wow.doge.mygame.implicits._ |
|
||||
import wow.doge.mygame.math.ImVector3f |
|
||||
import wow.doge.mygame.state.MyMaterial |
|
||||
import wow.doge.mygame.subsystems.events.EntityMovementEvent.PlayerMovementEvent |
|
||||
import wow.doge.mygame.subsystems.events.PlayerCameraEvent |
|
||||
import wow.doge.mygame.subsystems.movement.ImMovementActor |
|
||||
import wow.doge.mygame.utils.AkkaUtils |
|
||||
|
|
||||
// class PlayerNode(val name: String) extends Node(name) {} |
|
||||
sealed trait PlayerTag |
|
||||
sealed trait PlayerCameraNode |
|
||||
|
|
||||
object PlayerController { |
|
||||
sealed trait Error |
|
||||
case class GenericError(reason: String) extends Error |
|
||||
|
|
||||
class Props( |
|
||||
enqueueR: Function1[() => Unit, Unit], |
|
||||
rootNode: Ref[Task, Node], |
|
||||
camera: Camera, |
|
||||
loggerL: Logger[Task], |
|
||||
assetManager: AssetManager, |
|
||||
bulletAppState: BulletAppState, |
|
||||
initialPlayerPos: ImVector3f = ImVector3f.ZERO, |
|
||||
modelPath: os.RelPath, |
|
||||
spawnProtocol: ActorRef[SpawnProtocol.Command], |
|
||||
playerMovementEventBus: ActorRef[ |
|
||||
EventBus.Command[PlayerMovementEvent] |
|
||||
], |
|
||||
playerCameraEventBus: ActorRef[EventBus.Command[PlayerCameraEvent]], |
|
||||
_playerPhysicsControl: Option[BetterCharacterControl], |
|
||||
_playerNode: Option[Node with PlayerTag] = None, |
|
||||
_cameraNode: Option[CameraNode with PlayerCameraNode] = None, |
|
||||
appScheduler: monix.execution.Scheduler |
|
||||
)(implicit timeout: Timeout, scheduler: Scheduler) { |
|
||||
import Defaults._ |
|
||||
val create: IO[Error, Unit] = |
|
||||
// IO.raiseError(GenericError("not implemented yet")) |
|
||||
(for { |
|
||||
camNode <- IO( |
|
||||
_cameraNode.getOrElse(defaultCamerNode(camera, initialPlayerPos)) |
|
||||
) |
|
||||
playerPhysicsControl <- IO( |
|
||||
_playerPhysicsControl |
|
||||
.getOrElse(defaultPlayerPhysicsControl) |
|
||||
.taggedWith[PlayerTag] |
|
||||
) |
|
||||
playerNode <- IO.fromEither( |
|
||||
_playerNode.fold( |
|
||||
defaultPlayerNode( |
|
||||
assetManager, |
|
||||
modelPath, |
|
||||
initialPlayerPos, |
|
||||
camNode, |
|
||||
playerPhysicsControl |
|
||||
) |
|
||||
)(_.asRight) |
|
||||
) |
|
||||
playerActor <- AkkaUtils.spawnActorL( |
|
||||
spawnProtocol, |
|
||||
"playerActorSupervisor", |
|
||||
new PlayerActorSupervisor.Props( |
|
||||
enqueueR, |
|
||||
camNode, |
|
||||
playerMovementEventBus, |
|
||||
playerCameraEventBus |
|
||||
).create(playerPhysicsControl) |
|
||||
) |
|
||||
_ <- IO { |
|
||||
bulletAppState.physicsSpace += playerNode |
|
||||
bulletAppState.physicsSpace += playerPhysicsControl |
|
||||
} |
|
||||
_ <- rootNode.update(_ :+ playerNode) |
|
||||
} yield ()) |
|
||||
.onErrorHandleWith(e => IO.raiseError(GenericError(e.getMessage()))) |
|
||||
.executeOn(appScheduler) |
|
||||
} |
|
||||
|
|
||||
def apply( |
|
||||
app: GameApp, |
|
||||
modelPath: os.RelPath, |
|
||||
cam: Camera |
|
||||
)(assetManager: AssetManager, bulletAppState: BulletAppState) = { |
|
||||
lazy val playerPos = ImVector3f.ZERO |
|
||||
lazy val playerPhysicsControl = new BetterCharacterControl(1.5f, 6f, 1f) |
|
||||
.withJumpForce(ImVector3f(0, 5f, 0)) |
|
||||
lazy val playerNode = new Node("PlayerNode") |
|
||||
.withChildren( |
|
||||
assetManager |
|
||||
.loadModel(modelPath) |
|
||||
.asInstanceOf[Node] |
|
||||
.withRotate(0, FastMath.PI, 0) |
|
||||
) |
|
||||
.withLocalTranslation(playerPos) |
|
||||
.withControl(playerPhysicsControl) |
|
||||
|
|
||||
{ |
|
||||
bulletAppState.physicsSpace += playerNode |
|
||||
bulletAppState.physicsSpace += playerPhysicsControl |
|
||||
} |
|
||||
|
|
||||
{ |
|
||||
app.rootNode += playerNode |
|
||||
} |
|
||||
|
|
||||
playerPhysicsControl |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
object Defaults { |
|
||||
lazy val defaultMesh = { |
|
||||
val b = Box(1, 1, 1) |
|
||||
val geom = Geometry("playerMesh", b) |
|
||||
geom |
|
||||
} |
|
||||
def defaultTexture(assetManager: AssetManager) = |
|
||||
MyMaterial( |
|
||||
assetManager = assetManager, |
|
||||
path = os.rel / "Common" / "MatDefs" / "Misc" / "Unshaded.j3md" |
|
||||
) |
|
||||
|
|
||||
def defaultCamerNode(cam: Camera, playerPos: ImVector3f) = |
|
||||
new CameraNode("CameraNode", cam) |
|
||||
.withControlDir(ControlDirection.SpatialToCamera) |
|
||||
.withLocalTranslation(ImVector3f(0, 1.5f, 10)) |
|
||||
.withLookAt(playerPos, ImVector3f.UNIT_Y) |
|
||||
|
|
||||
def defaultPlayerNode( |
|
||||
assetManager: AssetManager, |
|
||||
modelPath: os.RelPath, |
|
||||
playerPos: ImVector3f, |
|
||||
camNode: CameraNode, |
|
||||
playerPhysicsControl: BetterCharacterControl |
|
||||
) = |
|
||||
Either.catchNonFatal( |
|
||||
Node("PlayerNode") |
|
||||
.withChildren( |
|
||||
camNode, |
|
||||
assetManager |
|
||||
.loadModel(modelPath) |
|
||||
.asInstanceOf[Node] |
|
||||
.withRotate(0, FastMath.PI, 0) |
|
||||
) |
|
||||
.withLocalTranslation(playerPos) |
|
||||
.withControl(playerPhysicsControl) |
|
||||
) |
|
||||
|
|
||||
lazy val defaultPlayerPhysicsControl = |
|
||||
new BetterCharacterControl(1.5f, 6f, 1f) |
|
||||
.withJumpForce(ImVector3f(0, 5f, 0)) |
|
||||
} |
|
||||
|
|
||||
object Methods { |
|
||||
def spawnMovementActor( |
|
||||
enqueueR: Function1[() => Unit, Unit], |
|
||||
spawnProtocol: ActorRef[SpawnProtocol.Command], |
|
||||
movable: BetterCharacterControl @@ PlayerTag, |
|
||||
playerMovementEventBus: ActorRef[ |
|
||||
EventBus.Command[PlayerMovementEvent] |
|
||||
], |
|
||||
loggerL: Logger[Task] |
|
||||
)(implicit timeout: Timeout, scheduler: Scheduler) = |
|
||||
spawnProtocol.askL[ActorRef[ImMovementActor.Command]]( |
|
||||
SpawnProtocol.Spawn( |
|
||||
ImMovementActor.Props(enqueueR, movable, playerMovementEventBus).create, |
|
||||
"imMovementActor", |
|
||||
Props.empty, |
|
||||
_ |
|
||||
) |
|
||||
) |
|
||||
// def spawnPlayerActor( |
|
||||
// app: GameApp, |
|
||||
// spawnProtocol: ActorRef[SpawnProtocol.Command], |
|
||||
// movable: BetterCharacterControl @@ Player, |
|
||||
// playerMovementEventBus: ActorRef[ |
|
||||
// EventBus.Command[PlayerMovementEvent] |
|
||||
// ] |
|
||||
// )(implicit timeout: Timeout, scheduler: Scheduler) = |
|
||||
// spawnProtocol.askL[ActorRef[PlayerActorSupervisor.Command]]( |
|
||||
// SpawnProtocol.Spawn( |
|
||||
// new PlayerActorSupervisor.Props( |
|
||||
// app, |
|
||||
// movable, |
|
||||
// playerMovementEventBus |
|
||||
// ).create, |
|
||||
// "playerActor", |
|
||||
// Props.empty, |
|
||||
// _ |
|
||||
// ) |
|
||||
// ) |
|
||||
} |
|
||||
// spawnPlayerActor( |
|
||||
// app, |
|
||||
// spawnProtocol, |
|
||||
// playerPhysicsControl, |
|
||||
// playerMovementEventBus |
|
||||
// ) |
|
@ -1,9 +0,0 @@ |
|||||
package wow.doge.mygame.game.subsystems.input |
|
||||
|
|
||||
object InputConstants { |
|
||||
val PLAYER_MOVE_LEFT = "PLAYER_MOVE_LEFT" |
|
||||
val PLAYER_MOVE_RIGHT = "PLAYER_MOVE_RIGHT" |
|
||||
val PLAYER_MOVE_FORWARD = "PLAYER_MOVE_FORWARD" |
|
||||
val PLAYER_MOVE_BACKWARD = "PLAYER_MOVE_BACKWARD" |
|
||||
val PLAYER_JUMP = "PLAYER_JUMP " |
|
||||
} |
|
@ -1,43 +1,15 @@ |
|||||
package wow.doge.mygame.game.subsystems.ui |
package wow.doge.mygame.game.subsystems.ui |
||||
|
|
||||
import com.jme3.app.Application |
|
||||
|
import scala.concurrent.duration._ |
||||
|
|
||||
import com.jayfella.jme.jfx.JavaFxUI |
import com.jayfella.jme.jfx.JavaFxUI |
||||
import scalafx.application.Platform |
|
||||
import monix.execution.CancelablePromise |
|
||||
import monix.bio.Task |
import monix.bio.Task |
||||
import cats.effect.concurrent.Deferred |
|
||||
import scala.concurrent.duration._ |
|
||||
import wow.doge.mygame.game.GameApp |
|
||||
|
import wow.doge.mygame.game.SimpleAppExt |
||||
|
|
||||
object JFxUI { |
object JFxUI { |
||||
def apply(app: GameApp) = |
|
||||
|
def apply(app: SimpleAppExt) = |
||||
Task(JavaFxUI.initialize(app)) |
Task(JavaFxUI.initialize(app)) |
||||
.executeOn(app.scheduler) >> Task.sleep(500.millis) >> Task( |
.executeOn(app.scheduler) >> Task.sleep(500.millis) >> Task( |
||||
JavaFxUI.getInstance() |
JavaFxUI.getInstance() |
||||
) |
) |
||||
// Task { |
|
||||
// Platform.runLater(() => { |
|
||||
// println("here jfx") |
|
||||
// JavaFxUI.initialize(app) |
|
||||
// println("here2 jfx2") |
|
||||
// val inst = JavaFxUI.getInstance() |
|
||||
// println(inst) |
|
||||
// }) |
|
||||
// } |
|
||||
// Task.fromFuture { |
|
||||
// val p = CancelablePromise[JavaFxUI]() |
|
||||
// Platform.runLater(() => { |
|
||||
// println("here") |
|
||||
// JavaFxUI.initialize(app) |
|
||||
// println("here2") |
|
||||
// val inst = JavaFxUI.getInstance() |
|
||||
// println(inst) |
|
||||
// p.success(inst) |
|
||||
// }) |
|
||||
// p.future |
|
||||
// } |
|
||||
// for { |
|
||||
// d <- Deferred[Task, JavaFxUI] |
|
||||
// _ <- Task(JavaFxUI.initialize(app)) |
|
||||
// } yield () |
|
||||
} |
} |
@ -1,18 +1,5 @@ |
|||||
package wow.doge.mygame.implicits |
package wow.doge.mygame.implicits |
||||
|
|
||||
import javafx.{ |
|
||||
collections => jfxc, |
|
||||
event => jfxe, |
|
||||
geometry => jfxg, |
|
||||
scene => jfxs, |
|
||||
util => jfxu |
|
||||
} |
|
||||
import javafx.scene.{input => jfxsi, layout => jfxsl, paint => jfxsp} |
|
||||
import scalafx.scene.Scene |
|
||||
import monix.execution.Cancelable |
|
||||
import monix.reactive.OverflowStrategy |
|
||||
import monix.reactive.Observable |
|
||||
import monix.execution.Ack |
|
||||
import scalafx.scene.control.Button |
|
||||
|
|
||||
|
|
||||
package object observables {} |
package object observables {} |
@ -1,14 +1,24 @@ |
|||||
package wow.doge.mygame.events |
|
||||
|
package wow.doge.mygame.subsystems.events |
||||
|
|
||||
object Events { |
|
||||
sealed trait Event |
|
||||
final case object BulletFired extends Event |
|
||||
|
sealed trait Event |
||||
|
final case object BulletFired extends Event |
||||
// type BulletFired = BulletFired.type |
// type BulletFired = BulletFired.type |
||||
final case class EventWithData(data: Int) extends Event |
|
||||
|
final case class EventWithData(data: Int) extends Event |
||||
|
|
||||
sealed trait Tick extends Event |
|
||||
object Tick { |
|
||||
final case object RenderTick extends Tick |
|
||||
final case object PhysicsTick extends Tick |
|
||||
} |
|
||||
|
sealed trait TickEvent extends Event |
||||
|
object TickEvent { |
||||
|
final case object RenderTick extends TickEvent |
||||
|
final case object PhysicsTick extends TickEvent |
||||
|
} |
||||
|
|
||||
|
sealed trait EntityMovementEvent extends Event |
||||
|
object EntityMovementEvent { |
||||
|
final case class MovedLeft(name: String, pressed: Boolean) |
||||
|
extends EntityMovementEvent |
||||
|
final case class MovedUp(name: String, pressed: Boolean) |
||||
|
extends EntityMovementEvent |
||||
|
final case class MovedRight(name: String, pressed: Boolean) |
||||
|
extends EntityMovementEvent |
||||
|
final case class MovedDown(name: String, pressed: Boolean) |
||||
|
extends EntityMovementEvent |
||||
} |
} |
@ -1,33 +0,0 @@ |
|||||
package wow.doge.mygame.subsystems.events |
|
||||
|
|
||||
import wow.doge.mygame.game.subsystems.movement.CanMove |
|
||||
|
|
||||
sealed trait EntityMovementEvent |
|
||||
object EntityMovementEvent { |
|
||||
final case class MovedLeft[T: CanMove](pressed: Boolean, movable: T) |
|
||||
extends EntityMovementEvent |
|
||||
final case class MovedUp[T: CanMove](pressed: Boolean, movable: T) |
|
||||
extends EntityMovementEvent |
|
||||
final case class MovedRight[T: CanMove](pressed: Boolean, movable: T) |
|
||||
extends EntityMovementEvent |
|
||||
final case class MovedDown[T: CanMove](pressed: Boolean, movable: T) |
|
||||
extends EntityMovementEvent |
|
||||
|
|
||||
sealed trait PlayerMovementEvent extends EntityMovementEvent |
|
||||
object PlayerMovementEvent { |
|
||||
final case class PlayerMovedLeft(pressed: Boolean) |
|
||||
extends PlayerMovementEvent |
|
||||
final case class PlayerMovedRight(pressed: Boolean) |
|
||||
extends PlayerMovementEvent |
|
||||
final case class PlayerMovedForward(pressed: Boolean) |
|
||||
extends PlayerMovementEvent |
|
||||
final case class PlayerMovedBackward(pressed: Boolean) |
|
||||
extends PlayerMovementEvent |
|
||||
final case object PlayerJumped extends PlayerMovementEvent |
|
||||
final case object PlayerRotatedRight extends PlayerMovementEvent |
|
||||
final case object PlayerRotatedLeft extends PlayerMovementEvent |
|
||||
final case object PlayerCameraUp extends PlayerMovementEvent |
|
||||
final case object PlayerCameraDown extends PlayerMovementEvent |
|
||||
|
|
||||
} |
|
||||
} |
|
@ -1,8 +1 @@ |
|||||
package wow.doge.mygame.subsystems.events |
package wow.doge.mygame.subsystems.events |
||||
|
|
||||
sealed trait PlayerCameraEvent |
|
||||
|
|
||||
object PlayerCameraEvent { |
|
||||
final case object CameraMovedUp extends PlayerCameraEvent |
|
||||
final case object CameraMovedDown extends PlayerCameraEvent |
|
||||
} |
|
@ -0,0 +1,24 @@ |
|||||
|
package wow.doge.mygame.subsystems.events |
||||
|
|
||||
|
sealed trait PlayerMovementEvent |
||||
|
object PlayerMovementEvent { |
||||
|
final case class PlayerMovedLeft(pressed: Boolean) extends PlayerMovementEvent |
||||
|
final case class PlayerMovedRight(pressed: Boolean) |
||||
|
extends PlayerMovementEvent |
||||
|
final case class PlayerMovedForward(pressed: Boolean) |
||||
|
extends PlayerMovementEvent |
||||
|
final case class PlayerMovedBackward(pressed: Boolean) |
||||
|
extends PlayerMovementEvent |
||||
|
final case object PlayerJumped extends PlayerMovementEvent |
||||
|
final case object PlayerRotatedRight extends PlayerMovementEvent |
||||
|
final case object PlayerRotatedLeft extends PlayerMovementEvent |
||||
|
final case object PlayerCameraUp extends PlayerMovementEvent |
||||
|
final case object PlayerCameraDown extends PlayerMovementEvent |
||||
|
} |
||||
|
|
||||
|
sealed trait PlayerCameraEvent |
||||
|
|
||||
|
object PlayerCameraEvent { |
||||
|
final case object CameraMovedUp extends PlayerCameraEvent |
||||
|
final case object CameraMovedDown extends PlayerCameraEvent |
||||
|
} |
@ -1,750 +0,0 @@ |
|||||
package wow.doge.mygame.utils |
|
||||
|
|
||||
/* |
|
||||
* Copyright (c) 2011-2019, ScalaFX Project |
|
||||
* All rights reserved. |
|
||||
* |
|
||||
* Redistribution and use in source and binary forms, with or without |
|
||||
* modification, are permitted provided that the following conditions are met: |
|
||||
* * Redistributions of source code must retain the above copyright |
|
||||
* notice, this list of conditions and the following disclaimer. |
|
||||
* * Redistributions in binary form must reproduce the above copyright |
|
||||
* notice, this list of conditions and the following disclaimer in the |
|
||||
* documentation and/or other materials provided with the distribution. |
|
||||
* * Neither the name of the ScalaFX Project nor the |
|
||||
* names of its contributors may be used to endorse or promote products |
|
||||
* derived from this software without specific prior written permission. |
|
||||
* |
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE SCALAFX PROJECT OR ITS CONTRIBUTORS BE LIABLE |
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||
*/ |
|
||||
|
|
||||
import javafx.scene.{input => jfxsi, layout => jfxsl, paint => jfxsp} |
|
||||
import javafx.{ |
|
||||
collections => jfxc, |
|
||||
event => jfxe, |
|
||||
geometry => jfxg, |
|
||||
scene => jfxs, |
|
||||
util => jfxu |
|
||||
} |
|
||||
import scalafx.Includes._ |
|
||||
import scalafx.beans.property.{ |
|
||||
ObjectProperty, |
|
||||
ReadOnlyDoubleProperty, |
|
||||
ReadOnlyObjectProperty |
|
||||
} |
|
||||
import scalafx.collections._ |
|
||||
import scalafx.delegate.SFXDelegate |
|
||||
import scalafx.geometry.NodeOrientation |
|
||||
import scalafx.scene.image.WritableImage |
|
||||
import scalafx.scene.input.{Dragboard, Mnemonic, TransferMode} |
|
||||
import scalafx.scene.paint.Paint |
|
||||
import com.goxr3plus.fxborderlessscene.borderless.{BorderlessScene => BScene} |
|
||||
|
|
||||
import scala.language.implicitConversions |
|
||||
import scalafx.scene.Cursor |
|
||||
import scalafx.scene._ |
|
||||
import scalafx.stage.Stage |
|
||||
import scalafx.stage.StageStyle |
|
||||
|
|
||||
object BorderlessScene { |
|
||||
implicit def sfxScene2jfx(v: BorderlessScene): Scene = |
|
||||
if (v != null) v.delegate else null |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Wraps [[http://docs.oracle.com/javase/8/javafx/api/javafx/scene/Scene.html]]. |
|
||||
* |
|
||||
* @constructor Create a new ScalaFX Scene with JavaFX Scene as delegate. |
|
||||
* @param delegate JavaFX Scene delegated. Its default value is a JavaFX Scene with a |
|
||||
* [[http://docs.oracle.com/javase/8/javafx/api/javafx/scene/Group.html Group]] as root Node. |
|
||||
*/ |
|
||||
class BorderlessScene( |
|
||||
override val delegate: BScene |
|
||||
) extends SFXDelegate[BScene] { |
|
||||
|
|
||||
def this(stage: Stage, stageStyle: StageStyle, parent: Parent) = |
|
||||
this(new BScene(stage, stageStyle, parent)) |
|
||||
|
|
||||
/** |
|
||||
* Returns the root Node of the scene graph |
|
||||
*/ |
|
||||
def root: ObjectProperty[jfxs.Parent] = delegate.rootProperty |
|
||||
|
|
||||
/** |
|
||||
* Sets the root Node of the scene graph |
|
||||
*/ |
|
||||
def root_=(v: Parent): Unit = { |
|
||||
root() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Returns Nodes children from this Scene's `root`. |
|
||||
*/ |
|
||||
def getChildren = |
|
||||
root.value match { |
|
||||
case group: jfxs.Group => group.getChildren |
|
||||
case pane: jfxsl.Pane => pane.getChildren |
|
||||
case _ => |
|
||||
throw new IllegalStateException( |
|
||||
"Cannot access children of root: " + root + "\n" + |
|
||||
"Use a class that extends Group or Pane, or override the getChildren method." |
|
||||
) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Returns scene's antialiasing setting. |
|
||||
*/ |
|
||||
def antialiasing: SceneAntialiasing = delegate.getAntiAliasing |
|
||||
|
|
||||
/** |
|
||||
* Returns Content's Node children from this Scene's `root`. |
|
||||
*/ |
|
||||
def content: jfxc.ObservableList[jfxs.Node] = getChildren |
|
||||
|
|
||||
/** |
|
||||
* Sets the list of Nodes children from this Scene's `root`, replacing the prior content. If you want append to |
|
||||
* current content, use `add` or similar. |
|
||||
* |
|
||||
* @param c list of Nodes children from this Scene's `root` to replace prior content. |
|
||||
*/ |
|
||||
def content_=(c: Iterable[Node]): Unit = { |
|
||||
fillSFXCollection(this.content, c) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Sets a Node child, replacing the prior content. If you want append to current content, use `add` or similar. |
|
||||
* |
|
||||
* @param n Node child to replace prior content. |
|
||||
*/ |
|
||||
def content_=(n: Node): Unit = { |
|
||||
fillSFXCollectionWithOne(this.content, n) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Specifies the type of camera use for rendering this `Scene`. |
|
||||
*/ |
|
||||
def camera: ObjectProperty[jfxs.Camera] = delegate.cameraProperty |
|
||||
|
|
||||
def camera_=(v: Camera): Unit = { |
|
||||
camera() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines the mouse cursor for this `Scene`. |
|
||||
*/ |
|
||||
def cursor: ObjectProperty[jfxs.Cursor] = delegate.cursorProperty |
|
||||
|
|
||||
def cursor_=(v: Cursor): Unit = { |
|
||||
cursor() = v |
|
||||
} |
|
||||
|
|
||||
/** The effective node orientation of a scene resolves the inheritance of node orientation, returning either left-to-right or right-to-left. */ |
|
||||
def effectiveNodeOrientation: ReadOnlyObjectProperty[jfxg.NodeOrientation] = |
|
||||
delegate.effectiveNodeOrientationProperty |
|
||||
|
|
||||
/** |
|
||||
* Specifies the event dispatcher for this scene. |
|
||||
*/ |
|
||||
def eventDispatcher: ObjectProperty[jfxe.EventDispatcher] = |
|
||||
delegate.eventDispatcherProperty |
|
||||
|
|
||||
def eventDispatcher_=(v: jfxe.EventDispatcher): Unit = { |
|
||||
eventDispatcher() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines the background fill of this Scene. |
|
||||
*/ |
|
||||
def fill: ObjectProperty[jfxsp.Paint] = delegate.fillProperty |
|
||||
|
|
||||
def fill_=(v: Paint): Unit = { |
|
||||
fill() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* The height of this Scene |
|
||||
*/ |
|
||||
def height: ReadOnlyDoubleProperty = delegate.heightProperty |
|
||||
|
|
||||
/** |
|
||||
* The width of this Scene |
|
||||
*/ |
|
||||
def width: ReadOnlyDoubleProperty = delegate.widthProperty |
|
||||
|
|
||||
def nodeOrientation: ObjectProperty[jfxg.NodeOrientation] = |
|
||||
delegate.nodeOrientationProperty |
|
||||
|
|
||||
def nodeOrientation_=(v: NodeOrientation): Unit = { |
|
||||
ObjectProperty.fillProperty[jfxg.NodeOrientation](this.nodeOrientation, v) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a mouse button has been clicked (pressed and released) on this `Scene`. |
|
||||
*/ |
|
||||
def onContextMenuRequested = delegate.onContextMenuRequestedProperty |
|
||||
|
|
||||
def onContextMenuRequested_=( |
|
||||
v: jfxe.EventHandler[_ >: jfxsi.ContextMenuEvent] |
|
||||
): Unit = { |
|
||||
onContextMenuRequested() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when drag gesture has been detected. |
|
||||
*/ |
|
||||
def onDragDetected = delegate.onDragDetectedProperty |
|
||||
|
|
||||
def onDragDetected_=(v: jfxe.EventHandler[_ >: jfxsi.MouseEvent]): Unit = { |
|
||||
onDragDetected() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when this `Scene` is a drag and drop gesture source after its data has been |
|
||||
* dropped on a drop target. |
|
||||
*/ |
|
||||
def onDragDone = delegate.onDragDoneProperty |
|
||||
|
|
||||
def onDragDone_=(v: jfxe.EventHandler[_ >: jfxsi.DragEvent]): Unit = { |
|
||||
onDragDone() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when the mouse button is released on this `Scene` during drag and drop gesture. |
|
||||
*/ |
|
||||
def onDragDropped = delegate.onDragDroppedProperty |
|
||||
|
|
||||
def onDragDropped_=(v: jfxe.EventHandler[_ >: jfxsi.DragEvent]): Unit = { |
|
||||
onDragDropped() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when drag gesture enters this Scene. |
|
||||
*/ |
|
||||
def onDragEntered = delegate.onDragEnteredProperty |
|
||||
|
|
||||
def onDragEntered_=(v: jfxe.EventHandler[_ >: jfxsi.DragEvent]): Unit = { |
|
||||
onDragEntered() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when drag gesture exits this Scene. |
|
||||
*/ |
|
||||
def onDragExited = delegate.onDragExitedProperty |
|
||||
|
|
||||
def onDragExited_=(v: jfxe.EventHandler[_ >: jfxsi.DragEvent]): Unit = { |
|
||||
onDragExited() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when drag gesture progresses within this `Scene`. |
|
||||
*/ |
|
||||
def onDragOver = delegate.onDragOverProperty |
|
||||
|
|
||||
def onDragOver_=(v: jfxe.EventHandler[_ >: jfxsi.DragEvent]): Unit = { |
|
||||
onDragOver() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when this `Node` has input focus and the input method text has changed. |
|
||||
*/ |
|
||||
def onInputMethodTextChanged = delegate.onInputMethodTextChangedProperty |
|
||||
|
|
||||
def onInputMethodTextChanged_=( |
|
||||
v: jfxe.EventHandler[_ >: jfxsi.InputMethodEvent] |
|
||||
): Unit = { |
|
||||
onInputMethodTextChanged() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when some `Node` of this `Scene` has input focus and a key has been pressed. |
|
||||
*/ |
|
||||
def onKeyPressed = delegate.onKeyPressedProperty |
|
||||
|
|
||||
def onKeyPressed_=(v: jfxe.EventHandler[_ >: jfxsi.KeyEvent]): Unit = { |
|
||||
onKeyPressed() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when some `Node` of this `Scene` has input focus and a key has been released. |
|
||||
*/ |
|
||||
def onKeyReleased = delegate.onKeyReleasedProperty |
|
||||
|
|
||||
def onKeyReleased_=(v: jfxe.EventHandler[_ >: jfxsi.KeyEvent]): Unit = { |
|
||||
onKeyReleased() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when some `Node` of this `Scene` has input focus and a key has been typed. |
|
||||
*/ |
|
||||
def onKeyTyped = delegate.onKeyTypedProperty |
|
||||
|
|
||||
def onKeyTyped_=(v: jfxe.EventHandler[_ >: jfxsi.KeyEvent]): Unit = { |
|
||||
onKeyTyped() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a mouse button has been clicked (pressed and released) on this `Scene`. |
|
||||
*/ |
|
||||
def onMouseClicked = delegate.onMouseClickedProperty |
|
||||
|
|
||||
def onMouseClicked_=(v: jfxe.EventHandler[_ >: jfxsi.MouseEvent]): Unit = { |
|
||||
onMouseClicked() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a mouse button is pressed on this `Scene` and then dragged. |
|
||||
*/ |
|
||||
def onMouseDragged = delegate.onMouseDraggedProperty |
|
||||
|
|
||||
def onMouseDragged_=(v: jfxe.EventHandler[_ >: jfxsi.MouseEvent]): Unit = { |
|
||||
onMouseDragged() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a full press-drag-release gesture enters this `Scene`. |
|
||||
*/ |
|
||||
def onMouseDragEntered = delegate.onMouseDragEnteredProperty |
|
||||
|
|
||||
def onMouseDragEntered_=( |
|
||||
v: jfxe.EventHandler[_ >: jfxsi.MouseDragEvent] |
|
||||
): Unit = { |
|
||||
onMouseDragEntered() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a full press-drag-release gesture exits this `Scene`. |
|
||||
*/ |
|
||||
def onMouseDragExited = delegate.onMouseDragExitedProperty |
|
||||
|
|
||||
def onMouseDragExited_=( |
|
||||
v: jfxe.EventHandler[_ >: jfxsi.MouseDragEvent] |
|
||||
): Unit = { |
|
||||
onMouseDragExited() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a full press-drag-release gesture progresses within this `Scene`. |
|
||||
*/ |
|
||||
def onMouseDragOver = delegate.onMouseDragOverProperty |
|
||||
|
|
||||
def onMouseDragOver_=( |
|
||||
v: jfxe.EventHandler[_ >: jfxsi.MouseDragEvent] |
|
||||
): Unit = { |
|
||||
onMouseDragOver() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a full press-drag-release gesture ends within this `Scene`. |
|
||||
*/ |
|
||||
def onMouseDragReleased = delegate.onMouseDragReleasedProperty |
|
||||
|
|
||||
def onMouseDragReleased_=( |
|
||||
v: jfxe.EventHandler[_ >: jfxsi.MouseDragEvent] |
|
||||
): Unit = { |
|
||||
onMouseDragReleased() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when the mouse enters this `Scene`. |
|
||||
*/ |
|
||||
def onMouseEntered = delegate.onMouseEnteredProperty |
|
||||
|
|
||||
def onMouseEntered_=(v: jfxe.EventHandler[_ >: jfxsi.MouseEvent]): Unit = { |
|
||||
onMouseEntered() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when the mouse exits this `Scene`. |
|
||||
*/ |
|
||||
def onMouseExited = delegate.onMouseExitedProperty |
|
||||
|
|
||||
def onMouseExited_=(v: jfxe.EventHandler[_ >: jfxsi.MouseEvent]): Unit = { |
|
||||
onMouseExited() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when mouse cursor moves within this `Scene` but no buttons have been pushed. |
|
||||
*/ |
|
||||
def onMouseMoved = delegate.onMouseMovedProperty |
|
||||
|
|
||||
def onMouseMoved_=(v: jfxe.EventHandler[_ >: jfxsi.MouseEvent]): Unit = { |
|
||||
onMouseMoved() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a mouse button has been pressed on this `Scene`. |
|
||||
*/ |
|
||||
def onMousePressed = delegate.onMousePressedProperty |
|
||||
|
|
||||
def onMousePressed_=(v: jfxe.EventHandler[_ >: jfxsi.MouseEvent]): Unit = { |
|
||||
onMousePressed() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a mouse button has been released on this `Scene`. |
|
||||
*/ |
|
||||
def onMouseReleased = delegate.onMouseReleasedProperty |
|
||||
|
|
||||
def onMouseReleased_=(v: jfxe.EventHandler[_ >: jfxsi.MouseEvent]): Unit = { |
|
||||
onMouseReleased() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when user performs a scrolling action. |
|
||||
*/ |
|
||||
def onScroll = delegate.onScrollProperty |
|
||||
|
|
||||
def onScroll_=(v: jfxe.EventHandler[_ >: jfxsi.ScrollEvent]): Unit = { |
|
||||
onScroll() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* The URL of the user-agent stylesheet that will be used by this Scene in place of the the platform-default |
|
||||
* user-agent stylesheet. If the URL does not resolve to a valid location, the platform-default user-agent |
|
||||
* stylesheet will be used. |
|
||||
* |
|
||||
* For additional information about using CSS with the scene graph, see the |
|
||||
* [[http://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.html CSS Reference Guide]]. |
|
||||
* |
|
||||
* @return The URL of the user-agent stylesheet that will be used by this SubScene, or null if has not been set. |
|
||||
*/ |
|
||||
def userAgentStylesheet: ObjectProperty[String] = |
|
||||
delegate.userAgentStylesheetProperty |
|
||||
|
|
||||
/** |
|
||||
* Set the URL of the user-agent stylesheet that will be used by this Scene in place of the the platform-default |
|
||||
* user-agent stylesheet. If the URL does not resolve to a valid location, the platform-default user-agent |
|
||||
* stylesheet will be used. |
|
||||
* |
|
||||
* For additional information about using CSS with the scene graph, see the |
|
||||
* [[http://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.html CSS Reference Guide]]. |
|
||||
* |
|
||||
* @param url The URL is a hierarchical URI of the form `[scheme:][//authority][path]`. |
|
||||
* If the URL does not have a `[scheme:]` component, the URL is considered to be the `[path]` |
|
||||
* component only. Any leading '/' character of the `[path]` is ignored and the `[path]` is |
|
||||
* treated as a path relative to the root of the application's classpath. |
|
||||
*/ |
|
||||
def userAgentStylesheet_=(url: String): Unit = { |
|
||||
ObjectProperty.fillProperty[String](userAgentStylesheet, url) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* The `Window` for this Scene |
|
||||
*/ |
|
||||
def window: ReadOnlyObjectProperty[javafx.stage.Window] = |
|
||||
delegate.windowProperty |
|
||||
|
|
||||
/** |
|
||||
* The horizontal location of this `Scene` on the `Window`. |
|
||||
*/ |
|
||||
def x: ReadOnlyDoubleProperty = delegate.xProperty |
|
||||
|
|
||||
/** |
|
||||
* The vertical location of this `Scene` on the `Window`. |
|
||||
*/ |
|
||||
def y: ReadOnlyDoubleProperty = delegate.yProperty |
|
||||
|
|
||||
/** |
|
||||
* Retrieves the depth buffer attribute for this scene. |
|
||||
*/ |
|
||||
def depthBuffer = delegate.isDepthBuffer |
|
||||
|
|
||||
/** |
|
||||
* Gets an observable list of string URLs linking to the stylesheets to use with this Parent's contents. |
|
||||
*/ |
|
||||
def stylesheets: jfxc.ObservableList[String] = delegate.getStylesheets |
|
||||
|
|
||||
/** |
|
||||
* Sets the list of stylesheets URLs, replacing the prior content. If you want append to current content, use `add` or |
|
||||
* similar. |
|
||||
* |
|
||||
* @param c list of stylesheets URLs to replace prior content. |
|
||||
*/ |
|
||||
def stylesheets_=(c: Iterable[String]): Unit = { |
|
||||
fillCollection(stylesheets, c) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Looks for any node within the scene graph based on the specified CSS selector. |
|
||||
* |
|
||||
* @param selector The css selector to look up |
|
||||
* @return A [[scala.Some]] containing the Node in the scene which matches the CSS selector, or [[scala.None]] |
|
||||
* if none is found. |
|
||||
*/ |
|
||||
def lookup(selector: String): Option[Node] = Option(delegate.lookup(selector)) |
|
||||
|
|
||||
/** |
|
||||
* Registers the specified mnemonic. |
|
||||
* |
|
||||
* @param m The Mnemonic |
|
||||
*/ |
|
||||
def addMnemonic(m: Mnemonic): Unit = { |
|
||||
delegate.addMnemonic(m) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Unregisters the specified mnemonic. |
|
||||
* |
|
||||
* @param m The Mnemonic to be removed. |
|
||||
*/ |
|
||||
def removeMnemonic(m: Mnemonic): Unit = { |
|
||||
delegate.removeMnemonic(m) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Gets the list of mnemonics for this `Scene`. |
|
||||
*/ |
|
||||
def getMnemonics |
|
||||
: jfxc.ObservableMap[jfxsi.KeyCombination, jfxc.ObservableList[ |
|
||||
jfxsi.Mnemonic |
|
||||
]] = delegate.getMnemonics |
|
||||
|
|
||||
/** |
|
||||
* Gets the list of accelerators for this Scene. |
|
||||
*/ |
|
||||
def accelerators: jfxc.ObservableMap[jfxsi.KeyCombination, Runnable] = |
|
||||
delegate.getAccelerators |
|
||||
|
|
||||
/** |
|
||||
* Confirms a potential drag and drop gesture that is recognized over this `Scene`. |
|
||||
* |
|
||||
* @param transferModes The supported `TransferMode`(s) of this `Node` |
|
||||
* @return A `Dragboard` to place this `Scene`'s data on |
|
||||
*/ |
|
||||
def startDragAndDrop(transferModes: TransferMode*): Dragboard = |
|
||||
delegate.startDragAndDrop(transferModes.map(_.delegate): _*) |
|
||||
|
|
||||
/** |
|
||||
* Starts a full press-drag-release gesture with this scene as gesture source. |
|
||||
*/ |
|
||||
def startFullDrag(): Unit = { |
|
||||
delegate.startFullDrag() |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* The scene's current focus owner node. This node's "focused" variable might be false if this scene has no window, |
|
||||
* or if the window is inactive (window.focused == false). |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def focusOwner: ReadOnlyObjectProperty[jfxs.Node] = |
|
||||
delegate.focusOwnerProperty() |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when user performs a rotation action. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onRotate = delegate.onRotateProperty |
|
||||
|
|
||||
def onRotate_=(v: jfxe.EventHandler[_ >: jfxsi.RotateEvent]): Unit = { |
|
||||
onRotate() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a rotation gesture ends. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onRotationFinished = delegate.onRotationFinishedProperty() |
|
||||
|
|
||||
def onRotationFinished_=( |
|
||||
v: jfxe.EventHandler[_ >: jfxsi.RotateEvent] |
|
||||
): Unit = { |
|
||||
onRotationFinished() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a rotation gesture starts. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onRotationStarted = delegate.onRotationFinishedProperty() |
|
||||
|
|
||||
def onRotationStarted_=( |
|
||||
v: jfxe.EventHandler[_ >: jfxsi.RotateEvent] |
|
||||
): Unit = { |
|
||||
onRotationStarted() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a Scroll gesture ends. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onScrollFinished = delegate.onScrollFinishedProperty() |
|
||||
|
|
||||
def onScrollFinished_=(v: jfxe.EventHandler[_ >: jfxsi.ScrollEvent]): Unit = { |
|
||||
onScrollFinished() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a Scroll gesture starts. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onScrollStarted = delegate.onScrollStartedProperty() |
|
||||
|
|
||||
def onScrollStarted_=(v: jfxe.EventHandler[_ >: jfxsi.ScrollEvent]): Unit = { |
|
||||
onScrollStarted() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a Swipe Down gesture starts. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onSwipeDown = delegate.onSwipeDownProperty() |
|
||||
|
|
||||
def onSwipeDown_=(v: jfxe.EventHandler[_ >: jfxsi.SwipeEvent]): Unit = { |
|
||||
onSwipeDown() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a Swipe Down gesture starts. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onSwipeLeft = delegate.onSwipeLeftProperty() |
|
||||
|
|
||||
def onSwipeLeft_=(v: jfxe.EventHandler[_ >: jfxsi.SwipeEvent]): Unit = { |
|
||||
onSwipeLeft() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a Swipe Up gesture starts. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onSwipeUp = delegate.onSwipeUpProperty() |
|
||||
|
|
||||
def onSwipeUp_=(v: jfxe.EventHandler[_ >: jfxsi.SwipeEvent]): Unit = { |
|
||||
onSwipeUp() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a Swipe Right gesture starts. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onSwipeRight = delegate.onSwipeRightProperty() |
|
||||
|
|
||||
def onSwipeRight_=(v: jfxe.EventHandler[_ >: jfxsi.SwipeEvent]): Unit = { |
|
||||
onSwipeRight() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when user performs a Touch action. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onZoom = delegate.onZoomProperty() |
|
||||
|
|
||||
def onZoom_=(v: jfxe.EventHandler[_ >: jfxsi.ZoomEvent]): Unit = { |
|
||||
onZoom() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a Zoom gesture ends. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onZoomFinished = delegate.onZoomFinishedProperty() |
|
||||
|
|
||||
def onZoomFinished_=(v: jfxe.EventHandler[_ >: jfxsi.ZoomEvent]): Unit = { |
|
||||
onZoomFinished() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when a Zoom gesture starts. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onZoomStarted = delegate.onZoomStartedProperty() |
|
||||
|
|
||||
def onZoomStarted_=(v: jfxe.EventHandler[_ >: jfxsi.ZoomEvent]): Unit = { |
|
||||
onZoomStarted() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when user performs a Touch Moved action. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onTouchMoved = delegate.onTouchMovedProperty() |
|
||||
|
|
||||
def onTouchMoved_=(v: jfxe.EventHandler[_ >: jfxsi.TouchEvent]): Unit = { |
|
||||
onTouchMoved() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when user performs a Touch Pressed action. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onTouchPressed = delegate.onTouchPressedProperty() |
|
||||
|
|
||||
def onTouchPressed_=(v: jfxe.EventHandler[_ >: jfxsi.TouchEvent]): Unit = { |
|
||||
onTouchPressed() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when user performs a Touch Released action. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onTouchReleased = delegate.onTouchReleasedProperty() |
|
||||
|
|
||||
def onTouchReleased_=(v: jfxe.EventHandler[_ >: jfxsi.TouchEvent]): Unit = { |
|
||||
onTouchReleased() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Defines a function to be called when user performs a Touch Stationary action. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def onTouchStationary = delegate.onTouchStationaryProperty() |
|
||||
|
|
||||
def onTouchStationary_=(v: jfxe.EventHandler[_ >: jfxsi.TouchEvent]): Unit = { |
|
||||
onTouchStationary() = v |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Takes a snapshot of this scene and returns the rendered image when it is ready. |
|
||||
* |
|
||||
* @param image The writable image that will be used to hold the rendered scene. |
|
||||
* @return the rendered image |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def snapshot(image: WritableImage): WritableImage = delegate.snapshot(image) |
|
||||
|
|
||||
/** |
|
||||
* Takes a snapshot of this scene at the next frame and calls the specified callback method when the image is ready. |
|
||||
* |
|
||||
* @param callback A function to be called when the image is ready. |
|
||||
* @param image The writable image that will be used to hold the rendered scene. |
|
||||
* |
|
||||
* @since 2.2 |
|
||||
*/ |
|
||||
def snapshot(callback: SnapshotResult => Unit, image: WritableImage): Unit = { |
|
||||
val javaCallback = new jfxu.Callback[jfxs.SnapshotResult, java.lang.Void] { |
|
||||
def call(result: jfxs.SnapshotResult): java.lang.Void = { |
|
||||
callback(new SnapshotResult(result)) |
|
||||
null |
|
||||
} |
|
||||
} |
|
||||
delegate.snapshot(javaCallback, image) |
|
||||
} |
|
||||
|
|
||||
} |
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue