add fade_random pattern
This commit is contained in:
		
							parent
							
								
									a9abc2e05b
								
							
						
					
					
						commit
						ae215ce252
					
				@ -25,7 +25,7 @@
 | 
				
			|||||||
            blue: 255
 | 
					            blue: 255
 | 
				
			||||||
          background_color: &black
 | 
					          background_color: &black
 | 
				
			||||||
            red: 0
 | 
					            red: 0
 | 
				
			||||||
            green: 0
 | 
					            green: 255
 | 
				
			||||||
            blue: 0
 | 
					            blue: 0
 | 
				
			||||||
          stability: 10
 | 
					          stability: 10
 | 
				
			||||||
          lines: 5
 | 
					          lines: 5
 | 
				
			||||||
@ -54,17 +54,18 @@
 | 
				
			|||||||
        period: 80
 | 
					        period: 80
 | 
				
			||||||
  - name: titi
 | 
					  - name: titi
 | 
				
			||||||
    sequence:
 | 
					    sequence:
 | 
				
			||||||
#      - pattern:
 | 
					      - pattern:
 | 
				
			||||||
#          type: Blink
 | 
					          type: FadeRandom
 | 
				
			||||||
#          fade :
 | 
					          fade :
 | 
				
			||||||
#            nbr_iterations: 20
 | 
					            steps: 50
 | 
				
			||||||
#            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
 | 
					          stability : 30
 | 
				
			||||||
#        period: 50
 | 
					          max_iteration : 50
 | 
				
			||||||
 | 
					        period: 100
 | 
				
			||||||
      - pattern:
 | 
					      - pattern:
 | 
				
			||||||
          type: Rainbow
 | 
					          type: Rainbow
 | 
				
			||||||
          max_iteration: 200
 | 
					          max_iteration: 200
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,6 @@ use clap::Parser;
 | 
				
			|||||||
use patterns::Strip;
 | 
					use patterns::Strip;
 | 
				
			||||||
use std::path::Path;
 | 
					use std::path::Path;
 | 
				
			||||||
use std::sync::{Arc, Mutex};
 | 
					use std::sync::{Arc, Mutex};
 | 
				
			||||||
use std::time::Duration;
 | 
					 | 
				
			||||||
use tokio::sync::mpsc;
 | 
					use tokio::sync::mpsc;
 | 
				
			||||||
use tokio::sync::watch;
 | 
					use tokio::sync::watch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -6,13 +6,17 @@ mod fill_random;
 | 
				
			|||||||
mod fill_unstable;
 | 
					mod fill_unstable;
 | 
				
			||||||
mod blink;
 | 
					mod blink;
 | 
				
			||||||
mod rain;
 | 
					mod rain;
 | 
				
			||||||
 | 
					mod fade_random;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use serde_derive::{Deserialize, Serialize};
 | 
					use serde_derive::{Deserialize, Serialize};
 | 
				
			||||||
use std::fmt;
 | 
					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::blink::Blink;
 | 
				
			||||||
use crate::patterns::color_wipe::ColorWipe;
 | 
					use crate::patterns::color_wipe::ColorWipe;
 | 
				
			||||||
use crate::patterns::fade::Fade;
 | 
					use crate::patterns::fade::Fade;
 | 
				
			||||||
 | 
					use crate::patterns::fade_random::FadeRandom;
 | 
				
			||||||
use crate::patterns::fill_random::FillRandom;
 | 
					use crate::patterns::fill_random::FillRandom;
 | 
				
			||||||
use crate::patterns::fill_unstable::FillUnstable;
 | 
					use crate::patterns::fill_unstable::FillUnstable;
 | 
				
			||||||
use crate::patterns::rain::Rain;
 | 
					use crate::patterns::rain::Rain;
 | 
				
			||||||
