many changes

This commit is contained in:
Rohan Sircar 2021-04-19 19:51:58 +05:30
parent 632bcccef3
commit ece29b6b0d
15 changed files with 282 additions and 242 deletions

View File

@ -18,6 +18,7 @@ lazy val osName = System.getProperty("os.name") match {
lazy val javaFXModules = lazy val javaFXModules =
Seq("base", "controls", "fxml", "graphics", "media", "swing", "web") Seq("base", "controls", "fxml", "graphics", "media", "swing", "web")
testFrameworks += new TestFramework("munit.Framework")
lazy val root = (project in file(".")).settings( lazy val root = (project in file(".")).settings(
name := "mygame", name := "mygame",
organization := "wow.doge", organization := "wow.doge",
@ -33,6 +34,7 @@ lazy val root = (project in file(".")).settings(
"com.simsilica" % "zay-es" % "1.2.1", "com.simsilica" % "zay-es" % "1.2.1",
"org.typelevel" %% "cats-core" % "2.3.0", "org.typelevel" %% "cats-core" % "2.3.0",
"com.lihaoyi" % "ammonite" % "2.2.0" cross CrossVersion.full, "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-main-kts" % "1.4.10",
"org.jetbrains.kotlin" % "kotlin-scripting-jsr223" % "1.4.10", "org.jetbrains.kotlin" % "kotlin-scripting-jsr223" % "1.4.10",
"org.codehaus.groovy" % "groovy-all" % "3.0.6" pomOnly (), "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-javafx" % "12.0.0",
"org.kordamp.ikonli" % "ikonli-fontawesome5-pack" % "12.0.0", "org.kordamp.ikonli" % "ikonli-fontawesome5-pack" % "12.0.0",
"org.kordamp.ikonli" % "ikonli-material-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 // Determine OS version of JavaFX binaries
@ -150,31 +156,23 @@ inThisBuild(
ThisBuild / scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.4.3" ThisBuild / scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.4.3"
scalafixDependencies in ThisBuild += "org.scalalint" %% "rules" % "0.1.4" scalafixDependencies in ThisBuild += "org.scalalint" %% "rules" % "0.1.4"
// wartremoverErrors in (Compile, compile) ++= Warts.allBut( wartremoverErrors in (Compile, compile) ++=
// Wart.Any, Warts.allBut(
// Wart.Nothing, Wart.Any,
// Wart.Serializable Wart.NonUnitStatements,
// ) // Wart.StringPlusAny,
Wart.Overloading,
// wartremoverWarnings in (Compile, compile) ++= Seq(Wart.Any, Wart.Serializable) Wart.PublicInference,
Wart.Nothing,
// wartremoverErrors in (Compile, compile) ++= Wart.Var,
// Warts.allBut( Wart.DefaultArguments,
// Wart.Any, // Wart.MutableDataStructures,
// Wart.NonUnitStatements, Wart.ImplicitConversion,
// // Wart.StringPlusAny, Wart.ImplicitParameter,
// Wart.Overloading, Wart.ToString,
// Wart.PublicInference, Wart.Recursion,
// Wart.Nothing, Wart.While,
// Wart.Var, Wart.ExplicitImplicitTypes,
// Wart.DefaultArguments, Wart.ListUnapply
// // Wart.MutableDataStructures, )
// Wart.ImplicitConversion,
// Wart.ImplicitParameter,
// Wart.ToString,
// Wart.Recursion,
// Wart.While,
// Wart.ExplicitImplicitTypes,
// Wart.ListUnapply
// )
// Seq(Wart.FinalCaseClass) // Seq(Wart.FinalCaseClass)

View File

@ -37,7 +37,7 @@ object Main extends BIOApp with ExecutorsModule {
fileLogger( fileLogger(
"application-log-1.log", "application-log-1.log",
Formatter.json Formatter.json
).withAsync(timeWindow = 1.milliseconds, maxBufferSize = Some(2000)) ).withAsync(timeWindow = 1.milliseconds, maxBufferSize = Some(100))
jmeScheduler <- jmeSchedulerResource jmeScheduler <- jmeSchedulerResource
// backend <- Resource.make(toIO(HttpClientMonixBackend()))(backend => // backend <- Resource.make(toIO(HttpClientMonixBackend()))(backend =>
// toIO(backend.close()) // toIO(backend.close())

View File

@ -99,7 +99,12 @@ class MainApp(
implicit val as = scheduler.value implicit val as = scheduler.value
val scriptSystemResource: Resource[UIO, ScriptCompiler] = 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) val eventsModule = new EventsModule(scheduler, spawnProtocol)

View File

@ -18,6 +18,7 @@ import monix.reactive.Consumer
import monix.reactive.Observable import monix.reactive.Observable
import wow.doge.mygame.implicits._ import wow.doge.mygame.implicits._
import wow.doge.mygame.utils.readAsyncL import wow.doge.mygame.utils.readAsyncL
import wow.doge.mygame.utils.IOUtils
@JsonCodec @JsonCodec
final case class Test1(hello1: String, hello2: String) final case class Test1(hello1: String, hello2: String)
@ -42,13 +43,15 @@ object ModdingSystem {
implicit val eq = Eq.fromUniversalEquals[Error] implicit val eq = Eq.fromUniversalEquals[Error]
} }
def readPluginsList2(dir: os.Path) = val x: IO[Error, String] =
for { IOUtils.liftErrors(readAsyncL(os.pwd / "plugins.json")) {
contents <- readAsyncL(dir) case _: FileNotFoundException =>
} yield () 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]] = def readPluginsList(dir: os.Path): IO[Error, ArraySeq[Plugin]] =
// IO(os.read(dir / "plugins.json"))
readAsyncL(dir / "plugins.json") readAsyncL(dir / "plugins.json")
.onErrorHandleWith { .onErrorHandleWith {
case _: FileNotFoundException => case _: FileNotFoundException =>
@ -64,110 +67,28 @@ object ModdingSystem {
) )
.flatMap(result => IO.fromEither(result).mapError(DecodingFailure)) .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( def findAndReadPluginFiles(
dir: os.Path, dir: os.Path,
plugins: ArraySeq[Plugin] 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
// IO { .parTraverse(plugins.sortBy(_.priority))(p =>
// val path = dir / os.RelPath(p.name + ".plugin.json") readAsyncL(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))
.onErrorHandleWith { .onErrorHandleWith {
case _: FileNotFoundException => IO.raiseError(FileNotFound(path)) case _: FileNotFoundException =>
case _: NoSuchFileException => IO.raiseError(FileNotFound(path)) 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)]) = def parsePluginFiles(files: View[(Plugin, String)]) =
files files
.map { .map {
@ -197,10 +118,10 @@ object ModdingSystem {
for { for {
plugins <- readPluginsList(wd) plugins <- readPluginsList(wd)
(readFailures, readSuccesses) <- findAndReadPluginFiles(wd, plugins) (readFailures, readSuccesses) <- findAndReadPluginFiles(wd, plugins)
(parseFailures, parseSuccesses) <- UIO(parsePluginFiles(readSuccesses)) (parseFailures, parseSuccesses) = parsePluginFiles(readSuccesses.view)
res <- UIO.parMap5( res <- UIO.parMap5(
UIO(readFailures.to(List)), UIO(readFailures.to(List)),
UIO(readSuccesses.to(List)), UIO.pure(readSuccesses),
UIO(parseFailures.to(List)), UIO(parseFailures.to(List)),
UIO(parseSuccesses.to(List)), UIO(parseSuccesses.to(List)),
Observable Observable

View File

@ -29,6 +29,8 @@ import monix.catnap.MVar
import monix.reactive.Observable import monix.reactive.Observable
import monix.{eval => me} import monix.{eval => me}
import wow.doge.mygame.implicits._ import wow.doge.mygame.implicits._
import wow.doge.mygame.utils.readAsyncL
import wow.doge.mygame.executors.Schedulers
trait Requestable[A] { trait Requestable[A] {
@ -84,7 +86,7 @@ object ScriptCompiler {
sealed trait KotlinEngineTag sealed trait KotlinEngineTag
type KotlinScriptEngine = ScriptEngine @@ 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 AmmoniteFailure(error: Res.Failure) extends Error
final case class AmmoniteException(error: Res.Exception) extends Error final case class AmmoniteException(error: Res.Exception) extends Error
final case class ScriptExceptionError(error: ScriptException) extends Error final case class ScriptExceptionError(error: ScriptException) extends Error
@ -221,6 +223,24 @@ object ScriptCompiler {
case _ => Left(SomeError("Failed to run script")) 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] = def runKotlin(path: os.Path): Either[Error, Any] =
Either Either
.catchNonFatal(kotlinRunner.eval(os.read(path))) .catchNonFatal(kotlinRunner.eval(os.read(path)))
@ -228,6 +248,8 @@ object ScriptCompiler {
case ex: ScriptException => ScriptExceptionError(ex) case ex: ScriptException => ScriptExceptionError(ex)
} }
// def runKotlin2(path: os.path): IO[Error,]
def runGroovy(path: os.Path): Either[Error, Any] = def runGroovy(path: os.Path): Either[Error, Any] =
Either Either
.catchNonFatal(groovyRunner.run(path.relativeTo(os.pwd).toString, "")) .catchNonFatal(groovyRunner.run(path.relativeTo(os.pwd).toString, ""))
@ -243,9 +265,9 @@ object ScriptCompiler {
class ScriptCompileSource( class ScriptCompileSource(
fns: ScriptCompileFns, fns: ScriptCompileFns,
logger: Logger[Task], logger: Logger[Task],
queue: ConcurrentQueue[Task, ScriptCompilerWorker.CompileRequest] queue: ConcurrentQueue[Task, ScriptCompilerWorker.CompileRequest],
ioScheduler: Schedulers.IoScheduler
) { ) {
import fns._
val source = val source =
Task.deferAction(implicit s => Task.deferAction(implicit s =>
@ -256,11 +278,12 @@ object ScriptCompiler {
.mapParallelUnorderedF(4) { .mapParallelUnorderedF(4) {
case ScriptCompilerWorker.CompileAny(path, result) => case ScriptCompilerWorker.CompileAny(path, result) =>
for { for {
mbRes <- Task( mbRes <- (logger.debugU("Test") >> Task(
runScala(path) fns
.flatMap(ensureReturnedObjectNotNull) .runScala(path)
.flatMap(fns.ensureReturnedObjectNotNull)
// .map(_.taggedWith[ScriptTag]) // .map(_.taggedWith[ScriptTag])
) )).executeOn(ioScheduler.value)
_ <- result.complete(mbRes) _ <- result.complete(mbRes)
} yield mbRes } yield mbRes
} }
@ -292,7 +315,8 @@ object ScriptCompiler {
logger: Logger[Task], logger: Logger[Task],
scalaRunner: ammonite.Main = defaultScalaRunner, scalaRunner: ammonite.Main = defaultScalaRunner,
kotlinRunner: KotlinScriptEngine = defaultKotlinRunner, kotlinRunner: KotlinScriptEngine = defaultKotlinRunner,
groovyRunner: GroovyScriptEngine = defaultGroovyRunner groovyRunner: GroovyScriptEngine = defaultGroovyRunner,
ioScheduler: Schedulers.IoScheduler
) = { ) = {
val acquire = for { val acquire = for {
queue <- ConcurrentQueue[Task].bounded[CompileRequest](10) 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) = def acquire(worker: ScriptCompilerWorker) =
for { for {
queue <- ConcurrentQueue.bounded[Task, Command](10) queue <- ConcurrentQueue.bounded[Task, Command](10)
fib <- wire[SourceMaker].get.flatMap(_.completedL.toIO.start) fib <- wire[SourceMaker].get.flatMap(_.completedL.toIO.start)
} yield new ScriptCompiler(queue) -> fib } yield new ScriptCompiler(queue) -> fib
ScriptCompilerWorker(logger) ScriptCompilerWorker(logger, ioScheduler = ioScheduler)
.flatMap(worker => .flatMap(worker =>
Resource.make(acquire(worker).hideErrors) { Resource.make(acquire(worker).hideErrors) {
case (_, fib) => fib.cancel case (_, fib) => fib.cancel

View File

@ -11,6 +11,7 @@ import monix.bio.Task
import monix.bio.UIO import monix.bio.UIO
import wow.doge.mygame.scriptsystem.ScriptCachingActor import wow.doge.mygame.scriptsystem.ScriptCachingActor
import wow.doge.mygame.utils.AkkaUtils import wow.doge.mygame.utils.AkkaUtils
import wow.doge.mygame.executors.Schedulers
/** /**
* Scripts can either be searched and compiled at startup (Eager mode) * Scripts can either be searched and compiled at startup (Eager mode)
@ -24,7 +25,8 @@ object ScriptInitMode {
class ScriptSystemResource( class ScriptSystemResource(
path: os.Path, path: os.Path,
logger: Logger[Task], logger: Logger[Task],
mode: ScriptInitMode = ScriptInitMode.Lazy mode: ScriptInitMode = ScriptInitMode.Lazy,
ioScheduler: Schedulers.IoScheduler
)(implicit )(implicit
spawnProtocol: ActorRef[SpawnProtocol.Command], spawnProtocol: ActorRef[SpawnProtocol.Command],
timeout: Timeout, timeout: Timeout,
@ -42,7 +44,7 @@ class ScriptSystemResource(
} yield scriptCacheActor } yield scriptCacheActor
val init2: Resource[UIO, ScriptCompiler] = for { val init2: Resource[UIO, ScriptCompiler] = for {
sc <- ScriptCompiler(logger) sc <- ScriptCompiler(logger, ioScheduler)
} yield sc } yield sc
def findScriptFiles(wd: os.Path) = def findScriptFiles(wd: os.Path) =

View File

@ -14,4 +14,15 @@ object IOUtils {
def fromCoevalEither[L, R](coeval: Coeval[Either[L, R]]) = def fromCoevalEither[L, R](coeval: Coeval[Either[L, R]]) =
coeval.to[Task].hideErrors.rethrow 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))
} }

View 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"))
}
}

View File

@ -1,67 +1,75 @@
package wow.doge.mygame package wow.doge.mygame
import scala.annotation.nowarn
import cats.syntax.eq._
import com.jme3.asset.DesktopAssetManager import com.jme3.asset.DesktopAssetManager
import com.jme3.material.Material import com.jme3.material.Material
import com.jme3.material.MaterialDef import com.jme3.material.MaterialDef
import com.jme3.scene.Geometry import com.jme3.scene.Geometry
import com.jme3.scene.Node 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
import wow.doge.mygame.utils.wrappers.jme.AssetManager.AssetNotFound import wow.doge.mygame.utils.wrappers.jme.AssetManager.AssetNotFound
import wow.doge.mygame.utils.wrappers.jme.AssetManager.CouldNotCastError import wow.doge.mygame.utils.wrappers.jme.AssetManager.CouldNotCastError
@nowarn("msg=method get in class LeftProjection is deprecated") class AssetManagerTest extends MonixBioSuite {
@nowarn("msg=method right in class Either is deprecated")
@nowarn("msg=method get in class RightProjection is deprecated")
class AssetManagerTest extends AnyFunSuite {
val _assetManager: jmea.AssetManager = new DesktopAssetManager(true) val fixture = FunFixture[AssetManager](
val assetManager = new AssetManager(_assetManager) setup = _ => new AssetManager(new DesktopAssetManager(true)),
teardown = _ => ()
)
test("Test for AssetNotFound error") { override def beforeAll(): Unit = {
val res = import java.util.logging.{Logger => JLogger, Level}
assetManager.loadModel(os.rel / "doesnotexist").attempt.runSyncUnsafe() JLogger.getLogger("").setLevel(Level.SEVERE)
assert(res.isLeft)
assert(res.left.get eqv AssetNotFound("doesnotexist"))
} }
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 modelPath = os.rel / "Models" / "Jaime" / "Jaime.j3o"
val res1 = assetManager assetManager
.loadModelAs[Geometry](modelPath) .loadModelAs[Geometry](modelPath)
.attempt .attempt
.runSyncUnsafe() .assertEquals(Left(CouldNotCastError))
assert(res1.isLeft)
assert(res1.left.get eqv 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) .loadModelAs[Node](modelPath)
.attempt .attempt
.runSyncUnsafe() .map(_.map(_.getName))
assert(res2.isRight) .assertEquals(Right("JaimeGeom-ogremesh"))
assert(res2.map(_.getName).right.get eqv "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 assetPath = os.rel / "Common" / "MatDefs" / "Misc" / "Unshaded.j3md"
assetManager
val res1 = assetManager
.loadAssetAs[Material](assetPath) .loadAssetAs[Material](assetPath)
.attempt .attempt
.runSyncUnsafe() .assertEquals(Left(CouldNotCastError))
assert(res1.isLeft) }
assert(res1.left.get eqv 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) .loadAssetAs[MaterialDef](assetPath)
.attempt .attempt
.runSyncUnsafe() .map(_.map(_.getName))
assert(res2.isRight) .assertEquals(Right("Unshaded"))
assert(res2.map(_.getName).right.get eqv "Unshaded")
} }
} }

View File

@ -1,35 +1,27 @@
package wow.doge.mygame package wow.doge.mygame
import java.util.Queue
import cats.syntax.eq._
import com.jme3.bounding.BoundingVolume import com.jme3.bounding.BoundingVolume
import com.jme3.collision.Collidable import com.jme3.collision.Collidable
import com.jme3.collision.CollisionResults import com.jme3.collision.CollisionResults
import com.jme3.scene.SceneGraphVisitor import com.jme3.scene.SceneGraphVisitor
import com.jme3.scene.Spatial import com.jme3.scene.Spatial
import com.jme3.scene.Spatial.DFSMode 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 wow.doge.mygame.utils.wrappers.jme.CollisionShapeFactory
import scala.annotation.nowarn
@nowarn("msg=method get in class LeftProjection is deprecated") import java.util.Queue
class CollisionShapeFactoryTest extends AnyFunSuite {
class CollisionShapeFactoryTest extends MonixBioSuite {
test("Test for WrongArgumentError") { test("Test for WrongArgumentError") {
val res = CollisionShapeFactory CollisionShapeFactory
.createMeshShape(new TestSpatial) .createMeshShape(new TestSpatial)
.attempt .attempt
.runSyncUnsafe() .assertEquals(
Left(
assert(res.isLeft)
assert(
res.left.get eqv
CollisionShapeFactory.WrongArgumentError( CollisionShapeFactory.WrongArgumentError(
"The spatial must either be a Node or a Geometry!" "The spatial must either be a Node or a Geometry!"
) )
) )
)
} }
} }

View File

@ -4,13 +4,21 @@ import scala.concurrent.duration._
import cats.syntax.show._ import cats.syntax.show._
import monix.bio.IO import monix.bio.IO
import monix.eval.Task
import monix.reactive.Observable import monix.reactive.Observable
import org.scalatest.funsuite.AnyFunSuite
import wow.doge.mygame.implicits._ import wow.doge.mygame.implicits._
import wow.doge.mygame.utils.MonixDirectoryWatcher 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") { // test("1") {
// import better.files._ // import better.files._
// import io.methvin.better.files._ // import io.methvin.better.files._
@ -36,27 +44,27 @@ class FileWatcherTest extends AnyFunSuite {
val obsT = MonixDirectoryWatcher(os.pwd / "assets" / "scripts") val obsT = MonixDirectoryWatcher(os.pwd / "assets" / "scripts")
import monix.execution.Scheduler.Implicits.global
obsT obsT
.flatMap( .flatMap(
_.takeUntil(Observable.unit.delayExecution(2.seconds)) _.takeUntil(Observable.unit.delayExecution(2.seconds))
.doOnNext { .doOnNext {
case MonixDirectoryWatcher.CreateEvent(file, count) => 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) => 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) => 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 .completedL
.flatMap(_ => Task.sleep(3.seconds)) .flatMap(_ => me.Task.sleep(3.seconds))
.toIO .toIO
) )
.onErrorHandleWith { .onErrorHandleWith {
case ex: java.nio.file.ClosedWatchServiceException => IO.unit case ex: java.nio.file.ClosedWatchServiceException => IO.unit
case ex: java.lang.UnsupportedOperationException => IO.unit case ex: java.lang.UnsupportedOperationException => IO.unit
} }
.runSyncUnsafe(16.seconds)
} }
} }

View File

@ -1,12 +1,41 @@
package wow.doge.mygame package wow.doge.mygame
import cats.syntax.eq._ import munit.ScalaCheckSuite
import cats.syntax.show._ import org.scalacheck.Prop._
import com.typesafe.scalalogging.LazyLogging import munit.FunSuite
import org.scalatest.funsuite.AnyFunSuite
import wow.doge.mygame.math.ImVector3f 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") { test("maxvalue") {
val v1 = ImVector3f.Max val v1 = ImVector3f.Max
val v2 = 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)) 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))
}
}
} }

View File

@ -3,11 +3,18 @@ package wow.doge.mygame
import cats.syntax.eq._ import cats.syntax.eq._
import io.circe.Printer import io.circe.Printer
import monix.bio.UIO import monix.bio.UIO
import monix.execution.Scheduler.Implicits.global
import org.scalatest.funsuite.AnyFunSuite import org.scalatest.funsuite.AnyFunSuite
import wow.doge.mygame.subsystems.moddingsystem.ModdingSystem 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 val printer = Printer.spaces2
test("main") { test("main") {
val io = for { val io = for {
@ -19,9 +26,6 @@ class ModdingSystemTest extends AnyFunSuite {
) )
_ <- ModdingSystem.log(res) _ <- ModdingSystem.log(res)
} yield res } yield res
io.attempt.runSyncUnsafe() match { io.attempt
case Left(value) => pprint.log(value); ()
case Right(value) => ()
}
} }
} }

View 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
}
}

View File

@ -4,14 +4,20 @@ import scala.concurrent.duration._
import io.odin.consoleLogger import io.odin.consoleLogger
import monix.bio.Task 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.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") { test("some-test") {
ScriptCompiler(consoleLogger[Task]()) ScriptCompiler(consoleLogger[Task](), Schedulers.default.io)
.use(scriptCompiler => .use(scriptCompiler =>
for { for {
// _ <- // _ <-
@ -23,7 +29,7 @@ class MonixScriptCompilerTest extends AnyFunSuite {
// .startAndForget // .startAndForget
response <- scriptCompiler.request( response <- scriptCompiler.request(
ScriptCompiler.GetScript( ScriptCompiler.GetScript(
os.pwd / "assets" / "scripts" / "scala" / "hello2.sc", os.pwd / "assets" / "scripts" / "scala" / "hello.sc",
_, _,
false false
) )
@ -39,6 +45,5 @@ class MonixScriptCompilerTest extends AnyFunSuite {
// _ <- Task.sleep(8.seconds) // _ <- Task.sleep(8.seconds)
} yield () } yield ()
) )
.runSyncUnsafe(20.seconds)
} }
} }