add rain pattern
This commit is contained in:
		
							parent
							
								
									ee133379f2
								
							
						
					
					
						commit
						a9abc2e05b
					
				@ -17,17 +17,27 @@
 | 
			
		||||
#              blue: 255
 | 
			
		||||
#          max_iteration: 10
 | 
			
		||||
#        period: 50
 | 
			
		||||
      - pattern:
 | 
			
		||||
          type: Rain
 | 
			
		||||
          color: &blue
 | 
			
		||||
            red: 0
 | 
			
		||||
            green: 0
 | 
			
		||||
            blue: 255
 | 
			
		||||
          background_color: &black
 | 
			
		||||
            red: 0
 | 
			
		||||
            green: 0
 | 
			
		||||
            blue: 0
 | 
			
		||||
          stability: 10
 | 
			
		||||
          lines: 5
 | 
			
		||||
        period: 200
 | 
			
		||||
      - pattern:
 | 
			
		||||
          type: Fade
 | 
			
		||||
          nbr_iterations: 20
 | 
			
		||||
          steps: 20
 | 
			
		||||
          begin_color: &red
 | 
			
		||||
            red: 255
 | 
			
		||||
            green: 0
 | 
			
		||||
            blue: 0
 | 
			
		||||
          end_color: &blue
 | 
			
		||||
            red: 0
 | 
			
		||||
            green: 0
 | 
			
		||||
            blue: 255
 | 
			
		||||
          end_color: *blue
 | 
			
		||||
        period: 200
 | 
			
		||||
      - pattern:
 | 
			
		||||
          type: ColorWipe
 | 
			
		||||
@ -60,6 +70,6 @@
 | 
			
		||||
          max_iteration: 200
 | 
			
		||||
        period: 10
 | 
			
		||||
      - pattern:
 | 
			
		||||
          type: ColorWipe
 | 
			
		||||
          type: Scanner
 | 
			
		||||
          color: *blue
 | 
			
		||||
        period: 100
 | 
			
		||||
@ -15,6 +15,7 @@ use crate::patterns::color_wipe::ColorWipe;
 | 
			
		||||
