1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use crate::strip::EffectIterator;
use crate::utils::{single_hsv_to_srgb, srgbu8_to_hsv};
use palette::{Hsv, Srgb};
pub struct RunningLights {
    colour: Hsv,
    count: usize,
    position: usize,
    reverse: bool,
}

impl RunningLights {
    pub fn new(count: usize, colour: Option<Srgb<u8>>, reverse: bool) -> Self {
        RunningLights {
            colour: match colour {
                Some(colour) => srgbu8_to_hsv(colour),
                None => Hsv::new(0.0, 0.0, 1.0),
            },
            count,
            position: match reverse {
                true => count,
                false => 0,
            },
            reverse,
        }
    }
}

impl EffectIterator for RunningLights {
    fn name(&self) -> &'static str {
        "RunningLights"
    }

    fn next(&mut self) -> Option<Vec<Srgb<u8>>> {
        let mut out = vec![Srgb::<u8>::new(0, 0, 0); self.count];
        for (i, pixel) in out.iter_mut().enumerate() {
            let brightness = (i as f32 + self.position as f32).sin() / 2.0 + 0.5;
            let mut hsv = self.colour;
            hsv.value = brightness;
            *pixel = single_hsv_to_srgb(hsv);
        }
        if self.reverse {
            self.position -= 1;
            if self.position == 0 {
                self.position = self.count;
            }
        } else {
            self.position += 1;
            if self.position >= self.count {
                self.position = 0;
            }
        }

        Some(out)
    }
}