diff --git a/crates/servicepoint/src/byte_grid.rs b/crates/servicepoint/src/byte_grid.rs index d9b515c..bc06534 100644 --- a/crates/servicepoint/src/byte_grid.rs +++ b/crates/servicepoint/src/byte_grid.rs @@ -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 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 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 { diff --git a/crates/servicepoint/src/grid.rs b/crates/servicepoint/src/grid.rs index 1a53f77..b9502f4 100644 --- a/crates/servicepoint/src/grid.rs +++ b/crates/servicepoint/src/grid.rs @@ -1,24 +1,47 @@ /// A two-dimensional grid of `T` pub trait Grid { - #[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; + + /// 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; + /// Sets all cells in the grid to the specified value fn fill(&mut self, value: T); @@ -27,36 +50,4 @@ pub trait Grid { /// 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; } diff --git a/crates/servicepoint/src/pixel_grid.rs b/crates/servicepoint/src/pixel_grid.rs index 2b7ec20..c6d02dd 100644 --- a/crates/servicepoint/src/pixel_grid.rs +++ b/crates/servicepoint/src/pixel_grid.rs @@ -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 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 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 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 {