use std::rc::Rc; use std::cell::RefCell; use std::sync::{Arc, Mutex}; use palette::blend::{BlendWith, Equations, Parameter, PreAlpha}; use crate::task; use crate::lib8::RGB8; use crate::power; use crate::time::Periodically; use crate::geometry::*; use std::time::Instant; pub trait Shader: Send { fn draw(&self, surface_coords: VirtualCoordinates) -> RGB8; } pub trait Surfaces { fn new_surface(&mut self) -> Surface; } pub trait Display: Surfaces { fn start_frame(&mut self) {} fn end_frame(&mut self) {} fn render_frame(&mut self) {} } impl task::Task for T where T: Display { fn name(&self) -> &'static str { "Renderer" } fn tick(&mut self) { self.start_frame(); self.render_frame(); self.end_frame(); } } struct ShaderBinding { shader: Option>, opacity: u8, } #[derive(Clone)] pub struct Surface { pub binding: Arc> } impl Surface { pub fn new() -> Self { Self { binding: Arc::new(Mutex::new(ShaderBinding { shader: None, opacity: 255, })), } } pub fn with_shader(&self, f: F) { if let Some(ref shader) = self.binding.lock().unwrap().shader { f(shader.as_ref()); } } pub fn set_shader(&mut self, shader: Box) { self.binding.lock().unwrap().shader = Some(shader); } pub fn clear_shader(&mut self) { self.binding.lock().unwrap().shader = None; } pub fn set_opacity(&mut self, opacity: u8) { self.binding.lock().unwrap().opacity = opacity; } }