Add rainbow width

This commit is contained in:
Your Name 2021-08-10 02:23:58 +01:00
parent 2ce2b09ad7
commit 04147e0989
4 changed files with 38 additions and 19 deletions

View File

@ -22,7 +22,7 @@ impl FromStr for Rgb {
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
if let [r, g, b] = s.split(" ").collect::<Vec<&str>>().as_slice() { if let [r, g, b] = s.split(" ").collect::<Vec<&str>>().as_slice() {
return Ok(Rgb(r.parse::<u8>()?, g.parse::<u8>()?, b.parse::<u8>()?)); return Ok(Self(r.parse::<u8>()?, g.parse::<u8>()?, b.parse::<u8>()?));
} }
hex::decode( hex::decode(
@ -32,7 +32,7 @@ impl FromStr for Rgb {
) )
.map_err(|_| ()) .map_err(|_| ())
.and_then(|v| { .and_then(|v| {
Ok(Rgb( Ok(Self(
*v.get(0).ok_or(())?, *v.get(0).ok_or(())?,
*v.get(1).ok_or(())?, *v.get(1).ok_or(())?,
*v.get(2).ok_or(())?, *v.get(2).ok_or(())?,
@ -41,7 +41,7 @@ impl FromStr for Rgb {
.or_else(|_| { .or_else(|_| {
// TODO: Return a proper error here // TODO: Return a proper error here
let color_value = s.parse::<u8>()?; let color_value = s.parse::<u8>()?;
Ok(Rgb(color_value, color_value, color_value)) Ok(Self(color_value, color_value, color_value))
}) })
} }
} }

View File

@ -44,11 +44,11 @@ fn main() -> Result<(), ProgramError> {
let strip_handle = thread::spawn(move || -> Result<(), ProgramError> { let strip_handle = thread::spawn(move || -> Result<(), ProgramError> {
let mut strip = LedStrip::new(strip::Config { let mut strip = LedStrip::new(strip::Config {
// I have 89 right now, but start off with 20 // I have 89 right now, but start off with 20
num_lights: 20, num_lights: 89,
// Skip 14 lights // Skip 14 lights
shift_lights: 14, shift_lights: 14,
// Scaling factor (scale 0..255) // Scaling factor (scale 0..255)
global_brightness_max: 20, global_brightness_max: 255,
tick_time_ms: strip::DEFAULT_TICK_TIME_MS, tick_time_ms: strip::DEFAULT_TICK_TIME_MS,
})?; })?;
strip.strip_loop(&rx) strip.strip_loop(&rx)

View File

@ -1,13 +1,19 @@
use super::Pattern; use super::Pattern;
use crate::color::{Rgb, RAINBOW}; use crate::color::{Rgb, RAINBOW};
use std::convert::TryFrom;
use std::iter;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct MovingRainbow { pub struct MovingRainbow {
lights_buf: Vec<Rgb>, lights_buf: Vec<Rgb>,
width: u8,
} }
impl MovingRainbow { impl MovingRainbow {
pub const fn new() -> Self { pub const fn new(width: u8) -> Self {
Self { lights_buf: vec![] } Self {
lights_buf: vec![],
width,
}
} }
} }
impl Pattern for MovingRainbow { impl Pattern for MovingRainbow {
@ -16,22 +22,31 @@ impl Pattern for MovingRainbow {
Ok(true) Ok(true)
} }
fn init(&mut self, num_lights: u16) -> Result<(), ()> { fn init(&mut self, num_lights: u16) -> Result<(), ()> {
if num_lights < 1 { if num_lights < 1 || num_lights > 255 {
return Err(()); return Err(());
} }
if self.width < 1 {
return Err(());
}
// The length of the buffer
// Always a factor of RAINBOW.len() * width
let length_factor = u16::try_from(RAINBOW.len()).or(Err(()))? * u16::from(self.width);
let buf_length = num_lights
.checked_sub(1)
.ok_or(())?
.div_euclid(length_factor)
.checked_add(1)
.ok_or(())?
* length_factor;
self.lights_buf = RAINBOW self.lights_buf = RAINBOW
.iter() .iter()
.flat_map(|&x| iter::repeat(x).take(self.width.into()))
.cycle() .cycle()
.take( .take(buf_length.into())
num_lights .collect();
.saturating_sub(1)
.div_euclid(7)
.saturating_add(1)
.saturating_mul(7)
.into(),
)
.copied()
.collect::<Vec<Rgb>>();
Ok(()) Ok(())
} }
fn get_strip(&self) -> &[Rgb] { fn get_strip(&self) -> &[Rgb] {

View File

@ -65,7 +65,11 @@ fn parse_cmd(tx: &Sender<strip::Message>, s: &str) -> Result<(), String> {
let color = parse_color(c, c, c)?; let color = parse_color(c, c, c)?;
change_pattern(tx, Box::new(pattern::Solid::new(color))) change_pattern(tx, Box::new(pattern::Solid::new(color)))
}, },
["r"] =>change_pattern(tx, Box::new(pattern::MovingRainbow::new())), ["r"] =>change_pattern(tx, Box::new(pattern::MovingRainbow::new(4))),
["r", w] => {
let width = w.parse::<u8>().map_err(|_| String::from("Width could not be parsed"))?;
change_pattern(tx, Box::new(pattern::MovingRainbow::new(width)))
},
["b", r1, g1, b1, r2, g2, b2, r3, g3, b3] => { ["b", r1, g1, b1, r2, g2, b2, r3, g3, b3] => {
let left = parse_color(r1, g1, b1)?; let left = parse_color(r1, g1, b1)?;
let right = parse_color(r2, g2, b2)?; let right = parse_color(r2, g2, b2)?;