@ -30,6 +34,7 @@ pub(crate) enum Patterns<const N: usize> {
 | 
				
			|||||||
    FillUnstable(FillUnstable<N>),
 | 
					    FillUnstable(FillUnstable<N>),
 | 
				
			||||||
    Blink(Blink<N>),
 | 
					    Blink(Blink<N>),
 | 
				
			||||||
    Rain(Rain<N>),
 | 
					    Rain(Rain<N>),
 | 
				
			||||||
 | 
					    FadeRandom(FadeRandom<N>)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub trait Pattern : Iterator {
 | 
					pub trait Pattern : Iterator {
 | 
				
			||||||
@ -52,6 +57,7 @@ impl<const N: usize> Iterator for Patterns<N> {
 | 
				
			|||||||
            Patterns::FillUnstable(p) => p.next(),
 | 
					            Patterns::FillUnstable(p) => p.next(),
 | 
				
			||||||
            Patterns::Blink(p) => p.next(),
 | 
					            Patterns::Blink(p) => p.next(),
 | 
				
			||||||
            Patterns::Rain(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::FillUnstable(p) => p.init(),
 | 
				
			||||||
            Patterns::Blink(p) => p.init(),
 | 
					            Patterns::Blink(p) => p.init(),
 | 
				
			||||||
            Patterns::Rain(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::FillUnstable(p) => p.is_last_iteration(),
 | 
				
			||||||
            Patterns::Blink(p) => p.is_last_iteration(),
 | 
					            Patterns::Blink(p) => p.is_last_iteration(),
 | 
				
			||||||
            Patterns::Rain(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 {
 | 
					impl SubAssign for PixelColor {
 | 
				
			||||||
    fn sub_assign(&mut self, rhs: Self) {
 | 
					    fn sub_assign(&mut self, rhs: Self) {
 | 
				
			||||||
        println!("self.red {}, red {}", self.red, rhs.red);
 | 
					 | 
				
			||||||
        self.red = self.red.saturating_sub(rhs.red);
 | 
					        self.red = self.red.saturating_sub(rhs.red);
 | 
				
			||||||
        self.green = self.red.saturating_sub(rhs.green);
 | 
					        self.green = self.red.saturating_sub(rhs.green);
 | 
				
			||||||
        self.blue = self.red.saturating_sub(rhs.blue);
 | 
					        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.
 | 
					/// 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::patterns::{Pattern, PixelColor};
 | 
				
			||||||
use crate::Strip;
 | 
					use crate::Strip;
 | 
				
			||||||
use serde::{Serialize, Deserialize};
 | 
					use serde::{Serialize, Deserialize};
 | 
				
			||||||
@ -45,25 +44,9 @@ impl<const N: usize> Iterator for FillRandom<N> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut strip = Strip::<N>::default();
 | 
					        let mut strip = Strip::<N>::default();
 | 
				
			||||||
        let mut rng = rand::thread_rng();
 | 
					        let rng = rand::thread_rng();
 | 
				
			||||||
        for i in 0..N {
 | 
					        for i in 0..N {
 | 
				
			||||||
            let red_delta = rng.gen_range(0..self.stability) as u8;
 | 
					            let c = self.color.random_delta(self.stability, &mut rng.clone());
 | 
				
			||||||
            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 };
 | 
					 | 
				
			||||||
            strip[i] = Some(c);
 | 
					            strip[i] = Some(c);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        self.current_iteration += 1;
 | 
					        self.current_iteration += 1;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,3 @@
 | 
				
			|||||||
use rand::Rng;
 | 
					 | 
				
			||||||
use crate::patterns::{Pattern, PixelColor};
 | 
					use crate::patterns::{Pattern, PixelColor};
 | 
				
			||||||
use crate::Strip;
 | 
					use crate::Strip;
 | 
				
			||||||
use serde::{Serialize, Deserialize};
 | 
					use serde::{Serialize, Deserialize};
 | 
				
			||||||
@ -44,26 +43,9 @@ impl<const N: usize> Iterator for FillUnstable<N> {
 | 
				
			|||||||
            return None;
 | 
					            return None;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut strip = Strip::<N>::default();
 | 
					 | 
				
			||||||
        let mut rng = rand::thread_rng();
 | 
					        let mut rng = rand::thread_rng();
 | 
				
			||||||
        let red_delta = rng.gen_range(0..self.stability) as u8;
 | 
					        let unstable_color = self.color.random_delta(self.stability, &mut rng);
 | 
				
			||||||
        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 });
 | 
					 | 
				
			||||||
        self.current_iteration += 1;
 | 
					        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>>>,
 | 
					    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> {
 | 
				
			||||||
@ -109,14 +107,14 @@ impl<const N: usize> Spectacle<N> {
 | 
				
			|||||||
        self.default_receiver = Some(rx);
 | 
					        self.default_receiver = Some(rx);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn nbr_tasks(&self) -> usize {
 | 
					    // pub fn nbr_tasks(&self) -> usize {
 | 
				
			||||||
        let mut nbr = 0;
 | 
					    //     let mut nbr = 0;
 | 
				
			||||||
        if self.default_receiver.is_some() {
 | 
					    //     if self.default_receiver.is_some() {
 | 
				
			||||||
            nbr += 1;
 | 
					    //         nbr += 1;
 | 
				
			||||||
        }
 | 
					    //     }
 | 
				
			||||||
        nbr += self.runners.len();
 | 
					    //     nbr += self.runners.len();
 | 
				
			||||||
        nbr
 | 
					    //     nbr
 | 
				
			||||||
    }
 | 
					    // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn get_channel(&self, mac_address: &Address) -> Option<Receiver<Strip<N>>> {
 | 
					    pub fn get_channel(&self, mac_address: &Address) -> Option<Receiver<Strip<N>>> {
 | 
				
			||||||
        let channel = self.channels.get(mac_address);
 | 
					        let channel = self.channels.get(mac_address);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user