first commit

This commit is contained in:
Rohan Sircar 2020-11-07 20:59:57 +05:30
commit 1f55e08fa5
53 changed files with 2862 additions and 0 deletions

View File

@ -0,0 +1,39 @@
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>*/
}

View File

@ -0,0 +1,45 @@
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>*/
}

View File

@ -0,0 +1,134 @@
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>*/
}

25
.gitignore vendored Normal file
View File

@ -0,0 +1,25 @@
*.class
*.log
# sbt specific
.cache/
.history/
.lib/
dist/*
target/
lib_managed/
src_managed/
project/boot/
project/plugins/project/
metals.sbt
.metals
.bloop
# Scala-IDE specific
.scala_dependencies
.worksheet
.idea/
.vscode
assets/
*.j3o

1
.scalafmt.conf Normal file
View File

@ -0,0 +1 @@
version = "2.6.4"

3
assets.jmp Normal file
View File

@ -0,0 +1,3 @@
#assets properties
#Fri Oct 23 22:34:43 IST 2020
assets.folder.name=src/main/resources/assets

192
build.sbt Normal file
View File

@ -0,0 +1,192 @@
// The simplest possible sbt build file is just one line:
scalaVersion := "2.13.3"
// That is, to create a valid sbt build, all you've got to do is define the
// version of Scala you'd like your project to use.
// ============================================================================
// Lines like the above defining `scalaVersion` are called "settings". Settings
// are key/value pairs. In the case of `scalaVersion`, the key is "scalaVersion"
// and the value is "2.13.1"
// It's possible to define many kinds of settings, such as:
// Note, it's not required for you to define these three settings. These are
// mostly only necessary if you intend to publish your library's binaries on a
// place like Sonatype or Bintray.
// Want to use a published library in your project?
// You can define other libraries as dependencies in your build like this:
resolvers += "Jcenter" at "https://jcenter.bintray.com/"
resolvers += "JME Bintray" at "https://bintray.com/jmonkeyengine/com.jme3"
resolvers += Resolver.mavenLocal
resolvers += Resolver.sonatypeRepo("snapshots")
lazy val jmeVersion = "3.3.2-stable"
lazy val osName = System.getProperty("os.name") match {
case n if n.startsWith("Linux") => "linux"
case n if n.startsWith("Mac") => "mac"
case n if n.startsWith("Windows") => "win"
case _ => throw new Exception("Unknown platform!")
}
lazy val javaFXModules =
Seq("base", "controls", "fxml", "graphics", "media", "swing", "web")
lazy val root = (project in file(".")).settings(
inThisBuild(
List(
scalaVersion := scalaVersion.value, // 2.11.12, or 2.13.3
semanticdbEnabled := true, // enable SemanticDB
semanticdbVersion := "4.3.24" // use Scalafix compatible version
)
),
name := "mygame",
organization := "wow.doge",
version := "1.0-SNAPSHOT",
libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2",
// https://mvnrepository.com/artifact/org.jmonkeyengine/jme3-core
"org.jmonkeyengine" % "jme3-core" % jmeVersion,
// https://mvnrepository.com/artifact/org.jmonkeyengine/jme3-desktop
"org.jmonkeyengine" % "jme3-desktop" % jmeVersion,
// https://mvnrepository.com/artifact/org.jmonkeyengine/jme3-lwjgl3
"org.jmonkeyengine" % "jme3-lwjgl3" % jmeVersion,
"org.jmonkeyengine" % "jme3-effects" % jmeVersion,
"org.jmonkeyengine" % "jme3-plugins" % jmeVersion,
"org.jmonkeyengine" % "jme3-blender" % jmeVersion,
// https://mvnrepository.com/artifact/com.github.stephengold/Minie
"com.github.stephengold" % "Minie" % "3.0.0",
// https://mvnrepository.com/artifact/com.simsilica/zay-es
"com.simsilica" % "zay-es" % "1.2.1",
"org.typelevel" %% "cats-core" % "2.1.1",
"com.lihaoyi" % "ammonite" % "2.2.0" cross CrossVersion.full,
"org.jetbrains.kotlin" % "kotlin-main-kts" % "1.4.10",
"org.jetbrains.kotlin" % "kotlin-scripting-jsr223" % "1.4.10",
// "wow.doge" % "game" % "1.0-SNAPSHOT",
"org.scalafx" %% "scalafx" % "14-R19",
"com.typesafe.akka" %% "akka-actor-typed" % "2.6.10",
"ch.qos.logback" % "logback-classic" % "1.2.3",
"org.typelevel" %% "cats-core" % "2.1.1",
"org.typelevel" %% "cats-effect" % "2.1.4",
"io.monix" %% "monix" % "3.2.2",
"io.monix" %% "monix-bio" % "1.0.0",
"io.circe" %% "circe-core" % "0.13.0",
"io.circe" %% "circe-generic" % "0.13.0",
"com.softwaremill.sttp.client" %% "core" % "2.2.5",
"com.softwaremill.sttp.client" %% "monix" % "2.2.5",
"com.softwaremill.sttp.client" %% "circe" % "2.2.5",
"com.softwaremill.sttp.client" %% "async-http-client-backend-monix" % "2.2.5",
"com.github.valskalla" %% "odin-monix" % "0.8.1",
"com.softwaremill.macwire" %% "util" % "2.3.7",
"com.softwaremill.macwire" %% "macros" % "2.3.6" % "provided",
"com.softwaremill.macwire" %% "macrosakka" % "2.3.6" % "provided",
"com.github.valskalla" %% "odin-slf4j" % "0.8.1",
"com.softwaremill.quicklens" %% "quicklens" % "1.6.1"
),
// Determine OS version of JavaFX binaries
// Add JavaFX dependencies
libraryDependencies ++= javaFXModules.map(m =>
"org.openjfx" % s"javafx-$m" % "14.0.1" classifier osName
),
scalacOptions ++= Seq(
"-encoding",
"UTF-8",
"-deprecation",
"-feature",
"-unchecked",
"-Xlint",
"-Ywarn-numeric-widen",
"-Ymacro-annotations",
// "utf-8", // Specify character encoding used by source files.
"-explaintypes" // Explain type errors in more detail.
),
javacOptions ++= Seq("-source", "11", "-target", "11"),
javaOptions ++= Seq("-Xmx2G", "-Xms2G"),
fork := true,
assemblyMergeStrategy in assembly := {
case PathList("javax", "servlet", xs @ _*) => MergeStrategy.first
case PathList(ps @ _*) if ps.last endsWith ".html" => MergeStrategy.first
case "application.conf" => MergeStrategy.concat
case "unwanted.txt" => MergeStrategy.discard
case x if Assembly.isConfigFile(x) =>
MergeStrategy.concat
case PathList("META-INF", xs @ _*) =>
(xs map { _.toLowerCase }) match {
case ("manifest.mf" :: Nil) | ("index.list" :: Nil) |
("dependencies" :: Nil) =>
MergeStrategy.discard
case ps @ (x :: xs)
if ps.last.endsWith(".sf") || ps.last.endsWith(".dsa") =>
MergeStrategy.discard
case "plexus" :: xs =>
MergeStrategy.discard
case "services" :: xs =>
MergeStrategy.filterDistinctLines
case ("spring.schemas" :: Nil) | ("spring.handlers" :: Nil) =>
MergeStrategy.filterDistinctLines
case _ => MergeStrategy.first // Changed deduplicate to first
}
case PathList(_*) => MergeStrategy.first
// case x =>
// val oldStrategy = (assemblyMergeStrategy in assembly).value
// oldStrategy(x)
}
// scalaVersion := "2.13.2", // 2.11.12, or 2.13.3
// semanticdbEnabled := true, // enable SemanticDB
// semanticdbVersion := scalafixSemanticdb.revision // use Scalafix compatible version
// semanticdbVersion := "4.3.24",
)
// Here, `libraryDependencies` is a set of dependencies, and by using `+=`,
// we're adding the scala-parser-combinators dependency to the set of dependencies
// that sbt will go and fetch when it starts up.
// Now, in any Scala file, you can import classes, objects, etc., from
// scala-parser-combinators with a regular import.
// TIP: To find the "dependency" that you need to add to the
// `libraryDependencies` set, which in the above example looks like this:
// "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2"
// You can use Scaladex, an index of all known published Scala libraries. There,
// after you find the library you want, you can just copy/paste the dependency
// information that you need into your build file. For example, on the
// scala/scala-parser-combinators Scaladex page,
// https://index.scala-lang.org/scala/scala-parser-combinators, you can copy/paste
// the sbt dependency from the sbt box on the right-hand side of the screen.
// IMPORTANT NOTE: while build files look _kind of_ like regular Scala, it's
// important to note that syntax in *.sbt files doesn't always behave like
// regular Scala. For example, notice in this build file that it's not required
// to put our settings into an enclosing object or class. Always remember that
// sbt is a bit different, semantically, than vanilla Scala.
// ============================================================================
// Most moderately interesting Scala projects don't make use of the very simple
// build file style (called "bare style") used in this build.sbt file. Most
// intermediate Scala projects make use of so-called "multi-project" builds. A
// multi-project build makes it possible to have different folders which sbt can
// be configured differently for. That is, you may wish to have different
// dependencies or different testing frameworks defined for different parts of
// your codebase. Multi-project builds make this possible.
// Here's a quick glimpse of what a multi-project build looks like for this
// build, with only one "subproject" defined, called `root`:
// lazy val root = (project in file(".")).
// settings(
// inThisBuild(List(
// organization := "ch.epfl.scala",
// scalaVersion := "2.13.1"
// )),
// name := "hello-world"
// )
// To learn more about multi-project builds, head over to the official sbt
// documentation at http://www.scala-sbt.org/documentation.html

BIN
libbulletjme.so Normal file

Binary file not shown.

1
project/build.properties Normal file
View File

@ -0,0 +1 @@
sbt.version=1.3.13

2
project/plugins.sbt Normal file
View File

@ -0,0 +1,2 @@
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.23")

View File

@ -0,0 +1 @@
org.jetbrains.kotlin.mainKts.jsr223.KotlinJsr223MainKtsScriptEngineFactory

View File

@ -0,0 +1,7 @@
jme-dispatcher {
type = "Dispatcher"
name = "JME-Thread"
executor = "wow.doge.mygame.executors.JMEThreadExecutorServiceConfigurator"
throughput = 1
}
akka.jvm-exit-on-fatal-error = on

View File

@ -0,0 +1,2 @@
// println("hello from dep")
class Test(x: Int)

View File

@ -0,0 +1,36 @@
// @file:Import("src/main/resources/hello2.main.kts")
@file:DependsOn("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.0-M1")
@file:DependsOn("/home/rohan/.m2/repository/wow/doge/game/1.0-SNAPSHOT/game-1.0-SNAPSHOT.jar")
@file:DependsOn("/home/rohan/.ivy2/local/wow.doge/mygame_2.13/1.0-SNAPSHOT/jars/mygame_2.13.jar")
import wow.doge.game.types.GameScript
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlin.random.Random
import wow.doge.mygame.components.Test
//println(x * 2)
println("hello from main script")
class GameScriptImpl : GameScript {
override fun start() = runBlocking {
for(x in 0 until 5) {
launch {
val del = Random.nextLong(20, 100)
delay(del)
println("hello from start $x, delay is $del")
}
}
}
override fun stop() {println("hello from stop")}
}
GameScriptImpl()
class MyTest : Test()

View File

@ -0,0 +1,35 @@
// #!/usr/bin/env amm
// import coursierapi.MavenRepository
// interp.repositories.update(
// interp.repositories() ::: List(
// MavenRepository.of("file://home/rohan/.m2/repository")
// )
// )
// @
// import $repo.`https://jcenter.bintray.com`
// // import $repo.`https://bintray.com/jmonkeyengine/com.jme3`
// import $file.dep
// import $ivy.`org.jmonkeyengine:jme3-core:3.2.4-stable`
// import $ivy.`wow.doge:game:1.0-SNAPSHOT`
// 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 $file.dep
import dep.Test
new Test(1)

View File

@ -0,0 +1,5 @@
println("hello from dep")
class Test(val x: Int)
var x = 2

View File

@ -0,0 +1,107 @@
#!/usr/bin/env amm
// import coursierapi.MavenRepository
// interp.repositories.update(
// interp.repositories() ::: List(
// MavenRepository.of("file://home/rohan/.m2/repository")
// )
// )
// @
import $repo.`https://jcenter.bintray.com`
// import $repo.`https://bintray.com/jmonkeyengine/com.jme3`
// import $file.dep
import $ivy.`org.jmonkeyengine:jme3-core:3.2.4-stable`
// import $ivy.`wow.doge:game:1.0-SNAPSHOT`
import $ivy.`wow.doge::mygame:1.0-SNAPSHOT`
// 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()

View File

@ -0,0 +1,19 @@
{
"record": "Weapon",
"values": {
"baseId": "4F00000062",
"weaponType": "sword",
"name": "Exquisite Steel Sword",
"attack": "40",
"weight": "20"
}
}
val entity = ed.createEntity()
entity.setComponents(
Record("Weapon"),
WeaponType("Sword"),
Name("Exquisite Steel Sword"),
Attack(40),
Weight(20)
)

View File

@ -0,0 +1,62 @@
package com.jme3
import com.jme3.input.Action
package object animation {
implicit class AnimChannelWrap(val uval: AnimChannel) extends AnyVal {
/**
* Set the current animation that is played by this AnimChannel.
* <p>
* See {@link #setAnim(java.lang.String, float)}.
* The blendTime argument by default is 150 milliseconds.
*
* @param action The action (name) of the animation to play
*/
def setAnim(action: Action): Unit = uval.setAnim(action.name)
/**
* Set the current animation that is played by this AnimChannel.
* <p>
* This resets the time to zero, and optionally blends the animation
* over <code>blendTime</code> seconds with the currently playing animation.
* Notice that this method will reset the control's speed to 1.0.
*
* @param action The action (name) of the animation to play
* @param blendTime The blend time over which to blend the new animation
* with the old one. If zero, then no blending will occur and the new
* animation will be applied instantly.
*/
def setAnim(action: Action, blendTime: Float): Unit = uval.setAnim(action.name, blendTime)
}
implicit class AnimEventListenerWrap(val uval: AnimEventListener) extends AnyVal {
/**
* Invoked when an animation "cycle" is done. For non-looping animations,
* this event is invoked when the animation is finished playing. For
* looping animations, this even is invoked each time the animation is restarted.
*
* @param control The control to which the listener is assigned.
* @param channel The channel being altered
* @param action The new animation action that is done.
*/
def onAnimCycleDone(control: AnimControl, channel: AnimChannel, action: Action): Unit =
uval.onAnimCycleDone(control, channel, action.name)
/**
* Invoked when a animation is set to play by the user on the given channel.
*
* @param control The control to which the listener is assigned.
* @param channel The channel being altered
* @param action The new animation action set.
*/
def onAnimChange(control: AnimControl, channel: AnimChannel, action: Action): Unit =
uval.onAnimChange(control, channel, action.name)
}
}

