use palette::Hsv; use rgb::RGB8; use crate::time::Periodically; use crate::geometry::{Coordinates, VirtualCoordinates}; use crate::render::{Shader, Surface}; use crate::task::Task; use crate::lib8::IntoRgb8; #[derive(Debug)] pub struct IdleTask { frame: u8, surface: T, updater: Periodically } #[derive(Debug)] struct IdleShader { frame: u8 } impl Shader for IdleShader { fn draw(&self, coords: &VirtualCoordinates) -> RGB8 { Hsv::new_srgb(self.frame.wrapping_add(coords.x).wrapping_add(coords.y), 255, 255).into_rgb8() } } impl IdleTask { pub fn new(surface: T) -> Self { IdleTask { frame: 0, surface: surface, updater: Periodically::new_every_n_ms(16) } } } impl Task for IdleTask { fn start(&mut self) { self.surface.set_shader(Box::new(IdleShader { frame: self.frame })); } fn tick(&mut self) { self.updater.run(|| { self.frame = self.frame.wrapping_add(1); self.surface.set_shader(Box::new(IdleShader { frame: self.frame })); }) } fn stop(&mut self) { self.surface.clear_shader(); } } #[derive(Clone, Copy, Debug)] enum Pattern { Red, Green, Blue, White, RGB, HSV, Outline } impl Pattern { pub fn next(self) -> Pattern { match self { Pattern::Red => Pattern::Green, Pattern::Green => Pattern::Blue, Pattern::Blue => Pattern::White, Pattern::White => Pattern::RGB, Pattern::RGB => Pattern::HSV, Pattern::HSV => Pattern::Outline, Pattern::Outline => Pattern::Red } } } #[derive(Debug)] struct TestShader { pattern: Pattern } impl Shader for TestShader { fn draw(&self, coords: &VirtualCoordinates) -> RGB8 { match self.pattern { Pattern::Red => RGB8::new(255, 0, 0), Pattern::Green => RGB8::new(0, 255, 0), Pattern::Blue => RGB8::new(0, 0, 255), Pattern::White => RGB8::new(255, 255, 255), Pattern::RGB => RGB8::new(coords.x, coords.y, 255 - (coords.x / 2 + coords.y / 2)), Pattern::HSV => Hsv::new_srgb(coords.x, coords.y, 255 - (coords.x / 2 + coords.y / 2)).into_rgb8(), Pattern::Outline => match (coords.x, coords.y) { (0, 0) => RGB8::new(255, 255, 255), (0, _) => RGB8::new(255, 0, 0), (_, 0) => RGB8::new(0, 255, 0), _ => RGB8::new(0, 0, 0) } } } } #[derive(Debug)] pub struct TestPattern { surface: T, updater: Periodically, pattern: Pattern } impl TestPattern { pub fn new(surface: T) -> Self { TestPattern { surface, updater: Periodically::new_every_n_seconds(10), pattern: Pattern::Red } } } impl Task for TestPattern { fn start(&mut self) { self.surface.set_shader(Box::new(TestShader { pattern: self.pattern })); } fn tick(&mut self) { self.updater.run(|| { self.pattern = self.pattern.next(); log::info!("Test pattern: {:?}", self.pattern); self.surface.set_shader(Box::new(TestShader { pattern: self.pattern })); }) } fn stop(&mut self) { self.surface.clear_shader(); } }