geometry: rewrite Coordinates trait into a concrete struct, pass coords by reference to shaders, and add a Rectangle type

This commit is contained in:
2024-11-16 11:31:45 +01:00
parent a23b2e8e94
commit e329a56c90
4 changed files with 89 additions and 32 deletions

View File

@ -1,14 +1,72 @@
use std::fmt::{Debug, Formatter};
use std::marker::PhantomData;
pub trait CoordinateSpace {}
pub trait Coordinates<T, S: CoordinateSpace> {
fn x(&self) -> T;
fn y(&self) -> T;
fn new(x: T, y: T) -> Self;
#[derive(PartialEq, Eq, Clone, Copy)]
pub struct Coordinates<T: CoordLimits<Data = T>, S: CoordinateSpace> {
pub x: T,
pub y: T,
space: PhantomData<S>,
}
const MAX: T;
const MIN: T;
impl<T: CoordLimits<Data = T> + Debug, S: CoordinateSpace> Debug for Coordinates<T, S> {
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)]
@ -26,28 +84,27 @@ pub struct Coord8<S: CoordinateSpace> {
space: PhantomData<S>
}
pub type VirtualCoordinates = Coord8<Virtual>;
pub type PhysicalCoordinates = Coord8<Physical>;
pub type VirtualCoordinates = Coordinates<u8, Virtual>;
pub type PhysicalCoordinates = Coordinates<usize, Physical>;
impl<S> Coordinates<u8, S> for Coord8<S>
where
S: CoordinateSpace {
fn new(x: u8, y: u8) -> Self {
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub struct Rectangle<CoordData: CoordLimits<Data = CoordData>, Space: CoordinateSpace> {
pub top_left: Coordinates<CoordData, Space>,
pub bottom_right: Coordinates<CoordData, Space>
}
impl<CoordData: CoordLimits<Data = CoordData>, Space: CoordinateSpace> Rectangle<CoordData, Space> {
pub fn new(top_left: Coordinates<CoordData, Space>, bottom_right: Coordinates<CoordData, Space>) -> Self {
Self {
x: x,
y: y,
space: PhantomData
top_left,
bottom_right
}
}
fn x(&self) -> u8 {
self.x
pub fn everything() -> Self {
Self {
top_left: Coordinates::<CoordData, Space>::top_left(),
bottom_right: Coordinates::<CoordData, Space>::bottom_right()
}
}
fn y(&self) -> u8 {
self.y
}
const MAX: u8 = 255;
const MIN: u8 = 255;
}