View File

@ -0,0 +1,16 @@
package com.jme3
/**
* Created by Brandon Barker on 6/19/17.
*/
package object app {
implicit class SimpleApplicationWrap(val uval: SimpleApplication) extends AnyVal {
//FIXME: proof of concept, remove later
def testWrap: String = uval.hashCode().toString
}
}

View File

@ -0,0 +1,6 @@
package com.jme3.input
/**
* Created by Brandon Barker on 6/19/17.
*/
final case class Action(name: String) extends AnyVal

View File

@ -0,0 +1,37 @@
package com.jme3.input
/**
* Created by Brandon Barker on 6/19/17.
*/
package object controls {
implicit class ActionListenerWrap(val uval: ActionListener) extends AnyVal {
/**
* Called when an input to which this listener is registered to is invoked.
*
* @param action The action (name) of the mapping that was invoked
* @param isPressed True if the action is "pressed", false otherwise
* @param tpf The time per frame value.
*/
def onAction(action: Action, keyPressed: Boolean, tpf: Float): Unit =
uval.onAction(action.name, keyPressed, tpf)
}
implicit class AnalogListenerWrap(val uval: AnalogListener) extends AnyVal {
/**
* Called to notify the implementation that an analog event has occurred.
*
* The results of KeyTrigger and MouseButtonTrigger events will have tpf
* == value.
*
* @param action The action (name) of the mapping that was invoked
* @param value Value of the axis, from 0 to 1.
* @param tpf The time per frame value.
*/
def onAnalog(action: Action, value: Float, tpf: Float): Unit =
uval.onAnalog(action.name, value, tpf)
}
}

