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.

76 lines
2.1 KiB

3 years ago
  1. package wow.doge.mygame.utils.wrappers.jme
  2. import cats.effect.Sync
  3. import com.jme3.{scene => jmes}
  4. import monix.execution.annotations.UnsafeBecauseImpure
  5. import monix.reactive.Observable
  6. import wow.doge.mygame.implicits._
  7. import com.jme3.light.Light
  8. trait NodeDelegate {
  9. /**
  10. * Get the underlying wrapped value
  11. */
  12. @UnsafeBecauseImpure
  13. def unsafeDelegate: jmes.Node
  14. }
  15. abstract class NodeWrapper[F[_]: Sync] protected (node: jmes.Node) {
  16. def children: Observable[jmes.Spatial] = node.observableChildren
  17. def attachChild(n: jmes.Spatial): F[Unit] = Sync[F].delay(node.attachChild(n))
  18. def add(wn: Node[F]): F[Unit] =
  19. Sync[F].delay(node.attachChild(wn.unsafeDelegate))
  20. def remove(n: jmes.Spatial): F[Unit] =
  21. Sync[F].delay(node.detachChild(n))
  22. def remove(wn: Node[F]): F[Unit] =
  23. Sync[F].delay(node.detachChild(wn.unsafeDelegate))
  24. def addLight(light: Light) =
  25. Sync[F].delay {
  26. node.addLight(light)
  27. }
  28. def removeLight(light: Light) =
  29. Sync[F].delay {
  30. node.removeLight(light)
  31. }
  32. def asSpatial: F[jmes.Spatial] = Sync[F].delay(node)
  33. }
  34. object NodeWrapper {
  35. implicit class NodeOps[F[_]](private val nw: NodeWrapper[F]) extends AnyVal {
  36. def +=(n: jmes.Spatial) = nw.attachChild(n)
  37. def +=(n: Node[F]) = nw.add(n)
  38. def -=(n: jmes.Spatial) = nw.remove(n)
  39. def -=(wn: Node[F]) = nw.remove(wn)
  40. def +=(light: Light) = {
  41. nw.addLight(light)
  42. }
  43. def -=(light: Light) = {
  44. nw.removeLight(light)
  45. }
  46. }
  47. }
  48. final class Node[F[_]: Sync] private (node: jmes.Node)
  49. extends NodeWrapper[F](node)
  50. with NodeDelegate {
  51. /**
  52. * Get the underlying wrapped value
  53. */
  54. @UnsafeBecauseImpure
  55. def unsafeDelegate = node
  56. }
  57. object Node {
  58. def apply[F[_]: Sync](name: String) = new Node[F](new jmes.Node(name))
  59. def apply[F[_]: Sync](n: jmes.Node) = new Node[F](n)
  60. }
  61. final class AppNode[F[_]: Sync] private (node: jmes.Node)
  62. extends NodeWrapper[F](node)
  63. object AppNode {
  64. def apply[F[_]: Sync](name: String) = new AppNode[F](new jmes.Node(name))
  65. def apply[F[_]: Sync](n: jmes.Node) = new AppNode[F](n)
  66. }