Spilt patterns across files
This commit is contained in:
parent
6c0a379aa7
commit
307d9b88ab
369
src/pattern.rs
369
src/pattern.rs
@ -1,323 +1,58 @@
|
||||
use crate::color::{self, RAINBOW, RGB};
|
||||
use crate::color::RGB;
|
||||
|
||||
pub mod collide;
|
||||
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;
|
||||
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>) -> bool;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MovingPixel {
|
||||
color: RGB,
|
||||
num_lights: u16,
|
||||
step: u16,
|
||||
}
|
||||
impl MovingPixel {
|
||||
pub const fn new(color: RGB) -> Self {
|
||||
Self {
|
||||
color,
|
||||
step: 0,
|
||||
num_lights: 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Pattern for MovingPixel {
|
||||
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> bool {
|
||||
let len = self.num_lights;
|
||||
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);
|
||||
true
|
||||
}
|
||||
fn init(&mut self, lights_buf: &mut Vec<RGB>, 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[0] = self.color;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
// #[cfg(test)]
|
||||
// mod tests {
|
||||
// use super::*;
|
||||
// const NUM_LIGHTS: u16 = 10;
|
||||
// fn test_strip() -> Vec<RGB> {
|
||||
// vec![color::BLACK; NUM_LIGHTS.into()]
|
||||
// }
|
||||
// #[test]
|
||||
// fn moving_pixel() {
|
||||
// let color = RGB(123, 152, 89);
|
||||
// let mut pat = MovingPixel::new(color.clone());
|
||||
// let mut strip = test_strip();
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Solid {
|
||||
color: RGB,
|
||||
has_run: bool,
|
||||
}
|
||||
impl Solid {
|
||||
pub const fn new(color: RGB) -> Self {
|
||||
Self {
|
||||
color,
|
||||
has_run: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Pattern for Solid {
|
||||
fn step(&mut self, _lights_buf: &mut Vec<RGB>) -> bool {
|
||||
let ret = !self.has_run;
|
||||
self.has_run = true;
|
||||
ret
|
||||
}
|
||||
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()> {
|
||||
if num_lights < 1 {
|
||||
return Err(());
|
||||
}
|
||||
self.has_run = false;
|
||||
*lights_buf = vec![self.color; num_lights.into()];
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MovingRainbow {}
|
||||
impl MovingRainbow {
|
||||
pub const fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
impl Pattern for MovingRainbow {
|
||||
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> bool {
|
||||
lights_buf.rotate_right(1);
|
||||
true
|
||||
}
|
||||
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()> {
|
||||
if num_lights < 1 {
|
||||
return Err(());
|
||||
}
|
||||
*lights_buf = RAINBOW
|
||||
.iter()
|
||||
.cycle()
|
||||
.take(
|
||||
num_lights
|
||||
.saturating_sub(1)
|
||||
.div_euclid(7)
|
||||
.saturating_add(1)
|
||||
.saturating_mul(7)
|
||||
.into(),
|
||||
)
|
||||
.copied()
|
||||
.collect::<Vec<RGB>>();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Fade {
|
||||
color: RGB,
|
||||
step: u8,
|
||||
direction: bool,
|
||||
num_lights: u16,
|
||||
}
|
||||
impl Fade {
|
||||
pub const fn new(color: RGB) -> Self {
|
||||
Self {
|
||||
color,
|
||||
step: 0,
|
||||
direction: true,
|
||||
num_lights: 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Pattern for Fade {
|
||||
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> bool {
|
||||
if self.direction {
|
||||
if self.step == 254 {
|
||||
self.direction = !self.direction;
|
||||
}
|
||||
self.step = self.step.saturating_add(1);
|
||||
} else {
|
||||
if self.step == 1 {
|
||||
self.direction = !self.direction;
|
||||
}
|
||||
self.step = self.step.saturating_sub(1);
|
||||
}
|
||||
*lights_buf = vec![RGB(self.step, self.step, self.step); self.num_lights.into()];
|
||||
true
|
||||
}
|
||||
fn init(&mut self, lights_buf: &mut Vec<RGB>, 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()];
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Collide {
|
||||
num_lights: u16,
|
||||
left_color: RGB,
|
||||
right_color: RGB,
|
||||
conjoined_color: RGB,
|
||||
step: u16,
|
||||
step_max: u16,
|
||||
conjoined_bounds: (u16, u16),
|
||||
offset_max: u16,
|
||||
offset: u16,
|
||||
previous_offset: u16,
|
||||
increase_offset: bool,
|
||||
}
|
||||
impl Collide {
|
||||
pub const fn new(left_color: RGB, right_color: RGB, conjoined_color: RGB) -> Self {
|
||||
Self {
|
||||
num_lights: 0,
|
||||
left_color,
|
||||
right_color,
|
||||
conjoined_color,
|
||||
step: 0,
|
||||
step_max: 0,
|
||||
conjoined_bounds: (0, 0),
|
||||
offset_max: 0,
|
||||
previous_offset: 0,
|
||||
offset: 0,
|
||||
increase_offset: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Pattern for Collide {
|
||||
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> bool {
|
||||
// TODO: Better range storage
|
||||
// Set the left and right color
|
||||
let colors =
|
||||
if ((self.conjoined_bounds.0)..=(self.conjoined_bounds.1)).contains(&(self.step)) {
|
||||
(self.conjoined_color, self.conjoined_color)
|
||||
} else {
|
||||
(self.left_color, self.right_color)
|
||||
};
|
||||
|
||||
// Turn off the previous LED
|
||||
lights_buf[usize::from(self.previous_offset)] = color::BLACK;
|
||||
if self.previous_offset
|
||||
!= self
|
||||
.num_lights
|
||||
.saturating_sub(1)
|
||||
.saturating_sub(self.previous_offset)
|
||||
{
|
||||
lights_buf[usize::from(
|
||||
self.num_lights
|
||||
.saturating_sub(1)
|
||||
.saturating_sub(self.previous_offset),
|
||||
)] = color::BLACK;
|
||||
}
|
||||
// Set the color of the current offset
|
||||
lights_buf[usize::from(self.offset)] = colors.0;
|
||||
if self.offset
|
||||
!= self
|
||||
.num_lights
|
||||
.saturating_sub(1)
|
||||
.saturating_sub(self.offset)
|
||||
{
|
||||
lights_buf[usize::from(
|
||||
self.num_lights
|
||||
.saturating_sub(1)
|
||||
.saturating_sub(self.offset),
|
||||
)] = colors.1;
|
||||
}
|
||||
|
||||
self.previous_offset = self.offset;
|
||||
if self.offset == 0 {
|
||||
self.increase_offset = true;
|
||||
self.offset = self.offset.saturating_add(1);
|
||||
} else if self.offset == self.offset_max {
|
||||
self.increase_offset = false;
|
||||
self.offset = self.offset.saturating_sub(1);
|
||||
} else if self.increase_offset {
|
||||
self.offset = self.offset.saturating_add(1);
|
||||
// The previous condition was false, so subtract
|
||||
} else {
|
||||
self.offset = self.offset.saturating_sub(1);
|
||||
}
|
||||
|
||||
self.step = self.step.saturating_add(1).rem_euclid(self.step_max);
|
||||
|
||||
true
|
||||
}
|
||||
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()> {
|
||||
// Reset changing parameters
|
||||
self.step = 0;
|
||||
self.offset = 0;
|
||||
self.previous_offset = 0;
|
||||
self.num_lights = num_lights;
|
||||
self.increase_offset = true;
|
||||
if self.num_lights < 3 {
|
||||
return Err(());
|
||||
}
|
||||
*lights_buf = vec![color::BLACK; self.num_lights.into()];
|
||||
if self.num_lights.rem_euclid(2) == 0 {
|
||||
self.conjoined_bounds = (
|
||||
self.num_lights
|
||||
.div_euclid(2)
|
||||
.saturating_add(1_u16.saturating_sub(1)),
|
||||
self.num_lights
|
||||
.saturating_add(1)
|
||||
.saturating_mul(3)
|
||||
.div_euclid(2)
|
||||
.saturating_sub(4),
|
||||
);
|
||||
} else {
|
||||
self.conjoined_bounds = (
|
||||
self.num_lights
|
||||
.div_euclid(2)
|
||||
.saturating_add(1_u16.saturating_sub(1)),
|
||||
self.num_lights
|
||||
.saturating_add(1)
|
||||
.saturating_mul(3)
|
||||
.div_euclid(2)
|
||||
.saturating_sub(3),
|
||||
);
|
||||
}
|
||||
self.offset_max = self.num_lights.saturating_sub(1).div_euclid(2);
|
||||
self.step_max = self
|
||||
.num_lights
|
||||
.saturating_sub(1)
|
||||
.div_euclid(2)
|
||||
.saturating_mul(4);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
const NUM_LIGHTS: u16 = 10;
|
||||
fn test_strip() -> Vec<RGB> {
|
||||
vec![color::BLACK; NUM_LIGHTS.into()]
|
||||
}
|
||||
#[test]
|
||||
fn moving_pixel() {
|
||||
let color = RGB(123, 152, 89);
|
||||
let mut pat = MovingPixel::new(color.clone());
|
||||
let mut strip = test_strip();
|
||||
|
||||
assert!(pat.init(&mut strip, NUM_LIGHTS).is_ok());
|
||||
// One is my color
|
||||
assert_eq!(strip.iter().filter(|c| **c == color).count(), 1);
|
||||
// The rest are off
|
||||
assert_eq!(
|
||||
strip.iter().filter(|c| **c == color::BLACK).count(),
|
||||
(NUM_LIGHTS - 1).into()
|
||||
);
|
||||
pat.step(&mut strip);
|
||||
// One is my color
|
||||
assert_eq!(strip.iter().filter(|c| **c == color).count(), 1);
|
||||
// The rest are off
|
||||
assert_eq!(
|
||||
strip.iter().filter(|c| **c == color::BLACK).count(),
|
||||
(NUM_LIGHTS - 1).into()
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn solid() {}
|
||||
#[test]
|
||||
fn moving_rainbow() {}
|
||||
#[test]
|
||||
fn fade() {}
|
||||
#[test]
|
||||
fn collide() {}
|
||||
}
|
||||
// assert!(pat.init(&mut strip, NUM_LIGHTS).is_ok());
|
||||
// // One is my color
|
||||
// assert_eq!(strip.iter().filter(|c| **c == color).count(), 1);
|
||||
// // The rest are off
|
||||
// assert_eq!(
|
||||
// strip.iter().filter(|c| **c == color::BLACK).count(),
|
||||
// (NUM_LIGHTS - 1).into()
|
||||
// );
|
||||
// pat.step(&mut strip);
|
||||
// // One is my color
|
||||
// assert_eq!(strip.iter().filter(|c| **c == color).count(), 1);
|
||||
// // The rest are off
|
||||
// assert_eq!(
|
||||
// strip.iter().filter(|c| **c == color::BLACK).count(),
|
||||
// (NUM_LIGHTS - 1).into()
|
||||
// );
|
||||
// }
|
||||
// #[test]
|
||||
// fn solid() {}
|
||||
// #[test]
|
||||
// fn moving_rainbow() {}
|
||||
// #[test]
|
||||
// fn fade() {}
|
||||
// #[test]
|
||||
// fn collide() {}
|
||||
// }
|
||||
|
135
src/pattern/collide.rs
Normal file
135
src/pattern/collide.rs
Normal file
@ -0,0 +1,135 @@
|
||||
use super::Pattern;
|
||||
use crate::color::{self, RGB};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Collide {
|
||||
num_lights: u16,
|
||||
left_color: RGB,
|
||||
right_color: RGB,
|
||||
conjoined_color: RGB,
|
||||
step: u16,
|
||||
step_max: u16,
|
||||
conjoined_bounds: (u16, u16),
|
||||
offset_max: u16,
|
||||
offset: u16,
|
||||
previous_offset: u16,
|
||||
increase_offset: bool,
|
||||
}
|
||||
impl Collide {
|
||||
pub const fn new(left_color: RGB, right_color: RGB, conjoined_color: RGB) -> Self {
|
||||
Self {
|
||||
num_lights: 0,
|
||||
left_color,
|
||||
right_color,
|
||||
conjoined_color,
|
||||
step: 0,
|
||||
step_max: 0,
|
||||
conjoined_bounds: (0, 0),
|
||||
offset_max: 0,
|
||||
previous_offset: 0,
|
||||
offset: 0,
|
||||
increase_offset: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Pattern for Collide {
|
||||
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> bool {
|
||||
// TODO: Better range storage
|
||||
// Set the left and right color
|
||||
let colors =
|
||||
if ((self.conjoined_bounds.0)..=(self.conjoined_bounds.1)).contains(&(self.step)) {
|
||||
(self.conjoined_color, self.conjoined_color)
|
||||
} else {
|
||||
(self.left_color, self.right_color)
|
||||
};
|
||||
|
||||
// Turn off the previous LED
|
||||
lights_buf[usize::from(self.previous_offset)] = color::BLACK;
|
||||
if self.previous_offset
|
||||
!= self
|
||||
.num_lights
|
||||
.saturating_sub(1)
|
||||
.saturating_sub(self.previous_offset)
|
||||
{
|
||||
lights_buf[usize::from(
|
||||
self.num_lights
|
||||
.saturating_sub(1)
|
||||
.saturating_sub(self.previous_offset),
|
||||
)] = color::BLACK;
|
||||
}
|
||||
// Set the color of the current offset
|
||||
lights_buf[usize::from(self.offset)] = colors.0;
|
||||
if self.offset
|
||||
!= self
|
||||
.num_lights
|
||||
.saturating_sub(1)
|
||||
.saturating_sub(self.offset)
|
||||
{
|
||||
lights_buf[usize::from(
|
||||
self.num_lights
|
||||
.saturating_sub(1)
|
||||
.saturating_sub(self.offset),
|
||||
)] = colors.1;
|
||||
}
|
||||
|
||||
self.previous_offset = self.offset;
|
||||
if self.offset == 0 {
|
||||
self.increase_offset = true;
|
||||
self.offset = self.offset.saturating_add(1);
|
||||
} else if self.offset == self.offset_max {
|
||||
self.increase_offset = false;
|
||||
self.offset = self.offset.saturating_sub(1);
|
||||
} else if self.increase_offset {
|
||||
self.offset = self.offset.saturating_add(1);
|
||||
// The previous condition was false, so subtract
|
||||
} else {
|
||||
self.offset = self.offset.saturating_sub(1);
|
||||
}
|
||||
|
||||
self.step = self.step.saturating_add(1).rem_euclid(self.step_max);
|
||||
|
||||
true
|
||||
}
|
||||
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()> {
|
||||
// Reset changing parameters
|
||||
self.step = 0;
|
||||
self.offset = 0;
|
||||
self.previous_offset = 0;
|
||||
self.num_lights = num_lights;
|
||||
self.increase_offset = true;
|
||||
if self.num_lights < 3 {
|
||||
return Err(());
|
||||
}
|
||||
*lights_buf = vec![color::BLACK; self.num_lights.into()];
|
||||
if self.num_lights.rem_euclid(2) == 0 {
|
||||
self.conjoined_bounds = (
|
||||
self.num_lights
|
||||
.div_euclid(2)
|
||||
.saturating_add(1_u16.saturating_sub(1)),
|
||||
self.num_lights
|
||||
.saturating_add(1)
|
||||
.saturating_mul(3)
|
||||
.div_euclid(2)
|
||||
.saturating_sub(4),
|
||||
);
|
||||
} else {
|
||||
self.conjoined_bounds = (
|
||||
self.num_lights
|
||||
.div_euclid(2)
|
||||
.saturating_add(1_u16.saturating_sub(1)),
|
||||
self.num_lights
|
||||
.saturating_add(1)
|
||||
.saturating_mul(3)
|
||||
.div_euclid(2)
|
||||
.saturating_sub(3),
|
||||
);
|
||||
}
|
||||
self.offset_max = self.num_lights.saturating_sub(1).div_euclid(2);
|
||||
self.step_max = self
|
||||
.num_lights
|
||||
.saturating_sub(1)
|
||||
.div_euclid(2)
|
||||
.saturating_mul(4);
|
||||
Ok(())
|
||||
}
|
||||
}
|
47
src/pattern/fade.rs
Normal file
47
src/pattern/fade.rs
Normal file
@ -0,0 +1,47 @@
|
||||
use super::Pattern;
|
||||
use crate::color::{self, RGB};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Fade {
|
||||
color: RGB,
|
||||
step: u8,
|
||||
direction: bool,
|
||||
num_lights: u16,
|
||||
}
|
||||
impl Fade {
|
||||
pub const fn new(color: RGB) -> Self {
|
||||
Self {
|
||||
color,
|
||||
step: 0,
|
||||
direction: true,
|
||||
num_lights: 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Pattern for Fade {
|
||||
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> bool {
|
||||
if self.direction {
|
||||
if self.step == 254 {
|
||||
self.direction = !self.direction;
|
||||
}
|
||||
self.step = self.step.saturating_add(1);
|
||||
} else {
|
||||
if self.step == 1 {
|
||||
self.direction = !self.direction;
|
||||
}
|
||||
self.step = self.step.saturating_sub(1);
|
||||
}
|
||||
*lights_buf = vec![RGB(self.step, self.step, self.step); self.num_lights.into()];
|
||||
true
|
||||
}
|
||||
fn init(&mut self, lights_buf: &mut Vec<RGB>, 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()];
|
||||
Ok(())
|
||||
}
|
||||
}
|
40
src/pattern/moving_pixel.rs
Normal file
40
src/pattern/moving_pixel.rs
Normal file
@ -0,0 +1,40 @@
|
||||
use super::Pattern;
|
||||
use crate::color::{self, RGB};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MovingPixel {
|
||||
color: RGB,
|
||||
num_lights: u16,
|
||||
step: u16,
|
||||
}
|
||||
impl MovingPixel {
|
||||
pub const fn new(color: RGB) -> Self {
|
||||
Self {
|
||||
color,
|
||||
step: 0,
|
||||
num_lights: 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Pattern for MovingPixel {
|
||||
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> bool {
|
||||
let len = self.num_lights;
|
||||
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);
|
||||
true
|
||||
}
|
||||
fn init(&mut self, lights_buf: &mut Vec<RGB>, 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[0] = self.color;
|
||||
Ok(())
|
||||
}
|
||||
}
|
35
src/pattern/moving_rainbow.rs
Normal file
35
src/pattern/moving_rainbow.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use super::Pattern;
|
||||
use crate::color::{RAINBOW, RGB};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MovingRainbow {}
|
||||
impl MovingRainbow {
|
||||
pub const fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
impl Pattern for MovingRainbow {
|
||||
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> bool {
|
||||
lights_buf.rotate_right(1);
|
||||
true
|
||||
}
|
||||
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()> {
|
||||
if num_lights < 1 {
|
||||
return Err(());
|
||||
}
|
||||
*lights_buf = RAINBOW
|
||||
.iter()
|
||||
.cycle()
|
||||
.take(
|
||||
num_lights
|
||||
.saturating_sub(1)
|
||||
.div_euclid(7)
|
||||
.saturating_add(1)
|
||||
.saturating_mul(7)
|
||||
.into(),
|
||||
)
|
||||
.copied()
|
||||
.collect::<Vec<RGB>>();
|
||||
Ok(())
|
||||
}
|
||||
}
|
31
src/pattern/solid.rs
Normal file
31
src/pattern/solid.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use super::Pattern;
|
||||
use crate::color::RGB;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Solid {
|
||||
color: RGB,
|
||||
has_run: bool,
|
||||
}
|
||||
impl Solid {
|
||||
pub const fn new(color: RGB) -> Self {
|
||||
Self {
|
||||
color,
|
||||
has_run: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Pattern for Solid {
|
||||
fn step(&mut self, _lights_buf: &mut Vec<RGB>) -> bool {
|
||||
let ret = !self.has_run;
|
||||
self.has_run = true;
|
||||
ret
|
||||
}
|
||||
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()> {
|
||||
if num_lights < 1 {
|
||||
return Err(());
|
||||
}
|
||||
self.has_run = false;
|
||||
*lights_buf = vec![self.color; num_lights.into()];
|
||||
Ok(())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user