View File

@ -0,0 +1,18 @@
package com.jme3
import com.jme3.input.controls.{InputListener, Trigger}
/**
* Created by Brandon Barker on 6/21/17.
*/
package object input {
implicit class InputManagerWrap(val uval: InputManager) extends AnyVal {
def addMapping(action: Action, triggers: Trigger*): Unit =
uval.addMapping(action.name, triggers: _*)
def addListener(listener: InputListener, actions: Action*): Unit =
uval.addListener(listener, actions.map(act => act.name): _*)
}
}

View File

@ -0,0 +1,11 @@
package com.jme3
import com.jme3.asset.AssetManager
package object material {
object Material {
def apply(contentMan: AssetManager, defName: String): Material =
new Material(contentMan, defName)
}
}

View File

@ -0,0 +1,19 @@
package com.jme3.scene
import com.jme3.animation.Skeleton
package object debug {
object SkeletonDebugger {
/**
* Creates a debugger with no length data. The wires will be a connection between the bones' heads only.
* The points will show the bones' heads only and no dotted line of inter bones connection will be visible.
* @param name
* the name of the debugger's node
* @param skeleton
* the skeleton that will be shown
*/
def apply(name: String, skeleton: Skeleton) = new SkeletonDebugger(name, skeleton)
}
}

View File

@ -0,0 +1,56 @@
package com.jme3
import com.jme3.scene.control.Control
/**
* Created by Brandon Barker on 6/19/17.
*/
package object scene {
object Geometry {
/**
* Create a geometry node with mesh data.
* The material of the geometry is null, it cannot
* be rendered until it is set.
*
* @param name The name of this geometry
* @param mesh The mesh data for this geometry
*/
def apply(name: String, mesh: Mesh): Geometry = new Geometry(name, mesh)
}
object Node {
/**
* Constructor instantiates a new <code>Node</code> with a default empty
* list for containing children.
*
* @param name the name of the scene element. This is required for
* identification and comparison purposes.
*/
def apply(name: String): Node = new Node(name)
}
implicit class NodeWrap(val uval: Node) extends AnyVal {
def getControlMaybe[T <: Control](controlType: Class[T]): Option[T] =
Option(uval.getControl(controlType))
}
implicit class SpatialWrap(val uval: Spatial) extends AnyVal {
def toNode: Either[ClassCastException, Node] =
uval match {
case ul: Node => Right(ul)
case ul =>
Left(
new ClassCastException(s"Couldn't convert ${ul.getName} to Node")
)
}
}
}

View File

@ -0,0 +1,20 @@
package com.jme3.scene
package object shape {
object Box {
/**
* Creates a new box.
* <p>
* The box has a center of 0,0,0 and extends in the out from the center by
* the given amount in <em>each</em> direction. So, for example, a box
* with extent of 0.5 would be the unit cube.
*
* @param xs the size of the box along the x axis, in both directions.
* @param ys the size of the box along the y axis, in both directions.
* @param zs the size of the box along the z axis, in both directions.
*/
def apply(xs: Float, ys: Float, zs: Float): Box = new Box(xs, ys, zs)
}
}

