growth port from LA3

ba9bb3c · gmorell · 2023-01-09 01:35

10 files +157 -4

Files changed

added lib/lambent_ex/machine/steps/growth.ex
+129 −0
@@ -0,0 +1,129 @@
1 +defmodule LambentEx.Machine.Steps.Growth.Cfg do
2 + # @enforce_keys [:h]
3 + defstruct h_g: [0, 128],
4 + h_d: [0, 128],
5 + min_g: 10,
6 + max_g: 50,
7 + min_d: 5,
8 + max_d: 25,
9 + lb_min: 30,
10 + lb_max: 130,
11 + s: 255,
12 + v: 255,
13 + id: 0,
14 + status: 0
15 +end
16 +
17 +defmodule LambentEx.Machine.Steps.Growth do
18 + @moduledoc false
19 + use GenServer
20 + # @behaviour LambentEx.Machine.Steps
21 +
22 + @registry :lambent_steps
23 + @cls :growth
24 +
25 + alias LambentEx.Machine.Steps.Growth.Cfg
26 + alias LambentEx.Utils.Color
27 +
28 + defp n(opts) do
29 + "#{@cls}-#{opts[:name]}-#{opts[:id]}"
30 + end
31 +
32 + def start_link(opts) do
33 + GenServer.start_link(__MODULE__, opts, name: via_tuple(n(opts)))
34 + end
35 +
36 + def init(opts) do
37 + opts = opts |> Map.put(:status, opts.id)
38 + cfg = struct(%LambentEx.Machine.Steps.Growth.Cfg{}, opts) |> Map.from_struct()
39 +
40 + {:ok,
41 + cfg
42 + |> Map.put(:hues, generate_hues(cfg))}
43 + end
44 +
45 + defp via_tuple(name) do
46 + {:via, Registry, {@registry, name}}
47 + end
48 +
49 + defp read(state) do
50 + List.pop_at(state[:hues], 0)
51 + end
52 +
53 + def handle_cast(:step, state) do
54 + state = case state[:hues] |> length do
55 + 0 -> %{state | hues: generate_hues(state)}
56 + _otherwise -> state
57 + end
58 + {:noreply, state}
59 + end
60 +
61 + defp listy(v) when is_tuple(v) do
62 + v |> Tuple.to_list
63 + end
64 +
65 + defp listy(v) do
66 + v
67 + end
68 +
69 + def handle_call(:read, _from, state) do
70 + {reply, hues} = read(state)
71 + reply = case reply do
72 + nil -> [0,0,0]
73 + val -> reply |> listy |> Color.hsv2rgb
74 + end
75 + {:reply, reply, %{state | hues: hues}}
76 + end
77 +
78 + defp expand(values) do
79 + values
80 + |> Enum.map(fn {val, lingerd} ->
81 + expanded = multier(val, lingerd)
82 + end)
83 + |> List.flatten()
84 + end
85 +
86 + defp multier(v, qty), do: [] ++ for(_i <- 0..qty, do: v)
87 +
88 + def generate_hues(state) do
89 + growths =
90 + state[:h_g]
91 + |> Enum.map(fn x -> {x, Enum.random(state[:min_g]..state[:max_g])} end)
92 + |> expand
93 +
94 + deaths =
95 + state[:h_d]
96 + |> Enum.map(fn x -> {x, Enum.random(state[:min_d]..state[:max_d])} end)
97 + |> expand
98 +
99 + lingerd = Enum.random(state[:lb_min]..state[:lb_max])
100 +
101 + {g,d} = {growths |> List.last, deaths |> List.first}
102 + intermediate = cond do
103 + {g == d} -> multier(d, lingerd)
104 + {g != d} ->
105 + l0 = multier(g, div(lingerd, 3))
106 + l1 = multier(d, div(lingerd, 3))
107 + lbt = g..d
108 + l0 ++ lbt ++ l1
109 + end
110 +
111 + final_hues = growths ++ intermediate ++ deaths
112 + v_first = final_hues |> List.first
113 + v_last = final_hues |> List.last
114 +
115 + intro_hues = multier(v_first, state[:v])
116 + intro_sats = multier(state[:s], state[:v])
117 + intro_vals = [] ++ 0..state[:v]
118 +
119 + outro_hues = multier(v_last, state[:v])
120 + outro_sats = multier(state[:s], state[:v])
121 + outro_vals = [] ++ state[:v]..0
122 +
123 + intro_trips = Enum.zip([intro_hues, intro_sats, intro_vals])
124 + outro_trips = Enum.zip([outro_hues, outro_sats, outro_vals])
125 + intermediate = final_hues |> Enum.map(fn h -> [h, state[:s], state[:v]] end)
126 +
127 + intro_trips ++ intermediate ++ outro_trips ++ multier([0,0,0], lingerd)
128 + end
129 +end
modified lib/lambent_ex/meta.ex
+2 −2
@@ -5,9 +5,9 @@ defmodule LambentEx.Meta do
5 5 @pubsub_name LambentEx.PubSub
6 6
7 7 def init(arg) do
8 − File.cd("meta")
8 +# File.cd("meta")
9 9 {:ok, table} = :dets.open_file(@table, type: :set)
10 − File.cd("..")
10 +# File.cd("..")
11 11
12 12 Phoenix.PubSub.subscribe(@pubsub_name, "machines_idx")
13 13 Process.send_after(self(), :machine_flush, 5000)
modified lib/lambent_ex/schema/machines.ex
+2 −2
@@ -10,7 +10,6 @@ defmodule LambentEx.Schema.Machines do
10 10 @values %{
11 11 gen_solid: "Solid",
12 12 gen_solid_h: "Solid (HSV)", #
13 − gen_color_cycle: "Color Cycler",
14 13 gen_chaser: "Chaser",
15 14 gen_chaser_h: "Chaser (HSV)", #
16 15 gen_chaser_m: "Multi-Chaser",
@@ -32,7 +31,6 @@ defmodule LambentEx.Schema.Machines do
32 31 @steps %{
33 32 # gen_solid: "Solid",
34 33 gen_solid_h: LambentEx.Machine.Steps.Solid,
35 − # gen_color_cycle: "Color Cycler",
36 34 # gen_chaser: "Chaser",
37 35 gen_chaser_h: LambentEx.Machine.Steps.Chase,
38 36 gen_rainbow: LambentEx.Machine.Steps.Rainbow,
@@ -42,6 +40,7 @@ defmodule LambentEx.Schema.Machines do
42 40 gen_scape: LambentEx.Machine.Steps.Scape,
43 41 gen_scape_s: LambentEx.Machine.Steps.Scape,
44 42 gen_firefly: LambentEx.Machine.Steps.Firefly,
43 + gen_growth: LambentEx.Machine.Steps.Growth,
45 44 }
46 45
47 46 embedded_schema do
@@ -62,6 +61,7 @@ defmodule LambentEx.Schema.Machines do
62 61 gen_rainbow: LambentEx.Schema.Steps.Rainbow,
63 62 gen_rainbow_s: LambentEx.Schema.Steps.Rainbow,
64 63 gen_firefly: LambentEx.Schema.Steps.Firefly,
64 + gen_growth: LambentEx.Schema.Steps.Growth,
65 65 ],
66 66 on_type_not_found: :raise,
67 67 on_replace: :update
added lib/lambent_ex/schema/steps/growth.ex
+24 −0
@@ -0,0 +1,24 @@
1 +defmodule LambentEx.Schema.Steps.Growth do
2 + use Ecto.Schema
3 + import Ecto.Changeset
4 +
5 + @primary_key false
6 +
7 + embedded_schema do
8 + field :h_g, {:array, :integer}, default: []
9 + field :h_d, {:array, :integer}, default: []
10 + field :h_sel, :integer
11 + field :min_g, :integer, default: 10
12 + field :max_g, :integer, default: 50
13 + field :min_d, :integer, default: 5
14 + field :max_d, :integer, default: 25
15 + field :lb_min, :integer, default: 30
16 + field :lb_max, :integer, default: 130
17 + end
18 +
19 + def changeset(source, params) do
20 + source
21 + |> cast(params, ~w(h_g, h_d, h_sel, min_g, max_g, min_d, max_d, lb_min, lb_max)a)
22 + |> validate_required([:h_g, :h_d, :h_sel, :min_g, :max_G, :min_d, :max_d, :lb_min, :lb_max])
23 + end
24 +end

Parents: ec8490d