mirror of
https://github.com/cccb/servicepoint.git
synced 2025-01-18 10:00:14 +01:00
remove Grid::window(), move Grid::new() to implementations
This commit is contained in:
parent
372582cec6
commit
6d562a4962
|
@ -9,6 +9,22 @@ pub struct 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.
|
||||
///
|
||||
/// returns: `ByteGrid` that contains a copy of the provided data
|
||||
|
@ -41,17 +57,6 @@ impl 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.
|
||||
///
|
||||
/// # Arguments
|
||||
|
@ -97,17 +102,6 @@ impl Grid<u8> for ByteGrid {
|
|||
fn height(&self) -> usize {
|
||||
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 {
|
||||
|
|
|
@ -1,24 +1,47 @@
|
|||
/// A two-dimensional grid of `T`
|
||||
pub trait Grid<T> {
|
||||
#[must_use]
|
||||
/// Creates a new Grid with the specified dimensions.
|
||||
/// Sets the value at the specified position
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - width: size in x-direction
|
||||
/// - 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
|
||||
/// * `x` and `y`: position of the cell to read
|
||||
///
|
||||
/// returns: the old value
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// When accessing `x` or `y` out of bounds.
|
||||
fn set(&mut self, x: usize, y: usize, value: T) -> T;
|
||||
|
||||
/// 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;
|
||||
|
||||
/// 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
|
||||
fn fill(&mut self, value: T);
|
||||
|
||||
|
@ -27,36 +50,4 @@ pub trait Grid<T> {
|
|||
|
||||
/// the height in y-direction
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,27 @@ pub struct 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.
|
||||
#[must_use]
|
||||
pub fn max_sized() -> Self {
|
||||
|
@ -54,27 +75,6 @@ impl 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`.
|
||||
///
|
||||
/// # Arguments
|
||||
|
@ -92,15 +92,6 @@ impl Grid<bool> for PixelGrid {
|
|||
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 {
|
||||
self.bit_vec.get(x + y * self.width)
|
||||
}
|
||||
|
@ -122,19 +113,6 @@ impl Grid<bool> for PixelGrid {
|
|||
fn height(&self) -> usize {
|
||||
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 {
|
||||
|
|
Loading…
Reference in a new issue