View File

@ -0,0 +1,14 @@
package com.jme3
/**
* Created by Brandon Barker on 6/21/17.
*/
package object syntax {
@specialized def discard[A](evaluateForSideEffectOnly: A): Unit = {
val _: A = evaluateForSideEffectOnly
() //Return unit to prevent warning due to discarding value
}
}

View File

@ -0,0 +1,5 @@
Hey guys, few days ago I discovered I could load objects created in scripts at runtime, and cast them to an interface to call their methods provided
1. both host program and script have access to the same interface via a common library
2. script object implements that interface
I was thinking, maybe I could implement appstates in scripts to implement game mechanics and attach them to the state manager at runtime, and similarly for components of an ECS. What do you guys think?

View File

@ -0,0 +1,127 @@
package wow.doge.mygame
import game.GameApp
import com.jme3.app.StatsAppState
import akka.actor.typed.ActorSystem
import akka.actor.typed.SpawnProtocol
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.Behavior
import akka.util.Timeout
import com.jme3.system.AppSettings
import wow.doge.mygame.game.GameAppActor
import wow.doge.mygame.scriptsystem.ScriptCachingActor
object Main extends App {
import java.util.logging.{Logger, Level}
Logger.getLogger("").setLevel(Level.SEVERE)
// runner.runCode("""|println("starting scala script engine")""".stripMargin)
val gameApp = new GameApp(
// new EntityDataState(),
// new TestAppState(),
// new PlayerMovementState(),
// new FlyCamAppState(),
new StatsAppState()
)
val settings = new AppSettings(true)
// settings.setVSync(true)
settings.setFrameRate(144)
gameApp.setSettings(settings)
val actorSystem = ActorSystem(RootActor(gameApp), "rootActor")
// actorSystem.eventStream
// gameApp.start()
println("here 1")
// actorSystem.terminate()
// JMEExecutorService.shutdown()
// println("here 2")
//FIXME remove this
// System.exit(0)
}
object RootActor {
def apply(app: GameApp): Behavior[SpawnProtocol.Command] =
Behaviors.setup { ctx =>
ctx.log.debug("Starting root actor")
val testActor = ctx.spawn(TestActor(), "testActor")
val _ = ctx.spawn(GameAppActor(app), "gameAppActor")
testActor ! TestActor.Test
SpawnProtocol()
}
}
object TestActor {
sealed trait Command
case object Test extends Command
private case object Done extends Command
// sealed trait Result
// case object Done extends Result
import scala.concurrent.duration._
implicit val timeout = Timeout(15.seconds)
// implicit val scheduler =
def apply(): Behavior[Command] =
Behaviors.setup { ctx =>
ctx.spawn(ScriptCachingActor(), "scriptCacher")
Behaviors.receiveMessage { msg =>
msg match {
case Test =>
// ctx.ask(
// router,
// ScriptActor.Compile(
// // os.pwd / "some.sc",
// os.pwd / "src" / "main" / "resources" / "hello2.main.kts",
// _
// )
// ) {
// case Success(value) =>
// ctx.log.debug("Received Value")
// ctx.log.debug(value.toString())
// Done
// case Failure(exception) =>
// ctx.log.debug(s"Received Error ${exception.getMessage()}")
// Done
// }
// val x = scriptStorer
// .askT(
// ScriptStoringActor
// .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
// )(timeout, ctx.system.scheduler)
// ctx.ask(
// scriptStorer,
// ScriptStoringActor
// .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
// ) {
// case Success(value) => {
// ctx.log.debug(value.toString())
// ctx.ask(
// scriptStorer,
// ScriptStoringActor
// .Get(os.pwd / "src" / "main" / "resources" / "hello2.sc", _)
// ) {
// case Success(value) => {
// ctx.log.debug(value.toString())
// Done
// }
// case Failure(exception) =>
// ctx.log.debug(exception.getMessage())
// Done
// }
// Done
// }
// case Failure(exception) =>
// ctx.log.debug(exception.getMessage())
// Done
// }
Behaviors.same
case Done => Behaviors.same
}
// SpawnProtocol()
// Behaviors.same
}
}
}

