Next iteration with backoffs, tasks, basic skeleton for events
This commit is contained in:
133
src/display.rs
Normal file
133
src/display.rs
Normal file
@@ -0,0 +1,133 @@
|
||||
use figments::{hardware::{Brightness, Gamma}, mappings::linear::LinearSpace, power::AsMilliwatts, prelude::*, smart_leds::BrightnessWriter};
|
||||
use core::{fmt::Debug, ops::IndexMut};
|
||||
//use std::io::Write;
|
||||
|
||||
//use super::{Output};
|
||||
use figments::hardware::Output;
|
||||
use smart_leds::SmartLedsWriteAsync;
|
||||
|
||||
pub trait LinearPixbuf: Pixbuf + Sample<'static, LinearSpace, Output = Self::Format> + IndexMut<usize, Output = Self::Format> + AsRef<[Self::Format]> {}
|
||||
impl<T> LinearPixbuf for T where T: Pixbuf + Sample<'static, LinearSpace, Output = Self::Format> + IndexMut<usize, Output = Self::Format> + AsRef<[Self::Format]> {}
|
||||
|
||||
pub struct BikeOutput<T: SmartLedsWriteAsync> {
|
||||
pixbuf: [T::Color; 178],
|
||||
writer: BrightnessWriter<T>
|
||||
}
|
||||
|
||||
impl<T: SmartLedsWriteAsync> Debug for BikeOutput<T> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("BikeOutput").field("pixbuf", &core::any::type_name_of_val(&self.pixbuf)).field("writer", &core::any::type_name_of_val(&self.writer)).finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SmartLedsWriteAsync> BikeOutput<T> where T::Color: HardwarePixel + Gamma + Fract8Ops, T::Error: core::fmt::Debug {
|
||||
pub fn new(target: T, max_mw: u32) -> Self {
|
||||
Self {
|
||||
pixbuf: [Default::default(); 178],
|
||||
writer: BrightnessWriter::new(target, max_mw)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SmartLedsWriteAsync> Brightness for BikeOutput<T> where T::Color: HardwarePixel + Gamma + Fract8Ops, T::Error: core::fmt::Debug {
|
||||
fn set_brightness(&mut self, brightness: u8) {
|
||||
self.writer.set_brightness(brightness);
|
||||
}
|
||||
|
||||
fn set_on(&mut self, is_on: bool) {
|
||||
self.writer.set_on(is_on);
|
||||
}
|
||||
|
||||
fn set_gamma(&mut self, gamma: f32) {
|
||||
self.writer.set_gamma(gamma);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: SmartLedsWriteAsync + 'a> Output<'a, BikeSpace> for BikeOutput<T> where T::Color: 'static + HardwarePixel + Gamma + Fract8Ops, [T::Color; 178]: AsMilliwatts + Gamma + Copy, T::Error: core::fmt::Debug {
|
||||
async fn blank(&mut self) -> Result<(), Self::Error> {
|
||||
self.pixbuf.blank();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn commit(&mut self) -> Result<(), Self::Error> {
|
||||
self.writer.write(&self.pixbuf).await
|
||||
}
|
||||
|
||||
type HardwarePixel = T::Color;
|
||||
type Error = T::Error;
|
||||
}
|
||||
|
||||
impl<'a, T: SmartLedsWriteAsync> Sample<'a, BikeSpace> for BikeOutput<T> where T::Color: HardwarePixel + Gamma + Fract8Ops, [T::Color; 178]: AsMilliwatts + 'static {
|
||||
type Output = T::Color;
|
||||
|
||||
fn sample(&mut self, rect: &Rectangle<BikeSpace>) -> impl Iterator<Item = (Coordinates<BikeSpace>, &'a mut Self::Output)> {
|
||||
let bufref = unsafe {
|
||||
&mut *(&mut self.pixbuf as *mut [T::Color; 178])
|
||||
};
|
||||
BikeIter {
|
||||
pixbuf: bufref,
|
||||
cur: rect.top_left,
|
||||
end: rect.bottom_right
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Strip {
|
||||
start: usize,
|
||||
length: usize,
|
||||
}
|
||||
|
||||
const STRIP_MAP: [Strip; 6] = [
|
||||
Strip { start: 0, length: 28 },
|
||||
Strip { start: 28, length: 17 },
|
||||
Strip { start: 45, length: 14 },
|
||||
Strip { start: 59, length: 17 },
|
||||
Strip { start: 76, length: 14 },
|
||||
Strip { start: 90, length: 88 }
|
||||
];
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug)]
|
||||
pub struct BikeSpace {}
|
||||
impl CoordinateSpace for BikeSpace {
|
||||
type Data = usize;
|
||||
}
|
||||
|
||||
pub struct BikeIter<'a, P: LinearPixbuf + Debug> {
|
||||
pixbuf: &'a mut P,
|
||||
cur: Coordinates<BikeSpace>,
|
||||
end: Coordinates<BikeSpace>
|
||||
}
|
||||
|
||||
impl<'a, P: LinearPixbuf + Debug> Debug for BikeIter<'a, P> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("BikeIter").field("cur", &self.cur).field("end", &self.end).finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, P: LinearPixbuf + Debug> Iterator for BikeIter<'a, P> {
|
||||
type Item = (Coordinates<BikeSpace>, &'a mut P::Format);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.cur.y > self.end.y || self.cur.y >= STRIP_MAP.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let this_strip = &STRIP_MAP[self.cur.y];
|
||||
|
||||
let offset = this_strip.start + self.cur.x;
|
||||
let pixel_coords = Coordinates::new(self.cur.x, self.cur.y);
|
||||
|
||||
self.cur.x += 1;
|
||||
|
||||
if self.cur.x >= this_strip.length || self.cur.x > self.end.x {
|
||||
self.cur.x = 0;
|
||||
self.cur.y += 1;
|
||||
}
|
||||
|
||||
let bufref = unsafe {
|
||||
&mut *(self.pixbuf as *mut P)
|
||||
};
|
||||
|
||||
Some((pixel_coords, &mut bufref[offset]))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user