From ab738f81e70b7fc2f3303549f303f0d01f373f37 Mon Sep 17 00:00:00 2001 From: Andrew Bruce Date: Thu, 31 Oct 2024 16:17:31 +0000 Subject: [PATCH] Can construct a straight line --- lib/mudbrick/content_stream/l.ex | 10 +++++++++ lib/mudbrick/content_stream/m.ex | 10 +++++++++ lib/mudbrick/content_stream/s.ex | 9 ++++++++ lib/mudbrick/drawing.ex | 20 ++++++++++-------- lib/mudbrick/drawing/output.ex | 20 ++++++++++++++++-- test/mudbrick/drawing_test.exs | 36 +++++++++++++++++++++++++++++--- 6 files changed, 91 insertions(+), 14 deletions(-) create mode 100644 lib/mudbrick/content_stream/l.ex create mode 100644 lib/mudbrick/content_stream/m.ex create mode 100644 lib/mudbrick/content_stream/s.ex diff --git a/lib/mudbrick/content_stream/l.ex b/lib/mudbrick/content_stream/l.ex new file mode 100644 index 0000000..cda952b --- /dev/null +++ b/lib/mudbrick/content_stream/l.ex @@ -0,0 +1,10 @@ +defmodule Mudbrick.ContentStream.L do + @enforce_keys :coords + defstruct [:coords] + + defimpl Mudbrick.Object do + def from(%Mudbrick.ContentStream.L{coords: {x, y}}) do + Enum.map_intersperse([x, y, "l"], " ", &to_string/1) + end + end +end diff --git a/lib/mudbrick/content_stream/m.ex b/lib/mudbrick/content_stream/m.ex new file mode 100644 index 0000000..fcb7a9e --- /dev/null +++ b/lib/mudbrick/content_stream/m.ex @@ -0,0 +1,10 @@ +defmodule Mudbrick.ContentStream.M do + @enforce_keys :coords + defstruct [:coords] + + defimpl Mudbrick.Object do + def from(%Mudbrick.ContentStream.M{coords: {x, y}}) do + Enum.map_intersperse([x, y, "m"], " ", &to_string/1) + end + end +end diff --git a/lib/mudbrick/content_stream/s.ex b/lib/mudbrick/content_stream/s.ex new file mode 100644 index 0000000..3dabd9a --- /dev/null +++ b/lib/mudbrick/content_stream/s.ex @@ -0,0 +1,9 @@ +defmodule Mudbrick.ContentStream.S do + defstruct [] + + defimpl Mudbrick.Object do + def from(_op) do + ["S"] + end + end +end diff --git a/lib/mudbrick/drawing.ex b/lib/mudbrick/drawing.ex index c9ff4cb..8dc9c65 100644 --- a/lib/mudbrick/drawing.ex +++ b/lib/mudbrick/drawing.ex @@ -1,18 +1,20 @@ defmodule Mudbrick.Drawing do - defstruct lines: [] - - def new() do - struct!(__MODULE__, []) - end + defstruct paths: [] defmodule Path do @enforce_keys [:from, :to] defstruct [:from, :to] - def new(drawing, opts) do - Map.update!(drawing, :lines, fn lines -> - [struct!(__MODULE__, opts) | lines] - end) + def new(opts) do + struct!(__MODULE__, opts) end end + + def new() do + struct!(__MODULE__, []) + end + + def path(drawing, opts) do + %{drawing | paths: [Path.new(opts) | drawing.paths]} + end end diff --git a/lib/mudbrick/drawing/output.ex b/lib/mudbrick/drawing/output.ex index de1a3f3..a5e0bb4 100644 --- a/lib/mudbrick/drawing/output.ex +++ b/lib/mudbrick/drawing/output.ex @@ -1,7 +1,23 @@ defmodule Mudbrick.Drawing.Output do defstruct operations: [] - def from(_) do - %__MODULE__{} + alias Mudbrick.ContentStream.{ + L, + M, + S + } + + def from(%Mudbrick.Drawing{} = drawing) do + for path <- Enum.reverse(drawing.paths), reduce: %__MODULE__{} do + acc -> + acc + |> add(%M{coords: path.from}) + |> add(%L{coords: path.to}) + |> add(%S{}) + end + end + + def add(%__MODULE__{} = output, op) do + %{output | operations: [op | output.operations]} end end diff --git a/test/mudbrick/drawing_test.exs b/test/mudbrick/drawing_test.exs index c7fe078..a1a56d2 100644 --- a/test/mudbrick/drawing_test.exs +++ b/test/mudbrick/drawing_test.exs @@ -4,11 +4,41 @@ defmodule Mudbrick.DrawingTest do import Mudbrick.TestHelper, only: [output: 2] alias Mudbrick.Drawing + alias Mudbrick.Drawing.Path + + test "can construct a path" do + import Drawing + + drawing = + new() + |> path(from: {0, 0}, to: {50, 50}) + + assert drawing.paths == [ + Path.new(from: {0, 0}, to: {50, 50}) + ] + end + + test "can make an empty drawing" do + import Drawing - test "can make an empty line drawing" do assert [] = output(fn -> - Drawing.new() + new() + end) + |> operations() + end + + test "can draw one path" do + import Drawing + + assert [ + "0 50 m", + "60 50 l", + "S" + ] = + output(fn -> + new() + |> path(from: {0, 50}, to: {60, 50}) end) |> operations() end @@ -16,6 +46,6 @@ defmodule Mudbrick.DrawingTest do defp output(f), do: output(fn _ -> f.() end, Mudbrick.Drawing.Output) defp operations(ops) do - Enum.map(ops, &Mudbrick.TestHelper.show/1) + Enum.map(ops, &Mudbrick.TestHelper.show/1) |> Enum.reverse() end end