geometry: rewrite Coordinates trait into a concrete struct, pass coords by reference to shaders, and add a Rectangle type
This commit is contained in:
parent
a23b2e8e94
commit
e329a56c90
@ -21,8 +21,8 @@ struct IdleShader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Shader for IdleShader {
|
impl Shader for IdleShader {
|
||||||
fn draw(&self, coords: VirtualCoordinates) -> RGB8 {
|
fn draw(&self, coords: &VirtualCoordinates) -> RGB8 {
|
||||||
Hsv::new_srgb(self.frame.wrapping_add(coords.x()).wrapping_add(coords.y()), 255, 255).into_rgb8()
|
Hsv::new_srgb(self.frame.wrapping_add(coords.x).wrapping_add(coords.y), 255, 255).into_rgb8()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,15 +84,15 @@ struct TestShader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Shader for TestShader {
|
impl Shader for TestShader {
|
||||||
fn draw(&self, coords: VirtualCoordinates) -> RGB8 {
|
fn draw(&self, coords: &VirtualCoordinates) -> RGB8 {
|
||||||
match self.pattern {
|
match self.pattern {
|
||||||
Pattern::Red => RGB8::new(255, 0, 0),
|
Pattern::Red => RGB8::new(255, 0, 0),
|
||||||
Pattern::Green => RGB8::new(0, 255, 0),
|
Pattern::Green => RGB8::new(0, 255, 0),
|
||||||
Pattern::Blue => RGB8::new(0, 0, 255),
|
Pattern::Blue => RGB8::new(0, 0, 255),
|
||||||
Pattern::White => RGB8::new(255, 255, 255),
|
Pattern::White => RGB8::new(255, 255, 255),
|
||||||
Pattern::RGB => RGB8::new(coords.x(), coords.y(), 255 - (coords.x() / 2 + coords.y() / 2)),
|
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::HSV => Hsv::new_srgb(coords.x, coords.y, 255 - (coords.x / 2 + coords.y / 2)).into_rgb8(),
|
||||||
Pattern::Outline => match (coords.x(), coords.y()) {
|
Pattern::Outline => match (coords.x, coords.y) {
|
||||||
(0, 0) => RGB8::new(255, 255, 255),
|
(0, 0) => RGB8::new(255, 255, 255),
|
||||||
(0, _) => RGB8::new(255, 0, 0),
|
(0, _) => RGB8::new(255, 0, 0),
|
||||||
(_, 0) => RGB8::new(0, 255, 0),
|
(_, 0) => RGB8::new(0, 255, 0),
|
||||||
|
115
src/geometry.rs
115
src/geometry.rs
@ -1,14 +1,72 @@
|
|||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
pub trait CoordinateSpace {}
|
pub trait CoordinateSpace {}
|
||||||
|
|
||||||
pub trait Coordinates<T, S: CoordinateSpace> {
|
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||||
fn x(&self) -> T;
|
pub struct Coordinates<T: CoordLimits<Data = T>, S: CoordinateSpace> {
|
||||||
fn y(&self) -> T;
|
pub x: T,
|
||||||
fn new(x: T, y: T) -> Self;
|
pub y: T,
|
||||||
|
space: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
const MAX: T;
|
impl<T: CoordLimits<Data = T> + Debug, S: CoordinateSpace> Debug for Coordinates<T, S> {
|
||||||
const MIN: T;
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_tuple("@")
|
||||||
|
.field(&self.x)
|
||||||
|
.field(&self.y)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait CoordLimits {
|
||||||
|
type Data: Sized;
|
||||||
|
const MIN: Self::Data;
|
||||||
|
const MAX: Self::Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CoordLimits for u8 {
|
||||||
|
type Data = u8;
|
||||||
|
const MIN: u8 = 0;
|
||||||
|
const MAX: u8 = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CoordLimits for u16 {
|
||||||
|
type Data = u16;
|
||||||
|
const MIN: u16 = u16::MIN;
|
||||||
|
const MAX: u16 = u16::MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CoordLimits for usize {
|
||||||
|
type Data = usize;
|
||||||
|
const MIN: usize = usize::MIN;
|
||||||
|
const MAX: usize = usize::MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: CoordLimits<Data = T>, S: CoordinateSpace> Coordinates<T, S> {
|
||||||
|
pub const fn new(x: T, y: T) -> Self {
|
||||||
|
Self {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
space: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn top_left() -> Self {
|
||||||
|
Self::new(T::MIN, T::MIN)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn top_right() -> Self {
|
||||||
|
Self::new(T::MAX, T::MIN)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bottom_left() -> Self {
|
||||||
|
Self::new(T::MIN, T::MAX)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bottom_right() -> Self {
|
||||||
|
Self::new(T::MAX, T::MAX)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Copy, Clone)]
|
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||||
@ -26,28 +84,27 @@ pub struct Coord8<S: CoordinateSpace> {
|
|||||||
space: PhantomData<S>
|
space: PhantomData<S>
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type VirtualCoordinates = Coord8<Virtual>;
|
pub type VirtualCoordinates = Coordinates<u8, Virtual>;
|
||||||
pub type PhysicalCoordinates = Coord8<Physical>;
|
pub type PhysicalCoordinates = Coordinates<usize, Physical>;
|
||||||
|
|
||||||
impl<S> Coordinates<u8, S> for Coord8<S>
|
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||||
where
|
pub struct Rectangle<CoordData: CoordLimits<Data = CoordData>, Space: CoordinateSpace> {
|
||||||
S: CoordinateSpace {
|
pub top_left: Coordinates<CoordData, Space>,
|
||||||
fn new(x: u8, y: u8) -> Self {
|
pub bottom_right: Coordinates<CoordData, Space>
|
||||||
Self {
|
}
|
||||||
x: x,
|
|
||||||
y: y,
|
impl<CoordData: CoordLimits<Data = CoordData>, Space: CoordinateSpace> Rectangle<CoordData, Space> {
|
||||||
space: PhantomData
|
pub fn new(top_left: Coordinates<CoordData, Space>, bottom_right: Coordinates<CoordData, Space>) -> Self {
|
||||||
}
|
Self {
|
||||||
}
|
top_left,
|
||||||
|
bottom_right
|
||||||
fn x(&self) -> u8 {
|
}
|
||||||
self.x
|
}
|
||||||
}
|
|
||||||
|
pub fn everything() -> Self {
|
||||||
fn y(&self) -> u8 {
|
Self {
|
||||||
self.y
|
top_left: Coordinates::<CoordData, Space>::top_left(),
|
||||||
}
|
bottom_right: Coordinates::<CoordData, Space>::bottom_right()
|
||||||
|
}
|
||||||
const MAX: u8 = 255;
|
}
|
||||||
const MIN: u8 = 255;
|
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ impl<T: SmartLedsWrite<Color = Rgb<u8>>, S: Surface> Display<S> for SmartLedDisp
|
|||||||
let mut pixel = Rgb::new(0, 0, 0);
|
let mut pixel = Rgb::new(0, 0, 0);
|
||||||
for surface in self.surfaces.iter() {
|
for surface in self.surfaces.iter() {
|
||||||
surface.with_shader(|shader| {
|
surface.with_shader(|shader| {
|
||||||
pixel = pixel.saturating_add(shader.draw(virt_coords.clone()));
|
pixel = pixel.saturating_add(shader.draw(&virt_coords));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
self.total_mw += pixel.as_milliwatts();
|
self.total_mw += pixel.as_milliwatts();
|
||||||
|
@ -14,7 +14,7 @@ use std::marker::PhantomData;
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
pub trait Shader: Send + Debug {
|
pub trait Shader: Send + Debug {
|
||||||
fn draw(&self, surface_coords: VirtualCoordinates) -> RGB8;
|
fn draw(&self, surface_coords: &VirtualCoordinates) -> RGB8;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Surface: Default + Clone + Debug {
|
pub trait Surface: Default + Clone + Debug {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user