geometry: cut down on <> noise with associated types
This commit is contained in:
parent
5488f85792
commit
2f9b99c2b0
@ -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());
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user