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_division,
// Expect prints a message when there is a critical error, so this is valid
// clippy::expect_used,
clippy::expect_used,
clippy::unwrap_used,
)]
// 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_rainbow;
pub mod solid;
pub use collide::Collide;
pub use fade::Fade;
pub use moving_pixel::MovingPixel;
@ -13,8 +12,10 @@ pub use moving_rainbow::MovingRainbow;
pub use solid::Solid;
pub trait Pattern: std::fmt::Debug {
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()>;
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> Result<bool, ()>;
fn init(&mut self, num_lights: u16) -> Result<(), ()>;
fn step(&mut self) -> Result<bool, ()>;
fn get_strip(&self) -> &[RGB];
// fn get_strip_mut(&mut self) -> &[RGB];
}
// #[cfg(test)]

View File

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

View File

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

View File

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

View File

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

View File

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