View File

@ -0,0 +1,6 @@
package wow.doge.mygame.components
import com.simsilica.es.EntityComponent;
import wow.doge.mygame.math.ImVector3f
final case class Position(location: ImVector3f) extends EntityComponent

View File

@ -0,0 +1,28 @@
package wow.doge.mygame.components
import com.simsilica.es.EntityComponent
final case class Tag(name: String) extends EntityComponent
object Tag {
val SpaceShip = "SpaceShip"
val BasicInvader = "BasicInvader"
}
// public class Model implements EntityComponent {
// private final String name;
// public final static String SpaceShip = "SpaceShip";
// public final static String BasicInvader = "BasicInvader";
// public Model(String name) {
// this.name = name;
// }
// public String getName() {
// return name;
// }
// @Override
// public String toString() {
// return "Model[" + name + "]";
// }
// }

View File

@ -0,0 +1,11 @@
package wow.doge.mygame.components;
import com.jme3.math.Vector3f;
import wow.doge.mygame.math.ImVector3f;
//test java final case class instantiation
public class Test {
public void test() {
var pos = Position.apply(ImVector3f.apply(1, 1, 1));
}
}

View File

@ -0,0 +1,5 @@
package wow.doge.mygame.components
import com.simsilica.es.EntityComponent
final case class TestComponent() extends EntityComponent

