Rainbow and Solid Rainbows

d18413e · gmorell · 2022-12-19 02:53

20 files +177 -23

Files changed

modified lib/lambent_ex/machine.ex
+24 −3
@@ -44,7 +44,7 @@ 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, single: false, count: 300])
47 + {:ok, opts} = Keyword.validate(opts, [:step, :step_opts, :name, single: false, persist: false, count: 300])
48 48 cnt = opts[:count]
49 49
50 50 specs = case opts[:single] do
@@ -82,7 +82,8 @@ defmodule LambentEx.Machine do
82 82 bright_mvmul: 2,
83 83 cnt: cnt,
84 84 single: opts[:single],
85 − started: DateTime.utc_now
85 + started: DateTime.utc_now,
86 + persist: opts[:persist],
86 87 }}
87 88 end
88 89
@@ -106,6 +107,14 @@ defmodule LambentEx.Machine do
106 107 via_tuple("machine-#{id}") |> GenServer.cast(:dimmer)
107 108 end
108 109
110 + def persist(id) do
111 + via_tuple("machine-#{id}") |> GenServer.cast(:persist)
112 + end
113 +
114 + def quit(id) do
115 + via_tuple("machine-#{id}") |> GenServer.cast(:quit)
116 + end
117 +
109 118 # impls
110 119
111 120 defp bmath(i, state) do
@@ -129,7 +138,8 @@ defmodule LambentEx.Machine do
129 138 step: state[:step] |> stripstep,
130 139 speed: state[:speed],
131 140 cnt: state[:cnt],
132 − bgt: state[:bright_curr]
141 + bgt: state[:bright_curr],
142 + persist: state[:persist],
133 143 }
134 144 end
135 145
@@ -277,6 +287,17 @@ defmodule LambentEx.Machine do
277 287 {:noreply, state |> Map.put(:bright_tgt, do_dimmer(state.bright_tgt))}
278 288 end
279 289
290 + @impl true
291 + def handle_cast(:persist, state) do
292 + {:noreply, state |> Map.put(:persist, !state.persist)}
293 + end
294 +
295 + @impl
296 + def handle_cast(:quit, state) do
297 + LambentEx.MachineSupervisor.abort_child(self())
298 + {:noreply, state}
299 + end
300 +
280 301 def handle_call(_msg, _from, state) do
281 302 {:reply, :ok, state}
282 303 end
added lib/lambent_ex/machine/steps/rainbow.ex
+49 −0
@@ -0,0 +1,49 @@
1 +defmodule LambentEx.Machine.Steps.Rainbow.Cfg do
2 + # @enforce_keys [:h]
3 + defstruct [modulo: 1, id: 0, s: 255, v: 255, status: 0]
4 +end
5 +
6 +defmodule LambentEx.Machine.Steps.Rainbow do
7 + @moduledoc false
8 + use GenServer
9 + # @behaviour LambentEx.Machine.Steps
10 +
11 + @registry :lambent_steps
12 + @cls :chase
13 +
14 + alias LambentEx.Machine.Steps.Rainbow.Cfg
15 + alias LambentEx.Utils.Color
16 +
17 + defp n(opts) do
18 + "#{@cls}-#{opts[:name]}-#{opts[:id]}"
19 + end
20 +
21 + def start_link(opts) do
22 + GenServer.start_link(__MODULE__, opts, name: via_tuple(n(opts)))
23 + end
24 +
25 + def init(opts) do
26 + opts = opts |> Map.put(:status, opts.id)
27 + cfg = struct(%LambentEx.Machine.Steps.Rainbow.Cfg{}, opts)
28 + {:ok, cfg}
29 + end
30 +
31 + defp via_tuple(name) do
32 + {:via, Registry, {@registry, name}}
33 + end
34 +
35 + defp read(state) do
36 + Color.hsv2rgb([state.status, state.s, state.v])
37 + end
38 +
39 + def handle_cast(:step, state) do
40 + state =
41 + state
42 + |> Map.put(:status, (state.status + 1) |> Integer.mod(255))
43 + {:noreply, state}
44 + end
45 +
46 + def handle_call(:read, _from, state) do
47 + {:reply, read(state), state}
48 + end
49 +end
modified lib/lambent_ex/schema/machines.ex
+28 −17
@@ -17,12 +17,13 @@ defmodule LambentEx.Schema.Machines do
17 17 gen_chaser_mh: "Multi-Chaser (HSV)",
18 18 gen_growth: "Growth",
19 19 gen_rocker: "Rocker",
20 − gen_rainbows: "Rainbow",
20 + gen_rainbow: "Rainbow",
21 + gen_rainbow_s: "Rainbow (Solid)",
21 22 gen_scape: "Scape",
22 23 gen_twinkler: "LA3PortTwinler",
23 24 rcv_fft: "FFT Receiver",
24 25 rcv_gsi: "GSI Receiver",
25 − rcv_hyp: "Hyperion Receiver",
26 + rcv_hyp: "Hyperion Receiver"
26 27 }
27 28
28 29 @steps %{
@@ -30,7 +31,9 @@ defmodule LambentEx.Schema.Machines do
30 31 gen_solid_h: LambentEx.Machine.Steps.Solid,
31 32 # gen_color_cycle: "Color Cycler",
32 33 # gen_chaser: "Chaser",
33 − gen_chaser_h: LambentEx.Machine.Steps.Chase
34 + gen_chaser_h: LambentEx.Machine.Steps.Chase,
35 + gen_rainbow: LambentEx.Machine.Steps.Rainbow,
36 + gen_rainbow_s: LambentEx.Machine.Steps.Rainbow,
34 37 }
35 38
36 39 embedded_schema do
@@ -43,7 +46,9 @@ defmodule LambentEx.Schema.Machines do
43 46 # gen_solid: LambentEx.Schema.Steps.Solid,
44 47 gen_solid_h: LambentEx.Schema.Steps.Solid,
45 48 gen_chaser: LambentEx.Schema.Steps.Chase,
46 − gen_chaser_h: LambentEx.Schema.Steps.Chase
49 + gen_chaser_h: LambentEx.Schema.Steps.Chase,
50 + gen_rainbow: LambentEx.Schema.Steps.Rainbow,
51 + gen_rainbow_s: LambentEx.Schema.Steps.Rainbow
47 52 ],
48 53 on_type_not_found: :raise,
49 54 on_replace: :update
@@ -67,22 +72,28 @@ defmodule LambentEx.Schema.Machines do
67 72
68 73 def update_machines(%Machines{} = machines, attrs) do
69 74 res = machines |> Machines.changeset(attrs)
75 + IO.inspect(res)
70 76
71 − opts = case res.changes[:type] do
72 − :gen_solid -> [single: true]
73 − :gen_solid_h -> [single: true]
74 − _otherwise -> []
75 − end
77 + opts =
78 + case res.changes[:type] do
79 + :gen_solid -> [single: true]
80 + :gen_solid_h -> [single: true]
81 + :gen_rainbow_s -> [single: true]
82 + _otherwise -> []
83 + end |> IO.inspect()
76 84
77 − opts = []
78 85 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 + true ->
87 + {:ok,
88 + LambentEx.MachineSupervisor.start_child(
89 + Map.get(@steps, res.changes[:type]),
90 + res.changes[:class] |> Map.from_struct(),
91 + res.changes[:name],
92 + opts
93 + )}
94 +
95 + false ->
96 + {:error, res}
86 97 end
87 98 end
88 99 end
added lib/lambent_ex/schema/steps/rainbow.ex
+16 −0
@@ -0,0 +1,16 @@
1 +defmodule LambentEx.Schema.Steps.Rainbow do
2 + use Ecto.Schema
3 + import Ecto.Changeset
4 +
5 + @primary_key false
6 +
7 + embedded_schema do
8 + field :modulo, :integer
9 + end
10 +
11 + def changeset(source, params) do
12 + source
13 + |> cast(params, ~w(modulo)a)
14 + |> validate_required([:modulo])
15 + end
16 +end
modified lib/lambent_ex/supervision/machine.ex
+3 −1
@@ -7,10 +7,12 @@ defmodule LambentEx.MachineSupervisor do
7 7
8 8 def start_child(step, opts, name, options, count \\ 300) do
9 9 spec = {LambentEx.Machine, [step: step, step_opts: opts, count: count, name: name] ++ options}
10 − DynamicSupervisor.start_child(__MODULE__, spec)
10 + IO.inspect(spec)
11 + DynamicSupervisor.start_child(__MODULE__, spec) |> IO.inspect
11 12 end
12 13
13 14 def abort_child(pid) do
15 + IO.inspect("here")
14 16 DynamicSupervisor.terminate_child(__MODULE__, pid)
15 17 end
16 18
modified lib/lambent_ex_web/live/links/index.html.heex
+2 −2
@@ -46,8 +46,8 @@ on_cancel={JS.navigate(~p"/cfg/links")}>
46 46 <input type="checkbox" phx-click="toggle" phx-value-tgt={k} class="toggle" />
47 47 <% end %>
48 48 &emsp;
49 − <a class="btn btn-error btn-outline" phx-click="quit" phx-value-tgt={k}>
50 − <i class="fa-solid fa-xmark"></i>
49 + <a class="btn btn-error btn-outline btn-circle" phx-click="quit" phx-value-tgt={k}>
50 + <i class="fa-solid fa-2x fa-xmark"></i>
51 51 </a>
52 52 </td>
53 53 </tr>
modified lib/lambent_ex_web/live/machines/form_component.html.heex
+31 −0
@@ -87,6 +87,37 @@
87 87 </div>
88 88 </div>
89 89 <% end %>
90 +
91 + <%= :gen_rainbow -> %>
92 + <%= polymorphic_embed_inputs_for f, :class, :gen_rainbow, fn gr -> %>
93 + <div tabindex="0" class="collapse collapse-arrow border border-base-300 bg-base-100 rounded-box">
94 + <div class="collapse-title text-xl font-medium">
95 + Extra Configuration Values
96 + </div>
97 + <div class="collapse-content">
98 + <p>
99 + <.input field={{gr, :modulo}} type="range" min="0" max="255" label="Saturation" class="range range-priamry range-lg" />
100 + </p>
101 + </div>
102 + </div>
103 + <% end %>
104 +
105 +
106 + <%= :gen_rainbow_s -> %>
107 + <%= polymorphic_embed_inputs_for f, :class, :gen_rainbow_s, fn grs -> %>
108 + <div tabindex="0" class="collapse collapse-arrow border border-base-300 bg-base-100 rounded-box">
109 + <div class="collapse-title text-xl font-medium">
110 + Extra Configuration Values
111 + </div>
112 + <div class="collapse-content">
113 + <p>
114 + <.input field={{grs, :modulo}} type="range" min="0" max="255" label="Saturation" class="range range-priamry range-lg" />
115 + </p>
116 + </div>
117 + </div>
118 + <% end %>
119 +
120 +
90 121 <% end %>
91 122 </div>
92 123 </div>
modified lib/lambent_ex_web/live/machines/index.ex
+11 −0
@@ -82,6 +82,17 @@ defmodule LambentExWeb.MachinesLive.Index do
82 82 {:noreply, socket}
83 83 end
84 84
85 + def handle_event("quit", params, socket) do
86 + LambentEx.Machine.quit(params["tgt"])
87 + machines = socket.assigns.machines |> Map.delete(params["tgt"])
88 + {:noreply, socket |> assign(:machines, machines)}
89 + end
90 +
91 + def handle_event("persist", data, socket) do
92 + LambentEx.Machine.persist(data["tgt"])
93 + {:noreply, socket}
94 + end
95 +
85 96 defp spd(val) do
86 97 @speeds[val]
87 98 end
modified lib/lambent_ex_web/live/machines/index.html.heex
+13 −0
@@ -54,6 +54,19 @@
54 54 <button class="btn btn-circle" phx-click="brighter" phx-value-id={v[:name] }>
55 55 <i class="fa-solid fa-2x fa-lightbulb"></i>
56 56 </button>
57 + <%= if v[:persist] == true do %>
58 + <a class="btn btn-success btn-circle" phx-click="persist" phx-value-tgt={v[:name]}>
59 + <i class="fa-solid fa-2x fa-anchor"></i>
60 + </a>
61 + <% else %>
62 + <a class="btn btn-success btn-outline btn-circle" phx-click="persist" phx-value-tgt={v[:name]}>
63 + <i class="fa-solid fa-2x fa-anchor"></i>
64 + </a>
65 + <% end %>
66 + <a class="btn btn-error btn-outline btn-circle" phx-click="quit" phx-value-tgt={v[:name]}>
67 + <i class="fa-solid fa-2x fa-xmark"></i>
68 + </a>
69 +
57 70 </td>
58 71 </tr>
59 72 <% end %>

Parents: 6677142