mirror of
https://github.com/cccb/servicepoint.git
synced 2025-01-18 18:10:14 +01:00
move more grid functionality into trait
This commit is contained in:
parent
79e963d045
commit
8adf563320
|
@ -9,17 +9,6 @@ pub struct ByteGrid {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ByteGrid {
|
impl ByteGrid {
|
||||||
/// Creates a new byte grid with the specified dimensions.
|
|
||||||
///
|
|
||||||
/// returns: ByteGrid initialized to 0.
|
|
||||||
pub fn new(width: usize, height: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
data: vec![0; width * height],
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Loads a byte grid with the specified dimensions from the provided data.
|
/// Loads a byte grid with the specified dimensions from the provided data.
|
||||||
///
|
///
|
||||||
/// returns: ByteGrid that contains a copy of the provided data
|
/// returns: ByteGrid that contains a copy of the provided data
|
||||||
|
@ -47,6 +36,17 @@ impl ByteGrid {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Grid<u8> for ByteGrid {
|
impl Grid<u8> for ByteGrid {
|
||||||
|
/// Creates a new byte grid with the specified dimensions.
|
||||||
|
///
|
||||||
|
/// returns: ByteGrid initialized to 0.
|
||||||
|
fn new(width: usize, height: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
data: vec![0; width * height],
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn set(&mut self, x: usize, y: usize, value: u8) -> u8 {
|
fn set(&mut self, x: usize, y: usize, value: u8) -> u8 {
|
||||||
self.check_indexes(x, y);
|
self.check_indexes(x, y);
|
||||||
let pos = &mut self.data[x + y * self.width];
|
let pos = &mut self.data[x + y * self.width];
|
||||||
|
@ -71,6 +71,17 @@ impl Grid<u8> for ByteGrid {
|
||||||
fn height(&self) -> usize {
|
fn height(&self) -> usize {
|
||||||
self.height
|
self.height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn window(&self, x: usize, y: usize, w: usize, h: usize) -> Self {
|
||||||
|
let mut win = Self::new(w, h);
|
||||||
|
for win_x in 0..w {
|
||||||
|
for win_y in 0..h {
|
||||||
|
let value = self.get(x + win_x, y + win_y);
|
||||||
|
win.set(win_x, win_y, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
win
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataRef for ByteGrid {
|
impl DataRef for ByteGrid {
|
||||||
|
|
|
@ -9,6 +9,16 @@ use crate::{
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct Origin(pub u16, pub u16);
|
pub struct Origin(pub u16, pub u16);
|
||||||
|
|
||||||
|
impl std::ops::Add<Origin> for Origin {
|
||||||
|
type Output = Origin;
|
||||||
|
|
||||||
|
fn add(self, rhs: Origin) -> Self::Output {
|
||||||
|
let Origin(x1, y1) = self;
|
||||||
|
let Origin(x2, y2) = rhs;
|
||||||
|
Origin(x1 + x2, y1 + y2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Size defines the width and height of a window
|
/// Size defines the width and height of a window
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Size(pub u16, pub u16);
|
pub struct Size(pub u16, pub u16);
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
pub trait Grid<T> {
|
pub trait Grid<T> {
|
||||||
|
fn new(width: usize, height: usize) -> Self;
|
||||||
|
|
||||||
/// Sets the value at the specified position
|
/// Sets the value at the specified position
|
||||||
///
|
///
|
||||||
/// returns: the old value
|
/// returns: the old value
|
||||||
|
@ -15,4 +17,35 @@ pub trait Grid<T> {
|
||||||
|
|
||||||
/// the height in y-direction
|
/// the height in y-direction
|
||||||
fn height(&self) -> usize;
|
fn height(&self) -> usize;
|
||||||
|
|
||||||
|
/// Creates a new instance containing the specified window.
|
||||||
|
///
|
||||||
|
/// Use concrete types to avoid boxing.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `x`: column of the top left cell
|
||||||
|
/// * `y`: row of the top left cell
|
||||||
|
/// * `w`: size of window in x-direction
|
||||||
|
/// * `h`: size of window in y-direction
|
||||||
|
///
|
||||||
|
/// returns: Self
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// To avoid boxing, this example is using the concrete type `ByteGrid`.
|
||||||
|
/// ```
|
||||||
|
/// use servicepoint2::{ByteGrid, Grid};
|
||||||
|
/// fn split(grid: ByteGrid) -> (ByteGrid, ByteGrid) {
|
||||||
|
/// assert!(grid.width() >= 2);
|
||||||
|
/// let split_x = grid.width() / 2;
|
||||||
|
/// let right_w = grid.width() - split_x;
|
||||||
|
///
|
||||||
|
/// let left = grid.window(0, 0, split_x, grid.height());
|
||||||
|
/// let right = grid.window(split_x, 0, right_w, grid.height());
|
||||||
|
/// (left, right)
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let (l, r) = split(ByteGrid::new(9, 5));
|
||||||
|
/// ```
|
||||||
|
fn window(&self, x: usize, y: usize, w: usize, h: usize) -> Self;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,27 +9,6 @@ pub struct PixelGrid {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PixelGrid {
|
impl PixelGrid {
|
||||||
/// Creates a new pixel grid with the specified dimensions.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `width`: size in pixels in x-direction
|
|
||||||
/// * `height`: size in pixels in y-direction
|
|
||||||
///
|
|
||||||
/// returns: PixelGrid initialized to all pixels off
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// - when the width is not dividable by 8
|
|
||||||
pub fn new(width: usize, height: usize) -> Self {
|
|
||||||
assert_eq!(width % 8, 0);
|
|
||||||
Self {
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
bit_vec: BitVec::new(width * height),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new pixel grid with the size of the whole screen.
|
/// Creates a new pixel grid with the size of the whole screen.
|
||||||
pub fn max_sized() -> Self {
|
pub fn max_sized() -> Self {
|
||||||
Self::new(PIXEL_WIDTH as usize, PIXEL_HEIGHT as usize)
|
Self::new(PIXEL_WIDTH as usize, PIXEL_HEIGHT as usize)
|
||||||
|
@ -69,6 +48,27 @@ impl PixelGrid {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Grid<bool> for PixelGrid {
|
impl Grid<bool> for PixelGrid {
|
||||||
|
/// Creates a new pixel grid with the specified dimensions.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `width`: size in pixels in x-direction
|
||||||
|
/// * `height`: size in pixels in y-direction
|
||||||
|
///
|
||||||
|
/// returns: PixelGrid initialized to all pixels off
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// - when the width is not dividable by 8
|
||||||
|
fn new(width: usize, height: usize) -> Self {
|
||||||
|
assert_eq!(width % 8, 0);
|
||||||
|
Self {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
bit_vec: BitVec::new(width * height),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn set(&mut self, x: usize, y: usize, value: bool) -> bool {
|
fn set(&mut self, x: usize, y: usize, value: bool) -> bool {
|
||||||
self.check_indexes(x, y);
|
self.check_indexes(x, y);
|
||||||
self.bit_vec.set(x + y * self.width, value)
|
self.bit_vec.set(x + y * self.width, value)
|
||||||
|
@ -89,6 +89,19 @@ impl Grid<bool> for PixelGrid {
|
||||||
fn height(&self) -> usize {
|
fn height(&self) -> usize {
|
||||||
self.height
|
self.height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn window(&self, x: usize, y: usize, w: usize, h: usize) -> Self {
|
||||||
|
// TODO: how to deduplicate?
|
||||||
|
// this cannot be moved into the trait because there, Self is not Sized
|
||||||
|
let mut win = Self::new(w, h);
|
||||||
|
for win_x in 0..w {
|
||||||
|
for win_y in 0..h {
|
||||||
|
let value = self.get(x + win_x, y + win_y);
|
||||||
|
win.set(win_x, win_y, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
win
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataRef for PixelGrid {
|
impl DataRef for PixelGrid {
|
||||||
|
|
Loading…
Reference in a new issue