add background color for color wipe and my first unit test !
This commit is contained in:
parent
b718334392
commit
ee133379f2
|
@ -2,21 +2,21 @@
|
||||||
mac_addresses :
|
mac_addresses :
|
||||||
- C9:81:9C:BA:53:BC
|
- C9:81:9C:BA:53:BC
|
||||||
sequence:
|
sequence:
|
||||||
- pattern:
|
# - pattern:
|
||||||
type: Blink
|
# type: Blink
|
||||||
fade:
|
# fade:
|
||||||
current_iteration: 10
|
# current_iteration: 10
|
||||||
nbr_iterations: 20
|
# nbr_iterations: 20
|
||||||
begin_color: &black
|
# begin_color: &black
|
||||||
red: 0
|
# red: 0
|
||||||
green: 0
|
# green: 0
|
||||||
blue: 0
|
# blue: 0
|
||||||
end_color: &purple
|
# end_color: &purple
|
||||||
red: 255
|
# red: 255
|
||||||
green: 0
|
# green: 0
|
||||||
blue: 255
|
# blue: 255
|
||||||
max_iteration: 10
|
# max_iteration: 10
|
||||||
period: 50
|
# period: 50
|
||||||
- pattern:
|
- pattern:
|
||||||
type: Fade
|
type: Fade
|
||||||
nbr_iterations: 20
|
nbr_iterations: 20
|
||||||
|
@ -36,7 +36,6 @@
|
||||||
red: 0
|
red: 0
|
||||||
green: 255
|
green: 255
|
||||||
blue: 0
|
blue: 0
|
||||||
background_color: *purple
|
|
||||||
period: 100
|
period: 100
|
||||||
- pattern:
|
- pattern:
|
||||||
type: FillRandom
|
type: FillRandom
|
||||||
|
@ -45,17 +44,22 @@
|
||||||
period: 80
|
period: 80
|
||||||
- name: titi
|
- name: titi
|
||||||
sequence:
|
sequence:
|
||||||
- pattern:
|
# - pattern:
|
||||||
type: Blink
|
# type: Blink
|
||||||
fade :
|
# fade :
|
||||||
nbr_iterations: 20
|
# nbr_iterations: 20
|
||||||
begin_color: *black
|
# begin_color: *black
|
||||||
end_color: &cyan
|
# end_color: &cyan
|
||||||
red: 0
|
# red: 0
|
||||||
green: 255
|
# green: 255
|
||||||
blue: 255
|
# blue: 255
|
||||||
max_iteration : 10
|
# max_iteration : 10
|
||||||
period: 50
|
# period: 50
|
||||||
- pattern:
|
- pattern:
|
||||||
type: Rainbow
|
type: Rainbow
|
||||||
|
max_iteration: 200
|
||||||
|
period: 10
|
||||||
|
- pattern:
|
||||||
|
type: ColorWipe
|
||||||
|
color: *blue
|
||||||
period: 100
|
period: 100
|
|
@ -5,6 +5,7 @@ mod rainbow;
|
||||||
mod fill_random;
|
mod fill_random;
|
||||||
mod fill_unstable;
|
mod fill_unstable;
|
||||||
mod blink;
|
mod blink;
|
||||||
|
mod rain;
|
||||||
|
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -29,6 +30,12 @@ pub(crate) enum Patterns<const N: usize> {
|
||||||
Blink(Blink<N>),
|
Blink(Blink<N>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Pattern : Iterator {
|
||||||
|
type Strip;
|
||||||
|
|
||||||
|
fn init(&self) -> Option<Self::Strip>;
|
||||||
|
}
|
||||||
|
|
||||||
impl<const N: usize> Iterator for Patterns<N> {
|
impl<const N: usize> Iterator for Patterns<N> {
|
||||||
type Item = Strip<N>;
|
type Item = Strip<N>;
|
||||||
|
|
||||||
|
@ -45,6 +52,22 @@ impl<const N: usize> Iterator for Patterns<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> Pattern for Patterns<N> {
|
||||||
|
type Strip = Strip<N>;
|
||||||
|
|
||||||
|
fn init(&self) -> Option<Self::Strip> {
|
||||||
|
match self {
|
||||||
|
Patterns::Rainbow(p) => p.init(),
|
||||||
|
Patterns::Fade(p) => p.init(),
|
||||||
|
Patterns::ColorWipe(p) => p.init(),
|
||||||
|
Patterns::Scanner(p) => p.init(),
|
||||||
|
Patterns::FillRandom(p) => p.init(),
|
||||||
|
Patterns::FillUnstable(p) => p.init(),
|
||||||
|
Patterns::Blink(p) => p.init(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// a struct for an RGB color
|
/// a struct for an RGB color
|
||||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Default, Eq, Hash, PartialEq)]
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Default, Eq, Hash, PartialEq)]
|
||||||
|
@ -84,17 +107,17 @@ impl SubAssign for PixelColor {
|
||||||
///
|
///
|
||||||
/// a basic newtype based on a fix array size.
|
/// a basic newtype based on a fix array size.
|
||||||
///
|
///
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
|
||||||
pub struct Strip<const N: usize>([PixelColor; N]);
|
pub struct Strip<const N: usize>([Option<PixelColor>; N]);
|
||||||
|
|
||||||
impl<const N: usize> Default for Strip<N> {
|
impl<const N: usize> Default for Strip<N> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Strip([PixelColor::default(); N])
|
Strip([None; N])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> Index<usize> for Strip<N> {
|
impl<const N: usize> Index<usize> for Strip<N> {
|
||||||
type Output = PixelColor;
|
type Output = Option<PixelColor>;
|
||||||
|
|
||||||
fn index(&self, index: usize) -> &Self::Output {
|
fn index(&self, index: usize) -> &Self::Output {
|
||||||
&self.0[index]
|
&self.0[index]
|
||||||
|
@ -102,7 +125,7 @@ impl<const N: usize> Index<usize> for Strip<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> IndexMut<usize> for Strip<N> {
|
impl<const N: usize> IndexMut<usize> for Strip<N> {
|
||||||
fn index_mut(&mut self, index: usize) -> &mut PixelColor {
|
fn index_mut(&mut self, index: usize) -> &mut Option<PixelColor> {
|
||||||
&mut self.0[index]
|
&mut self.0[index]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,16 +135,17 @@ impl<const N: usize> Strip<N> {
|
||||||
let mut data: Vec<u8> = vec![];
|
let mut data: Vec<u8> = vec![];
|
||||||
|
|
||||||
for i in 0..N {
|
for i in 0..N {
|
||||||
data.append(&mut vec![self[i].green, self[i].red, self[i].blue]);
|
let color = self[i].unwrap_or(PixelColor::default());
|
||||||
|
data.append(&mut vec![color.green, color.red, color.blue]);
|
||||||
}
|
}
|
||||||
data
|
data
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(color: PixelColor) -> Strip<N> {
|
pub fn new(color: PixelColor) -> Strip<N> {
|
||||||
Strip { 0: [color; N] }
|
Strip { 0: [Some(color); N] }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fill(&mut self, color: PixelColor) {
|
pub fn fill(&mut self, color: PixelColor) {
|
||||||
self.0.fill(color);
|
self.0.fill(Some(color));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::patterns::fade::Fade;
|
use crate::patterns::fade::Fade;
|
||||||
use crate::Strip;
|
use crate::Strip;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
use crate::patterns::Pattern;
|
||||||
|
|
||||||
/// # Blink
|
/// # Blink
|
||||||
///
|
///
|
||||||
|
@ -13,6 +14,14 @@ pub struct Blink<const N: usize> {
|
||||||
fade: Fade<N>,
|
fade: Fade<N>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> Pattern for Blink<N> {
|
||||||
|
type Strip = Strip<N>;
|
||||||
|
|
||||||
|
fn init(&self) -> Option<Self::Strip> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<const N: usize> Iterator for Blink<N> {
|
impl<const N: usize> Iterator for Blink<N> {
|
||||||
type Item = Strip<N>;
|
type Item = Strip<N>;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::patterns::PixelColor;
|
use crate::patterns::{Pattern, PixelColor};
|
||||||
use crate::Strip;
|
use crate::Strip;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
@ -20,6 +20,18 @@ pub struct ColorWipe<const N: usize> {
|
||||||
pub(crate) background_color: Option<PixelColor>,
|
pub(crate) background_color: Option<PixelColor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> Pattern for ColorWipe<N> {
|
||||||
|
type Strip = Strip<N>;
|
||||||
|
|
||||||
|
fn init(&self) -> Option<Self::Strip> {
|
||||||
|
if let Some(color) = self.background_color {
|
||||||
|
Some(Strip::<N>::new(color))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<const N: usize> Iterator for ColorWipe<N> {
|
impl<const N: usize> Iterator for ColorWipe<N> {
|
||||||
type Item = Strip<N>;
|
type Item = Strip<N>;
|
||||||
|
|
||||||
|
@ -36,7 +48,7 @@ impl<const N: usize> Iterator for ColorWipe<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..iteration {
|
for i in 0..iteration {
|
||||||
strip[i] = self.color;
|
strip[i] = Some(self.color);
|
||||||
}
|
}
|
||||||
self.current_iteration += 1;
|
self.current_iteration += 1;
|
||||||
Some(strip)
|
Some(strip)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::patterns::PixelColor;
|
use crate::patterns::{Pattern, PixelColor};
|
||||||
use crate::Strip;
|
use crate::Strip;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
@ -17,6 +17,14 @@ fn fade_value(value_start: u8, value_end: u8, index: usize, nbr_iter: usize) ->
|
||||||
((value_start as usize * (nbr_iter - index) + value_end as usize * index) / nbr_iter) as u8
|
((value_start as usize * (nbr_iter - index) + value_end as usize * index) / nbr_iter) as u8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> Pattern for Fade<N> {
|
||||||
|
type Strip = Strip<N>;
|
||||||
|
|
||||||
|
fn init(&self) -> Option<Self::Strip> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<const N: usize> Iterator for Fade<N> {
|
impl<const N: usize> Iterator for Fade<N> {
|
||||||
type Item = Strip<N>;
|
type Item = Strip<N>;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use crate::patterns::PixelColor;
|
use crate::patterns::{Pattern, PixelColor};
|
||||||
use crate::Strip;
|
use crate::Strip;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
@ -13,6 +13,14 @@ pub struct FillRandom<const N: usize> {
|
||||||
pub(crate) max_iteration: Option<usize>,
|
pub(crate) max_iteration: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> Pattern for FillRandom<N> {
|
||||||
|
type Strip = Strip<N>;
|
||||||
|
|
||||||
|
fn init(&self) -> Option<Self::Strip> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<const N: usize> Iterator for FillRandom<N> {
|
impl<const N: usize> Iterator for FillRandom<N> {
|
||||||
type Item = Strip<N>;
|
type Item = Strip<N>;
|
||||||
|
|
||||||
|
@ -45,7 +53,7 @@ impl<const N: usize> Iterator for FillRandom<N> {
|
||||||
blue = self.color.blue.saturating_sub(blue_delta);
|
blue = self.color.blue.saturating_sub(blue_delta);
|
||||||
}
|
}
|
||||||
let c = PixelColor { red, green, blue };
|
let c = PixelColor { red, green, blue };
|
||||||
strip[i] = c;
|
strip[i] = Some(c);
|
||||||
}
|
}
|
||||||
Some(strip)
|
Some(strip)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use crate::patterns::PixelColor;
|
use crate::patterns::{Pattern, PixelColor};
|
||||||
use crate::Strip;
|
use crate::Strip;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
@ -13,6 +13,14 @@ pub struct FillUnstable<const N: usize> {
|
||||||
pub(crate) max_iteration: Option<usize>,
|
pub(crate) max_iteration: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> Pattern for FillUnstable<N> {
|
||||||
|
type Strip = Strip<N>;
|
||||||
|
|
||||||
|
fn init(&self) -> Option<Self::Strip> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<const N: usize> Iterator for FillUnstable<N> {
|
impl<const N: usize> Iterator for FillUnstable<N> {
|
||||||
type Item = Strip<N>;
|
type Item = Strip<N>;
|
||||||
|
|
||||||
|
|
48
src/patterns/rain.rs
Normal file
48
src/patterns/rain.rs
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
use crate::patterns::PixelColor;
|
||||||
|
use crate::Strip;
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
/// # scanner pattern
|
||||||
|
/// color one pixel with a color and leave a train of this color fading to black
|
||||||
|
///
|
||||||
|
/// # note
|
||||||
|
///
|
||||||
|
/// background_color work only for color not set by scanner pattern
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)]
|
||||||
|
pub struct Scanner<const N: usize> {
|
||||||
|
#[serde(default)]
|
||||||
|
current_iteration: usize,
|
||||||
|
pub(crate) color: PixelColor,
|
||||||
|
pub(crate) background_color: Option<PixelColor>,
|
||||||
|
pub(crate) stability: usize,
|
||||||
|
#[serde(skip)]
|
||||||
|
strip : Strip<N>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> Iterator for Scanner<N> {
|
||||||
|
type Item = Strip<N>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let mut strip = Strip::<N>::default();
|
||||||
|
if let Some(c) = self.background_color {
|
||||||
|
strip.fill(c);
|
||||||
|
} else {
|
||||||
|
strip.fill(PixelColor::default());
|
||||||
|
}
|
||||||
|
|
||||||
|
let current_led = self.current_iteration % N;
|
||||||
|
let min_led;
|
||||||
|
if current_led < 8 {
|
||||||
|
min_led = 0;
|
||||||
|
} else {
|
||||||
|
min_led = current_led - 8;
|
||||||
|
}
|
||||||
|
let mut c = self.color;
|
||||||
|
for i in min_led..current_led {
|
||||||
|
strip[i] = Some(c);
|
||||||
|
c = c / 2;
|
||||||
|
}
|
||||||
|
self.current_iteration += 1;
|
||||||
|
Some(strip)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::patterns::PixelColor;
|
use crate::patterns::{Pattern, PixelColor};
|
||||||
use crate::Strip;
|
use crate::Strip;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
@ -20,6 +20,14 @@ pub struct Rainbow<const N: usize> {
|
||||||
pub(crate) step: Option<usize>,
|
pub(crate) step: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> Pattern for Rainbow<N> {
|
||||||
|
type Strip = Strip<N>;
|
||||||
|
|
||||||
|
fn init(&self) -> Option<Self::Strip> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<const N: usize> Iterator for Rainbow<N> {
|
impl<const N: usize> Iterator for Rainbow<N> {
|
||||||
type Item = Strip<N>;
|
type Item = Strip<N>;
|
||||||
|
|
||||||
|
@ -33,7 +41,7 @@ impl<const N: usize> Iterator for Rainbow<N> {
|
||||||
let step = self.step.unwrap_or(255 / N);
|
let step = self.step.unwrap_or(255 / N);
|
||||||
for i in 0..N {
|
for i in 0..N {
|
||||||
let pos = (i * step + self.current_iteration) as u8;
|
let pos = (i * step + self.current_iteration) as u8;
|
||||||
strip[i] = wheel(pos)
|
strip[i] = Some(wheel(pos))
|
||||||
}
|
}
|
||||||
self.current_iteration += 1;
|
self.current_iteration += 1;
|
||||||
Some(strip)
|
Some(strip)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::patterns::PixelColor;
|
use crate::patterns::{Pattern, PixelColor};
|
||||||
use crate::Strip;
|
use crate::Strip;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
@ -16,6 +16,18 @@ pub struct Scanner<const N: usize> {
|
||||||
pub(crate) background_color: Option<PixelColor>,
|
pub(crate) background_color: Option<PixelColor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<const N:usize> Pattern for Scanner<N> {
|
||||||
|
type Strip = Strip<N>;
|
||||||
|
|
||||||
|
fn init(&self) -> Option<Self::Strip> {
|
||||||
|
if let Some(color) = self.background_color {
|
||||||
|
Some(Strip::<N>::new(color))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<const N: usize> Iterator for Scanner<N> {
|
impl<const N: usize> Iterator for Scanner<N> {
|
||||||
type Item = Strip<N>;
|
type Item = Strip<N>;
|
||||||
|
|
||||||
|
@ -36,7 +48,7 @@ impl<const N: usize> Iterator for Scanner<N> {
|
||||||
}
|
}
|
||||||
let mut c = self.color;
|
let mut c = self.color;
|
||||||
for i in min_led..current_led {
|
for i in min_led..current_led {
|
||||||
strip[i] = c;
|
strip[i] = Some(c);
|
||||||
c = c / 2;
|
c = c / 2;
|
||||||
}
|
}
|
||||||
self.current_iteration += 1;
|
self.current_iteration += 1;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::patterns::{Patterns, PixelColor};
|
use crate::patterns::{Patterns, PixelColor, Pattern};
|
||||||
use crate::Strip;
|
use crate::Strip;
|
||||||
use bluer::Address;
|
use bluer::Address;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -41,27 +41,46 @@ pub struct Context<const N: usize> {
|
||||||
|
|
||||||
pub(crate) type DeviceSequence<const N: usize> = Vec<Context<N>>;
|
pub(crate) type DeviceSequence<const N: usize> = Vec<Context<N>>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub async fn runner_loop<const N: usize>(runner: DeviceSequence<N>, tx: Sender<Strip<N>>) {
|
pub async fn runner_loop<const N: usize>(runner: DeviceSequence<N>, tx: Sender<Strip<N>>) {
|
||||||
|
let mut background = Strip::<N>::default();
|
||||||
for mut context in runner {
|
for mut context in runner {
|
||||||
let mut strip = context.pattern.next().unwrap();
|
let mut strip = context.pattern.init().unwrap_or(background);
|
||||||
let delay = context.period;
|
let delay = context.period;
|
||||||
while tx.send(strip).is_ok() {
|
while tx.send(strip).is_ok() {
|
||||||
if let Some(value) = context.pattern.next() {
|
if let Some(value) = context.pattern.next() {
|
||||||
strip = value;
|
strip = apply_mask(background, value);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tokio::time::sleep(delay).await;
|
tokio::time::sleep(delay).await;
|
||||||
}
|
}
|
||||||
|
background = strip;
|
||||||
|
println!("{:?}", background);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn apply_mask<const N: usize>(previous_strip: Strip<N>, strip: Strip<{ N }>) -> Strip<N> {
|
||||||
|
let mut new_strip = Strip::default();
|
||||||
|
for i in 0..N {
|
||||||
|
if let Some(color) = strip[i] {
|
||||||
|
new_strip[i] = Some(color);
|
||||||
|
} else {
|
||||||
|
new_strip[i] = previous_strip[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_strip
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Spectacle<const N: usize> {
|
pub struct Spectacle<const N: usize> {
|
||||||
runners: HashMap<DeviceSequence<N>, (Sender<Strip<N>>, Receiver<Strip<N>>)>,
|
runners: HashMap<DeviceSequence<N>, (Sender<Strip<N>>, Receiver<Strip<N>>)>,
|
||||||
channels: HashMap<Address, Receiver<Strip<N>>>,
|
channels: HashMap<Address, Receiver<Strip<N>>>,
|
||||||
default_runner: Option<(DeviceSequence<N>, Sender<Strip<N>>)>,
|
default_runner: Option<(DeviceSequence<N>, Sender<Strip<N>>)>,
|
||||||
default_receiver: Option<Receiver<Strip<N>>>,
|
default_receiver: Option<Receiver<Strip<N>>>,
|
||||||
|
// #[serde(skip)]
|
||||||
|
buffered_strip: Strip<N>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> Spectacle<N> {
|
impl<const N: usize> Spectacle<N> {
|
||||||
|
@ -134,6 +153,7 @@ impl<const N: usize> Spectacle<N> {
|
||||||
}
|
}
|
||||||
joinhandles
|
joinhandles
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> From<Config<N>> for Spectacle<N> {
|
impl<const N: usize> From<Config<N>> for Spectacle<N> {
|
||||||
|
@ -159,3 +179,35 @@ impl<const N: usize> From<Config<N>> for Spectacle<N> {
|
||||||
spectacle
|
spectacle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn apply_mask() {
|
||||||
|
let pixel_entry = PixelColor {
|
||||||
|
red: 10,
|
||||||
|
green: 10,
|
||||||
|
blue: 10
|
||||||
|
};
|
||||||
|
|
||||||
|
let pixel_mask = PixelColor {
|
||||||
|
red: 20,
|
||||||
|
green: 20,
|
||||||
|
blue: 20
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut entry = Strip::<5>::new(pixel_entry) ;
|
||||||
|
entry[0] = None;
|
||||||
|
entry[1] = None;
|
||||||
|
|
||||||
|
let mut mask = Strip::<5>::new(pixel_mask) ;
|
||||||
|
mask[0] = None;
|
||||||
|
|
||||||
|
let mut expected = entry.clone();
|
||||||
|
expected[1] = Some(pixel_mask);
|
||||||
|
assert_eq!(expected, super::apply_mask(mask, entry));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user