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.
130 lines
4.1 KiB
130 lines
4.1 KiB
package wow.doge.mygame.utils.wrappers.jme
|
|
|
|
import cats.effect.Sync
|
|
import cats.syntax.eq._
|
|
import com.jme3.light.Light
|
|
import com.jme3.{scene => jmes}
|
|
import monix.bio.IO
|
|
import monix.bio.UIO
|
|
import monix.execution.annotations.UnsafeBecauseImpure
|
|
import monix.reactive.Observable
|
|
import wow.doge.mygame.implicits._
|
|
|
|
abstract class NodeWrapper[F[_]: Sync] protected (node: jmes.Node) {
|
|
def name = node.getName()
|
|
def children: Observable[jmes.Spatial] = node.observableChildren
|
|
def attachChild(n: jmes.Spatial): F[Unit] = Sync[F].delay(node.attachChild(n))
|
|
def add(wn: Node[F]): F[Unit] =
|
|
Sync[F].delay(node.attachChild(wn.unsafeDelegate))
|
|
def remove(n: jmes.Spatial): F[Unit] = Sync[F].delay(node.detachChild(n))
|
|
def remove(wn: Node[F]): F[Unit] =
|
|
Sync[F].delay(node.detachChild(wn.unsafeDelegate))
|
|
def addLight(light: Light) =
|
|
Sync[F].delay {
|
|
node.addLight(light)
|
|
}
|
|
def removeLight(light: Light) =
|
|
Sync[F].delay {
|
|
node.removeLight(light)
|
|
}
|
|
def asSpatial: F[jmes.Spatial] = Sync[F].delay(node)
|
|
}
|
|
object NodeWrapper {
|
|
implicit class NodeOps[F[_]](private val nw: NodeWrapper[F]) extends AnyVal {
|
|
def +=(n: jmes.Spatial) = nw.attachChild(n)
|
|
def +=(n: Node[F]) = nw.add(n)
|
|
def -=(n: jmes.Spatial) = nw.remove(n)
|
|
def -=(wn: Node[F]) = nw.remove(wn)
|
|
def +=(light: Light) =
|
|
nw.addLight(light)
|
|
|
|
def -=(light: Light) =
|
|
nw.removeLight(light)
|
|
}
|
|
}
|
|
|
|
final class Node[F[_]: Sync] private (node: jmes.Node)
|
|
extends NodeWrapper[F](node) {
|
|
|
|
/**
|
|
* Get the underlying wrapped value
|
|
*/
|
|
@UnsafeBecauseImpure
|
|
def unsafeDelegate = node
|
|
}
|
|
object Node {
|
|
def apply[F[_]: Sync](name: String) = new Node[F](new jmes.Node(name))
|
|
def apply[F[_]: Sync](n: jmes.Node) = new Node[F](n)
|
|
}
|
|
|
|
final class AppNode[F[_]: Sync] private (node: jmes.Node)
|
|
extends NodeWrapper[F](node)
|
|
object AppNode {
|
|
|
|
def apply[F[_]: Sync](name: String) = new AppNode[F](new jmes.Node(name))
|
|
def apply[F[_]: Sync](n: jmes.Node) = new AppNode[F](n)
|
|
|
|
}
|
|
|
|
abstract class NodeWrapper2 protected (node: jmes.Node) {
|
|
import NodeWrapper2._
|
|
def name = node.getName()
|
|
def children: Observable[jmes.Spatial] = node.observableChildren
|
|
def breadthFirstTraversal = node.observableBreadthFirst()
|
|
def depthFirstTraversal = node.observableDepthFirst()
|
|
def attachChild(n: jmes.Spatial): IO[AddNodeToItselfError.type, Unit] =
|
|
IO { node.attachChild(n); () }.onErrorHandleWith {
|
|
case ex: IllegalArgumentException =>
|
|
if (ex.getMessage === "Cannot add child to itself")
|
|
IO.raiseError(AddNodeToItselfError)
|
|
else IO.unit
|
|
}
|
|
def add(wn: Node2): IO[AddNodeToItselfError.type, Unit] =
|
|
IO { node.attachChild(wn.unsafeDelegate); () }.onErrorHandleWith {
|
|
case ex: IllegalArgumentException =>
|
|
if (ex.getMessage === "Cannot add child to itself")
|
|
IO.raiseError(AddNodeToItselfError)
|
|
else IO.unit
|
|
}
|
|
def remove(n: jmes.Spatial) = UIO(node.detachChild(n))
|
|
def remove(wn: Node2) = UIO(node.detachChild(wn.unsafeDelegate))
|
|
def addLight(light: Light) = UIO(node.addLight(light))
|
|
def removeLight(light: Light) = UIO(node.removeLight(light))
|
|
def asSpatial: UIO[jmes.Spatial] = UIO(node)
|
|
}
|
|
object NodeWrapper2 {
|
|
sealed trait Error
|
|
case object AddNodeToItselfError extends Error
|
|
implicit class NodeOps[F[_]](private val nw: NodeWrapper2) extends AnyVal {
|
|
def +=(n: jmes.Spatial) = nw.attachChild(n)
|
|
def +=(n: Node2) = nw.add(n)
|
|
def -=(n: jmes.Spatial) = nw.remove(n)
|
|
def -=(wn: Node2) = nw.remove(wn)
|
|
def +=(light: Light) =
|
|
nw.addLight(light)
|
|
|
|
def -=(light: Light) =
|
|
nw.removeLight(light)
|
|
}
|
|
}
|
|
|
|
final class Node2 private (node: jmes.Node) extends NodeWrapper2(node) {
|
|
|
|
/**
|
|
* Get the underlying wrapped value
|
|
*/
|
|
@UnsafeBecauseImpure
|
|
def unsafeDelegate = node
|
|
}
|
|
object Node2 {
|
|
def apply(name: String) = new Node2(new jmes.Node(name))
|
|
def apply(n: jmes.Node) = new Node2(n)
|
|
}
|
|
|
|
final class AppNode2 private (node: jmes.Node) extends NodeWrapper2(node)
|
|
object AppNode2 {
|
|
// sealed trait Error extends NodeWrapper2.Error
|
|
def apply(name: String) = new AppNode2(new jmes.Node(name))
|
|
def apply(n: jmes.Node) = new AppNode2(n)
|
|
|
|
}
|