View File

@ -0,0 +1,139 @@
package wow.doge.mygame.events
// import akka.event.ActorEventBus
// import akka.event.ManagedActorClassification
// import akka.event.ActorClassifier
import akka.actor.typed.ActorRef
// import akka.actor.ActorSystem
// import akka.event.EventBus
// import akka.util.Subclassification
// import java.util.concurrent.atomic.AtomicReference
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.Behaviors
import scala.reflect.ClassTag
import akka.event.EventStream
// private[events] final case class ClassificationMessage(ref: ActorRef, id: Int)
// class ActorBusImpl(val system: ActorSystem, val busSize: Int)
// extends ActorEventBus
// with ActorClassifier
// with ManagedActorClassification {
// type Event = ClassificationMessage
// // is used for extracting the classifier from the incoming events
// override protected def classify(event: Event): ActorRef = event.ref
// // determines the initial size of the index data structure
// // used internally (i.e. the expected number of different classifiers)
// override protected def mapSize: Int = busSize
// }
// class StartsWithSubclassification extends Subclassification[String] {
// override def isEqual(x: String, y: String): Boolean =
// x == y
// override def isSubclass(x: String, y: String): Boolean =
// x.startsWith(y)
// }
// import akka.event.SubchannelClassification
// final case class MsgEnvelope(topic: String, payload: Any)
// import akka.actor.typed.scaladsl.adapter._
// /**
// * Publishes the payload of the MsgEnvelope when the topic of the
// * MsgEnvelope starts with the String specified when subscribing.
// */
// class SubchannelBusImpl extends EventBus with SubchannelClassification {
// type Event = Any
// type Classifier = Class[_]
// type Subscriber = ActorRef
// // Subclassification is an object providing `isEqual` and `isSubclass`
// // to be consumed by the other methods of this classifier
// // override protected val subclassification: Subclassification[Classifier] =
// // new StartsWithSubclassification
// private val initiallySubscribedOrUnsubscriber =
// new AtomicReference[Either[Set[ActorRef], ActorRef]](Left(Set.empty))
// override protected implicit val subclassification
// : Subclassification[Classifier] = new Subclassification[Class[_]] {
// def isEqual(x: Class[_], y: Class[_]) = x == y
// def isSubclass(x: Class[_], y: Class[_]) = y.isAssignableFrom(x)
// }
// // is used for extracting the classifier from the incoming events
// override protected def classify(event: Event): Classifier = event.getClass()
// // will be invoked for each event for all subscribers which registered
// // themselves for the events classifier
// override protected def publish(event: Event, subscriber: Subscriber): Unit = {
// // subscriber ! event.payload
// subscriber ! event
// }
// }
object EventBus {
sealed trait Command[A]
final case class Publish[A, E <: A](event: E, publisher: ActorRef[_])
extends Command[A]
/**
* Subscribe a typed actor to listen for types or subtypes of E
* by sending this command to the [[akka.actor.typed.ActorSystem.eventStream]].
*
* ==Simple example==
* {{{
* sealed trait A
* case object A1 extends A
* //listen for all As
* def subscribe(actorSystem: ActorSystem[_], actorRef: ActorRef[A]) =
* actorSystem.eventStream ! EventStream.Subscribe(actorRef)
* //listen for A1s only
* def subscribe(actorSystem: ActorSystem[_], actorRef: ActorRef[A]) =
* actorSystem.eventStream ! EventStream.Subscribe[A1](actorRef)
* }}}
*/
final case class Subscribe[A, E <: A](subscriber: ActorRef[E])(implicit
classTag: ClassTag[E]
) extends Command[A] {
def topic: Class[_] = classTag.runtimeClass
}
/**
* Unsubscribe an actor ref from the event stream
* by sending this command to the [[akka.actor.typed.ActorSystem.eventStream]].
*/
final case class Unsubscribe[A, E <: A](subscriber: ActorRef[E])
extends Command[A]
def apply[A](): Behavior[EventBus.Command[A]] =
Behaviors.setup { ctx =>
val eventStream = new EventStream(ctx.system.classicSystem)
new EventBus().eventStreamBehavior(eventStream)
}
}
class EventBus[B] {
import akka.actor.typed.scaladsl.adapter._
private def eventStreamBehavior(
eventStream: akka.event.EventStream
): Behavior[EventBus.Command[B]] =
Behaviors.receiveMessage {
case EventBus.Publish(event, publisher) =>
eventStream.publish(event)
Behaviors.same
case s @ EventBus.Subscribe(subscriber) =>
eventStream.subscribe(subscriber.toClassic, s.topic)
Behaviors.same
case EventBus.Unsubscribe(subscriber) =>
eventStream.unsubscribe(subscriber.toClassic)
Behaviors.same
}
}

