From d5e08faeb15e74720d51f0e9703c55465e9518ec Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 18 May 2024 11:11:15 +0200 Subject: [PATCH] move data_ref to trait --- examples/game_of_life/src/main.rs | 2 +- examples/moving_line/src/main.rs | 2 +- examples/random_brightness/src/main.rs | 2 +- examples/wiping_clear/src/main.rs | 2 +- servicepoint2/src/bit_vec.rs | 25 +++++++++++------- servicepoint2/src/byte_grid.rs | 27 ++++++++++++------- servicepoint2/src/command.rs | 5 +++- servicepoint2/src/connection.rs | 8 +++--- servicepoint2/src/data_ref.rs | 11 ++++++++ servicepoint2/src/lib.rs | 6 +++-- servicepoint2/src/pixel_grid.rs | 36 +++++++++++++++----------- 11 files changed, 81 insertions(+), 45 deletions(-) create mode 100644 servicepoint2/src/data_ref.rs diff --git a/examples/game_of_life/src/main.rs b/examples/game_of_life/src/main.rs index 2a6de30..40e6901 100644 --- a/examples/game_of_life/src/main.rs +++ b/examples/game_of_life/src/main.rs @@ -3,7 +3,7 @@ use std::thread; use clap::Parser; use rand::{distributions, Rng}; -use servicepoint2::{Command, CompressionCode, Connection, Origin, PixelGrid, FRAME_PACING, Grid}; +use servicepoint2::*; #[derive(Parser, Debug)] struct Cli { diff --git a/examples/moving_line/src/main.rs b/examples/moving_line/src/main.rs index 6c0491f..b571054 100644 --- a/examples/moving_line/src/main.rs +++ b/examples/moving_line/src/main.rs @@ -2,7 +2,7 @@ use std::thread; use clap::Parser; -use servicepoint2::{Command, CompressionCode, Connection, Origin, PixelGrid, FRAME_PACING, PIXEL_HEIGHT, PIXEL_WIDTH, Grid}; +use servicepoint2::*; #[derive(Parser, Debug)] struct Cli { diff --git a/examples/random_brightness/src/main.rs b/examples/random_brightness/src/main.rs index af12043..d44b086 100644 --- a/examples/random_brightness/src/main.rs +++ b/examples/random_brightness/src/main.rs @@ -4,7 +4,7 @@ use clap::Parser; use rand::Rng; use servicepoint2::Command::{BitmapLinearWin, Brightness, CharBrightness}; -use servicepoint2::{ByteGrid, CompressionCode, Connection, Grid, Origin, PixelGrid, TILE_HEIGHT, TILE_WIDTH}; +use servicepoint2::*; #[derive(Parser, Debug)] struct Cli { diff --git a/examples/wiping_clear/src/main.rs b/examples/wiping_clear/src/main.rs index aa8f3ea..69dcd0d 100644 --- a/examples/wiping_clear/src/main.rs +++ b/examples/wiping_clear/src/main.rs @@ -3,7 +3,7 @@ use std::time::Duration; use clap::Parser; -use servicepoint2::{BitVec, Command, CompressionCode, Connection, PixelGrid, FRAME_PACING, PIXEL_HEIGHT, PIXEL_WIDTH, Grid}; +use servicepoint2::*; #[derive(Parser, Debug)] struct Cli { diff --git a/servicepoint2/src/bit_vec.rs b/servicepoint2/src/bit_vec.rs index 099704e..b500e4e 100644 --- a/servicepoint2/src/bit_vec.rs +++ b/servicepoint2/src/bit_vec.rs @@ -1,3 +1,5 @@ +use crate::DataRef; + /// A vector of bits #[derive(Clone, PartialEq)] pub struct BitVec { @@ -83,11 +85,6 @@ impl BitVec { self.data.is_empty() } - /// Get the underlying bits in their raw packed bytes form - pub fn mut_data_ref(&mut self) -> &mut [u8] { - self.data.as_mut_slice() - } - /// Calculates the byte index and bitmask for a specific bit in the vector fn get_indexes(&self, bit_index: usize) -> (usize, u8) { if bit_index >= self.size { @@ -104,6 +101,16 @@ impl BitVec { } } +impl DataRef for BitVec { + fn data_ref_mut(&mut self) -> &mut [u8] { + self.data.as_mut_slice() + } + + fn data_ref(&self) -> &[u8] { + self.data.as_slice() + } +} + impl From for Vec { /// Turns the `BitVec` into the underlying `Vec` fn from(value: BitVec) -> Self { @@ -133,7 +140,7 @@ impl std::fmt::Debug for BitVec { #[cfg(feature = "c_api")] pub mod c_api { - use crate::{BitVec, CByteSlice}; + use crate::{BitVec, CByteSlice, DataRef}; /// Creates a new `BitVec` instance. /// The returned instance has to be freed with `bit_vec_dealloc`. @@ -220,7 +227,7 @@ pub mod c_api { pub unsafe extern "C" fn sp2_bit_vec_unsafe_data_ref( this: *mut BitVec, ) -> CByteSlice { - let data = (*this).mut_data_ref(); + let data = (*this).data_ref_mut(); CByteSlice { start: data.as_mut_ptr_range().start, length: data.len(), @@ -230,7 +237,7 @@ pub mod c_api { #[cfg(test)] mod tests { - use crate::BitVec; + use crate::{BitVec, DataRef}; #[test] fn fill() { @@ -280,7 +287,7 @@ mod tests { fn mut_data_ref() { let mut vec = BitVec::new(8 * 3); - let data_ref = vec.mut_data_ref(); + let data_ref = vec.data_ref_mut(); data_ref.copy_from_slice(&[0x40, 0x10, 0x00]); assert_eq!(vec.data, [0x40, 0x10, 0x00]); diff --git a/servicepoint2/src/byte_grid.rs b/servicepoint2/src/byte_grid.rs index 8aa90ec..9cf323f 100644 --- a/servicepoint2/src/byte_grid.rs +++ b/servicepoint2/src/byte_grid.rs @@ -1,4 +1,4 @@ -use crate::Grid; +use crate::{DataRef, Grid}; /// A 2D grid of bytes #[derive(Debug, Clone, PartialEq)] @@ -36,11 +36,6 @@ impl ByteGrid { } } - /// Get the underlying byte rows - pub fn mut_data_ref(&mut self) -> &mut [u8] { - self.data.as_mut_slice() - } - 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 +73,17 @@ impl Grid for ByteGrid { } } +impl DataRef for ByteGrid { + /// Get the underlying byte rows mutable + fn data_ref_mut(&mut self) -> &mut [u8] { + self.data.as_mut_slice() + } + + /// Get the underlying byte rows read only + fn data_ref(&self) -> &[u8] { + self.data.as_slice() + } +} impl From for Vec { /// Turn into the underlying `Vec` containing the rows of bytes. @@ -88,8 +94,9 @@ impl From for Vec { #[cfg(feature = "c_api")] pub mod c_api { - use crate::{ByteGrid, CByteSlice}; + use crate::data_ref::DataRef; use crate::grid::Grid; + use crate::{ByteGrid, CByteSlice}; /// Creates a new `ByteGrid` instance. /// The returned instance has to be freed with `byte_grid_dealloc`. @@ -190,7 +197,7 @@ pub mod c_api { pub unsafe extern "C" fn sp2_byte_grid_unsafe_data_ref( this: *mut ByteGrid, ) -> CByteSlice { - let data = (*this).mut_data_ref(); + let data = (*this).data_ref_mut(); CByteSlice { start: data.as_mut_ptr_range().start, length: data.len(), @@ -200,7 +207,7 @@ pub mod c_api { #[cfg(test)] mod tests { - use crate::{ByteGrid, Grid}; + use crate::{ByteGrid, DataRef, Grid}; #[test] fn fill() { @@ -247,7 +254,7 @@ mod tests { fn mut_data_ref() { let mut vec = ByteGrid::new(2, 2); - let data_ref = vec.mut_data_ref(); + let data_ref = vec.data_ref_mut(); data_ref.copy_from_slice(&[1, 2, 3, 4]); assert_eq!(vec.data, [1, 2, 3, 4]); diff --git a/servicepoint2/src/command.rs b/servicepoint2/src/command.rs index f40cace..42be0c5 100644 --- a/servicepoint2/src/command.rs +++ b/servicepoint2/src/command.rs @@ -1,6 +1,9 @@ use crate::command_code::CommandCode; use crate::compression::{into_compressed, into_decompressed}; -use crate::{BitVec, ByteGrid, CompressionCode, Grid, 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)] diff --git a/servicepoint2/src/connection.rs b/servicepoint2/src/connection.rs index 7480166..e38d95d 100644 --- a/servicepoint2/src/connection.rs +++ b/servicepoint2/src/connection.rs @@ -38,20 +38,20 @@ impl Connection { /// # Examples /// /// ```rust - /// use servicepoint2::CompressionCode; + /// use servicepoint2::{Command, CompressionCode, Grid, PixelGrid}; /// let connection = servicepoint2::Connection::open("172.23.42.29:2342") /// .expect("connection failed"); /// /// // turn off all pixels - /// connection.send(servicepoint2::Command::Clear.into()) + /// connection.send(Command::Clear.into()) /// .expect("send failed"); /// /// // turn on all pixels - /// let mut pixels = servicepoint2::PixelGrid::max_sized(); + /// let mut pixels = PixelGrid::max_sized(); /// pixels.fill(true); /// /// // send pixels to display - /// connection.send(servicepoint2::Command::BitmapLinearWin(servicepoint2::Origin(0, 0), pixels, CompressionCode::Lzma).into()) + /// connection.send(Command::BitmapLinearWin(servicepoint2::Origin(0, 0), pixels, CompressionCode::Uncompressed).into()) /// .expect("send failed"); /// ``` pub fn send(&self, packet: Packet) -> Result<(), std::io::Error> { diff --git a/servicepoint2/src/data_ref.rs b/servicepoint2/src/data_ref.rs new file mode 100644 index 0000000..d2665d6 --- /dev/null +++ b/servicepoint2/src/data_ref.rs @@ -0,0 +1,11 @@ +/// A trait for getting the underlying raw byte slices of data containers. +/// +/// The expectation is that you can create an equal instance with this data given the additional +/// metadata needed. +pub trait DataRef { + /// Get the underlying bytes writable. + fn data_ref_mut(&mut self) -> &mut [u8]; + + /// Get the underlying bytes read-only. + fn data_ref(&self) -> &[u8]; +} diff --git a/servicepoint2/src/lib.rs b/servicepoint2/src/lib.rs index 049cde5..dc3dc85 100644 --- a/servicepoint2/src/lib.rs +++ b/servicepoint2/src/lib.rs @@ -3,9 +3,10 @@ pub use crate::byte_grid::ByteGrid; pub use crate::command::{Brightness, Command, Offset, Origin, Size}; pub use crate::compression_code::CompressionCode; pub use crate::connection::Connection; +pub use crate::data_ref::DataRef; +pub use crate::grid::Grid; 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")] @@ -19,9 +20,10 @@ mod command_code; mod compression; mod compression_code; mod connection; +mod data_ref; +mod grid; mod packet; mod pixel_grid; -mod grid; /// size of a single tile in one dimension pub const TILE_SIZE: u16 = 8; diff --git a/servicepoint2/src/pixel_grid.rs b/servicepoint2/src/pixel_grid.rs index 725e2f2..a2c0257 100644 --- a/servicepoint2/src/pixel_grid.rs +++ b/servicepoint2/src/pixel_grid.rs @@ -1,4 +1,4 @@ -use crate::{BitVec, Grid, PIXEL_HEIGHT, PIXEL_WIDTH}; +use crate::{BitVec, DataRef, Grid, PIXEL_HEIGHT, PIXEL_WIDTH}; /// A grid of pixels stored in packed bytes. #[derive(Debug, Clone, PartialEq)] @@ -58,10 +58,6 @@ impl PixelGrid { } } - pub fn mut_data_ref(&mut self) -> &mut [u8] { - self.bit_vec.mut_data_ref() - } - 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) @@ -95,6 +91,16 @@ impl Grid for PixelGrid { } } +impl DataRef for PixelGrid { + fn data_ref_mut(&mut self) -> &mut [u8] { + self.bit_vec.data_ref_mut() + } + + fn data_ref(&self) -> &[u8] { + self.bit_vec.data_ref() + } +} + impl From for Vec { /// Turns a `PixelGrid` into the underlying `Vec`. fn from(value: PixelGrid) -> Self { @@ -105,7 +111,7 @@ impl From for Vec { #[cfg(feature = "c_api")] pub mod c_api { use crate::c_slice::CByteSlice; - use crate::{Grid, PixelGrid}; + use crate::{DataRef, Grid, PixelGrid}; /// Creates a new `PixelGrid` instance. /// The returned instance has to be freed with `pixel_grid_dealloc`. @@ -206,7 +212,7 @@ pub mod c_api { pub unsafe extern "C" fn sp2_pixel_grid_unsafe_data_ref( this: *mut PixelGrid, ) -> CByteSlice { - let data = (*this).mut_data_ref(); + let data = (*this).data_ref_mut(); CByteSlice { start: data.as_mut_ptr_range().start, length: data.len(), @@ -216,18 +222,18 @@ pub mod c_api { #[cfg(test)] mod tests { - use crate::{Grid, PixelGrid}; + use crate::{DataRef, Grid, PixelGrid}; #[test] fn fill() { let mut grid = PixelGrid::new(8, 2); - assert_eq!(grid.mut_data_ref(), [0x00, 0x00]); + assert_eq!(grid.data_ref(), [0x00, 0x00]); grid.fill(true); - assert_eq!(grid.mut_data_ref(), [0xFF, 0xFF]); + assert_eq!(grid.data_ref(), [0xFF, 0xFF]); grid.fill(false); - assert_eq!(grid.mut_data_ref(), [0x00, 0x00]); + assert_eq!(grid.data_ref(), [0x00, 0x00]); } #[test] @@ -238,7 +244,7 @@ mod tests { grid.set(5, 0, true); grid.set(1, 1, true); - assert_eq!(grid.mut_data_ref(), [0x04, 0x40]); + assert_eq!(grid.data_ref(), [0x04, 0x40]); assert!(grid.get(5, 0)); assert!(grid.get(1, 1)); @@ -254,11 +260,11 @@ mod tests { } } - assert_eq!(grid.mut_data_ref(), [0xAA, 0x55, 0xAA]); + assert_eq!(grid.data_ref(), [0xAA, 0x55, 0xAA]); let data: Vec = grid.into(); - let mut grid = PixelGrid::load(8, 3, &data); - assert_eq!(grid.mut_data_ref(), [0xAA, 0x55, 0xAA]); + let grid = PixelGrid::load(8, 3, &data); + assert_eq!(grid.data_ref(), [0xAA, 0x55, 0xAA]); } }