Pass slice instead of mutable vec reference

This commit is contained in:
Austen Adler 2021-08-06 20:32:16 -04:00
parent cb14450d07
commit fa2f55c170
8 changed files with 84 additions and 54 deletions

View File

@ -22,7 +22,7 @@
clippy::integer_arithmetic, clippy::integer_arithmetic,
clippy::integer_division, clippy::integer_division,
// Expect prints a message when there is a critical error, so this is valid // Expect prints a message when there is a critical error, so this is valid
// clippy::expect_used, clippy::expect_used,
clippy::unwrap_used, clippy::unwrap_used,
)] )]
// See https://rust-lang.github.io/rust-clippy/master/index.html for more lints // See https://rust-lang.github.io/rust-clippy/master/index.html for more lints

View File

@ -5,7 +5,6 @@ pub mod fade;
pub mod moving_pixel; pub mod moving_pixel;
pub mod moving_rainbow; pub mod moving_rainbow;
pub mod solid; pub mod solid;
pub use collide::Collide; pub use collide::Collide;
pub use fade::Fade; pub use fade::Fade;
pub use moving_pixel::MovingPixel; pub use moving_pixel::MovingPixel;
@ -13,8 +12,10 @@ pub use moving_rainbow::MovingRainbow;
pub use solid::Solid; pub use solid::Solid;
pub trait Pattern: std::fmt::Debug { pub trait Pattern: std::fmt::Debug {
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()>; fn init(&mut self, num_lights: u16) -> Result<(), ()>;
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> Result<bool, ()>; fn step(&mut self) -> Result<bool, ()>;
fn get_strip(&self) -> &[RGB];
// fn get_strip_mut(&mut self) -> &[RGB];
} }
// #[cfg(test)] // #[cfg(test)]

View File

