geometry: cut down on <> noise with associated types

This commit is contained in:
Victoria Fischer 2024-11-29 00:10:52 +01:00
parent 5488f85792
commit 2f9b99c2b0
5 changed files with 100 additions and 106 deletions

View File

@ -12,7 +12,7 @@ use std::sync::{Arc, Mutex};
#[derive(Debug)] #[derive(Debug)]
pub struct ShaderBinding { pub struct ShaderBinding {
shader: Option<Box<dyn Shader>>, shader: Option<Box<dyn Shader>>,
rect: Rectangle<u8, Virtual>, rect: Rectangle<Virtual>,
opacity: u8 opacity: u8
} }
@ -45,7 +45,7 @@ impl Default for BoundSurface<Rc<RefCell<ShaderBinding>>>{
} }
impl Surface for BoundSurface<Rc<RefCell<ShaderBinding>>> { impl Surface for BoundSurface<Rc<RefCell<ShaderBinding>>> {
fn rect(&self) -> Rectangle<u8, Virtual> { fn rect(&self) -> Rectangle<Virtual> {
self.binding.borrow().rect.clone() self.binding.borrow().rect.clone()
} }
@ -63,7 +63,7 @@ impl Surface for BoundSurface<Rc<RefCell<ShaderBinding>>> {
self.binding.borrow_mut().shader = None; self.binding.borrow_mut().shader = None;
} }
fn set_rect(&mut self, rect: &Rectangle<u8, Virtual>) { fn set_rect(&mut self, rect: &Rectangle<Virtual>) {
self.binding.borrow_mut().rect = rect.clone(); self.binding.borrow_mut().rect = rect.clone();
} }
@ -159,7 +159,7 @@ impl<S: Surface + Default> SurfacePool<S> {
} }
impl<S: Surface + Default> Surfaces<S> for SurfacePool<S> { impl<S: Surface + Default> Surfaces<S> for SurfacePool<S> {
fn new_surface(&mut self, area: &Rectangle<u8, Virtual>) -> Result<S, io::Error> { fn new_surface(&mut self, area: &Rectangle<Virtual>) -> Result<S, io::Error> {
let mut surface = S::default(); let mut surface = S::default();
surface.set_rect(area); surface.set_rect(area);
self.surfaces.push(surface.clone()); self.surfaces.push(surface.clone());

View File

@ -1,19 +1,26 @@
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use std::marker::PhantomData;
use std::ops::{Mul, Sub, Add}; use std::ops::{Mul, Sub, Add};
use num::{One, pow, integer::Roots}; use num::{One, pow, integer::Roots};
use std::cmp::{min, max}; use std::cmp::{min, max};
pub trait CoordinateSpace {} pub trait CoordinateOp: PartialOrd + PartialEq + Sub + Clone + Mul + Copy + One + Add + Eq + Debug where
Self: Sub<Output=Self> {
#[derive(PartialEq, Eq, Clone, Copy, PartialOrd, Ord)] const MIN: Self;
pub struct Coordinates<T: CoordLimits<Data = T>, S: CoordinateSpace> { const MAX: Self;
pub x: T, fn distance(x1: Self, y1: Self, x2: Self, y2: Self) -> Self;
pub y: T,
space: PhantomData<S>,
} }
impl<T: CoordLimits<Data = T> + Debug, S: CoordinateSpace> Debug for Coordinates<T, S> { pub trait CoordinateSpace {
type Data: CoordinateOp;
}
#[derive(PartialEq, Eq, Clone, Copy, PartialOrd, Ord)]
pub struct Coordinates<S: CoordinateSpace> {
pub x: S::Data,
pub y: S::Data,
}
impl<S: CoordinateSpace> Debug for Coordinates<S> where S::Data: Debug {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("@") f.debug_tuple("@")
.field(&self.x) .field(&self.x)
@ -22,16 +29,7 @@ impl<T: CoordLimits<Data = T> + Debug, S: CoordinateSpace> Debug for Coordinates
} }
} }
pub trait CoordLimits: PartialOrd + PartialEq + Sub + Clone + Mul + Copy + One + Add { impl CoordinateOp for u8 {
type Data: CoordLimits;
const MIN: Self::Data;
const MAX: Self::Data;
fn distance(x1: Self, y1: Self, x2: Self, y2: Self) -> Self;
}
impl CoordLimits for u8 {
type Data = u8;
const MIN: u8 = 0; const MIN: u8 = 0;
const MAX: u8 = 255; const MAX: u8 = 255;
@ -41,8 +39,7 @@ impl CoordLimits for u8 {
} }
} }
impl CoordLimits for u16 { impl CoordinateOp for u16 {
type Data = u16;
const MIN: u16 = u16::MIN; const MIN: u16 = u16::MIN;
const MAX: u16 = u16::MAX; const MAX: u16 = u16::MAX;
@ -51,8 +48,7 @@ impl CoordLimits for u16 {
} }
} }
impl CoordLimits for usize { impl CoordinateOp for usize {
type Data = usize;
const MIN: usize = usize::MIN; const MIN: usize = usize::MIN;
const MAX: usize = usize::MAX; const MAX: usize = usize::MAX;
@ -61,57 +57,51 @@ impl CoordLimits for usize {
} }
} }
impl<T: CoordLimits<Data = T>, S: CoordinateSpace> Coordinates<T, S> { impl<S: CoordinateSpace> Coordinates<S> {
pub const fn new(x: T, y: T) -> Self { pub const fn new(x: S::Data, y: S::Data) -> Self {
Self { Self {
x, x,
y, y
space: PhantomData,
} }
} }
fn top_left() -> Self { fn top_left() -> Self {
Self::new(T::MIN, T::MIN) Self::new(S::Data::MIN, S::Data::MIN)
} }
fn top_right() -> Self { fn top_right() -> Self {
Self::new(T::MAX, T::MIN) Self::new(S::Data::MAX, S::Data::MIN)
} }
fn bottom_left() -> Self { fn bottom_left() -> Self {
Self::new(T::MIN, T::MAX) Self::new(S::Data::MIN, S::Data::MAX)
} }
fn bottom_right() -> Self { fn bottom_right() -> Self {
Self::new(T::MAX, T::MAX) Self::new(S::Data::MAX, S::Data::MAX)
} }
pub fn distance_to(&self, other: &Self) -> T { pub fn distance_to(&self, other: &Self) -> S::Data {
T::distance(self.x, other.x, self.y, other.y) S::Data::distance(self.x, other.x, self.y, other.y)
} }
} }
#[derive(PartialEq, Debug, Copy, Clone)] #[derive(PartialEq, Debug, Copy, Clone)]
pub struct Virtual {} pub struct Virtual {}
impl CoordinateSpace for Virtual {} impl CoordinateSpace for Virtual {
type Data = u8;
#[derive(PartialEq, Debug, Copy, Clone)]
pub struct Coord8<S: CoordinateSpace> {
x: u8,
y: u8,
space: PhantomData<S>
} }
pub type VirtualCoordinates = Coordinates<u8, Virtual>; pub type VirtualCoordinates = Coordinates<Virtual>;
#[derive(PartialEq, Eq, Copy, Clone, Debug, PartialOrd)] #[derive(PartialEq, Eq, Copy, Clone, Debug, PartialOrd)]
pub struct Rectangle<CoordData: CoordLimits<Data = CoordData>, Space: CoordinateSpace> { pub struct Rectangle<Space: CoordinateSpace> {
pub top_left: Coordinates<CoordData, Space>, pub top_left: Coordinates<Space>,
pub bottom_right: Coordinates<CoordData, Space> pub bottom_right: Coordinates<Space>
} }
impl<CoordData: CoordLimits<Data = CoordData> + Sub<Output=CoordData>, Space: CoordinateSpace> Rectangle<CoordData, Space> { impl<Space: CoordinateSpace> Rectangle<Space> {
pub fn new(top_left: Coordinates<CoordData, Space>, bottom_right: Coordinates<CoordData, Space>) -> Self { pub fn new(top_left: Coordinates<Space>, bottom_right: Coordinates<Space>) -> Self {
debug_assert!(top_left.x <= bottom_right.x); debug_assert!(top_left.x <= bottom_right.x);
debug_assert!(top_left.y <= bottom_right.y); debug_assert!(top_left.y <= bottom_right.y);
Self { Self {
@ -122,32 +112,32 @@ impl<CoordData: CoordLimits<Data = CoordData> + Sub<Output=CoordData>, Space: Co
pub fn everything() -> Self { pub fn everything() -> Self {
Self { Self {
top_left: Coordinates::<CoordData, Space>::top_left(), top_left: Coordinates::<Space>::top_left(),
bottom_right: Coordinates::<CoordData, Space>::bottom_right() bottom_right: Coordinates::<Space>::bottom_right()
} }
} }
pub fn width(&self) -> CoordData { pub fn width(&self) -> Space::Data {
self.bottom_right.x.clone() - self.top_left.x.clone() self.bottom_right.x.clone() - self.top_left.x.clone()
} }
pub fn height(&self) -> CoordData { pub fn height(&self) -> Space::Data {
self.bottom_right.y.clone() - self.top_left.y.clone() self.bottom_right.y.clone() - self.top_left.y.clone()
} }
pub const fn left(&self) -> CoordData { pub const fn left(&self) -> Space::Data {
self.top_left.x self.top_left.x
} }
pub const fn top(&self) -> CoordData { pub const fn top(&self) -> Space::Data {
self.top_left.y self.top_left.y
} }
pub const fn right (&self) -> CoordData { pub const fn right (&self) -> Space::Data {
self.bottom_right.x self.bottom_right.x
} }
pub const fn bottom(&self) -> CoordData { pub const fn bottom(&self) -> Space::Data {
self.bottom_right.y self.bottom_right.y
} }
} }

View File

@ -7,20 +7,22 @@ use std::fmt::{Formatter, Debug};
use ansi_term::Color; use ansi_term::Color;
use rgb::Rgb; use rgb::Rgb;
pub trait CoordinateView<CoordData: CoordLimits<Data = CoordData>, Space: CoordinateSpace>: Debug { pub trait CoordinateView: Debug {
fn next(&mut self) -> Option<(Coordinates<u8, Virtual>, Coordinates<CoordData, Space>)>; type Space: CoordinateSpace;
fn next(&mut self) -> Option<(Coordinates<Virtual>, Coordinates<Self::Space>)>;
} }
pub trait PixelMapping<CoordData: CoordLimits<Data = CoordData>, Space: CoordinateSpace> { pub trait PixelMapping {
fn select(&self, rect: &Rectangle<u8, Virtual>) -> impl CoordinateView<CoordData, Space>; type Space: CoordinateSpace;
fn to_idx(&self, coords: &Coordinates<CoordData, Space>) -> usize; fn select(&self, rect: &Rectangle<Virtual>) -> impl CoordinateView<Space = Self::Space>;
fn to_idx(&self, coords: &Coordinates<Self::Space>) -> usize;
} }
pub trait DisplayDump<T: PixelMapping<CoordData, Space>, CoordData: CoordLimits<Data = CoordData>, Space: CoordinateSpace> { pub trait DisplayDump<T: PixelMapping> {
fn dump(&self, map: &T); fn dump(&self, map: &T);
} }
impl<const PIXEL_NUM: usize> DisplayDump<LinearPixelMapping, usize, LinearSpace> for [Rgb<u8>; PIXEL_NUM] { impl<const PIXEL_NUM: usize> DisplayDump<LinearPixelMapping> for [Rgb<u8>; PIXEL_NUM] {
fn dump(&self, _map: &LinearPixelMapping) { fn dump(&self, _map: &LinearPixelMapping) {
for ref pixel in self { for ref pixel in self {
print!("{}", Color::RGB(pixel.r, pixel.g, pixel.b).paint("")); print!("{}", Color::RGB(pixel.r, pixel.g, pixel.b).paint(""));
@ -29,7 +31,7 @@ impl<const PIXEL_NUM: usize> DisplayDump<LinearPixelMapping, usize, LinearSpace>
} }
} }
impl<const PIXEL_NUM: usize> DisplayDump<StrideMapping, u8, StrideSpace> for [Rgb<u8>; PIXEL_NUM] { impl<const PIXEL_NUM: usize> DisplayDump<StrideMapping> for [Rgb<u8>; PIXEL_NUM] {
fn dump(&self, map: &StrideMapping) { fn dump(&self, map: &StrideMapping) {
for y in 0..map.stride_count { for y in 0..map.stride_count {
let stride = &map.strides[y]; let stride = &map.strides[y];
@ -55,15 +57,19 @@ impl<const PIXEL_NUM: usize> DisplayDump<StrideMapping, u8, StrideSpace> for [Rg
#[derive(Debug)] #[derive(Debug)]
struct LinearCoordView { struct LinearCoordView {
rect: Rectangle<u8, Virtual>, rect: Rectangle<Virtual>,
idx: usize, idx: usize,
} }
pub struct LinearSpace {} pub struct LinearSpace {}
impl CoordinateSpace for LinearSpace {} impl CoordinateSpace for LinearSpace {
pub type LinearCoords = Coordinates<usize, LinearSpace>; type Data = usize;
}
impl CoordinateView<usize, LinearSpace> for LinearCoordView { pub type LinearCoords = Coordinates<LinearSpace>;
impl CoordinateView for LinearCoordView {
type Space = LinearSpace;
fn next(&mut self) -> Option<(VirtualCoordinates, LinearCoords)> { fn next(&mut self) -> Option<(VirtualCoordinates, LinearCoords)> {
if self.idx as u8 == self.rect.bottom_right.x { if self.idx as u8 == self.rect.bottom_right.x {
None None
@ -88,15 +94,16 @@ impl LinearPixelMapping {
} }
} }
impl PixelMapping<usize, LinearSpace> for LinearPixelMapping { impl PixelMapping for LinearPixelMapping {
fn select(&self, rect: &Rectangle<u8, Virtual>) -> impl CoordinateView<usize, LinearSpace> { type Space = LinearSpace;
fn select(&self, rect: &Rectangle<Virtual>) -> impl CoordinateView<Space = Self::Space> {
LinearCoordView { LinearCoordView {
rect: rect.clone(), rect: rect.clone(),
idx: 0, idx: 0,
} }
} }
fn to_idx(&self, coords: &Coordinates<usize, LinearSpace>) -> usize { fn to_idx(&self, coords: &Coordinates<LinearSpace>) -> usize {
coords.x coords.x
} }
} }
@ -125,7 +132,7 @@ pub struct StrideMapping<const STRIDE_NUM: usize = 24> {
pub strides: [Stride; STRIDE_NUM], pub strides: [Stride; STRIDE_NUM],
pub stride_count: usize, pub stride_count: usize,
pub pixel_count: usize, pub pixel_count: usize,
pub size: Rectangle<usize, StrideSpace> pub size: Rectangle<StrideSpace>
} }
impl<const STRIDE_NUM: usize> StrideMapping<STRIDE_NUM> { impl<const STRIDE_NUM: usize> StrideMapping<STRIDE_NUM> {
@ -183,7 +190,7 @@ impl<const STRIDE_NUM: usize> StrideMapping<STRIDE_NUM> {
let mut strides = [Stride::default(); STRIDE_NUM]; let mut strides = [Stride::default(); STRIDE_NUM];
let stride_count = stride_json.len(); let stride_count = stride_json.len();
let mut physical_idx = 0; let mut physical_idx = 0;
let mut size: Option<Rectangle<usize, StrideSpace>> = None;//Rectangle::new(Coordinates::new(usize::MAX, usize::MAX), Coordinates::new(0, 0)); let mut size: Option<Rectangle<StrideSpace>> = None;//Rectangle::new(Coordinates::new(usize::MAX, usize::MAX), Coordinates::new(0, 0));
for stride_idx in 0..stride_count { for stride_idx in 0..stride_count {
let json_data = stride_json[stride_idx]; let json_data = stride_json[stride_idx];
let x = json_data.0; let x = json_data.0;
@ -230,24 +237,27 @@ impl<const STRIDE_NUM: usize> StrideMapping<STRIDE_NUM> {
} }
} }
impl PixelMapping<u8, StrideSpace> for StrideMapping { impl PixelMapping for StrideMapping {
fn select(&self, rect: &Rectangle<u8, Virtual>) -> impl CoordinateView<u8, StrideSpace> { type Space = StrideSpace;
fn select(&self, rect: &Rectangle<Virtual>) -> impl CoordinateView<Space = StrideSpace> {
StrideView::new(self, rect) StrideView::new(self, rect)
} }
fn to_idx(&self, coords: &Coordinates<u8, StrideSpace>) -> usize { fn to_idx(&self, coords: &Coordinates<StrideSpace>) -> usize {
self.strides[coords.x as usize].pixel_idx_for_offset(coords.y) self.strides[coords.x as usize].pixel_idx_for_offset(coords.y)
} }
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct StrideSpace {} pub struct StrideSpace {}
impl CoordinateSpace for StrideSpace {} impl CoordinateSpace for StrideSpace {
pub type StrideCoords = Coordinates<u8, StrideSpace>; type Data = u8;
}
pub type StrideCoords = Coordinates<StrideSpace>;
struct StrideView<'a> { struct StrideView<'a> {
map: &'a StrideMapping, map: &'a StrideMapping,
range: Rectangle<u8, StrideSpace>, range: Rectangle<StrideSpace>,
cur: StrideCoords, cur: StrideCoords,
step_size: VirtualCoordinates step_size: VirtualCoordinates
} }
@ -262,9 +272,9 @@ impl<'a> Debug for StrideView<'a> {
} }
impl<'a> StrideView<'a> { impl<'a> StrideView<'a> {
fn new(map: &'a StrideMapping, rect: &Rectangle<u8, Virtual>) -> Self { fn new(map: &'a StrideMapping, rect: &Rectangle<Virtual>) -> Self {
// Zero-index shape of the pixel picking area // Zero-index shape of the pixel picking area
let range: Rectangle<u8, StrideSpace> = Rectangle::new( let range: Rectangle<StrideSpace> = Rectangle::new(
Coordinates::new( Coordinates::new(
scale8(map.size.width() as u8, rect.top_left.x) + map.size.left() as u8, scale8(map.size.width() as u8, rect.top_left.x) + map.size.left() as u8,
scale8(map.size.height() as u8, rect.top_left.y) + map.size.top() as u8 scale8(map.size.height() as u8, rect.top_left.y) + map.size.top() as u8
@ -300,7 +310,8 @@ impl<'a> StrideView<'a> {
} }
} }
impl<'a> CoordinateView<u8, StrideSpace> for StrideView<'a> { impl<'a> CoordinateView for StrideView<'a> {
type Space = StrideSpace;
fn next(&mut self) -> Option<(VirtualCoordinates, StrideCoords)> { fn next(&mut self) -> Option<(VirtualCoordinates, StrideCoords)> {
// Keep scanning until we reach the far right of the range // Keep scanning until we reach the far right of the range
while self.cur.x <= self.range.bottom_right.x { while self.cur.x <= self.range.bottom_right.x {

View File

@ -17,13 +17,15 @@ use std::ops::IndexMut;
pub trait HardwarePixel: Send + Sync + Rgb8Blend + Copy + AsMilliwatts + Default + From<Rgb<u8>> + Fract8Ops {} pub trait HardwarePixel: Send + Sync + Rgb8Blend + Copy + AsMilliwatts + Default + From<Rgb<u8>> + Fract8Ops {}
impl<T> HardwarePixel for T where T: Send + Sync + Rgb8Blend + Copy + AsMilliwatts + Default + From<Rgb<u8>> + Fract8Ops {} impl<T> HardwarePixel for T where T: Send + Sync + Rgb8Blend + Copy + AsMilliwatts + Default + From<Rgb<u8>> + Fract8Ops {}
pub trait Pixbuf<T: HardwarePixel>: AsMilliwatts + IndexMut<usize, Output=T> { pub trait Pixbuf: AsMilliwatts + IndexMut<usize, Output=Self::Pixel> {
type Pixel: HardwarePixel;
fn new() -> Self; fn new() -> Self;
fn blank(&mut self); fn blank(&mut self);
fn iter_with_brightness(&self, brightness: u8) -> impl Iterator<Item = T> + Send; fn iter_with_brightness(&self, brightness: u8) -> impl Iterator<Item = Self::Pixel> + Send;
} }
impl<T: HardwarePixel, const PIXEL_NUM: usize> Pixbuf<T> for [T; PIXEL_NUM] { impl<T: HardwarePixel, const PIXEL_NUM: usize> Pixbuf for [T; PIXEL_NUM] {
type Pixel = T;
fn new() -> Self { fn new() -> Self {
[T::default(); PIXEL_NUM] [T::default(); PIXEL_NUM]
} }
@ -37,7 +39,7 @@ impl<T: HardwarePixel, const PIXEL_NUM: usize> Pixbuf<T> for [T; PIXEL_NUM] {
} }
} }
struct SmartLedDisplay<T: FastWrite, S: Surface, P: Pixbuf<T::Color>> { struct SmartLedDisplay<T: FastWrite, S: Surface, P: Pixbuf<Pixel = T::Color>> {
surfaces : Option<SurfacePool<S>>, surfaces : Option<SurfacePool<S>>,
pixmap: StrideMapping, pixmap: StrideMapping,
target: T, target: T,
@ -46,7 +48,7 @@ struct SmartLedDisplay<T: FastWrite, S: Surface, P: Pixbuf<T::Color>> {
frame: usize frame: usize
} }
impl<T: FastWrite, S: Surface, P: Pixbuf<T::Color>> Debug for SmartLedDisplay<T, S, P> { impl<T: FastWrite, S: Surface, P: Pixbuf<Pixel = T::Color>> Debug for SmartLedDisplay<T, S, P> {
fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> { fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> {
f.debug_struct("SmartLedDisplay") f.debug_struct("SmartLedDisplay")
.field("total_mw", &self.pixbuf.as_milliwatts()) .field("total_mw", &self.pixbuf.as_milliwatts())
@ -55,7 +57,7 @@ impl<T: FastWrite, S: Surface, P: Pixbuf<T::Color>> Debug for SmartLedDisplay<T,
} }
} }
impl<T: FastWrite, S: Surface, P: Pixbuf<T::Color>> SmartLedDisplay<T, S, P> { impl<T: FastWrite, S: Surface, P: Pixbuf<Pixel = T::Color>> SmartLedDisplay<T, S, P> {
fn new(target: T, max_mw: u32, pixmap: StrideMapping, pixbuf: P) -> Self { fn new(target: T, max_mw: u32, pixmap: StrideMapping, pixbuf: P) -> Self {
SmartLedDisplay { SmartLedDisplay {
pixbuf, pixbuf,
@ -68,20 +70,11 @@ impl<T: FastWrite, S: Surface, P: Pixbuf<T::Color>> SmartLedDisplay<T, S, P> {
} }
} }
impl<T, S, P> AsMilliwatts for SmartLedDisplay<T, S, P> where
T: FastWrite,
S: Surface,
P: Pixbuf<T::Color> {
fn as_milliwatts(&self) -> u32 {
self.pixbuf.as_milliwatts()
}
}
impl<T, S, P> Surfaces<S> for SmartLedDisplay<T, S, P> where impl<T, S, P> Surfaces<S> for SmartLedDisplay<T, S, P> where
T: FastWrite, T: FastWrite,
S: Surface, S: Surface,
P: Pixbuf<T::Color> { P: Pixbuf<Pixel = T::Color> {
fn new_surface(&mut self, area: &Rectangle<u8, Virtual>) -> Result<S, io::Error> { fn new_surface(&mut self, area: &Rectangle<Virtual>) -> Result<S, io::Error> {
if let Some(ref mut s) = self.surfaces { if let Some(ref mut s) = self.surfaces {
s.new_surface(area) s.new_surface(area)
} else { } else {
@ -93,7 +86,7 @@ P: Pixbuf<T::Color> {
impl<T, S, P> Display<S> for SmartLedDisplay<T, S, P> where impl<T, S, P> Display<S> for SmartLedDisplay<T, S, P> where
T: FastWrite, T: FastWrite,
S: Surface, S: Surface,
P: Pixbuf<T::Color> { P: Pixbuf<Pixel = T::Color> {
fn render_frame(&mut self) { fn render_frame(&mut self) {
let surfaces = self.surfaces.take().unwrap(); let surfaces = self.surfaces.take().unwrap();
for surface in surfaces.iter() { for surface in surfaces.iter() {
@ -126,7 +119,7 @@ trait FastWrite {
impl<T, S, P> Framed for SmartLedDisplay<T, S, P> where impl<T, S, P> Framed for SmartLedDisplay<T, S, P> where
T: FastWrite, T: FastWrite,
S: Surface, S: Surface,
P: Pixbuf<T::Color> { P: Pixbuf<Pixel = T::Color> {
fn start_frame(&mut self) { fn start_frame(&mut self) {
self.pixbuf.blank(); self.pixbuf.blank();

View File

@ -13,7 +13,7 @@ pub trait Shader: Send + Debug {
} }
pub trait Surfaces<T: Surface>: Debug { pub trait Surfaces<T: Surface>: Debug {
fn new_surface(&mut self, area: &Rectangle<u8, Virtual>) -> Result<T, io::Error>; fn new_surface(&mut self, area: &Rectangle<Virtual>) -> Result<T, io::Error>;
} }
pub trait Surface: Default + Clone + Debug { pub trait Surface: Default + Clone + Debug {
@ -21,8 +21,8 @@ pub trait Surface: Default + Clone + Debug {
fn set_shader(&mut self, shader: Box<dyn Shader>); fn set_shader(&mut self, shader: Box<dyn Shader>);
fn clear_shader(&mut self); fn clear_shader(&mut self);
fn rect(&self) -> Rectangle<u8, Virtual>; fn rect(&self) -> Rectangle<Virtual>;
fn set_rect(&mut self, rect: &Rectangle<u8, Virtual>); fn set_rect(&mut self, rect: &Rectangle<Virtual>);
fn opacity(&self) -> u8; fn opacity(&self) -> u8;
fn set_opacity(&mut self, opacity: u8); fn set_opacity(&mut self, opacity: u8);
} }