many changes
This commit is contained in:
parent
632bcccef3
commit
ece29b6b0d
54
build.sbt
54
build.sbt
@ -18,6 +18,7 @@ lazy val osName = System.getProperty("os.name") match {
|
||||
lazy val javaFXModules =
|
||||
Seq("base", "controls", "fxml", "graphics", "media", "swing", "web")
|
||||
|
||||
testFrameworks += new TestFramework("munit.Framework")
|
||||
lazy val root = (project in file(".")).settings(
|
||||
name := "mygame",
|
||||
organization := "wow.doge",
|
||||
@ -33,6 +34,7 @@ lazy val root = (project in file(".")).settings(
|
||||
"com.simsilica" % "zay-es" % "1.2.1",
|
||||
"org.typelevel" %% "cats-core" % "2.3.0",
|
||||
"com.lihaoyi" % "ammonite" % "2.2.0" cross CrossVersion.full,
|
||||
// "com.lihaoyi" % "ammonite" % "2.3.8" % "test" cross CrossVersion.full,
|
||||
"org.jetbrains.kotlin" % "kotlin-main-kts" % "1.4.10",
|
||||
"org.jetbrains.kotlin" % "kotlin-scripting-jsr223" % "1.4.10",
|
||||
"org.codehaus.groovy" % "groovy-all" % "3.0.6" pomOnly (),
|
||||
@ -75,7 +77,11 @@ lazy val root = (project in file(".")).settings(
|
||||
"org.kordamp.ikonli" % "ikonli-javafx" % "12.0.0",
|
||||
"org.kordamp.ikonli" % "ikonli-fontawesome5-pack" % "12.0.0",
|
||||
"org.kordamp.ikonli" % "ikonli-material-pack" % "12.0.0",
|
||||
"org.kordamp.bootstrapfx" % "bootstrapfx-core" % "0.4.0"
|
||||
"org.kordamp.bootstrapfx" % "bootstrapfx-core" % "0.4.0",
|
||||
"org.scalameta" %% "munit" % "0.7.23" % Test,
|
||||
"de.lolhens" %% "munit-tagless-final" % "0.0.1" % Test,
|
||||
"org.scalameta" %% "munit-scalacheck" % "0.7.23" % Test,
|
||||
"org.scalacheck" %% "scalacheck" % "1.15.3" % Test
|
||||
),
|
||||
// Determine OS version of JavaFX binaries
|
||||
|
||||
@ -150,31 +156,23 @@ inThisBuild(
|
||||
ThisBuild / scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.4.3"
|
||||
scalafixDependencies in ThisBuild += "org.scalalint" %% "rules" % "0.1.4"
|
||||
|
||||
// wartremoverErrors in (Compile, compile) ++= Warts.allBut(
|
||||
// Wart.Any,
|
||||
// Wart.Nothing,
|
||||
// Wart.Serializable
|
||||
// )
|
||||
|
||||
// wartremoverWarnings in (Compile, compile) ++= Seq(Wart.Any, Wart.Serializable)
|
||||
|
||||
// wartremoverErrors in (Compile, compile) ++=
|
||||
// Warts.allBut(
|
||||
// Wart.Any,
|
||||
// Wart.NonUnitStatements,
|
||||
// // Wart.StringPlusAny,
|
||||
// Wart.Overloading,
|
||||
// Wart.PublicInference,
|
||||
// Wart.Nothing,
|
||||
// Wart.Var,
|
||||
// Wart.DefaultArguments,
|
||||
// // Wart.MutableDataStructures,
|
||||
// Wart.ImplicitConversion,
|
||||
// Wart.ImplicitParameter,
|
||||
// Wart.ToString,
|
||||
// Wart.Recursion,
|
||||
// Wart.While,
|
||||
// Wart.ExplicitImplicitTypes,
|
||||
// Wart.ListUnapply
|
||||
// )
|
||||
wartremoverErrors in (Compile, compile) ++=
|
||||
Warts.allBut(
|
||||
Wart.Any,
|
||||
Wart.NonUnitStatements,
|
||||
// Wart.StringPlusAny,
|
||||
Wart.Overloading,
|
||||
Wart.PublicInference,
|
||||
Wart.Nothing,
|
||||
Wart.Var,
|
||||
Wart.DefaultArguments,
|
||||
// Wart.MutableDataStructures,
|
||||
Wart.ImplicitConversion,
|
||||
Wart.ImplicitParameter,
|
||||
Wart.ToString,
|
||||
Wart.Recursion,
|
||||
Wart.While,
|
||||
Wart.ExplicitImplicitTypes,
|
||||
Wart.ListUnapply
|
||||
)
|
||||
// Seq(Wart.FinalCaseClass)
|
||||
|
@ -37,7 +37,7 @@ object Main extends BIOApp with ExecutorsModule {
|
||||
fileLogger(
|
||||
"application-log-1.log",
|
||||
Formatter.json
|
||||
).withAsync(timeWindow = 1.milliseconds, maxBufferSize = Some(2000))
|
||||
).withAsync(timeWindow = 1.milliseconds, maxBufferSize = Some(100))
|
||||
jmeScheduler <- jmeSchedulerResource
|
||||
// backend <- Resource.make(toIO(HttpClientMonixBackend()))(backend =>
|
||||
// toIO(backend.close())
|
||||
|
@ -99,7 +99,12 @@ class MainApp(
|
||||
implicit val as = scheduler.value
|
||||
|
||||
val scriptSystemResource: Resource[UIO, ScriptCompiler] =
|
||||
new ScriptSystemResource(os.pwd, logger, ScriptInitMode.Eager).init2
|
||||
new ScriptSystemResource(
|
||||
os.pwd,
|
||||
logger,
|
||||
ScriptInitMode.Eager,
|
||||
schedulers.io
|
||||
).init2
|
||||
|
||||
val eventsModule = new EventsModule(scheduler, spawnProtocol)
|
||||
|
||||
|
@ -18,6 +18,7 @@ import monix.reactive.Consumer
|
||||
import monix.reactive.Observable
|
||||
import wow.doge.mygame.implicits._
|
||||
import wow.doge.mygame.utils.readAsyncL
|
||||
import wow.doge.mygame.utils.IOUtils
|
||||
|
||||
@JsonCodec
|
||||
final case class Test1(hello1: String, hello2: String)
|
||||
@ -42,13 +43,15 @@ object ModdingSystem {
|
||||
implicit val eq = Eq.fromUniversalEquals[Error]
|
||||
}
|
||||
|
||||
def readPluginsList2(dir: os.Path) =
|
||||
for {
|
||||
contents <- readAsyncL(dir)
|
||||
} yield ()
|
||||
val x: IO[Error, String] =
|
||||
IOUtils.liftErrors(readAsyncL(os.pwd / "plugins.json")) {
|
||||
case _: FileNotFoundException =>
|
||||
IO.raiseError(FileNotFound(os.pwd / "plugins.json"))
|
||||
case _: NoSuchFileException =>
|
||||
IO.raiseError(FileNotFound(os.pwd / "plugins.json"))
|
||||
}
|
||||
|
||||
def readPluginsList(dir: os.Path): IO[Error, ArraySeq[Plugin]] =
|
||||
// IO(os.read(dir / "plugins.json"))
|
||||
readAsyncL(dir / "plugins.json")
|
||||
.onErrorHandleWith {
|
||||
case _: FileNotFoundException =>
|
||||
@ -64,110 +67,28 @@ object ModdingSystem {
|
||||
)
|
||||
.flatMap(result => IO.fromEither(result).mapError(DecodingFailure))
|
||||
|
||||
// def findPluginFiles(dir: os.Path): View[os.Path] =
|
||||
// os.list(dir)
|
||||
// .view
|
||||
// .filter(f => f.ext === "json" && f.baseName.endsWith("plugin"))
|
||||
|
||||
def findAndReadPluginFiles(
|
||||
dir: os.Path,
|
||||
plugins: ArraySeq[Plugin]
|
||||
): UIO[(View[(Plugin, Error)], View[(Plugin, String)])] =
|
||||
UIO(
|
||||
plugins
|
||||
.sortBy(_.priority)
|
||||
.view
|
||||
.map { p =>
|
||||
val path = dir / os.RelPath(p.name + ".plugin.json")
|
||||
p ->
|
||||
Either
|
||||
.catchNonFatal(os.read(path))
|
||||
.leftMap {
|
||||
case _: FileNotFoundException => FileNotFound(path)
|
||||
case _: NoSuchFileException => FileNotFound(path)
|
||||
}
|
||||
|
||||
}
|
||||
.partitionMap {
|
||||
case (p, either) =>
|
||||
either match {
|
||||
case Left(value) => Left(p -> value)
|
||||
case Right(value) => Right(p -> value)
|
||||
}
|
||||
}
|
||||
)
|
||||
// : (View[(Plugin, Error)], View[(Plugin, String)])
|
||||
def findAndReadPluginFiles2(
|
||||
dir: os.Path,
|
||||
plugins: ArraySeq[Plugin]
|
||||
) =
|
||||
// IO.parTraverse(plugins.sortBy(_.priority))(p =>
|
||||
// IO {
|
||||
// val path = dir / os.RelPath(p.name + ".plugin.json")
|
||||
// os.read(path)
|
||||
// }
|
||||
// .onErrorHandleWith {
|
||||
// case _: FileNotFoundException =>
|
||||
// IO.raiseError(FileNotFound(dir.toString))
|
||||
// case _: NoSuchFileException =>
|
||||
// IO.raiseError(FileNotFound(dir.toString))
|
||||
// }
|
||||
// .flatMap(r => UIO(p -> r))
|
||||
// ).map {
|
||||
// _.partitionMap {
|
||||
// case (p, either) =>
|
||||
// either match {
|
||||
// case Left(value) => Left(p -> value)
|
||||
// case Right(value) => Right(p -> value)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
plugins
|
||||
.sortBy(_.priority)
|
||||
.view
|
||||
.map { p =>
|
||||
val path = dir / os.RelPath(p.name + ".plugin.json")
|
||||
p -> IO(os.read(path))
|
||||
IO
|
||||
.parTraverse(plugins.sortBy(_.priority))(p =>
|
||||
readAsyncL(dir / os.RelPath(p.name + ".plugin.json"))
|
||||
.onErrorHandleWith {
|
||||
case _: FileNotFoundException => IO.raiseError(FileNotFound(path))
|
||||
case _: NoSuchFileException => IO.raiseError(FileNotFound(path))
|
||||
case _: FileNotFoundException =>
|
||||
IO.raiseError(FileNotFound(dir))
|
||||
case _: NoSuchFileException =>
|
||||
IO.raiseError(FileNotFound(dir))
|
||||
case other => IO.terminate(other)
|
||||
}
|
||||
// .map(r => p -> r)
|
||||
.attempt
|
||||
.map(r => p -> r)
|
||||
)
|
||||
.map(_.partitionMap {
|
||||
case p -> Left(value) => Left(p -> value)
|
||||
case p -> Right(value) => Right(p -> value)
|
||||
})
|
||||
|
||||
}
|
||||
.map {
|
||||
case (p, io) =>
|
||||
io.attempt.map {
|
||||
case Left(value) => Left(p -> value)
|
||||
case Right(value) => Right(p -> value)
|
||||
}
|
||||
}
|
||||
.to(List)
|
||||
.parSequence
|
||||
|
||||
// .partitionMap {
|
||||
// _.map {
|
||||
// case l @ Left(value) => l
|
||||
// case r @ Right(value) => r
|
||||
// }
|
||||
// }
|
||||
// .sequence
|
||||
|
||||
// def readPluginFiles(filePaths: View[os.Path]) =
|
||||
// filePaths.map(path => os.read(path))
|
||||
|
||||
// def readPluginFiles2(filePaths: View[os.Path]) =
|
||||
// filePaths
|
||||
// .map(path =>
|
||||
// IO(os.read(path)).onErrorHandleWith {
|
||||
// case _: FileNotFoundException =>
|
||||
// IO.raiseError(FileNotFound(path))
|
||||
// case _: NoSuchFileException =>
|
||||
// IO.raiseError(FileNotFound(path))
|
||||
// }
|
||||
// )
|
||||
// .to(List)
|
||||
// .parSequence
|
||||
def parsePluginFiles(files: View[(Plugin, String)]) =
|
||||
files
|
||||
.map {
|
||||
@ -197,10 +118,10 @@ object ModdingSystem {
|
||||
for {
|
||||
plugins <- readPluginsList(wd)
|
||||
(readFailures, readSuccesses) <- findAndReadPluginFiles(wd, plugins)
|
||||
(parseFailures, parseSuccesses) <- UIO(parsePluginFiles(readSuccesses))
|
||||
(parseFailures, parseSuccesses) = parsePluginFiles(readSuccesses.view)
|
||||
res <- UIO.parMap5(
|
||||
UIO(readFailures.to(List)),
|
||||
UIO(readSuccesses.to(List)),
|
||||
UIO.pure(readSuccesses),
|
||||
UIO(parseFailures.to(List)),
|
||||
UIO(parseSuccesses.to(List)),
|
||||
Observable
|
||||
|
@ -29,6 +29,8 @@ import monix.catnap.MVar
|
||||
import monix.reactive.Observable
|
||||
import monix.{eval => me}
|
||||
import wow.doge.mygame.implicits._
|
||||
import wow.doge.mygame.utils.readAsyncL
|
||||
import wow.doge.mygame.executors.Schedulers
|
||||
|
||||
trait Requestable[A] {
|
||||
|
||||
@ -84,7 +86,7 @@ object ScriptCompiler {
|
||||
sealed trait KotlinEngineTag
|
||||
type KotlinScriptEngine = ScriptEngine @@ KotlinEngineTag
|
||||
|
||||
sealed trait Error
|
||||
sealed trait Error extends Product with Serializable
|
||||
final case class AmmoniteFailure(error: Res.Failure) extends Error
|
||||
final case class AmmoniteException(error: Res.Exception) extends Error
|
||||
final case class ScriptExceptionError(error: ScriptException) extends Error
|
||||
@ -221,6 +223,24 @@ object ScriptCompiler {
|
||||
case _ => Left(SomeError("Failed to run script"))
|
||||
}
|
||||
|
||||
def runScala2(path: os.Path): IO[Error, Any] =
|
||||
for {
|
||||
scriptContent <- readAsyncL(path).hideErrors
|
||||
res <- IO.fromEither(
|
||||
scalaRunner
|
||||
.runCode(scriptContent)
|
||||
._1 match {
|
||||
case e @ Res.Exception(t, msg) => Left(AmmoniteException(e))
|
||||
|
||||
case f @ Failure(msg) => Left(AmmoniteFailure(f))
|
||||
|
||||
case Res.Success(obj) => Right(obj)
|
||||
|
||||
case _ => Left(SomeError("Failed to run script"))
|
||||
}
|
||||
)
|
||||
} yield res
|
||||
|
||||
def runKotlin(path: os.Path): Either[Error, Any] =
|
||||
Either
|
||||
.catchNonFatal(kotlinRunner.eval(os.read(path)))
|
||||
@ -228,6 +248,8 @@ object ScriptCompiler {
|
||||
case ex: ScriptException => ScriptExceptionError(ex)
|
||||
}
|
||||
|
||||
// def runKotlin2(path: os.path): IO[Error,]
|
||||
|
||||
def runGroovy(path: os.Path): Either[Error, Any] =
|
||||
Either
|
||||
.catchNonFatal(groovyRunner.run(path.relativeTo(os.pwd).toString, ""))
|
||||
@ -243,9 +265,9 @@ object ScriptCompiler {
|
||||
class ScriptCompileSource(
|
||||
fns: ScriptCompileFns,
|
||||
logger: Logger[Task],
|
||||
queue: ConcurrentQueue[Task, ScriptCompilerWorker.CompileRequest]
|
||||
queue: ConcurrentQueue[Task, ScriptCompilerWorker.CompileRequest],
|
||||
ioScheduler: Schedulers.IoScheduler
|
||||
) {
|
||||
import fns._
|
||||
|
||||
val source =
|
||||
Task.deferAction(implicit s =>
|
||||
@ -256,11 +278,12 @@ object ScriptCompiler {
|
||||
.mapParallelUnorderedF(4) {
|
||||
case ScriptCompilerWorker.CompileAny(path, result) =>
|
||||
for {
|
||||
mbRes <- Task(
|
||||
runScala(path)
|
||||
.flatMap(ensureReturnedObjectNotNull)
|
||||
mbRes <- (logger.debugU("Test") >> Task(
|
||||
fns
|
||||
.runScala(path)
|
||||
.flatMap(fns.ensureReturnedObjectNotNull)
|
||||
// .map(_.taggedWith[ScriptTag])
|
||||
)
|
||||
)).executeOn(ioScheduler.value)
|
||||
_ <- result.complete(mbRes)
|
||||
} yield mbRes
|
||||
}
|
||||
@ -292,7 +315,8 @@ object ScriptCompiler {
|
||||
logger: Logger[Task],
|
||||
scalaRunner: ammonite.Main = defaultScalaRunner,
|
||||
kotlinRunner: KotlinScriptEngine = defaultKotlinRunner,
|
||||
groovyRunner: GroovyScriptEngine = defaultGroovyRunner
|
||||
groovyRunner: GroovyScriptEngine = defaultGroovyRunner,
|
||||
ioScheduler: Schedulers.IoScheduler
|
||||
) = {
|
||||
val acquire = for {
|
||||
queue <- ConcurrentQueue[Task].bounded[CompileRequest](10)
|
||||
@ -310,14 +334,17 @@ object ScriptCompiler {
|
||||
|
||||
}
|
||||
|
||||
def apply(logger: Logger[Task]): Resource[UIO, ScriptCompiler] = {
|
||||
def apply(
|
||||
logger: Logger[Task],
|
||||
ioScheduler: Schedulers.IoScheduler
|
||||
): Resource[UIO, ScriptCompiler] = {
|
||||
def acquire(worker: ScriptCompilerWorker) =
|
||||
for {
|
||||
queue <- ConcurrentQueue.bounded[Task, Command](10)
|
||||
fib <- wire[SourceMaker].get.flatMap(_.completedL.toIO.start)
|
||||
} yield new ScriptCompiler(queue) -> fib
|
||||
|
||||
ScriptCompilerWorker(logger)
|
||||
ScriptCompilerWorker(logger, ioScheduler = ioScheduler)
|
||||
.flatMap(worker =>
|
||||
Resource.make(acquire(worker).hideErrors) {
|
||||
case (_, fib) => fib.cancel
|
||||
|
@ -11,6 +11,7 @@ import monix.bio.Task
|
||||
import monix.bio.UIO
|
||||
import wow.doge.mygame.scriptsystem.ScriptCachingActor
|
||||
import wow.doge.mygame.utils.AkkaUtils
|
||||
import wow.doge.mygame.executors.Schedulers
|
||||
|
||||
/**
|
||||
* Scripts can either be searched and compiled at startup (Eager mode)
|
||||
@ -24,7 +25,8 @@ object ScriptInitMode {
|
||||
class ScriptSystemResource(
|
||||
path: os.Path,
|
||||
logger: Logger[Task],
|
||||
mode: ScriptInitMode = ScriptInitMode.Lazy
|
||||
mode: ScriptInitMode = ScriptInitMode.Lazy,
|
||||
ioScheduler: Schedulers.IoScheduler
|
||||
)(implicit
|
||||
spawnProtocol: ActorRef[SpawnProtocol.Command],
|
||||
timeout: Timeout,
|
||||
@ -42,7 +44,7 @@ class ScriptSystemResource(
|
||||
} yield scriptCacheActor
|
||||
|
||||
val init2: Resource[UIO, ScriptCompiler] = for {
|
||||
sc <- ScriptCompiler(logger)
|
||||
sc <- ScriptCompiler(logger, ioScheduler)
|
||||
} yield sc
|
||||
|
||||
def findScriptFiles(wd: os.Path) =
|
||||
|
@ -14,4 +14,15 @@ object IOUtils {
|
||||
def fromCoevalEither[L, R](coeval: Coeval[Either[L, R]]) =
|
||||
coeval.to[Task].hideErrors.rethrow
|
||||
|
||||
def liftErrors[E, T](
|
||||
task: Task[T]
|
||||
)(pf: PartialFunction[Throwable, IO[E, T]]): IO[E, T] = {
|
||||
val _ = 1
|
||||
// val x = task.onErrorRecoverWith()
|
||||
task.onErrorHandleWith(ex => pf.applyOrElse(ex, IO.terminate))
|
||||
}
|
||||
|
||||
// final def mapErrorPartial[E1, B >: A](pf: PartialFunction[E, IO[E1, B]])(implicit ev: E <:< Throwable): IO[E1, B] =
|
||||
// onErrorHandleWith(ex => pf.applyOrElse(ex, IO.terminate))
|
||||
|
||||
}
|
||||
|
32
src/test/scala/wow/doge/mygame/AmmoniteTest.scala
Normal file
32
src/test/scala/wow/doge/mygame/AmmoniteTest.scala
Normal file
@ -0,0 +1,32 @@
|
||||
package wow.doge.mygame
|
||||
|
||||
import monix.bio.Task
|
||||
import wow.doge.mygame.subsystems.scriptsystem.ScriptCompiler
|
||||
import monix.bio.UIO
|
||||
import scala.concurrent.Future
|
||||
import monix.execution.Scheduler
|
||||
|
||||
class AmmoniteTest extends munit.TaglessFinalSuite[Task] {
|
||||
|
||||
override protected def toFuture[A](f: Task[A]): Future[A] = {
|
||||
implicit val s = Scheduler.global
|
||||
f.runToFuture
|
||||
}
|
||||
|
||||
val scriptCompileFns = new ScriptCompiler.ScriptCompileFns(
|
||||
ScriptCompiler.defaultScalaRunner,
|
||||
ScriptCompiler.defaultKotlinRunner,
|
||||
ScriptCompiler.defaultGroovyRunner
|
||||
)
|
||||
|
||||
override def afterAll(): Unit = ()
|
||||
|
||||
test("Basic test") {
|
||||
UIO(
|
||||
scriptCompileFns
|
||||
.runScala(
|
||||
os.pwd / "assets" / "scripts" / "scala" / "basicTestScript.sc"
|
||||
)
|
||||
).assertEquals(Right("hello"))
|
||||
}
|
||||
}
|
@ -1,67 +1,75 @@
|
||||
package wow.doge.mygame
|
||||
|
||||
import scala.annotation.nowarn
|
||||
|
||||
import cats.syntax.eq._
|
||||
import com.jme3.asset.DesktopAssetManager
|
||||
import com.jme3.material.Material
|
||||
import com.jme3.material.MaterialDef
|
||||
import com.jme3.scene.Geometry
|
||||
import com.jme3.scene.Node
|
||||
import com.jme3.{asset => jmea}
|
||||
import monix.execution.Scheduler.Implicits.global
|
||||
import org.scalatest.funsuite.AnyFunSuite
|
||||
import wow.doge.mygame.utils.wrappers.jme.AssetManager
|
||||
import wow.doge.mygame.utils.wrappers.jme.AssetManager.AssetNotFound
|
||||
import wow.doge.mygame.utils.wrappers.jme.AssetManager.CouldNotCastError
|
||||
|
||||
@nowarn("msg=method get in class LeftProjection is deprecated")
|
||||
@nowarn("msg=method right in class Either is deprecated")
|
||||
@nowarn("msg=method get in class RightProjection is deprecated")
|
||||
class AssetManagerTest extends AnyFunSuite {
|
||||
class AssetManagerTest extends MonixBioSuite {
|
||||
|
||||
val _assetManager: jmea.AssetManager = new DesktopAssetManager(true)
|
||||
val assetManager = new AssetManager(_assetManager)
|
||||
val fixture = FunFixture[AssetManager](
|
||||
setup = _ => new AssetManager(new DesktopAssetManager(true)),
|
||||
teardown = _ => ()
|
||||
)
|
||||
|
||||
test("Test for AssetNotFound error") {
|
||||
val res =
|
||||
assetManager.loadModel(os.rel / "doesnotexist").attempt.runSyncUnsafe()
|
||||
assert(res.isLeft)
|
||||
assert(res.left.get eqv AssetNotFound("doesnotexist"))
|
||||
override def beforeAll(): Unit = {
|
||||
import java.util.logging.{Logger => JLogger, Level}
|
||||
JLogger.getLogger("").setLevel(Level.SEVERE)
|
||||
}
|
||||
|
||||
test("Test for Model CouldNotCastError") {
|
||||
fixture.test(
|
||||
"AssetManager#loadModel should fail with AssetNotFoundError when asset does not exist"
|
||||
) { assetManager =>
|
||||
assetManager
|
||||
.loadModel(os.rel / "doesnotexist")
|
||||
.attempt
|
||||
.assertEquals(Left(AssetNotFound("doesnotexist")))
|
||||
}
|
||||
|
||||
fixture.test(
|
||||
"AssetManager#loadModelAs should fail with CouldNotCastError when model is not of target type"
|
||||
) { assetManager =>
|
||||
val modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o"
|
||||
val res1 = assetManager
|
||||
assetManager
|
||||
.loadModelAs[Geometry](modelPath)
|
||||
.attempt
|
||||
.runSyncUnsafe()
|
||||
assert(res1.isLeft)
|
||||
assert(res1.left.get eqv CouldNotCastError)
|
||||
.assertEquals(Left(CouldNotCastError))
|
||||
|
||||
val res2 = assetManager
|
||||
}
|
||||
|
||||
fixture.test(
|
||||
"AssetManager#loadModelAs should load com.jme3.Node successfully"
|
||||
) { assetManager =>
|
||||
val modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o"
|
||||
assetManager
|
||||
.loadModelAs[Node](modelPath)
|
||||
.attempt
|
||||
.runSyncUnsafe()
|
||||
assert(res2.isRight)
|
||||
assert(res2.map(_.getName).right.get eqv "JaimeGeom-ogremesh")
|
||||
.map(_.map(_.getName))
|
||||
.assertEquals(Right("JaimeGeom-ogremesh"))
|
||||
}
|
||||
|
||||
test("Test for Asset CouldNotCastError") {
|
||||
fixture.test(
|
||||
"AssetManager#loadAssetAs should fail with CouldNotCastError when asset is not of target type"
|
||||
) { assetManager =>
|
||||
val assetPath = os.rel / "Common" / "MatDefs" / "Misc" / "Unshaded.j3md"
|
||||
|
||||
val res1 = assetManager
|
||||
assetManager
|
||||
.loadAssetAs[Material](assetPath)
|
||||
.attempt
|
||||
.runSyncUnsafe()
|
||||
assert(res1.isLeft)
|
||||
assert(res1.left.get eqv CouldNotCastError)
|
||||
.assertEquals(Left(CouldNotCastError))
|
||||
}
|
||||
|
||||
val res2 = assetManager
|
||||
fixture.test(
|
||||
"AssetManager#loadAssetAs should should load asset succesfully"
|
||||
) { assetManager =>
|
||||
val assetPath = os.rel / "Common" / "MatDefs" / "Misc" / "Unshaded.j3md"
|
||||
assetManager
|
||||
.loadAssetAs[MaterialDef](assetPath)
|
||||
.attempt
|
||||
.runSyncUnsafe()
|
||||
assert(res2.isRight)
|
||||
assert(res2.map(_.getName).right.get eqv "Unshaded")
|
||||
.map(_.map(_.getName))
|
||||
.assertEquals(Right("Unshaded"))
|
||||
}
|
||||
}
|
||||
|
@ -1,35 +1,27 @@
|
||||
package wow.doge.mygame
|
||||
|
||||
import java.util.Queue
|
||||
|
||||
import cats.syntax.eq._
|
||||
import com.jme3.bounding.BoundingVolume
|
||||
import com.jme3.collision.Collidable
|
||||
import com.jme3.collision.CollisionResults
|
||||
import com.jme3.scene.SceneGraphVisitor
|
||||
import com.jme3.scene.Spatial
|
||||
import com.jme3.scene.Spatial.DFSMode
|
||||
import monix.execution.Scheduler.Implicits.global
|
||||
import org.scalatest.funsuite.AnyFunSuite
|
||||
import wow.doge.mygame.utils.wrappers.jme.CollisionShapeFactory
|
||||
import scala.annotation.nowarn
|
||||
|
||||
@nowarn("msg=method get in class LeftProjection is deprecated")
|
||||
class CollisionShapeFactoryTest extends AnyFunSuite {
|
||||
import java.util.Queue
|
||||
|
||||
class CollisionShapeFactoryTest extends MonixBioSuite {
|
||||
test("Test for WrongArgumentError") {
|
||||
val res = CollisionShapeFactory
|
||||
CollisionShapeFactory
|
||||
.createMeshShape(new TestSpatial)
|
||||
.attempt
|
||||
.runSyncUnsafe()
|
||||
|
||||
assert(res.isLeft)
|
||||
|
||||
assert(
|
||||
res.left.get eqv
|
||||
.assertEquals(
|
||||
Left(
|
||||
CollisionShapeFactory.WrongArgumentError(
|
||||
"The spatial must either be a Node or a Geometry!"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,13 +4,21 @@ import scala.concurrent.duration._
|
||||
|
||||
import cats.syntax.show._
|
||||
import monix.bio.IO
|
||||
import monix.eval.Task
|
||||
import monix.reactive.Observable
|
||||
import org.scalatest.funsuite.AnyFunSuite
|
||||
import wow.doge.mygame.implicits._
|
||||
import wow.doge.mygame.utils.MonixDirectoryWatcher
|
||||
import scala.concurrent.Future
|
||||
import monix.execution.Scheduler
|
||||
import monix.bio.Task
|
||||
import monix.{eval => me}
|
||||
|
||||
class FileWatcherTest extends munit.TaglessFinalSuite[Task] {
|
||||
|
||||
override protected def toFuture[A](f: Task[A]): Future[A] = {
|
||||
implicit val s = Scheduler.global
|
||||
f.runToFuture
|
||||
}
|
||||
|
||||
class FileWatcherTest extends AnyFunSuite {
|
||||
// test("1") {
|
||||
// import better.files._
|
||||
// import io.methvin.better.files._
|
||||
@ -36,27 +44,27 @@ class FileWatcherTest extends AnyFunSuite {
|
||||
|
||||
val obsT = MonixDirectoryWatcher(os.pwd / "assets" / "scripts")
|
||||
|
||||
import monix.execution.Scheduler.Implicits.global
|
||||
obsT
|
||||
.flatMap(
|
||||
_.takeUntil(Observable.unit.delayExecution(2.seconds))
|
||||
.doOnNext {
|
||||
case MonixDirectoryWatcher.CreateEvent(file, count) =>
|
||||
Task(println(show"${file.toString} got created"))
|
||||
me.Task(println(show"${file.toString} got created"))
|
||||
case MonixDirectoryWatcher.DeleteEvent(file, count) =>
|
||||
Task(println(show"${file.toString} got deleted"))
|
||||
me.Task(println(show"${file.toString} got deleted"))
|
||||
case MonixDirectoryWatcher.ModifyEvent(file, count) =>
|
||||
Task(pprint.log(show"${file.toString} got modified $count times"))
|
||||
me.Task(
|
||||
pprint.log(show"${file.toString} got modified $count times")
|
||||
)
|
||||
|
||||
}
|
||||
.completedL
|
||||
.flatMap(_ => Task.sleep(3.seconds))
|
||||
.flatMap(_ => me.Task.sleep(3.seconds))
|
||||
.toIO
|
||||
)
|
||||
.onErrorHandleWith {
|
||||
case ex: java.nio.file.ClosedWatchServiceException => IO.unit
|
||||
case ex: java.lang.UnsupportedOperationException => IO.unit
|
||||
}
|
||||
.runSyncUnsafe(16.seconds)
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,41 @@
|
||||
package wow.doge.mygame
|
||||
|
||||
import cats.syntax.eq._
|
||||
import cats.syntax.show._
|
||||
import com.typesafe.scalalogging.LazyLogging
|
||||
import org.scalatest.funsuite.AnyFunSuite
|
||||
import munit.ScalaCheckSuite
|
||||
import org.scalacheck.Prop._
|
||||
import munit.FunSuite
|
||||
import wow.doge.mygame.math.ImVector3f
|
||||
import com.typesafe.scalalogging.LazyLogging
|
||||
import cats.syntax.show._
|
||||
import cats.syntax.eq._
|
||||
import org.scalacheck.Gen
|
||||
import org.scalacheck.Arbitrary.arbitrary
|
||||
|
||||
class ImVector3fSuite extends FunSuite with ScalaCheckSuite with LazyLogging {
|
||||
|
||||
val floatGen = for {
|
||||
a <- arbitrary[Float]
|
||||
b <- arbitrary[Float]
|
||||
c <- arbitrary[Float]
|
||||
} yield ImVector3f(a, b, c)
|
||||
|
||||
val intGen = for {
|
||||
a <- arbitrary[Int]
|
||||
b <- arbitrary[Int]
|
||||
c <- arbitrary[Int]
|
||||
} yield ImVector3f(a.toFloat, b.toFloat, c.toFloat)
|
||||
|
||||
property("imvector3f dst float") {
|
||||
forAll(floatGen, floatGen) { (v1: ImVector3f, v2: ImVector3f) =>
|
||||
assertEquals(ImVector3f.dst(v1, v2), ImVector3f.dst(v2, v1))
|
||||
}
|
||||
}
|
||||
|
||||
property("imvector3f dst int") {
|
||||
forAll(intGen, intGen) { (v1: ImVector3f, v2: ImVector3f) =>
|
||||
assertEquals(ImVector3f.dst(v1, v2), ImVector3f.dst(v2, v1))
|
||||
}
|
||||
}
|
||||
|
||||
class ImVector3fTest extends AnyFunSuite with LazyLogging {
|
||||
test("maxvalue") {
|
||||
val v1 = ImVector3f.Max
|
||||
val v2 = ImVector3f.Max
|
||||
@ -33,19 +62,4 @@ class ImVector3fTest extends AnyFunSuite with LazyLogging {
|
||||
assert(ImVector3f.dst(v1, v2) eqv ImVector3f.dst(v2, v1))
|
||||
}
|
||||
|
||||
test("another") {
|
||||
{
|
||||
val v1 = ImVector3f(1, 0, 0)
|
||||
val v2 = ImVector3f(1, 1, 1)
|
||||
logger.info(ImVector3f.dst(v1, v2).show)
|
||||
assert(ImVector3f.dst(v1, v2) eqv ImVector3f.dst(v2, v1))
|
||||
}
|
||||
{
|
||||
val v1 = ImVector3f(1, 1, 0)
|
||||
val v2 = ImVector3f(1, 1, 1)
|
||||
logger.info(ImVector3f.dst(v1, v2).show)
|
||||
assert(ImVector3f.dst(v1, v2) eqv ImVector3f.dst(v2, v1))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -3,11 +3,18 @@ package wow.doge.mygame
|
||||
import cats.syntax.eq._
|
||||
import io.circe.Printer
|
||||
import monix.bio.UIO
|
||||
import monix.execution.Scheduler.Implicits.global
|
||||
import org.scalatest.funsuite.AnyFunSuite
|
||||
import wow.doge.mygame.subsystems.moddingsystem.ModdingSystem
|
||||
import monix.bio.Task
|
||||
import scala.concurrent.Future
|
||||
import monix.execution.Scheduler
|
||||
|
||||
class ModdingSystemTest extends AnyFunSuite {
|
||||
class ModdingSystemTest extends munit.TaglessFinalSuite[Task] {
|
||||
|
||||
override protected def toFuture[A](f: Task[A]): Future[A] = {
|
||||
implicit val s = Scheduler.global
|
||||
f.runToFuture
|
||||
}
|
||||
val printer = Printer.spaces2
|
||||
test("main") {
|
||||
val io = for {
|
||||
@ -19,9 +26,6 @@ class ModdingSystemTest extends AnyFunSuite {
|
||||
)
|
||||
_ <- ModdingSystem.log(res)
|
||||
} yield res
|
||||
io.attempt.runSyncUnsafe() match {
|
||||
case Left(value) => pprint.log(value); ()
|
||||
case Right(value) => ()
|
||||
}
|
||||
io.attempt
|
||||
}
|
||||
}
|
||||
|
13
src/test/scala/wow/doge/mygame/MonixBioSuite.scala
Normal file
13
src/test/scala/wow/doge/mygame/MonixBioSuite.scala
Normal file
@ -0,0 +1,13 @@
|
||||
package wow.doge.mygame
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
import monix.bio.Task
|
||||
import monix.execution.Scheduler
|
||||
|
||||
trait MonixBioSuite extends munit.TaglessFinalSuite[Task] {
|
||||
override protected def toFuture[A](f: Task[A]): Future[A] = {
|
||||
implicit val s = Scheduler.global
|
||||
f.runToFuture
|
||||
}
|
||||
}
|
@ -4,14 +4,20 @@ import scala.concurrent.duration._
|
||||
|
||||
import io.odin.consoleLogger
|
||||
import monix.bio.Task
|
||||
import monix.execution.Scheduler.Implicits.global
|
||||
import org.scalatest.funsuite.AnyFunSuite
|
||||
import wow.doge.mygame.subsystems.scriptsystem.ScriptCompiler
|
||||
import wow.doge.mygame.executors.Schedulers
|
||||
import scala.concurrent.Future
|
||||
import monix.execution.Scheduler
|
||||
|
||||
class MonixScriptCompilerTest extends AnyFunSuite {
|
||||
class MonixScriptCompilerTest extends munit.TaglessFinalSuite[Task] {
|
||||
|
||||
override protected def toFuture[A](f: Task[A]): Future[A] = {
|
||||
implicit val s = Scheduler.global
|
||||
f.runToFuture
|
||||
}
|
||||
|
||||
test("some-test") {
|
||||
ScriptCompiler(consoleLogger[Task]())
|
||||
ScriptCompiler(consoleLogger[Task](), Schedulers.default.io)
|
||||
.use(scriptCompiler =>
|
||||
for {
|
||||
// _ <-
|
||||
@ -23,7 +29,7 @@ class MonixScriptCompilerTest extends AnyFunSuite {
|
||||
// .startAndForget
|
||||
response <- scriptCompiler.request(
|
||||
ScriptCompiler.GetScript(
|
||||
os.pwd / "assets" / "scripts" / "scala" / "hello2.sc",
|
||||
os.pwd / "assets" / "scripts" / "scala" / "hello.sc",
|
||||
_,
|
||||
false
|
||||
)
|
||||
@ -39,6 +45,5 @@ class MonixScriptCompilerTest extends AnyFunSuite {
|
||||
// _ <- Task.sleep(8.seconds)
|
||||
} yield ()
|
||||
)
|
||||
.runSyncUnsafe(20.seconds)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user