Compare commits

...

9 Commits

37 changed files with 966 additions and 3200 deletions

BIN
.gitignore vendored

Binary file not shown.

View File

@ -1,48 +1,10 @@
lazy val scodec = (project in file("scodec")).settings(
lazy val core = (project in file("core")).settings(
organization := "tf.bug",
name := "fancadescodec",
version := "0.1.0",
scalaVersion := "2.13.3",
name := "fancade",
version := "2.0.0-SNAPSHOT",
scalaVersion := "2.13.5",
libraryDependencies ++= Seq(
"org.scodec" %% "scodec-core" % "1.11.7",
"org.scodec" %% "scodec-bits" % "1.1.17",
"org.scodec" %% "scodec-stream" % "2.0.0",
"org.typelevel" %% "cats-effect" % "2.1.3",
"org.typelevel" %% "cats-core" % "2.1.1",
"co.fs2" %% "fs2-core" % "2.4.2",
"co.fs2" %% "fs2-io" % "2.4.2",
"tf.bug" %% "shinji" % "0.1.8",
"com.lihaoyi" %% "pprint" % "0.5.6",
),
mainClass in assembly := Some("tf.bug.fancadescodec.Main"),
)
lazy val graph = (project in file("graph")).settings(
organization := "tf.bug",
name := "fancadegraph",
version := "0.1.0",
scalaVersion := "2.13.3",
resolvers += Resolver.bintrayRepo("alexknvl", "maven"),
libraryDependencies ++= Seq(
"org.scala-graph" %% "graph-core" % "1.13.2",
"com.alexknvl" %% "polymorphic" % "0.5.0",
),
addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.11.0" cross CrossVersion.full),
).dependsOn(scodec)
lazy val tagless = (project in file("tagless")).settings(
organization := "tf.bug",
name := "fancadetagless",
version := "0.1.0",
scalaVersion := "2.13.3",
libraryDependencies ++= Seq(
"org.scala-graph" %% "graph-core" % "1.13.2",
"com.chuusai" %% "shapeless" % "2.3.3",
"org.typelevel" %% "cats-core" % "2.1.1",
"org.typelevel" %% "cats-effect" % "2.1.3",
"org.typelevel" %% "cats-collections-core" % "0.9.0",
"io.chrisdavenport" %% "fuuid" % "0.4.0",
"io.higherkindness" %% "droste-core" % "0.8.0",
"org.scalameta" %% "munit" % "0.7.9" % Test,
),
testFrameworks += new TestFramework("munit.Framework"),
addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.11.0" cross CrossVersion.full),
).dependsOn(scodec, graph)

View File

@ -0,0 +1,724 @@
package tf.bug.fancade
import tf.bug.shinji.{Arrow, ArrowLoop, Cartesian, Monoidal}
object Fanscript {
sealed trait Pin
case object Number extends Pin
case object Bool extends Pin
case object Vector extends Pin
case object Rotation extends Pin
case object Obj extends Pin
case object Constraint extends Pin
case object Pull extends Pin
case object T extends Pin
case class ×[A <: Pin, B <: Pin](a: A, b: B) extends Pin
trait PinEv[A <: Pin] {
val value: A
}
object PinEv {
implicit val pinValueForNumber: PinEv[Number.type] = new PinEv[Number.type] {
override val value: Number.type = Number
}
implicit val pinValueForBool: PinEv[Bool.type] = new PinEv[Bool.type] {
override val value: Bool.type = Bool
}
implicit val pinValueForVector: PinEv[Vector.type] = new PinEv[Vector.type] {
override val value: Vector.type = Vector
}
implicit val pinValueForRotation: PinEv[Rotation.type] = new PinEv[Rotation.type] {
override val value: Rotation.type = Rotation
}
implicit val pinValueForObj: PinEv[Obj.type] = new PinEv[Obj.type] {
override val value: Obj.type = Obj
}
implicit val pinValueForConstraint: PinEv[Constraint.type] = new PinEv[Constraint.type] {
override val value: Constraint.type = Constraint
}
implicit val pinValueForPull: PinEv[Pull.type] = new PinEv[Pull.type] {
override val value: Pull.type = Pull
}
implicit val pinValueForT: PinEv[T.type] = new PinEv[T.type] {
override val value: T.type = T
}
implicit def pinValueForProduct[A <: Pin, B <: Pin](implicit left: PinEv[A], right: PinEv[B]): PinEv[A × B] = new PinEv[A × B] {
override val value: A × B = ×(left.value, right.value)
}
}
sealed trait [A <: Pin, B <: Pin] {
def left: A
def right: B
final def leftEv: PinEv[A] = new PinEv[A] {
override val value: A = left
}
final def rightEv: PinEv[B] = new PinEv[B] {
override val value: B = right
}
final def andThen[C <: Pin](f: B C): A C =
fanscript.andThen(this, f)
final def >>>[C <: Pin](f: B C): A C =
andThen(f)
final def compose[C <: Pin](f: C A): C B =
fanscript.compose(this, f)
final def <<<[C <: Pin](f: C A): C B =
compose(f)
final def split[C <: Pin, D <: Pin](f: C D): (A × C) (B × D) =
fanscript.split(this, f)
final def ***[C <: Pin, D <: Pin](f: C D): (A × C) (B × D) =
split(f)
final def merge[C <: Pin](f: A C): A (B × C) =
fanscript.merge(this, f)
final def &&&[C <: Pin](f: A C): A (B × C) =
merge(f)
}
case class Id[A <: Pin](a: A) extends (A A) {
override def left: A = a
override def right: A = a
}
case class AndThen[A <: Pin, B <: Pin, C <: Pin](f: A B, g: B C) extends (A C) {
override def left: A = f.left
override def right: C = g.right
}
case class Swap[A <: Pin, B <: Pin](a: A, b: B) extends ((A × B) (B × A)) {
override def left: A × B = ×(a, b)
override def right: B × A = ×(b, a)
}
case class Deunit[A <: Pin](a: A) extends (A (T.type × A)) {
override def left: A = a
override def right: T.type × A = ×(T, a)
}
case class Unit[A <: Pin](a: A) extends ((T.type × A) A) {
override def left: T.type × A = ×(T, a)
override def right: A = a
}
case class Associate[A <: Pin, B <: Pin, C <: Pin](a: A, b: B, c: C) extends (((A × B) × C) (A × (B × C))) {
override def left: (A × B) × C = ×(×(a, b), c)
override def right: A × (B × C) = ×(a, ×(b, c))
}
case class Duplicate[A <: Pin](a: A) extends (A (A × A)) {
override def left: A = a
override def right: A × A = ×(a, a)
}
case class Terminate[A <: Pin](a: A) extends (A T.type) {
override def left: A = a
override def right: T.type = T
}
case class Bimap[A <: Pin, B <: Pin, C <: Pin, D <: Pin](f: A B, g: C D) extends ((A × C) (B × D)) {
override def left: A × C = ×(f.left, g.left)
override def right: B × D = ×(f.right, g.right)
}
case class Loop[A <: Pin, B <: Pin, C <: Pin](f: (A × C) (B × C)) extends (A B) {
override def left: A = f.left.a
override def right: B = f.right.a
}
case object Z extends (T.type Pull.type) {
override def left: T.type = T
override def right: Pull.type = Pull
}
def bubbleSort[In <: Pin, Out <: Pin](sort: Vector[Int])(implicit inEv: PinEv[In], outEv: PinEv[Out]): Option[In Out] = {
???
}
object Builtin {
case class NumberValue(number: Float) extends (T.type Number.type) {
override def left: T.type = T
override def right: Number.type = Number
}
case class VectorValue(x: Float, y: Float, z: Float) extends (T.type Vector.type) {
override def left: T.type = T
override def right: Vector.type = Vector
}
case class RotationValue(x: Float, y: Float, z: Float) extends (T.type Rotation.type) {
override def left: T.type = T
override def right: Rotation.type = Rotation
}
case object TrueValue extends (T.type Bool.type) {
override def left: T.type = T
override def right: Bool.type = Bool
}
case object FalseValue extends (T.type Bool.type) {
override def left: T.type = T
override def right: Bool.type = Bool
}
case object InspectNumber extends ((Number.type × Pull.type) Pull.type) {
override def left: Number.type × Pull.type = ×(Number, Pull)
override def right: Pull.type = Pull
}
case object InspectVector extends ((Vector.type × Pull.type) Pull.type) {
override def left: Vector.type × Pull.type = ×(Vector, Pull)
override def right: Pull.type = Pull
}
case object InspectRotation extends ((Rotation.type × Pull.type) Pull.type) {
override def left: Rotation.type × Pull.type = ×(Rotation, Pull)
override def right: Pull.type = Pull
}
case object InspectTruth extends ((Bool.type × Pull.type) Pull.type) {
override def left: Bool.type × Pull.type = ×(Bool, Pull)
override def right: Pull.type = Pull
}
case object InspectObject extends ((Obj.type × Pull.type) Pull.type) {
override def left: Obj.type × Pull.type = ×(Obj, Pull)
override def right: Pull.type = Pull
}
case object Win extends (Pull.type Pull.type) {
override def left: Pull.type = Pull
override def right: Pull.type = Pull
}
case object Lose extends (Pull.type Pull.type) {
override def left: Pull.type = Pull
override def right: Pull.type = Pull
}
case object SetScore extends ((Number.type × Pull.type) Pull.type) {
override def left: Number.type × Pull.type = ×(Number, Pull)
override def right: Pull.type = Pull
}
case object SetCamera extends ((Vector.type × Rotation.type × Number.type × Pull.type) Pull.type) {
override def left: Vector.type × Rotation.type × Number.type × Pull.type = ×(×(×(Vector, Rotation), Number), Pull)
override def right: Pull.type = Pull
}
case object SetLight extends ((Vector.type × Rotation.type × Pull.type) Pull.type) {
override def left: Vector.type × Rotation.type × Pull.type = ×(×(Vector, Rotation), Pull)
override def right: Pull.type = Pull
}
case object ScreenSize extends (T.type (Number.type × Number.type)) {
override def left: T.type = T
override def right: Number.type × Number.type = ×(Number, Number)
}
case object Accelerometer extends (T.type Vector.type) {
override def left: T.type = T
override def right: Vector.type = Vector
}
case object CurrentFrame extends (T.type Number.type) {
override def left: T.type = T
override def right: Number.type = Number
}
case object GetPosition extends (Obj.type (Vector.type × Rotation.type)) {
override def left: Obj.type = Obj
override def right: Vector.type × Rotation.type = ×(Vector, Rotation)
}
case object SetPosition extends ((Obj.type × Vector.type × Rotation.type × Pull.type) Pull.type) {
override def left: Obj.type × Vector.type × Rotation.type × Pull.type = ×(×(×(Obj, Vector), Rotation), Pull)
override def right: Pull.type = Pull
}
case object Raycast extends ((Vector.type × Vector.type) (Bool.type × Vector.type × Obj.type)) {
override def left: Vector.type × Vector.type = ×(Vector, Vector)
override def right: Bool.type × Vector.type × Obj.type = ×(×(Bool, Vector), Obj)
}
case object GetSize extends (Obj.type (Vector.type × Vector.type)) {
override def left: Obj.type = Obj
override def right: Vector.type × Vector.type = ×(Vector, Vector)
}
case object SetVisible extends ((Obj.type × Bool.type × Pull.type) Pull.type) {
override def left: Obj.type × Bool.type × Pull.type = ×(×(Obj, Bool), Pull)
override def right: Pull.type = Pull
}
case object CreateObject extends ((Obj.type × Pull.type) (Obj.type × Pull.type)) {
override def left: Obj.type × Pull.type = ×(Obj, Pull)
override def right: Obj.type × Pull.type = ×(Obj, Pull)
}
case object DestroyObject extends ((Obj.type × Pull.type) Pull.type) {
override def left: Obj.type × Pull.type = ×(Obj, Pull)
override def right: Pull.type = Pull
}
case class PlaySound(loop: Boolean, sample: SoundSample) extends ((Number.type × Number.type × Pull.type) (Number.type × Pull.type)) {
override def left: Number.type × Number.type × Pull.type = ×(×(Number, Number), Pull)
override def right: Number.type × Pull.type = ×(Number, Pull)
}
case object StopSound extends ((Number.type × Pull.type) Pull.type) {
override def left: Number.type × Pull.type = ×(Number, Pull)
override def right: Pull.type = Pull
}
case object VolumePitch extends ((Number.type × Number.type × Number.type × Pull.type) Pull.type) {
override def left: Number.type × Number.type × Number.type × Pull.type = ×(×(×(Number, Number), Number), Pull)
override def right: Pull.type = Pull
}
case object AddForce extends ((Obj.type × Vector.type × Vector.type × Vector.type × Vector.type × Pull.type) Pull.type) {
override def left: Obj.type × Vector.type × Vector.type × Vector.type × Vector.type × Pull.type = ×(×(×(×(×(Obj, Vector), Vector), Vector), Vector), Pull)
override def right: Pull.type = Pull
}
case object GetVelocity extends (Obj.type (Vector.type × Vector.type)) {
override def left: Obj.type = Obj
override def right: Vector.type × Vector.type = ×(Vector, Vector)
}
case object SetVelocity extends ((Obj.type × Vector.type × Vector.type × Pull.type) Pull.type) {
override def left: Obj.type × Vector.type × Vector.type × Pull.type = ×(×(×(Obj, Vector), Vector), Pull)
override def right: Pull.type = Pull
}
case object SetLocked extends ((Obj.type × Vector.type × Vector.type × Pull.type) Pull.type) {
override def left: Obj.type × Vector.type × Vector.type × Pull.type = ×(×(×(Obj, Vector), Vector), Pull)
override def right: Pull.type = Pull
}
case object SetMass extends ((Obj.type × Number.type × Pull.type) Pull.type) {
override def left: Obj.type × Number.type × Pull.type = ×(×(Obj, Number), Pull)
override def right: Pull.type = Pull
}
case object SetFriction extends ((Obj.type × Number.type × Pull.type) Pull.type) {
override def left: Obj.type × Number.type × Pull.type = ×(×(Obj, Number), Pull)
override def right: Pull.type = Pull
}
case object SetBounciness extends ((Obj.type × Number.type × Pull.type) Pull.type) {
override def left: Obj.type × Number.type × Pull.type = ×(×(Obj, Number), Pull)
override def right: Pull.type = Pull
}
case object SetGravity extends ((Vector.type × Pull.type) Pull.type) {
override def left: Vector.type × Pull.type = ×(Vector, Pull)
override def right: Pull.type = Pull
}
case object AddConstraint extends ((Obj.type × Obj.type × Vector.type × Pull.type) (Constraint.type × Pull.type)) {
override def left: Obj.type × Obj.type × Vector.type × Pull.type = ×(×(×(Obj, Obj), Vector), Pull)
override def right: Constraint.type × Pull.type = ×(Constraint, Pull)
}
case object LinearLimits extends ((Constraint.type × Vector.type × Vector.type × Pull.type) Pull.type) {
override def left: Constraint.type × Vector.type × Vector.type × Pull.type = ×(×(×(Constraint, Vector), Vector), Pull)
override def right: Pull.type = Pull
}
case object AngularLimits extends ((Constraint.type × Vector.type × Vector.type × Pull.type) Pull.type) {
override def left: Constraint.type × Vector.type × Vector.type × Pull.type = ×(×(×(Constraint, Vector), Vector), Pull)
override def right: Pull.type = Pull
}
case object LinearSpring extends ((Constraint.type × Vector.type × Vector.type × Pull.type) Pull.type) {
override def left: Constraint.type × Vector.type × Vector.type × Pull.type = ×(×(×(Constraint, Vector), Vector), Pull)
override def right: Pull.type = Pull
}
case object AngularSpring extends ((Constraint.type × Vector.type × Vector.type × Pull.type) Pull.type) {
override def left: Constraint.type × Vector.type × Vector.type × Pull.type = ×(×(×(Constraint, Vector), Vector), Pull)
override def right: Pull.type = Pull
}
case object LinearMotor extends ((Constraint.type × Vector.type × Vector.type × Pull.type) Pull.type) {
override def left: Constraint.type × Vector.type × Vector.type × Pull.type = ×(×(×(Constraint, Vector), Vector), Pull)
override def right: Pull.type = Pull
}
case object AngularMotor extends ((Constraint.type × Vector.type × Vector.type × Pull.type) Pull.type) {
override def left: Constraint.type × Vector.type × Vector.type × Pull.type = ×(×(×(Constraint, Vector), Vector), Pull)
override def right: Pull.type = Pull
}
case object If extends ((Bool.type × Pull.type × Pull.type × Pull.type) Pull.type) {
override def left: Bool.type × Pull.type × Pull.type × Pull.type = ×(×(×(Bool, Pull), Pull), Pull)
override def right: Pull.type = Pull
}
case object OnPlay extends ((Pull.type × Pull.type) Pull.type) {
override def left: Pull.type × Pull.type = ×(Pull, Pull)
override def right: Pull.type = Pull
}
case object LateUpdate extends ((Pull.type × Pull.type) Pull.type) {
override def left: Pull.type × Pull.type = ×(Pull, Pull)
override def right: Pull.type = Pull
}
case object BoxArt extends ((Pull.type × Pull.type) Pull.type) {
override def left: Pull.type × Pull.type = ×(Pull, Pull)
override def right: Pull.type = Pull
}
case class OnTouch(event: TouchEvent, finger: TouchFinger) extends ((Pull.type × Pull.type) (Number.type × Number.type × Pull.type)) {
override def left: Pull.type × Pull.type = ×(Pull, Pull)
override def right: Number.type × Number.type × Pull.type = ×(×(Number, Number), Pull)
}
case object OnSwipe extends ((Pull.type × Pull.type) (Vector.type × Pull.type)) {
override def left: Pull.type × Pull.type = ×(Pull, Pull)
override def right: Vector.type × Pull.type = ×(Vector, Pull)
}
case object OnCollision extends ((Obj.type × Pull.type × Pull.type) (Obj.type × Number.type × Vector.type × Pull.type)) {
override def left: Obj.type × Pull.type × Pull.type = ×(×(Obj, Pull), Pull)
override def right: Obj.type × Number.type × Vector.type × Pull.type = ×(×(×(Obj, Number), Vector), Pull)
}
case object Loop extends ((Number.type × Number.type × Pull.type × Pull.type) (Number.type × Pull.type)) {
override def left: Number.type × Number.type × Pull.type × Pull.type = ×(×(×(Number, Number), Pull), Pull)
override def right: Number.type × Pull.type = ×(Number, Pull)
}
case object Negate extends (Number.type Number.type) {
override def left: Number.type = Number
override def right: Number.type = Number
}
case object Inverse extends (Rotation.type Rotation.type) {
override def left: Rotation.type = Rotation
override def right: Rotation.type = Rotation
}
case object AddNumbers extends ((Number.type × Number.type) Number.type) {
override def left: Number.type × Number.type = ×(Number, Number)
override def right: Number.type = Number
}
case object AddVectors extends ((Vector.type × Vector.type) Vector.type) {
override def left: Vector.type × Vector.type = ×(Vector, Vector)
override def right: Vector.type = Vector
}
case object SubtractNumbers extends ((Number.type × Number.type) Number.type) {
override def left: Number.type × Number.type = ×(Number, Number)
override def right: Number.type = Number
}
case object SubtractVectors extends ((Vector.type × Vector.type) Vector.type) {
override def left: Vector.type × Vector.type = ×(Vector, Vector)
override def right: Vector.type = Vector
}
case object Multiply extends ((Number.type × Number.type) Number.type) {
override def left: Number.type × Number.type = ×(Number, Number)
override def right: Number.type = Number
}
case object Scale extends ((Vector.type × Number.type) Vector.type) {
override def left: Vector.type × Number.type = ×(Vector, Number)
override def right: Vector.type = Vector
}
case object Rotate extends ((Vector.type × Rotation.type) Vector.type) {
override def left: Vector.type × Rotation.type = ×(Vector, Rotation)
override def right: Vector.type = Vector
}
case object Combine extends ((Rotation.type × Rotation.type) Rotation.type) {
override def left: Rotation.type × Rotation.type = ×(Rotation, Rotation)
override def right: Rotation.type = Rotation
}
case object Divide extends ((Number.type × Number.type) Number.type) {
override def left: Number.type × Number.type = ×(Number, Number)
override def right: Number.type = Number
}
case object Power extends ((Number.type × Number.type) Number.type) {
override def left: Number.type × Number.type = ×(Number, Number)
override def right: Number.type = Number
}
case object EqualNumbers extends ((Number.type × Number.type) Bool.type) {
override def left: Number.type × Number.type = ×(Number, Number)
override def right: Bool.type = Bool
}
case object EqualVectors extends ((Vector.type × Vector.type) Bool.type) {
override def left: Vector.type × Vector.type = ×(Vector, Vector)
override def right: Bool.type = Bool
}
case object EqualObjects extends ((Obj.type × Obj.type) Bool.type) {
override def left: Obj.type × Obj.type = ×(Obj, Obj)
override def right: Bool.type = Bool
}
case object EqualTruths extends ((Bool.type × Bool.type) Bool.type) {
override def left: Bool.type × Bool.type = ×(Bool, Bool)
override def right: Bool.type = Bool
}
case object LessThan extends ((Number.type × Number.type) Bool.type) {
override def left: Number.type × Number.type = ×(Number, Number)
override def right: Bool.type = Bool
}
case object GreaterThan extends ((Number.type × Number.type) Bool.type) {
override def left: Number.type × Number.type = ×(Number, Number)
override def right: Bool.type = Bool
}
case object And extends ((Bool.type × Bool.type) Bool.type) {
override def left: Bool.type × Bool.type = ×(Bool, Bool)
override def right: Bool.type = Bool
}
case object Or extends ((Bool.type × Bool.type) Bool.type) {
override def left: Bool.type × Bool.type = ×(Bool, Bool)
override def right: Bool.type = Bool
}
case object Not extends (Bool.type Bool.type) {
override def left: Bool.type = Bool
override def right: Bool.type = Bool
}
case object Random extends ((Number.type × Number.type) Number.type) {
override def left: Number.type × Number.type = ×(Number, Number)
override def right: Number.type = Number
}
case object RandomSeed extends ((Number.type × Pull.type) Pull.type) {
override def left: Number.type × Pull.type = ×(Number, Pull)
override def right: Pull.type = Pull
}
case object Min extends ((Number.type × Number.type) Number.type) {
override def left: Number.type × Number.type = ×(Number, Number)
override def right: Number.type = Number
}
case object Max extends ((Number.type × Number.type) Number.type) {
override def left: Number.type × Number.type = ×(Number, Number)
override def right: Number.type = Number
}
case object Sin extends (Number.type Number.type) {
override def left: Number.type = Number
override def right: Number.type = Number
}
case object Cos extends (Number.type Number.type) {
override def left: Number.type = Number
override def right: Number.type = Number
}
case object Round extends (Number.type Number.type) {
override def left: Number.type = Number
override def right: Number.type = Number
}
case object Floor extends (Number.type Number.type) {
override def left: Number.type = Number
override def right: Number.type = Number
}
case object Ceiling extends (Number.type Number.type) {
override def left: Number.type = Number
override def right: Number.type = Number
}
case object Absolute extends (Number.type Number.type) {
override def left: Number.type = Number
override def right: Number.type = Number
}
case object Modulo extends ((Number.type × Number.type) Number.type) {
override def left: Number.type × Number.type = ×(Number, Number)
override def right: Number.type = Number
}
case object Logarithm extends ((Number.type × Number.type) Number.type) {
override def left: Number.type × Number.type = ×(Number, Number)
override def right: Number.type = Number
}
case object BreakVector extends (Vector.type (Number.type × Number.type × Number.type)) {
override def left: Vector.type = Vector
override def right: Number.type × Number.type × Number.type = ×(×(Number, Number), Number)
}
case object MakeVector extends ((Number.type × Number.type × Number.type) Vector.type) {
override def left: Number.type × Number.type × Number.type = ×(×(Number, Number), Number)
override def right: Vector.type = Vector
}
case object Normalize extends (Vector.type Vector.type) {
override def left: Vector.type = Vector
override def right: Vector.type = Vector
}
case object DotProduct extends ((Vector.type × Vector.type) Vector.type) {
override def left: Vector.type × Vector.type = ×(Vector, Vector)
override def right: Vector.type = Vector
}
case object CrossProduct extends ((Vector.type × Vector.type) Vector.type) {
override def left: Vector.type × Vector.type = ×(Vector, Vector)
override def right: Vector.type = Vector
}
case object BreakRotation extends (Rotation.type (Number.type × Number.type × Number.type)) {
override def left: Rotation.type = Rotation
override def right: Number.type × Number.type × Number.type = ×(×(Number, Number), Number)
}
case object MakeRotation extends ((Number.type × Number.type × Number.type) Rotation.type) {
override def left: Number.type × Number.type × Number.type = ×(×(Number, Number), Number)
override def right: Rotation.type = Rotation
}
case object Distance extends ((Vector.type × Vector.type) Number.type) {
override def left: Vector.type × Vector.type = ×(Vector, Vector)
override def right: Number.type = Number
}
case object LERP extends ((Rotation.type × Rotation.type × Number.type) Rotation.type) {
override def left: Rotation.type × Rotation.type × Number.type = ×(×(Rotation, Rotation), Number)
override def right: Rotation.type = Rotation
}
case object AxisAngle extends ((Vector.type × Number.type) Rotation.type) {
override def left: Vector.type × Number.type = ×(Vector, Number)
override def right: Rotation.type = Rotation
}
case object ScreenToWorld extends ((Number.type × Number.type) (Vector.type × Vector.type)) {
override def left: Number.type × Number.type = ×(Number, Number)
override def right: Vector.type × Vector.type = ×(Vector, Vector)
}
case object WorldToScreen extends (Vector.type (Number.type × Number.type)) {
override def left: Vector.type = Vector
override def right: Number.type × Number.type = ×(Number, Number)
}
case object LineVsPlane extends ((Vector.type × Vector.type × Vector.type × Vector.type) Vector.type) {
override def left: Vector.type × Vector.type × Vector.type × Vector.type = ×(×(×(Vector, Vector), Vector), Vector)
override def right: Vector.type = Vector
}
case object LookRotation extends ((Vector.type × Vector.type) Rotation.type) {
override def left: Vector.type × Vector.type = ×(Vector, Vector)
override def right: Rotation.type = Rotation
}
case class GetNumber(name: String) extends (T.type Number.type) {
override def left: T.type = T
override def right: Number.type = Number
}
case class GetObject(name: String) extends (T.type Obj.type) {
override def left: T.type = T
override def right: Obj.type = Obj
}
case class GetVector(name: String) extends (T.type Vector.type) {
override def left: T.type = T
override def right: Vector.type = Vector
}
case class GetRotation(name: String) extends (T.type Rotation.type) {
override def left: T.type = T
override def right: Rotation.type = Rotation
}
case class GetTruth(name: String) extends (T.type Bool.type) {
override def left: T.type = T
override def right: Bool.type = Bool
}
case class GetConstraint(name: String) extends (T.type Constraint.type) {
override def left: T.type = T
override def right: Constraint.type = Constraint
}
case class SetNumber(name: String) extends ((Number.type × Pull.type) Pull.type) {
override def left: Number.type × Pull.type = ×(Number, Pull)
override def right: Pull.type = Pull
}
case class SetObject(name: String) extends ((Obj.type × Pull.type) Pull.type) {
override def left: Obj.type × Pull.type = ×(Obj, Pull)
override def right: Pull.type = Pull
}
case class SetVector(name: String) extends ((Vector.type × Pull.type) Pull.type) {
override def left: Vector.type × Pull.type = ×(Vector, Pull)
override def right: Pull.type = Pull
}
case class SetRotation(name: String) extends ((Rotation.type × Pull.type) Pull.type) {
override def left: Rotation.type × Pull.type = ×(Rotation, Pull)
override def right: Pull.type = Pull
}
case class SetTruth(name: String) extends ((Bool.type × Pull.type) Pull.type) {
override def left: Bool.type × Pull.type = ×(Bool, Pull)
override def right: Pull.type = Pull
}
case class SetConstraint(name: String) extends ((Constraint.type × Pull.type) Pull.type) {
override def left: Constraint.type × Pull.type = ×(Constraint, Pull)
override def right: Pull.type = Pull
}
case object SetNumberRef extends ((Number.type × Number.type × Pull.type) Pull.type) {
override def left: Number.type × Number.type × Pull.type = ×(×(Number, Number), Pull)
override def right: Pull.type = Pull
}
case object SetObjectRef extends ((Obj.type × Obj.type × Pull.type) Pull.type) {
override def left: Obj.type × Obj.type × Pull.type = ×(×(Obj, Obj), Pull)
override def right: Pull.type = Pull
}
case object SetVectorRef extends ((Vector.type × Vector.type × Pull.type) Pull.type) {
override def left: Vector.type × Vector.type × Pull.type = ×(×(Vector, Vector), Pull)
override def right: Pull.type = Pull
}
case object SetRotationRef extends ((Rotation.type × Rotation.type × Pull.type) Pull.type) {
override def left: Rotation.type × Rotation.type × Pull.type = ×(×(Rotation, Rotation), Pull)
override def right: Pull.type = Pull
}
case object SetTruthRef extends ((Bool.type × Bool.type × Pull.type) Pull.type) {
override def left: Bool.type × Bool.type × Pull.type = ×(×(Bool, Bool), Pull)
override def right: Pull.type = Pull
}
case object SetConstraintRef extends ((Constraint.type × Constraint.type × Pull.type) Pull.type) {
override def left: Constraint.type × Constraint.type × Pull.type = ×(×(Constraint, Constraint), Pull)
override def right: Pull.type = Pull
}
case object ListNumber extends ((Number.type × Number.type) Number.type) {
override def left: Number.type × Number.type = ×(Number, Number)
override def right: Number.type = Number
}
case object ListObject extends ((Obj.type × Number.type) Obj.type) {
override def left: Obj.type × Number.type = ×(Obj, Number)
override def right: Obj.type = Obj
}
case object ListVector extends ((Vector.type × Number.type) Vector.type) {
override def left: Vector.type × Number.type = ×(Vector, Number)
override def right: Vector.type = Vector
}
case object ListRotation extends ((Rotation.type × Number.type) Rotation.type) {
override def left: Rotation.type × Number.type = ×(Rotation, Number)
override def right: Rotation.type = Rotation
}
case object ListTruth extends ((Bool.type × Number.type) Bool.type) {
override def left: Bool.type × Number.type = ×(Bool, Number)
override def right: Bool.type = Bool
}
case object ListConstraint extends ((Constraint.type × Number.type) Constraint.type) {
override def left: Constraint.type × Number.type = ×(Constraint, Number)
override def right: Constraint.type = Constraint
}
case object Increment extends ((Number.type × Pull.type) Pull.type) {
override def left: Number.type × Pull.type = ×(Number, Pull)
override def right: Pull.type = Pull
}
case object Decrement extends ((Number.type × Pull.type) Pull.type) {
override def left: Number.type × Pull.type = ×(Number, Pull)
override def right: Pull.type = Pull
}
}
implicit lazy val fanscript:
Cartesian[Pin, PinEv, , T.type, ×] with ArrowLoop[Pin, PinEv, , T.type, ×, ] =
new Cartesian[Pin, PinEv, , T.type, ×] with ArrowLoop[Pin, PinEv, , T.type, ×, ] {
override def duplicate[A <: Pin](implicit a: PinEv[A]): A (A × A) =
Duplicate(a.value)
override def terminate[A <: Pin](implicit a: PinEv[A]): A T.type =
Terminate(a.value)
override def loop[A <: Pin, B <: Pin, C <: Pin](f: (A × C) (B × C)): A B =
Loop(f)
override def lift[A <: Pin, B <: Pin](f: A B): A B =
f
override def id[A <: Pin](implicit a: PinEv[A]): A A =
Id(a.value)
override def strongProfunctorCategory: Monoidal[Pin, PinEv, , T.type, ×] =
this
override def first[A <: Pin, B <: Pin, C <: Pin](f: A B)(implicit c: PinEv[C]): (A × C) (B × C) =
bimap(f, id[C])
override def second[A <: Pin, B <: Pin, C <: Pin](f: A B)(implicit c: PinEv[C]): (C × A) (C × B) = {
implicit val a: PinEv[A] = f.leftEv
implicit val b: PinEv[B] = f.rightEv
val unswapped: (A × C) (B × C) = first(f)
andThen(swap[C, A], andThen(unswapped, swap[B, C]))
}
override def profunctorLeftConstraint[A <: Pin, B <: Pin](f: A B): PinEv[A] =
f.leftEv
override def profunctorRightConstraint[A <: Pin, B <: Pin](f: A B): PinEv[B] =
f.rightEv
override def swap[A <: Pin, B <: Pin](implicit a: PinEv[A], b: PinEv[B]): (A × B) (B × A) =
Swap(a.value, b.value)
override implicit def unitConstraint: PinEv[T.type] =
PinEv.pinValueForT
override def associateRight[A <: Pin, B <: Pin, C <: Pin](implicit a: PinEv[A], b: PinEv[B], c: PinEv[C]): ((A × B) × C) (A × (B × C)) =
Associate(a.value, b.value, c.value)
override def unitorLeft[A <: Pin](implicit a: PinEv[A]): (T.type × A) A =
Unit(a.value)
override def deunitorLeft[A <: Pin](implicit a: PinEv[A]): A (T.type × A) =
Deunit(a.value)
override def homLeftConstraint[A <: Pin, B <: Pin](hom: A B): PinEv[A] =
hom.leftEv
override def homRightConstraint[A <: Pin, B <: Pin](hom: A B): PinEv[B] =
hom.rightEv
override def andThen[A <: Pin, B <: Pin, C <: Pin](f: A B, g: B C): A C =
AndThen(f, g)
override def compose[A <: Pin, B <: Pin, C <: Pin](f: B C, g: A B): A C =
andThen(g, f)
override implicit def bifunctorApplyConstraint[A <: Pin, B <: Pin](implicit a: PinEv[A], b: PinEv[B]): PinEv[A × B] =
PinEv.pinValueForProduct[A, B](a, b)
override def bifunctorLeftConstraint[A <: Pin, B <: Pin](implicit e: PinEv[A × B]): PinEv[A] =
new PinEv[A] {
override val value: A = e.value.a
}
override def bifunctorRightConstraint[A <: Pin, B <: Pin](implicit e: PinEv[A × B]): PinEv[B] =
new PinEv[B] {
override val value: B = e.value.b
}
override def bimap[A <: Pin, B <: Pin, C <: Pin, D <: Pin](f: A C, g: B D): (A × B) (C × D) =
Bimap(f, g)
}
}

View File

@ -0,0 +1,193 @@
package tf.bug.fancade
object Main {
def main(args: Array[String]): Unit = {
import Fanscript._
import tf.bug.shinji.syntax.all._
// min, max, start, result, after -> end, index, sum, before
val sum: (Number.type × Number.type × Pull.type × Number.type × Pull.type) (Pull.type × Number.type × Number.type × Pull.type) = {
val getSum: T.type Number.type = Builtin.GetNumber("Sum")
val setSum: (Number.type × Pull.type) Pull.type = Builtin.SetNumber("Sum")
val addToSum: (Number.type × Pull.type) Pull.type = {
val add: (Number.type × Number.type) Number.type = Builtin.AddNumbers
val sumAsFirstInput: (T.type × Number.type) (Number.type × Number.type) = fanscript.first(getSum)
val branch: Number.type (T.type × Number.type) = fanscript.deunitorLeft
val justSecondInput: Number.type (Number.type × Number.type) = fanscript.andThen(branch, sumAsFirstInput)
val addSum: Number.type Number.type = fanscript.ldimap[Number.type × Number.type, Number.type, Number.type](justSecondInput).apply(add)
val storeSum: (Number.type × Pull.type) Pull.type = setSum
fanscript.ldimap[Number.type × Pull.type, Pull.type, Number.type × Pull.type](fanscript.lbimap(addSum)).apply(storeSum)
}
val getIndex: T.type Number.type = Builtin.GetNumber("Index")
val setIndex: (Number.type × Pull.type) Pull.type = Builtin.SetNumber("Index")
val indexGreaterThan: Number.type Bool.type = {
val greaterThan: (Number.type × Number.type) Bool.type = Builtin.GreaterThan
val indexAsFirstInput: (T.type × Number.type) (Number.type × Number.type) = fanscript.first(getIndex)
val branch: Number.type (T.type × Number.type) = fanscript.deunitorLeft
val comparisonAsSecondInput: Number.type (Number.type × Number.type) = fanscript.andThen(branch, indexAsFirstInput)
fanscript.andThen(comparisonAsSecondInput, greaterThan)
}
val indexNotGreaterThan: Number.type Bool.type = fanscript.andThen(indexGreaterThan, Builtin.Not)
val checkContinue: (Number.type × Pull.type × Pull.type × Pull.type) Pull.type = {
val ifBlock: (Bool.type × Pull.type × Pull.type × Pull.type) Pull.type = Builtin.If
val checkGreater: (Number.type × Pull.type × Pull.type × Pull.type) (Bool.type × Pull.type × Pull.type × Pull.type) = {
val one: (Number.type × Pull.type) (Bool.type × Pull.type) = fanscript.first(indexGreaterThan)
val two: (Number.type × Pull.type × Pull.type) (Bool.type × Pull.type × Pull.type) = fanscript.first(one)
val three: (Number.type × Pull.type × Pull.type × Pull.type) (Bool.type × Pull.type × Pull.type × Pull.type) = fanscript.first(two)
three
}
fanscript.andThen(checkGreater, ifBlock)
}
// sumToIndex -> before
val initializeSum: Pull.type Pull.type = {
val zero: T.type Number.type = Builtin.NumberValue(0.0F)
val zeroAsInput: (T.type × Pull.type) (Number.type × Pull.type) = fanscript.first(zero)
val branch: Pull.type (T.type × Pull.type) = fanscript.deunitorLeft[Pull.type]
fanscript.andThen(fanscript.andThen(branch, zeroAsInput), setSum)
}
// min, indexToLoopStart -> sumToIndex
val initializeIndex: (Number.type × Pull.type) Pull.type = setIndex
// max, start, , after -> (indexToLoopStart + incrementToLoop)
val startLoop: (Number.type × Pull.type × Pull.type × Pull.type) Pull.type = checkContinue
// result, increaseSum -> end
val increaseSum: (Number.type × Pull.type) Pull.type = addToSum
// incrementToLoop -> increaseSum
val incrementIndex: Pull.type Pull.type = {
val get: T.type Number.type = getIndex
val set: (Number.type × Pull.type) Pull.type = setIndex
val one: T.type Number.type = Builtin.NumberValue(1.0F)
val additionOperands: T.type (Number.type × Number.type) = fanscript.merge(get, one)
val add: T.type Number.type = fanscript.andThen(additionOperands, Builtin.AddNumbers)
val carryPull: (T.type × Pull.type) (Number.type × Pull.type) = fanscript.first(add)
val branch: Pull.type (T.type × Pull.type) = fanscript.deunitorLeft[Pull.type]
fanscript.andThen(fanscript.andThen(branch, carryPull), set)
}
// min, indexToLoopStart -> before
val initialize: (Number.type × Pull.type) Pull.type = fanscript.andThen(initializeIndex, initializeSum)
// result, incrementToLoop -> end
val postLoop: (Number.type × Pull.type) Pull.type = {
val carryResult = fanscript.second[Pull.type, Pull.type, Number.type](incrementIndex)
fanscript.andThen(carryResult, increaseSum)
}
// max, start, after -> (indexToLoopStart + incrementToLoop)
val condition: (Number.type × Pull.type × Pull.type) Pull.type = {
val zThree: (Number.type × Pull.type) (Number.type × Pull.type × Pull.type) =
fanscript.andThen(fanscript.deunitorRight, fanscript.rbimap(Z))
val zFour: (Number.type × Pull.type × Pull.type) (Number.type × Pull.type × Pull.type × Pull.type) =
fanscript.lbimap(zThree)
fanscript.ldimap[Number.type × Pull.type × Pull.type × Pull.type, Pull.type, Number.type × Pull.type × Pull.type](zFour).apply(checkContinue)
}
// min, max, start, result, after -> end, index, sum, before
val result: (Number.type × Number.type × Pull.type × Number.type × Pull.type) (Pull.type × Number.type × Number.type × Pull.type) = {
// max, start, after -> indexToLoopStart, incrementToLoop
val duplicateCondition: (Number.type × Pull.type × Pull.type) (Pull.type × Pull.type) =
fanscript.andThen(condition, fanscript.duplicate)
// min, indexToLoopStart, result, incrementToLoop -> before, end
val conditionPrecursors: (Number.type × Pull.type × Number.type × Pull.type) (Pull.type × Pull.type) =
fanscript.associateRight[Number.type × Pull.type, Number.type, Pull.type] >>> (initialize *** postLoop)
// min, result, (indexToLoopStart, incrementToLoop) -> end, before
val orientConditionPrecursors: ((Number.type × Number.type) × (Pull.type × Pull.type)) (Pull.type × Pull.type) = {
val flattenAssoc: ((Number.type × Number.type) × (Pull.type × Pull.type)) (((Number.type × Number.type) × Pull.type) × Pull.type) = fanscript.associateLeft
val assocInside: (((Number.type × Number.type) × Pull.type) × Pull.type) ((Number.type × (Number.type × Pull.type)) × Pull.type) = fanscript.lbimap(fanscript.associateRight)
val swapInside: ((Number.type × (Number.type × Pull.type)) × Pull.type) ((Number.type × (Pull.type × Number.type)) × Pull.type) = fanscript.lbimap(fanscript.rbimap(fanscript.swap))
val reassocInside: ((Number.type × (Pull.type × Number.type)) × Pull.type) (((Number.type × Pull.type) × Number.type) × Pull.type) = fanscript.lbimap(fanscript.associateLeft)
val orientConditionInputs: ((Number.type × Number.type) × (Pull.type × Pull.type)) (((Number.type × Pull.type) × Number.type) × Pull.type) =
fanscript.andThen(fanscript.andThen(fanscript.andThen(flattenAssoc, assocInside), swapInside), reassocInside)
val swapEnd: (Pull.type × Pull.type) (Pull.type × Pull.type) = fanscript.swap
fanscript.dimap(orientConditionInputs, swapEnd)(conditionPrecursors)
}
// min, max, start, result, after -> end, before
val nonNumbers: (Number.type × Number.type × Pull.type × Number.type × Pull.type) (Pull.type × Pull.type) = {
val duplicateConditionLeftNumbers: ((Number.type × Number.type) × (Number.type × Pull.type × Pull.type)) ((Number.type × Number.type) × (Pull.type × Pull.type)) =
fanscript.second[Number.type × Pull.type × Pull.type, Pull.type × Pull.type, Number.type × Number.type](duplicateCondition)
// (min, result), (max, start, after) -> end, before
val aggregate: ((Number.type × Number.type) × (Number.type × Pull.type × Pull.type)) (Pull.type × Pull.type) =
fanscript.andThen(duplicateConditionLeftNumbers, orientConditionPrecursors)
// (max, start, after, (min, result)) -> end, before
val align: (Number.type × Pull.type × Pull.type × (Number.type × Number.type)) (Pull.type × Pull.type) =
fanscript.andThen(fanscript.swap, aggregate)
// max, start, after, min, result -> end, before
val assoc: (Number.type × Pull.type × Pull.type × Number.type × Number.type) (Pull.type × Pull.type) =
fanscript.andThen(fanscript.associateRight, align)
// min, max, start, result, after -> max, start, after, min, result
val realign: ((((Number.type × Number.type) × Pull.type) × Number.type) × Pull.type) ((((Number.type × Pull.type) × Pull.type) × Number.type) × Number.type) = {
val one: ((((Number.type × Number.type) × Pull.type) × Number.type) × Pull.type) (((Number.type × (Number.type × Pull.type)) × Number.type) × Pull.type) =
fanscript.lbimap(fanscript.lbimap(fanscript.associateRight))
val two: (((Number.type × (Number.type × Pull.type)) × Number.type) × Pull.type) ((((Number.type × Pull.type) × Number.type) × Number.type) × Pull.type) =
fanscript.lbimap(fanscript.lbimap(fanscript.swap))
val three: ((((Number.type × Pull.type) × Number.type) × Number.type) × Pull.type) (((Number.type × Pull.type) × Number.type) × (Number.type × Pull.type)) =
fanscript.associateRight
val four: (((Number.type × Pull.type) × Number.type) × (Number.type × Pull.type)) (((Number.type × Pull.type) × Number.type) × (Pull.type × Number.type)) =
fanscript.rbimap(fanscript.swap)
val five: (((Number.type × Pull.type) × Number.type) × (Pull.type × Number.type)) ((((Number.type × Pull.type) × Number.type) × Pull.type) × Number.type) =
fanscript.associateLeft
val six: ((((Number.type × Pull.type) × Number.type) × Pull.type) × Number.type) (((Number.type × Pull.type) × (Number.type × Pull.type)) × Number.type) =
fanscript.lbimap(fanscript.associateRight)
val seven: (((Number.type × Pull.type) × (Number.type × Pull.type)) × Number.type) (((Number.type × Pull.type) × (Pull.type × Number.type)) × Number.type) =
fanscript.lbimap(fanscript.rbimap(fanscript.swap))
val eight: (((Number.type × Pull.type) × (Pull.type × Number.type)) × Number.type) ((((Number.type × Pull.type) × Pull.type) × Number.type) × Number.type) =
fanscript.lbimap(fanscript.associateLeft)
fanscript.andThen(
fanscript.andThen(
fanscript.andThen(
fanscript.andThen(
fanscript.andThen(
fanscript.andThen(
fanscript.andThen(
one,
two
),
three
),
four
),
five
),
six
),
seven
),
eight
)
}
fanscript.andThen(realign, assoc)
}
// end, before -> end, index, sum, before
val addOutputs: (Pull.type × Pull.type) (Pull.type × Number.type × Number.type × Pull.type) =
fanscript.lbimap(fanscript.andThen(
fanscript.andThen[Pull.type, Pull.type × T.type, Pull.type × Number.type](fanscript.deunitorRight[Pull.type], fanscript.rbimap(getIndex)),
fanscript.andThen[Pull.type × Number.type, Pull.type × Number.type × T.type, Pull.type × Number.type × Number.type](fanscript.deunitorRight[Pull.type × Number.type], fanscript.rbimap(getSum))
))
fanscript.andThen(nonNumbers, addOutputs)
}
result
}
pprint.pprintln(sum)
}
}

View File

@ -0,0 +1,23 @@
package tf.bug.fancade
sealed trait SoundSample
object SoundSample {
case object Chirp extends SoundSample
case object Scrape extends SoundSample
case object Squeek extends SoundSample
case object Engine extends SoundSample
case object Button extends SoundSample
case object Ball extends SoundSample
case object Piano extends SoundSample
case object Marimba extends SoundSample
case object Pad extends SoundSample
case object Beep extends SoundSample
case object Plop extends SoundSample
case object Flop extends SoundSample
case object Splash extends SoundSample
case object Boom extends SoundSample
case object Hit extends SoundSample
case object Clang extends SoundSample
case object Jump extends SoundSample
}

View File

@ -0,0 +1,9 @@
package tf.bug.fancade
sealed trait TouchEvent
object TouchEvent {
case object Touching extends TouchEvent
case object Begins extends TouchEvent
case object Ends extends TouchEvent
}

View File

@ -0,0 +1,9 @@
package tf.bug.fancade
sealed trait TouchFinger
object TouchFinger {
case object First extends TouchFinger
case object Second extends TouchFinger
case object Third extends TouchFinger
}

View File

@ -1,39 +0,0 @@
package tf.bug.fancadegraph
import tf.bug.{fancadescodec => fansc}
trait Argument[T] {
def encode(value: T)(pos: fansc.Position): Vector[fansc.Metadata]
}
object Argument {
implicit val unitArg: Argument[Unit] = new Argument[Unit] {
override def encode(value: Unit)(pos: fansc.Position): Vector[fansc.Metadata] = Vector.empty
}
implicit val stringArg: Argument[String] = new Argument[String] {
override def encode(value: String)(pos: fansc.Position): Vector[fansc.Metadata] = Vector(
fansc.Metadata.Text(pos, value)
)
}
implicit val floatArg: Argument[Float] = new Argument[Float] {
override def encode(value: Float)(pos: fansc.Position): Vector[fansc.Metadata] = Vector(
fansc.Metadata.Number(pos, value)
)
}
implicit val booleanArg: Argument[Boolean] = new Argument[Boolean] {
override def encode(value: Boolean)(pos: fansc.Position): Vector[fansc.Metadata] = Vector(
fansc.Metadata.Bool(pos, value)
)
}
implicit val soundOptionsArg: Argument[SoundOptions] = new Argument[SoundOptions] {
override def encode(value: SoundOptions)(pos: fansc.Position): Vector[fansc.Metadata] = Vector(
fansc.Metadata.Bool(pos, value.loop),
fansc.Metadata.PlaySoundSample(pos, value.sample)
)
}
}
case class SoundOptions(
loop: Boolean,
sample: fansc.Metadata.Sample
)

View File

@ -1,14 +0,0 @@
package tf.bug.fancadegraph
import polymorphic._
import tf.bug.fancadescodec.{Metadata, Position}
case class Block(
position: Position,
template: Exists[Template]
) {
def metadata: Vector[Metadata] = {
val t = Exists.unwrap(template)
t.ev.encode(t.args)(position)
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,92 +0,0 @@
package tf.bug.fancadegraph
import cats.data._
import polymorphic._
import scalax.collection.Graph
import scalax.collection.GraphEdge.DiHyperEdge
import tf.bug.{fancadescodec => fansc}
case class Level(
blocks: Set[Block],
wires: Graph[Pin, DiHyperEdge]
) {
def boundary =
blocks.foldLeft(fansc.Boundary(0, 0, 0)) {
case (fansc.Boundary(lr, du, nf), block) =>
val tlr = block.position.lr + Exists.unwrap(block.template).definition.width
val tdu = block.position.du + Exists.unwrap(block.template).definition.height
val tnf = block.position.nf + Exists.unwrap(block.template).definition.depth
fansc.Boundary(lr.max(tlr), du.max(tdu), nf.max(tnf))
}
}
object Level {
def validate(level: Level): Chain[String] = {
???
}
def encode(level: Level): tf.bug.fancadescodec.Entry = {
val boundary = level.boundary
val objs: Vector[fansc.Obj] = {
val initialVector = Vector.fill(boundary.sizeNF, boundary.sizeDU, boundary.sizeLR)(fansc.Obj.empty)
level.blocks.foldLeft(initialVector) {
case (ew, nb) =>
val fansc.Position(sx, sy, sz) = nb.position
val nbd = Exists.unwrap(nb.template).definition
(0 until nbd.depth).foldLeft(ew) {
case (zw, z) =>
(0 until nbd.height).foldLeft(zw) {
case (yw, y) =>
(0 until nbd.width).foldLeft(yw) {
case (xw, x) =>
val objInd = x + (y * nbd.width) + (z * nbd.width * nbd.height)
xw.updated(sz + z, xw(sz + z).updated(sy + y, xw(sz + z)(sy + y).updated(sx + x, nbd.ids(objInd))))
}
}
}
}
}.flatten.flatten
val metadatas = level.blocks.toVector.map(_.metadata).flatten
val wires = level.wires.edges.toVector.map(_.edge).flatMap {
edge =>
val from = edge.nodeSeq.head
edge.nodeSeq.tail.map { to =>
if(from.definition.dataType == PinType.Pull) {
fansc.Wire(
to.basePosition,
from.basePosition,
to.definition.voxel,
from.definition.voxel
)
} else {
fansc.Wire(
from.basePosition,
to.basePosition,
from.definition.voxel,
to.definition.voxel
)
}
}
}
fansc.Entry(
Some(0x03), // TODO
"hello", // TODO
None, // TODO
Some(fansc.World(
boundary,
objs
)),
Some(metadatas),
Some(wires)
)
}
def toScodec(ours: Level): ValidatedNec[String, tf.bug.fancadescodec.Entry] = {
NonEmptyChain.fromChain(validate(ours))
.fold[ValidatedNec[String, tf.bug.fancadescodec.Entry]](
Validated.Valid(encode(ours))
)(Validated.Invalid(_))
}
}

View File

@ -1,47 +0,0 @@
package tf.bug.fancadegraph
import cats.effect.{Blocker, ExitCode, IO, IOApp}
import fs2._
import java.nio.file.{Paths, StandardOpenOption}
import polymorphic._
import scalax.collection.Graph
import scalax.collection.GraphEdge.DiHyperEdge
import scodec.stream.StreamEncoder
import tf.bug.fancadescodec.{Cartridge, Codecs, Position}
object Main extends IOApp {
override def run(args: List[String]): IO[ExitCode] = {
val winBlock = Block(Position(0, 0, 0), Exists(Template(BlockDefinition.Win, true)))
val loseBlock = Block(Position(0, 0, 3), Exists(Template(BlockDefinition.Lose, true)))
val loseAfter = Pin(loseBlock.position, BlockDefinition.Lose.after)
val winBefore = Pin(winBlock.position, BlockDefinition.Win.before)
val level = Level(
Set(
winBlock,
loseBlock
),
Graph[Pin, DiHyperEdge](
DiHyperEdge(winBefore, loseAfter)
)
)
val output = Paths.get("""C:\Users\aprim\Documents\FancadeLevels\GraphTest""")
val cart = Cartridge(
"Graph Test",
"Raymond AC",
"Test of Fancade Graph Library",
Vector(
Level.encode(level)
)
)
(for {
blocker <- Stream.resource(Blocker[IO])
result <- Stream.emit[IO, Cartridge](cart)
.through(StreamEncoder.once(Codecs.encCartridge).toPipeByte[IO])
.through(io.file.writeAll(output, blocker, Seq(StandardOpenOption.CREATE_NEW)))
} yield result).compile.drain.as(ExitCode.Success)
}
}

View File

@ -1,8 +0,0 @@
package tf.bug.fancadegraph
import tf.bug.fancadescodec.Position
case class Pin(
basePosition: Position,
definition: PinDefinition
)

View File

@ -1,47 +0,0 @@
package tf.bug.fancadegraph
import tf.bug.fancadescodec.Position
case class PinDefinition(
dataType: PinType,
direction: PinDirection,
voxel: Position
)
sealed trait PinType
object PinType {
case object Number extends PinType
case object Object extends PinType
case object Vector extends PinType
case object Rotation extends PinType
case object Truth extends PinType
case object Constraint extends PinType
case object Pull extends PinType
case class Pointer(of: PinType) extends PinType
}
sealed trait PinDirection
object PinDirection {
case object Input extends PinDirection
case object Output extends PinDirection
}
object PinPosition {
def bottom(n: Int): Position = Position(3 + (8 * n), 1, 0)
def top(depth: Int)(n: Int): Position = Position(3 + (8 * n), 1, 6 + (8 * (depth - 1)))
def left(n: Int): Position = Position(0, 1, 3 + (8 * n))
def right(width: Int)(n: Int): Position = Position(6 + (8 * (width - 1)), 1, 3 + (8 * n))
val top1: Int => Position = top(1)
val top2: Int => Position = top(2)
val top3: Int => Position = top(3)
val top4: Int => Position = top(4)
val right2: Int => Position = right(2)
}

View File

@ -1,3 +0,0 @@
package tf.bug.fancadegraph
case class Template[T](definition: BlockDefinition[T], args: T)(implicit val ev: Argument[T])

View File

@ -1 +1 @@
sbt.version = 1.3.9
sbt.version=1.5.1

View File

@ -1,3 +1 @@
addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.13")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.10")
addSbtPlugin("org.jmotor.sbt" % "sbt-dependency-updates" % "1.2.2")

View File

@ -1,13 +0,0 @@
package tf.bug.fancadescodec
case class Position(
lr: Int,
du: Int,
nf: Int
)
case class Boundary(
sizeLR: Int,
sizeDU: Int,
sizeNF: Int
)

View File

@ -1,8 +0,0 @@
package tf.bug.fancadescodec
case class Cartridge(
title: String,
author: String,
description: String,
entries: Vector[Entry]
)

View File

@ -1,159 +0,0 @@
package tf.bug.fancadescodec
import scodec._
import scodec.bits.{BitVector, ByteVector}
import scodec.codecs._
object Codecs {
lazy val low: Codec[Unit] = constant(BitVector.low(1L))
lazy val high: Codec[Unit] = constant(BitVector.high(1L))
def optionC[A](b: Boolean, c: Codec[A]): Codec[Option[A]] =
optional(provide(b), c)
lazy val fancadeString: Codec[String] = variableSizeBytes(uint8L, utf8)
lazy val cartridgeMagic: Codec[Unit] = constant(ByteVector(0x1B, 0x00))
lazy val entriesMagic: Codec[Unit] = constant(ByteVector(0x2C, 0x02))
lazy val cartridge: Codec[Cartridge] =
(
cartridgeMagic ~>
fancadeString ::
fancadeString ::
fancadeString ::
(entriesMagic ~> vectorOfN(uint16L, entry)).hlist
).as[Cartridge]
lazy val boundary: Codec[Boundary] =
(uint16L :: uint16L :: uint16L).as[Boundary]
lazy val position: Codec[Position] =
(uint16L :: uint16L :: uint16L).as[Position]
lazy val face: Codec[Vector[Int]] = fixedSizeBytes(8L * 8L * 8L, vector(uint8L))
lazy val faces: Codec[Faces] =
(face :: face :: face :: face :: face :: face).as[Faces]
lazy val obj: Codec[Obj] = uint16L.xmap(Obj(_), _.id)
lazy val world: Codec[World] = boundary.flatPrepend { b =>
vectorOfN(provide(b.sizeLR * b.sizeDU * b.sizeNF), obj).hlist
}.as[World]
lazy val wires: Codec[Vector[Wire]] = vectorOfN(uint16L, wire)
lazy val wire: Codec[Wire] =
(position :: position :: position :: position.hlist).as[Wire]
lazy val metadatas: Codec[Vector[Metadata]] = vectorOfN(uint16L, metadata)
lazy val metadata: Codec[Metadata] =
discriminated[Metadata].by(uint16L)
.subcaseP(0x0100) {
case bool: Metadata.Bool => bool
} (metadataBool)
.subcaseP(0x0201) {
case pss: Metadata.PlaySoundSample => pss
} (metadataPlaySoundSample)
.subcaseP(0x0400) {
case num: Metadata.Number => num
} (metadataNumber)
.subcaseP(0x0500) {
case triple: Metadata.Triple => triple
} (metadataTriple)
.subcaseP(0x0600) {
case text: Metadata.Text => text
} (metadataText)
.subcaseP(0x0700) {
case terminal: Metadata.Terminal => terminal
} (metadataTerminal)
lazy val metadataBool: Codec[Metadata.Bool] =
(position :: bool(8).hlist).as[Metadata.Bool]
lazy val metadataPlaySoundSample: Codec[Metadata.PlaySoundSample] =
(position :: sample.hlist).as[Metadata.PlaySoundSample]
lazy val metadataNumber: Codec[Metadata.Number] =
(position :: floatL.hlist).as[Metadata.Number]
lazy val metadataTriple: Codec[Metadata.Triple] =
(position :: floatL :: floatL :: floatL.hlist).as[Metadata.Triple]
lazy val metadataText: Codec[Metadata.Text] =
(position :: fancadeString.hlist).as[Metadata.Text]
lazy val metadataTerminal: Codec[Metadata.Terminal] =
(position :: fancadeString.hlist).as[Metadata.Terminal]
lazy val sample: Codec[Metadata.Sample] =
discriminated[Metadata.Sample].by(uint16L)
.subcaseP(0) {
case chirp @ Metadata.Sample.Chirp => chirp
} (provide(Metadata.Sample.Chirp))
.subcaseP(1) {
case scrape @ Metadata.Sample.Scrape => scrape
} (provide(Metadata.Sample.Scrape))
.subcaseP(2) {
case squeek @ Metadata.Sample.Squeek => squeek
} (provide(Metadata.Sample.Squeek))
.subcaseP(3) {
case engine @ Metadata.Sample.Engine => engine
} (provide(Metadata.Sample.Engine))
.subcaseP(4) {
case button @ Metadata.Sample.Button => button
} (provide(Metadata.Sample.Button))
.subcaseP(5) {
case ball @ Metadata.Sample.Ball => ball
} (provide(Metadata.Sample.Ball))
.subcaseP(6) {
case piano @ Metadata.Sample.Piano => piano
} (provide(Metadata.Sample.Piano))
.subcaseP(7) {
case marimba @ Metadata.Sample.Marimba => marimba
} (provide(Metadata.Sample.Marimba))
.subcaseP(8) {
case pad @ Metadata.Sample.Pad => pad
} (provide(Metadata.Sample.Pad))
.subcaseP(9) {
case beep @ Metadata.Sample.Beep => beep
} (provide(Metadata.Sample.Beep))
.subcaseP(10) {
case plop @ Metadata.Sample.Plop => plop
} (provide(Metadata.Sample.Plop))
.subcaseP(11) {
case flop @ Metadata.Sample.Flop => flop
} (provide(Metadata.Sample.Flop))
.subcaseP(12) {
case splash @ Metadata.Sample.Splash => splash
} (provide(Metadata.Sample.Splash))
.subcaseP(13) {
case boom @ Metadata.Sample.Boom => boom
} (provide(Metadata.Sample.Boom))
.subcaseP(14) {
case hit @ Metadata.Sample.Hit => hit
} (provide(Metadata.Sample.Hit))
.subcaseP(15) {
case clang @ Metadata.Sample.Clang => clang
} (provide(Metadata.Sample.Clang))
.subcaseP(16) {
case jump @ Metadata.Sample.Jump => jump
} (provide(Metadata.Sample.Jump))
lazy val entry: Codec[Entry] =
( low ~ low ~ low ~ low ~
bool ~ bool ~ bool ~ bool ~
low ~ low ~ low ~ bool ~
high ~ low ~ low ~ low).consume {
case (_ ~ _ ~ _ ~ _ ~ isFaces ~ isWorld ~ isMetadata ~ isWires ~ _ ~ _ ~ _ ~ isVisible ~ _ ~ _ ~ _ ~ _) =>
(
optionC(isVisible, uint8L) ::
fancadeString ::
optionC(isFaces, faces) ::
optionC(isWorld, world) ::
optionC(isMetadata, metadatas) ::
optionC(isWires, wires).hlist
).as[Entry]
} {
case Entry(vFlags, _, f, wd, mt, wr) =>
(() ~ () ~ () ~ () ~ f.isDefined ~ wd.isDefined ~ mt.isDefined ~ wr.isDefined ~ () ~ () ~ () ~ vFlags.isDefined ~ () ~ () ~ () ~ ())
}
lazy val encCartridge: Codec[Cartridge] = zlib(cartridge)
}

View File

@ -1,10 +0,0 @@
package tf.bug.fancadescodec
case class Entry(
visibilityFlags: Option[Int],
name: String,
faces: Option[Faces],
world: Option[World],
metadatas: Option[Vector[Metadata]],
wires: Option[Vector[Wire]]
)

View File

@ -1,10 +0,0 @@
package tf.bug.fancadescodec
case class Faces(
faceRight: Vector[Int],
faceLeft: Vector[Int],
faceUp: Vector[Int],
faceDown: Vector[Int],
faceFar: Vector[Int],
faceNear: Vector[Int]
)

View File

@ -1,125 +0,0 @@
package tf.bug.fancadescodec
import cats.effect._
import cats.implicits._
import fs2._
import java.nio.file.Paths
import scodec.stream.{StreamDecoder, StreamEncoder}
object Main extends IOApp {
override def run(args: List[String]): IO[ExitCode] = {
(Stream.resource(Blocker[IO]) >>= read[IO]).compile.drain.as(ExitCode.Success)
}
def read[F[_] : RaiseThrowable : Sync : ContextShift](blocker: Blocker): Stream[F, Unit] = {
val input = Paths.get("""C:\Users\aprim\Documents\FancadeLevels\TaglessTest""")
io.file.readAll[F](input, blocker, 1024)
.through(StreamDecoder.once(Codecs.encCartridge).toPipeByte)
.evalMap(c => Sync[F].delay(println(c)))
}
def write[F[_] : RaiseThrowable : Sync : ContextShift](blocker: Blocker): Stream[F, Unit] = {
val output = Paths.get("""C:\Users\aprim\Documents\FancadeLevels\AllTheSamples""")
val outputCartridge = Cartridge(
"AllTheSamples",
"rayc",
"A Fancade game",
Vector(
Entry(
Some(0x03),
"New Level",
None,
Some(
World(
Boundary(2, 17, 2),
Vector.fill(17)(Vector(Obj.playSound0, Obj.playSound1)).flatten ++ Vector.fill(17)(Vector(Obj.playSound2, Obj.playSound3)).flatten
)
),
Some(
(0 until 17).map { case h =>
Metadata.PlaySoundSample(
Position(0, h, 0),
h match {
case 0 => Metadata.Sample.Chirp
case 1 => Metadata.Sample.Scrape
case 2 => Metadata.Sample.Squeek
case 3 => Metadata.Sample.Engine
case 4 => Metadata.Sample.Button
case 5 => Metadata.Sample.Ball
case 6 => Metadata.Sample.Piano
case 7 => Metadata.Sample.Marimba
case 8 => Metadata.Sample.Pad
case 9 => Metadata.Sample.Beep
case 10 => Metadata.Sample.Plop
case 11 => Metadata.Sample.Flop
case 12 => Metadata.Sample.Splash
case 13 => Metadata.Sample.Boom
case 14 => Metadata.Sample.Hit
case 15 => Metadata.Sample.Clang
case 16 => Metadata.Sample.Jump
}
)
}.toVector
),
None
)
)
)
Stream.emit[F, Cartridge](outputCartridge)
.through(StreamEncoder.once(Codecs.encCartridge).toPipeByte)
.through(io.file.writeAll[F](output, blocker))
}
val paletteMap: ((Int, Int, Int)) => String = Map(
(238, 165, 162) -> "Brown 1",
(255, 255, 255) -> "Tan 1",
(192, 152, 255) -> "Purple 1",
(255, 203, 252) -> "Pink 1",
(255, 170, 170) -> "Red 1",
(255, 185, 142) -> "Orange 1",
(255, 255, 134) -> "Yellow 1",
(194, 255, 118) -> "Green 1",
(0, 205, 255) -> "Blue 1",
(255, 255, 255) -> "White 1",
(109, 111, 126) -> "Black 1",
(203, 117, 137) -> "Brown 2",
(255, 231, 207) -> "Tan 2",
(153, 122, 234) -> "Purple 2",
(255, 164, 224) -> "Pink 2",
(255, 81, 115) -> "Red 2",
(255, 123, 91) -> "Orange 2",
(255, 234, 0) -> "Yellow 2",
(72, 208, 85) -> "Green 2",
(0, 154, 255) -> "Blue 2",
(206, 208, 216) -> "White 2",
(68, 68, 83) -> "Black 2",
(156, 90, 100) -> "Brown 3",
(255, 195, 180) -> "Tan 3",
(113, 91, 173) -> "Purple 3",
(255, 123, 186) -> "Pink 3",
(205, 59, 86) -> "Red 3",
(215, 89, 71) -> "Orange 3",
(246, 185, 0) -> "Yellow 3",
(0, 147, 82) -> "Green 3",
(0, 117, 237) -> "Blue 3",
(156, 158, 173) -> "White 3",
(31, 31, 41) -> "Black 3",
).withDefaultValue("Transparent")
val indexMap: String => Int = List(
"Black",
"White",
"Brown",
"Tan",
"Red",
"Orange",
"Yellow",
"Green",
"Blue",
"Purple",
"Pink"
).flatMap(n => List(s"$n 3", s"$n 2", s"$n 1")).zipWithIndex.map { case (n, i) => (n, i + 1) }.toMap.withDefaultValue(0)
}

View File

@ -1,60 +0,0 @@
package tf.bug.fancadescodec
sealed trait Metadata
object Metadata {
case class Bool(
block: Position,
doLoop: Boolean
) extends Metadata
case class PlaySoundSample(
block: Position,
sample: Sample
) extends Metadata
sealed trait Sample
object Sample {
case object Chirp extends Sample
case object Scrape extends Sample
case object Squeek extends Sample
case object Engine extends Sample
case object Button extends Sample
case object Ball extends Sample
case object Piano extends Sample
case object Marimba extends Sample
case object Pad extends Sample
case object Beep extends Sample
case object Plop extends Sample
case object Flop extends Sample
case object Splash extends Sample
case object Boom extends Sample
case object Hit extends Sample
case object Clang extends Sample
case object Jump extends Sample
}
case class Number(
block: Position,
value: Float
) extends Metadata
case class Text(
block: Position,
name: String
) extends Metadata
case class Triple(
block: Position,
x: Float,
y: Float,
z: Float
) extends Metadata
case class Terminal(
voxel: Position,
name: String
) extends Metadata
}

View File

@ -1,651 +0,0 @@
package tf.bug.fancadescodec
case class Obj(
id: Int
) extends AnyVal
object Obj {
final val empty = Obj(0)
final val bricks = Obj(2)
final val grass = Obj(3)
final val grassDotty = Obj(4)
final val dirt = Obj(5)
final val dirtDotty = Obj(493)
final val dirtSlab = Obj(384)
final val foliageSlab = Obj(499)
final val foliageDotty = Obj(496)
final val foliageTop = Obj(497)
final val foliage = Obj(495)
final val foliageBottom = Obj(498)
final val stone = Obj(501)
final val stoneDotty = Obj(502)
final val stoneSlab = Obj(505)
final val stoneTop = Obj(503)
final val stoneBottom = Obj(504)
final val stoneBlock = Obj(1)
final val stonePillar = Obj(506)
final val stoneHalf = Obj(507)
final val slate = Obj(547)
final val slateDotty = Obj(548)
final val slateNE = Obj(549)
final val slateNW = Obj(550)
final val slateSE = Obj(551)
final val slateSW = Obj(552)
final val slateTop = Obj(553)
final val slateBottom = Obj(554)
final val woodLR = Obj(6)
final val woodDU = Obj(8)
final val woodNF = Obj(7)
final val woodLowLR = Obj(508)
final val woodLowNF = Obj(509)
final val woodHighLR = Obj(510)
final val woodHighNF = Obj(511)
final val steel = Obj(385)
final val box = Obj(388)
final val sphere = Obj(546)
final val physicsBox = Obj(425)
final val physicsSphere = Obj(426)
final val passThrough = Obj(448)
final val scriptBlock = Obj(545)
final val flowers = Obj(494)
final val particle = Obj(555)
final val marker = Obj(536)
final val shrub = Obj(500)
final val archLower = Obj(386)
final val archHigher = Obj(387)
final val stickLR = Obj(512)
final val stickDU = Obj(513)
final val stickNF = Obj(514)
final val stickRF = Obj(515)
final val stickLF = Obj(516)
final val stickLN = Obj(517)
final val stickRN = Obj(518)
final val stickRU = Obj(519)
final val stickUF = Obj(520)
final val stickLU = Obj(521)
final val stickUN = Obj(522)
final val stickRD = Obj(523)
final val stickDF = Obj(524)
final val stickLD = Obj(525)
final val stickDN = Obj(526)
final val win0 = Obj(252)
final val win1 = Obj(253)
final val win2 = Obj(254)
final val win3 = Obj(255)
final val lose0 = Obj(256)
final val lose1 = Obj(257)
final val lose2 = Obj(258)
final val lose3 = Obj(259)
final val setScore0 = Obj(260)
final val setScore1 = Obj(261)
final val setScore2 = Obj(262)
final val setScore3 = Obj(263)
final val setCamera0 = Obj(268)
final val setCamera1 = Obj(269)
final val setCamera2 = Obj(270)
final val setCamera3 = Obj(271)
final val setCamera4 = Obj(272)
final val setCamera5 = Obj(273)
final val setLight0 = Obj(274)
final val setLight1 = Obj(275)
final val setLight2 = Obj(276)
final val setLight3 = Obj(277)
final val screenSize0 = Obj(220)
final val screenSize1 = Obj(221)
final val screenSize2 = Obj(222)
final val screenSize3 = Obj(223)
final val accelerometer0 = Obj(224)
final val accelerometer1 = Obj(225)
final val accelerometer2 = Obj(226)
final val accelerometer3 = Obj(227)
final val getPosition0 = Obj(278)
final val getPosition1 = Obj(279)
final val getPosition2 = Obj(280)
final val getPosition3 = Obj(281)
final val setPosition0 = Obj(282)
final val setPosition1 = Obj(283)
final val setPosition2 = Obj(284)
final val setPosition3 = Obj(285)
final val setPosition4 = Obj(286)
final val setPosition5 = Obj(287)
final val raycast0 = Obj(228)
final val raycast1 = Obj(229)
final val raycast2 = Obj(230)
final val raycast3 = Obj(231)
final val raycast4 = Obj(232)
final val raycast5 = Obj(233)
final val getSize0 = Obj(489)
final val getSize1 = Obj(490)
final val getSize2 = Obj(491)
final val getSize3 = Obj(492)
final val setVisible0 = Obj(306)
final val setVisible1 = Obj(307)
final val setVisible2 = Obj(308)
final val setVisible3 = Obj(309)
final val createObject0 = Obj(316)
final val createObject1 = Obj(317)
final val createObject2 = Obj(318)
final val createObject3 = Obj(319)
final val destroyObject0 = Obj(320)
final val destroyObject1 = Obj(321)
final val destroyObject2 = Obj(322)
final val destroyObject3 = Obj(323)
final val playSound0 = Obj(264)
final val playSound1 = Obj(265)
final val playSound2 = Obj(266)
final val playSound3 = Obj(267)
final val stopSound0 = Obj(397)
final val stopSound1 = Obj(398)
final val stopSound2 = Obj(399)
final val stopSound3 = Obj(400)
final val volumePitch0 = Obj(391)
final val volumePitch1 = Obj(392)
final val volumePitch2 = Obj(393)
final val volumePitch3 = Obj(394)
final val volumePitch4 = Obj(395)
final val volumePitch5 = Obj(396)
final val addForce0 = Obj(298)
final val addForce1 = Obj(299)
final val addForce2 = Obj(300)
final val addForce3 = Obj(301)
final val addForce4 = Obj(302)
final val addForce5 = Obj(303)
final val addForce6 = Obj(304)
final val addForce7 = Obj(305)
final val getVelocity0 = Obj(288)
final val getVelocity1 = Obj(289)
final val getVelocity2 = Obj(290)
final val getVelocity3 = Obj(291)
final val setVelocity0 = Obj(292)
final val setVelocity1 = Obj(293)
final val setVelocity2 = Obj(294)
final val setVelocity3 = Obj(295)
final val setVelocity4 = Obj(296)
final val setVelocity5 = Obj(297)
final val setLocked0 = Obj(310)
final val setLocked1 = Obj(311)
final val setLocked2 = Obj(312)
final val setLocked3 = Obj(313)
final val setLocked4 = Obj(314)
final val setLocked5 = Obj(315)
final val setMass0 = Obj(328)
final val setMass1 = Obj(329)
final val setMass2 = Obj(330)
final val setMass3 = Obj(331)
final val setFriction0 = Obj(332)
final val setFriction1 = Obj(333)
final val setFriction2 = Obj(334)
final val setFriction3 = Obj(335)
final val setBounciness0 = Obj(336)
final val setBounciness1 = Obj(337)
final val setBounciness2 = Obj(338)
final val setBounciness3 = Obj(339)
final val setGravity0 = Obj(324)
final val setGravity1 = Obj(325)
final val setGravity2 = Obj(326)
final val setGravity3 = Obj(327)
final val addConstraint0 = Obj(340)
final val addConstraint1 = Obj(341)
final val addConstraint2 = Obj(342)
final val addConstraint3 = Obj(343)
final val addConstraint4 = Obj(344)
final val addConstraint5 = Obj(345)
final val linearLimits0 = Obj(346)
final val linearLimits1 = Obj(347)
final val linearLimits2 = Obj(348)
final val linearLimits3 = Obj(349)
final val linearLimits4 = Obj(350)
final val linearLimits5 = Obj(351)
final val angularLimits0 = Obj(352)
final val angularLimits1 = Obj(353)
final val angularLimits2 = Obj(354)
final val angularLimits3 = Obj(355)
final val angularLimits4 = Obj(356)
final val angularLimits5 = Obj(357)
final val linearSpring0 = Obj(358)
final val linearSpring1 = Obj(359)
final val linearSpring2 = Obj(360)
final val linearSpring3 = Obj(361)
final val linearSpring4 = Obj(362)
final val linearSpring5 = Obj(363)
final val angularSpring0 = Obj(364)
final val angularSpring1 = Obj(365)
final val angularSpring2 = Obj(366)
final val angularSpring3 = Obj(367)
final val angularSpring4 = Obj(368)
final val angularSpring5 = Obj(369)
final val linearMotor0 = Obj(370)
final val linearMotor1 = Obj(371)
final val linearMotor2 = Obj(372)
final val linearMotor3 = Obj(373)
final val linearMotor4 = Obj(374)
final val linearMotor5 = Obj(375)
final val angularMotor0 = Obj(376)
final val angularMotor1 = Obj(377)
final val angularMotor2 = Obj(378)
final val angularMotor3 = Obj(379)
final val angularMotor4 = Obj(380)
final val angularMotor5 = Obj(381)
final val if0 = Obj(234)
final val if1 = Obj(235)
final val if2 = Obj(236)
final val if3 = Obj(237)
final val playSensor0 = Obj(238)
final val playSensor1 = Obj(239)
final val playSensor2 = Obj(240)
final val playSensor3 = Obj(241)
final val boxArtSensor0 = Obj(409)
final val boxArtSensor1 = Obj(410)
final val boxArtSensor2 = Obj(411)
final val boxArtSensor3 = Obj(412)
final val touchSensor0 = Obj(242)
final val touchSensor1 = Obj(243)
final val touchSensor2 = Obj(244)
final val touchSensor3 = Obj(245)
final val touchSensor4 = Obj(246)
final val touchSensor5 = Obj(247)
final val swipeSensor0 = Obj(248)
final val swipeSensor1 = Obj(249)
final val swipeSensor2 = Obj(250)
final val swipeSensor3 = Obj(251)
final val collision0 = Obj(401)
final val collision1 = Obj(402)
final val collision2 = Obj(403)
final val collision3 = Obj(404)
final val collision4 = Obj(405)
final val collision5 = Obj(406)
final val negate0 = Obj(90)
final val negate1 = Obj(91)
final val inverse0 = Obj(440)
final val inverse1 = Obj(441)
final val addNumbers0 = Obj(92)
final val addNumbers1 = Obj(93)
final val addNumbers2 = Obj(94)
final val addNumbers3 = Obj(95)
final val addVectors0 = Obj(96)
final val addVectors1 = Obj(97)
final val addVectors2 = Obj(98)
final val addVectors3 = Obj(99)
final val subtractNumbers0 = Obj(100)
final val subtractNumbers1 = Obj(101)
final val subtractNumbers2 = Obj(102)
final val subtractNumbers3 = Obj(103)
final val subtractVectors0 = Obj(104)
final val subtractVectors1 = Obj(105)
final val subrtactVectors2 = Obj(106)
final val subtractVectors3 = Obj(107)
final val multiply0 = Obj(108)
final val multiply1 = Obj(109)
final val multiply2 = Obj(110)
final val multiply3 = Obj(111)
final val scale0 = Obj(112)
final val scale1 = Obj(113)
final val scale2 = Obj(114)
final val scale3 = Obj(115)
final val rotate0 = Obj(116)
final val rotate1 = Obj(117)
final val rotate2 = Obj(118)
final val rotate3 = Obj(119)
final val combine0 = Obj(120)
final val combine1 = Obj(121)
final val combine2 = Obj(122)
final val combine3 = Obj(123)
final val divide0 = Obj(124)
final val divide1 = Obj(125)
final val divide2 = Obj(126)
final val divide3 = Obj(127)
final val power0 = Obj(457)
final val power1 = Obj(458)
final val power2 = Obj(459)
final val power3 = Obj(460)
final val equalNumbers0 = Obj(132)
final val equalNumbers1 = Obj(133)
final val equalNumbers2 = Obj(134)
final val equalNumbers3 = Obj(135)
final val equalVectors0 = Obj(136)
final val equalVectors1 = Obj(137)
final val equalVectors2 = Obj(138)
final val equalVectors3 = Obj(139)
final val equalObjects0 = Obj(140)
final val equalObjects1 = Obj(141)
final val equalObjects2 = Obj(142)
final val equalObjects3 = Obj(143)
final val equalTruths0 = Obj(421)
final val equalTruths1 = Obj(422)
final val equalTruths2 = Obj(423)
final val equalTruths3 = Obj(424)
final val lessThan0 = Obj(128)
final val lessThan1 = Obj(129)
final val lessThan2 = Obj(130)
final val lessThan3 = Obj(131)
final val greaterThan0 = Obj(481)
final val greaterThan1 = Obj(482)
final val greaterThan2 = Obj(483)
final val greaterThan3 = Obj(484)
final val and0 = Obj(146)
final val and1 = Obj(147)
final val and2 = Obj(148)
final val and3 = Obj(149)
final val or0 = Obj(417)
final val or1 = Obj(418)
final val or2 = Obj(419)
final val or3 = Obj(420)
final val not0 = Obj(144)
final val not1 = Obj(145)
final val random0 = Obj(168)
final val random1 = Obj(169)
final val random2 = Obj(170)
final val random3 = Obj(171)
final val randomSeed0 = Obj(485)
final val randomSeed1 = Obj(486)
final val randomSeed2 = Obj(487)
final val randomSeed3 = Obj(488)
final val min0 = Obj(176)
final val min1 = Obj(177)
final val min2 = Obj(178)
final val min3 = Obj(179)
final val max0 = Obj(180)
final val max1 = Obj(181)
final val max2 = Obj(182)
final val max3 = Obj(183)
final val sin0 = Obj(413)
final val sin1 = Obj(414)
final val cos0 = Obj(453)
final val cos1 = Obj(454)
final val round0 = Obj(184)
final val round1 = Obj(185)
final val floor0 = Obj(186)
final val floor1 = Obj(187)
final val ceiling0 = Obj(188)
final val ceiling1 = Obj(189)
final val absolute0 = Obj(455)
final val absolute1 = Obj(456)
final val modulo0 = Obj(172)
final val modulo1 = Obj(173)
final val modulo2 = Obj(174)
final val modulo3 = Obj(175)
final val breakVector0 = Obj(156)
final val breakVector1 = Obj(157)
final val breakVector2 = Obj(158)
final val breakVector3 = Obj(159)
final val breakVector4 = Obj(160)
final val breakVector5 = Obj(161)
final val makeVector0 = Obj(150)
final val makeVector1 = Obj(151)
final val makeVector2 = Obj(152)
final val makeVector3 = Obj(153)
final val makeVector4 = Obj(154)
final val makeVector5 = Obj(155)
final val breakRotation0 = Obj(442)
final val breakRotation1 = Obj(443)
final val breakRotation2 = Obj(444)
final val breakRotation3 = Obj(445)
final val breakRotation4 = Obj(446)
final val breakRotation5 = Obj(447)
final val makeRotation0 = Obj(162)
final val makeRotation1 = Obj(163)
final val makeRotation2 = Obj(164)
final val makeRotation3 = Obj(165)
final val makeRotation4 = Obj(166)
final val makeRotation5 = Obj(167)
final val distance0 = Obj(190)
final val distance1 = Obj(191)
final val distance2 = Obj(192)
final val distance3 = Obj(193)
final val lerp0 = Obj(194)
final val lerp1 = Obj(195)
final val lerp2 = Obj(196)
final val lerp3 = Obj(197)
final val lerp4 = Obj(198)
final val lerp5 = Obj(199)
final val axisAngle0 = Obj(200)
final val axisAngle1 = Obj(201)
final val axisAngle2 = Obj(202)
final val axisAngle3 = Obj(203)
final val screenToWorld0 = Obj(216)
final val screenToWorld1 = Obj(217)
final val screenToWorld2 = Obj(218)
final val screenToWorld3 = Obj(219)
final val worldToScreen0 = Obj(477)
final val worldToScreen1 = Obj(478)
final val worldToScreen2 = Obj(479)
final val worldToScreen3 = Obj(480)
final val lineVsPlane0 = Obj(208)
final val lineVsPlane1 = Obj(209)
final val lineVsPlane2 = Obj(210)
final val lineVsPlane3 = Obj(211)
final val lineVsPlane4 = Obj(212)
final val lineVsPlane5 = Obj(213)
final val lineVsPlane6 = Obj(214)
final val lineVsPlane7 = Obj(215)
final val lookRotation0 = Obj(204)
final val lookRotation1 = Obj(205)
final val lookRotation2 = Obj(206)
final val lookRotation3 = Obj(207)
final val number0 = Obj(36)
final val number1 = Obj(37)
final val vector0 = Obj(38)
final val vector1 = Obj(39)
final val vector2 = Obj(40)
final val vector3 = Obj(41)
final val rotation0 = Obj(42)
final val rotation1 = Obj(43)
final val rotation2 = Obj(44)
final val rotation3 = Obj(45)
final val true0 = Obj(449)
final val true1 = Obj(450)
final val false0 = Obj(451)
final val false1 = Obj(452)
final val comment = Obj(15)
final val inspectNumber0 = Obj(16)
final val inspectNumber1 = Obj(17)
final val inspectNumber2 = Obj(18)
final val inspectNumber3 = Obj(19)
final val inspectVector0 = Obj(20)
final val inspectVector1 = Obj(21)
final val inspectVector2 = Obj(22)
final val inspectVector3 = Obj(23)
final val inspectRotation0 = Obj(24)
final val inspectRotation1 = Obj(25)
final val inspectRotation2 = Obj(26)
final val inspectRotation3 = Obj(27)
final val inspectTruth0 = Obj(28)
final val inspectTruth1 = Obj(29)
final val inspectTruth2 = Obj(30)
final val inspectTruth3 = Obj(31)
final val inspectObject0 = Obj(32)
final val inspectObject1 = Obj(33)
final val inspectObject2 = Obj(34)
final val inspectObject3 = Obj(35)
final val getNumber0 = Obj(46)
final val getNumber1 = Obj(47)
final val getObject0 = Obj(54)
final val getObject1 = Obj(55)
final val getVector0 = Obj(48)
final val getVector1 = Obj(49)
final val getRotation0 = Obj(50)
final val getRotation1 = Obj(51)
final val getTruth0 = Obj(52)
final val getTruth1 = Obj(53)
final val getConstraint0 = Obj(56)
final val getConstraint1 = Obj(57)
final val setNumber0 = Obj(428)
final val setNumber1 = Obj(429)
final val setObject0 = Obj(436)
final val setObject1 = Obj(437)
final val setVector0 = Obj(430)
final val setVector1 = Obj(431)
final val setRotation0 = Obj(432)
final val setRotation1 = Obj(433)
final val setTruth0 = Obj(434)
final val setTruth1 = Obj(435)
final val setConstraint0 = Obj(438)
final val setConstraint1 = Obj(439)
final val setNumberReference0 = Obj(58)
final val setNumberReference1 = Obj(59)
final val setNumberReference2 = Obj(60)
final val setNumberReference3 = Obj(61)
final val setObjectReference0 = Obj(74)
final val setObjectReference1 = Obj(75)
final val setObjectReference2 = Obj(76)
final val setObjectReference3 = Obj(77)
final val setVectorReference0 = Obj(62)
final val setVectorReference1 = Obj(63)
final val setVectorReference2 = Obj(64)
final val setVectorReference3 = Obj(65)
final val setRotationReference0 = Obj(66)
final val setRotationReference1 = Obj(67)
final val setRotationReference2 = Obj(68)
final val setRotationReference3 = Obj(69)
final val setTruthReference0 = Obj(70)
final val setTruthReference1 = Obj(71)
final val setTruthReference2 = Obj(72)
final val setTruthReference3 = Obj(73)
final val setConstraintReference0 = Obj(78)
final val setConstraintReference1 = Obj(79)
final val setConstraintReference2 = Obj(80)
final val setConstraintReference3 = Obj(81)
final val listNumber0 = Obj(82)
final val listNumber1 = Obj(83)
final val listNumber2 = Obj(84)
final val listNumber3 = Obj(85)
final val listObject0 = Obj(86)
final val listObject1 = Obj(87)
final val listObject2 = Obj(88)
final val listObject3 = Obj(89)
final val listVector0 = Obj(461)
final val listVector1 = Obj(462)
final val listVector2 = Obj(463)
final val listVector3 = Obj(464)
final val listRotation0 = Obj(465)
final val listRotation1 = Obj(466)
final val listRotation2 = Obj(467)
final val listRotation3 = Obj(468)
final val listTruth0 = Obj(469)
final val listTruth1 = Obj(470)
final val listTruth2 = Obj(471)
final val listTruth3 = Obj(472)
final val listConstraint0 = Obj(473)
final val listConstraint1 = Obj(474)
final val listConstraint2 = Obj(475)
final val listConstraint3 = Obj(476)
}

View File

@ -1,8 +0,0 @@
package tf.bug.fancadescodec
case class Wire(
startNearLeftBottom: Position,
endNearLeftBottom: Position,
startVoxel: Position,
endVoxel: Position
)

View File

@ -1,6 +0,0 @@
package tf.bug.fancadescodec
case class World(
boundary: Boundary,
objs: Vector[Obj]
)

View File

@ -1,3 +0,0 @@
package tf.bug.fancadetagless
case class Constraint()

View File

@ -1,135 +0,0 @@
package tf.bug.fancadetagless
import cats._
import cats.implicits._
import higherkindness.droste.data._
import polymorphic._
import tf.bug.fancadegraph.Level
import tf.bug.fancadegraph.PinDefinition
import tf.bug.fancadegraph.Template
import tf.bug.fancadegraph.Block
import tf.bug.fancadescodec.Position
import scalax.collection.Graph
import scalax.collection.GraphEdge.DiHyperEdge
import tf.bug.fancadegraph.Pin
sealed trait FancadeF[A]
object FancadeF {
case class Create[A](from: Vector[A], template: Exists[Template], imports: Vector[PinDefinition], exports: Vector[PinDefinition]) extends FancadeF[A]
case class Select[A](from: A, indicies: Vector[Int]) extends FancadeF[A]
case class Combine[A](from: Vector[A]) extends FancadeF[A]
case class Sequence[A](first: A, afterPin: PinDefinition, next: A) extends FancadeF[A]
case class Noop[A]() extends FancadeF[A]
implicit val fancadeTraverse: Traverse[FancadeF] = new Traverse[FancadeF] {
override def traverse[G[_]: Applicative, A, B](fa: FancadeF[A])(f: A => G[B]): G[FancadeF[B]] =
fa match {
case Create(v, t, i, e) => v.traverse(f).map(w => Create(w, t, i, e))
case Select(a, i) => f(a).map(b => Select(b, i))
case Combine(v) => v.traverse(f).map(w => Combine(w))
case Sequence(i, p, n) => (f(i), f(n)).mapN((j, o) => Sequence(j, p, o))
case Noop() => Noop[B]().pure[G].widen
}
override def foldLeft[A, B](fa: FancadeF[A], b: B)(f: (B, A) => B): B =
fa match {
case Create(v, _, _, _) => v.foldLeft(b)(f)
case Select(a, _) => f(b, a)
case Combine(v) => v.foldLeft(b)(f)
case Sequence(i, _, n) => f(f(b, i), n)
case Noop() => b
}
override def foldRight[A, B](fa: FancadeF[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
fa match {
case Create(v, _, _, _) => v.foldr(lb)(f)
case Select(a, _) => f(a, lb)
case Combine(v) => v.foldr(lb)(f)
case Sequence(i, _, n) => f(i, f(n, lb))
case Noop() => lb
}
}
def origins(root: Int, stack: Vector[FancadeF[Int]]): Vector[(Int, PinDefinition)] = {
stack(root) match {
case Create(_, _, _, pins) =>
pins.map((root, _))
case Select(f, i) =>
val original = origins(f, stack)
i.map(original(_))
case Combine(f) =>
f.flatMap(origins(_, stack))
case Sequence(f, _, _) =>
origins(f, stack)
case Noop() =>
Vector.empty
}
}
def filteredIndex[A](vec: Vector[A], f: A => Boolean): Vector[(A, Int)] = {
vec.zipWithIndex.filter { case (e, _) => f(e) }
}
def render(f: Fix[FancadeF]): Level = {
val pc: PointerChain[Id, FancadeF] = PointerChain.deduplicate[Id, FancadeF](f)
val pcv: Vector[FancadeF[Int]] = pc.vertices
val bdVector: Vector[Exists[Template]] = pcv.collect {
case Create(_, template, _, _) => template
}
val blocks: Set[Block] = bdVector.zipWithIndex.map {
case (template, idx) =>
Block(
Position(0, idx, 0),
template
)
}.toSet
val pcf: Vector[(FancadeF[Int], Int)] = filteredIndex(pcv, (_: FancadeF[Int]) match {
case Create(_, _, _, _) => true
case _ => false
})
val pcfr: Int => Int =
idx => pcf.indexWhere { case (_, i) => i == idx }
val wires: Graph[Pin, DiHyperEdge] =
pcv.zipWithIndex.foldLeft(Graph.empty[Pin, DiHyperEdge]) {
case (graph, (entry, idx)) =>
entry match {
case Create(from, _, imports, _) =>
val thisH = pcfr(idx)
val dependencies: Vector[(Int, PinDefinition)] = from.flatMap(origins(_, pcv))
val newWires = imports.zip(dependencies).map {
case (thisPinD, (thatI, thatPinD)) =>
val thisPin = Pin(
Position(0, thisH, 0),
thisPinD
)
val thatPin = Pin(
Position(0, pcfr(thatI), 0),
thatPinD
)
DiHyperEdge(thatPin, thisPin)
}
graph ++ newWires
case Sequence(f, p, n) =>
if(pcv(n) == Noop()) graph
else {
val po = origins(f, pcv)
val to = Pin(
Position(0, pcfr(po.head._1), 0),
p
)
val fo = origins(n, pcv)
val from = Pin(
Position(0, pcfr(fo.head._1), 0),
fo.head._2
)
graph ++ Set(DiHyperEdge(from, to))
}
case _ => graph
}
}
Level(blocks, wires)
}
}

View File

@ -1,257 +0,0 @@
package tf.bug.fancadetagless
import higherkindness.droste.data._
import polymorphic._
import tf.bug.fancadetagless.Fanscript.{Position, ScreenSize}
import tf.bug.fancadescodec.Metadata.Sample
import tf.bug.fancadegraph.BlockDefinition
import tf.bug.fancadegraph.Template
trait Fanscript[F[_]] {
def unit: F[Unit]
def lift(value: Float): F[Float]
def lift(value: Vector3): F[Vector3]
def lift(value: Rotation): F[Rotation]
def lift(value: Boolean): F[Boolean]
def inspect(value: F[Float], after: () => F[Unit]): F[Unit]
def win(stop: Boolean)(after: () => F[Unit]): F[Unit]
def lose(stop: Boolean)(after: () => F[Unit]): F[Unit]
def setScore(score: F[Float], after: () => F[Unit]): F[Unit]
def setCamera(position: F[Vector3], rotation: F[Rotation], distance: F[Float], after: () => F[Unit]): F[Unit]
def setLight(position: F[Vector3], rotation: F[Rotation], after: () => F[Unit]): F[Unit]
def screenSize: F[Fanscript.ScreenSize]
def accelerometer: F[Vector3]
def getPosition(obj: F[Obj]): F[Fanscript.Position]
def setPosition(obj: F[Obj], position: F[Vector3], rotation: F[Rotation], after: () => F[Unit]): F[Unit]
def raycast(from: F[Vector3], to: F[Vector3]): F[Fanscript.Raycast]
def getSize(obj: F[Obj]): F[Fanscript.Size]
def setVisible(obj: F[Obj], visible: F[Boolean], after: () => F[Unit]): F[Unit]
def createObj(original: F[Obj], after: F[Obj] => F[Unit]): F[Unit]
def destroyObj(obj: F[Obj], after: () => F[Unit]): F[Unit]
def playSound(loop: Boolean, sound: Sample)(volume: F[Float], pitch: F[Float], after: F[Float] => F[Unit]): F[Unit]
def stopSound(channel: F[Float], after: () => F[Unit]): F[Unit]
def volumePitch(channel: F[Float], volume: F[Float], pitch: F[Float], after: () => F[Unit]): F[Unit]
def addForce(obj: F[Obj], force: F[Vector3], applyAt: F[Vector3], torque: F[Vector3], after: () => F[Unit]): F[Unit]
def getVelocity(obj: F[Obj]): F[Fanscript.Velocity]
def setVelocity(obj: F[Obj], velocity: F[Vector3], spin: F[Vector3], after: () => F[Unit]): F[Unit]
def setLocked(obj: F[Obj], position: F[Vector3], rotation: F[Vector3], after: () => F[Unit]): F[Unit]
def setMass(obj: F[Obj], mass: F[Float], after: () => F[Unit]): F[Unit]
def setFriction(obj: F[Obj], friction: F[Float]): F[Unit]
def setBounciness(obj: F[Obj], bounciness: F[Float]): F[Unit]
def setGravity(gravity: F[Vector3]): F[Unit]
def addConstraint(base: F[Obj], part: F[Obj], pivot: F[Vector3]): F[Constraint]
def linearLimits(constraint: F[Constraint], lower: F[Vector3], upper: F[Vector3]): F[Unit]
def angularLimits(constraint: F[Constraint], lower: F[Vector3], upper: F[Vector3]): F[Unit]
def linearSpring(constraint: F[Constraint], stiffness: F[Vector3], damping: F[Vector3]): F[Unit]
def angularSpring(constraint: F[Constraint], stiffness: F[Vector3], damping: F[Vector3]): F[Unit]
def linearMotor(constraint: F[Constraint], speed: F[Vector3], force: F[Vector3]): F[Unit]
def angularMotor(constraint: F[Constraint], speed: F[Vector3], force: F[Vector3]): F[Unit]
def ifElse(cond: F[Boolean])(ifTrue: F[Unit])(ifFalse: F[Unit]): F[Unit]
def onPlay(onPlay: F[Unit]): F[Unit]
def onBoxArt(onBoxArt: F[Unit]): F[Unit]
def onTouch(onTouch: F[Fanscript.Touch] => F[Unit]): F[Unit]
def addNumbers(a: F[Float], b: F[Float]): F[Float]
def numberVariable(name: String): F[Float]
def setNumber(reference: F[Float], value: F[Float], after: () => F[Unit]): F[Unit]
def screenSizeWidth(screenSize: F[ScreenSize]): F[Float]
def screenSizeHeight(screenSize: F[ScreenSize]): F[Float]
def positionPosition(position: F[Position]): F[Vector3]
def positionRotation(position: F[Position]): F[Rotation]
def raycastHit(raycast: F[Fanscript.Raycast]): F[Boolean]
def raycastPosition(raycast: F[Fanscript.Raycast]): F[Vector3]
def raycastObj(raycast: F[Fanscript.Raycast]): F[Obj]
def sizeMin(size: F[Fanscript.Size]): F[Vector3]
def sizeMax(size: F[Fanscript.Size]): F[Vector3]
def velocityVelocity(velocity: F[Fanscript.Velocity]): F[Vector3]
def velocitySpin(velocity: F[Fanscript.Velocity]): F[Vector3]
}
object Fanscript {
trait Program[R] {
def run[F[_]](implicit interp: Fanscript[F]): F[R]
}
implicit object fancade extends Fanscript[Fancade] {
override def unit: Fancade[Unit] =
Fix(FancadeF.Noop())
override def lift(value: Float): Fancade[Float] =
Fix(FancadeF.Create(
Vector(),
Exists(Template(
BlockDefinition.NumberValue,
value
)),
Vector(),
Vector(BlockDefinition.NumberValue.output)
))
override def lift(value: Vector3): Fancade[Vector3] = ???
override def lift(value: Rotation): Fancade[Rotation] = ???
override def lift(value: Boolean): Fancade[Boolean] = ???
override def inspect(value: Fancade[Float], after: () => Fancade[Unit]): Fancade[Unit] = {
val us = Fix(FancadeF.Create(
Vector(value),
Exists(Template(
BlockDefinition.InspectNumber,
()
)),
Vector(BlockDefinition.InspectNumber.value),
Vector(BlockDefinition.InspectNumber.before)
))
Fix(FancadeF.Sequence(
us,
BlockDefinition.InspectNumber.after,
after()
))
}
override def win(stop: Boolean)(after: () => Fancade[Unit]): Fancade[Unit] = ???
override def lose(stop: Boolean)(after: () => Fancade[Unit]): Fancade[Unit] = ???
override def setScore(score: Fancade[Float], after: () => Fancade[Unit]): Fancade[Unit] = ???
override def setCamera(position: Fancade[Vector3], rotation: Fancade[Rotation], distance: Fancade[Float], after: () => Fancade[Unit]): Fancade[Unit] = ???
override def setLight(position: Fancade[Vector3], rotation: Fancade[Rotation], after: () => Fancade[Unit]): Fancade[Unit] = ???
override def screenSize: Fancade[ScreenSize] =
Fix(FancadeF.Create(
Vector(),
Exists(Template(
BlockDefinition.ScreenSize,
()
)),
Vector(),
Vector(BlockDefinition.ScreenSize.screenWidth, BlockDefinition.ScreenSize.screenHeight),
))
override def accelerometer: Fancade[Vector3] = ???
override def getPosition(obj: Fancade[Obj]): Fancade[Position] =
Fix(FancadeF.Create(
Vector(obj),
Exists(Template(
BlockDefinition.GetPosition,
()
)),
Vector(BlockDefinition.GetPosition.obj),
Vector(BlockDefinition.GetPosition.position)
))
override def setPosition(obj: Fancade[Obj], position: Fancade[Vector3], rotation: Fancade[Rotation], after: () => Fancade[Unit]): Fancade[Unit] = ???
override def raycast(from: Fancade[Vector3], to: Fancade[Vector3]): Fancade[Raycast] = ???
override def getSize(obj: Fancade[Obj]): Fancade[Size] = ???
override def setVisible(obj: Fancade[Obj], visible: Fancade[Boolean], after: () => Fancade[Unit]): Fancade[Unit] = ???
override def createObj(original: Fancade[Obj], after: (Fancade[Obj]) => Fancade[Unit]): Fancade[Unit] = ???
override def destroyObj(obj: Fancade[Obj], after: () => Fancade[Unit]): Fancade[Unit] = ???
override def playSound(loop: Boolean, sound: Sample)(volume: Fancade[Float], pitch: Fancade[Float], after: Fancade[Float] => Fancade[Unit]): Fancade[Unit] = ???
override def stopSound(channel: Fancade[Float], after: () => Fancade[Unit]): Fancade[Unit] = ???
override def volumePitch(channel: Fancade[Float], volume: Fancade[Float], pitch: Fancade[Float], after: () => Fancade[Unit]): Fancade[Unit] = ???
override def addForce(obj: Fancade[Obj], force: Fancade[Vector3], applyAt: Fancade[Vector3], torque: Fancade[Vector3], after: () => Fancade[Unit]): Fancade[Unit] = ???
override def getVelocity(obj: Fancade[Obj]): Fancade[Fanscript.Velocity] = ???
override def setVelocity(obj: Fancade[Obj], velocity: Fancade[Vector3], spin: Fancade[Vector3], after: () => Fancade[Unit]): Fancade[Unit] = ???
override def setLocked(obj: Fancade[Obj], position: Fancade[Vector3], rotation: Fancade[Vector3], after: () => Fancade[Unit]): Fancade[Unit] = ???
override def setMass(obj: Fancade[Obj], mass: Fancade[Float], after: () => Fancade[Unit]): Fancade[Unit] = ???
override def setFriction(obj: Fancade[Obj], friction: Fancade[Float]): Fancade[Unit] = ???
override def setBounciness(obj: Fancade[Obj], bounciness: Fancade[Float]): Fancade[Unit] = ???
override def setGravity(gravity: Fancade[Vector3]): Fancade[Unit] = ???
override def addConstraint(base: Fancade[Obj], part: Fancade[Obj], pivot: Fancade[Vector3]): Fancade[Constraint] = ???
override def linearLimits(constraint: Fancade[Constraint], lower: Fancade[Vector3], upper: Fancade[Vector3]): Fancade[Unit] = ???
override def angularLimits(constraint: Fancade[Constraint], lower: Fancade[Vector3], upper: Fancade[Vector3]): Fancade[Unit] = ???
override def linearSpring(constraint: Fancade[Constraint], stiffness: Fancade[Vector3], damping: Fancade[Vector3]): Fancade[Unit] = ???
override def angularSpring(constraint: Fancade[Constraint], stiffness: Fancade[Vector3], damping: Fancade[Vector3]): Fancade[Unit] = ???
override def linearMotor(constraint: Fancade[Constraint], speed: Fancade[Vector3], force: Fancade[Vector3]): Fancade[Unit] = ???
override def angularMotor(constraint: Fancade[Constraint], speed: Fancade[Vector3], force: Fancade[Vector3]): Fancade[Unit] = ???
override def ifElse(cond: Fancade[Boolean])(ifTrue: Fancade[Unit])(ifFalse: Fancade[Unit]): Fancade[Unit] = ???
override def onPlay(onPlay: Fancade[Unit]): Fancade[Unit] = ???
override def onBoxArt(onBoxArt: Fancade[Unit]): Fancade[Unit] = ???
override def onTouch(onTouch: Fancade[Touch] => Fancade[Unit]): Fancade[Unit] = ???
override def addNumbers(a: Fancade[Float], b: Fancade[Float]): Fancade[Float] =
Fix(FancadeF.Create(
Vector(a, b),
Exists(Template(
BlockDefinition.AddNumbers,
()
)),
Vector(BlockDefinition.AddNumbers.input1, BlockDefinition.AddNumbers.input2),
Vector(BlockDefinition.AddNumbers.output)
))
override def screenSizeWidth(screenSize: Fancade[ScreenSize]): Fancade[Float] =
Fix(FancadeF.Select(
screenSize,
Vector(0)
))
override def screenSizeHeight(screenSize: Fancade[ScreenSize]): Fancade[Float] =
Fix(FancadeF.Select(
screenSize,
Vector(1)
))
override def numberVariable(name: String): Fancade[Float] =
Fix(FancadeF.Create(
Vector(),
Exists(Template(
BlockDefinition.GetNumber,
name
)),
Vector(),
Vector(BlockDefinition.GetNumber.output)
))
override def setNumber(reference: Fancade[Float], value: Fancade[Float], after: () => Fancade[Unit]): Fancade[Unit] = {
val us = Fix(FancadeF.Create(
Vector(reference, value),
Exists(Template(
BlockDefinition.SetNumberReference,
()
)),
Vector(BlockDefinition.SetNumberReference.reference, BlockDefinition.SetNumberReference.value),
Vector(BlockDefinition.SetNumberReference.before)
))
Fix(FancadeF.Sequence(
us,
BlockDefinition.SetNumberReference.after,
after()
))
}
override def positionPosition(position: Fancade[Position]): Fancade[Vector3] = ???
override def positionRotation(position: Fancade[Position]): Fancade[Rotation] = ???
override def raycastHit(raycast: Fancade[Raycast]): Fancade[Boolean] = ???
override def raycastPosition(raycast: Fancade[Raycast]): Fancade[Vector3] = ???
override def raycastObj(raycast: Fancade[Raycast]): Fancade[Obj] = ???
override def sizeMin(size: Fancade[Size]): Fancade[Vector3] = ???
override def sizeMax(size: Fancade[Size]): Fancade[Vector3] = ???
override def velocityVelocity(velocity: Fancade[Velocity]): Fancade[Vector3] = ???
override def velocitySpin(velocity: Fancade[Velocity]): Fancade[Vector3] = ???
}
case class ScreenSize(width: Float, height: Float)
case class Position(position: Vector3, rotation: Rotation)
case class Raycast(hit: Boolean, position: Vector3, obj: Obj)
case class Size(min: Vector3, max: Vector3)
case class Velocity(velocity: Vector3, spin: Vector3)
case class Touch(screenX: Float, screenY: Float)
}

View File

@ -1,52 +0,0 @@
package tf.bug.fancadetagless
import cats.effect.{Blocker, ContextShift, ExitCode, IO, IOApp, Sync}
import fs2._
import higherkindness.droste.data._
import java.nio.file.{Paths, StandardOpenOption}
import scodec.stream.StreamEncoder
import tf.bug.fancadegraph.Level
import tf.bug.fancadescodec.Cartridge
import tf.bug.fancadescodec.Codecs
object Main extends IOApp {
override def run(args: List[String]): IO[ExitCode] =
program[IO].compile.drain.as(ExitCode.Success)
def program[F[_] : Sync : ContextShift]: Stream[F, Unit] = {
val program = new Fanscript.Program[Unit] {
override def run[G[_]](implicit interp: Fanscript[G]): G[Unit] = {
val score = interp.numberVariable("Score")
val one = interp.lift(1.0F)
val addToScore = interp.addNumbers(score, one)
val setScore = interp.setNumber(score, addToScore, () => interp.unit)
val inspectScore = interp.inspect(score, () => setScore)
inspectScore
}
}
val fancade: Fix[FancadeF] = program.run[Fancade]
val level: Level = FancadeF.render(fancade)
val cart: Cartridge = Cartridge(
"Test",
"rayc",
"Test of tagless",
Vector(
Level.encode(level)
)
)
val output = Paths.get("""C:\Users\aprim\Documents\FancadeLevels\TaglessTest""")
(for {
blocker <- Stream.resource(Blocker[F])
result <- Stream.emit[F, Cartridge](cart)
.through(StreamEncoder.once(Codecs.encCartridge).toPipeByte[F])
.through(io.file.writeAll(output, blocker, Seq(StandardOpenOption.TRUNCATE_EXISTING)))
} yield result)
}
}

View File

@ -1,3 +0,0 @@
package tf.bug.fancadetagless
case class Obj() // FIXME

View File

@ -1,52 +0,0 @@
package tf.bug.fancadetagless
import cats._
import cats.implicits._
import cats.data.State
import higherkindness.droste._
import higherkindness.droste.data._
import higherkindness.droste.scheme
case class PointerChain[T[_], E[_]](vertices: Vector[E[Int]], roots: T[Int])
case class PointerState[F[_]](seen: Map[F[Int], Int], vertices: Vector[F[Int]], lastIndex: Int)
object PointerChain {
def deduplicate[R[_], F[_]](input: R[Fix[F]])(
implicit rt: Traverse[R],
rf: Traverse[F]
): PointerChain[R, F] = {
val addAll: State[PointerState[F], R[Int]] = input.traverse(scheme.cataM(findOrAddNode[F]))
val result: (PointerState[F], R[Int]) = addAll.run(PointerState.empty[F]).value
val graphed: (Vector[F[Int]], R[Int]) = result.leftMap(_.vertices.reverse)
val chain: PointerChain[R, F] = PointerChain(graphed._1, graphed._2)
chain
}
def findOrAddNode[F[_]]: AlgebraM[State[PointerState[F], *], F, Int] = AlgebraM { tree =>
for {
gs <- State.get[PointerState[F]]
seen = gs.seen
result <- seen.get(tree) match {
case Some(index) => State.pure[PointerState[F], Int](index)
case None =>
val index = gs.lastIndex
for {
_ <- State.set(PointerState(
seen + (tree -> index),
tree +: gs.vertices,
index + 1
))
} yield index
}
} yield result
}
}
object PointerState {
def empty[F[_]]: PointerState[F] = PointerState(Map(), Vector(), 0)
}

View File

@ -1,7 +0,0 @@
package tf.bug.fancadetagless
case class Rotation(
pitch: Float,
yaw: Float,
roll: Float
)

View File

@ -1,7 +0,0 @@
package tf.bug.fancadetagless
case class Vector3(
x: Float,
y: Float,
z: Float
)

View File

@ -1,9 +0,0 @@
package tf.bug
import higherkindness.droste.data.Fix
package object fancadetagless {
type Fancade[A] = Fix[FancadeF]
}

View File

@ -1,55 +0,0 @@
package tf.bug.fancadetagless
import tf.bug.fancadegraph.BlockDefinition
class FancadeSuite extends munit.FunSuite {
test("A capture creates one block") {
val capture: FancadeF = Fix(Fancade.Capture[String](BlockDefinition.GetNumber, "hello", Vector(
BlockDefinition.GetNumber.output
)))
assertEquals(Fancade.render(capture).blocks.size, 1)
}
test("Stacking 1 + 1 results in a 2-element map") {
val one: FancadeF = Fix(Fancade.Capture(BlockDefinition.NumberValue, 1.0f, Vector(
BlockDefinition.NumberValue.output
)))
val add: FancadeF = Fix(Fancade.Use(
Vector(one, one),
BlockDefinition.AddNumbers,
(),
Vector(
BlockDefinition.AddNumbers.input1,
BlockDefinition.AddNumbers.input2
),
Vector(
BlockDefinition.AddNumbers.output
)
))
val stacked = Fancade.stack(add)
assertEquals(stacked, Map(
1 -> Fancade.Capture(BlockDefinition.NumberValue, 1.0f, Vector(BlockDefinition.NumberValue.output)),
0 -> Fancade.Use(Vector(1, 1), BlockDefinition.AddNumbers, (),
Vector(
BlockDefinition.AddNumbers.input1,
BlockDefinition.AddNumbers.input2
),
Vector(BlockDefinition.AddNumbers.output)
)
))
}
test("A constant creates a capture") {
val program = new Fanscript.Program[Float] {
override def run[F[_]](implicit interp: Fanscript[F]): F[Float] = interp.lift(1.0f)
}
val result = program.run[FancadeW]
assertEquals(result, Fancade.Capture(
BlockDefinition.NumberValue,
1.0f,
Vector(BlockDefinition.NumberValue.output)
))
}
}