From c554fbd80048dbedc7e553075a16704033ca234a Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sun, 23 Jun 2024 15:12:03 +0200 Subject: [PATCH] wip BrightnessGrid --- crates/servicepoint/examples/announce.rs | 4 +- .../examples/brightness_tester.rs | 5 +- .../examples/random_brightness.rs | 9 +- crates/servicepoint/src/brightness.rs | 53 +++++++++++- crates/servicepoint/src/command.rs | 38 ++++++--- crates/servicepoint/src/data_ref.rs | 6 +- crates/servicepoint/src/lib.rs | 8 +- crates/servicepoint/src/pixel_grid.rs | 2 +- .../src/{byte_grid.rs => primitive_grid.rs} | 83 ++++++++++--------- .../servicepoint_binding_c/src/byte_grid.rs | 4 +- crates/servicepoint_binding_c/src/command.rs | 8 +- .../ServicePoint/BindGen/ServicePoint.g.cs | 26 +++--- crates/servicepoint_binding_cs/build.rs | 2 +- 13 files changed, 162 insertions(+), 86 deletions(-) rename crates/servicepoint/src/{byte_grid.rs => primitive_grid.rs} (74%) diff --git a/crates/servicepoint/examples/announce.rs b/crates/servicepoint/examples/announce.rs index ceb7ca2..4f19194 100644 --- a/crates/servicepoint/examples/announce.rs +++ b/crates/servicepoint/examples/announce.rs @@ -2,7 +2,7 @@ use clap::Parser; -use servicepoint::{ByteGrid, Command, Connection, Grid, Origin}; +use servicepoint::{Command, Connection, Cp473Grid, Grid, Origin}; #[derive(Parser, Debug)] struct Cli { @@ -33,7 +33,7 @@ fn main() { let max_width = cli.text.iter().map(|t| t.len()).max().unwrap(); - let mut chars = ByteGrid::new(max_width, cli.text.len()); + let mut chars = Cp473Grid::new(max_width, cli.text.len()); for y in 0..cli.text.len() { let row = &cli.text[y]; diff --git a/crates/servicepoint/examples/brightness_tester.rs b/crates/servicepoint/examples/brightness_tester.rs index b36b42c..650a428 100644 --- a/crates/servicepoint/examples/brightness_tester.rs +++ b/crates/servicepoint/examples/brightness_tester.rs @@ -27,9 +27,10 @@ fn main() { )) .expect("send failed"); - let mut brightnesses = ByteGrid::new(TILE_WIDTH, TILE_HEIGHT); + let max_brightness = usize::from(u8::from(Brightness::MAX)); + let mut brightnesses = BrightnessGrid::new(TILE_WIDTH, TILE_HEIGHT); for (index, byte) in brightnesses.data_ref_mut().iter_mut().enumerate() { - *byte = (index % u8::MAX as usize) as u8; + *byte = Brightness::try_from((index % max_brightness) as u8).unwrap(); } connection diff --git a/crates/servicepoint/examples/random_brightness.rs b/crates/servicepoint/examples/random_brightness.rs index d37b7f2..01487a2 100644 --- a/crates/servicepoint/examples/random_brightness.rs +++ b/crates/servicepoint/examples/random_brightness.rs @@ -31,8 +31,11 @@ fn main() { let mut filled_grid = PixelGrid::max_sized(); filled_grid.fill(true); - let command = - BitmapLinearWin(Origin::new(0, 0), filled_grid, CompressionCode::Lzma); + let command = BitmapLinearWin( + Origin::new(0, 0), + filled_grid, + CompressionCode::Lzma, + ); connection.send(command).expect("send failed"); } @@ -50,7 +53,7 @@ fn main() { let h = rng.gen_range(min_size..=TILE_HEIGHT - y); let origin = Origin::new(x, y); - let mut luma = ByteGrid::new(w, h); + let mut luma = BrightnessGrid::new(w, h); for y in 0..h { for x in 0..w { diff --git a/crates/servicepoint/src/brightness.rs b/crates/servicepoint/src/brightness.rs index 94ab3c7..dae3450 100644 --- a/crates/servicepoint/src/brightness.rs +++ b/crates/servicepoint/src/brightness.rs @@ -1,3 +1,4 @@ +use crate::{Grid, PrimitiveGrid}; #[cfg(feature = "rand")] use rand::{ distributions::{Distribution, Standard}, @@ -8,6 +9,9 @@ use rand::{ #[derive(Debug, Copy, Clone, PartialEq)] pub struct Brightness(u8); +/// A grid containing brightness values. +pub type BrightnessGrid = PrimitiveGrid; + impl From for u8 { fn from(brightness: Brightness) -> Self { brightness.0 @@ -15,11 +19,11 @@ impl From for u8 { } impl TryFrom for Brightness { - type Error = (); + type Error = u8; fn try_from(value: u8) -> Result { if value > Self::MAX.0 { - Err(()) + Err(value) } else { Ok(Brightness(value)) } @@ -33,6 +37,51 @@ impl Brightness { pub const MIN: Brightness = Brightness(0); } +impl Default for Brightness { + fn default() -> Self { + Self::MAX + } +} + +impl From for Vec { + fn from(value: PrimitiveGrid) -> Self { + value + .iter() + .map(|brightness| (*brightness).into()) + .collect() + } +} + +impl From for PrimitiveGrid { + fn from(value: PrimitiveGrid) -> Self { + let u8s = value + .iter() + .map(|brightness| (*brightness).into()) + .collect::>(); + PrimitiveGrid::load(value.width(), value.height(), &u8s) + } +} + +impl TryFrom> for BrightnessGrid { + type Error = u8; + + fn try_from(value: PrimitiveGrid) -> Result { + let brightnesses = value + .iter() + .map(|b| Brightness::try_from(*b)) + .collect::, _>>(); + let brightnesses = match brightnesses { + Ok(vec) => vec, + Err(u8) => return Err(u8), + }; + Ok(BrightnessGrid::load( + value.width(), + value.height(), + &brightnesses, + )) + } +} + #[cfg(feature = "rand")] impl Distribution for Standard { fn sample(&self, rng: &mut R) -> Brightness { diff --git a/crates/servicepoint/src/command.rs b/crates/servicepoint/src/command.rs index 2b28d1c..11b151b 100644 --- a/crates/servicepoint/src/command.rs +++ b/crates/servicepoint/src/command.rs @@ -3,13 +3,18 @@ use bitvec::prelude::BitVec; use crate::{ command_code::CommandCode, compression::{into_compressed, into_decompressed}, - Brightness, ByteGrid, CompressionCode, Grid, Header, Origin, Packet, - PixelGrid, Pixels, SpBitVec, Tiles, TILE_SIZE, + Brightness, BrightnessGrid, CompressionCode, Grid, Header, Origin, Packet, + PixelGrid, Pixels, PrimitiveGrid, SpBitVec, Tiles, TILE_SIZE, }; /// Type alias for documenting the meaning of the u16 in enum values pub type Offset = usize; +/// A grid containing codepage 437 characters. +/// +/// The encoding is currently not enforced. +pub type Cp473Grid = PrimitiveGrid; + /// A command to send to the display. #[derive(Debug, Clone, PartialEq)] pub enum Command { @@ -22,7 +27,7 @@ pub enum Command { /// The library does not currently convert between UTF-8 and CP-437. /// Because Rust expects UTF-8 strings, it might be necessary to only send ASCII for now. /// - Cp437Data(Origin, ByteGrid), + Cp437Data(Origin, Cp473Grid), /// Sets a window of pixels to the specified values BitmapLinearWin(Origin, PixelGrid, CompressionCode), @@ -31,7 +36,7 @@ pub enum Command { Brightness(Brightness), /// Set the brightness of individual tiles in a rectangular area of the display. - CharBrightness(Origin, ByteGrid), + CharBrightness(Origin, BrightnessGrid), /// Set pixel data starting at the pixel offset on screen. /// @@ -271,14 +276,24 @@ impl TryFrom for Command { let Packet(_, payload) = packet; Ok(Command::Cp437Data( Origin::new(a as usize, b as usize), - ByteGrid::load(c as usize, d as usize, &payload), + Cp473Grid::load(c as usize, d as usize, &payload), )) } CommandCode::CharBrightness => { let Packet(_, payload) = packet; + + let grid = + PrimitiveGrid::load(c as usize, d as usize, &payload); + let grid = match BrightnessGrid::try_from(grid) { + Ok(grid) => grid, + Err(val) => { + return Err(TryFromPacketError::InvalidBrightness(val)) + } + }; + Ok(Command::CharBrightness( Origin::new(a as usize, b as usize), - ByteGrid::load(c as usize, d as usize, &payload), + grid, )) } #[allow(deprecated)] @@ -424,8 +439,8 @@ impl Command { mod tests { use crate::{ bitvec::prelude::BitVec, command::TryFromPacketError, - command_code::CommandCode, origin::Pixels, Brightness, ByteGrid, - Command, CompressionCode, Header, Origin, Packet, PixelGrid, + command_code::CommandCode, origin::Pixels, Brightness, Command, + CompressionCode, Header, Origin, Packet, PixelGrid, PrimitiveGrid, }; fn round_trip(original: Command) { @@ -481,13 +496,16 @@ mod tests { fn round_trip_char_brightness() { round_trip(Command::CharBrightness( Origin::new(5, 2), - ByteGrid::new(7, 5), + PrimitiveGrid::new(7, 5), )); } #[test] fn round_trip_cp437_data() { - round_trip(Command::Cp437Data(Origin::new(5, 2), ByteGrid::new(7, 5))); + round_trip(Command::Cp437Data( + Origin::new(5, 2), + PrimitiveGrid::new(7, 5), + )); } #[test] diff --git a/crates/servicepoint/src/data_ref.rs b/crates/servicepoint/src/data_ref.rs index d2665d6..94a40b0 100644 --- a/crates/servicepoint/src/data_ref.rs +++ b/crates/servicepoint/src/data_ref.rs @@ -2,10 +2,10 @@ /// /// The expectation is that you can create an equal instance with this data given the additional /// metadata needed. -pub trait DataRef { +pub trait DataRef { /// Get the underlying bytes writable. - fn data_ref_mut(&mut self) -> &mut [u8]; + fn data_ref_mut(&mut self) -> &mut [T]; /// Get the underlying bytes read-only. - fn data_ref(&self) -> &[u8]; + fn data_ref(&self) -> &[T]; } diff --git a/crates/servicepoint/src/lib.rs b/crates/servicepoint/src/lib.rs index e8edea6..f923257 100644 --- a/crates/servicepoint/src/lib.rs +++ b/crates/servicepoint/src/lib.rs @@ -5,9 +5,8 @@ use std::time::Duration; pub use bitvec; use bitvec::prelude::{BitVec, Msb0}; -pub use crate::brightness::Brightness; -pub use crate::byte_grid::ByteGrid; -pub use crate::command::{Command, Offset}; +pub use crate::brightness::{Brightness, BrightnessGrid}; +pub use crate::command::{Command, Cp473Grid, Offset}; pub use crate::compression_code::CompressionCode; pub use crate::connection::Connection; pub use crate::data_ref::DataRef; @@ -15,11 +14,11 @@ pub use crate::grid::Grid; pub use crate::origin::{Origin, Pixels, Tiles}; pub use crate::packet::{Header, Packet, Payload}; pub use crate::pixel_grid::PixelGrid; +pub use crate::primitive_grid::PrimitiveGrid; type SpBitVec = BitVec; mod brightness; -mod byte_grid; mod command; mod command_code; mod compression; @@ -30,6 +29,7 @@ mod grid; mod origin; mod packet; mod pixel_grid; +mod primitive_grid; /// size of a single tile in one dimension pub const TILE_SIZE: usize = 8; diff --git a/crates/servicepoint/src/pixel_grid.rs b/crates/servicepoint/src/pixel_grid.rs index f8c34b4..82e45d1 100644 --- a/crates/servicepoint/src/pixel_grid.rs +++ b/crates/servicepoint/src/pixel_grid.rs @@ -158,7 +158,7 @@ impl Grid for PixelGrid { } } -impl DataRef for PixelGrid { +impl DataRef for PixelGrid { fn data_ref_mut(&mut self) -> &mut [u8] { self.bit_vec.as_raw_mut_slice() } diff --git a/crates/servicepoint/src/byte_grid.rs b/crates/servicepoint/src/primitive_grid.rs similarity index 74% rename from crates/servicepoint/src/byte_grid.rs rename to crates/servicepoint/src/primitive_grid.rs index 74b9e3c..d96221b 100644 --- a/crates/servicepoint/src/byte_grid.rs +++ b/crates/servicepoint/src/primitive_grid.rs @@ -2,26 +2,29 @@ use std::slice::{Iter, IterMut}; use crate::{DataRef, Grid}; +pub trait PrimitiveGridType: Sized + Default + Copy + Clone {} +impl PrimitiveGridType for T {} + /// A 2D grid of bytes #[derive(Debug, Clone, PartialEq)] -pub struct ByteGrid { +pub struct PrimitiveGrid { width: usize, height: usize, - data: Vec, + data: Vec, } -impl ByteGrid { - /// Creates a new `ByteGrid` with the specified dimensions. +impl PrimitiveGrid { + /// Creates a new `PrimitiveGrid` with the specified dimensions. /// /// # Arguments /// /// - width: size in x-direction /// - height: size in y-direction /// - /// returns: `ByteGrid` initialized to 0. + /// returns: `ByteGrid` initialized to default value. pub fn new(width: usize, height: usize) -> Self { Self { - data: vec![0; width * height], + data: vec![Default::default(); width * height], width, height, } @@ -35,7 +38,7 @@ impl ByteGrid { /// /// - when the dimensions and data size do not match exactly. #[must_use] - pub fn load(width: usize, height: usize, data: &[u8]) -> Self { + pub fn load(width: usize, height: usize, data: &[T]) -> Self { assert_eq!(width * height, data.len()); Self { data: Vec::from(data), @@ -48,20 +51,20 @@ impl ByteGrid { /// /// Order is equivalent to the following loop: /// ``` - /// # use servicepoint::{ByteGrid, Grid}; - /// # let grid = ByteGrid::new(2,2); + /// # use servicepoint::{PrimitiveGrid, Grid}; + /// # let grid = PrimitiveGrid::::new(2,2); /// for y in 0..grid.height() { /// for x in 0..grid.width() { /// grid.get(x, y); /// } /// } /// ``` - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter { self.data.iter() } /// Iterate over all rows in `ByteGrid` top to bottom. - pub fn iter_rows(&self) -> IterRows { + pub fn iter_rows(&self) -> IterRows { IterRows { byte_grid: self, row: 0, @@ -71,7 +74,7 @@ impl ByteGrid { /// Returns an iterator that allows modifying each value. /// /// The iterator yields all cells from top left to bottom right. - pub fn iter_mut(&mut self) -> IterMut { + pub fn iter_mut(&mut self) -> IterMut { self.data.iter_mut() } @@ -84,7 +87,7 @@ impl ByteGrid { /// # Panics /// /// When accessing `x` or `y` out of bounds. - pub fn get_ref_mut(&mut self, x: usize, y: usize) -> &mut u8 { + pub fn get_ref_mut(&mut self, x: usize, y: usize) -> &mut T { self.assert_in_bounds(x, y); &mut self.data[x + y * self.width] } @@ -100,7 +103,7 @@ impl ByteGrid { &mut self, x: isize, y: isize, - ) -> Option<&mut u8> { + ) -> Option<&mut T> { if self.is_in_bounds(x, y) { Some(&mut self.data[x as usize + y as usize * self.width]) } else { @@ -109,7 +112,7 @@ impl ByteGrid { } } -impl Grid for ByteGrid { +impl Grid for PrimitiveGrid { /// Sets the value of the cell at the specified position in the `ByteGrid. /// /// # Arguments @@ -120,7 +123,7 @@ impl Grid for ByteGrid { /// # Panics /// /// When accessing `x` or `y` out of bounds. - fn set(&mut self, x: usize, y: usize, value: u8) { + fn set(&mut self, x: usize, y: usize, value: T) { self.assert_in_bounds(x, y); self.data[x + y * self.width] = value; } @@ -134,12 +137,12 @@ impl Grid for ByteGrid { /// # Panics /// /// When accessing `x` or `y` out of bounds. - fn get(&self, x: usize, y: usize) -> u8 { + fn get(&self, x: usize, y: usize) -> T { self.assert_in_bounds(x, y); self.data[x + y * self.width] } - fn fill(&mut self, value: u8) { + fn fill(&mut self, value: T) { self.data.fill(value); } @@ -152,32 +155,32 @@ impl Grid for ByteGrid { } } -impl DataRef for ByteGrid { +impl DataRef for PrimitiveGrid { /// Get the underlying byte rows mutable - fn data_ref_mut(&mut self) -> &mut [u8] { + fn data_ref_mut(&mut self) -> &mut [T] { self.data.as_mut_slice() } /// Get the underlying byte rows read only - fn data_ref(&self) -> &[u8] { + fn data_ref(&self) -> &[T] { self.data.as_slice() } } -impl From for Vec { +impl From> for Vec { /// Turn into the underlying `Vec` containing the rows of bytes. - fn from(value: ByteGrid) -> Self { + fn from(value: PrimitiveGrid) -> Self { value.data } } -pub struct IterRows<'t> { - byte_grid: &'t ByteGrid, +pub struct IterRows<'t, T: PrimitiveGridType> { + byte_grid: &'t PrimitiveGrid, row: usize, } -impl<'t> Iterator for IterRows<'t> { - type Item = Iter<'t, u8>; +impl<'t, T: PrimitiveGridType> Iterator for IterRows<'t, T> { + type Item = Iter<'t, T>; fn next(&mut self) -> Option { if self.row >= self.byte_grid.height { @@ -194,11 +197,11 @@ impl<'t> Iterator for IterRows<'t> { #[cfg(test)] mod tests { - use crate::{ByteGrid, DataRef, Grid}; + use crate::{DataRef, Grid, PrimitiveGrid}; #[test] fn fill() { - let mut grid = ByteGrid::new(2, 2); + let mut grid = PrimitiveGrid::::new(2, 2); assert_eq!(grid.data, [0x00, 0x00, 0x00, 0x00]); grid.fill(42); @@ -207,7 +210,7 @@ mod tests { #[test] fn get_set() { - let mut grid = ByteGrid::new(2, 2); + let mut grid = PrimitiveGrid::new(2, 2); assert_eq!(grid.get(0, 0), 0); assert_eq!(grid.get(1, 1), 0); @@ -222,7 +225,7 @@ mod tests { #[test] fn load() { - let mut grid = ByteGrid::new(2, 3); + let mut grid = PrimitiveGrid::new(2, 3); for x in 0..grid.width { for y in 0..grid.height { grid.set(x, y, (x + y) as u8); @@ -233,13 +236,13 @@ mod tests { let data: Vec = grid.into(); - let grid = ByteGrid::load(2, 3, &data); + let grid = PrimitiveGrid::load(2, 3, &data); assert_eq!(grid.data, [0, 1, 1, 2, 2, 3]); } #[test] fn mut_data_ref() { - let mut vec = ByteGrid::new(2, 2); + let mut vec = PrimitiveGrid::new(2, 2); let data_ref = vec.data_ref_mut(); data_ref.copy_from_slice(&[1, 2, 3, 4]); @@ -250,7 +253,7 @@ mod tests { #[test] fn iter() { - let mut vec = ByteGrid::new(2, 2); + let mut vec = PrimitiveGrid::new(2, 2); vec.set(1, 1, 5); let mut iter = vec.iter(); @@ -262,7 +265,7 @@ mod tests { #[test] fn iter_mut() { - let mut vec = ByteGrid::new(2, 3); + let mut vec = PrimitiveGrid::new(2, 3); for (index, cell) in vec.iter_mut().enumerate() { *cell = index as u8; } @@ -272,7 +275,7 @@ mod tests { #[test] fn iter_rows() { - let vec = ByteGrid::load(2, 3, &[0, 1, 1, 2, 2, 3]); + let vec = PrimitiveGrid::load(2, 3, &[0, 1, 1, 2, 2, 3]); for (y, row) in vec.iter_rows().enumerate() { for (x, val) in row.enumerate() { assert_eq!(*val, (x + y) as u8); @@ -283,20 +286,20 @@ mod tests { #[test] #[should_panic] fn out_of_bounds_x() { - let mut vec = ByteGrid::load(2, 2, &[0, 1, 2, 3]); + let mut vec = PrimitiveGrid::load(2, 2, &[0, 1, 2, 3]); vec.set(2, 1, 5); } #[test] #[should_panic] fn out_of_bounds_y() { - let vec = ByteGrid::load(2, 2, &[0, 1, 2, 3]); + let vec = PrimitiveGrid::load(2, 2, &[0, 1, 2, 3]); vec.get(1, 2); } #[test] fn ref_mut() { - let mut vec = ByteGrid::load(2, 2, &[0, 1, 2, 3]); + let mut vec = PrimitiveGrid::load(2, 2, &[0, 1, 2, 3]); let top_left = vec.get_ref_mut(0, 0); *top_left += 5; @@ -307,7 +310,7 @@ mod tests { #[test] fn optional() { - let mut grid = ByteGrid::load(2, 2, &[0, 1, 2, 3]); + let mut grid = PrimitiveGrid::load(2, 2, &[0, 1, 2, 3]); grid.set_optional(0, 0, 5); grid.set_optional(-1, 0, 8); grid.set_optional(0, 8, 42); diff --git a/crates/servicepoint_binding_c/src/byte_grid.rs b/crates/servicepoint_binding_c/src/byte_grid.rs index 9b4425f..4c8c1cb 100644 --- a/crates/servicepoint_binding_c/src/byte_grid.rs +++ b/crates/servicepoint_binding_c/src/byte_grid.rs @@ -2,10 +2,12 @@ //! //! prefix `sp_byte_grid_` -use servicepoint::{ByteGrid, DataRef, Grid}; +use servicepoint::{DataRef, Grid, PrimitiveGrid}; use crate::c_slice::CByteSlice; +pub type ByteGrid = PrimitiveGrid; + /// Creates a new `ByteGrid` with the specified dimensions. /// /// returns: `ByteGrid` initialized to 0. diff --git a/crates/servicepoint_binding_c/src/command.rs b/crates/servicepoint_binding_c/src/command.rs index 8882162..b799072 100644 --- a/crates/servicepoint_binding_c/src/command.rs +++ b/crates/servicepoint_binding_c/src/command.rs @@ -5,8 +5,8 @@ use std::ptr::null_mut; use servicepoint::{ - Brightness, ByteGrid, Command, CompressionCode, Offset, Origin, Packet, - PixelGrid, + Brightness, BrightnessGrid, Command, CompressionCode, Cp473Grid, Offset, + Origin, Packet, PixelGrid, }; use crate::bit_vec::CBitVec; @@ -126,7 +126,7 @@ pub unsafe extern "C" fn sp_command_brightness(brightness: u8) -> *mut Command { pub unsafe extern "C" fn sp_command_char_brightness( x: usize, y: usize, - byte_grid: *mut ByteGrid, + byte_grid: *mut BrightnessGrid, ) -> *mut Command { let byte_grid = *Box::from_raw(byte_grid); Box::into_raw(Box::new(Command::CharBrightness( @@ -254,7 +254,7 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_xor( pub unsafe extern "C" fn sp_command_cp437_data( x: usize, y: usize, - byte_grid: *mut ByteGrid, + byte_grid: *mut Cp473Grid, ) -> *mut Command { let byte_grid = *Box::from_raw(byte_grid); Box::into_raw(Box::new(Command::Cp437Data(Origin::new(x, y), byte_grid))) diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs index 5af738e..1738b8f 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/BindGen/ServicePoint.g.cs @@ -63,43 +63,43 @@ namespace ServicePoint.BindGen /// Creates a new `ByteGrid` with the specified dimensions. returns: `ByteGrid` initialized to 0. # Safety The caller has to make sure that: - the returned instance is freed in some way, either by using a consuming function or by explicitly calling `sp_byte_grid_dealloc`. [DllImport(__DllName, EntryPoint = "sp_byte_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteGrid* sp_byte_grid_new(nuint width, nuint height); + public static extern PrimitiveGrid* sp_byte_grid_new(nuint width, nuint height); /// Loads a `ByteGrid` with the specified dimensions from the provided data. # Panics When the provided `data_length` is not sufficient for the `height` and `width` # Safety The caller has to make sure that: - `data` points to a valid memory location of at least `data_length` bytes in size. - the returned instance is freed in some way, either by using a consuming function or by explicitly calling `sp_byte_grid_dealloc`. [DllImport(__DllName, EntryPoint = "sp_byte_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteGrid* sp_byte_grid_load(nuint width, nuint height, byte* data, nuint data_length); + public static extern PrimitiveGrid* sp_byte_grid_load(nuint width, nuint height, byte* data, nuint data_length); /// Clones a `ByteGrid`. # Safety The caller has to make sure that: - `this` points to a valid `ByteGrid` - `this` is not written to concurrently - the returned instance is freed in some way, either by using a consuming function or by explicitly calling `sp_byte_grid_dealloc`. [DllImport(__DllName, EntryPoint = "sp_byte_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteGrid* sp_byte_grid_clone(ByteGrid* @this); + public static extern PrimitiveGrid* sp_byte_grid_clone(PrimitiveGrid* @this); /// Deallocates a `ByteGrid`. # Safety The caller has to make sure that: - `this` points to a valid `ByteGrid` - `this` is not used concurrently or after this call - `this` was not passed to another consuming function, e.g. to create a `Command` [DllImport(__DllName, EntryPoint = "sp_byte_grid_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_byte_grid_dealloc(ByteGrid* @this); + public static extern void sp_byte_grid_dealloc(PrimitiveGrid* @this); /// Gets the current value at the specified position. # Arguments * `this`: instance to read from * `x` and `y`: position of the cell to read # Panics When accessing `x` or `y` out of bounds. # Safety The caller has to make sure that: - `this` points to a valid `ByteGrid` - `this` is not written to concurrently [DllImport(__DllName, EntryPoint = "sp_byte_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern byte sp_byte_grid_get(ByteGrid* @this, nuint x, nuint y); + public static extern byte sp_byte_grid_get(PrimitiveGrid* @this, nuint x, nuint y); /// Sets the value of the specified position in the `ByteGrid`. # Arguments * `this`: instance to write to * `x` and `y`: position of the cell * `value`: the value to write to the cell returns: old value of the cell # Panics When accessing `x` or `y` out of bounds. # Safety The caller has to make sure that: - `this` points to a valid `BitVec` - `this` is not written to or read from concurrently [DllImport(__DllName, EntryPoint = "sp_byte_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_byte_grid_set(ByteGrid* @this, nuint x, nuint y, byte value); + public static extern void sp_byte_grid_set(PrimitiveGrid* @this, nuint x, nuint y, byte value); /// Sets the value of all cells in the `ByteGrid`. # Arguments * `this`: instance to write to * `value`: the value to set all cells to # Safety The caller has to make sure that: - `this` points to a valid `ByteGrid` - `this` is not written to or read from concurrently [DllImport(__DllName, EntryPoint = "sp_byte_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_byte_grid_fill(ByteGrid* @this, byte value); + public static extern void sp_byte_grid_fill(PrimitiveGrid* @this, byte value); /// Gets the width of the `ByteGrid` instance. # Arguments * `this`: instance to read from # Safety The caller has to make sure that: - `this` points to a valid `ByteGrid` [DllImport(__DllName, EntryPoint = "sp_byte_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_byte_grid_width(ByteGrid* @this); + public static extern nuint sp_byte_grid_width(PrimitiveGrid* @this); /// Gets the height of the `ByteGrid` instance. # Arguments * `this`: instance to read from # Safety The caller has to make sure that: - `this` points to a valid `ByteGrid` [DllImport(__DllName, EntryPoint = "sp_byte_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_byte_grid_height(ByteGrid* @this); + public static extern nuint sp_byte_grid_height(PrimitiveGrid* @this); /// Gets an unsafe reference to the data of the `ByteGrid` instance. ## Safety The caller has to make sure that: - `this` points to a valid `ByteGrid` - the returned memory range is never accessed after the passed `ByteGrid` has been freed - the returned memory range is never accessed concurrently, either via the `ByteGrid` or directly [DllImport(__DllName, EntryPoint = "sp_byte_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern CByteSlice sp_byte_grid_unsafe_data_ref(ByteGrid* @this); + public static extern CByteSlice sp_byte_grid_unsafe_data_ref(PrimitiveGrid* @this); /// Tries to turn a `Packet` into a `Command`. The packet is deallocated in the process. Returns: pointer to new `Command` instance or NULL # Safety The caller has to make sure that: - `packet` points to a valid instance of `Packet` - `packet` is not used concurrently or after this call - the result is checked for NULL - the returned `Command` instance is freed in some way, either by using a consuming function or by explicitly calling `sp_command_dealloc`. [DllImport(__DllName, EntryPoint = "sp_command_try_from_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -127,7 +127,7 @@ namespace ServicePoint.BindGen /// Allocates a new `Command::CharBrightness` instance. The passed `ByteGrid` gets consumed. # Safety The caller has to make sure that: - `byte_grid` points to a valid instance of `ByteGrid` - `byte_grid` is not used concurrently or after this call - the returned `Command` instance is freed in some way, either by using a consuming function or by explicitly calling `sp_command_dealloc`. [DllImport(__DllName, EntryPoint = "sp_command_char_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_char_brightness(nuint x, nuint y, ByteGrid* byte_grid); + public static extern Command* sp_command_char_brightness(nuint x, nuint y, BrightnessGrid* byte_grid); /// Allocates a new `Command::BitmapLinear` instance. The passed `BitVec` gets consumed. # Safety The caller has to make sure that: - `bit_vec` points to a valid instance of `BitVec` - `bit_vec` is not used concurrently or after this call - `compression` matches one of the allowed enum values - the returned `Command` instance is freed in some way, either by using a consuming function or by explicitly calling `sp_command_dealloc`. [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -147,7 +147,7 @@ namespace ServicePoint.BindGen /// Allocates a new `Command::Cp437Data` instance. The passed `ByteGrid` gets consumed. # Safety The caller has to make sure that: - `byte_grid` points to a valid instance of `ByteGrid` - `byte_grid` is not used concurrently or after this call - the returned `Command` instance is freed in some way, either by using a consuming function or by explicitly calling `sp_command_dealloc`. [DllImport(__DllName, EntryPoint = "sp_command_cp437_data", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_cp437_data(nuint x, nuint y, ByteGrid* byte_grid); + public static extern Command* sp_command_cp437_data(nuint x, nuint y, PrimitiveGrid* byte_grid); /// Allocates a new `Command::BitmapLinearWin` instance. The passed `PixelGrid` gets consumed. # Safety The caller has to make sure that: - `pixel_grid` points to a valid instance of `PixelGrid` - `pixel_grid` is not used concurrently or after this call - `compression` matches one of the allowed enum values - the returned `Command` instance is freed in some way, either by using a consuming function or by explicitly calling `sp_command_dealloc`. [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_win", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] @@ -239,7 +239,7 @@ namespace ServicePoint.BindGen } [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct ByteGrid + public unsafe partial struct PrimitiveGrid { } diff --git a/crates/servicepoint_binding_cs/build.rs b/crates/servicepoint_binding_cs/build.rs index 49747b2..b9b71d2 100644 --- a/crates/servicepoint_binding_cs/build.rs +++ b/crates/servicepoint_binding_cs/build.rs @@ -12,7 +12,7 @@ fn main() { .input_extern_file("../servicepoint_binding_c/src/lib.rs") .input_extern_file("../servicepoint_binding_c/src/c_slice.rs") .input_extern_file("../servicepoint_binding_c/src/packet.rs") - .input_extern_file("../servicepoint/src/byte_grid.rs") + .input_extern_file("../servicepoint/src/primitive_grid.rs") .input_extern_file("../servicepoint/src/command.rs") .input_extern_file("../servicepoint/src/connection.rs") .input_extern_file("../servicepoint/src/pixel_grid.rs")