From bcf040911d3bec31534dd1ffc86eb4ad75a9030e Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 18 May 2024 10:50:35 +0200 Subject: [PATCH] move grid functions to trait --- README.md | 14 +++--- examples/announce/src/main.rs | 2 +- examples/game_of_life/src/main.rs | 4 +- examples/moving_line/src/main.rs | 5 +-- examples/random_brightness/src/main.rs | 5 +-- examples/wiping_clear/src/main.rs | 5 +-- servicepoint2/src/byte_grid.rs | 62 +++++++++++++------------- servicepoint2/src/command.rs | 5 +-- servicepoint2/src/grid.rs | 18 ++++++++ servicepoint2/src/lib.rs | 7 +++ servicepoint2/src/pixel_grid.rs | 57 +++++++++++------------ 11 files changed, 96 insertions(+), 88 deletions(-) create mode 100644 servicepoint2/src/grid.rs diff --git a/README.md b/README.md index 511a9f8..fff4a4d 100644 --- a/README.md +++ b/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; } ``` diff --git a/examples/announce/src/main.rs b/examples/announce/src/main.rs index 9c6be95..7d90b7e 100644 --- a/examples/announce/src/main.rs +++ b/examples/announce/src/main.rs @@ -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 { diff --git a/examples/game_of_life/src/main.rs b/examples/game_of_life/src/main.rs index 1b6c3f8..2a6de30 100644 --- a/examples/game_of_life/src/main.rs +++ b/examples/game_of_life/src/main.rs @@ -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 { diff --git a/examples/moving_line/src/main.rs b/examples/moving_line/src/main.rs index 23e34d4..6c0491f 100644 --- a/examples/moving_line/src/main.rs +++ b/examples/moving_line/src/main.rs @@ -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 { diff --git a/examples/random_brightness/src/main.rs b/examples/random_brightness/src/main.rs index 3235390..af12043 100644 --- a/examples/random_brightness/src/main.rs +++ b/examples/random_brightness/src/main.rs @@ -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 { diff --git a/examples/wiping_clear/src/main.rs b/examples/wiping_clear/src/main.rs index 5c9818e..aa8f3ea 100644 --- a/examples/wiping_clear/src/main.rs +++ b/examples/wiping_clear/src/main.rs @@ -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 { diff --git a/servicepoint2/src/byte_grid.rs b/servicepoint2/src/byte_grid.rs index 0712717..8aa90ec 100644 --- a/servicepoint2/src/byte_grid.rs +++ b/servicepoint2/src/byte_grid.rs @@ -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 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 for Vec { /// Turn into the underlying `Vec` containing the rows of bytes. fn from(value: ByteGrid) -> Self { @@ -88,6 +89,7 @@ impl From for Vec { #[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() { diff --git a/servicepoint2/src/command.rs b/servicepoint2/src/command.rs index 5eb0c59..f40cace 100644 --- a/servicepoint2/src/command.rs +++ b/servicepoint2/src/command.rs @@ -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()); } } diff --git a/servicepoint2/src/grid.rs b/servicepoint2/src/grid.rs new file mode 100644 index 0000000..4140fe2 --- /dev/null +++ b/servicepoint2/src/grid.rs @@ -0,0 +1,18 @@ +pub trait Grid { + /// 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; +} diff --git a/servicepoint2/src/lib.rs b/servicepoint2/src/lib.rs index 8e028e3..049cde5 100644 --- a/servicepoint2/src/lib.rs +++ b/servicepoint2/src/lib.rs @@ -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; diff --git a/servicepoint2/src/pixel_grid.rs b/servicepoint2/src/pixel_grid.rs index 2acbabe..725e2f2 100644 --- a/servicepoint2/src/pixel_grid.rs +++ b/servicepoint2/src/pixel_grid.rs @@ -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 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 for Vec { /// Turns a `PixelGrid` into the underlying `Vec`. fn from(value: PixelGrid) -> Self { @@ -110,7 +105,7 @@ impl From for Vec { #[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() {