View File

@ -0,0 +1,17 @@
package wow.doge.mygame.events
// object Test {
// Events.BulletFired
// }
object Events {
sealed trait Event
case object BulletFired extends Event
// type BulletFired = BulletFired.type
case class EventWithData(data: Int) extends Event
sealed trait Tick extends Event
case object RenderTick extends Tick
case object PhysicsTick extends Tick
}

View File

@ -0,0 +1,3 @@
package wow.doge.mygame.events
trait EventsModule {}

View File

@ -0,0 +1,5 @@
package wow.doge.mygame.executors
trait ExecutorsModule {
lazy val schedulers = new Schedulers()
}

View File

@ -0,0 +1,103 @@
package wow.doge.mygame.executors
import akka.dispatch.{
DispatcherPrerequisites,
ExecutorServiceFactory,
ExecutorServiceConfigurator
}
import com.typesafe.config.Config
import java.util.concurrent.{
ExecutorService,
AbstractExecutorService,
ThreadFactory,
TimeUnit
}
import java.util.Collections
import javax.swing.SwingUtilities
import javafx.application.Platform
import monix.execution.Scheduler
import scala.concurrent.ExecutionContext
import java.util.concurrent.Executor
import wow.doge.mygame.Main
// First we wrap invokeLater/runLater as an ExecutorService
trait GUIExecutorService extends AbstractExecutorService {
def execute(command: Runnable): Unit
def shutdown(): Unit = ()
def shutdownNow() = Collections.emptyList[Runnable]
def isShutdown = false
def isTerminated = false
def awaitTermination(l: Long, timeUnit: TimeUnit) = true
}
object JavaFXExecutorService extends GUIExecutorService {
override def execute(command: Runnable) = Platform.runLater(command)
}
object SwingExecutorService extends GUIExecutorService {
override def execute(command: Runnable) = SwingUtilities.invokeLater(command)
}
object JMEExecutorService extends GUIExecutorService {
override def execute(command: Runnable) = Main.gameApp.enqueue(command)
}
class JavaFXEventThreadExecutorServiceConfigurator(
config: Config,
prerequisites: DispatcherPrerequisites
) extends ExecutorServiceConfigurator(config, prerequisites) {
private val f = new ExecutorServiceFactory {
def createExecutorService: ExecutorService = JavaFXExecutorService
}
def createExecutorServiceFactory(
id: String,
threadFactory: ThreadFactory
): ExecutorServiceFactory = f
}
class JMEThreadExecutorServiceConfigurator(
config: Config,
prerequisites: DispatcherPrerequisites
) extends ExecutorServiceConfigurator(config, prerequisites) {
private val f = new ExecutorServiceFactory {
def createExecutorService: ExecutorService = JMEExecutorService
}
def createExecutorServiceFactory(
id: String,
threadFactory: ThreadFactory
): ExecutorServiceFactory = f
}
// Then we create an ExecutorServiceConfigurator so that Akka can use our SwingExecutorService for the dispatchers
class SwingEventThreadExecutorServiceConfigurator(
config: Config,
prerequisites: DispatcherPrerequisites
) extends ExecutorServiceConfigurator(config, prerequisites) {
private val f = new ExecutorServiceFactory {
def createExecutorService: ExecutorService = SwingExecutorService
}
def createExecutorServiceFactory(
id: String,
threadFactory: ThreadFactory
): ExecutorServiceFactory = f
}
object JFXExecutionContexts {
val javaFxExecutionContext: ExecutionContext =
ExecutionContext.fromExecutor(new Executor {
def execute(command: Runnable): Unit = {
Platform.runLater(command)
}
})
val fxScheduler =
Scheduler(javaFxExecutionContext)
}