diff --git a/graph/src/main/scala/tf/bug/fancadegraph/BlockDefinition.scala b/graph/src/main/scala/tf/bug/fancadegraph/BlockDefinition.scala index 381f4c8..4e629bc 100644 --- a/graph/src/main/scala/tf/bug/fancadegraph/BlockDefinition.scala +++ b/graph/src/main/scala/tf/bug/fancadegraph/BlockDefinition.scala @@ -1162,6 +1162,45 @@ object BlockDefinition { ) } + case object InspectNumber extends BuiltIn[Unit] { + override val width: Int = 2 + override val height: Int = 1 + override val depth: Int = 2 + override val ids: Vector[Obj] = Vector( + Obj.inspectNumber0, + Obj.inspectNumber1, + Obj.inspectNumber2, + Obj.inspectNumber3 + ) + + val after: PinDefinition = + PinDefinition( + PinType.Pull, + PinDirection.Input, + PinPosition.bottom(0) + ) + + val before: PinDefinition = + PinDefinition( + PinType.Pull, + PinDirection.Output, + PinPosition.top2(0) + ) + + val value: PinDefinition = + PinDefinition( + PinType.Number, + PinDirection.Input, + PinPosition.left(1) + ) + + override val pins: Vector[PinDefinition] = Vector( + after, + before, + value + ) + } + case object GetNumber extends BuiltIn[String] { override val width: Int = 2 override val height: Int = 1 diff --git a/tagless/src/main/scala/tf/bug/fancadetagless/FancadeF.scala b/tagless/src/main/scala/tf/bug/fancadetagless/FancadeF.scala index 9010b80..3e5c4e1 100644 --- a/tagless/src/main/scala/tf/bug/fancadetagless/FancadeF.scala +++ b/tagless/src/main/scala/tf/bug/fancadetagless/FancadeF.scala @@ -13,37 +13,44 @@ import tf.bug.fancadegraph.PinDefinition import tf.bug.fancadegraph.Template import tf.bug.fancadescodec.Position -sealed trait FancadeF[A] { - val template: Exists[Template] - val pins: Vector[PinDefinition] -} +sealed trait FancadeF[A] object FancadeF { + case class Inspect[A]( + uses: Vector[A], + template: Exists[Template], + inputs: Vector[PinDefinition], + outputs: Vector[PinDefinition] + ) extends FancadeF[A] + case class Modify[A]( + uses: Vector[A], + template: Exists[Template], + inputs: Vector[PinDefinition], + before: PinDefinition, + after: PinDefinition, + outputs: Vector[PinDefinition] + ) 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 Capture(t, p) => Capture[B](t, p).pure[G].widen - case Use(c, t, i, o) => - c.traverse(f).map { newC => Use(newC, t, i, o) } + case Inspect(u, t, i, o) => u.traverse(f).map { v => Inspect(v, t, i, o) } + case Modify(u, t, i, b, a, o) => u.traverse(f).map { v => Modify(v, t, i, b, a, o) } } override def foldLeft[A, B](fa: FancadeF[A], b: B)(f: (B, A) => B): B = fa match { - case Capture(_, _) => b - case Use(c, _, _, _) => c.foldLeft(b)(f) + case Inspect(u, _, _, _) => u.foldl(b)(f) + case Modify(u, _, _, _, _, _) => u.foldl(b)(f) } override def foldRight[A, B](fa: FancadeF[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = fa match { - case Capture(_, _) => lb - case Use(c, _, _, _) => Traverse[Vector].foldRight(c, lb)(f) + case Inspect(u, _, _, _) => u.foldr(lb)(f) } } - case class Capture[A](template: Exists[Template], pins: Vector[PinDefinition]) extends FancadeF[A] - case class Use[A](children: Vector[A], template: Exists[Template], inputs: Vector[PinDefinition], pins: Vector[PinDefinition]) extends FancadeF[A] - def render(f: Fix[FancadeF]): Level = { val pc = PointerChain.deduplicate[Id, FancadeF](f) val pcvi = pc.vertices.zipWithIndex @@ -58,8 +65,8 @@ object FancadeF { pcvi.foldLeft(Graph.empty[Pin, DiHyperEdge]) { case (graph, (block, y)) => block match { - case Capture(_, _) => graph - case Use(children, template, inputs, _) => + case Capture(_, _, _) => graph + case Use(children, template, inputs, _, _) => val thisBlock = Block( Position(0, y, 0), template @@ -76,7 +83,28 @@ object FancadeF { val newEdges: Vector[DiHyperEdge[Pin]] = childrenPins.zip(thesePins).map { case (from, to) => DiHyperEdge(from, to) } + println(newEdges) graph ++ newEdges + case Select(_, _) => graph + case AndThen(original, next, beforePinDef) => + val beforePin = Pin( + Block( + Position(0, y, 0), + next.template + ), + beforePinDef + ) + val originalInst = pc.vertices(original) + graph ++ originalInst.after.map { afterPinDef => + val afterPin = Pin( + Block( + Position(0, original, 0), + originalInst.template + ), + afterPinDef + ) + DiHyperEdge(beforePin, afterPin) + } } } Level(blocks, wires) diff --git a/tagless/src/main/scala/tf/bug/fancadetagless/Fanscript.scala b/tagless/src/main/scala/tf/bug/fancadetagless/Fanscript.scala index 2082e2b..83812fe 100644 --- a/tagless/src/main/scala/tf/bug/fancadetagless/Fanscript.scala +++ b/tagless/src/main/scala/tf/bug/fancadetagless/Fanscript.scala @@ -14,6 +14,8 @@ trait Fanscript[F[_]] { def lift(value: Rotation): F[Rotation] def lift(value: Boolean): F[Boolean] + def inspect(value: F[Float]): F[Unit] + def win(stop: Boolean): F[Unit] def lose(stop: Boolean): F[Unit] def setScore(score: F[Float]): F[Unit] @@ -73,6 +75,8 @@ trait Fanscript[F[_]] { def velocityVelocity(velocity: F[Fanscript.Velocity]): F[Vector3] def velocitySpin(velocity: F[Fanscript.Velocity]): F[Vector3] + def andThen[A, B](before: F[A], next: F[A] => F[B]): F[B] + } object Fanscript { @@ -84,23 +88,46 @@ object Fanscript { implicit object fancade extends Fanscript[Fancade] { override def lift(value: Float): Fancade[Float] = - Fix(FancadeF.Capture( + Fix(FancadeF.Inspect( + 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]): Fancade[Unit] = + Fix(FancadeF.Modify( + Vector(value), + Exists(Template( + BlockDefinition.InspectNumber, + () + )), + Vector(BlockDefinition.InspectNumber.value), + BlockDefinition.InspectNumber.before, + BlockDefinition.InspectNumber.after, + Vector() + )) override def win(stop: Boolean): Fancade[Unit] = ??? override def lose(stop: Boolean): Fancade[Unit] = ??? override def setScore(score: Fancade[Float]): Fancade[Unit] = ??? override def setCamera(position: Fancade[Vector3], rotation: Fancade[Rotation], distance: Fancade[Float]): Fancade[Unit] = ??? override def setLight(position: Fancade[Vector3], rotation: Fancade[Rotation]): Fancade[Unit] = ??? - override def screenSize: Fancade[ScreenSize] = ??? + override def screenSize: Fancade[ScreenSize] = + Fix(FancadeF.Inspect( + Exists(Template( + BlockDefinition.ScreenSize, + () + )), + Vector(BlockDefinition.ScreenSize.screenWidth, BlockDefinition.ScreenSize.screenHeight), + None + )) override def accelerometer: Fancade[Vector3] = ??? override def getPosition(obj: Fancade[Obj]): Fancade[Position] = @@ -111,7 +138,8 @@ object Fanscript { () )), Vector(BlockDefinition.GetPosition.obj), - Vector(BlockDefinition.GetPosition.position) + Vector(BlockDefinition.GetPosition.position), + None )) override def setPosition(obj: Fancade[Obj], position: Fancade[Vector3], rotation: Fancade[Rotation]): Fancade[Unit] = ??? override def raycast(from: Fancade[Vector3], to: Fancade[Vector3]): Fancade[Raycast] = ??? @@ -153,11 +181,20 @@ object Fanscript { () )), Vector(BlockDefinition.AddNumbers.input1, BlockDefinition.AddNumbers.input2), - Vector(BlockDefinition.AddNumbers.output) + Vector(BlockDefinition.AddNumbers.output), + None )) - override def screenSizeWidth(screenSize: Fancade[ScreenSize]): Fancade[Float] = ??? - override def screenSizeHeight(screenSize: Fancade[ScreenSize]): Fancade[Float] = ??? + override def screenSizeWidth(screenSize: Fancade[ScreenSize]): Fancade[Float] = + Fix(FancadeF.Select( + Fix.un(screenSize), + (0 to 0) + )) + override def screenSizeHeight(screenSize: Fancade[ScreenSize]): Fancade[Float] = + Fix(FancadeF.Select( + Fix.un(screenSize), + (1 to 1) + )) override def positionPosition(position: Fancade[Position]): Fancade[Vector3] = ??? override def positionRotation(position: Fancade[Position]): Fancade[Rotation] = ??? @@ -171,7 +208,7 @@ object Fanscript { override def velocityVelocity(velocity: Fancade[Velocity]): Fancade[Vector3] = ??? override def velocitySpin(velocity: Fancade[Velocity]): Fancade[Vector3] = ??? - + } case class ScreenSize(width: Float, height: Float) diff --git a/tagless/src/main/scala/tf/bug/fancadetagless/Main.scala b/tagless/src/main/scala/tf/bug/fancadetagless/Main.scala index bc44b76..095744d 100644 --- a/tagless/src/main/scala/tf/bug/fancadetagless/Main.scala +++ b/tagless/src/main/scala/tf/bug/fancadetagless/Main.scala @@ -15,24 +15,12 @@ object Main extends IOApp { program[IO].compile.drain.as(ExitCode.Success) def program[F[_] : Sync : ContextShift]: Stream[F, Unit] = { - val program = new Fanscript.Program[Float] { - override def run[G[_]](implicit interp: Fanscript[G]): G[Float] = { - val one = interp.lift(1.0f) - val two = interp.lift(2.0f) - val three = interp.lift(3.0f) - interp.addNumbers( - interp.addNumbers( - one, - interp.addNumbers( - two, - three - ) - ), - interp.addNumbers( - two, - three - ) - ) + val program = new Fanscript.Program[Unit] { + override def run[G[_]](implicit interp: Fanscript[G]): G[Unit] = { + val screenSize = interp.screenSize + val screenWidth = interp.screenSizeWidth(screenSize) + val inspectWidth = interp.inspect(screenWidth) + inspectWidth } }