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
	
	 Vinzenz Schroeter
						Vinzenz Schroeter