machine single mode w/ expansion + machine form completion + solidz + machine opts refactor

4e46c7d · gmorell · 2022-12-18 21:50

15 files +138 -30

Files changed

modified lib/lambent_ex/machine.ex
+22 −7
@@ -44,17 +44,24 @@ defmodule LambentEx.Machine do
44 44 def init(opts) do
45 45 Process.send_after(self(), :step, 100)
46 46 Process.send_after(self(), :publish, 50)
47 − {:ok, opts} = Keyword.validate(opts, [:step, :step_opts, :name, count: 300])
47 + {:ok, opts} = Keyword.validate(opts, [:step, :step_opts, :name, single: false, count: 300])
48 48 cnt = opts[:count]
49 49
50 − specs =
51 − 1..cnt
50 + specs = case opts[:single] do
51 + true -> # only start one, and then step & expand to meet cnt
52 + [Parent.child_spec(
53 + {opts[:step], opts[:step_opts] |> Map.put(:id, 0) |> Map.put(:name, opts[:name])},
54 + id: 0
55 + )]
56 + false -> # start cnt children
57 + 0..cnt
52 58 |> Enum.map(fn id ->
53 59 Parent.child_spec(
54 60 {opts[:step], opts[:step_opts] |> Map.put(:id, id) |> Map.put(:name, opts[:name])},
55 61 id: id
56 62 )
57 63 end)
64 + end
58 65
59 66 pids =
60 67 specs
@@ -74,6 +81,7 @@ defmodule LambentEx.Machine do
74 81 bright_delay: 0,
75 82 bright_mvmul: 2,
76 83 cnt: cnt,
84 + single: opts[:single],
77 85 started: DateTime.utc_now
78 86 }}
79 87 end
@@ -132,10 +140,17 @@ defmodule LambentEx.Machine do
132 140 state[:steps]
133 141 |> Enum.map(&GenServer.cast(&1, :step))
134 142
135 − data =
136 − state[:steps]
137 − |> Enum.map(&GenServer.call(&1, :read))
138 − |> Enum.map(fn x -> x |> Enum.map(fn y -> bmath(y, state) end) end)
143 + data = state[:steps]
144 + |> Enum.map(&GenServer.call(&1, :read))
145 + |> Enum.map(fn x -> x |> Enum.map(fn y -> bmath(y, state) end) end)
146 +
147 + data = case state[:single] do
148 + true -> # expand single to fill cnt
149 + data |> List.flatten |> Stream.cycle |> Enum.take(state[:cnt] * 3)
150 + false -> # do nothing
151 + data
152 + end
153 +
139 154
140 155 #
141 156 # |> IO.inspect()
modified lib/lambent_ex/schema/links.ex
+0 −3
@@ -20,9 +20,6 @@ defmodule LambentEx.Schema.Links do
20 20 end
21 21
22 22 def update_links(%Links{} = link, attrs) do
23 − IO.puts("actual write")
24 −
25 −
26 23 res = link
27 24 |> Links.changeset(attrs)
28 25
modified lib/lambent_ex/schema/machines.ex
+35 −8
@@ -9,7 +9,7 @@ defmodule LambentEx.Schema.Machines do
9 9
10 10 @values %{
11 11 gen_solid: "Solid",
12 − gen_solid_h: "Solid",
12 + gen_solid_h: "Solid (HSV)",
13 13 gen_color_cycle: "Color Cycler",
14 14 gen_chaser: "Chaser",
15 15 gen_chaser_h: "Chaser (HSV)",
@@ -24,20 +24,25 @@ defmodule LambentEx.Schema.Machines do
24 24 rcv_gsi: "GSI Receiver"
25 25 }
26 26
27 + @steps %{
28 + # gen_solid: "Solid",
29 + gen_solid_h: LambentEx.Machine.Steps.Solid,
30 + # gen_color_cycle: "Color Cycler",
31 + # gen_chaser: "Chaser",
32 + gen_chaser_h: LambentEx.Machine.Steps.Chase
33 + }
34 +
27 35 embedded_schema do
28 36 field(:name, :string)
29 37
30 − field(:type, Ecto.Enum,
31 − values:
32 − @values |> Map.keys()
33 − )
38 + field(:type, Ecto.Enum, values: @values |> Map.keys())
34 39
35 40 field(:class, PolymorphicEmbed,
36 41 types: [
37 −# gen_solid: LambentEx.Schema.Steps.Solid,
38 −# gen_solid_h: LambentEx.Schema.Steps.Solid,
42 + # gen_solid: LambentEx.Schema.Steps.Solid,
43 + gen_solid_h: LambentEx.Schema.Steps.Solid,
39 44 gen_chaser: LambentEx.Schema.Steps.Chase,
40 − gen_chaser_h: LambentEx.Schema.Steps.Chase,
45 + gen_chaser_h: LambentEx.Schema.Steps.Chase
41 46 ],
42 47 on_type_not_found: :raise,
43 48 on_replace: :update
@@ -58,4 +63,26 @@ defmodule LambentEx.Schema.Machines do
58 63 def change_machine(%Machines{} = machine, attrs \\ %{}) do
59 64 Machines.changeset(machine, attrs)
60 65 end
66 +
67 + def update_machines(%Machines{} = machines, attrs) do
68 + res = machines |> Machines.changeset(attrs)
69 + IO.inspect(res)
70 +
71 + opts = case res.changes[:type] do
72 + :gen_solid -> [single: true]
73 + :gen_solid_h -> [single: true]
74 + _otherwise -> []
75 + end
76 +
77 + opts = []
78 + case res.valid? do
79 + true -> {:ok, LambentEx.MachineSupervisor.start_child(
80 + Map.get(@steps, res.changes[:type]),
81 + res.changes[:class] |> Map.from_struct,
82 + res.changes[:name],
83 + opts
84 + )}
85 + false -> {:error, res}
86 + end
87 + end
61 88 end
added lib/lambent_ex/schema/steps/solid.ex
+18 −0
@@ -0,0 +1,18 @@
1 +defmodule LambentEx.Schema.Steps.Solid do
2 + use Ecto.Schema
3 + import Ecto.Changeset
4 +
5 + @primary_key false
6 +
7 + embedded_schema do
8 + field :h, :integer
9 + field :s, :integer, default: 255
10 + field :v, :integer, default: 255
11 + end
12 +
13 + def changeset(source, params) do
14 + source
15 + |> cast(params, ~w(h s v)a)
16 + |> validate_required([:h, :s, :v])
17 + end
18 +end
modified lib/lambent_ex/supervision/machine.ex
+2 −2
@@ -5,8 +5,8 @@ defmodule LambentEx.MachineSupervisor do
5 5 DynamicSupervisor.start_link(__MODULE__, init_arg, name: __MODULE__)
6 6 end
7 7
8 − def start_child(step, opts, name, count \\ 300) do
9 − spec = {LambentEx.Machine, step: step, step_opts: opts, count: count, name: name}
8 + def start_child(step, opts, name, options, count \\ 300) do
9 + spec = {LambentEx.Machine, [step: step, step_opts: opts, count: count, name: name] ++ options}
10 10 DynamicSupervisor.start_child(__MODULE__, spec)
11 11 end
12 12
modified lib/lambent_ex_web/live/machines/form_component.ex
+16 −1
@@ -32,17 +32,32 @@ defmodule LambentEx.MachinesLive.FormComponent do
32 32 IO.inspect(changeset)
33 33 keys = case changeset.changes[:type] do
34 34 :gen_chaser_h -> changeset.changes[:class] |> hue_keys
35 + :gen_solid_h -> changeset.changes[:class] |> hue_keys
35 36 _otherwise -> []
36 37 end
37 38
38 39 socket = case keys do
39 40 [r: r, g: g, b: b] -> socket |> assign(:rgb, "rgb(#{r}, #{g}, #{b})")
41 + [r: r, g: g, b: b, h: h] -> socket |> assign(:rgb, "rgb(#{r}, #{g}, #{b})") |> assign(:h, h)
40 42 [] -> socket
41 43 end
42 44
43 45 {:noreply, assign(socket, :changeset, changeset)}
44 46 end
45 47
48 + def handle_event("save", %{"machines" => machines_params}, socket) do
49 + case Machines.update_machines(socket.assigns.machine, machines_params) do
50 + {:ok, _machine} ->
51 + {:noreply,
52 + socket
53 + |> put_flash(:info, "Machine Created Successfully")
54 + |> push_navigate(to: socket.assigns.navigate)}
55 +
56 + {:error, %Ecto.Changeset{} = changeset} ->
57 + {:noreply, assign(socket, :changeset, changeset)}
58 + end
59 + end
60 +
46 61 def handle_event("new-name", _params, socket) do
47 62 changeset = socket.assigns.changeset |> Ecto.Changeset.change(name: Names.name())
48 63 {:noreply, assign(socket, :changeset, changeset)}
@@ -55,6 +70,6 @@ defmodule LambentEx.MachinesLive.FormComponent do
55 70 defp hue_keys(nil), do: []
56 71 defp hue_keys(%{h: h, s: s, v: v}) do
57 72 [r,g,b] = LambentEx.Utils.Color.hsv2rgb([h,s,v])
58 − [r: r, g: g, b: b]
73 + [r: r, g: g, b: b, h: h]
59 74 end
60 75 end
modified lib/lambent_ex_web/live/machines/form_component.html.heex
+45 −9
@@ -28,16 +28,22 @@
28 28 <%= :gen_chaser -> %> rgb
29 29 <%= :gen_chaser_h -> %>
30 30 <%= polymorphic_embed_inputs_for f, :class, :gen_chaser_h, fn gch -> %>
31 − <.input field={{gch, :h}} type="range" min="0" max="255" label="Hue" class="range range-priamry range-lg" />
32 − <div class="w-full flex justify-between text-xs px-2 mb-4" style={"color: #{@rgb}"}>
33 − <span>&#9608;</span>
34 − <span>&#9608;</span>
35 − <span>&#9608;</span>
36 − <span>&#9608;</span>
37 − <span>&#9608;</span>
38 − <span>&#9608;</span>
39 − <span>&#9608;</span>
31 + <div class="flex">
32 + <div class="flex-auto">
33 + <.input field={{gch, :h}} type="range" min="0" max="255" label="Hue" class="range range-priamry range-lg" />
34 + <div class="w-full flex justify-between text-xs px-2 mb-4" style={"color: #{@rgb}"}>
35 + <span>&#9608;</span>
36 + <span>&#9608;</span>
37 + <span>&#9608;</span>
38 + <span>&#9608;</span>
39 + <span>&#9608;</span>
40 + <span>&#9608;</span>
41 + <span>&#9608;</span>
42 + </div>
43 + </div>
44 + <div class="flex-none text-5xl p-8"><%= @h %></div>
40 45 </div>
46 +
41 47 <div tabindex="0" class="collapse collapse-arrow border border-base-300 bg-base-100 rounded-box">
42 48 <div class="collapse-title text-xl font-medium">
43 49 Extra Configuration Values
@@ -51,6 +57,36 @@
51 57 </div>
52 58 <% end %>
53 59
60 + <%= :gen_solid_h -> %>
61 + <%= polymorphic_embed_inputs_for f, :class, :gen_solid_h, fn gsh -> %>
62 + <div class="flex">
63 + <div class="flex-auto">
64 + <.input field={{gsh, :h}} type="range" min="0" max="255" label="Hue" class="range range-priamry range-lg" />
65 + <div class="w-full flex justify-between text-xs px-2 mb-4" style={"color: #{@rgb}"}>
66 + <span>&#9608;</span>
67 + <span>&#9608;</span>
68 + <span>&#9608;</span>
69 + <span>&#9608;</span>
70 + <span>&#9608;</span>
71 + <span>&#9608;</span>
72 + <span>&#9608;</span>
73 + </div>
74 + </div>
75 + <div class="flex-none text-5xl p-8"><%= @h %></div>
76 + </div>
77 +
78 + <div tabindex="0" class="collapse collapse-arrow border border-base-300 bg-base-100 rounded-box">
79 + <div class="collapse-title text-xl font-medium">
80 + Extra Configuration Values
81 + </div>
82 + <div class="collapse-content">
83 + <p>
84 + <.input field={{gsh, :s}} type="range" min="0" max="255" label="Saturation" class="range range-priamry range-lg" />
85 + <.input field={{gsh, :v}} type="range" min="0" max="255" label="Saturation" class="range range-priamry range-lg" />
86 + </p>
87 + </div>
88 + </div>
89 + <% end %>
54 90 <% end %>
55 91 </div>
56 92 </div>

Parents: 78b7a65