diff --git a/spectacle.yml b/spectacle.yml index 64d4c99..f3c016f 100644 --- a/spectacle.yml +++ b/spectacle.yml @@ -25,7 +25,7 @@ blue: 255 background_color: &black red: 0 - green: 0 + green: 255 blue: 0 stability: 10 lines: 5 @@ -54,17 +54,18 @@ period: 80 - name: titi sequence: -# - pattern: -# type: Blink -# fade : -# nbr_iterations: 20 -# begin_color: *black -# end_color: &cyan -# red: 0 -# green: 255 -# blue: 255 -# max_iteration : 10 -# period: 50 + - pattern: + type: FadeRandom + fade : + steps: 50 + begin_color: *black + end_color: &cyan + red: 0 + green: 255 + blue: 255 + stability : 30 + max_iteration : 50 + period: 100 - pattern: type: Rainbow max_iteration: 200 diff --git a/src/main.rs b/src/main.rs index b156f7e..e60beb1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,6 @@ use clap::Parser; use patterns::Strip; use std::path::Path; use std::sync::{Arc, Mutex}; -use std::time::Duration; use tokio::sync::mpsc; use tokio::sync::watch; diff --git a/src/patterns.rs b/src/patterns.rs index 8cb3ba0..48dcdb2 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -6,13 +6,17 @@ mod fill_random; mod fill_unstable; mod blink; mod rain; +mod fade_random; use serde_derive::{Deserialize, Serialize}; use std::fmt; -use std::ops::{Div, Index, IndexMut, SubAssign}; +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::fill_random::FillRandom; use crate::patterns::fill_unstable::FillUnstable; use crate::patterns::rain::Rain; @@ -30,6 +34,7 @@ pub(crate) enum Patterns { FillUnstable(FillUnstable), Blink(Blink), Rain(Rain), + FadeRandom(FadeRandom) } pub trait Pattern : Iterator { @@ -52,6 +57,7 @@ impl Iterator for Patterns { Patterns::FillUnstable(p) => p.next(), Patterns::Blink(p) => p.next(), Patterns::Rain(p) => p.next(), + Patterns::FadeRandom(p) => p.next(), } } } @@ -69,6 +75,7 @@ impl Pattern for Patterns { Patterns::FillUnstable(p) => p.init(), Patterns::Blink(p) => p.init(), Patterns::Rain(p) => p.init(), + Patterns::FadeRandom(p) => p.init(), } } @@ -82,6 +89,7 @@ impl Pattern for Patterns { Patterns::FillUnstable(p) => p.is_last_iteration(), Patterns::Blink(p) => p.is_last_iteration(), Patterns::Rain(p) => p.is_last_iteration(), + Patterns::FadeRandom(p) => p.is_last_iteration(), } } } @@ -115,13 +123,55 @@ impl Div for PixelColor { impl SubAssign for PixelColor { fn sub_assign(&mut self, rhs: Self) { - println!("self.red {}, red {}", self.red, rhs.red); self.red = self.red.saturating_sub(rhs.red); self.green = self.red.saturating_sub(rhs.green); self.blue = self.red.saturating_sub(rhs.blue); } } +impl AddAssign for PixelColor { + fn add_assign(&mut self, rhs: Self) { + self.red = self.red.saturating_add(rhs.red); + self.green = self.red.saturating_add(rhs.green); + self.blue = self.red.saturating_add(rhs.blue); + } +} + +impl PixelColor { + /// apply random delta to pixel and return computed value + /// + /// # Arguments + /// + /// * `pixel`: pixel to apply delta + /// * `stability`: amplitude of delta between 0 and `stability` + /// + /// returns: PixelColor + /// + pub fn random_delta(&self, stability: usize, rng: &mut ThreadRng) -> PixelColor { + let red_delta = rng.gen_range(0..stability) as u8; + let green_delta = rng.gen_range(0..stability) as u8; + let blue_delta = rng.gen_range(0..stability) as u8; + let operation = rng.gen_bool(0.5); + let red; + let green; + let blue; + if operation { + red = self.red.saturating_add(red_delta); + green = self.green.saturating_add(green_delta); + blue = self.blue.saturating_add(blue_delta); + } else { + red = self.red.saturating_sub(red_delta); + green = self.green.saturating_sub(green_delta); + blue = self.blue.saturating_sub(blue_delta); + } + PixelColor { + red, + green, + blue + } + } +} + /// /// a basic newtype based on a fix array size. /// diff --git a/src/patterns/fade_random.rs b/src/patterns/fade_random.rs new file mode 100644 index 0000000..ca21799 --- /dev/null +++ b/src/patterns/fade_random.rs @@ -0,0 +1,61 @@ +use crate::patterns::fade::Fade; +use crate::Strip; +use serde::{Serialize, Deserialize}; +use crate::patterns::Pattern; + +/// # Blink +/// +/// fade from one color to an other then go back several times +#[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)] +pub struct FadeRandom { + #[serde(default)] + pub(crate) current_iteration: usize, + pub(crate) max_iteration: Option, + pub(crate) stability: usize, + fade: Fade, +} + +impl Pattern for FadeRandom { + 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 FadeRandom { + type Item = Strip; + + fn next(&mut self) -> Option { + let strip = self.fade.next(); + match strip { + None => { None } + Some(mut fade) => { + let rng = rand::thread_rng(); + for i in 0..N { + match fade[i] { + 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/fill_random.rs b/src/patterns/fill_random.rs index 727b37a..d4ec092 100644 --- a/src/patterns/fill_random.rs +++ b/src/patterns/fill_random.rs @@ -1,4 +1,3 @@ -use rand::Rng; use crate::patterns::{Pattern, PixelColor}; use crate::Strip; use serde::{Serialize, Deserialize}; @@ -45,25 +44,9 @@ impl Iterator for FillRandom { } let mut strip = Strip::::default(); - let mut rng = rand::thread_rng(); + let rng = rand::thread_rng(); for i in 0..N { - let red_delta = rng.gen_range(0..self.stability) as u8; - let green_delta = rng.gen_range(0..self.stability) as u8; - let blue_delta = rng.gen_range(0..self.stability) as u8; - let operation = rng.gen_bool(0.5); - let red; - let green; - let blue; - if operation { - red = self.color.red.saturating_add(red_delta); - green = self.color.green.saturating_add(green_delta); - blue = self.color.blue.saturating_add(blue_delta); - } else { - red = self.color.red.saturating_sub(red_delta); - green = self.color.green.saturating_sub(green_delta); - blue = self.color.blue.saturating_sub(blue_delta); - } - let c = PixelColor { red, green, blue }; + let c = self.color.random_delta(self.stability, &mut rng.clone()); strip[i] = Some(c); } self.current_iteration += 1; diff --git a/src/patterns/fill_unstable.rs b/src/patterns/fill_unstable.rs index 4a39b4c..efc6599 100644 --- a/src/patterns/fill_unstable.rs +++ b/src/patterns/fill_unstable.rs @@ -1,4 +1,3 @@ -use rand::Rng; use crate::patterns::{Pattern, PixelColor}; use crate::Strip; use serde::{Serialize, Deserialize}; @@ -44,26 +43,9 @@ impl Iterator for FillUnstable { return None; } - let mut strip = Strip::::default(); let mut rng = rand::thread_rng(); - let red_delta = rng.gen_range(0..self.stability) as u8; - let green_delta = rng.gen_range(0..self.stability) as u8; - let blue_delta = rng.gen_range(0..self.stability) as u8; - let operation = rng.gen_bool(0.5); - let red; - let green; - let blue; - if operation { - red = self.color.red.saturating_add(red_delta); - green = self.color.green.saturating_add(green_delta); - blue = self.color.blue.saturating_add(blue_delta); - } else { - red = self.color.red.saturating_sub(red_delta); - green = self.color.green.saturating_sub(green_delta); - blue = self.color.blue.saturating_sub(blue_delta); - } - strip.fill(PixelColor { red, green, blue }); + let unstable_color = self.color.random_delta(self.stability, &mut rng); self.current_iteration += 1; - Some(strip) + Some(Strip::::new(unstable_color)) } } \ No newline at end of file diff --git a/src/runner.rs b/src/runner.rs index 9f39448..5450d29 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -79,8 +79,6 @@ pub struct Spectacle { channels: HashMap>>, default_runner: Option<(DeviceSequence, Sender>)>, default_receiver: Option>>, - // #[serde(skip)] - buffered_strip: Strip, } impl Spectacle { @@ -109,14 +107,14 @@ impl Spectacle { self.default_receiver = Some(rx); } - pub fn nbr_tasks(&self) -> usize { - let mut nbr = 0; - if self.default_receiver.is_some() { - nbr += 1; - } - nbr += self.runners.len(); - nbr - } + // pub fn nbr_tasks(&self) -> usize { + // let mut nbr = 0; + // if self.default_receiver.is_some() { + // nbr += 1; + // } + // nbr += self.runners.len(); + // nbr + // } pub fn get_channel(&self, mac_address: &Address) -> Option>> { let channel = self.channels.get(mac_address);