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 {
|
pub trait Pattern: std::fmt::Debug {
|
||||||
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()>;
|
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()>;
|
||||||
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> bool;
|
fn step(&mut self, lights_buf: &mut Vec<RGB>) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
// #[cfg(test)]
|
||||||
pub struct MovingPixel {
|
// mod tests {
|
||||||
color: RGB,
|
// use super::*;
|
||||||
num_lights: u16,
|
// const NUM_LIGHTS: u16 = 10;
|
||||||
step: u16,
|
// fn test_strip() -> Vec<RGB> {
|
||||||
}
|
// vec![color::BLACK; NUM_LIGHTS.into()]
|
||||||
impl MovingPixel {
|
// }
|
||||||
pub const fn new(color: RGB) -> Self {
|
// #[test]
|
||||||
Self {
|
// fn moving_pixel() {
|
||||||
color,
|
// let color = RGB(123, 152, 89);
|
||||||
step: 0,
|
// let mut pat = MovingPixel::new(color.clone());
|
||||||
num_lights: 1,
|
// let mut strip = test_strip();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
// assert!(pat.init(&mut strip, NUM_LIGHTS).is_ok());
|
||||||
pub struct Solid {
|
// // One is my color
|
||||||
color: RGB,
|
// assert_eq!(strip.iter().filter(|c| **c == color).count(), 1);
|
||||||
has_run: bool,
|
// // The rest are off
|
||||||
}
|
// assert_eq!(
|
||||||
impl Solid {
|
// strip.iter().filter(|c| **c == color::BLACK).count(),
|
||||||
pub const fn new(color: RGB) -> Self {
|
// (NUM_LIGHTS - 1).into()
|
||||||
Self {
|
// );
|
||||||
color,
|
// pat.step(&mut strip);
|
||||||
has_run: false,
|
// // One is my color
|
||||||
}
|
// assert_eq!(strip.iter().filter(|c| **c == color).count(), 1);
|
||||||
}
|
// // The rest are off
|
||||||
}
|
// assert_eq!(
|
||||||
impl Pattern for Solid {
|
// strip.iter().filter(|c| **c == color::BLACK).count(),
|
||||||
fn step(&mut self, _lights_buf: &mut Vec<RGB>) -> bool {
|
// (NUM_LIGHTS - 1).into()
|
||||||
let ret = !self.has_run;
|
// );
|
||||||
self.has_run = true;
|
// }
|
||||||
ret
|
// #[test]
|
||||||
}
|
// fn solid() {}
|
||||||
fn init(&mut self, lights_buf: &mut Vec<RGB>, num_lights: u16) -> Result<(), ()> {
|
// #[test]
|
||||||
if num_lights < 1 {
|
// fn moving_rainbow() {}
|
||||||
return Err(());
|
// #[test]
|
||||||
}
|
// fn fade() {}
|
||||||
self.has_run = false;
|
// #[test]
|
||||||
*lights_buf = vec![self.color; num_lights.into()];
|
// fn collide() {}
|
||||||
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() {}
|
|
||||||
}
|
|
||||||
|
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