Skip to content

Commit 8d82b83

Browse files
committed
feat(config): Add classic led config generator
1 parent f4d6c8d commit 8d82b83

File tree

2 files changed

+205
-0
lines changed

2 files changed

+205
-0
lines changed

src/models.rs

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ use validator::Validate;
99

1010
use crate::db::models as db_models;
1111

12+
mod layouts;
13+
pub use layouts::*;
14+
1215
pub type Color = palette::rgb::LinSrgb<u8>;
1316
pub type Color16 = palette::rgb::LinSrgb<u16>;
1417

@@ -695,6 +698,7 @@ pub struct ClassicLedConfig {
695698
pub hdepth: u32,
696699
#[validate(range(min = 1, max = 100))]
697700
pub vdepth: u32,
701+
#[validate(range(min = 0, max = 100))]
698702
pub overlap: u32,
699703
#[validate(range(max = 50))]
700704
pub edgegap: u32,

src/models/layouts.rs

+201
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
use super::{ClassicLedConfig, Led, Leds};
2+
3+
/// Trait for converting a LED configuration to LEDs
4+
pub trait ToLeds {
5+
fn to_leds(&self) -> Leds;
6+
}
7+
8+
struct ClassicLedParams {
9+
ledstop: u32,
10+
ledsbottom: u32,
11+
ledsleft: u32,
12+
ledsright: u32,
13+
ledsglength: u32,
14+
ledsgpos: u32,
15+
position: i32,
16+
reverse: bool,
17+
ledsvdepth: f32,
18+
ledshdepth: f32,
19+
edgehgap: f32,
20+
edgevgap: f32,
21+
overlap: f32,
22+
ptblh: f32,
23+
ptblv: f32,
24+
ptbrh: f32,
25+
ptbrv: f32,
26+
pttlh: f32,
27+
pttlv: f32,
28+
pttrh: f32,
29+
pttrv: f32,
30+
}
31+
32+
impl From<&ClassicLedConfig> for ClassicLedParams {
33+
fn from(c: &ClassicLedConfig) -> Self {
34+
Self {
35+
ledstop: c.top,
36+
ledsbottom: c.bottom,
37+
ledsleft: c.left,
38+
ledsright: c.right,
39+
ledsglength: c.glength,
40+
ledsgpos: c.gpos,
41+
position: c.position,
42+
reverse: c.reverse,
43+
ledsvdepth: c.vdepth as f32 / 100.,
44+
ledshdepth: c.hdepth as f32 / 100.,
45+
edgehgap: (c.edgegap as f32 / 200.) / (16. / 9.),
46+
edgevgap: c.edgegap as f32 / 200.,
47+
overlap: c.overlap as f32 / 100.,
48+
ptblh: c.pblh as f32 / 100.,
49+
ptblv: c.pblv as f32 / 100.,
50+
ptbrh: c.pbrh as f32 / 100.,
51+
ptbrv: c.pbrv as f32 / 100.,
52+
pttlh: c.ptlh as f32 / 100.,
53+
pttlv: c.ptlv as f32 / 100.,
54+
pttrh: c.ptrh as f32 / 100.,
55+
pttrv: c.ptrv as f32 / 100.,
56+
}
57+
}
58+
}
59+
60+
impl ClassicLedParams {
61+
fn round(x: f32) -> f32 {
62+
let factor = 1e4;
63+
(x * factor).round() / factor
64+
}
65+
66+
fn create_led(hmin: f32, hmax: f32, vmin: f32, vmax: f32) -> Led {
67+
Led {
68+
hmin: Self::round(hmin),
69+
hmax: Self::round(hmax),
70+
vmin: Self::round(vmin),
71+
vmax: Self::round(vmax),
72+
color_order: None,
73+
name: None,
74+
}
75+
}
76+
77+
fn ovl_plus(&self, x: f32) -> f32 {
78+
(x + self.overlap).clamp(0., 1.)
79+
}
80+
81+
fn ovl_minus(&self, x: f32) -> f32 {
82+
(x - self.overlap).clamp(0., 1.)
83+
}
84+
85+
fn create_top_leds(&self, leds: &mut Vec<Led>) {
86+
let steph = (self.pttrh - self.pttlh - (2. * self.edgehgap)) as f32 / self.ledstop as f32;
87+
let stepv = (self.pttrv - self.pttlv) as f32 / self.ledstop as f32;
88+
89+
leds.reserve(self.ledstop as _);
90+
for i in 0..self.ledstop {
91+
let i = i as f32;
92+
let hmin = self.ovl_minus(self.pttlh + (steph * i) + self.edgehgap);
93+
let hmax = self.ovl_plus(self.pttlh + (steph * (i + 1.)) + self.edgehgap);
94+
let vmin = self.pttlv + (stepv * i);
95+
let vmax = vmin + self.ledshdepth;
96+
97+
leds.push(Self::create_led(hmin, hmax, vmin, vmax));
98+
}
99+
}
100+
101+
fn create_right_leds(&self, leds: &mut Vec<Led>) {
102+
let steph = (self.ptbrh - self.pttrh) as f32 / self.ledsright as f32;
103+
let stepv = (self.ptbrv - self.pttrv - (2. * self.edgevgap)) / self.ledsright as f32;
104+
105+
leds.reserve(self.ledsright as _);
106+
for i in 0..self.ledsright {
107+
let i = i as f32;
108+
let hmax = self.pttrh + (steph * (i + 1.));
109+
let hmin = hmax - self.ledsvdepth;
110+
let vmin = self.ovl_minus(self.pttrv + (stepv * i) + self.edgevgap);
111+
let vmax = self.ovl_plus(self.pttrv + (stepv * (i + 1.)) + self.edgevgap);
112+
113+
leds.push(Self::create_led(hmin, hmax, vmin, vmax));
114+
}
115+
}
116+
117+
fn create_bottom_leds(&self, leds: &mut Vec<Led>) {
118+
let steph =
119+
(self.ptbrh - self.ptblh - (2. * self.edgehgap)) as f32 / self.ledsbottom as f32;
120+
let stepv = (self.ptbrv - self.ptblv) as f32 / self.ledsbottom as f32;
121+
122+
leds.reserve(self.ledsbottom as _);
123+
for i in 0..self.ledsbottom {
124+
let i = i as f32;
125+
let hmin = self.ovl_minus(self.ptblh + (steph * i) + self.edgehgap);
126+
let hmax = self.ovl_plus(self.ptblh + (steph * (i + 1.)) + self.edgehgap);
127+
let vmax = self.ptblv + (stepv * i);
128+
let vmin = vmax - self.ledshdepth;
129+
130+
leds.push(Self::create_led(hmin, hmax, vmin, vmax));
131+
}
132+
}
133+
134+
fn create_left_leds(&self, leds: &mut Vec<Led>) {
135+
let steph = (self.ptblh - self.pttlh) as f32 / self.ledsleft as f32;
136+
let stepv = (self.ptblv - self.pttlv - (2. * self.edgevgap)) as f32 / self.ledsleft as f32;
137+
138+
leds.reserve(self.ledsleft as _);
139+
for i in 0..self.ledsleft {
140+
let i = i as f32;
141+
let hmin = self.pttlh + (steph * i);
142+
let hmax = hmin + self.ledsvdepth;
143+
let vmin = self.ovl_minus(self.pttlv + (stepv * i) + self.edgevgap);
144+
let vmax = self.ovl_plus(self.pttlv + (stepv * (i + 1.)) + self.edgevgap);
145+
146+
leds.push(Self::create_led(hmin, hmax, vmin, vmax));
147+
}
148+
}
149+
}
150+
151+
impl ToLeds for ClassicLedParams {
152+
fn to_leds(&self) -> Leds {
153+
let mut leds = Vec::with_capacity(
154+
(self.ledstop + self.ledsbottom + self.ledsleft + self.ledsright) as usize,
155+
);
156+
157+
self.create_top_leds(&mut leds);
158+
self.create_right_leds(&mut leds);
159+
self.create_bottom_leds(&mut leds);
160+
self.create_left_leds(&mut leds);
161+
162+
// Check LED gap pos
163+
let ledsgpos = if self.ledsgpos + self.ledsglength > leds.len() as _ {
164+
(leds.len() as isize - self.ledsglength as isize).max(0) as usize
165+
} else {
166+
self.ledsglength as usize
167+
};
168+
169+
// Check LED gap length
170+
let ledsglength = if self.ledsglength >= leds.len() as _ {
171+
leds.len() as isize - self.ledsglength as isize - 1
172+
} else {
173+
self.ledsglength as _
174+
};
175+
176+
if ledsglength > 0 {
177+
leds.splice(
178+
ledsgpos..(ledsgpos + ledsglength as usize),
179+
std::iter::empty(),
180+
);
181+
}
182+
183+
if self.position < 0 {
184+
leds.rotate_left(-self.position as _);
185+
} else if self.position > 0 {
186+
leds.rotate_right(self.position as _);
187+
}
188+
189+
if self.reverse {
190+
leds.reverse();
191+
}
192+
193+
Leds { leds }
194+
}
195+
}
196+
197+
impl ToLeds for ClassicLedConfig {
198+
fn to_leds(&self) -> Leds {
199+
ClassicLedParams::from(self).to_leds()
200+
}
201+
}

0 commit comments

Comments
 (0)