remove Grid::window(), move Grid::new() to implementations

This commit is contained in:
Vinzenz Schroeter 2024-06-02 13:13:49 +02:00
parent 372582cec6
commit 6d562a4962
3 changed files with 69 additions and 106 deletions

View file

@ -9,6 +9,22 @@ pub struct ByteGrid {
} }
impl ByteGrid { impl ByteGrid {
/// Creates a new `ByteGrid` with the specified dimensions.
///
/// # Arguments
///
/// - width: size in x-direction
/// - height: size in y-direction
///
/// returns: `ByteGrid` initialized to 0.
pub fn new(width: usize, height: usize) -> Self {
Self {
data: vec![0; width * height],
width,
height,
}
}
/// Loads a `ByteGrid` with the specified dimensions from the provided data. /// Loads a `ByteGrid` 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
@ -41,17 +57,6 @@ impl ByteGrid {
} }
impl Grid<u8> for ByteGrid { impl Grid<u8> for ByteGrid {
/// Creates a new `ByteGrid` with the specified dimensions.
///
/// returns: `ByteGrid` initialized to 0.
fn new(width: usize, height: usize) -> Self {
Self {
data: vec![0; width * height],
width,
height,
}
}
/// Sets the value of the cell at the specified position in the `ByteGrid. /// Sets the value of the cell at the specified position in the `ByteGrid.
/// ///
/// # Arguments /// # Arguments
@ -97,17 +102,6 @@ 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 {

View file

@ -1,24 +1,47 @@
/// A two-dimensional grid of `T` /// A two-dimensional grid of `T`
pub trait Grid<T> { pub trait Grid<T> {
#[must_use] /// Sets the value at the specified position
/// Creates a new Grid with the specified dimensions.
/// ///
/// # Arguments /// # Arguments
/// ///
/// - width: size in x-direction /// * `x` and `y`: position of the cell to read
/// - height: size in y-direction
///
/// returns: Grid with all cells initialized to default state.
fn new(width: usize, height: usize) -> Self;
/// Sets the value at the specified position
/// ///
/// returns: the old value /// returns: the old value
///
/// # Panics
///
/// When accessing `x` or `y` out of bounds.
fn set(&mut self, x: usize, y: usize, value: T) -> T; fn set(&mut self, x: usize, y: usize, value: T) -> T;
/// Get the current value at the specified position /// Get the current value at the specified position
///
/// # Arguments
///
/// * `x` and `y`: position of the cell to read
///
/// # Panics
///
/// When accessing `x` or `y` out of bounds.
fn get(&self, x: usize, y: usize) -> T; fn get(&self, x: usize, y: usize) -> T;
/// Get the current value at the specified position if the position is inside of bounds
///
/// # Arguments
///
/// * `x` and `y`: position of the cell to read
///
/// returns: Value at position or None
fn get_optional(&self, x: isize, y: isize) -> Option<T>;
/// Sets the value at the specified position if the position is inside of bounds
///
/// # Arguments
///
/// * `x` and `y`: position of the cell to read
///
/// returns: the old value or None
fn set_optional(&mut self, x: isize, y: isize, value: T) -> Option<T>;
/// Sets all cells in the grid to the specified value /// Sets all cells in the grid to the specified value
fn fill(&mut self, value: T); fn fill(&mut self, value: T);
@ -27,36 +50,4 @@ 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 servicepoint::{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));
/// ```
#[must_use]
fn window(&self, x: usize, y: usize, w: usize, h: usize) -> Self;
} }

View file

@ -9,6 +9,27 @@ pub struct PixelGrid {
} }
impl PixelGrid { impl PixelGrid {
/// Creates a new `PixelGrid` 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.
#[must_use] #[must_use]
pub fn max_sized() -> Self { pub fn max_sized() -> Self {
@ -54,27 +75,6 @@ impl PixelGrid {
} }
impl Grid<bool> for PixelGrid { impl Grid<bool> for PixelGrid {
/// Creates a new `PixelGrid` 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),
}
}
/// Sets the value of the specified position in the `PixelGrid`. /// Sets the value of the specified position in the `PixelGrid`.
/// ///
/// # Arguments /// # Arguments
@ -92,15 +92,6 @@ impl Grid<bool> for PixelGrid {
self.bit_vec.set(x + y * self.width, value) self.bit_vec.set(x + y * self.width, value)
} }
/// Gets the current value at the specified position.
///
/// # Arguments
///
/// * `x` and `y`: position of the cell to read
///
/// # Panics
///
/// When accessing `x` or `y` out of bounds.
fn get(&self, x: usize, y: usize) -> bool { fn get(&self, x: usize, y: usize) -> bool {
self.bit_vec.get(x + y * self.width) self.bit_vec.get(x + y * self.width)
} }
@ -122,19 +113,6 @@ 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 {