diff --git a/src/main.rs b/src/main.rs index e60beb1..29dbfea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,7 +33,6 @@ async fn main() -> bluer::Result<()> { let spectacle = Spectacle::from(config); let spectacle = Arc::new(Mutex::new(spectacle)); - let adapter = bluetooth::create_session().await?; let (tx_scan, rx_scan) = mpsc::channel(3); diff --git a/src/patterns.rs b/src/patterns.rs index 48dcdb2..e85af09 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -1,27 +1,29 @@ -mod scanner; -mod fade; +mod blink; mod color_wipe; -mod rainbow; +mod fade; +mod fade_random; +mod fade_unstable; mod fill_random; mod fill_unstable; -mod blink; mod rain; -mod fade_random; +mod rainbow; +mod scanner; -use serde_derive::{Deserialize, Serialize}; -use std::fmt; -use std::ops::{AddAssign, Div, Index, IndexMut, SubAssign}; -use rand::Rng; -use rand::rngs::ThreadRng; use crate::patterns::blink::Blink; use crate::patterns::color_wipe::ColorWipe; use crate::patterns::fade::Fade; use crate::patterns::fade_random::FadeRandom; +use crate::patterns::fade_unstable::FadeUnstable; use crate::patterns::fill_random::FillRandom; use crate::patterns::fill_unstable::FillUnstable; use crate::patterns::rain::Rain; use crate::patterns::rainbow::Rainbow; use crate::patterns::scanner::Scanner; +use rand::rngs::ThreadRng; +use rand::Rng; +use serde_derive::{Deserialize, Serialize}; +use std::fmt; +use std::ops::{AddAssign, Div, Index, IndexMut, SubAssign}; #[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)] #[serde(tag = "type")] @@ -34,10 +36,11 @@ pub(crate) enum Patterns { FillUnstable(FillUnstable), Blink(Blink), Rain(Rain), - FadeRandom(FadeRandom) + FadeRandom(FadeRandom), + FadeUnstable(FadeUnstable), } -pub trait Pattern : Iterator { +pub trait Pattern: Iterator { type Strip; fn init(&mut self) -> Option; @@ -58,6 +61,7 @@ impl Iterator for Patterns { Patterns::Blink(p) => p.next(), Patterns::Rain(p) => p.next(), Patterns::FadeRandom(p) => p.next(), + Patterns::FadeUnstable(p) => p.next(), } } } @@ -76,6 +80,7 @@ impl Pattern for Patterns { Patterns::Blink(p) => p.init(), Patterns::Rain(p) => p.init(), Patterns::FadeRandom(p) => p.init(), + Patterns::FadeUnstable(p) => p.init(), } } @@ -90,6 +95,7 @@ impl Pattern for Patterns { Patterns::Blink(p) => p.is_last_iteration(), Patterns::Rain(p) => p.is_last_iteration(), Patterns::FadeRandom(p) => p.is_last_iteration(), + Patterns::FadeUnstable(p) => p.is_last_iteration(), } } } @@ -164,11 +170,7 @@ impl PixelColor { green = self.green.saturating_sub(green_delta); blue = self.blue.saturating_sub(blue_delta); } - PixelColor { - red, - green, - blue - } + PixelColor { red, green, blue } } } @@ -210,10 +212,12 @@ impl Strip { } pub fn new(color: PixelColor) -> Strip { - Strip { 0: [Some(color); N] } + Strip { + 0: [Some(color); N], + } } pub fn fill(&mut self, color: PixelColor) { self.0.fill(Some(color)); } -} \ No newline at end of file +} diff --git a/src/patterns/blink.rs b/src/patterns/blink.rs index f6ca981..fdf732b 100644 --- a/src/patterns/blink.rs +++ b/src/patterns/blink.rs @@ -1,7 +1,7 @@ use crate::patterns::fade::Fade; -use crate::Strip; -use serde::{Serialize, Deserialize}; use crate::patterns::Pattern; +use crate::Strip; +use serde::{Deserialize, Serialize}; /// # Blink /// @@ -23,7 +23,7 @@ impl Pattern for Blink { fn is_last_iteration(&self) -> bool { match self.max_iteration { - None => { false } + None => false, Some(max_iter) => { if self.current_iteration >= max_iter { true @@ -43,7 +43,7 @@ impl Iterator for Blink { match value { None => { if self.is_last_iteration() { - return None; + return None; } self.current_iteration += 1; self.fade.current_iteration = 0; @@ -53,4 +53,4 @@ impl Iterator for Blink { Some(value) => Some(value), } } -} \ No newline at end of file +} diff --git a/src/patterns/color_wipe.rs b/src/patterns/color_wipe.rs index a8ff360..05e5e63 100644 --- a/src/patterns/color_wipe.rs +++ b/src/patterns/color_wipe.rs @@ -1,6 +1,6 @@ use crate::patterns::{Pattern, PixelColor}; use crate::Strip; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; /// # Colorwipe pattern /// every pattern implement the iterator trait @@ -33,7 +33,7 @@ impl Pattern for ColorWipe { fn is_last_iteration(&self) -> bool { match self.max_iteration { - None => { false } + None => false, Some(max_iter) => { if self.current_iteration >= max_iter { true @@ -59,12 +59,10 @@ impl Iterator for ColorWipe { } let iteration = self.current_iteration % N; - - for i in 0..iteration { strip[i] = Some(self.color); } self.current_iteration += 1; Some(strip) } -} \ No newline at end of file +} diff --git a/src/patterns/fade.rs b/src/patterns/fade.rs index d660846..ddc8371 100644 --- a/src/patterns/fade.rs +++ b/src/patterns/fade.rs @@ -1,6 +1,6 @@ use crate::patterns::{Pattern, PixelColor}; use crate::Strip; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; /// # fade pattern /// fade from one color to an other diff --git a/src/patterns/fade_random.rs b/src/patterns/fade_random.rs index ca21799..f5bf2c5 100644 --- a/src/patterns/fade_random.rs +++ b/src/patterns/fade_random.rs @@ -1,7 +1,7 @@ use crate::patterns::fade::Fade; -use crate::Strip; -use serde::{Serialize, Deserialize}; use crate::patterns::Pattern; +use crate::Strip; +use serde::{Deserialize, Serialize}; /// # Blink /// @@ -24,7 +24,7 @@ impl Pattern for FadeRandom { fn is_last_iteration(&self) -> bool { match self.max_iteration { - None => { false } + None => false, Some(max_iter) => { if self.current_iteration >= max_iter { true @@ -42,20 +42,19 @@ impl Iterator for FadeRandom { fn next(&mut self) -> Option { let strip = self.fade.next(); match strip { - None => { None } + None => None, Some(mut fade) => { let rng = rand::thread_rng(); for i in 0..N { match fade[i] { - None => { } + None => {} Some(pixel) => { fade[i] = Some(pixel.random_delta(self.stability, &mut rng.clone())) } } - } Some(fade) } } } -} \ No newline at end of file +} diff --git a/src/patterns/fade_unstable.rs b/src/patterns/fade_unstable.rs new file mode 100644 index 0000000..68ec6ba --- /dev/null +++ b/src/patterns/fade_unstable.rs @@ -0,0 +1,54 @@ +use crate::patterns::fade::Fade; +use crate::patterns::Pattern; +use crate::Strip; +use serde::{Deserialize, Serialize}; + +/// # Blink +/// +/// fade from one color to an other then go back several times +#[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)] +pub struct FadeUnstable { + #[serde(default)] + pub(crate) current_iteration: usize, + pub(crate) max_iteration: Option, + pub(crate) stability: usize, + fade: Fade, +} + +impl Pattern for FadeUnstable { + type Strip = Strip; + + fn init(&mut self) -> Option { + None + } + + fn is_last_iteration(&self) -> bool { + match self.max_iteration { + None => false, + Some(max_iter) => { + if self.current_iteration >= max_iter { + true + } else { + false + } + } + } + } +} + +impl Iterator for FadeUnstable { + type Item = Strip; + + fn next(&mut self) -> Option { + let strip = self.fade.next(); + match strip { + None => None, + Some(fade) => { + let mut rng = rand::thread_rng(); + let pixel = fade[0].unwrap().random_delta(self.stability, &mut rng); + + Some(Strip::new(pixel)) + } + } + } +} diff --git a/src/patterns/fill_random.rs b/src/patterns/fill_random.rs index d4ec092..e12ee13 100644 --- a/src/patterns/fill_random.rs +++ b/src/patterns/fill_random.rs @@ -1,6 +1,6 @@ use crate::patterns::{Pattern, PixelColor}; use crate::Strip; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; /// # FillRandom /// @@ -23,7 +23,7 @@ impl Pattern for FillRandom { fn is_last_iteration(&self) -> bool { match self.max_iteration { - None => { false } + None => false, Some(max_iter) => { if self.current_iteration >= max_iter { true @@ -52,4 +52,4 @@ impl Iterator for FillRandom { self.current_iteration += 1; Some(strip) } -} \ No newline at end of file +} diff --git a/src/patterns/fill_unstable.rs b/src/patterns/fill_unstable.rs index efc6599..209b6e1 100644 --- a/src/patterns/fill_unstable.rs +++ b/src/patterns/fill_unstable.rs @@ -1,6 +1,6 @@ use crate::patterns::{Pattern, PixelColor}; use crate::Strip; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; /// # FillUnstable /// @@ -23,7 +23,7 @@ impl Pattern for FillUnstable { fn is_last_iteration(&self) -> bool { match self.max_iteration { - None => { false } + None => false, Some(max_iter) => { if self.current_iteration >= max_iter { true @@ -48,4 +48,4 @@ impl Iterator for FillUnstable { self.current_iteration += 1; Some(Strip::::new(unstable_color)) } -} \ No newline at end of file +} diff --git a/src/patterns/rain.rs b/src/patterns/rain.rs index 990e4ae..973fb4d 100644 --- a/src/patterns/rain.rs +++ b/src/patterns/rain.rs @@ -1,7 +1,7 @@ -use rand::Rng; use crate::patterns::{Pattern, PixelColor}; use crate::Strip; -use serde::{Serialize, Deserialize}; +use rand::Rng; +use serde::{Deserialize, Serialize}; /// # rain pattern /// randomly fall colors from top or bottom. @@ -23,7 +23,7 @@ pub struct Rain { pub(crate) stability: usize, pub(crate) lines: usize, #[serde(skip)] - drops : Strip, + drops: Strip, } impl Pattern for Rain { @@ -40,7 +40,7 @@ impl Pattern for Rain { fn is_last_iteration(&self) -> bool { match self.max_iteration { - None => { false } + None => false, Some(max_iter) => { if self.current_iteration >= max_iter { true @@ -58,17 +58,17 @@ impl Iterator for Rain { fn next(&mut self) -> Option { let mut strip = Strip::::default(); - for i in 0..(N-self.lines) { - strip[i+self.lines] = self.drops[i]; + for i in 0..(N - self.lines) { + strip[i + self.lines] = self.drops[i]; } let mut rng = rand::thread_rng(); for i in 0..self.lines { if rng.gen_bool(self.stability as f64 / 100 as f64) { strip[i] = Some(self.color); } else { - let c = strip[i+self.lines]; + let c = strip[i + self.lines]; if self.background_color != c && c != Some(PixelColor::default()) { - strip[i] = Some(strip[i+self.lines].unwrap()/ 2); + strip[i] = Some(strip[i + self.lines].unwrap() / 2); } else { strip[i] = self.background_color; } @@ -79,4 +79,4 @@ impl Iterator for Rain { self.current_iteration += 1; Some(strip) } -} \ No newline at end of file +} diff --git a/src/patterns/rainbow.rs b/src/patterns/rainbow.rs index 590f9af..fd89b4c 100644 --- a/src/patterns/rainbow.rs +++ b/src/patterns/rainbow.rs @@ -1,6 +1,6 @@ use crate::patterns::{Pattern, PixelColor}; use crate::Strip; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; /// # Rainbow pattern /// @@ -29,7 +29,7 @@ impl Pattern for Rainbow { fn is_last_iteration(&self) -> bool { match self.max_iteration { - None => { false } + None => false, Some(max_iter) => { if self.current_iteration >= max_iter { true @@ -92,4 +92,4 @@ fn wheel(index: u8) -> PixelColor { } } } -} \ No newline at end of file +} diff --git a/src/patterns/scanner.rs b/src/patterns/scanner.rs index bfd2022..00789dc 100644 --- a/src/patterns/scanner.rs +++ b/src/patterns/scanner.rs @@ -1,6 +1,6 @@ use crate::patterns::{Pattern, PixelColor}; use crate::Strip; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; /// # scanner pattern /// color one pixel with a color and leave a train of this color fading to black @@ -18,7 +18,7 @@ pub struct Scanner { pub(crate) max_iteration: Option, } -impl Pattern for Scanner { +impl Pattern for Scanner { type Strip = Strip; fn init(&mut self) -> Option { @@ -31,7 +31,7 @@ impl Pattern for Scanner { fn is_last_iteration(&self) -> bool { match self.max_iteration { - None => { false } + None => false, Some(max_iter) => { if self.current_iteration >= max_iter { true @@ -51,7 +51,7 @@ impl Iterator for Scanner { return None; } - let mut strip : Strip; + let mut strip: Strip; if let Some(color) = self.background_color { strip = Strip::new(color); @@ -74,4 +74,4 @@ impl Iterator for Scanner { self.current_iteration += 1; Some(strip) } -} \ No newline at end of file +} diff --git a/src/runner.rs b/src/runner.rs index 5450d29..a714f2b 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -1,5 +1,5 @@ use crate::config::Config; -use crate::patterns::{Patterns, PixelColor, Pattern}; +use crate::patterns::{Pattern, Patterns, PixelColor}; use crate::Strip; use bluer::Address; use serde::{Deserialize, Serialize}; @@ -10,9 +10,8 @@ use std::time::Duration; use tokio::sync::watch::{Receiver, Sender}; pub(crate) mod period { - use std::time::Duration; use serde::{de::Error as _, Deserialize, Deserializer}; - + use std::time::Duration; /// Custom deserializer for period from millisecond value /// @@ -23,11 +22,12 @@ pub(crate) mod period { /// returns: Result::Error> /// pub fn deserialize<'de, D>(deserializer: D) -> Result - where - D: Deserializer<'de>, + where + D: Deserializer<'de>, { String::deserialize(deserializer)? - .parse::().and_then(|d| Ok(Duration::from_millis(d))) + .parse::() + .and_then(|d| Ok(Duration::from_millis(d))) .map_err(|e| D::Error::custom(format!("{}", e))) } } @@ -35,14 +35,12 @@ pub(crate) mod period { #[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)] pub struct Context { pub(crate) pattern: Patterns, - #[serde(deserialize_with = "period::deserialize")] + #[serde(deserialize_with = "period::deserialize")] pub period: Duration, } pub(crate) type DeviceSequence = Vec>; - - pub async fn runner_loop(runner: DeviceSequence, tx: Sender>) { let mut background = Strip::::default(); for mut context in runner { @@ -151,7 +149,6 @@ impl Spectacle { } joinhandles } - } impl From> for Spectacle { @@ -178,7 +175,6 @@ impl From> for Spectacle { } } - #[cfg(test)] mod tests { use super::*; @@ -188,24 +184,24 @@ mod tests { let pixel_entry = PixelColor { red: 10, green: 10, - blue: 10 + blue: 10, }; let pixel_mask = PixelColor { red: 20, green: 20, - blue: 20 + blue: 20, }; - let mut entry = Strip::<5>::new(pixel_entry) ; + let mut entry = Strip::<5>::new(pixel_entry); entry[0] = None; entry[1] = None; - let mut mask = Strip::<5>::new(pixel_mask) ; + 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)); } -} \ No newline at end of file +}