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 {
|
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 {
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue