Browse Source

many changes

development
Rohan Sircar 3 years ago
parent
commit
ece29b6b0d
  1. 54
      build.sbt
  2. 2
      src/main/scala/wow/doge/mygame/Main.scala
  3. 7
      src/main/scala/wow/doge/mygame/MainApp.scala
  4. 129
      src/main/scala/wow/doge/mygame/subsystems/moddingsystem/ModdingSystem.scala
  5. 49
      src/main/scala/wow/doge/mygame/subsystems/scriptsystem/MonixScriptCompiler.scala
  6. 6
      src/main/scala/wow/doge/mygame/subsystems/scriptsystem/ScriptSystemModule.scala
  7. 11
      src/main/scala/wow/doge/mygame/utils/IOUtils.scala
  8. 32
      src/test/scala/wow/doge/mygame/AmmoniteTest.scala
  9. 80
      src/test/scala/wow/doge/mygame/AssetManagerTest.scala
  10. 28
      src/test/scala/wow/doge/mygame/CollisionShapeFactoryTest.scala
  11. 26
      src/test/scala/wow/doge/mygame/FileWatcherTest.scala
  12. 54
      src/test/scala/wow/doge/mygame/ImVector3fSuite.scala
  13. 16
      src/test/scala/wow/doge/mygame/ModdingSystemTest.scala
  14. 13
      src/test/scala/wow/doge/mygame/MonixBioSuite.scala
  15. 17
      src/test/scala/wow/doge/mygame/MonixScriptCompilerTest.scala

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)

2
src/main/scala/wow/doge/mygame/Main.scala

@ -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())

7
src/main/scala/wow/doge/mygame/MainApp.scala

@ -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)

129
src/main/scala/wow/doge/mygame/subsystems/moddingsystem/ModdingSystem.scala

@ -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

49
src/main/scala/wow/doge/mygame/subsystems/scriptsystem/MonixScriptCompiler.scala

@ -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)
// .map(_.taggedWith[ScriptTag])
)
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

6
src/main/scala/wow/doge/mygame/subsystems/scriptsystem/ScriptSystemModule.scala

@ -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) =

11
src/main/scala/wow/doge/mygame/utils/IOUtils.scala

@ -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

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

80
src/test/scala/wow/doge/mygame/AssetManagerTest.scala

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

28
src/test/scala/wow/doge/mygame/CollisionShapeFactoryTest.scala

@ -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
CollisionShapeFactory.WrongArgumentError(
"The spatial must either be a Node or a Geometry!"
.assertEquals(
Left(
CollisionShapeFactory.WrongArgumentError(
"The spatial must either be a Node or a Geometry!"
)
)
)
)
}
}

26
src/test/scala/wow/doge/mygame/FileWatcherTest.scala

@ -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)
}
}

54
src/test/scala/wow/doge/mygame/ImVector3fTest.scala → src/test/scala/wow/doge/mygame/ImVector3fSuite.scala

@ -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))
}
}
}

16
src/test/scala/wow/doge/mygame/ModdingSystemTest.scala

@ -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

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

17
src/test/scala/wow/doge/mygame/MonixScriptCompilerTest.scala

@ -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…
Cancel
Save