move more grid functionality into trait
This commit is contained in:
		
							parent
							
								
									79e963d045
								
							
						
					
					
						commit
						8adf563320
					
				
					 4 changed files with 99 additions and 32 deletions
				
			
		| 
						 | 
				
			
			@ -9,17 +9,6 @@ pub struct 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.
 | 
			
		||||
    ///
 | 
			
		||||
    /// returns: ByteGrid that contains a copy of the provided data
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +36,17 @@ impl 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 {
 | 
			
		||||
        self.check_indexes(x, y);
 | 
			
		||||
        let pos = &mut self.data[x + y * self.width];
 | 
			
		||||
| 
						 | 
				
			
			@ -71,6 +71,17 @@ 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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,16 @@ use crate::{
 | 
			
		|||
#[derive(Debug, Clone, Copy, PartialEq)]
 | 
			
		||||
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
 | 
			
		||||
#[derive(Debug, Clone, Copy)]
 | 
			
		||||
pub struct Size(pub u16, pub u16);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,6 @@
 | 
			
		|||
pub trait Grid<T> {
 | 
			
		||||
    fn new(width: usize, height: usize) -> Self;
 | 
			
		||||
 | 
			
		||||
    /// Sets the value at the specified position
 | 
			
		||||
    ///
 | 
			
		||||
    /// returns: the old value
 | 
			
		||||
| 
						 | 
				
			
			@ -15,4 +17,35 @@ 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 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 {
 | 
			
		||||
    /// 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.
 | 
			
		||||
    pub fn max_sized() -> Self {
 | 
			
		||||
        Self::new(PIXEL_WIDTH as usize, PIXEL_HEIGHT as usize)
 | 
			
		||||
| 
						 | 
				
			
			@ -69,6 +48,27 @@ impl 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 {
 | 
			
		||||
        self.check_indexes(x, y);
 | 
			
		||||
        self.bit_vec.set(x + y * self.width, value)
 | 
			
		||||
| 
						 | 
				
			
			@ -89,6 +89,19 @@ 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue