move c_api into binding_c crate, update C# binding
This commit is contained in:
		
							parent
							
								
									edcad6fd03
								
							
						
					
					
						commit
						f759395393
					
				
					 40 changed files with 895 additions and 916 deletions
				
			
		
							
								
								
									
										3
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										3
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							|  | @ -621,6 +621,7 @@ name = "servicepoint_binding_c" | |||
| version = "0.4.2" | ||||
| dependencies = [ | ||||
|  "cbindgen", | ||||
|  "servicepoint", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  | @ -628,7 +629,7 @@ name = "servicepoint_binding_cs" | |||
| version = "0.4.2" | ||||
| dependencies = [ | ||||
|  "csbindgen", | ||||
|  "servicepoint", | ||||
|  "servicepoint_binding_c", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ repository = "https://github.com/cccb/servicepoint" | |||
| readme = "../../README.md" | ||||
| 
 | ||||
| [lib] | ||||
| crate-type = ["staticlib", "rlib", "cdylib"] | ||||
| crate-type = ["rlib"] | ||||
| 
 | ||||
| [dependencies] | ||||
| log = "0.4" | ||||
|  | @ -20,10 +20,9 @@ zstd = { version = "0.13", optional = true } | |||
| rust-lzma = { version = "0.6.0", optional = true } | ||||
| 
 | ||||
| [features] | ||||
| default = ["compression_lzma", "c_api"] | ||||
| default = ["compression_lzma"] | ||||
| compression_zlib = ["dep:flate2"] | ||||
| compression_bzip2 = ["dep:bzip2"] | ||||
| compression_lzma = ["dep:rust-lzma"] | ||||
| compression_zstd = ["dep:zstd"] | ||||
| all_compressions = ["compression_zlib", "compression_bzip2", "compression_lzma", "compression_zstd"] | ||||
| c_api = [] | ||||
|  |  | |||
|  | @ -135,103 +135,6 @@ impl From<&[u8]> for BitVec { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(feature = "c_api")] | ||||
| pub mod c_api { | ||||
|     use crate::{BitVec, CByteSlice, DataRef}; | ||||
| 
 | ||||
|     /// Creates a new `BitVec` instance.
 | ||||
|     /// The returned instance has to be freed with `bit_vec_dealloc`.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_bit_vec_new(size: usize) -> *mut BitVec { | ||||
|         Box::into_raw(Box::new(BitVec::new(size))) | ||||
|     } | ||||
| 
 | ||||
|     /// Loads a `BitVec` from the provided data.
 | ||||
|     /// The returned instance has to be freed with `bit_vec_dealloc`.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_bit_vec_load( | ||||
|         data: *const u8, | ||||
|         data_length: usize, | ||||
|     ) -> *mut BitVec { | ||||
|         let data = std::slice::from_raw_parts(data, data_length); | ||||
|         Box::into_raw(Box::new(BitVec::from(data))) | ||||
|     } | ||||
| 
 | ||||
|     /// Clones a `BitVec`.
 | ||||
|     /// The returned instance has to be freed with `bit_vec_dealloc`.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_bit_vec_clone( | ||||
|         this: *const BitVec, | ||||
|     ) -> *mut BitVec { | ||||
|         Box::into_raw(Box::new((*this).clone())) | ||||
|     } | ||||
| 
 | ||||
|     /// Deallocates a `BitVec`.
 | ||||
|     ///
 | ||||
|     /// Note: do not call this if the grid has been consumed in another way, e.g. to create a command.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_bit_vec_dealloc(this: *mut BitVec) { | ||||
|         _ = Box::from_raw(this); | ||||
|     } | ||||
| 
 | ||||
|     /// Gets the value of a bit from the `BitVec`.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_bit_vec_get( | ||||
|         this: *const BitVec, | ||||
|         index: usize, | ||||
|     ) -> bool { | ||||
|         (*this).get(index) | ||||
|     } | ||||
| 
 | ||||
|     /// Sets the value of a bit in the `BitVec`.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_bit_vec_set( | ||||
|         this: *mut BitVec, | ||||
|         index: usize, | ||||
|         value: bool, | ||||
|     ) -> bool { | ||||
|         (*this).set(index, value) | ||||
|     } | ||||
| 
 | ||||
|     /// Sets the value of all bits in the `BitVec`.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_bit_vec_fill(this: *mut BitVec, value: bool) { | ||||
|         (*this).fill(value) | ||||
|     } | ||||
| 
 | ||||
|     /// Gets the length of the `BitVec` in bits.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_bit_vec_len(this: *const BitVec) -> usize { | ||||
|         (*this).len() | ||||
|     } | ||||
| 
 | ||||
|     /// Returns true if length is 0.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_bit_vec_is_empty(this: *const BitVec) -> bool { | ||||
|         (*this).is_empty() | ||||
|     } | ||||
| 
 | ||||
|     /// Gets an unsafe reference to the data of the `BitVec` instance.
 | ||||
|     ///
 | ||||
|     /// ## Safety
 | ||||
|     ///
 | ||||
|     /// The caller has to make sure to never access the returned memory after the `BitVec`
 | ||||
|     /// instance has been consumed or manually deallocated.
 | ||||
|     ///
 | ||||
|     /// Reading and writing concurrently to either the original instance or the returned data will
 | ||||
|     /// result in undefined behavior.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_bit_vec_unsafe_data_ref( | ||||
|         this: *mut BitVec, | ||||
|     ) -> CByteSlice { | ||||
|         let data = (*this).data_ref_mut(); | ||||
|         CByteSlice { | ||||
|             start: data.as_mut_ptr_range().start, | ||||
|             length: data.len(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use crate::{BitVec, DataRef}; | ||||
|  |  | |||
|  | @ -108,119 +108,6 @@ impl From<ByteGrid> for Vec<u8> { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(feature = "c_api")] | ||||
| pub mod c_api { | ||||
|     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`.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_byte_grid_new( | ||||
|         width: usize, | ||||
|         height: usize, | ||||
|     ) -> *mut ByteGrid { | ||||
|         Box::into_raw(Box::new(ByteGrid::new(width, height))) | ||||
|     } | ||||
| 
 | ||||
|     /// Loads a `ByteGrid` with the specified dimensions from the provided data.
 | ||||
|     /// The returned instance has to be freed with `byte_grid_dealloc`.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_byte_grid_load( | ||||
|         width: usize, | ||||
|         height: usize, | ||||
|         data: *const u8, | ||||
|         data_length: usize, | ||||
|     ) -> *mut ByteGrid { | ||||
|         let data = std::slice::from_raw_parts(data, data_length); | ||||
|         Box::into_raw(Box::new(ByteGrid::load(width, height, data))) | ||||
|     } | ||||
| 
 | ||||
|     /// Clones a `ByteGrid`.
 | ||||
|     /// The returned instance has to be freed with `byte_grid_dealloc`.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_byte_grid_clone( | ||||
|         this: *const ByteGrid, | ||||
|     ) -> *mut ByteGrid { | ||||
|         Box::into_raw(Box::new((*this).clone())) | ||||
|     } | ||||
| 
 | ||||
|     /// Deallocates a `ByteGrid`.
 | ||||
|     ///
 | ||||
|     /// Note: do not call this if the grid has been consumed in another way, e.g. to create a command.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_byte_grid_dealloc(this: *mut ByteGrid) { | ||||
|         _ = Box::from_raw(this); | ||||
|     } | ||||
| 
 | ||||
|     /// Get the current value at the specified position
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_byte_grid_get( | ||||
|         this: *const ByteGrid, | ||||
|         x: usize, | ||||
|         y: usize, | ||||
|     ) -> u8 { | ||||
|         (*this).get(x, y) | ||||
|     } | ||||
| 
 | ||||
|     /// Sets the current value at the specified position
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_byte_grid_set( | ||||
|         this: *mut ByteGrid, | ||||
|         x: usize, | ||||
|         y: usize, | ||||
|         value: u8, | ||||
|     ) { | ||||
|         (*this).set(x, y, value); | ||||
|     } | ||||
| 
 | ||||
|     /// Fills the whole `ByteGrid` with the specified value
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_byte_grid_fill( | ||||
|         this: *mut ByteGrid, | ||||
|         value: u8, | ||||
|     ) { | ||||
|         (*this).fill(value); | ||||
|     } | ||||
| 
 | ||||
|     /// Gets the width in pixels of the `ByteGrid` instance.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_byte_grid_width( | ||||
|         this: *const ByteGrid, | ||||
|     ) -> usize { | ||||
|         (*this).width | ||||
|     } | ||||
| 
 | ||||
|     /// Gets the height in pixels of the `ByteGrid` instance.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_byte_grid_height( | ||||
|         this: *const ByteGrid, | ||||
|     ) -> usize { | ||||
|         (*this).height | ||||
|     } | ||||
| 
 | ||||
|     /// Gets an unsafe reference to the data of the `ByteGrid` instance.
 | ||||
|     ///
 | ||||
|     /// ## Safety
 | ||||
|     ///
 | ||||
|     /// The caller has to make sure to never access the returned memory after the `ByteGrid`
 | ||||
|     /// instance has been consumed or manually deallocated.
 | ||||
|     ///
 | ||||
|     /// Reading and writing concurrently to either the original instance or the returned data will
 | ||||
|     /// result in undefined behavior.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_byte_grid_unsafe_data_ref( | ||||
|         this: *mut ByteGrid, | ||||
|     ) -> CByteSlice { | ||||
|         let data = (*this).data_ref_mut(); | ||||
|         CByteSlice { | ||||
|             start: data.as_mut_ptr_range().start, | ||||
|             length: data.len(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use crate::{ByteGrid, DataRef, Grid}; | ||||
|  |  | |||
|  | @ -391,179 +391,6 @@ impl Command { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(feature = "c_api")] | ||||
| pub mod c_api { | ||||
|     use std::ptr::null_mut; | ||||
| 
 | ||||
|     use crate::{ | ||||
|         BitVec, Brightness, ByteGrid, Command, CompressionCode, Offset, Origin, | ||||
|         Packet, PixelGrid, | ||||
|     }; | ||||
| 
 | ||||
|     /// Tries to turn a `Packet` into a `Command`. The packet is gets deallocated in the process.
 | ||||
|     ///
 | ||||
|     /// Returns: pointer to command or NULL
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_command_try_from_packet( | ||||
|         packet: *mut Packet, | ||||
|     ) -> *mut Command { | ||||
|         let packet = *Box::from_raw(packet); | ||||
|         match Command::try_from(packet) { | ||||
|             Err(_) => null_mut(), | ||||
|             Ok(command) => Box::into_raw(Box::new(command)), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Clones a `Command` instance
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_command_clone( | ||||
|         original: *const Command, | ||||
|     ) -> *mut Command { | ||||
|         Box::into_raw(Box::new((*original).clone())) | ||||
|     } | ||||
| 
 | ||||
|     /// Allocates a new `Command::Clear` instance
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_command_clear() -> *mut Command { | ||||
|         Box::into_raw(Box::new(Command::Clear)) | ||||
|     } | ||||
| 
 | ||||
|     /// Allocates a new `Command::HardReset` instance
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_command_hard_reset() -> *mut Command { | ||||
|         Box::into_raw(Box::new(Command::HardReset)) | ||||
|     } | ||||
| 
 | ||||
|     /// Allocates a new `Command::FadeOut` instance
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_command_fade_out() -> *mut Command { | ||||
|         Box::into_raw(Box::new(Command::FadeOut)) | ||||
|     } | ||||
| 
 | ||||
|     /// Allocates a new `Command::Brightness` instance
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_command_brightness( | ||||
|         brightness: Brightness, | ||||
|     ) -> *mut Command { | ||||
|         Box::into_raw(Box::new(Command::Brightness(brightness))) | ||||
|     } | ||||
| 
 | ||||
|     /// Allocates a new `Command::CharBrightness` instance.
 | ||||
|     /// The passed `ByteGrid` gets deallocated in the process.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_command_char_brightness( | ||||
|         x: usize, | ||||
|         y: usize, | ||||
|         byte_grid: *mut ByteGrid, | ||||
|     ) -> *mut Command { | ||||
|         let byte_grid = *Box::from_raw(byte_grid); | ||||
|         Box::into_raw(Box::new(Command::CharBrightness( | ||||
|             Origin(x, y), | ||||
|             byte_grid, | ||||
|         ))) | ||||
|     } | ||||
| 
 | ||||
|     /// Allocates a new `Command::BitmapLinear` instance.
 | ||||
|     /// The passed `BitVec` gets deallocated in the process.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_command_bitmap_linear( | ||||
|         offset: Offset, | ||||
|         bit_vec: *mut BitVec, | ||||
|         compression: CompressionCode, | ||||
|     ) -> *mut Command { | ||||
|         let bit_vec = *Box::from_raw(bit_vec); | ||||
|         Box::into_raw(Box::new(Command::BitmapLinear( | ||||
|             offset, | ||||
|             bit_vec, | ||||
|             compression, | ||||
|         ))) | ||||
|     } | ||||
| 
 | ||||
|     /// Allocates a new `Command::BitmapLinearAnd` instance.
 | ||||
|     /// The passed `BitVec` gets deallocated in the process.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_command_bitmap_linear_and( | ||||
|         offset: Offset, | ||||
|         bit_vec: *mut BitVec, | ||||
|         compression: CompressionCode, | ||||
|     ) -> *mut Command { | ||||
|         let bit_vec = *Box::from_raw(bit_vec); | ||||
|         Box::into_raw(Box::new(Command::BitmapLinearAnd( | ||||
|             offset, | ||||
|             bit_vec, | ||||
|             compression, | ||||
|         ))) | ||||
|     } | ||||
| 
 | ||||
|     /// Allocates a new `Command::BitmapLinearOr` instance.
 | ||||
|     /// The passed `BitVec` gets deallocated in the process.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_command_bitmap_linear_or( | ||||
|         offset: Offset, | ||||
|         bit_vec: *mut BitVec, | ||||
|         compression: CompressionCode, | ||||
|     ) -> *mut Command { | ||||
|         let bit_vec = *Box::from_raw(bit_vec); | ||||
|         Box::into_raw(Box::new(Command::BitmapLinearOr( | ||||
|             offset, | ||||
|             bit_vec, | ||||
|             compression, | ||||
|         ))) | ||||
|     } | ||||
| 
 | ||||
|     /// Allocates a new `Command::BitmapLinearXor` instance.
 | ||||
|     /// The passed `BitVec` gets deallocated in the process.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_command_bitmap_linear_xor( | ||||
|         offset: Offset, | ||||
|         bit_vec: *mut BitVec, | ||||
|         compression: CompressionCode, | ||||
|     ) -> *mut Command { | ||||
|         let bit_vec = *Box::from_raw(bit_vec); | ||||
|         Box::into_raw(Box::new(Command::BitmapLinearXor( | ||||
|             offset, | ||||
|             bit_vec, | ||||
|             compression, | ||||
|         ))) | ||||
|     } | ||||
| 
 | ||||
|     /// Allocates a new `Command::Cp437Data` instance.
 | ||||
|     /// The passed `ByteGrid` gets deallocated in the process.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_command_cp437_data( | ||||
|         x: usize, | ||||
|         y: usize, | ||||
|         byte_grid: *mut ByteGrid, | ||||
|     ) -> *mut Command { | ||||
|         let byte_grid = *Box::from_raw(byte_grid); | ||||
|         Box::into_raw(Box::new(Command::Cp437Data(Origin(x, y), byte_grid))) | ||||
|     } | ||||
| 
 | ||||
|     /// Allocates a new `Command::BitmapLinearWin` instance.
 | ||||
|     /// The passed `PixelGrid` gets deallocated in the process.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_command_bitmap_linear_win( | ||||
|         x: usize, | ||||
|         y: usize, | ||||
|         byte_grid: *mut PixelGrid, | ||||
|         compression_code: CompressionCode, | ||||
|     ) -> *mut Command { | ||||
|         let byte_grid = *Box::from_raw(byte_grid); | ||||
|         Box::into_raw(Box::new(Command::BitmapLinearWin( | ||||
|             Origin(x, y), | ||||
|             byte_grid, | ||||
|             compression_code, | ||||
|         ))) | ||||
|     } | ||||
| 
 | ||||
|     /// Deallocates a `Command`. Note that connection_send does this implicitly, so you only need
 | ||||
|     /// to do this if you use the library for parsing commands.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_command_dealloc(ptr: *mut Command) { | ||||
|         _ = Box::from_raw(ptr); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use crate::command::TryFromPacketError; | ||||
|  |  | |||
|  | @ -10,8 +10,6 @@ pub struct Connection { | |||
|     socket: UdpSocket, | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| impl Connection { | ||||
|     /// Open a new UDP socket and connect to the provided host.
 | ||||
|     ///
 | ||||
|  | @ -64,7 +62,10 @@ impl Connection { | |||
|     ///  connection.send(Command::BitmapLinearWin(servicepoint::Origin(0, 0), pixels, CompressionCode::Uncompressed))
 | ||||
|     ///     .expect("send failed");
 | ||||
|     /// ```
 | ||||
|     pub fn send(&self, packet: impl Into<Packet>) -> Result<(), std::io::Error> { | ||||
|     pub fn send( | ||||
|         &self, | ||||
|         packet: impl Into<Packet>, | ||||
|     ) -> Result<(), std::io::Error> { | ||||
|         let packet = packet.into(); | ||||
|         debug!("sending {packet:?}"); | ||||
|         let data: Vec<u8> = packet.into(); | ||||
|  | @ -72,46 +73,3 @@ impl Connection { | |||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(feature = "c_api")] | ||||
| pub mod c_api { | ||||
|     use std::ffi::{c_char, CStr}; | ||||
|     use std::ptr::null_mut; | ||||
| 
 | ||||
|     use crate::{Connection, Packet}; | ||||
| 
 | ||||
|     /// Creates a new instance of Connection.
 | ||||
|     /// The returned instance has to be deallocated with `connection_dealloc`.
 | ||||
|     ///
 | ||||
|     /// returns: NULL if connection fails or connected instance
 | ||||
|     ///
 | ||||
|     /// Panics: bad string encoding
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_connection_open( | ||||
|         host: *const c_char, | ||||
|     ) -> *mut Connection { | ||||
|         let host = CStr::from_ptr(host).to_str().expect("Bad encoding"); | ||||
|         let connection = match Connection::open(host) { | ||||
|             Err(_) => return null_mut(), | ||||
|             Ok(value) => value, | ||||
|         }; | ||||
| 
 | ||||
|         Box::into_raw(Box::new(connection)) | ||||
|     } | ||||
| 
 | ||||
|     /// Sends the command instance. The instance is consumed / destroyed and cannot be used after this call.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_connection_send( | ||||
|         connection: *const Connection, | ||||
|         command_ptr: *mut Packet, | ||||
|     ) -> bool { | ||||
|         let packet = Box::from_raw(command_ptr); | ||||
|         (*connection).send(*packet).is_ok() | ||||
|     } | ||||
| 
 | ||||
|     /// Closes and deallocates a connection instance
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_connection_dealloc(ptr: *mut Connection) { | ||||
|         _ = Box::from_raw(ptr); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -2,8 +2,6 @@ use std::time::Duration; | |||
| 
 | ||||
| pub use crate::bit_vec::BitVec; | ||||
| pub use crate::byte_grid::ByteGrid; | ||||
| #[cfg(feature = "c_api")] | ||||
| pub use crate::c_slice::CByteSlice; | ||||
| pub use crate::command::{Brightness, Command, Offset, Origin}; | ||||
| pub use crate::compression_code::CompressionCode; | ||||
| pub use crate::connection::Connection; | ||||
|  | @ -14,7 +12,6 @@ pub use crate::pixel_grid::PixelGrid; | |||
| 
 | ||||
| mod bit_vec; | ||||
| mod byte_grid; | ||||
| mod c_slice; | ||||
| mod command; | ||||
| mod command_code; | ||||
| mod compression; | ||||
|  |  | |||
|  | @ -58,46 +58,6 @@ impl TryFrom<&[u8]> for Packet { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(feature = "c_api")] | ||||
| mod c_api { | ||||
|     use std::ptr::null_mut; | ||||
| 
 | ||||
|     use crate::{Command, Packet}; | ||||
| 
 | ||||
|     /// Turns a `Command` into a `Packet`. The command gets deallocated in the process.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_packet_from_command( | ||||
|         command: *mut Command, | ||||
|     ) -> *mut Packet { | ||||
|         let command = *Box::from_raw(command); | ||||
|         let packet = command.into(); | ||||
|         Box::into_raw(Box::new(packet)) | ||||
|     } | ||||
| 
 | ||||
|     /// Tries to load a `Packet` from the passed array with the specified length.
 | ||||
|     ///
 | ||||
|     /// returns: NULL in case of an error, pointer to the allocated packet otherwise
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_packet_try_load( | ||||
|         data: *const u8, | ||||
|         length: usize, | ||||
|     ) -> *mut Packet { | ||||
|         let data = std::slice::from_raw_parts(data, length); | ||||
|         match Packet::try_from(data) { | ||||
|             Err(_) => null_mut(), | ||||
|             Ok(packet) => Box::into_raw(Box::new(packet)), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Deallocates a `Packet`.
 | ||||
|     ///
 | ||||
|     /// Note: do not call this if the instance has been consumed in another way, e.g. by sending it.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_packet_dealloc(this: *mut Packet) { | ||||
|         _ = Box::from_raw(this) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use crate::{Header, Packet}; | ||||
|  |  | |||
|  | @ -127,118 +127,6 @@ impl From<PixelGrid> for Vec<u8> { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(feature = "c_api")] | ||||
| pub mod c_api { | ||||
|     use crate::c_slice::CByteSlice; | ||||
|     use crate::{DataRef, Grid, PixelGrid}; | ||||
| 
 | ||||
|     /// Creates a new `PixelGrid` instance.
 | ||||
|     /// The returned instance has to be freed with `pixel_grid_dealloc`.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_pixel_grid_new( | ||||
|         width: usize, | ||||
|         height: usize, | ||||
|     ) -> *mut PixelGrid { | ||||
|         Box::into_raw(Box::new(PixelGrid::new(width, height))) | ||||
|     } | ||||
| 
 | ||||
|     /// Loads a `PixelGrid` with the specified dimensions from the provided data.
 | ||||
|     /// The returned instance has to be freed with `pixel_grid_dealloc`.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_pixel_grid_load( | ||||
|         width: usize, | ||||
|         height: usize, | ||||
|         data: *const u8, | ||||
|         data_length: usize, | ||||
|     ) -> *mut PixelGrid { | ||||
|         let data = std::slice::from_raw_parts(data, data_length); | ||||
|         Box::into_raw(Box::new(PixelGrid::load(width, height, data))) | ||||
|     } | ||||
| 
 | ||||
|     /// Clones a `PixelGrid`.
 | ||||
|     /// The returned instance has to be freed with `pixel_grid_dealloc`.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_pixel_grid_clone( | ||||
|         this: *const PixelGrid, | ||||
|     ) -> *mut PixelGrid { | ||||
|         Box::into_raw(Box::new((*this).clone())) | ||||
|     } | ||||
| 
 | ||||
|     /// Deallocates a `PixelGrid`.
 | ||||
|     ///
 | ||||
|     /// Note: do not call this if the grid has been consumed in another way, e.g. to create a command.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_pixel_grid_dealloc(this: *mut PixelGrid) { | ||||
|         _ = Box::from_raw(this); | ||||
|     } | ||||
| 
 | ||||
|     /// Get the current value at the specified position
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_pixel_grid_get( | ||||
|         this: *const PixelGrid, | ||||
|         x: usize, | ||||
|         y: usize, | ||||
|     ) -> bool { | ||||
|         (*this).get(x, y) | ||||
|     } | ||||
| 
 | ||||
|     /// Sets the current value at the specified position
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_pixel_grid_set( | ||||
|         this: *mut PixelGrid, | ||||
|         x: usize, | ||||
|         y: usize, | ||||
|         value: bool, | ||||
|     ) { | ||||
|         (*this).set(x, y, value); | ||||
|     } | ||||
| 
 | ||||
|     /// Fills the whole `PixelGrid` with the specified value
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_pixel_grid_fill( | ||||
|         this: *mut PixelGrid, | ||||
|         value: bool, | ||||
|     ) { | ||||
|         (*this).fill(value); | ||||
|     } | ||||
| 
 | ||||
|     /// Gets the width in pixels of the `PixelGrid` instance.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_pixel_grid_width( | ||||
|         this: *const PixelGrid, | ||||
|     ) -> usize { | ||||
|         (*this).width | ||||
|     } | ||||
| 
 | ||||
|     /// Gets the height in pixels of the `PixelGrid` instance.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_pixel_grid_height( | ||||
|         this: *const PixelGrid, | ||||
|     ) -> usize { | ||||
|         (*this).height | ||||
|     } | ||||
| 
 | ||||
|     /// Gets an unsafe reference to the data of the `PixelGrid` instance.
 | ||||
|     ///
 | ||||
|     /// ## Safety
 | ||||
|     ///
 | ||||
|     /// The caller has to make sure to never access the returned memory after the `PixelGrid`
 | ||||
|     /// instance has been consumed or manually deallocated.
 | ||||
|     ///
 | ||||
|     /// Reading and writing concurrently to either the original instance or the returned data will
 | ||||
|     /// result in undefined behavior.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_pixel_grid_unsafe_data_ref( | ||||
|         this: *mut PixelGrid, | ||||
|     ) -> CByteSlice { | ||||
|         let data = (*this).data_ref_mut(); | ||||
|         CByteSlice { | ||||
|             start: data.as_mut_ptr_range().start, | ||||
|             length: data.len(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use crate::{DataRef, Grid, PixelGrid}; | ||||
|  |  | |||
|  | @ -10,5 +10,13 @@ repository = "https://github.com/cccb/servicepoint" | |||
| readme = "../../README.md" | ||||
| links = "servicepoint" | ||||
| 
 | ||||
| [lib] | ||||
| crate-type = ["staticlib", "cdylib", "rlib"] | ||||
| 
 | ||||
| [build-dependencies] | ||||
| cbindgen = "0.26.0" | ||||
| 
 | ||||
| [dependencies.servicepoint] | ||||
| version = "0.4.2" | ||||
| path = "../servicepoint" | ||||
| features = ["all_compressions"] | ||||
|  |  | |||
|  | @ -8,12 +8,11 @@ fn main() { | |||
| 
 | ||||
|     let config = | ||||
|         Config::from_file(crate_dir.clone() + "/cbindgen.toml").unwrap(); | ||||
|     let servicepoint_dir = crate_dir.clone() + "/../servicepoint"; | ||||
| 
 | ||||
|     let output_dir = env::var("OUT_DIR").unwrap(); | ||||
|     let header_file = output_dir.clone() + "/servicepoint.h"; | ||||
| 
 | ||||
|     generate_with_config(servicepoint_dir, config) | ||||
|     generate_with_config(crate_dir, config) | ||||
|         .unwrap() | ||||
|         .write_to_file(&header_file); | ||||
|     println!("cargo:include={output_dir}"); | ||||
|  |  | |||
|  | @ -19,17 +19,18 @@ sort_by = "Name" | |||
| usize_is_size_t = true | ||||
| 
 | ||||
| [defines] | ||||
| "feature = compression_zlib" = "SP2_FEATURE_compression_zlib" | ||||
| "feature = compression_bzip2" = "SP2_FEATURE_compression_bzip2" | ||||
| "feature = compression_lzma" = "SP2_FEATURE_compression_lzma" | ||||
| "feature = compression_zstd" = "SP2_FEATURE_compression_zstd" | ||||
| #"feature = compression_zlib" = "SP_FEATURE_compression_zlib" | ||||
| #"feature = compression_bzip2" = "SP_FEATURE_compression_bzip2" | ||||
| #"feature = compression_lzma" = "SP_FEATURE_compression_lzma" | ||||
| #"feature = compression_zstd" = "SP_FEATURE_compression_zstd" | ||||
| 
 | ||||
| [export] | ||||
| prefix = "sp2_" | ||||
| prefix = "sp_" | ||||
| 
 | ||||
| [parse] | ||||
| #include = ["servicepoint"] | ||||
| parse_deps = true | ||||
| include = ["servicepoint"] | ||||
| extra_bindings = ["servicepoint"] | ||||
| 
 | ||||
| [parse.expand] | ||||
| features = ["c-api"] | ||||
| all_features = true | ||||
| #all_features = true | ||||
|  |  | |||
							
								
								
									
										94
									
								
								crates/servicepoint_binding_c/src/bit_vec.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								crates/servicepoint_binding_c/src/bit_vec.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,94 @@ | |||
| pub use servicepoint::BitVec; | ||||
| use servicepoint::DataRef; | ||||
| 
 | ||||
| use crate::c_slice::CByteSlice; | ||||
| 
 | ||||
| /// Creates a new `BitVec` instance.
 | ||||
| /// The returned instance has to be freed with `bit_vec_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_new(size: usize) -> *mut BitVec { | ||||
|     Box::into_raw(Box::new(BitVec::new(size))) | ||||
| } | ||||
| 
 | ||||
| /// Loads a `BitVec` from the provided data.
 | ||||
| /// The returned instance has to be freed with `bit_vec_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_load( | ||||
|     data: *const u8, | ||||
|     data_length: usize, | ||||
| ) -> *mut BitVec { | ||||
|     let data = std::slice::from_raw_parts(data, data_length); | ||||
|     Box::into_raw(Box::new(BitVec::from(data))) | ||||
| } | ||||
| 
 | ||||
| /// Clones a `BitVec`.
 | ||||
| /// The returned instance has to be freed with `bit_vec_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_clone(this: *const BitVec) -> *mut BitVec { | ||||
|     Box::into_raw(Box::new((*this).clone())) | ||||
| } | ||||
| 
 | ||||
| /// Deallocates a `BitVec`.
 | ||||
| ///
 | ||||
| /// Note: do not call this if the grid has been consumed in another way, e.g. to create a command.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_dealloc(this: *mut BitVec) { | ||||
|     _ = Box::from_raw(this); | ||||
| } | ||||
| 
 | ||||
| /// Gets the value of a bit from the `BitVec`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_get( | ||||
|     this: *const BitVec, | ||||
|     index: usize, | ||||
| ) -> bool { | ||||
|     (*this).get(index) | ||||
| } | ||||
| 
 | ||||
| /// Sets the value of a bit in the `BitVec`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_set( | ||||
|     this: *mut BitVec, | ||||
|     index: usize, | ||||
|     value: bool, | ||||
| ) -> bool { | ||||
|     (*this).set(index, value) | ||||
| } | ||||
| 
 | ||||
| /// Sets the value of all bits in the `BitVec`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_fill(this: *mut BitVec, value: bool) { | ||||
|     (*this).fill(value) | ||||
| } | ||||
| 
 | ||||
| /// Gets the length of the `BitVec` in bits.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_len(this: *const BitVec) -> usize { | ||||
|     (*this).len() | ||||
| } | ||||
| 
 | ||||
| /// Returns true if length is 0.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_is_empty(this: *const BitVec) -> bool { | ||||
|     (*this).is_empty() | ||||
| } | ||||
| 
 | ||||
| /// Gets an unsafe reference to the data of the `BitVec` instance.
 | ||||
| ///
 | ||||
| /// ## Safety
 | ||||
| ///
 | ||||
| /// The caller has to make sure to never access the returned memory after the `BitVec`
 | ||||
| /// instance has been consumed or manually deallocated.
 | ||||
| ///
 | ||||
| /// Reading and writing concurrently to either the original instance or the returned data will
 | ||||
| /// result in undefined behavior.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_unsafe_data_ref( | ||||
|     this: *mut BitVec, | ||||
| ) -> CByteSlice { | ||||
|     let data = (*this).data_ref_mut(); | ||||
|     CByteSlice { | ||||
|         start: data.as_mut_ptr_range().start, | ||||
|         length: data.len(), | ||||
|     } | ||||
| } | ||||
							
								
								
									
										103
									
								
								crates/servicepoint_binding_c/src/byte_grid.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								crates/servicepoint_binding_c/src/byte_grid.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,103 @@ | |||
| pub use servicepoint::ByteGrid; | ||||
| use servicepoint::{DataRef, Grid}; | ||||
| 
 | ||||
| use crate::c_slice::CByteSlice; | ||||
| 
 | ||||
| /// Creates a new `ByteGrid` instance.
 | ||||
| /// The returned instance has to be freed with `byte_grid_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_byte_grid_new( | ||||
|     width: usize, | ||||
|     height: usize, | ||||
| ) -> *mut ByteGrid { | ||||
|     Box::into_raw(Box::new(ByteGrid::new(width, height))) | ||||
| } | ||||
| 
 | ||||
| /// Loads a `ByteGrid` with the specified dimensions from the provided data.
 | ||||
| /// The returned instance has to be freed with `byte_grid_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_byte_grid_load( | ||||
|     width: usize, | ||||
|     height: usize, | ||||
|     data: *const u8, | ||||
|     data_length: usize, | ||||
| ) -> *mut ByteGrid { | ||||
|     let data = std::slice::from_raw_parts(data, data_length); | ||||
|     Box::into_raw(Box::new(ByteGrid::load(width, height, data))) | ||||
| } | ||||
| 
 | ||||
| /// Clones a `ByteGrid`.
 | ||||
| /// The returned instance has to be freed with `byte_grid_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_byte_grid_clone( | ||||
|     this: *const ByteGrid, | ||||
| ) -> *mut ByteGrid { | ||||
|     Box::into_raw(Box::new((*this).clone())) | ||||
| } | ||||
| 
 | ||||
| /// Deallocates a `ByteGrid`.
 | ||||
| ///
 | ||||
| /// Note: do not call this if the grid has been consumed in another way, e.g. to create a command.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_byte_grid_dealloc(this: *mut ByteGrid) { | ||||
|     _ = Box::from_raw(this); | ||||
| } | ||||
| 
 | ||||
| /// Get the current value at the specified position
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_byte_grid_get( | ||||
|     this: *const ByteGrid, | ||||
|     x: usize, | ||||
|     y: usize, | ||||
| ) -> u8 { | ||||
|     (*this).get(x, y) | ||||
| } | ||||
| 
 | ||||
| /// Sets the current value at the specified position
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_byte_grid_set( | ||||
|     this: *mut ByteGrid, | ||||
|     x: usize, | ||||
|     y: usize, | ||||
|     value: u8, | ||||
| ) { | ||||
|     (*this).set(x, y, value); | ||||
| } | ||||
| 
 | ||||
| /// Fills the whole `ByteGrid` with the specified value
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_byte_grid_fill(this: *mut ByteGrid, value: u8) { | ||||
|     (*this).fill(value); | ||||
| } | ||||
| 
 | ||||
| /// Gets the width in pixels of the `ByteGrid` instance.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_byte_grid_width(this: *const ByteGrid) -> usize { | ||||
|     (*this).width() | ||||
| } | ||||
| 
 | ||||
| /// Gets the height in pixels of the `ByteGrid` instance.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_byte_grid_height(this: *const ByteGrid) -> usize { | ||||
|     (*this).height() | ||||
| } | ||||
| 
 | ||||
| /// Gets an unsafe reference to the data of the `ByteGrid` instance.
 | ||||
| ///
 | ||||
| /// ## Safety
 | ||||
| ///
 | ||||
| /// The caller has to make sure to never access the returned memory after the `ByteGrid`
 | ||||
| /// instance has been consumed or manually deallocated.
 | ||||
| ///
 | ||||
| /// Reading and writing concurrently to either the original instance or the returned data will
 | ||||
| /// result in undefined behavior.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_byte_grid_unsafe_data_ref( | ||||
|     this: *mut ByteGrid, | ||||
| ) -> CByteSlice { | ||||
|     let data = (*this).data_ref_mut(); | ||||
|     CByteSlice { | ||||
|         start: data.as_mut_ptr_range().start, | ||||
|         length: data.len(), | ||||
|     } | ||||
| } | ||||
|  | @ -1,4 +1,3 @@ | |||
| #[cfg(feature = "c_api")] | ||||
| #[repr(C)] | ||||
| /// Represents a span of memory (`&mut [u8]` ) as a struct usable by C code.
 | ||||
| ///
 | ||||
							
								
								
									
										166
									
								
								crates/servicepoint_binding_c/src/command.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								crates/servicepoint_binding_c/src/command.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,166 @@ | |||
| use std::ptr::null_mut; | ||||
| 
 | ||||
| use servicepoint::{ | ||||
|     BitVec, ByteGrid, CompressionCode, Origin, Packet, PixelGrid, | ||||
| }; | ||||
| pub use servicepoint::{Brightness, Command, Offset}; | ||||
| 
 | ||||
| /// Tries to turn a `Packet` into a `Command`. The packet is gets deallocated in the process.
 | ||||
| ///
 | ||||
| /// Returns: pointer to command or NULL
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_try_from_packet( | ||||
|     packet: *mut Packet, | ||||
| ) -> *mut Command { | ||||
|     let packet = *Box::from_raw(packet); | ||||
|     match Command::try_from(packet) { | ||||
|         Err(_) => null_mut(), | ||||
|         Ok(command) => Box::into_raw(Box::new(command)), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Clones a `Command` instance
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_clone( | ||||
|     original: *const Command, | ||||
| ) -> *mut Command { | ||||
|     Box::into_raw(Box::new((*original).clone())) | ||||
| } | ||||
| 
 | ||||
| /// Allocates a new `Command::Clear` instance
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_clear() -> *mut Command { | ||||
|     Box::into_raw(Box::new(Command::Clear)) | ||||
| } | ||||
| 
 | ||||
| /// Allocates a new `Command::HardReset` instance
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_hard_reset() -> *mut Command { | ||||
|     Box::into_raw(Box::new(Command::HardReset)) | ||||
| } | ||||
| 
 | ||||
| /// Allocates a new `Command::FadeOut` instance
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_fade_out() -> *mut Command { | ||||
|     Box::into_raw(Box::new(Command::FadeOut)) | ||||
| } | ||||
| 
 | ||||
| /// Allocates a new `Command::Brightness` instance
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_brightness( | ||||
|     brightness: Brightness, | ||||
| ) -> *mut Command { | ||||
|     Box::into_raw(Box::new(Command::Brightness(brightness))) | ||||
| } | ||||
| 
 | ||||
| /// Allocates a new `Command::CharBrightness` instance.
 | ||||
| /// The passed `ByteGrid` gets deallocated in the process.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_char_brightness( | ||||
|     x: usize, | ||||
|     y: usize, | ||||
|     byte_grid: *mut ByteGrid, | ||||
| ) -> *mut Command { | ||||
|     let byte_grid = *Box::from_raw(byte_grid); | ||||
|     Box::into_raw(Box::new(Command::CharBrightness(Origin(x, y), byte_grid))) | ||||
| } | ||||
| 
 | ||||
| /// Allocates a new `Command::BitmapLinear` instance.
 | ||||
| /// The passed `BitVec` gets deallocated in the process.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_bitmap_linear( | ||||
|     offset: Offset, | ||||
|     bit_vec: *mut BitVec, | ||||
|     compression: CompressionCode, | ||||
| ) -> *mut Command { | ||||
|     let bit_vec = *Box::from_raw(bit_vec); | ||||
|     Box::into_raw(Box::new(Command::BitmapLinear( | ||||
|         offset, | ||||
|         bit_vec, | ||||
|         compression, | ||||
|     ))) | ||||
| } | ||||
| 
 | ||||
| /// Allocates a new `Command::BitmapLinearAnd` instance.
 | ||||
| /// The passed `BitVec` gets deallocated in the process.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_bitmap_linear_and( | ||||
|     offset: Offset, | ||||
|     bit_vec: *mut BitVec, | ||||
|     compression: CompressionCode, | ||||
| ) -> *mut Command { | ||||
|     let bit_vec = *Box::from_raw(bit_vec); | ||||
|     Box::into_raw(Box::new(Command::BitmapLinearAnd( | ||||
|         offset, | ||||
|         bit_vec, | ||||
|         compression, | ||||
|     ))) | ||||
| } | ||||
| 
 | ||||
| /// Allocates a new `Command::BitmapLinearOr` instance.
 | ||||
| /// The passed `BitVec` gets deallocated in the process.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_bitmap_linear_or( | ||||
|     offset: Offset, | ||||
|     bit_vec: *mut BitVec, | ||||
|     compression: CompressionCode, | ||||
| ) -> *mut Command { | ||||
|     let bit_vec = *Box::from_raw(bit_vec); | ||||
|     Box::into_raw(Box::new(Command::BitmapLinearOr( | ||||
|         offset, | ||||
|         bit_vec, | ||||
|         compression, | ||||
|     ))) | ||||
| } | ||||
| 
 | ||||
| /// Allocates a new `Command::BitmapLinearXor` instance.
 | ||||
| /// The passed `BitVec` gets deallocated in the process.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_bitmap_linear_xor( | ||||
|     offset: Offset, | ||||
|     bit_vec: *mut BitVec, | ||||
|     compression: CompressionCode, | ||||
| ) -> *mut Command { | ||||
|     let bit_vec = *Box::from_raw(bit_vec); | ||||
|     Box::into_raw(Box::new(Command::BitmapLinearXor( | ||||
|         offset, | ||||
|         bit_vec, | ||||
|         compression, | ||||
|     ))) | ||||
| } | ||||
| 
 | ||||
| /// Allocates a new `Command::Cp437Data` instance.
 | ||||
| /// The passed `ByteGrid` gets deallocated in the process.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_cp437_data( | ||||
|     x: usize, | ||||
|     y: usize, | ||||
|     byte_grid: *mut ByteGrid, | ||||
| ) -> *mut Command { | ||||
|     let byte_grid = *Box::from_raw(byte_grid); | ||||
|     Box::into_raw(Box::new(Command::Cp437Data(Origin(x, y), byte_grid))) | ||||
| } | ||||
| 
 | ||||
| /// Allocates a new `Command::BitmapLinearWin` instance.
 | ||||
| /// The passed `PixelGrid` gets deallocated in the process.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_bitmap_linear_win( | ||||
|     x: usize, | ||||
|     y: usize, | ||||
|     byte_grid: *mut PixelGrid, | ||||
|     compression_code: CompressionCode, | ||||
| ) -> *mut Command { | ||||
|     let byte_grid = *Box::from_raw(byte_grid); | ||||
|     Box::into_raw(Box::new(Command::BitmapLinearWin( | ||||
|         Origin(x, y), | ||||
|         byte_grid, | ||||
|         compression_code, | ||||
|     ))) | ||||
| } | ||||
| 
 | ||||
| /// Deallocates a `Command`. Note that connection_send does this implicitly, so you only need
 | ||||
| /// to do this if you use the library for parsing commands.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_dealloc(ptr: *mut Command) { | ||||
|     _ = Box::from_raw(ptr); | ||||
| } | ||||
							
								
								
									
										40
									
								
								crates/servicepoint_binding_c/src/connection.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								crates/servicepoint_binding_c/src/connection.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | |||
| use std::ffi::{c_char, CStr}; | ||||
| use std::ptr::null_mut; | ||||
| 
 | ||||
| pub use servicepoint::Connection; | ||||
| use servicepoint::Packet; | ||||
| 
 | ||||
| /// Creates a new instance of Connection.
 | ||||
| /// The returned instance has to be deallocated with `connection_dealloc`.
 | ||||
| ///
 | ||||
| /// returns: NULL if connection fails or connected instance
 | ||||
| ///
 | ||||
| /// Panics: bad string encoding
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_connection_open( | ||||
|     host: *const c_char, | ||||
| ) -> *mut Connection { | ||||
|     let host = CStr::from_ptr(host).to_str().expect("Bad encoding"); | ||||
|     let connection = match Connection::open(host) { | ||||
|         Err(_) => return null_mut(), | ||||
|         Ok(value) => value, | ||||
|     }; | ||||
| 
 | ||||
|     Box::into_raw(Box::new(connection)) | ||||
| } | ||||
| 
 | ||||
| /// Sends the command instance. The instance is consumed / destroyed and cannot be used after this call.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_connection_send( | ||||
|     connection: *const Connection, | ||||
|     command_ptr: *mut Packet, | ||||
| ) -> bool { | ||||
|     let packet = Box::from_raw(command_ptr); | ||||
|     (*connection).send(*packet).is_ok() | ||||
| } | ||||
| 
 | ||||
| /// Closes and deallocates a connection instance
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_connection_dealloc(ptr: *mut Connection) { | ||||
|     _ = Box::from_raw(ptr); | ||||
| } | ||||
|  | @ -0,0 +1,14 @@ | |||
| pub use servicepoint::{ | ||||
|     CompressionCode, PIXEL_COUNT, PIXEL_HEIGHT, PIXEL_WIDTH, TILE_HEIGHT, | ||||
|     TILE_SIZE, TILE_WIDTH, | ||||
| }; | ||||
| 
 | ||||
| pub mod bit_vec; | ||||
| pub mod byte_grid; | ||||
| pub mod c_slice; | ||||
| pub mod command; | ||||
| pub mod connection; | ||||
| pub mod packet; | ||||
| pub mod pixel_grid; | ||||
| 
 | ||||
| pub const FRAME_PACING_MS: u32 = servicepoint::FRAME_PACING.as_millis() as u32; | ||||
							
								
								
									
										37
									
								
								crates/servicepoint_binding_c/src/packet.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								crates/servicepoint_binding_c/src/packet.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | |||
| use std::ptr::null_mut; | ||||
| 
 | ||||
| use servicepoint::Command; | ||||
| pub use servicepoint::Packet; | ||||
| 
 | ||||
| /// Turns a `Command` into a `Packet`. The command gets deallocated in the process.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_packet_from_command( | ||||
|     command: *mut Command, | ||||
| ) -> *mut Packet { | ||||
|     let command = *Box::from_raw(command); | ||||
|     let packet = command.into(); | ||||
|     Box::into_raw(Box::new(packet)) | ||||
| } | ||||
| 
 | ||||
| /// Tries to load a `Packet` from the passed array with the specified length.
 | ||||
| ///
 | ||||
| /// returns: NULL in case of an error, pointer to the allocated packet otherwise
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_packet_try_load( | ||||
|     data: *const u8, | ||||
|     length: usize, | ||||
| ) -> *mut Packet { | ||||
|     let data = std::slice::from_raw_parts(data, length); | ||||
|     match Packet::try_from(data) { | ||||
|         Err(_) => null_mut(), | ||||
|         Ok(packet) => Box::into_raw(Box::new(packet)), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Deallocates a `Packet`.
 | ||||
| ///
 | ||||
| /// Note: do not call this if the instance has been consumed in another way, e.g. by sending it.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_packet_dealloc(this: *mut Packet) { | ||||
|     _ = Box::from_raw(this) | ||||
| } | ||||
							
								
								
									
										102
									
								
								crates/servicepoint_binding_c/src/pixel_grid.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								crates/servicepoint_binding_c/src/pixel_grid.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,102 @@ | |||
| use servicepoint::{DataRef, Grid, PixelGrid}; | ||||
| 
 | ||||
| use crate::c_slice::CByteSlice; | ||||
| 
 | ||||
| /// Creates a new `PixelGrid` instance.
 | ||||
| /// The returned instance has to be freed with `pixel_grid_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_new( | ||||
|     width: usize, | ||||
|     height: usize, | ||||
| ) -> *mut PixelGrid { | ||||
|     Box::into_raw(Box::new(PixelGrid::new(width, height))) | ||||
| } | ||||
| 
 | ||||
| /// Loads a `PixelGrid` with the specified dimensions from the provided data.
 | ||||
| /// The returned instance has to be freed with `pixel_grid_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_load( | ||||
|     width: usize, | ||||
|     height: usize, | ||||
|     data: *const u8, | ||||
|     data_length: usize, | ||||
| ) -> *mut PixelGrid { | ||||
|     let data = std::slice::from_raw_parts(data, data_length); | ||||
|     Box::into_raw(Box::new(PixelGrid::load(width, height, data))) | ||||
| } | ||||
| 
 | ||||
| /// Clones a `PixelGrid`.
 | ||||
| /// The returned instance has to be freed with `pixel_grid_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_clone( | ||||
|     this: *const PixelGrid, | ||||
| ) -> *mut PixelGrid { | ||||
|     Box::into_raw(Box::new((*this).clone())) | ||||
| } | ||||
| 
 | ||||
| /// Deallocates a `PixelGrid`.
 | ||||
| ///
 | ||||
| /// Note: do not call this if the grid has been consumed in another way, e.g. to create a command.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_dealloc(this: *mut PixelGrid) { | ||||
|     _ = Box::from_raw(this); | ||||
| } | ||||
| 
 | ||||
| /// Get the current value at the specified position
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_get( | ||||
|     this: *const PixelGrid, | ||||
|     x: usize, | ||||
|     y: usize, | ||||
| ) -> bool { | ||||
|     (*this).get(x, y) | ||||
| } | ||||
| 
 | ||||
| /// Sets the current value at the specified position
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_set( | ||||
|     this: *mut PixelGrid, | ||||
|     x: usize, | ||||
|     y: usize, | ||||
|     value: bool, | ||||
| ) { | ||||
|     (*this).set(x, y, value); | ||||
| } | ||||
| 
 | ||||
| /// Fills the whole `PixelGrid` with the specified value
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_fill(this: *mut PixelGrid, value: bool) { | ||||
|     (*this).fill(value); | ||||
| } | ||||
| 
 | ||||
| /// Gets the width in pixels of the `PixelGrid` instance.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_width(this: *const PixelGrid) -> usize { | ||||
|     (*this).width() | ||||
| } | ||||
| 
 | ||||
| /// Gets the height in pixels of the `PixelGrid` instance.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_height(this: *const PixelGrid) -> usize { | ||||
|     (*this).height() | ||||
| } | ||||
| 
 | ||||
| /// Gets an unsafe reference to the data of the `PixelGrid` instance.
 | ||||
| ///
 | ||||
| /// ## Safety
 | ||||
| ///
 | ||||
| /// The caller has to make sure to never access the returned memory after the `PixelGrid`
 | ||||
| /// instance has been consumed or manually deallocated.
 | ||||
| ///
 | ||||
| /// Reading and writing concurrently to either the original instance or the returned data will
 | ||||
| /// result in undefined behavior.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_unsafe_data_ref( | ||||
|     this: *mut PixelGrid, | ||||
| ) -> CByteSlice { | ||||
|     let data = (*this).data_ref_mut(); | ||||
|     CByteSlice { | ||||
|         start: data.as_mut_ptr_range().start, | ||||
|         length: data.len(), | ||||
|     } | ||||
| } | ||||
|  | @ -8,8 +8,8 @@ readme = "../../README.md" | |||
| [lib] | ||||
| crate-type = ["cdylib"] | ||||
| 
 | ||||
| [dependencies] | ||||
| servicepoint = { path = "../servicepoint", features = ["c_api"] } | ||||
| 
 | ||||
| [build-dependencies] | ||||
| csbindgen = "1.8.0" | ||||
| 
 | ||||
| [dependencies] | ||||
| servicepoint_binding_c = { path = "../servicepoint_binding_c" } | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
|  | ||||
| Microsoft Visual Studio Solution File, Format Version 12.00 | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServicePoint", "src/ServicePoint.csproj", "{70EFFA3F-012A-4518-9627-466BEAE4252E}" | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServicePoint", "ServicePoint/ServicePoint.csproj", "{70EFFA3F-012A-4518-9627-466BEAE4252E}" | ||||
| EndProject | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "lang-cs", "../examples/lang_cs/lang_cs.csproj", "{DA3B8B6E-993A-47DA-844B-F92AF520FF59}" | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "lang-cs", "../../examples/lang_cs/lang_cs.csproj", "{DA3B8B6E-993A-47DA-844B-F92AF520FF59}" | ||||
| EndProject | ||||
| Global | ||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
|  |  | |||
|  | @ -12,218 +12,228 @@ namespace ServicePoint.BindGen | |||
| { | ||||
|     public static unsafe partial class NativeMethods | ||||
|     { | ||||
|         const string __DllName = "servicepoint"; | ||||
|         const string __DllName = "servicepoint_binding_c"; | ||||
| 
 | ||||
|         public const nuint TILE_SIZE = 8; | ||||
|         public const nuint TILE_WIDTH = 56; | ||||
|         public const nuint TILE_HEIGHT = 20; | ||||
| 
 | ||||
| 
 | ||||
|         /// <summary>Creates a new `BitVec` instance. The returned instance has to be freed with `bit_vec_dealloc`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_bit_vec_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern BitVec* sp2_bit_vec_new(nuint size); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern BitVec* sp_bit_vec_new(nuint size); | ||||
| 
 | ||||
|         /// <summary>Loads a `BitVec` from the provided data. The returned instance has to be freed with `bit_vec_dealloc`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_bit_vec_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern BitVec* sp2_bit_vec_load(byte* data, nuint data_length); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern BitVec* sp_bit_vec_load(byte* data, nuint data_length); | ||||
| 
 | ||||
|         /// <summary>Clones a `BitVec`. The returned instance has to be freed with `bit_vec_dealloc`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_bit_vec_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern BitVec* sp2_bit_vec_clone(BitVec* @this); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern BitVec* sp_bit_vec_clone(BitVec* @this); | ||||
| 
 | ||||
|         /// <summary>Deallocates a `BitVec`.  Note: do not call this if the grid has been consumed in another way, e.g. to create a command.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_bit_vec_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp2_bit_vec_dealloc(BitVec* @this); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp_bit_vec_dealloc(BitVec* @this); | ||||
| 
 | ||||
|         /// <summary>Gets the value of a bit from the `BitVec`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_bit_vec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         [return: MarshalAs(UnmanagedType.U1)] | ||||
|         public static extern bool sp2_bit_vec_get(BitVec* @this, nuint index); | ||||
|         public static extern bool sp_bit_vec_get(BitVec* @this, nuint index); | ||||
| 
 | ||||
|         /// <summary>Sets the value of a bit in the `BitVec`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_bit_vec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         [return: MarshalAs(UnmanagedType.U1)] | ||||
|         public static extern bool sp2_bit_vec_set(BitVec* @this, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); | ||||
|         public static extern bool sp_bit_vec_set(BitVec* @this, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); | ||||
| 
 | ||||
|         /// <summary>Sets the value of all bits in the `BitVec`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_bit_vec_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp2_bit_vec_fill(BitVec* @this, [MarshalAs(UnmanagedType.U1)] bool value); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp_bit_vec_fill(BitVec* @this, [MarshalAs(UnmanagedType.U1)] bool value); | ||||
| 
 | ||||
|         /// <summary>Gets the length of the `BitVec` in bits.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_bit_vec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern nuint sp2_bit_vec_len(BitVec* @this); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern nuint sp_bit_vec_len(BitVec* @this); | ||||
| 
 | ||||
|         /// <summary>Returns true if length is 0.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_bit_vec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         [return: MarshalAs(UnmanagedType.U1)] | ||||
|         public static extern bool sp2_bit_vec_is_empty(BitVec* @this); | ||||
|         public static extern bool sp_bit_vec_is_empty(BitVec* @this); | ||||
| 
 | ||||
|         /// <summary>Gets an unsafe reference to the data of the `BitVec` instance.  ## Safety  The caller has to make sure to never access the returned memory after the `BitVec` instance has been consumed or manually deallocated.  Reading and writing concurrently to either the original instance or the returned data will result in undefined behavior.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_bit_vec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern CByteSlice sp2_bit_vec_unsafe_data_ref(BitVec* @this); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_bit_vec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern CByteSlice sp_bit_vec_unsafe_data_ref(BitVec* @this); | ||||
| 
 | ||||
|         /// <summary>Creates a new `ByteGrid` instance. The returned instance has to be freed with `byte_grid_dealloc`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_byte_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern ByteGrid* sp2_byte_grid_new(nuint width, nuint height); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_byte_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern ByteGrid* sp_byte_grid_new(nuint width, nuint height); | ||||
| 
 | ||||
|         /// <summary>Loads a `ByteGrid` with the specified dimensions from the provided data. The returned instance has to be freed with `byte_grid_dealloc`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_byte_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern ByteGrid* sp2_byte_grid_load(nuint width, nuint height, byte* data, nuint data_length); | ||||
|         [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); | ||||
| 
 | ||||
|         /// <summary>Clones a `ByteGrid`. The returned instance has to be freed with `byte_grid_dealloc`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_byte_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern ByteGrid* sp2_byte_grid_clone(ByteGrid* @this); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_byte_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern ByteGrid* sp_byte_grid_clone(ByteGrid* @this); | ||||
| 
 | ||||
|         /// <summary>Deallocates a `ByteGrid`.  Note: do not call this if the grid has been consumed in another way, e.g. to create a command.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_byte_grid_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp2_byte_grid_dealloc(ByteGrid* @this); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_byte_grid_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp_byte_grid_dealloc(ByteGrid* @this); | ||||
| 
 | ||||
|         /// <summary>Get the current value at the specified position</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_byte_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern byte sp2_byte_grid_get(ByteGrid* @this, nuint x, nuint y); | ||||
|         [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); | ||||
| 
 | ||||
|         /// <summary>Sets the current value at the specified position</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_byte_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp2_byte_grid_set(ByteGrid* @this, nuint x, nuint y, byte value); | ||||
|         [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); | ||||
| 
 | ||||
|         /// <summary>Fills the whole `ByteGrid` with the specified value</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_byte_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp2_byte_grid_fill(ByteGrid* @this, byte value); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_byte_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp_byte_grid_fill(ByteGrid* @this, byte value); | ||||
| 
 | ||||
|         /// <summary>Gets the width in pixels of the `ByteGrid` instance.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_byte_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern nuint sp2_byte_grid_width(ByteGrid* @this); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_byte_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern nuint sp_byte_grid_width(ByteGrid* @this); | ||||
| 
 | ||||
|         /// <summary>Gets the height in pixels of the `ByteGrid` instance.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_byte_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern nuint sp2_byte_grid_height(ByteGrid* @this); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_byte_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern nuint sp_byte_grid_height(ByteGrid* @this); | ||||
| 
 | ||||
|         /// <summary>Gets an unsafe reference to the data of the `ByteGrid` instance.  ## Safety  The caller has to make sure to never access the returned memory after the `ByteGrid` instance has been consumed or manually deallocated.  Reading and writing concurrently to either the original instance or the returned data will result in undefined behavior.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_byte_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern CByteSlice sp2_byte_grid_unsafe_data_ref(ByteGrid* @this); | ||||
|         [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); | ||||
| 
 | ||||
|         /// <summary>Tries to turn a `Packet` into a `Command`. The packet is gets deallocated in the process.  Returns: pointer to command or NULL</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_try_from_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp2_command_try_from_packet(Packet* packet); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_command_try_from_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp_command_try_from_packet(Packet* packet); | ||||
| 
 | ||||
|         /// <summary>Clones a `Command` instance</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp2_command_clone(Command* original); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_command_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp_command_clone(Command* original); | ||||
| 
 | ||||
|         /// <summary>Allocates a new `Command::Clear` instance</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_clear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp2_command_clear(); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_command_clear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp_command_clear(); | ||||
| 
 | ||||
|         /// <summary>Allocates a new `Command::HardReset` instance</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_hard_reset", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp2_command_hard_reset(); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_command_hard_reset", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp_command_hard_reset(); | ||||
| 
 | ||||
|         /// <summary>Allocates a new `Command::FadeOut` instance</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_fade_out", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp2_command_fade_out(); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_command_fade_out", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp_command_fade_out(); | ||||
| 
 | ||||
|         /// <summary>Allocates a new `Command::Brightness` instance</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp2_command_brightness(byte brightness); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_command_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp_command_brightness(byte brightness); | ||||
| 
 | ||||
|         /// <summary>Allocates a new `Command::CharBrightness` instance. The passed `ByteGrid` gets deallocated in the process.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_char_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp2_command_char_brightness(nuint x, nuint y, ByteGrid* byte_grid); | ||||
|         [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); | ||||
| 
 | ||||
|         /// <summary>Allocates a new `Command::BitmapLinear` instance. The passed `BitVec` gets deallocated in the process.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_bitmap_linear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp2_command_bitmap_linear(nuint offset, BitVec* bit_vec, CompressionCode compression); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp_command_bitmap_linear(nuint offset, BitVec* bit_vec, CompressionCode compression); | ||||
| 
 | ||||
|         /// <summary>Allocates a new `Command::BitmapLinearAnd` instance. The passed `BitVec` gets deallocated in the process.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_bitmap_linear_and", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp2_command_bitmap_linear_and(nuint offset, BitVec* bit_vec, CompressionCode compression); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_and", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp_command_bitmap_linear_and(nuint offset, BitVec* bit_vec, CompressionCode compression); | ||||
| 
 | ||||
|         /// <summary>Allocates a new `Command::BitmapLinearOr` instance. The passed `BitVec` gets deallocated in the process.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_bitmap_linear_or", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp2_command_bitmap_linear_or(nuint offset, BitVec* bit_vec, CompressionCode compression); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_or", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp_command_bitmap_linear_or(nuint offset, BitVec* bit_vec, CompressionCode compression); | ||||
| 
 | ||||
|         /// <summary>Allocates a new `Command::BitmapLinearXor` instance. The passed `BitVec` gets deallocated in the process.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_bitmap_linear_xor", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp2_command_bitmap_linear_xor(nuint offset, BitVec* bit_vec, CompressionCode compression); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_xor", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp_command_bitmap_linear_xor(nuint offset, BitVec* bit_vec, CompressionCode compression); | ||||
| 
 | ||||
|         /// <summary>Allocates a new `Command::Cp437Data` instance. The passed `ByteGrid` gets deallocated in the process.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_cp437_data", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp2_command_cp437_data(nuint x, nuint y, ByteGrid* byte_grid); | ||||
|         [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); | ||||
| 
 | ||||
|         /// <summary>Allocates a new `Command::BitmapLinearWin` instance. The passed `PixelGrid` gets deallocated in the process.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_bitmap_linear_win", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp2_command_bitmap_linear_win(nuint x, nuint y, PixelGrid* byte_grid, CompressionCode compression_code); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_win", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp_command_bitmap_linear_win(nuint x, nuint y, PixelGrid* byte_grid, CompressionCode compression_code); | ||||
| 
 | ||||
|         /// <summary>Deallocates a `Command`. Note that connection_send does this implicitly, so you only need to do this if you use the library for parsing commands.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp2_command_dealloc(Command* ptr); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_command_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp_command_dealloc(Command* ptr); | ||||
| 
 | ||||
|         /// <summary>Creates a new instance of Connection. The returned instance has to be deallocated with `connection_dealloc`.  returns: NULL if connection fails or connected instance  Panics: bad string encoding</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_connection_open", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Connection* sp2_connection_open(byte* host); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_connection_open", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Connection* sp_connection_open(byte* host); | ||||
| 
 | ||||
|         /// <summary>Sends the command instance. The instance is consumed / destroyed and cannot be used after this call.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_connection_send", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         [DllImport(__DllName, EntryPoint = "sp_connection_send", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         [return: MarshalAs(UnmanagedType.U1)] | ||||
|         public static extern bool sp2_connection_send(Connection* connection, Packet* command_ptr); | ||||
|         public static extern bool sp_connection_send(Connection* connection, Packet* command_ptr); | ||||
| 
 | ||||
|         /// <summary>Closes and deallocates a connection instance</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_connection_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp2_connection_dealloc(Connection* ptr); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_connection_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp_connection_dealloc(Connection* ptr); | ||||
| 
 | ||||
|         /// <summary>Creates a new `PixelGrid` instance. The returned instance has to be freed with `pixel_grid_dealloc`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern PixelGrid* sp2_pixel_grid_new(nuint width, nuint height); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_pixel_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern PixelGrid* sp_pixel_grid_new(nuint width, nuint height); | ||||
| 
 | ||||
|         /// <summary>Loads a `PixelGrid` with the specified dimensions from the provided data. The returned instance has to be freed with `pixel_grid_dealloc`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern PixelGrid* sp2_pixel_grid_load(nuint width, nuint height, byte* data, nuint data_length); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_pixel_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern PixelGrid* sp_pixel_grid_load(nuint width, nuint height, byte* data, nuint data_length); | ||||
| 
 | ||||
|         /// <summary>Clones a `PixelGrid`. The returned instance has to be freed with `pixel_grid_dealloc`.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern PixelGrid* sp2_pixel_grid_clone(PixelGrid* @this); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_pixel_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern PixelGrid* sp_pixel_grid_clone(PixelGrid* @this); | ||||
| 
 | ||||
|         /// <summary>Deallocates a `PixelGrid`.  Note: do not call this if the grid has been consumed in another way, e.g. to create a command.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp2_pixel_grid_dealloc(PixelGrid* @this); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_pixel_grid_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp_pixel_grid_dealloc(PixelGrid* @this); | ||||
| 
 | ||||
|         /// <summary>Get the current value at the specified position</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         [DllImport(__DllName, EntryPoint = "sp_pixel_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         [return: MarshalAs(UnmanagedType.U1)] | ||||
|         public static extern bool sp2_pixel_grid_get(PixelGrid* @this, nuint x, nuint y); | ||||
|         public static extern bool sp_pixel_grid_get(PixelGrid* @this, nuint x, nuint y); | ||||
| 
 | ||||
|         /// <summary>Sets the current value at the specified position</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp2_pixel_grid_set(PixelGrid* @this, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_pixel_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp_pixel_grid_set(PixelGrid* @this, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value); | ||||
| 
 | ||||
|         /// <summary>Fills the whole `PixelGrid` with the specified value</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp2_pixel_grid_fill(PixelGrid* @this, [MarshalAs(UnmanagedType.U1)] bool value); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_pixel_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp_pixel_grid_fill(PixelGrid* @this, [MarshalAs(UnmanagedType.U1)] bool value); | ||||
| 
 | ||||
|         /// <summary>Gets the width in pixels of the `PixelGrid` instance.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern nuint sp2_pixel_grid_width(PixelGrid* @this); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_pixel_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern nuint sp_pixel_grid_width(PixelGrid* @this); | ||||
| 
 | ||||
|         /// <summary>Gets the height in pixels of the `PixelGrid` instance.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern nuint sp2_pixel_grid_height(PixelGrid* @this); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_pixel_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern nuint sp_pixel_grid_height(PixelGrid* @this); | ||||
| 
 | ||||
|         /// <summary>Gets an unsafe reference to the data of the `PixelGrid` instance.  ## Safety  The caller has to make sure to never access the returned memory after the `PixelGrid` instance has been consumed or manually deallocated.  Reading and writing concurrently to either the original instance or the returned data will result in undefined behavior.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_pixel_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern CByteSlice sp2_pixel_grid_unsafe_data_ref(PixelGrid* @this); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_pixel_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern CByteSlice sp_pixel_grid_unsafe_data_ref(PixelGrid* @this); | ||||
| 
 | ||||
|         /// <summary>Turns a `Command` into a `Packet`. The command gets deallocated in the process.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_packet_from_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Packet* sp2_packet_from_command(Command* command); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_packet_from_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Packet* sp_packet_from_command(Command* command); | ||||
| 
 | ||||
|         /// <summary>Tries to load a `Packet` from the passed array with the specified length.  returns: NULL in case of an error, pointer to the allocated packet otherwise</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_packet_try_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Packet* sp2_packet_try_load(byte* data, nuint length); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_packet_try_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Packet* sp_packet_try_load(byte* data, nuint length); | ||||
| 
 | ||||
|         /// <summary>Deallocates a `Packet`.  Note: do not call this if the instance has been consumed in another way, e.g. by sending it.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_packet_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp2_packet_dealloc(Packet* @this); | ||||
|         [DllImport(__DllName, EntryPoint = "sp_packet_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern void sp_packet_dealloc(Packet* @this); | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     [StructLayout(LayoutKind.Sequential)] | ||||
|     public unsafe partial struct CByteSlice | ||||
|     { | ||||
|         public byte* start; | ||||
|         public nuint length; | ||||
|     } | ||||
| 
 | ||||
|     [StructLayout(LayoutKind.Sequential)] | ||||
|     public unsafe partial struct BitVec | ||||
|     { | ||||
|  | @ -244,13 +254,6 @@ namespace ServicePoint.BindGen | |||
|     { | ||||
|     } | ||||
| 
 | ||||
|     [StructLayout(LayoutKind.Sequential)] | ||||
|     public unsafe partial struct CByteSlice | ||||
|     { | ||||
|         public byte* start; | ||||
|         public nuint length; | ||||
|     } | ||||
| 
 | ||||
|     [StructLayout(LayoutKind.Sequential)] | ||||
|     public unsafe partial struct Packet | ||||
|     { | ||||
|  | @ -8,7 +8,7 @@ public sealed class BitVec : SpNativeInstance<BindGen.BitVec> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return new BitVec(NativeMethods.sp2_bit_vec_new((nuint)size)); | ||||
|             return new BitVec(NativeMethods.sp_bit_vec_new((nuint)size)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -18,7 +18,7 @@ public sealed class BitVec : SpNativeInstance<BindGen.BitVec> | |||
|         { | ||||
|             fixed (byte* bytesPtr = bytes) | ||||
|             { | ||||
|                 return new BitVec(NativeMethods.sp2_bit_vec_load(bytesPtr, (nuint)bytes.Length)); | ||||
|                 return new BitVec(NativeMethods.sp_bit_vec_load(bytesPtr, (nuint)bytes.Length)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -27,7 +27,7 @@ public sealed class BitVec : SpNativeInstance<BindGen.BitVec> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return new BitVec(NativeMethods.sp2_bit_vec_clone(Instance)); | ||||
|             return new BitVec(NativeMethods.sp_bit_vec_clone(Instance)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -37,14 +37,14 @@ public sealed class BitVec : SpNativeInstance<BindGen.BitVec> | |||
|         { | ||||
|             unsafe | ||||
|             { | ||||
|                 return NativeMethods.sp2_bit_vec_get(Instance, (nuint)index); | ||||
|                 return NativeMethods.sp_bit_vec_get(Instance, (nuint)index); | ||||
|             } | ||||
|         } | ||||
|         set | ||||
|         { | ||||
|             unsafe | ||||
|             { | ||||
|                 NativeMethods.sp2_bit_vec_set(Instance, (nuint)index, value); | ||||
|                 NativeMethods.sp_bit_vec_set(Instance, (nuint)index, value); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -53,7 +53,7 @@ public sealed class BitVec : SpNativeInstance<BindGen.BitVec> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             NativeMethods.sp2_bit_vec_fill(Instance, value); | ||||
|             NativeMethods.sp_bit_vec_fill(Instance, value); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -63,7 +63,7 @@ public sealed class BitVec : SpNativeInstance<BindGen.BitVec> | |||
|         { | ||||
|             unsafe | ||||
|             { | ||||
|                 return (int)NativeMethods.sp2_bit_vec_len(Instance); | ||||
|                 return (int)NativeMethods.sp_bit_vec_len(Instance); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -74,7 +74,7 @@ public sealed class BitVec : SpNativeInstance<BindGen.BitVec> | |||
|         { | ||||
|             unsafe | ||||
|             { | ||||
|                 var slice = NativeMethods.sp2_bit_vec_unsafe_data_ref(Instance); | ||||
|                 var slice = NativeMethods.sp_bit_vec_unsafe_data_ref(Instance); | ||||
|                 return new Span<byte>(slice.start, (int)slice.length); | ||||
|             } | ||||
|         } | ||||
|  | @ -86,6 +86,6 @@ public sealed class BitVec : SpNativeInstance<BindGen.BitVec> | |||
| 
 | ||||
|     private protected override unsafe void Dealloc() | ||||
|     { | ||||
|         NativeMethods.sp2_bit_vec_dealloc(Instance); | ||||
|         NativeMethods.sp_bit_vec_dealloc(Instance); | ||||
|     } | ||||
| } | ||||
|  | @ -9,7 +9,7 @@ public sealed class ByteGrid : SpNativeInstance<BindGen.ByteGrid> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return new ByteGrid(NativeMethods.sp2_byte_grid_new((nuint)width, (nuint)height)); | ||||
|             return new ByteGrid(NativeMethods.sp_byte_grid_new((nuint)width, (nuint)height)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -19,7 +19,7 @@ public sealed class ByteGrid : SpNativeInstance<BindGen.ByteGrid> | |||
|         { | ||||
|             fixed (byte* bytesPtr = bytes) | ||||
|             { | ||||
|                 return new ByteGrid(NativeMethods.sp2_byte_grid_load((nuint)width, (nuint)height, bytesPtr, | ||||
|                 return new ByteGrid(NativeMethods.sp_byte_grid_load((nuint)width, (nuint)height, bytesPtr, | ||||
|                     (nuint)bytes.Length)); | ||||
|             } | ||||
|         } | ||||
|  | @ -29,7 +29,7 @@ public sealed class ByteGrid : SpNativeInstance<BindGen.ByteGrid> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return new ByteGrid(NativeMethods.sp2_byte_grid_clone(Instance)); | ||||
|             return new ByteGrid(NativeMethods.sp_byte_grid_clone(Instance)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -39,14 +39,14 @@ public sealed class ByteGrid : SpNativeInstance<BindGen.ByteGrid> | |||
|         { | ||||
|             unsafe | ||||
|             { | ||||
|                 return NativeMethods.sp2_byte_grid_get(Instance, (nuint)x, (nuint)y); | ||||
|                 return NativeMethods.sp_byte_grid_get(Instance, (nuint)x, (nuint)y); | ||||
|             } | ||||
|         } | ||||
|         set | ||||
|         { | ||||
|             unsafe | ||||
|             { | ||||
|                 NativeMethods.sp2_byte_grid_set(Instance, (nuint)x, (nuint)y, value); | ||||
|                 NativeMethods.sp_byte_grid_set(Instance, (nuint)x, (nuint)y, value); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -85,7 +85,7 @@ public sealed class ByteGrid : SpNativeInstance<BindGen.ByteGrid> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             NativeMethods.sp2_byte_grid_fill(Instance, value); | ||||
|             NativeMethods.sp_byte_grid_fill(Instance, value); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -95,7 +95,7 @@ public sealed class ByteGrid : SpNativeInstance<BindGen.ByteGrid> | |||
|         { | ||||
|             unsafe | ||||
|             { | ||||
|                 return (int)NativeMethods.sp2_byte_grid_width(Instance); | ||||
|                 return (int)NativeMethods.sp_byte_grid_width(Instance); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -106,7 +106,7 @@ public sealed class ByteGrid : SpNativeInstance<BindGen.ByteGrid> | |||
|         { | ||||
|             unsafe | ||||
|             { | ||||
|                 return (int)NativeMethods.sp2_byte_grid_height(Instance); | ||||
|                 return (int)NativeMethods.sp_byte_grid_height(Instance); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -117,7 +117,7 @@ public sealed class ByteGrid : SpNativeInstance<BindGen.ByteGrid> | |||
|         { | ||||
|             unsafe | ||||
|             { | ||||
|                 var slice = NativeMethods.sp2_byte_grid_unsafe_data_ref(Instance); | ||||
|                 var slice = NativeMethods.sp_byte_grid_unsafe_data_ref(Instance); | ||||
|                 return new Span<byte>(slice.start, (int)slice.length); | ||||
|             } | ||||
|         } | ||||
|  | @ -129,6 +129,6 @@ public sealed class ByteGrid : SpNativeInstance<BindGen.ByteGrid> | |||
| 
 | ||||
|     private protected override unsafe void Dealloc() | ||||
|     { | ||||
|         NativeMethods.sp2_byte_grid_dealloc(Instance); | ||||
|         NativeMethods.sp_byte_grid_dealloc(Instance); | ||||
|     } | ||||
| } | ||||
|  | @ -9,7 +9,7 @@ public sealed class Command : SpNativeInstance<BindGen.Command> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             var result = NativeMethods.sp2_command_try_from_packet(packet.Into()); | ||||
|             var result = NativeMethods.sp_command_try_from_packet(packet.Into()); | ||||
|             if (result == null) | ||||
|             { | ||||
|                 command = null; | ||||
|  | @ -25,7 +25,7 @@ public sealed class Command : SpNativeInstance<BindGen.Command> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return new Command(NativeMethods.sp2_command_clone(Instance)); | ||||
|             return new Command(NativeMethods.sp_command_clone(Instance)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -33,7 +33,7 @@ public sealed class Command : SpNativeInstance<BindGen.Command> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return new Command(NativeMethods.sp2_command_clear()); | ||||
|             return new Command(NativeMethods.sp_command_clear()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -41,7 +41,7 @@ public sealed class Command : SpNativeInstance<BindGen.Command> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return new Command(NativeMethods.sp2_command_hard_reset()); | ||||
|             return new Command(NativeMethods.sp_command_hard_reset()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -49,7 +49,7 @@ public sealed class Command : SpNativeInstance<BindGen.Command> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return new Command(NativeMethods.sp2_command_fade_out()); | ||||
|             return new Command(NativeMethods.sp_command_fade_out()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -57,7 +57,7 @@ public sealed class Command : SpNativeInstance<BindGen.Command> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return new Command(NativeMethods.sp2_command_brightness(brightness)); | ||||
|             return new Command(NativeMethods.sp_command_brightness(brightness)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -65,7 +65,7 @@ public sealed class Command : SpNativeInstance<BindGen.Command> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return new Command(NativeMethods.sp2_command_char_brightness((ushort)x, (ushort)y, grid.Into())); | ||||
|             return new Command(NativeMethods.sp_command_char_brightness((ushort)x, (ushort)y, grid.Into())); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -74,7 +74,7 @@ public sealed class Command : SpNativeInstance<BindGen.Command> | |||
|         unsafe | ||||
|         { | ||||
|             return new Command( | ||||
|                 NativeMethods.sp2_command_bitmap_linear((ushort)offset, bitVec.Into(), compressionCode)); | ||||
|                 NativeMethods.sp_command_bitmap_linear((ushort)offset, bitVec.Into(), compressionCode)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -83,7 +83,7 @@ public sealed class Command : SpNativeInstance<BindGen.Command> | |||
|         unsafe | ||||
|         { | ||||
|             return new Command( | ||||
|                 NativeMethods.sp2_command_bitmap_linear_and((ushort)offset, bitVec.Into(), compressionCode)); | ||||
|                 NativeMethods.sp_command_bitmap_linear_and((ushort)offset, bitVec.Into(), compressionCode)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -92,7 +92,7 @@ public sealed class Command : SpNativeInstance<BindGen.Command> | |||
|         unsafe | ||||
|         { | ||||
|             return new Command( | ||||
|                 NativeMethods.sp2_command_bitmap_linear_or((ushort)offset, bitVec.Into(), compressionCode)); | ||||
|                 NativeMethods.sp_command_bitmap_linear_or((ushort)offset, bitVec.Into(), compressionCode)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -101,7 +101,7 @@ public sealed class Command : SpNativeInstance<BindGen.Command> | |||
|         unsafe | ||||
|         { | ||||
|             return new Command( | ||||
|                 NativeMethods.sp2_command_bitmap_linear_xor((ushort)offset, bitVec.Into(), compressionCode)); | ||||
|                 NativeMethods.sp_command_bitmap_linear_xor((ushort)offset, bitVec.Into(), compressionCode)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -109,7 +109,7 @@ public sealed class Command : SpNativeInstance<BindGen.Command> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return new Command(NativeMethods.sp2_command_bitmap_linear_win((ushort)x, (ushort)y, pixelGrid.Into(), compression)); | ||||
|             return new Command(NativeMethods.sp_command_bitmap_linear_win((ushort)x, (ushort)y, pixelGrid.Into(), compression)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -117,7 +117,7 @@ public sealed class Command : SpNativeInstance<BindGen.Command> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return new Command(NativeMethods.sp2_command_cp437_data((ushort)x, (ushort)y, byteGrid.Into())); | ||||
|             return new Command(NativeMethods.sp_command_cp437_data((ushort)x, (ushort)y, byteGrid.Into())); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -127,6 +127,6 @@ public sealed class Command : SpNativeInstance<BindGen.Command> | |||
| 
 | ||||
|     private protected override unsafe void Dealloc() | ||||
|     { | ||||
|         NativeMethods.sp2_command_dealloc(Instance); | ||||
|         NativeMethods.sp_command_dealloc(Instance); | ||||
|     } | ||||
| } | ||||
|  | @ -11,7 +11,7 @@ public sealed class Connection : SpNativeInstance<BindGen.Connection> | |||
|         { | ||||
|             fixed (byte* bytePtr = Encoding.UTF8.GetBytes(host)) | ||||
|             { | ||||
|                 return new Connection(NativeMethods.sp2_connection_open(bytePtr)); | ||||
|                 return new Connection(NativeMethods.sp_connection_open(bytePtr)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -20,13 +20,13 @@ public sealed class Connection : SpNativeInstance<BindGen.Connection> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return NativeMethods.sp2_connection_send(Instance, packet.Into()); | ||||
|             return NativeMethods.sp_connection_send(Instance, packet.Into()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private protected override unsafe void Dealloc() | ||||
|     { | ||||
|         NativeMethods.sp2_connection_dealloc(Instance); | ||||
|         NativeMethods.sp_connection_dealloc(Instance); | ||||
|     } | ||||
| 
 | ||||
|     private unsafe Connection(BindGen.Connection* instance) : base(instance) | ||||
|  | @ -9,7 +9,7 @@ public sealed class Packet : SpNativeInstance<BindGen.Packet> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return new Packet(NativeMethods.sp2_packet_from_command(command.Into())); | ||||
|             return new Packet(NativeMethods.sp_packet_from_command(command.Into())); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -19,7 +19,7 @@ public sealed class Packet : SpNativeInstance<BindGen.Packet> | |||
|         { | ||||
|             fixed (byte* bytesPtr = bytes) | ||||
|             { | ||||
|                 var instance = NativeMethods.sp2_packet_try_load(bytesPtr, (nuint)bytes.Length); | ||||
|                 var instance = NativeMethods.sp_packet_try_load(bytesPtr, (nuint)bytes.Length); | ||||
|                 packet = instance == null | ||||
|                     ? null | ||||
|                     : new Packet(instance); | ||||
|  | @ -34,6 +34,6 @@ public sealed class Packet : SpNativeInstance<BindGen.Packet> | |||
| 
 | ||||
|     private protected override unsafe void Dealloc() | ||||
|     { | ||||
|         NativeMethods.sp2_packet_dealloc(Instance); | ||||
|         NativeMethods.sp_packet_dealloc(Instance); | ||||
|     } | ||||
| } | ||||
|  | @ -8,7 +8,7 @@ public sealed class PixelGrid : SpNativeInstance<BindGen.PixelGrid> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return new PixelGrid(NativeMethods.sp2_pixel_grid_new((nuint)width, (nuint)height)); | ||||
|             return new PixelGrid(NativeMethods.sp_pixel_grid_new((nuint)width, (nuint)height)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -18,7 +18,7 @@ public sealed class PixelGrid : SpNativeInstance<BindGen.PixelGrid> | |||
|         { | ||||
|             fixed (byte* bytesPtr = bytes) | ||||
|             { | ||||
|                 return new PixelGrid(NativeMethods.sp2_pixel_grid_load((nuint)width, (nuint)height, bytesPtr, | ||||
|                 return new PixelGrid(NativeMethods.sp_pixel_grid_load((nuint)width, (nuint)height, bytesPtr, | ||||
|                     (nuint)bytes.Length)); | ||||
|             } | ||||
|         } | ||||
|  | @ -28,7 +28,7 @@ public sealed class PixelGrid : SpNativeInstance<BindGen.PixelGrid> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             return new PixelGrid(NativeMethods.sp2_pixel_grid_clone(Instance)); | ||||
|             return new PixelGrid(NativeMethods.sp_pixel_grid_clone(Instance)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -38,14 +38,14 @@ public sealed class PixelGrid : SpNativeInstance<BindGen.PixelGrid> | |||
|         { | ||||
|             unsafe | ||||
|             { | ||||
|                 return NativeMethods.sp2_pixel_grid_get(Instance, (nuint)x, (nuint)y); | ||||
|                 return NativeMethods.sp_pixel_grid_get(Instance, (nuint)x, (nuint)y); | ||||
|             } | ||||
|         } | ||||
|         set | ||||
|         { | ||||
|             unsafe | ||||
|             { | ||||
|                 NativeMethods.sp2_pixel_grid_set(Instance, (nuint)x, (nuint)y, value); | ||||
|                 NativeMethods.sp_pixel_grid_set(Instance, (nuint)x, (nuint)y, value); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -54,7 +54,7 @@ public sealed class PixelGrid : SpNativeInstance<BindGen.PixelGrid> | |||
|     { | ||||
|         unsafe | ||||
|         { | ||||
|             NativeMethods.sp2_pixel_grid_fill(Instance, value); | ||||
|             NativeMethods.sp_pixel_grid_fill(Instance, value); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -64,7 +64,7 @@ public sealed class PixelGrid : SpNativeInstance<BindGen.PixelGrid> | |||
|         { | ||||
|             unsafe | ||||
|             { | ||||
|                 return (int)NativeMethods.sp2_pixel_grid_width(Instance); | ||||
|                 return (int)NativeMethods.sp_pixel_grid_width(Instance); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -75,7 +75,7 @@ public sealed class PixelGrid : SpNativeInstance<BindGen.PixelGrid> | |||
|         { | ||||
|             unsafe | ||||
|             { | ||||
|                 return (int)NativeMethods.sp2_pixel_grid_height(Instance); | ||||
|                 return (int)NativeMethods.sp_pixel_grid_height(Instance); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -86,7 +86,7 @@ public sealed class PixelGrid : SpNativeInstance<BindGen.PixelGrid> | |||
|         { | ||||
|             unsafe | ||||
|             { | ||||
|                 var slice = NativeMethods.sp2_pixel_grid_unsafe_data_ref(Instance); | ||||
|                 var slice = NativeMethods.sp_pixel_grid_unsafe_data_ref(Instance); | ||||
|                 return new Span<byte>(slice.start, (int)slice.length); | ||||
|             } | ||||
|         } | ||||
|  | @ -98,6 +98,6 @@ public sealed class PixelGrid : SpNativeInstance<BindGen.PixelGrid> | |||
| 
 | ||||
|     private protected override unsafe void Dealloc() | ||||
|     { | ||||
|         NativeMethods.sp2_pixel_grid_dealloc(Instance); | ||||
|         NativeMethods.sp_pixel_grid_dealloc(Instance); | ||||
|     } | ||||
| } | ||||
|  | @ -26,45 +26,39 @@ | |||
|         <PublishRepositoryUrl>true</PublishRepositoryUrl> | ||||
|     </PropertyGroup> | ||||
| 
 | ||||
|     <Target Name="BuildLibrary" Condition="'$(Configuration)'=='Release'" BeforeTargets="Build"> | ||||
|         <Exec Command="cargo build --manifest-path ../../servicepoint/Cargo.toml --all-features --release"/> | ||||
|     </Target> | ||||
| 
 | ||||
|     <Target Name="BuildLibrary" Condition="'$(Configuration)'=='Debug'" BeforeTargets="Build"> | ||||
|         <Exec Command="cargo build --manifest-path ../../servicepoint/Cargo.toml --all-features"/> | ||||
|     </Target> | ||||
| 
 | ||||
|     <!-- generate C# bindings --> | ||||
|     <Target Name="BuildBindings" Condition="'$(Configuration)'=='Release'" BeforeTargets="Build"> | ||||
|         <Exec Command="cargo build --release"/> | ||||
|     </Target> | ||||
| 
 | ||||
|     <Target Name="BuildBindings" Condition="'$(Configuration)'=='Debug'" BeforeTargets="Build"> | ||||
|         <Exec Command="cargo build"/> | ||||
|     </Target> | ||||
| 
 | ||||
|     <!-- build native library to include in output --> | ||||
|     <Target Name="BuildLibrary" Condition="'$(Configuration)'=='Release'" BeforeTargets="Build"> | ||||
|         <Exec Command="cargo build --manifest-path ../../../crates/servicepoint/Cargo.toml --release"/> | ||||
|     </Target> | ||||
|     <Target Name="BuildLibrary" Condition="'$(Configuration)'=='Debug'" BeforeTargets="Build"> | ||||
|         <Exec Command="cargo build --manifest-path ../../../crates/servicepoint/Cargo.toml"/> | ||||
|     </Target> | ||||
| 
 | ||||
|     <!-- include native binary in output --> | ||||
|     <ItemGroup Condition="'$(Configuration)'=='Debug'"> | ||||
|         <Content Include="../../target/debug/libservicepoint.so" CopyToOutputDirectory="Always"> | ||||
|             <Link>libservicepoint.so</Link> | ||||
|         <Content Include="../../../target/debug/libservicepoint_binding_c.so" CopyToOutputDirectory="Always"> | ||||
|             <Link>libservicepoint_binding_c.so</Link> | ||||
|         </Content> | ||||
|     </ItemGroup> | ||||
| 
 | ||||
|     <ItemGroup Condition="'$(Configuration)'=='Release'"> | ||||
|         <Content Include="../../target/release/libservicepoint.so" CopyToOutputDirectory="Always"> | ||||
|             <Link>libservicepoint.so</Link> | ||||
|         <Content Include="../../../target/release/libservicepoint_binding_c.so" CopyToOutputDirectory="Always"> | ||||
|             <Link>libservicepoint_binding_c.so</Link> | ||||
|         </Content> | ||||
|     </ItemGroup> | ||||
| 
 | ||||
|     <ItemGroup> | ||||
|         <!-- include link to source code at revision --> | ||||
|         <None Include="../../README.md" Pack="true" PackagePath="\"/> | ||||
|         <None Include="../../../README.md" Pack="true" PackagePath="\"/> | ||||
|         <!-- add README.md to package --> | ||||
|         <PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All"/> | ||||
|     </ItemGroup> | ||||
| 
 | ||||
|     <ItemGroup> | ||||
|       <Content Include="..\build.rs"> | ||||
|         <Link>build.rs</Link> | ||||
|       </Content> | ||||
|     </ItemGroup> | ||||
| 
 | ||||
| </Project> | ||||
|  | @ -1,19 +1,28 @@ | |||
| fn main() { | ||||
|     println!("cargo:rerun-if-changed=DOESNOTEXIST"); // rebuild every time
 | ||||
|     println!("cargo:rerun-if-changed=../servicepoint_binding_c/src"); | ||||
|     println!("cargo:rerun-if-changed=build.rs"); | ||||
|     csbindgen::Builder::default() | ||||
|         .input_extern_file("../servicepoint_binding_c/src/bit_vec.rs") | ||||
|         .input_extern_file("../servicepoint_binding_c/src/byte_grid.rs") | ||||
|         .input_extern_file("../servicepoint_binding_c/src/command.rs") | ||||
|         .input_extern_file("../servicepoint_binding_c/src/connection.rs") | ||||
|         .input_extern_file("../servicepoint_binding_c/src/pixel_grid.rs") | ||||
|         .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/bit_vec.rs") | ||||
|         .input_extern_file("../servicepoint/src/byte_grid.rs") | ||||
|         .input_extern_file("../servicepoint/src/command.rs") | ||||
|         .input_extern_file("../servicepoint/src/compression_code.rs") | ||||
|         .input_extern_file("../servicepoint/src/connection.rs") | ||||
|         .input_extern_file("../servicepoint/src/pixel_grid.rs") | ||||
|         .input_extern_file("../servicepoint/src/lib.rs") | ||||
|         .input_extern_file("../servicepoint/src/c_slice.rs") | ||||
|         .input_extern_file("../servicepoint/src/packet.rs") | ||||
|         .csharp_dll_name("servicepoint") | ||||
|         .input_extern_file("../servicepoint/src/compression_code.rs") | ||||
|         .csharp_dll_name("servicepoint_binding_c") | ||||
|         .csharp_namespace("ServicePoint.BindGen") | ||||
|         .csharp_use_nint_types(true) | ||||
|         .csharp_class_accessibility("public") | ||||
|         .generate_csharp_file("src/BindGen/ServicePoint.g.cs") | ||||
|         .csharp_generate_const_filter(|_| true) | ||||
|         .generate_csharp_file("ServicePoint/BindGen/ServicePoint.g.cs") | ||||
|         .unwrap(); | ||||
| } | ||||
|  |  | |||
|  | @ -15,22 +15,19 @@ run: out/lang_c | |||
| PHONY: build clean dependencies run | ||||
| 
 | ||||
| out/lang_c: dependencies src/main.c | ||||
| 	mkdir out || true | ||||
| 	mkdir -p out || true | ||||
| 	${CC} src/main.c \
 | ||||
| 		-I include \
 | ||||
| 		-L $(REPO_ROOT)/target/release \
 | ||||
| 		-Wl,-Bstatic -lservicepoint \
 | ||||
| 		-Wl,-Bstatic -lservicepoint_binding_c \
 | ||||
| 		-Wl,-Bdynamic -llzma \
 | ||||
| 		-o out/lang_c \
 | ||||
| 		-o out/lang_c | ||||
| 
 | ||||
| dependencies: FORCE | ||||
| 	mkdir include || true | ||||
| 	# generate servicepoint header | ||||
| 	mkdir -p include || true | ||||
| 	# generate servicepoint header and binary to link against | ||||
| 	SERVICEPOINT_HEADER_OUT=$(THIS_DIR)/include cargo build \
 | ||||
| 		--manifest-path=$(REPO_ROOT)/crates/servicepoint_binding_c/Cargo.toml | ||||
| 
 | ||||
| 	# build release binary to link against | ||||
| 	cargo build --manifest-path=$(REPO_ROOT)/crates/servicepoint/Cargo.toml --release \
 | ||||
| 		--features c_api,all_compressions | ||||
| 		--manifest-path=$(REPO_ROOT)/crates/servicepoint_binding_c/Cargo.toml \
 | ||||
| 		--release | ||||
| 
 | ||||
| FORCE: ; | ||||
|  |  | |||
|  | @ -1,11 +1,12 @@ | |||
| fn main() { | ||||
|     println!("cargo::rerun-if-changed=src/main.c"); | ||||
|     println!("cargo::rerun-if-changed=build.rs"); | ||||
| const SP_INCLUDE: &str = "DEP_SERVICEPOINT_INCLUDE"; | ||||
| 
 | ||||
|     let sp_include = std::env::var_os("DEP_SERVICEPOINT_INCLUDE") | ||||
|         .unwrap() | ||||
|         .into_string() | ||||
|         .unwrap(); | ||||
| fn main() { | ||||
|     println!("cargo:rerun-if-changed=src/main.c"); | ||||
|     println!("cargo:rerun-if-changed=build.rs"); | ||||
|     println!("cargo:rerun-if-env-changed={SP_INCLUDE}"); | ||||
| 
 | ||||
|     let sp_include = | ||||
|         std::env::var_os(SP_INCLUDE).unwrap().into_string().unwrap(); | ||||
| 
 | ||||
|     // this builds a lib, this is only to check that the example compiles
 | ||||
|     let mut cc = cc::Build::new(); | ||||
|  |  | |||
|  | @ -9,95 +9,87 @@ | |||
| /**
 | ||||
|  * pixel count on whole screen | ||||
|  */ | ||||
| #define sp2_PIXEL_COUNT (sp2_PIXEL_WIDTH * sp2_PIXEL_HEIGHT) | ||||
| #define sp_PIXEL_COUNT (sp_PIXEL_WIDTH * sp_PIXEL_HEIGHT) | ||||
| 
 | ||||
| /**
 | ||||
|  * screen height in pixels | ||||
|  */ | ||||
| #define sp2_PIXEL_HEIGHT (sp2_TILE_HEIGHT * sp2_TILE_SIZE) | ||||
| #define sp_PIXEL_HEIGHT (sp_TILE_HEIGHT * sp_TILE_SIZE) | ||||
| 
 | ||||
| /**
 | ||||
|  * screen width in pixels | ||||
|  */ | ||||
| #define sp2_PIXEL_WIDTH (sp2_TILE_WIDTH * sp2_TILE_SIZE) | ||||
| #define sp_PIXEL_WIDTH (sp_TILE_WIDTH * sp_TILE_SIZE) | ||||
| 
 | ||||
| /**
 | ||||
|  * tile count in the y-direction | ||||
|  */ | ||||
| #define sp2_TILE_HEIGHT 20 | ||||
| #define sp_TILE_HEIGHT 20 | ||||
| 
 | ||||
| /**
 | ||||
|  * size of a single tile in one dimension | ||||
|  */ | ||||
| #define sp2_TILE_SIZE 8 | ||||
| #define sp_TILE_SIZE 8 | ||||
| 
 | ||||
| /**
 | ||||
|  * tile count in the x-direction | ||||
|  */ | ||||
| #define sp2_TILE_WIDTH 56 | ||||
| #define sp_TILE_WIDTH 56 | ||||
| 
 | ||||
| /**
 | ||||
|  * Specifies the kind of compression to use. Availability depends on features. | ||||
|  */ | ||||
| enum sp2_CompressionCode | ||||
| enum sp_CompressionCode | ||||
| #ifdef __cplusplus | ||||
|   : uint16_t | ||||
| #endif // __cplusplus
 | ||||
|  { | ||||
|     Uncompressed = 0, | ||||
| #if defined(SP2_FEATURE_compression_zlib) | ||||
|     Zlib = 26490, | ||||
| #endif | ||||
| #if defined(SP2_FEATURE_compression_bzip2) | ||||
|     Bzip2 = 25210, | ||||
| #endif | ||||
| #if defined(SP2_FEATURE_compression_lzma) | ||||
|     Lzma = 27770, | ||||
| #endif | ||||
| #if defined(SP2_FEATURE_compression_zstd) | ||||
|     Zstd = 31347, | ||||
| #endif | ||||
| }; | ||||
| #ifndef __cplusplus | ||||
| typedef uint16_t sp2_CompressionCode; | ||||
| typedef uint16_t sp_CompressionCode; | ||||
| #endif // __cplusplus
 | ||||
| 
 | ||||
| /**
 | ||||
|  * A vector of bits | ||||
|  */ | ||||
| typedef struct sp2_BitVec sp2_BitVec; | ||||
| typedef struct sp_BitVec sp_BitVec; | ||||
| 
 | ||||
| /**
 | ||||
|  * A 2D grid of bytes | ||||
|  */ | ||||
| typedef struct sp2_ByteGrid sp2_ByteGrid; | ||||
| typedef struct sp_ByteGrid sp_ByteGrid; | ||||
| 
 | ||||
| /**
 | ||||
|  * A command to send to the display. | ||||
|  */ | ||||
| typedef struct sp2_Command sp2_Command; | ||||
| typedef struct sp_Command sp_Command; | ||||
| 
 | ||||
| /**
 | ||||
|  * A connection to the display. | ||||
|  */ | ||||
| typedef struct sp2_Connection sp2_Connection; | ||||
| typedef struct sp_Connection sp_Connection; | ||||
| 
 | ||||
| /**
 | ||||
|  * The raw packet. Should probably not be used directly. | ||||
|  */ | ||||
| typedef struct sp2_Packet sp2_Packet; | ||||
| typedef struct sp_Packet sp_Packet; | ||||
| 
 | ||||
| /**
 | ||||
|  * A grid of pixels stored in packed bytes. | ||||
|  */ | ||||
| typedef struct sp2_PixelGrid sp2_PixelGrid; | ||||
| typedef struct sp_PixelGrid sp_PixelGrid; | ||||
| 
 | ||||
| /**
 | ||||
|  * Represents a span of memory (`&mut [u8]` ) as a struct usable by C code. | ||||
|  * | ||||
|  * Usage of this type is inherently unsafe. | ||||
|  */ | ||||
| typedef struct sp2_CByteSlice { | ||||
| typedef struct sp_CByteSlice { | ||||
|     /**
 | ||||
|      * The start address of the memory | ||||
|      */ | ||||
|  | @ -106,17 +98,17 @@ typedef struct sp2_CByteSlice { | |||
|      * The amount of memory in bytes | ||||
|      */ | ||||
|     size_t length; | ||||
| } sp2_CByteSlice; | ||||
| } sp_CByteSlice; | ||||
| 
 | ||||
| /**
 | ||||
|  * Type alias for documenting the meaning of the u16 in enum values | ||||
|  */ | ||||
| typedef size_t sp2_Offset; | ||||
| typedef size_t sp_Offset; | ||||
| 
 | ||||
| /**
 | ||||
|  * Type alias for documenting the meaning of the u16 in enum values | ||||
|  */ | ||||
| typedef uint8_t sp2_Brightness; | ||||
| typedef uint8_t sp_Brightness; | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
|  | @ -126,51 +118,51 @@ extern "C" { | |||
|  * Clones a `BitVec`. | ||||
|  * The returned instance has to be freed with `bit_vec_dealloc`. | ||||
|  */ | ||||
| struct sp2_BitVec *sp2_bit_vec_clone(const struct sp2_BitVec *this_); | ||||
| struct sp_BitVec *sp_bit_vec_clone(const struct sp_BitVec *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Deallocates a `BitVec`. | ||||
|  * | ||||
|  * Note: do not call this if the grid has been consumed in another way, e.g. to create a command. | ||||
|  */ | ||||
| void sp2_bit_vec_dealloc(struct sp2_BitVec *this_); | ||||
| void sp_bit_vec_dealloc(struct sp_BitVec *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Sets the value of all bits in the `BitVec`. | ||||
|  */ | ||||
| void sp2_bit_vec_fill(struct sp2_BitVec *this_, bool value); | ||||
| void sp_bit_vec_fill(struct sp_BitVec *this_, bool value); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the value of a bit from the `BitVec`. | ||||
|  */ | ||||
| bool sp2_bit_vec_get(const struct sp2_BitVec *this_, size_t index); | ||||
| bool sp_bit_vec_get(const struct sp_BitVec *this_, size_t index); | ||||
| 
 | ||||
| /**
 | ||||
|  * Returns true if length is 0. | ||||
|  */ | ||||
| bool sp2_bit_vec_is_empty(const struct sp2_BitVec *this_); | ||||
| bool sp_bit_vec_is_empty(const struct sp_BitVec *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the length of the `BitVec` in bits. | ||||
|  */ | ||||
| size_t sp2_bit_vec_len(const struct sp2_BitVec *this_); | ||||
| size_t sp_bit_vec_len(const struct sp_BitVec *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Loads a `BitVec` from the provided data. | ||||
|  * The returned instance has to be freed with `bit_vec_dealloc`. | ||||
|  */ | ||||
| struct sp2_BitVec *sp2_bit_vec_load(const uint8_t *data, size_t data_length); | ||||
| struct sp_BitVec *sp_bit_vec_load(const uint8_t *data, size_t data_length); | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates a new `BitVec` instance. | ||||
|  * The returned instance has to be freed with `bit_vec_dealloc`. | ||||
|  */ | ||||
| struct sp2_BitVec *sp2_bit_vec_new(size_t size); | ||||
| struct sp_BitVec *sp_bit_vec_new(size_t size); | ||||
| 
 | ||||
| /**
 | ||||
|  * Sets the value of a bit in the `BitVec`. | ||||
|  */ | ||||
| bool sp2_bit_vec_set(struct sp2_BitVec *this_, size_t index, bool value); | ||||
| bool sp_bit_vec_set(struct sp_BitVec *this_, size_t index, bool value); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets an unsafe reference to the data of the `BitVec` instance. | ||||
|  | @ -183,58 +175,58 @@ bool sp2_bit_vec_set(struct sp2_BitVec *this_, size_t index, bool value); | |||
|  * Reading and writing concurrently to either the original instance or the returned data will | ||||
|  * result in undefined behavior. | ||||
|  */ | ||||
| struct sp2_CByteSlice sp2_bit_vec_unsafe_data_ref(struct sp2_BitVec *this_); | ||||
| struct sp_CByteSlice sp_bit_vec_unsafe_data_ref(struct sp_BitVec *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Clones a `ByteGrid`. | ||||
|  * The returned instance has to be freed with `byte_grid_dealloc`. | ||||
|  */ | ||||
| struct sp2_ByteGrid *sp2_byte_grid_clone(const struct sp2_ByteGrid *this_); | ||||
| struct sp_ByteGrid *sp_byte_grid_clone(const struct sp_ByteGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Deallocates a `ByteGrid`. | ||||
|  * | ||||
|  * Note: do not call this if the grid has been consumed in another way, e.g. to create a command. | ||||
|  */ | ||||
| void sp2_byte_grid_dealloc(struct sp2_ByteGrid *this_); | ||||
| void sp_byte_grid_dealloc(struct sp_ByteGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Fills the whole `ByteGrid` with the specified value | ||||
|  */ | ||||
| void sp2_byte_grid_fill(struct sp2_ByteGrid *this_, uint8_t value); | ||||
| void sp_byte_grid_fill(struct sp_ByteGrid *this_, uint8_t value); | ||||
| 
 | ||||
| /**
 | ||||
|  * Get the current value at the specified position | ||||
|  */ | ||||
| uint8_t sp2_byte_grid_get(const struct sp2_ByteGrid *this_, size_t x, size_t y); | ||||
| uint8_t sp_byte_grid_get(const struct sp_ByteGrid *this_, size_t x, size_t y); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the height in pixels of the `ByteGrid` instance. | ||||
|  */ | ||||
| size_t sp2_byte_grid_height(const struct sp2_ByteGrid *this_); | ||||
| size_t sp_byte_grid_height(const struct sp_ByteGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Loads a `ByteGrid` with the specified dimensions from the provided data. | ||||
|  * The returned instance has to be freed with `byte_grid_dealloc`. | ||||
|  */ | ||||
| struct sp2_ByteGrid *sp2_byte_grid_load(size_t width, | ||||
|                                         size_t height, | ||||
|                                         const uint8_t *data, | ||||
|                                         size_t data_length); | ||||
| struct sp_ByteGrid *sp_byte_grid_load(size_t width, | ||||
|                                       size_t height, | ||||
|                                       const uint8_t *data, | ||||
|                                       size_t data_length); | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates a new `ByteGrid` instance. | ||||
|  * The returned instance has to be freed with `byte_grid_dealloc`. | ||||
|  */ | ||||
| struct sp2_ByteGrid *sp2_byte_grid_new(size_t width, size_t height); | ||||
| struct sp_ByteGrid *sp_byte_grid_new(size_t width, size_t height); | ||||
| 
 | ||||
| /**
 | ||||
|  * Sets the current value at the specified position | ||||
|  */ | ||||
| void sp2_byte_grid_set(struct sp2_ByteGrid *this_, | ||||
|                        size_t x, | ||||
|                        size_t y, | ||||
|                        uint8_t value); | ||||
| void sp_byte_grid_set(struct sp_ByteGrid *this_, | ||||
|                       size_t x, | ||||
|                       size_t y, | ||||
|                       uint8_t value); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets an unsafe reference to the data of the `ByteGrid` instance. | ||||
|  | @ -247,112 +239,112 @@ void sp2_byte_grid_set(struct sp2_ByteGrid *this_, | |||
|  * Reading and writing concurrently to either the original instance or the returned data will | ||||
|  * result in undefined behavior. | ||||
|  */ | ||||
| struct sp2_CByteSlice sp2_byte_grid_unsafe_data_ref(struct sp2_ByteGrid *this_); | ||||
| struct sp_CByteSlice sp_byte_grid_unsafe_data_ref(struct sp_ByteGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the width in pixels of the `ByteGrid` instance. | ||||
|  */ | ||||
| size_t sp2_byte_grid_width(const struct sp2_ByteGrid *this_); | ||||
| size_t sp_byte_grid_width(const struct sp_ByteGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::BitmapLinear` instance. | ||||
|  * The passed `BitVec` gets deallocated in the process. | ||||
|  */ | ||||
| struct sp2_Command *sp2_command_bitmap_linear(sp2_Offset offset, | ||||
|                                               struct sp2_BitVec *bit_vec, | ||||
|                                               sp2_CompressionCode compression); | ||||
| struct sp_Command *sp_command_bitmap_linear(sp_Offset offset, | ||||
|                                             struct sp_BitVec *bit_vec, | ||||
|                                             sp_CompressionCode compression); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::BitmapLinearAnd` instance. | ||||
|  * The passed `BitVec` gets deallocated in the process. | ||||
|  */ | ||||
| struct sp2_Command *sp2_command_bitmap_linear_and(sp2_Offset offset, | ||||
|                                                   struct sp2_BitVec *bit_vec, | ||||
|                                                   sp2_CompressionCode compression); | ||||
| struct sp_Command *sp_command_bitmap_linear_and(sp_Offset offset, | ||||
|                                                 struct sp_BitVec *bit_vec, | ||||
|                                                 sp_CompressionCode compression); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::BitmapLinearOr` instance. | ||||
|  * The passed `BitVec` gets deallocated in the process. | ||||
|  */ | ||||
| struct sp2_Command *sp2_command_bitmap_linear_or(sp2_Offset offset, | ||||
|                                                  struct sp2_BitVec *bit_vec, | ||||
|                                                  sp2_CompressionCode compression); | ||||
| struct sp_Command *sp_command_bitmap_linear_or(sp_Offset offset, | ||||
|                                                struct sp_BitVec *bit_vec, | ||||
|                                                sp_CompressionCode compression); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::BitmapLinearWin` instance. | ||||
|  * The passed `PixelGrid` gets deallocated in the process. | ||||
|  */ | ||||
| struct sp2_Command *sp2_command_bitmap_linear_win(size_t x, | ||||
|                                                   size_t y, | ||||
|                                                   struct sp2_PixelGrid *byte_grid, | ||||
|                                                   sp2_CompressionCode compression_code); | ||||
| struct sp_Command *sp_command_bitmap_linear_win(size_t x, | ||||
|                                                 size_t y, | ||||
|                                                 struct sp_PixelGrid *byte_grid, | ||||
|                                                 sp_CompressionCode compression_code); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::BitmapLinearXor` instance. | ||||
|  * The passed `BitVec` gets deallocated in the process. | ||||
|  */ | ||||
| struct sp2_Command *sp2_command_bitmap_linear_xor(sp2_Offset offset, | ||||
|                                                   struct sp2_BitVec *bit_vec, | ||||
|                                                   sp2_CompressionCode compression); | ||||
| struct sp_Command *sp_command_bitmap_linear_xor(sp_Offset offset, | ||||
|                                                 struct sp_BitVec *bit_vec, | ||||
|                                                 sp_CompressionCode compression); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::Brightness` instance | ||||
|  */ | ||||
| struct sp2_Command *sp2_command_brightness(sp2_Brightness brightness); | ||||
| struct sp_Command *sp_command_brightness(sp_Brightness brightness); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::CharBrightness` instance. | ||||
|  * The passed `ByteGrid` gets deallocated in the process. | ||||
|  */ | ||||
| struct sp2_Command *sp2_command_char_brightness(size_t x, | ||||
|                                                 size_t y, | ||||
|                                                 struct sp2_ByteGrid *byte_grid); | ||||
| struct sp_Command *sp_command_char_brightness(size_t x, | ||||
|                                               size_t y, | ||||
|                                               struct sp_ByteGrid *byte_grid); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::Clear` instance | ||||
|  */ | ||||
| struct sp2_Command *sp2_command_clear(void); | ||||
| struct sp_Command *sp_command_clear(void); | ||||
| 
 | ||||
| /**
 | ||||
|  * Clones a `Command` instance | ||||
|  */ | ||||
| struct sp2_Command *sp2_command_clone(const struct sp2_Command *original); | ||||
| struct sp_Command *sp_command_clone(const struct sp_Command *original); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::Cp437Data` instance. | ||||
|  * The passed `ByteGrid` gets deallocated in the process. | ||||
|  */ | ||||
| struct sp2_Command *sp2_command_cp437_data(size_t x, | ||||
|                                            size_t y, | ||||
|                                            struct sp2_ByteGrid *byte_grid); | ||||
| struct sp_Command *sp_command_cp437_data(size_t x, | ||||
|                                          size_t y, | ||||
|                                          struct sp_ByteGrid *byte_grid); | ||||
| 
 | ||||
| /**
 | ||||
|  * Deallocates a `Command`. Note that connection_send does this implicitly, so you only need | ||||
|  * to do this if you use the library for parsing commands. | ||||
|  */ | ||||
| void sp2_command_dealloc(struct sp2_Command *ptr); | ||||
| void sp_command_dealloc(struct sp_Command *ptr); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::FadeOut` instance | ||||
|  */ | ||||
| struct sp2_Command *sp2_command_fade_out(void); | ||||
| struct sp_Command *sp_command_fade_out(void); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::HardReset` instance | ||||
|  */ | ||||
| struct sp2_Command *sp2_command_hard_reset(void); | ||||
| struct sp_Command *sp_command_hard_reset(void); | ||||
| 
 | ||||
| /**
 | ||||
|  * Tries to turn a `Packet` into a `Command`. The packet is gets deallocated in the process. | ||||
|  * | ||||
|  * Returns: pointer to command or NULL | ||||
|  */ | ||||
| struct sp2_Command *sp2_command_try_from_packet(struct sp2_Packet *packet); | ||||
| struct sp_Command *sp_command_try_from_packet(struct sp_Packet *packet); | ||||
| 
 | ||||
| /**
 | ||||
|  * Closes and deallocates a connection instance | ||||
|  */ | ||||
| void sp2_connection_dealloc(struct sp2_Connection *ptr); | ||||
| void sp_connection_dealloc(struct sp_Connection *ptr); | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates a new instance of Connection. | ||||
|  | @ -362,83 +354,83 @@ void sp2_connection_dealloc(struct sp2_Connection *ptr); | |||
|  * | ||||
|  * Panics: bad string encoding | ||||
|  */ | ||||
| struct sp2_Connection *sp2_connection_open(const char *host); | ||||
| struct sp_Connection *sp_connection_open(const char *host); | ||||
| 
 | ||||
| /**
 | ||||
|  * Sends the command instance. The instance is consumed / destroyed and cannot be used after this call. | ||||
|  */ | ||||
| bool sp2_connection_send(const struct sp2_Connection *connection, | ||||
|                          struct sp2_Packet *command_ptr); | ||||
| bool sp_connection_send(const struct sp_Connection *connection, | ||||
|                         struct sp_Packet *command_ptr); | ||||
| 
 | ||||
| /**
 | ||||
|  * Deallocates a `Packet`. | ||||
|  * | ||||
|  * Note: do not call this if the instance has been consumed in another way, e.g. by sending it. | ||||
|  */ | ||||
| void sp2_packet_dealloc(struct sp2_Packet *this_); | ||||
| void sp_packet_dealloc(struct sp_Packet *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Turns a `Command` into a `Packet`. The command gets deallocated in the process. | ||||
|  */ | ||||
| struct sp2_Packet *sp2_packet_from_command(struct sp2_Command *command); | ||||
| struct sp_Packet *sp_packet_from_command(struct sp_Command *command); | ||||
| 
 | ||||
| /**
 | ||||
|  * Tries to load a `Packet` from the passed array with the specified length. | ||||
|  * | ||||
|  * returns: NULL in case of an error, pointer to the allocated packet otherwise | ||||
|  */ | ||||
| struct sp2_Packet *sp2_packet_try_load(const uint8_t *data, size_t length); | ||||
| struct sp_Packet *sp_packet_try_load(const uint8_t *data, size_t length); | ||||
| 
 | ||||
| /**
 | ||||
|  * Clones a `PixelGrid`. | ||||
|  * The returned instance has to be freed with `pixel_grid_dealloc`. | ||||
|  */ | ||||
| struct sp2_PixelGrid *sp2_pixel_grid_clone(const struct sp2_PixelGrid *this_); | ||||
| struct sp_PixelGrid *sp_pixel_grid_clone(const struct sp_PixelGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Deallocates a `PixelGrid`. | ||||
|  * | ||||
|  * Note: do not call this if the grid has been consumed in another way, e.g. to create a command. | ||||
|  */ | ||||
| void sp2_pixel_grid_dealloc(struct sp2_PixelGrid *this_); | ||||
| void sp_pixel_grid_dealloc(struct sp_PixelGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Fills the whole `PixelGrid` with the specified value | ||||
|  */ | ||||
| void sp2_pixel_grid_fill(struct sp2_PixelGrid *this_, bool value); | ||||
| void sp_pixel_grid_fill(struct sp_PixelGrid *this_, bool value); | ||||
| 
 | ||||
| /**
 | ||||
|  * Get the current value at the specified position | ||||
|  */ | ||||
| bool sp2_pixel_grid_get(const struct sp2_PixelGrid *this_, size_t x, size_t y); | ||||
| bool sp_pixel_grid_get(const struct sp_PixelGrid *this_, size_t x, size_t y); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the height in pixels of the `PixelGrid` instance. | ||||
|  */ | ||||
| size_t sp2_pixel_grid_height(const struct sp2_PixelGrid *this_); | ||||
| size_t sp_pixel_grid_height(const struct sp_PixelGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Loads a `PixelGrid` with the specified dimensions from the provided data. | ||||
|  * The returned instance has to be freed with `pixel_grid_dealloc`. | ||||
|  */ | ||||
| struct sp2_PixelGrid *sp2_pixel_grid_load(size_t width, | ||||
|                                           size_t height, | ||||
|                                           const uint8_t *data, | ||||
|                                           size_t data_length); | ||||
| struct sp_PixelGrid *sp_pixel_grid_load(size_t width, | ||||
|                                         size_t height, | ||||
|                                         const uint8_t *data, | ||||
|                                         size_t data_length); | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates a new `PixelGrid` instance. | ||||
|  * The returned instance has to be freed with `pixel_grid_dealloc`. | ||||
|  */ | ||||
| struct sp2_PixelGrid *sp2_pixel_grid_new(size_t width, size_t height); | ||||
| struct sp_PixelGrid *sp_pixel_grid_new(size_t width, size_t height); | ||||
| 
 | ||||
| /**
 | ||||
|  * Sets the current value at the specified position | ||||
|  */ | ||||
| void sp2_pixel_grid_set(struct sp2_PixelGrid *this_, | ||||
|                         size_t x, | ||||
|                         size_t y, | ||||
|                         bool value); | ||||
| void sp_pixel_grid_set(struct sp_PixelGrid *this_, | ||||
|                        size_t x, | ||||
|                        size_t y, | ||||
|                        bool value); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets an unsafe reference to the data of the `PixelGrid` instance. | ||||
|  | @ -451,12 +443,12 @@ void sp2_pixel_grid_set(struct sp2_PixelGrid *this_, | |||
|  * Reading and writing concurrently to either the original instance or the returned data will | ||||
|  * result in undefined behavior. | ||||
|  */ | ||||
| struct sp2_CByteSlice sp2_pixel_grid_unsafe_data_ref(struct sp2_PixelGrid *this_); | ||||
| struct sp_CByteSlice sp_pixel_grid_unsafe_data_ref(struct sp_PixelGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the width in pixels of the `PixelGrid` instance. | ||||
|  */ | ||||
| size_t sp2_pixel_grid_width(const struct sp2_PixelGrid *this_); | ||||
| size_t sp_pixel_grid_width(const struct sp_PixelGrid *this_); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } // extern "C"
 | ||||
|  |  | |||
|  | @ -2,18 +2,18 @@ | |||
| #include "servicepoint.h" | ||||
| 
 | ||||
| int main(void) { | ||||
|     sp2_Connection *connection = sp2_connection_open("localhost:2342"); | ||||
|     sp_Connection *connection = sp_connection_open("localhost:2342"); | ||||
|     if (connection == NULL) | ||||
|         return 1; | ||||
| 
 | ||||
|     sp2_PixelGrid *pixels = sp2_pixel_grid_new(sp2_PIXEL_WIDTH, sp2_PIXEL_HEIGHT); | ||||
|     sp2_pixel_grid_fill(pixels, true); | ||||
|     sp_PixelGrid *pixels = sp_pixel_grid_new(sp_PIXEL_WIDTH, sp_PIXEL_HEIGHT); | ||||
|     sp_pixel_grid_fill(pixels, true); | ||||
| 
 | ||||
|     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)) | ||||
|     sp_Command *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed); | ||||
|     sp_Packet *packet = sp_packet_from_command(command); | ||||
|     if (!sp_connection_send(connection, packet)) | ||||
|         return 1; | ||||
| 
 | ||||
|     sp2_connection_dealloc(connection); | ||||
|     sp_connection_dealloc(connection); | ||||
|     return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ | |||
|     </PropertyGroup> | ||||
| 
 | ||||
|     <ItemGroup> | ||||
|         <ProjectReference Include="..\..\servicepoint-binding-cs\src\ServicePoint.csproj"/> | ||||
|         <ProjectReference Include="../../crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj"/> | ||||
|     </ItemGroup> | ||||
| 
 | ||||
| </Project> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vinzenz Schroeter
						Vinzenz Schroeter