move grid functions to trait
This commit is contained in:
		
							parent
							
								
									314bec36f3
								
							
						
					
					
						commit
						bcf040911d
					
				
					 11 changed files with 96 additions and 88 deletions
				
			
		
							
								
								
									
										14
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								README.md
									
										
									
									
									
								
							|  | @ -63,15 +63,13 @@ int main(void) { | |||
| 
 | ||||
|     sp2_PixelGrid *pixels = sp2_pixel_grid_new(sp2_PIXEL_WIDTH, sp2_PIXEL_HEIGHT); | ||||
|     sp2_pixel_grid_fill(pixels, true); | ||||
|      | ||||
|     command = sp2_command_bitmap_linear_win(0, 0, pixels); // pixels get consumed here | ||||
|     if (command == NULL) | ||||
|         return 4; | ||||
|     if (!sp2_connection_send(connection, command)) // command gets consumed here | ||||
|         return 5; | ||||
| 
 | ||||
|     // connection does not get consumed and has to be freed manually | ||||
|     sp2_connection_dealloc(connection);  | ||||
|     sp2_Command *command = sp2_command_bitmap_linear_win(0, 0, pixels, Uncompressed); | ||||
|     sp2_Packet *packet = sp2_packet_from_command(command); | ||||
|     if (!sp2_connection_send(connection, packet)) | ||||
|         return 1; | ||||
| 
 | ||||
|     sp2_connection_dealloc(connection); | ||||
|     return 0; | ||||
| } | ||||
| ``` | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| use clap::Parser; | ||||
| 
 | ||||
| use servicepoint2::{ByteGrid, Command, Connection, Origin}; | ||||
| use servicepoint2::{ByteGrid, Command, Connection, Grid, Origin}; | ||||
| 
 | ||||
| #[derive(Parser, Debug)] | ||||
| struct Cli { | ||||
|  |  | |||
|  | @ -3,9 +3,7 @@ use std::thread; | |||
| use clap::Parser; | ||||
| use rand::{distributions, Rng}; | ||||
| 
 | ||||
| use servicepoint2::{ | ||||
|     Command, CompressionCode, Connection, Origin, PixelGrid, FRAME_PACING, | ||||
| }; | ||||
| use servicepoint2::{Command, CompressionCode, Connection, Origin, PixelGrid, FRAME_PACING, Grid}; | ||||
| 
 | ||||
| #[derive(Parser, Debug)] | ||||
| struct Cli { | ||||
|  |  | |||
|  | @ -2,10 +2,7 @@ use std::thread; | |||
| 
 | ||||
| use clap::Parser; | ||||
| 
 | ||||
| use servicepoint2::{ | ||||
|     Command, CompressionCode, Connection, Origin, PixelGrid, FRAME_PACING, | ||||
|     PIXEL_HEIGHT, PIXEL_WIDTH, | ||||
| }; | ||||
| use servicepoint2::{Command, CompressionCode, Connection, Origin, PixelGrid, FRAME_PACING, PIXEL_HEIGHT, PIXEL_WIDTH, Grid}; | ||||
| 
 | ||||
| #[derive(Parser, Debug)] | ||||
| struct Cli { | ||||
|  |  | |||
|  | @ -4,10 +4,7 @@ use clap::Parser; | |||
| use rand::Rng; | ||||
| 
 | ||||
| use servicepoint2::Command::{BitmapLinearWin, Brightness, CharBrightness}; | ||||
| use servicepoint2::{ | ||||
|     ByteGrid, CompressionCode, Connection, Origin, PixelGrid, TILE_HEIGHT, | ||||
|     TILE_WIDTH, | ||||
| }; | ||||
| use servicepoint2::{ByteGrid, CompressionCode, Connection, Grid, Origin, PixelGrid, TILE_HEIGHT, TILE_WIDTH}; | ||||
| 
 | ||||
| #[derive(Parser, Debug)] | ||||
| struct Cli { | ||||
|  |  | |||
|  | @ -3,10 +3,7 @@ use std::time::Duration; | |||
| 
 | ||||
| use clap::Parser; | ||||
| 
 | ||||
| use servicepoint2::{ | ||||
|     BitVec, Command, CompressionCode, Connection, PixelGrid, FRAME_PACING, | ||||
|     PIXEL_HEIGHT, PIXEL_WIDTH, | ||||
| }; | ||||
| use servicepoint2::{BitVec, Command, CompressionCode, Connection, PixelGrid, FRAME_PACING, PIXEL_HEIGHT, PIXEL_WIDTH, Grid}; | ||||
| 
 | ||||
| #[derive(Parser, Debug)] | ||||
| struct Cli { | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| use crate::Grid; | ||||
| 
 | ||||
| /// A 2D grid of bytes
 | ||||
| #[derive(Debug, Clone, PartialEq)] | ||||
| pub struct ByteGrid { | ||||
|  | @ -34,40 +36,11 @@ impl ByteGrid { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Get the current value at the specified position
 | ||||
|     ///
 | ||||
|     /// returns: current byte value
 | ||||
|     pub fn get(&self, x: usize, y: usize) -> u8 { | ||||
|         self.check_indexes(x, y); | ||||
|         self.data[x + y * self.width] | ||||
|     } | ||||
| 
 | ||||
|     /// Sets the byte value at the specified position
 | ||||
|     pub fn set(&mut self, x: usize, y: usize, value: u8) { | ||||
|         self.check_indexes(x, y); | ||||
|         self.data[x + y * self.width] = value; | ||||
|     } | ||||
| 
 | ||||
|     /// Sets all bytes in the grid to the specified value
 | ||||
|     pub fn fill(&mut self, value: u8) { | ||||
|         self.data.fill(value) | ||||
|     } | ||||
| 
 | ||||
|     /// Get the underlying byte rows
 | ||||
|     pub fn mut_data_ref(&mut self) -> &mut [u8] { | ||||
|         self.data.as_mut_slice() | ||||
|     } | ||||
| 
 | ||||
|     /// the size in x-direction
 | ||||
|     pub fn width(&self) -> usize { | ||||
|         self.width | ||||
|     } | ||||
| 
 | ||||
|     /// the height in y-direction
 | ||||
|     pub fn height(&self) -> usize { | ||||
|         self.height | ||||
|     } | ||||
| 
 | ||||
|     fn check_indexes(&self, x: usize, y: usize) { | ||||
|         if x >= self.width { | ||||
|             panic!("cannot access byte {x}-{y} because x is outside of bounds 0..{}", self.width) | ||||
|  | @ -78,6 +51,34 @@ impl ByteGrid { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Grid<u8> for ByteGrid { | ||||
|     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]; | ||||
|         let old_val = *pos; | ||||
|         *pos = value; | ||||
|         old_val | ||||
|     } | ||||
| 
 | ||||
|     fn get(&self, x: usize, y: usize) -> u8 { | ||||
|         self.check_indexes(x, y); | ||||
|         self.data[x + y * self.width] | ||||
|     } | ||||
| 
 | ||||
|     fn fill(&mut self, value: u8) { | ||||
|         self.data.fill(value) | ||||
|     } | ||||
| 
 | ||||
|     fn width(&self) -> usize { | ||||
|         self.width | ||||
|     } | ||||
| 
 | ||||
|     fn height(&self) -> usize { | ||||
|         self.height | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| impl From<ByteGrid> for Vec<u8> { | ||||
|     /// Turn into the underlying `Vec<u8>` containing the rows of bytes.
 | ||||
|     fn from(value: ByteGrid) -> Self { | ||||
|  | @ -88,6 +89,7 @@ impl From<ByteGrid> for Vec<u8> { | |||
| #[cfg(feature = "c_api")] | ||||
| pub mod c_api { | ||||
|     use crate::{ByteGrid, CByteSlice}; | ||||
|     use crate::grid::Grid; | ||||
| 
 | ||||
|     /// Creates a new `ByteGrid` instance.
 | ||||
|     /// The returned instance has to be freed with `byte_grid_dealloc`.
 | ||||
|  | @ -198,7 +200,7 @@ pub mod c_api { | |||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use crate::ByteGrid; | ||||
|     use crate::{ByteGrid, Grid}; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn fill() { | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| use crate::command_code::CommandCode; | ||||
| use crate::compression::{into_compressed, into_decompressed}; | ||||
| use crate::{ | ||||
|     BitVec, ByteGrid, CompressionCode, Header, Packet, PixelGrid, TILE_SIZE, | ||||
| }; | ||||
| use crate::{BitVec, ByteGrid, CompressionCode, Grid, Header, Packet, PixelGrid, TILE_SIZE}; | ||||
| 
 | ||||
| /// An origin marks the top left position of a window sent to the display.
 | ||||
| #[derive(Debug, Clone, Copy, PartialEq)] | ||||
|  | @ -728,6 +726,7 @@ mod tests { | |||
|             if compression != CompressionCode::Uncompressed { | ||||
|                 assert_eq!(result, Err(TryFromPacketError::DecompressionFailed)) | ||||
|             } else { | ||||
|                 // when not compressing, there is no way to detect corrupted data
 | ||||
|                 assert!(result.is_ok()); | ||||
|             } | ||||
|         } | ||||
|  |  | |||
							
								
								
									
										18
									
								
								servicepoint2/src/grid.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								servicepoint2/src/grid.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| pub trait Grid<T> { | ||||
|     /// Sets the value at the specified position
 | ||||
|     ///
 | ||||
|     /// returns: the old value
 | ||||
|     fn set(&mut self, x: usize, y: usize, value: T) -> T; | ||||
| 
 | ||||
|     /// Get the current value at the specified position
 | ||||
|     fn get(&self, x: usize, y: usize) -> T; | ||||
| 
 | ||||
|     /// Sets all cells in the grid to the specified value
 | ||||
|     fn fill(&mut self, value: T); | ||||
| 
 | ||||
|     /// the size in x-direction
 | ||||
|     fn width(&self) -> usize; | ||||
| 
 | ||||
|     /// the height in y-direction
 | ||||
|     fn height(&self) -> usize; | ||||
| } | ||||
|  | @ -5,6 +5,7 @@ pub use crate::compression_code::CompressionCode; | |||
| pub use crate::connection::Connection; | ||||
| pub use crate::packet::{Header, Packet, Payload}; | ||||
| pub use crate::pixel_grid::PixelGrid; | ||||
| pub use crate::grid::Grid; | ||||
| use std::time::Duration; | ||||
| 
 | ||||
| #[cfg(feature = "c_api")] | ||||
|  | @ -20,17 +21,23 @@ mod compression_code; | |||
| mod connection; | ||||
| mod packet; | ||||
| mod pixel_grid; | ||||
| mod grid; | ||||
| 
 | ||||
| /// size of a single tile in one dimension
 | ||||
| pub const TILE_SIZE: u16 = 8; | ||||
| 
 | ||||
| /// tile count in the x-direction
 | ||||
| pub const TILE_WIDTH: u16 = 56; | ||||
| 
 | ||||
| /// tile count in the y-direction
 | ||||
| pub const TILE_HEIGHT: u16 = 20; | ||||
| 
 | ||||
| /// screen width in pixels
 | ||||
| pub const PIXEL_WIDTH: u16 = TILE_WIDTH * TILE_SIZE; | ||||
| 
 | ||||
| /// screen height in pixels
 | ||||
| pub const PIXEL_HEIGHT: u16 = TILE_HEIGHT * TILE_SIZE; | ||||
| 
 | ||||
| /// pixel count on whole screen
 | ||||
| pub const PIXEL_COUNT: usize = PIXEL_WIDTH as usize * PIXEL_HEIGHT as usize; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| use crate::{BitVec, PIXEL_HEIGHT, PIXEL_WIDTH}; | ||||
| use crate::{BitVec, Grid, PIXEL_HEIGHT, PIXEL_WIDTH}; | ||||
| 
 | ||||
| /// A grid of pixels stored in packed bytes.
 | ||||
| #[derive(Debug, Clone, PartialEq)] | ||||
|  | @ -58,38 +58,10 @@ impl PixelGrid { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Sets the byte value at the specified position
 | ||||
|     pub 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) | ||||
|     } | ||||
| 
 | ||||
|     /// Get the current value at the specified position
 | ||||
|     ///
 | ||||
|     /// returns: current pixel value
 | ||||
|     pub fn get(&self, x: usize, y: usize) -> bool { | ||||
|         self.bit_vec.get(x + y * self.width) | ||||
|     } | ||||
| 
 | ||||
|     /// Sets all pixels in the grid to the specified value
 | ||||
|     pub fn fill(&mut self, value: bool) { | ||||
|         self.bit_vec.fill(value); | ||||
|     } | ||||
| 
 | ||||
|     pub fn mut_data_ref(&mut self) -> &mut [u8] { | ||||
|         self.bit_vec.mut_data_ref() | ||||
|     } | ||||
| 
 | ||||
|     /// the size in x-direction in pixels
 | ||||
|     pub fn width(&self) -> usize { | ||||
|         self.width | ||||
|     } | ||||
| 
 | ||||
|     /// the height in y-direction in pixels
 | ||||
|     pub fn height(&self) -> usize { | ||||
|         self.height | ||||
|     } | ||||
| 
 | ||||
|     fn check_indexes(&self, x: usize, y: usize) { | ||||
|         if x >= self.width { | ||||
|             panic!("cannot access pixel {x}-{y} because x is outside of bounds 0..{}", self.width) | ||||
|  | @ -100,6 +72,29 @@ impl PixelGrid { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Grid<bool> for PixelGrid { | ||||
|     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) | ||||
|     } | ||||
| 
 | ||||
|     fn get(&self, x: usize, y: usize) -> bool { | ||||
|         self.bit_vec.get(x + y * self.width) | ||||
|     } | ||||
| 
 | ||||
|     fn fill(&mut self, value: bool) { | ||||
|         self.bit_vec.fill(value); | ||||
|     } | ||||
| 
 | ||||
|     fn width(&self) -> usize { | ||||
|         self.width | ||||
|     } | ||||
| 
 | ||||
|     fn height(&self) -> usize { | ||||
|         self.height | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<PixelGrid> for Vec<u8> { | ||||
|     /// Turns a `PixelGrid` into the underlying `Vec<u8>`.
 | ||||
|     fn from(value: PixelGrid) -> Self { | ||||
|  | @ -110,7 +105,7 @@ impl From<PixelGrid> for Vec<u8> { | |||
| #[cfg(feature = "c_api")] | ||||
| pub mod c_api { | ||||
|     use crate::c_slice::CByteSlice; | ||||
|     use crate::PixelGrid; | ||||
|     use crate::{Grid, PixelGrid}; | ||||
| 
 | ||||
|     /// Creates a new `PixelGrid` instance.
 | ||||
|     /// The returned instance has to be freed with `pixel_grid_dealloc`.
 | ||||
|  | @ -221,7 +216,7 @@ pub mod c_api { | |||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use crate::PixelGrid; | ||||
|     use crate::{Grid, PixelGrid}; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn fill() { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vinzenz Schroeter
						Vinzenz Schroeter