use crate::patterns::fade::Fade;
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
@ -28,12 +29,14 @@ pub(crate) enum Patterns<const N: usize> {
 | 
			
		||||
    FillRandom(FillRandom<N>),
 | 
			
		||||
    FillUnstable(FillUnstable<N>),
 | 
			
		||||
    Blink(Blink<N>),
 | 
			
		||||
    Rain(Rain<N>),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait Pattern : Iterator {
 | 
			
		||||
    type Strip;
 | 
			
		||||
 | 
			
		||||
    fn init(&self) -> Option<Self::Strip>;
 | 
			
		||||
    fn init(&mut self) -> Option<Self::Strip>;
 | 
			
		||||
    fn is_last_iteration(&self) -> bool;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<const N: usize> Iterator for Patterns<N> {
 | 
			
		||||
@ -48,6 +51,7 @@ impl<const N: usize> Iterator for Patterns<N> {
 | 
			
		||||
            Patterns::FillRandom(p) => p.next(),
 | 
			
		||||
            Patterns::FillUnstable(p) => p.next(),
 | 
			
		||||
            Patterns::Blink(p) => p.next(),
 | 
			
		||||
            Patterns::Rain(p) => p.next(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -55,7 +59,7 @@ 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> {
 | 
			
		||||
    fn init(&mut self) -> Option<Self::Strip> {
 | 
			
		||||
        match self {
 | 
			
		||||
            Patterns::Rainbow(p) => p.init(),
 | 
			
		||||
            Patterns::Fade(p) => p.init(),
 | 
			
		||||
@ -64,6 +68,20 @@ impl<const N: usize> Pattern for Patterns<N> {
 | 
			
		||||
            Patterns::FillRandom(p) => p.init(),
 | 
			
		||||
            Patterns::FillUnstable(p) => p.init(),
 | 
			
		||||
            Patterns::Blink(p) => p.init(),
 | 
			
		||||
            Patterns::Rain(p) => p.init(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn is_last_iteration(&self) -> bool {
 | 
			
		||||
        match self {
 | 
			
		||||
            Patterns::Rainbow(p) => p.is_last_iteration(),
 | 
			
		||||
            Patterns::Fade(p) => p.is_last_iteration(),
 | 
			
		||||
            Patterns::ColorWipe(p) => p.is_last_iteration(),
 | 
			
		||||
            Patterns::Scanner(p) => p.is_last_iteration(),
 | 
			
		||||
            Patterns::FillRandom(p) => p.is_last_iteration(),
 | 
			
		||||
            Patterns::FillUnstable(p) => p.is_last_iteration(),
 | 
			
		||||
            Patterns::Blink(p) => p.is_last_iteration(),
 | 
			
		||||
            Patterns::Rain(p) => p.is_last_iteration(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -17,9 +17,22 @@ pub struct Blink<const N: usize> {
 | 
			
		||||
impl<const N: usize> Pattern for Blink<N> {
 | 
			
		||||
    type Strip = Strip<N>;
 | 
			
		||||
 | 
			
		||||
    fn init(&self) -> Option<Self::Strip> {
 | 
			
		||||
    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 Blink<N> {
 | 
			
		||||
@ -29,12 +42,10 @@ impl<const N: usize> Iterator for Blink<N> {
 | 
			
		||||
        let value = self.fade.next();
 | 
			
		||||
        match value {
 | 
			
		||||
            None => {
 | 
			
		||||
                if let Some(iter_max) = self.max_iteration {
 | 
			
		||||
                    if self.current_iteration >= iter_max {
 | 
			
		||||
                        return None;
 | 
			
		||||
                    }
 | 
			
		||||
                    self.current_iteration += 1;
 | 
			
		||||
                if self.is_last_iteration() {
 | 
			
		||||
                    return  None;
 | 
			
		||||
                }
 | 
			
		||||
                self.current_iteration += 1;
 | 
			
		||||
                self.fade.current_iteration = 0;
 | 
			
		||||
                std::mem::swap(&mut self.fade.begin_color, &mut self.fade.end_color);
 | 
			
		||||
                self.fade.next()
 | 
			
		||||
 | 
			
		||||
@ -23,29 +23,43 @@ pub struct ColorWipe<const N: usize> {
 | 
			
		||||
impl<const N: usize> Pattern for ColorWipe<N> {
 | 
			
		||||
    type Strip = Strip<N>;
 | 
			
		||||
 | 
			
		||||
    fn init(&self) -> Option<Self::Strip> {
 | 
			
		||||
    fn init(&mut self) -> Option<Self::Strip> {
 | 
			
		||||
        if let Some(color) = self.background_color {
 | 
			
		||||
            Some(Strip::<N>::new(color))
 | 
			
		||||
        } else {
 | 
			
		||||
            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 ColorWipe<N> {
 | 
			
		||||
    type Item = Strip<N>;
 | 
			
		||||
 | 
			
		||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
			
		||||
        if self.is_last_iteration() {
 | 
			
		||||
            return None;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let mut strip = Strip::default();
 | 
			
		||||
        if let Some(c) = self.background_color {
 | 
			
		||||
            strip.fill(c);
 | 
			
		||||
        }
 | 
			
		||||
        let iteration = self.current_iteration % N;
 | 
			
		||||
        if let Some(max_iteration) = self.max_iteration {
 | 
			
		||||
            if self.current_iteration >= max_iteration {
 | 
			
		||||
                return None;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        for i in 0..iteration {
 | 
			
		||||
            strip[i] = Some(self.color);
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@ use serde::{Serialize, Deserialize};
 | 
			
		||||
pub struct Fade<const N: usize> {
 | 
			
		||||
    #[serde(default)]
 | 
			
		||||
    pub(crate) current_iteration: usize,
 | 
			
		||||
    pub(crate) nbr_iterations: usize,
 | 
			
		||||
    pub(crate) steps: usize,
 | 
			
		||||
    pub(crate) begin_color: PixelColor,
 | 
			
		||||
    pub(crate) end_color: PixelColor,
 | 
			
		||||
}
 | 
			
		||||
@ -20,9 +20,13 @@ fn fade_value(value_start: u8, value_end: u8, index: usize, nbr_iter: usize) ->
 | 
			
		||||
impl<const N: usize> Pattern for Fade<N> {
 | 
			
		||||
    type Strip = Strip<N>;
 | 
			
		||||
 | 
			
		||||
    fn init(&self) -> Option<Self::Strip> {
 | 
			
		||||
    fn init(&mut self) -> Option<Self::Strip> {
 | 
			
		||||
        None
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn is_last_iteration(&self) -> bool {
 | 
			
		||||
        self.current_iteration >= self.steps
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<const N: usize> Iterator for Fade<N> {
 | 
			
		||||
@ -31,7 +35,7 @@ impl<const N: usize> Iterator for Fade<N> {
 | 
			
		||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
			
		||||
        let mut strip = Strip::default();
 | 
			
		||||
 | 
			
		||||
        if self.current_iteration >= self.nbr_iterations {
 | 
			
		||||
        if self.is_last_iteration() {
 | 
			
		||||
            return None;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -39,19 +43,19 @@ impl<const N: usize> Iterator for Fade<N> {
 | 
			
		||||
            self.begin_color.red,
 | 
			
		||||
            self.end_color.red,
 | 
			
		||||
            self.current_iteration,
 | 
			
		||||
            self.nbr_iterations,
 | 
			
		||||
            self.steps,
 | 
			
		||||
        );
 | 
			
		||||
        let green = fade_value(
 | 
			
		||||
            self.begin_color.green,
 | 
			
		||||
            self.end_color.green,
 | 
			
		||||
            self.current_iteration,
 | 
			
		||||
            self.nbr_iterations,
 | 
			
		||||
            self.steps,
 | 
			
		||||
        );
 | 
			
		||||
        let blue = fade_value(
 | 
			
		||||
            self.begin_color.blue,
 | 
			
		||||
            self.end_color.blue,
 | 
			
		||||
            self.current_iteration,
 | 
			
		||||
            self.nbr_iterations,
 | 
			
		||||
            self.steps,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        let current_color = PixelColor { red, green, blue };
 | 
			
		||||
 | 
			
		||||
@ -11,26 +11,37 @@ pub struct FillRandom<const N: usize> {
 | 
			
		||||
    pub(crate) color: PixelColor,
 | 
			
		||||
    pub(crate) stability: usize,
 | 
			
		||||
    pub(crate) max_iteration: Option<usize>,
 | 
			
		||||
    #[serde(default)]
 | 
			
		||||
    pub(crate) current_iteration: usize,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<const N: usize> Pattern for FillRandom<N> {
 | 
			
		||||
    type Strip = Strip<N>;
 | 
			
		||||
 | 
			
		||||
    fn init(&self) -> Option<Self::Strip> {
 | 
			
		||||
    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 FillRandom<N> {
 | 
			
		||||
    type Item = Strip<N>;
 | 
			
		||||
 | 
			
		||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
			
		||||
        if let Some(iteration) = self.max_iteration {
 | 
			
		||||
            if iteration == 0 {
 | 
			
		||||
                return None;
 | 
			
		||||
            } else {
 | 
			
		||||
                self.max_iteration = Some(iteration - 1);
 | 
			
		||||
            }
 | 
			
		||||
        if self.is_last_iteration() {
 | 
			
		||||
            return None;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let mut strip = Strip::<N>::default();
 | 
			
		||||
@ -55,6 +66,7 @@ impl<const N: usize> Iterator for FillRandom<N> {
 | 
			
		||||
            let c = PixelColor { red, green, blue };
 | 
			
		||||
            strip[i] = Some(c);
 | 
			
		||||
        }
 | 
			
		||||
        self.current_iteration += 1;
 | 
			
		||||
        Some(strip)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -11,26 +11,37 @@ pub struct FillUnstable<const N: usize> {
 | 
			
		||||
    pub(crate) color: PixelColor,
 | 
			
		||||
    pub(crate) stability: usize,
 | 
			
		||||
    pub(crate) max_iteration: Option<usize>,
 | 
			
		||||
    #[serde(default)]
 | 
			
		||||
    pub(crate) current_iteration: usize,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<const N: usize> Pattern for FillUnstable<N> {
 | 
			
		||||
    type Strip = Strip<N>;
 | 
			
		||||
 | 
			
		||||
    fn init(&self) -> Option<Self::Strip> {
 | 
			
		||||
    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 FillUnstable<N> {
 | 
			
		||||
    type Item = Strip<N>;
 | 
			
		||||
 | 
			
		||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
			
		||||
        if let Some(iteration) = self.max_iteration {
 | 
			
		||||
            if iteration == 0 {
 | 
			
		||||
                return None;
 | 
			
		||||
            } else {
 | 
			
		||||
                self.max_iteration = Some(iteration - 1);
 | 
			
		||||
            }
 | 
			
		||||
        if self.is_last_iteration() {
 | 
			
		||||
            return None;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let mut strip = Strip::<N>::default();
 | 
			
		||||
@ -52,6 +63,7 @@ impl<const N: usize> Iterator for FillUnstable<N> {
 | 
			
		||||
            blue = self.color.blue.saturating_sub(blue_delta);
 | 
			
		||||
        }
 | 
			
		||||
        strip.fill(PixelColor { red, green, blue });
 | 
			
		||||
        self.current_iteration += 1;
 | 
			
		||||
        Some(strip)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,47 +1,81 @@
 | 
			
		||||
use crate::patterns::PixelColor;
 | 
			
		||||
use rand::Rng;
 | 
			
		||||
use crate::patterns::{Pattern, 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
 | 
			
		||||
/// # rain pattern
 | 
			
		||||
/// randomly fall colors from top or bottom.
 | 
			
		||||
///
 | 
			
		||||
///
 | 
			
		||||
/// # note
 | 
			
		||||
///
 | 
			
		||||
/// background_color work only for color not set by scanner pattern
 | 
			
		||||
/// `stability` is the probability (between 0 an 1) that any led will light on.
 | 
			
		||||
/// The probability of at least one led light on is `stability*number of lines`
 | 
			
		||||
///
 | 
			
		||||
/// this pattern works only for 5x5 square
 | 
			
		||||
#[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)]
 | 
			
		||||
pub struct Scanner<const N: usize> {
 | 
			
		||||
    #[serde(default)]
 | 
			
		||||
    current_iteration: usize,
 | 
			
		||||
pub struct Rain<const N: usize> {
 | 
			
		||||
    pub(crate) color: PixelColor,
 | 
			
		||||
    pub(crate) background_color: Option<PixelColor>,
 | 
			
		||||
    pub(crate) max_iteration: Option<usize>,
 | 
			
		||||
    #[serde(default)]
 | 
			
		||||
    pub(crate) current_iteration: usize,
 | 
			
		||||
    pub(crate) stability: usize,
 | 
			
		||||
    pub(crate) lines: usize,
 | 
			
		||||
    #[serde(skip)]
 | 
			
		||||
    strip : Strip<N>,
 | 
			
		||||
    drops : Strip<N>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<const N: usize> Iterator for Scanner<N> {
 | 
			
		||||
impl<const N: usize> Pattern for Rain<N> {
 | 
			
		||||
    type Strip = Strip<N>;
 | 
			
		||||
 | 
			
		||||
    fn init(&mut self) -> Option<Self::Strip> {
 | 
			
		||||
        if let Some(color) = self.background_color {
 | 
			
		||||
            self.drops = Strip::<N>::new(color);
 | 
			
		||||
            Some(Strip::<N>::new(color))
 | 
			
		||||
        } else {
 | 
			
		||||
            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 Rain<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;
 | 
			
		||||
        for i in 0..(N-self.lines) {
 | 
			
		||||
            strip[i+self.lines] = self.drops[i];
 | 
			
		||||
        }
 | 
			
		||||
        let mut c = self.color;
 | 
			
		||||
        for i in min_led..current_led {
 | 
			
		||||
            strip[i] = Some(c);
 | 
			
		||||
            c = c / 2;
 | 
			
		||||
        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];
 | 
			
		||||
                if self.background_color != c && c != Some(PixelColor::default()) {
 | 
			
		||||
                    strip[i] = Some(strip[i+self.lines].unwrap()/ 2);
 | 
			
		||||
                } else {
 | 
			
		||||
                    strip[i] = self.background_color;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        self.drops = strip.clone();
 | 
			
		||||
 | 
			
		||||
        self.current_iteration += 1;
 | 
			
		||||
        Some(strip)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -23,19 +23,30 @@ pub struct Rainbow<const N: usize> {
 | 
			
		||||
impl<const N: usize> Pattern for Rainbow<N> {
 | 
			
		||||
    type Strip = Strip<N>;
 | 
			
		||||
 | 
			
		||||
    fn init(&self) -> Option<Self::Strip> {
 | 
			
		||||
    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 Rainbow<N> {
 | 
			
		||||
    type Item = Strip<N>;
 | 
			
		||||
 | 
			
		||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
			
		||||
        if let Some(nbr_iteration) = self.max_iteration {
 | 
			
		||||
            if nbr_iteration == self.current_iteration {
 | 
			
		||||
                return None;
 | 
			
		||||
            }
 | 
			
		||||
        if self.is_last_iteration() {
 | 
			
		||||
            return None;
 | 
			
		||||
        }
 | 
			
		||||
        let mut strip = Strip::default();
 | 
			
		||||
        let step = self.step.unwrap_or(255 / N);
 | 
			
		||||
 | 
			
		||||
@ -14,29 +14,49 @@ pub struct Scanner<const N: usize> {
 | 
			
		||||
    pub(crate) current_iteration: usize,
 | 
			
		||||
    pub(crate) color: PixelColor,
 | 
			
		||||
    pub(crate) background_color: Option<PixelColor>,
 | 
			
		||||
    #[serde(default)]
 | 
			
		||||
    pub(crate) max_iteration: Option<usize>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<const N:usize> Pattern for Scanner<N> {
 | 
			
		||||
    type Strip = Strip<N>;
 | 
			
		||||
 | 
			
		||||
    fn init(&self) -> Option<Self::Strip> {
 | 
			
		||||
    fn init(&mut self) -> Option<Self::Strip> {
 | 
			
		||||
        if let Some(color) = self.background_color {
 | 
			
		||||
            Some(Strip::<N>::new(color))
 | 
			
		||||
        } else {
 | 
			
		||||
            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 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);
 | 
			
		||||
        if self.is_last_iteration() {
 | 
			
		||||
            return None;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let mut strip : Strip<N>;
 | 
			
		||||
 | 
			
		||||
        if let Some(color) = self.background_color {
 | 
			
		||||
            strip = Strip::new(color);
 | 
			
		||||
        } else {
 | 
			
		||||
            strip.fill(PixelColor::default());
 | 
			
		||||
            strip = Strip::default();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let current_led = self.current_iteration % N;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user