add fade_random pattern
This commit is contained in:
		
							parent
							
								
									a9abc2e05b
								
							
						
					
					
						commit
						ae215ce252
					
				@ -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
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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<const N: usize> {
 | 
			
		||||
    FillUnstable(FillUnstable<N>),
 | 
			
		||||
    Blink(Blink<N>),
 | 
			
		||||
    Rain(Rain<N>),
 | 
			
		||||
    FadeRandom(FadeRandom<N>)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait Pattern : Iterator {
 | 
			
		||||
@ -52,6 +57,7 @@ impl<const N: usize> Iterator for Patterns<N> {
 | 
			
		||||
            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<const N: usize> Pattern for Patterns<N> {
 | 
			
		||||
            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<const N: usize> Pattern for Patterns<N> {
 | 
			
		||||
            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<u8> 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.
 | 
			
		||||
///
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										61
									
								
								src/patterns/fade_random.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/patterns/fade_random.rs
									
									
									
									
									
										Normal file
									
								
							@ -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<const N: usize> {
 | 
			
		||||
    #[serde(default)]
 | 
			
		||||
    pub(crate) current_iteration: usize,
 | 
			
		||||
    pub(crate) max_iteration: Option<usize>,
 | 
			
		||||
    pub(crate) stability: usize,
 | 
			
		||||
    fade: Fade<N>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<const N: usize> Pattern for FadeRandom<N> {
 | 
			
		||||
    type Strip = Strip<N>;
 | 
			
		||||
 | 
			
		||||
    fn init(&mut self) -> Option<Self::Strip> {
 | 
			
		||||
        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<const N: usize> Iterator for FadeRandom<N> {
 | 
			
		||||
    type Item = Strip<N>;
 | 
			
		||||
 | 
			
		||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
			
		||||
        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)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,4 +1,3 @@
 | 
			
		||||
use rand::Rng;
 | 
			
		||||
use crate::patterns::{Pattern, PixelColor};
 | 
			
		||||
use crate::Strip;
 | 
			
		||||
use serde::{Serialize, Deserialize};
 | 
			
		||||
@ -45,25 +44,9 @@ impl<const N: usize> Iterator for FillRandom<N> {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let mut strip = Strip::<N>::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;
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,3 @@
 | 
			
		||||
use rand::Rng;
 | 
			
		||||
use crate::patterns::{Pattern, PixelColor};
 | 
			
		||||
use crate::Strip;
 | 
			
		||||
use serde::{Serialize, Deserialize};
 | 
			
		||||
@ -44,26 +43,9 @@ impl<const N: usize> Iterator for FillUnstable<N> {
 | 
			
		||||
            return None;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let mut strip = Strip::<N>::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::<N>::new(unstable_color))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -79,8 +79,6 @@ pub struct Spectacle<const N: usize> {
 | 
			
		||||
    channels: HashMap<Address, Receiver<Strip<N>>>,
 | 
			
		||||
    default_runner: Option<(DeviceSequence<N>, Sender<Strip<N>>)>,
 | 
			
		||||
    default_receiver: Option<Receiver<Strip<N>>>,
 | 
			
		||||
    // #[serde(skip)]
 | 
			
		||||
    buffered_strip: Strip<N>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<const N: usize> Spectacle<N> {
 | 
			
		||||
@ -109,14 +107,14 @@ impl<const N: usize> Spectacle<N> {
 | 
			
		||||
        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<Receiver<Strip<N>>> {
 | 
			
		||||
        let channel = self.channels.get(mac_address);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user