@ -14,6 +14,7 @@ pub struct Collide {
offset: u16, offset: u16,
previous_offset: u16, previous_offset: u16,
increase_offset: bool, increase_offset: bool,
lights_buf: Vec<RGB>,
} }
impl Collide { impl Collide {
pub const fn new(left_color: RGB, right_color: RGB, conjoined_color: RGB) -> Self { pub const fn new(left_color: RGB, right_color: RGB, conjoined_color: RGB) -> Self {
@ -29,11 +30,12 @@ impl Collide {
previous_offset: 0, previous_offset: 0,
offset: 0, offset: 0,
increase_offset: true, increase_offset: true,
lights_buf: vec![],
} }
} }
} }
impl Pattern for Collide { impl Pattern for Collide {
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> Result<bool, ()> { fn step(&mut self) -> Result<bool, ()> {
// TODO: Better range storage // TODO: Better range storage
// Set the left and right color // Set the left and right color
let colors = let colors =
@ -44,7 +46,8 @@ impl Pattern for Collide {
}; };
// Turn off the previous LED // Turn off the previous LED
*lights_buf *self
.lights_buf
.get_mut(usize::from(self.previous_offset)) .get_mut(usize::from(self.previous_offset))
.ok_or(())? = color::BLACK; .ok_or(())? = color::BLACK;
if self.previous_offset if self.previous_offset
@ -53,7 +56,8 @@ impl Pattern for Collide {
.saturating_sub(1) .saturating_sub(1)
.saturating_sub(self.previous_offset) .saturating_sub(self.previous_offset)
{ {
*lights_buf *self
.lights_buf
.get_mut(usize::from( .get_mut(usize::from(
self.num_lights self.num_lights
.saturating_sub(1) .saturating_sub(1)
@ -62,14 +66,18 @@ impl Pattern for Collide {
.ok_or(())? = color::BLACK; .ok_or(())? = color::BLACK;
} }
// Set the color of the current offset // Set the color of the current offset
*lights_buf.get_mut(usize::from(self.offset)).ok_or(())? = colors.0; *self
.lights_buf
.get_mut(usize::from(self.offset))
.ok_or(())? = colors.0;
if self.offset if self.offset
!= self != self
.num_lights .num_lights
.saturating_sub(1) .saturating_sub(1)
.saturating_sub(self.offset) .saturating_sub(self.offset)
{ {
*lights_buf *self
.lights_buf
.get_mut(usize::from( .get_mut(usize::from(
self.num_lights self.num_lights
.saturating_sub(1) .saturating_sub(1)
@ -96,7 +104,7 @@ impl Pattern for Collide {
Ok(true) Ok(true)
} }
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()> { fn init(&mut self, num_lights: u16) -> Result<(), ()> {
// Reset changing parameters // Reset changing parameters
self.step = 0; self.step = 0;
self.offset = 0; self.offset = 0;
@ -106,7 +114,7 @@ impl Pattern for Collide {
if self.num_lights < 3 { if self.num_lights < 3 {
return Err(()); return Err(());
} }
*lights_buf = vec![color::BLACK; self.num_lights.into()]; self.lights_buf = vec![color::BLACK; self.num_lights.into()];
if self.num_lights.rem_euclid(2) == 0 { if self.num_lights.rem_euclid(2) == 0 {
self.conjoined_bounds = ( self.conjoined_bounds = (
self.num_lights self.num_lights
@ -138,4 +146,8 @@ impl Pattern for Collide {
.saturating_mul(4); .saturating_mul(4);
Ok(()) Ok(())
} }
fn get_strip(&self) -> &[RGB] {
&self.lights_buf
}
} }

View File

@ -7,6 +7,7 @@ pub struct Fade {
step: u8, step: u8,
direction: bool, direction: bool,
num_lights: u16, num_lights: u16,
lights_buf: Vec<RGB>,
} }
impl Fade { impl Fade {
pub const fn new(color: RGB) -> Self { pub const fn new(color: RGB) -> Self {
@ -15,11 +16,12 @@ impl Fade {
step: 0, step: 0,
direction: true, direction: true,
num_lights: 1, num_lights: 1,
lights_buf: vec![],
} }
} }
} }
impl Pattern for Fade { impl Pattern for Fade {
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> Result<bool, ()> { fn step(&mut self) -> Result<bool, ()> {
if self.direction { if self.direction {
if self.step == 254 { if self.step == 254 {
self.direction = !self.direction; self.direction = !self.direction;
@ -31,17 +33,20 @@ impl Pattern for Fade {
} }
self.step = self.step.saturating_sub(1); self.step = self.step.saturating_sub(1);
} }
*lights_buf = vec![RGB(self.step, self.step, self.step); self.num_lights.into()]; self.lights_buf = vec![RGB(self.step, self.step, self.step); self.num_lights.into()];
Ok(true) Ok(true)
} }
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()> { fn init(&mut self, num_lights: u16) -> Result<(), ()> {
if num_lights < 1 { if num_lights < 1 {
return Err(()); return Err(());
} }
self.step = 0; self.step = 0;
self.direction = true; self.direction = true;
self.num_lights = num_lights; self.num_lights = num_lights;
*lights_buf = vec![color::BLACK; self.num_lights.into()]; self.lights_buf = vec![color::BLACK; self.num_lights.into()];
Ok(()) Ok(())
} }
fn get_strip(&self) -> &[RGB] {
&self.lights_buf
}
} }

View File

@ -6,35 +6,43 @@ pub struct MovingPixel {
color: RGB, color: RGB,
num_lights: u16, num_lights: u16,
step: u16, step: u16,
lights_buf: Vec<RGB>,
} }
impl MovingPixel { impl MovingPixel {
pub const fn new(color: RGB) -> Self { pub const fn new(color: RGB) -> Self {
Self { Self {
color, color,
step: 0, step: 0,
// TODO: Better initialization
num_lights: 1, num_lights: 1,
lights_buf: vec![],
} }
} }
} }
impl Pattern for MovingPixel { impl Pattern for MovingPixel {
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> Result<bool, ()> { fn step(&mut self) -> Result<bool, ()> {
let len = self.num_lights; let len = self.num_lights;
lights_buf.swap( self.lights_buf.swap(
self.step.rem_euclid(len).into(), self.step.rem_euclid(len).into(),
self.step.saturating_add(1).saturating_mul(3).into(), self.step.saturating_add(1).saturating_mul(3).into(),
); );
self.step = self.step.wrapping_add(1); self.step = self.step.wrapping_add(1);
Ok(true) Ok(true)
} }
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()> { fn init(&mut self, num_lights: u16) -> Result<(), ()> {
if num_lights < 1 { if num_lights < 1 {
return Err(()); return Err(());
} }
self.step = 0; self.step = 0;
self.num_lights = num_lights; self.num_lights = num_lights;
// Set the strip to black except for one pixel // Set the strip to black except for one pixel
*lights_buf = vec![color::BLACK; num_lights.into()]; self.lights_buf = vec![color::BLACK; num_lights.into()];
*lights_buf.get_mut(0).ok_or(())? = self.color; *self.lights_buf.get_mut(0).ok_or(())? = self.color;
Ok(()) Ok(())
} }
fn get_strip(&self) -> &[RGB] {
&self.lights_buf
}
} }

View File

@ -2,22 +2,24 @@ use super::Pattern;
use crate::color::{RAINBOW, RGB}; use crate::color::{RAINBOW, RGB};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct MovingRainbow {} pub struct MovingRainbow {
lights_buf: Vec<RGB>,
}
impl MovingRainbow { impl MovingRainbow {
pub const fn new() -> Self { pub const fn new() -> Self {
Self {} Self { lights_buf: vec![] }
} }
} }
impl Pattern for MovingRainbow { impl Pattern for MovingRainbow {
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> Result<bool, ()> { fn step(&mut self) -> Result<bool, ()> {
lights_buf.rotate_right(1); self.lights_buf.rotate_right(1);
Ok(true) Ok(true)
} }
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()> { fn init(&mut self, num_lights: u16) -> Result<(), ()> {
if num_lights < 1 { if num_lights < 1 {
return Err(()); return Err(());
} }
*lights_buf = RAINBOW self.lights_buf = RAINBOW
.iter() .iter()
.cycle() .cycle()
.take( .take(
@ -32,4 +34,7 @@ impl Pattern for MovingRainbow {
.collect::<Vec<RGB>>(); .collect::<Vec<RGB>>();
Ok(()) Ok(())
} }
fn get_strip(&self) -> &[RGB] {
&self.lights_buf
}
} }

View File

@ -5,27 +5,33 @@ use crate::color::RGB;
pub struct Solid { pub struct Solid {
color: RGB, color: RGB,
has_run: bool, has_run: bool,
lights_buf: Vec<RGB>,
} }
impl Solid { impl Solid {
pub const fn new(color: RGB) -> Self { pub const fn new(color: RGB) -> Self {
Self { Self {
color, color,
has_run: false, has_run: false,
lights_buf: vec![],
} }
} }
} }
impl Pattern for Solid { impl Pattern for Solid {
fn step(&mut self, _lights_buf: &mut Vec<RGB>) -> Result<bool, ()> { fn step(&mut self) -> Result<bool, ()> {
let ret = !self.has_run; let ret = !self.has_run;
self.has_run = true; self.has_run = true;
Ok(ret) Ok(ret)
} }
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()> { fn init(&mut self, num_lights: u16) -> Result<(), ()> {
if num_lights < 1 { if num_lights < 1 {
return Err(()); return Err(());
} }
self.has_run = false; self.has_run = false;
*lights_buf = vec![self.color; num_lights.into()]; self.lights_buf = vec![self.color; num_lights.into()];
Ok(()) Ok(())
} }
fn get_strip(&self) -> &[RGB] {
&self.lights_buf
}
} }

View File

@ -1,4 +1,4 @@
use crate::color::{self, RGB}; use crate::color;
use crate::pattern::{self, Pattern}; use crate::pattern::{self, Pattern};
use std::cmp; use std::cmp;
use std::ops::Add; use std::ops::Add;
@ -40,7 +40,6 @@ pub struct LEDStrip {
pub adapter: Box<dyn WS28xxAdapter>, pub adapter: Box<dyn WS28xxAdapter>,
pub config: Config, pub config: Config,
pub pattern: Box<dyn Pattern>, pub pattern: Box<dyn Pattern>,
pub lights_buf: Vec<RGB>,
} }
impl LEDStrip { impl LEDStrip {
@ -50,36 +49,37 @@ impl LEDStrip {
); );
let pattern = Box::new(pattern::Solid::new(color::BLACK)); let pattern = Box::new(pattern::Solid::new(color::BLACK));
let num_lights = config.num_lights; let num_lights = config.num_lights;
let lights_buf = vec![color::BLACK; num_lights.into()];
let mut ret = Self { let mut ret = Self {
adapter, adapter,
pattern, pattern,
lights_buf,
config, config,
}; };
ret.set_num_lights(num_lights); ret.set_num_lights(num_lights);
ret ret
} }
fn write_buf(&mut self) { fn write_buf_from_pattern(&mut self) {
let global_brightness_max = self.config.global_brightness_max;
let data = vec![color::BLACK] let data = vec![color::BLACK]
.iter() .iter()
.cycle() .cycle()
.take(self.config.shift_lights.into()) .take(self.config.shift_lights.into())
.chain( .chain(
self.lights_buf self.pattern
.as_slice() .get_strip()
// .as_slice()
.iter() .iter()
.take(self.config.num_lights.into()), .take(self.config.num_lights.into()),
) )
.map(|c| c.to_tuple()) .map(|c| c.to_tuple())
.map(|(r, g, b)| { .map(|(r, g, b)| {
( (
cmp::min(r, self.config.global_brightness_max), cmp::min(r, global_brightness_max),
cmp::min(g, self.config.global_brightness_max), cmp::min(g, global_brightness_max),
cmp::min(b, self.config.global_brightness_max), cmp::min(b, global_brightness_max),
) )
}) })
// TODO: Do not re-collect as u8s
.collect::<Vec<(u8, u8, u8)>>(); .collect::<Vec<(u8, u8, u8)>>();
self.adapter self.adapter
.write_rgb(data.as_slice()) .write_rgb(data.as_slice())
@ -94,7 +94,7 @@ impl LEDStrip {
); );
return; return;
} }
if self.pattern.init(&mut self.lights_buf, num_lights).is_ok() { if self.pattern.init(num_lights).is_ok() {
self.config.num_lights = num_lights; self.config.num_lights = num_lights;
} }
} }
@ -108,10 +108,7 @@ impl LEDStrip {
match message { match message {
Message::ClearLights => { Message::ClearLights => {
let mut pat = Box::new(pattern::Solid::new(color::BLACK)); let mut pat = Box::new(pattern::Solid::new(color::BLACK));
if pat if pat.init(self.config.num_lights).is_ok() {
.init(&mut self.lights_buf, self.config.num_lights)
.is_ok()
{
self.pattern = pat; self.pattern = pat;
} else { } else {
println!("Clearing light strip: {:?}", pat); println!("Clearing light strip: {:?}", pat);
@ -119,10 +116,7 @@ impl LEDStrip {
} }
Message::ChangePattern(pat) => { Message::ChangePattern(pat) => {
let mut pat = pat; let mut pat = pat;
if pat if pat.init(self.config.num_lights).is_ok() {
.init(&mut self.lights_buf, self.config.num_lights)
.is_ok()
{
self.pattern = pat; self.pattern = pat;
} else { } else {
println!("Error with pattern: {:?}", pat); println!("Error with pattern: {:?}", pat);
@ -140,10 +134,7 @@ impl LEDStrip {
Message::Quit => { Message::Quit => {
exit = true; exit = true;
let mut pat = pattern::Solid::new(color::BLACK); let mut pat = pattern::Solid::new(color::BLACK);
if pat if pat.init(self.config.num_lights).is_ok() {
.init(&mut self.lights_buf, self.config.num_lights)
.is_ok()
{
self.pattern = Box::new(pat); self.pattern = Box::new(pat);
} else { } else {
println!("Could not construct clear pattern"); println!("Could not construct clear pattern");
@ -152,8 +143,10 @@ impl LEDStrip {
} }
} }
if let Ok(true) = self.pattern.step(&mut self.lights_buf) { // TODO: Handle error properly
self.write_buf(); let result = self.pattern.step();
if let Ok(true) = result {
self.write_buf_from_pattern();
} }
if exit { if exit {