Testing out JmonkeyEngine to make a game in Scala with Akka Actors within a pure FP layer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
4.1 KiB

4 years ago
  1. package wow.doge.mygame.subsystems.moddingsystem
  2. import java.io.FileNotFoundException
  3. import scala.collection.View
  4. import scala.collection.immutable.ArraySeq
  5. import scala.util.Try
  6. import cats.implicits._
  7. import io.circe._
  8. import io.circe.generic.semiauto._
  9. import io.circe.parser._
  10. import monix.bio.IO
  11. import monix.bio.UIO
  12. import java.nio.file.NoSuchFileException
  13. import io.circe.generic.JsonCodec
  14. @JsonCodec
  15. case class Test1(hello1: String, hello2: String)
  16. @JsonCodec
  17. case class Test2(hello1: String)
  18. case class Plugin(name: String, priority: Int)
  19. object Plugin {
  20. implicit val pluginFormat: Decoder[Plugin] = deriveDecoder
  21. }
  22. object ModdingSystem {
  23. sealed trait Error extends Serializable with Product
  24. case class CouldNotDecode(cause: String) extends Error
  25. case class ParseFailure(cause: String) extends Error
  26. case class FileNotFound(name: String) extends Error
  27. case object GenericError extends Error
  28. def readPluginsList(dir: os.Path): Try[Either[Error, ArraySeq[Plugin]]] =
  29. Try(
  30. parse(os.read(dir / "plugins.json"))
  31. .map(
  32. _.as[ArraySeq[Plugin]]
  33. .leftMap(e => CouldNotDecode(e.getMessage()))
  34. )
  35. .leftMap((e: ParsingFailure) => ParseFailure(e.message))
  36. .flatten
  37. )
  38. // .toValidated
  39. def findPluginFiles(dir: os.Path): View[os.Path] =
  40. os.list(dir)
  41. .view
  42. .filter(f => f.ext == "json" && f.baseName.endsWith("plugin"))
  43. def findAndReadPluginFiles(
  44. dir: os.Path,
  45. plugins: ArraySeq[Plugin]
  46. ) =
  47. plugins
  48. .sortBy(_.priority)
  49. .view
  50. .map(p =>
  51. p ->
  52. Either
  53. .catchNonFatal {
  54. val path = dir / os.RelPath(p.name + ".plugin.json")
  55. os.read(path)
  56. }
  57. .leftMap {
  58. case _: FileNotFoundException =>
  59. FileNotFound(p.name)
  60. case _: NoSuchFileException => FileNotFound(p.name)
  61. case e => GenericError
  62. }
  63. )
  64. .partitionMap {
  65. case (p, either) =>
  66. either match {
  67. case Left(value) => Left(p -> value)
  68. case Right(value) => Right(p -> value)
  69. }
  70. }
  71. def readPluginFiles(filePaths: View[os.Path]) = {
  72. filePaths.map(path => os.read(path))
  73. }
  74. def parsePluginFiles(files: View[(Plugin, String)]) =
  75. files
  76. .map {
  77. case (p, s) => p -> parse(s)
  78. }
  79. .partitionMap {
  80. case (p, Left(value)) => Left(p -> value)
  81. case (p, Right(value)) => Right(p -> value)
  82. }
  83. def mergePluginData(plugins: View[(Plugin, Json)]) = {
  84. plugins.foldLeft(Json.fromString("empty")) {
  85. case (json, that) =>
  86. that match {
  87. case (p, io.circe.Json.Null) => json //ignore null values
  88. case (p, value) => json.deepMerge(value)
  89. }
  90. }
  91. }
  92. // def test =
  93. // for {
  94. // filePaths <- Task(findPluginFiles(os.pwd))
  95. // files <- Task(readPluginFiles(filePaths))
  96. // (failures, successes) <- Task(parsePluginFiles(files))
  97. // merged <- Task(mergePluginData(successes))
  98. // _ <- Task {
  99. // println(s"Successes = ${successes.to(Seq)}")
  100. // println(s"Failure = ${failures.to(Seq)}")
  101. // println(s"Merged = $merged")
  102. // }
  103. // } yield ()
  104. def test(wd: os.Path = os.pwd) =
  105. for {
  106. plugins <- IO.fromTryEither(readPluginsList(wd))
  107. (readFailures, readSuccesses) <- UIO(findAndReadPluginFiles(wd, plugins))
  108. (parseFailures, parseSuccesses) <- UIO(parsePluginFiles(readSuccesses))
  109. res <- UIO(mergePluginData(parseSuccesses))
  110. f <- UIO {
  111. println(s"Read Successes = ${readSuccesses.to(Seq)}")
  112. println(s"Read Failures = ${readFailures.to(Seq)}")
  113. println(s"Parse Successes = ${parseSuccesses.to(Seq)}")
  114. println(s"Parse Failures = ${parseFailures.to(Seq)}")
  115. println(s"Merged = $res")
  116. }
  117. } yield ()
  118. // monix.eval.Task.deferAction(implicit s =>
  119. // ModdingSystem
  120. // .test()
  121. // .leftMap(e => new Throwable(e.toString()))
  122. // .to[monix.eval.Task]
  123. // )
  124. // def test3(wd: os.Path = os.pwd) = {
  125. // (readPluginsList(os.pwd).toValidatedNec)
  126. // }
  127. ;
  128. }