wrap and rename ALL the types
This commit is contained in:
		
							parent
							
								
									b9fc06117e
								
							
						
					
					
						commit
						051dbfabea
					
				
					 18 changed files with 577 additions and 480 deletions
				
			
		|  | @ -9,38 +9,24 @@ use crate::Packet; | |||
| ///
 | ||||
| /// # Examples
 | ||||
| /// ```rust
 | ||||
| /// # use servicepoint::{Command, Connection};
 | ||||
| /// let connection = servicepoint::UdpConnection::open("172.23.42.29:2342")
 | ||||
| /// let connection = servicepoint::Connection::open("172.23.42.29:2342")
 | ||||
| ///     .expect("connection failed");
 | ||||
| ///  connection.send(Command::Clear);
 | ||||
| ///  connection.send(servicepoint::Command::Clear)
 | ||||
| ///     .expect("send failed");
 | ||||
| /// ```
 | ||||
| pub trait Connection { | ||||
|     /// Send something packet-like to the display. Usually this is in the form of a Command.
 | ||||
|     ///
 | ||||
|     /// # Arguments
 | ||||
|     ///
 | ||||
|     /// - `packet`: the packet-like to send
 | ||||
|     ///
 | ||||
|     /// returns: true if packet was sent, otherwise false
 | ||||
|     ///
 | ||||
|     /// # Examples
 | ||||
|     ///
 | ||||
|     /// ```rust
 | ||||
|     /// # use servicepoint::{Command, Connection };
 | ||||
|     /// # let connection = servicepoint::UdpConnection::open("172.23.42.29:2342")
 | ||||
|     /// #     .expect("connection failed");
 | ||||
|     ///  // turn off all pixels on display
 | ||||
|     ///  connection.send(Command::Clear);
 | ||||
|     /// ```
 | ||||
|     fn send(&self, packet: impl Into<Packet>) -> bool; | ||||
| pub enum Connection { | ||||
|     /// A real connection using the UDP protocol
 | ||||
|     Udp(UdpSocket), | ||||
|     /// A fake connection for testing that does not actually send anything
 | ||||
|     Fake, | ||||
| } | ||||
| 
 | ||||
| /// A real connection using the UDP protocol
 | ||||
| pub struct UdpConnection { | ||||
|     socket: UdpSocket, | ||||
| #[derive(Debug)] | ||||
| pub enum SendError { | ||||
|     IoError(std::io::Error), | ||||
| } | ||||
| 
 | ||||
| impl UdpConnection { | ||||
| impl Connection { | ||||
|     /// Open a new UDP socket and connect to the provided host.
 | ||||
|     ///
 | ||||
|     /// Note that this is UDP, which means that the open call can succeed even if the display is unreachable.
 | ||||
|  | @ -58,24 +44,37 @@ impl UdpConnection { | |||
|         info!("connecting to {addr:?}"); | ||||
|         let socket = UdpSocket::bind("0.0.0.0:0")?; | ||||
|         socket.connect(addr)?; | ||||
|         Ok(Self { socket }) | ||||
|         Ok(Self::Udp(socket)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Connection for UdpConnection { | ||||
|     fn send(&self, packet: impl Into<Packet>) -> bool { | ||||
|     /// Send something packet-like to the display. Usually this is in the form of a Command.
 | ||||
|     ///
 | ||||
|     /// # Arguments
 | ||||
|     ///
 | ||||
|     /// - `packet`: the packet-like to send
 | ||||
|     ///
 | ||||
|     /// returns: true if packet was sent, otherwise false
 | ||||
|     ///
 | ||||
|     /// # Examples
 | ||||
|     ///
 | ||||
|     /// ```rust
 | ||||
|     /// # let connection = servicepoint::Connection::Fake;
 | ||||
|     ///  // turn off all pixels on display
 | ||||
|     ///  connection.send(servicepoint::Command::Clear)
 | ||||
|     ///      .expect("send failed");
 | ||||
|     /// ```
 | ||||
|     pub fn send(&self, packet: impl Into<Packet>) -> Result<(), SendError> { | ||||
|         let packet = packet.into(); | ||||
|         debug!("sending {packet:?}"); | ||||
|         let data: Vec<u8> = packet.into(); | ||||
|         self.socket.send(&data).is_err() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// A fake connection for testing that does not actually send anything
 | ||||
| pub struct NoopConnection; | ||||
| 
 | ||||
| impl Connection for NoopConnection { | ||||
|     fn send(&self, packet: impl Into<Packet>) -> bool { | ||||
|         true | ||||
|         match self { | ||||
|             Connection::Udp(socket) => { | ||||
|                 socket | ||||
|                     .send(&data) | ||||
|                     .map_err(move |io_err| SendError::IoError(io_err)) | ||||
|                     .map(move |_| ()) // ignore Ok value
 | ||||
|             } | ||||
|             Connection::Fake => Ok(()), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ use bitvec::prelude::{BitVec, Msb0}; | |||
| pub use crate::brightness::{Brightness, BrightnessGrid}; | ||||
| pub use crate::command::{Command, Cp437Grid, Offset}; | ||||
| pub use crate::compression_code::CompressionCode; | ||||
| pub use crate::connection::{Connection, UdpConnection}; | ||||
| pub use crate::connection::Connection; | ||||
| pub use crate::data_ref::DataRef; | ||||
| pub use crate::grid::Grid; | ||||
| pub use crate::origin::{Origin, Pixels, Tiles}; | ||||
|  |  | |||
|  | @ -18,19 +18,8 @@ style = "both" | |||
| sort_by = "Name" | ||||
| usize_is_size_t = true | ||||
| 
 | ||||
| [defines] | ||||
| #"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 = "sp_" | ||||
| 
 | ||||
| [parse] | ||||
| parse_deps = true | ||||
| include = ["servicepoint"] | ||||
| extra_bindings = ["servicepoint"] | ||||
| parse_deps = false | ||||
| 
 | ||||
| [parse.expand] | ||||
| all_features = true | ||||
|  |  | |||
|  | @ -6,8 +6,9 @@ REPO_ROOT := $(THIS_DIR)/../../../.. | |||
| build: out/lang_c | ||||
| 
 | ||||
| clean: | ||||
| 	rm -r out | ||||
| 	rm include/servicepoint.h | ||||
| 	rm -r out || true | ||||
| 	rm include/servicepoint.h || true | ||||
| 	cargo clean | ||||
| 
 | ||||
| run: out/lang_c | ||||
| 	out/lang_c | ||||
|  |  | |||
|  | @ -9,78 +9,37 @@ | |||
| /**
 | ||||
|  * pixel count on whole screen | ||||
|  */ | ||||
| #define sp_PIXEL_COUNT (sp_PIXEL_WIDTH * sp_PIXEL_HEIGHT) | ||||
| #define SP_PIXEL_COUNT (SP_PIXEL_WIDTH * SP_PIXEL_HEIGHT) | ||||
| 
 | ||||
| /**
 | ||||
|  * Display height in pixels | ||||
|  * | ||||
|  * # Examples | ||||
|  * | ||||
|  * ```rust | ||||
|  * # use servicepoint::{PIXEL_HEIGHT, PIXEL_WIDTH, PixelGrid}; | ||||
|  * let grid = PixelGrid::new(PIXEL_WIDTH, PIXEL_HEIGHT); | ||||
|  * ``` | ||||
|  */ | ||||
| #define sp_PIXEL_HEIGHT (sp_TILE_HEIGHT * sp_TILE_SIZE) | ||||
| #define SP_PIXEL_HEIGHT (SP_TILE_HEIGHT * SP_TILE_SIZE) | ||||
| 
 | ||||
| /**
 | ||||
|  * Display width in pixels | ||||
|  * | ||||
|  * # Examples | ||||
|  * | ||||
|  * ```rust | ||||
|  * # use servicepoint::{PIXEL_HEIGHT, PIXEL_WIDTH, PixelGrid}; | ||||
|  * let grid = PixelGrid::new(PIXEL_WIDTH, PIXEL_HEIGHT); | ||||
|  * ``` | ||||
|  */ | ||||
| #define sp_PIXEL_WIDTH (sp_TILE_WIDTH * sp_TILE_SIZE) | ||||
| #define SP_PIXEL_WIDTH (SP_TILE_WIDTH * SP_TILE_SIZE) | ||||
| 
 | ||||
| /**
 | ||||
|  * Display tile count in the y-direction | ||||
|  * | ||||
|  * # Examples | ||||
|  * | ||||
|  * ```rust | ||||
|  * # use servicepoint::{Cp437Grid, TILE_HEIGHT, TILE_WIDTH}; | ||||
|  * let grid = Cp437Grid::new(TILE_WIDTH, TILE_HEIGHT); | ||||
|  * ``` | ||||
|  */ | ||||
| #define sp_TILE_HEIGHT 20 | ||||
| #define SP_TILE_HEIGHT 20 | ||||
| 
 | ||||
| /**
 | ||||
|  * size of a single tile in one dimension | ||||
|  */ | ||||
| #define sp_TILE_SIZE 8 | ||||
| #define SP_TILE_SIZE 8 | ||||
| 
 | ||||
| /**
 | ||||
|  * Display tile count in the x-direction | ||||
|  * | ||||
|  * # Examples | ||||
|  * | ||||
|  * ```rust | ||||
|  * # use servicepoint::{Cp437Grid, TILE_HEIGHT, TILE_WIDTH}; | ||||
|  * let grid = Cp437Grid::new(TILE_WIDTH, TILE_HEIGHT); | ||||
|  * ``` | ||||
|  */ | ||||
| #define sp_TILE_WIDTH 56 | ||||
| #define SP_TILE_WIDTH 56 | ||||
| 
 | ||||
| /**
 | ||||
|  * Specifies the kind of compression to use. Availability depends on features. | ||||
|  * | ||||
|  * # Examples | ||||
|  * | ||||
|  * ```rust | ||||
|  * # use servicepoint::{Command, CompressionCode, Origin, PixelGrid}; | ||||
|  * // create command without payload compression
 | ||||
|  * # let pixels = PixelGrid::max_sized(); | ||||
|  * _ = Command::BitmapLinearWin(Origin::new(0, 0), pixels, CompressionCode::Uncompressed); | ||||
|  * | ||||
|  * // create command with payload compressed with lzma and appropriate header flags
 | ||||
|  * # let pixels = PixelGrid::max_sized(); | ||||
|  * _ = Command::BitmapLinearWin(Origin::new(0, 0), pixels, CompressionCode::Lzma); | ||||
|  * ``` | ||||
|  * Specifies the kind of compression to use. | ||||
|  */ | ||||
| enum sp_CompressionCode | ||||
| enum SPCompressionCode | ||||
| #ifdef __cplusplus | ||||
|   : uint16_t | ||||
| #endif // __cplusplus
 | ||||
|  | @ -107,75 +66,103 @@ enum sp_CompressionCode | |||
|     Zstd = 31347, | ||||
| }; | ||||
| #ifndef __cplusplus | ||||
| typedef uint16_t sp_CompressionCode; | ||||
| typedef uint16_t SPCompressionCode; | ||||
| #endif // __cplusplus
 | ||||
| 
 | ||||
| /**
 | ||||
|  * A display brightness value, checked for correct value range | ||||
|  * A vector of bits | ||||
|  * | ||||
|  * # Examples | ||||
|  * | ||||
|  * ``` | ||||
|  * # use servicepoint::{Brightness, Command, Connection}; | ||||
|  * let b = Brightness::MAX; | ||||
|  * let val: u8 = b.into(); | ||||
|  * | ||||
|  * let b = Brightness::try_from(7).unwrap(); | ||||
|  * # let connection = Connection::open("127.0.0.1:2342").unwrap(); | ||||
|  * let result = connection.send(Command::Brightness(b)); | ||||
|  * ```C | ||||
|  * SPBitVec vec = sp_bit_vec_new(8); | ||||
|  * sp_bit_vec_set(vec, 5, true); | ||||
|  * sp_bit_vec_dealloc(vec); | ||||
|  * ``` | ||||
|  */ | ||||
| typedef struct sp_Brightness sp_Brightness; | ||||
| typedef struct SPBitVec SPBitVec; | ||||
| 
 | ||||
| /**
 | ||||
|  * A vector of bits | ||||
|  * A grid containing brightness values. | ||||
|  * | ||||
|  * # Examples | ||||
|  * ```C | ||||
|  * SPConnection connection = sp_connection_open("127.0.0.1:2342"); | ||||
|  * if (connection == NULL) | ||||
|  *     return 1; | ||||
|  * | ||||
|  * SPBrightnessGrid grid = sp_brightness_grid_new(2, 2); | ||||
|  * sp_brightness_grid_set(grid, 0, 0, 0); | ||||
|  * sp_brightness_grid_set(grid, 1, 1, 10); | ||||
|  * | ||||
|  * SPCommand command = sp_command_char_brightness(grid); | ||||
|  * sp_connection_dealloc(connection); | ||||
|  * ``` | ||||
|  */ | ||||
| typedef struct sp_CBitVec sp_CBitVec; | ||||
| 
 | ||||
| /**
 | ||||
|  * C-wrapper for grid containing brightness values. | ||||
|  */ | ||||
| typedef struct sp_CBrightnessGrid sp_CBrightnessGrid; | ||||
| typedef struct SPBrightnessGrid SPBrightnessGrid; | ||||
| 
 | ||||
| /**
 | ||||
|  * A low-level display command. | ||||
|  * | ||||
|  * This struct and associated functions implement the UDP protocol for the display. | ||||
|  * | ||||
|  * To send a `CCommand`, use a `Connection`. | ||||
|  */ | ||||
| typedef struct sp_CCommand sp_CCommand; | ||||
| 
 | ||||
| /**
 | ||||
|  * A C-wrapper for grid containing codepage 437 characters. | ||||
|  * To send a `CCommand`, use a `CConnection`. | ||||
|  * | ||||
|  * The encoding is currently not enforced. | ||||
|  * # Examples | ||||
|  * | ||||
|  * ```C | ||||
|  * sp_connection_send(connection, sp_command_clear()); | ||||
|  * sp_connection_send(connection, sp_command_brightness(5)); | ||||
|  * ``` | ||||
|  */ | ||||
| typedef struct sp_CCp437Grid sp_CCp437Grid; | ||||
| typedef struct SPCommand SPCommand; | ||||
| 
 | ||||
| /**
 | ||||
|  * A connection to the display. | ||||
|  * | ||||
|  * # Examples | ||||
|  * ```rust | ||||
|  * # use servicepoint::Command; | ||||
|  * let connection = servicepoint::Connection::open("172.23.42.29:2342") | ||||
|  *     .expect("connection failed"); | ||||
|  *  connection.send(Command::Clear) | ||||
|  *     .expect("send failed"); | ||||
|  * | ||||
|  * ```C | ||||
|  * CConnection connection = sp_connection_open("172.23.42.29:2342"); | ||||
|  * if (connection != NULL) | ||||
|  *     sp_connection_send(connection, sp_command_clear()); | ||||
|  * ``` | ||||
|  */ | ||||
| typedef struct sp_Connection sp_Connection; | ||||
| typedef struct SPConnection SPConnection; | ||||
| 
 | ||||
| /**
 | ||||
|  * The raw packet. Should probably not be used directly. | ||||
|  * A C-wrapper for grid containing codepage 437 characters. | ||||
|  * | ||||
|  * The encoding is currently not enforced. | ||||
|  * | ||||
|  * # Examples | ||||
|  * | ||||
|  * ```C | ||||
|  * Cp437Grid grid = sp_cp437_grid_new(4, 3); | ||||
|  * sp_cp437_grid_fill(grid, '?'); | ||||
|  * sp_cp437_grid_set(grid, 0, 0, '!'); | ||||
|  * sp_cp437_grid_dealloc(grid); | ||||
|  * ``` | ||||
|  */ | ||||
| typedef struct sp_Packet sp_Packet; | ||||
| typedef struct SPCp437Grid SPCp437Grid; | ||||
| 
 | ||||
| /**
 | ||||
|  * A grid of pixels stored in packed bytes. | ||||
|  * The raw packet | ||||
|  */ | ||||
| typedef struct sp_PixelGrid sp_PixelGrid; | ||||
| typedef struct SPPacket SPPacket; | ||||
| 
 | ||||
| /**
 | ||||
|  * A grid of pixels. | ||||
|  * | ||||
|  * # Examples | ||||
|  * | ||||
|  * ```C | ||||
|  * Cp437Grid grid = sp_pixel_grid_new(8, 3); | ||||
|  * sp_pixel_grid_fill(grid, true); | ||||
|  * sp_pixel_grid_set(grid, 0, 0, false); | ||||
|  * sp_pixel_grid_dealloc(grid); | ||||
|  * ``` | ||||
|  */ | ||||
| typedef struct SPPixelGrid SPPixelGrid; | ||||
| 
 | ||||
| /**
 | ||||
|  * Represents a span of memory (`&mut [u8]` ) as a struct usable by C code. | ||||
|  | @ -188,7 +175,7 @@ typedef struct sp_PixelGrid sp_PixelGrid; | |||
|  * - the lifetime of the `CByteSlice` does not outlive the memory it points to, as described in | ||||
|  *   the function returning this type. | ||||
|  */ | ||||
| typedef struct sp_CByteSlice { | ||||
| typedef struct SPByteSlice { | ||||
|     /**
 | ||||
|      * The start address of the memory | ||||
|      */ | ||||
|  | @ -197,16 +184,12 @@ typedef struct sp_CByteSlice { | |||
|      * The amount of memory in bytes | ||||
|      */ | ||||
|     size_t length; | ||||
| } sp_CByteSlice; | ||||
| } SPByteSlice; | ||||
| 
 | ||||
| /**
 | ||||
|  * Type alias for documenting the meaning of the u16 in enum values | ||||
|  * Type alias for documenting the meaning of the variable in enum values | ||||
|  */ | ||||
| typedef size_t sp_Offset; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| typedef size_t SPOffset; | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
|  | @ -224,7 +207,7 @@ extern "C" { | |||
|  * - the returned instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_bit_vec_dealloc`. | ||||
|  */ | ||||
| struct sp_CBitVec *sp_bit_vec_clone(const struct sp_CBitVec *this_); | ||||
| struct SPBitVec *sp_bit_vec_clone(const struct SPBitVec *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Deallocates a `BitVec`. | ||||
|  | @ -237,7 +220,7 @@ struct sp_CBitVec *sp_bit_vec_clone(const struct sp_CBitVec *this_); | |||
|  * - `this` is not used concurrently or after this call | ||||
|  * - `this` was not passed to another consuming function, e.g. to create a `Command` | ||||
|  */ | ||||
| void sp_bit_vec_dealloc(struct sp_CBitVec *this_); | ||||
| void sp_bit_vec_dealloc(struct SPBitVec *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Sets the value of all bits in the `BitVec`. | ||||
|  | @ -253,7 +236,7 @@ void sp_bit_vec_dealloc(struct sp_CBitVec *this_); | |||
|  * - `this` points to a valid `BitVec` | ||||
|  * - `this` is not written to or read from concurrently | ||||
|  */ | ||||
| void sp_bit_vec_fill(struct sp_CBitVec *this_, bool value); | ||||
| void sp_bit_vec_fill(struct SPBitVec *this_, bool value); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the value of a bit from the `BitVec`. | ||||
|  | @ -276,7 +259,7 @@ void sp_bit_vec_fill(struct sp_CBitVec *this_, bool value); | |||
|  * - `this` points to a valid `BitVec` | ||||
|  * - `this` is not written to concurrently | ||||
|  */ | ||||
| bool sp_bit_vec_get(const struct sp_CBitVec *this_, size_t index); | ||||
| bool sp_bit_vec_get(const struct SPBitVec *this_, size_t index); | ||||
| 
 | ||||
| /**
 | ||||
|  * Returns true if length is 0. | ||||
|  | @ -287,7 +270,7 @@ bool sp_bit_vec_get(const struct sp_CBitVec *this_, size_t index); | |||
|  * | ||||
|  * - `this` points to a valid `BitVec` | ||||
|  */ | ||||
| bool sp_bit_vec_is_empty(const struct sp_CBitVec *this_); | ||||
| bool sp_bit_vec_is_empty(const struct SPBitVec *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the length of the `BitVec` in bits. | ||||
|  | @ -298,7 +281,7 @@ bool sp_bit_vec_is_empty(const struct sp_CBitVec *this_); | |||
|  * | ||||
|  * - `this` points to a valid `BitVec` | ||||
|  */ | ||||
| size_t sp_bit_vec_len(const struct sp_CBitVec *this_); | ||||
| size_t sp_bit_vec_len(const struct SPBitVec *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Interpret the data as a series of bits and load then into a new `BitVec` instance. | ||||
|  | @ -312,7 +295,7 @@ size_t sp_bit_vec_len(const struct sp_CBitVec *this_); | |||
|  * - the returned instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_bit_vec_dealloc`. | ||||
|  */ | ||||
| struct sp_CBitVec *sp_bit_vec_load(const uint8_t *data, | ||||
| struct SPBitVec *sp_bit_vec_load(const uint8_t *data, | ||||
|                                  size_t data_length); | ||||
| 
 | ||||
| /**
 | ||||
|  | @ -335,7 +318,7 @@ struct sp_CBitVec *sp_bit_vec_load(const uint8_t *data, | |||
|  * - the returned instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_bit_vec_dealloc`. | ||||
|  */ | ||||
| struct sp_CBitVec *sp_bit_vec_new(size_t size); | ||||
| struct SPBitVec *sp_bit_vec_new(size_t size); | ||||
| 
 | ||||
| /**
 | ||||
|  * Sets the value of a bit in the `BitVec`. | ||||
|  | @ -359,7 +342,7 @@ struct sp_CBitVec *sp_bit_vec_new(size_t size); | |||
|  * - `this` points to a valid `BitVec` | ||||
|  * - `this` is not written to or read from concurrently | ||||
|  */ | ||||
| void sp_bit_vec_set(struct sp_CBitVec *this_, size_t index, bool value); | ||||
| void sp_bit_vec_set(struct SPBitVec *this_, size_t index, bool value); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets an unsafe reference to the data of the `BitVec` instance. | ||||
|  | @ -372,7 +355,7 @@ void sp_bit_vec_set(struct sp_CBitVec *this_, size_t index, bool value); | |||
|  * - the returned memory range is never accessed after the passed `BitVec` has been freed | ||||
|  * - the returned memory range is never accessed concurrently, either via the `BitVec` or directly | ||||
|  */ | ||||
| struct sp_CByteSlice sp_bit_vec_unsafe_data_ref(struct sp_CBitVec *this_); | ||||
| struct SPByteSlice sp_bit_vec_unsafe_data_ref(struct SPBitVec *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Clones a `BrightnessGrid`. | ||||
|  | @ -386,7 +369,7 @@ struct sp_CByteSlice sp_bit_vec_unsafe_data_ref(struct sp_CBitVec *this_); | |||
|  * - the returned instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_brightness_grid_dealloc`. | ||||
|  */ | ||||
| struct sp_CBrightnessGrid *sp_brightness_grid_clone(const struct sp_CBrightnessGrid *this_); | ||||
| struct SPBrightnessGrid *sp_brightness_grid_clone(const struct SPBrightnessGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Deallocates a `BrightnessGrid`. | ||||
|  | @ -399,7 +382,7 @@ struct sp_CBrightnessGrid *sp_brightness_grid_clone(const struct sp_CBrightnessG | |||
|  * - `this` is not used concurrently or after this call | ||||
|  * - `this` was not passed to another consuming function, e.g. to create a `Command` | ||||
|  */ | ||||
| void sp_brightness_grid_dealloc(struct sp_CBrightnessGrid *this_); | ||||
| void sp_brightness_grid_dealloc(struct SPBrightnessGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Sets the value of all cells in the `BrightnessGrid`. | ||||
|  | @ -420,7 +403,7 @@ void sp_brightness_grid_dealloc(struct sp_CBrightnessGrid *this_); | |||
|  * - `this` points to a valid `BrightnessGrid` | ||||
|  * - `this` is not written to or read from concurrently | ||||
|  */ | ||||
| void sp_brightness_grid_fill(struct sp_CBrightnessGrid *this_, uint8_t value); | ||||
| void sp_brightness_grid_fill(struct SPBrightnessGrid *this_, uint8_t value); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the current value at the specified position. | ||||
|  | @ -441,7 +424,7 @@ void sp_brightness_grid_fill(struct sp_CBrightnessGrid *this_, uint8_t value); | |||
|  * - `this` points to a valid `BrightnessGrid` | ||||
|  * - `this` is not written to concurrently | ||||
|  */ | ||||
| uint8_t sp_brightness_grid_get(const struct sp_CBrightnessGrid *this_, | ||||
| uint8_t sp_brightness_grid_get(const struct SPBrightnessGrid *this_, | ||||
|                                size_t x, | ||||
|                                size_t y); | ||||
| 
 | ||||
|  | @ -458,7 +441,7 @@ uint8_t sp_brightness_grid_get(const struct sp_CBrightnessGrid *this_, | |||
|  * | ||||
|  * - `this` points to a valid `BrightnessGrid` | ||||
|  */ | ||||
| size_t sp_brightness_grid_height(const struct sp_CBrightnessGrid *this_); | ||||
| size_t sp_brightness_grid_height(const struct SPBrightnessGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Loads a `BrightnessGrid` with the specified dimensions from the provided data. | ||||
|  | @ -476,7 +459,7 @@ size_t sp_brightness_grid_height(const struct sp_CBrightnessGrid *this_); | |||
|  * - the returned instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_brightness_grid_dealloc`. | ||||
|  */ | ||||
| struct sp_CBrightnessGrid *sp_brightness_grid_load(size_t width, | ||||
| struct SPBrightnessGrid *sp_brightness_grid_load(size_t width, | ||||
|                                                  size_t height, | ||||
|                                                  const uint8_t *data, | ||||
|                                                  size_t data_length); | ||||
|  | @ -493,7 +476,7 @@ struct sp_CBrightnessGrid *sp_brightness_grid_load(size_t width, | |||
|  * - the returned instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_brightness_grid_dealloc`. | ||||
|  */ | ||||
| struct sp_CBrightnessGrid *sp_brightness_grid_new(size_t width, | ||||
| struct SPBrightnessGrid *sp_brightness_grid_new(size_t width, | ||||
|                                                 size_t height); | ||||
| 
 | ||||
| /**
 | ||||
|  | @ -519,7 +502,7 @@ struct sp_CBrightnessGrid *sp_brightness_grid_new(size_t width, | |||
|  * - `this` points to a valid `BitVec` | ||||
|  * - `this` is not written to or read from concurrently | ||||
|  */ | ||||
| void sp_brightness_grid_set(struct sp_CBrightnessGrid *this_, | ||||
| void sp_brightness_grid_set(struct SPBrightnessGrid *this_, | ||||
|                             size_t x, | ||||
|                             size_t y, | ||||
|                             uint8_t value); | ||||
|  | @ -535,7 +518,7 @@ void sp_brightness_grid_set(struct sp_CBrightnessGrid *this_, | |||
|  * - the returned memory range is never accessed after the passed `BrightnessGrid` has been freed | ||||
|  * - the returned memory range is never accessed concurrently, either via the `BrightnessGrid` or directly | ||||
|  */ | ||||
| struct sp_CByteSlice sp_brightness_grid_unsafe_data_ref(struct sp_CBrightnessGrid *this_); | ||||
| struct SPByteSlice sp_brightness_grid_unsafe_data_ref(struct SPBrightnessGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the width of the `BrightnessGrid` instance. | ||||
|  | @ -550,7 +533,7 @@ struct sp_CByteSlice sp_brightness_grid_unsafe_data_ref(struct sp_CBrightnessGri | |||
|  * | ||||
|  * - `this` points to a valid `BrightnessGrid` | ||||
|  */ | ||||
| size_t sp_brightness_grid_width(const struct sp_CBrightnessGrid *this_); | ||||
| size_t sp_brightness_grid_width(const struct SPBrightnessGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::BitmapLinear` instance. | ||||
|  | @ -566,9 +549,9 @@ size_t sp_brightness_grid_width(const struct sp_CBrightnessGrid *this_); | |||
|  * - the returned `Command` instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_command_dealloc`. | ||||
|  */ | ||||
| struct sp_CCommand *sp_command_bitmap_linear(sp_Offset offset, | ||||
|                                              struct sp_CBitVec *bit_vec, | ||||
|                                              sp_CompressionCode compression); | ||||
| struct SPCommand *sp_command_bitmap_linear(SPOffset offset, | ||||
|                                            struct SPBitVec *bit_vec, | ||||
|                                            SPCompressionCode compression); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::BitmapLinearAnd` instance. | ||||
|  | @ -584,9 +567,9 @@ struct sp_CCommand *sp_command_bitmap_linear(sp_Offset offset, | |||
|  * - the returned `Command` instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_command_dealloc`. | ||||
|  */ | ||||
| struct sp_CCommand *sp_command_bitmap_linear_and(sp_Offset offset, | ||||
|                                                  struct sp_CBitVec *bit_vec, | ||||
|                                                  sp_CompressionCode compression); | ||||
| struct SPCommand *sp_command_bitmap_linear_and(SPOffset offset, | ||||
|                                                struct SPBitVec *bit_vec, | ||||
|                                                SPCompressionCode compression); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::BitmapLinearOr` instance. | ||||
|  | @ -602,9 +585,9 @@ struct sp_CCommand *sp_command_bitmap_linear_and(sp_Offset offset, | |||
|  * - the returned `Command` instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_command_dealloc`. | ||||
|  */ | ||||
| struct sp_CCommand *sp_command_bitmap_linear_or(sp_Offset offset, | ||||
|                                                 struct sp_CBitVec *bit_vec, | ||||
|                                                 sp_CompressionCode compression); | ||||
| struct SPCommand *sp_command_bitmap_linear_or(SPOffset offset, | ||||
|                                               struct SPBitVec *bit_vec, | ||||
|                                               SPCompressionCode compression); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::BitmapLinearWin` instance. | ||||
|  | @ -620,10 +603,10 @@ struct sp_CCommand *sp_command_bitmap_linear_or(sp_Offset offset, | |||
|  * - the returned `Command` instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_command_dealloc`. | ||||
|  */ | ||||
| struct sp_CCommand *sp_command_bitmap_linear_win(size_t x, | ||||
| struct SPCommand *sp_command_bitmap_linear_win(size_t x, | ||||
|                                                size_t y, | ||||
|                                                  struct sp_PixelGrid *pixel_grid, | ||||
|                                                  sp_CompressionCode compression_code); | ||||
|                                                struct SPPixelGrid *pixel_grid, | ||||
|                                                SPCompressionCode compression_code); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::BitmapLinearXor` instance. | ||||
|  | @ -639,9 +622,9 @@ struct sp_CCommand *sp_command_bitmap_linear_win(size_t x, | |||
|  * - the returned `Command` instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_command_dealloc`. | ||||
|  */ | ||||
| struct sp_CCommand *sp_command_bitmap_linear_xor(sp_Offset offset, | ||||
|                                                  struct sp_CBitVec *bit_vec, | ||||
|                                                  sp_CompressionCode compression); | ||||
| struct SPCommand *sp_command_bitmap_linear_xor(SPOffset offset, | ||||
|                                                struct SPBitVec *bit_vec, | ||||
|                                                SPCompressionCode compression); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::Brightness` instance for setting the brightness of all tiles to the | ||||
|  | @ -655,27 +638,27 @@ struct sp_CCommand *sp_command_bitmap_linear_xor(sp_Offset offset, | |||
|  * | ||||
|  * The caller has to make sure that: | ||||
|  * | ||||
|  * - the returned `Command` instance is freed in some way, either by using a consuming function or | ||||
|  * - the returned `SPCommand` instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_command_dealloc`. | ||||
|  */ | ||||
| struct sp_CCommand *sp_command_brightness(uint8_t brightness); | ||||
| struct SPCommand *sp_command_brightness(uint8_t brightness); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::CharBrightness` instance. | ||||
|  * The passed `ByteGrid` gets consumed. | ||||
|  * The passed `SPBrightnessGrid` gets consumed. | ||||
|  * | ||||
|  * # Safety | ||||
|  * | ||||
|  * The caller has to make sure that: | ||||
|  * | ||||
|  * - `byte_grid` points to a valid instance of `ByteGrid` | ||||
|  * - `byte_grid` is not used concurrently or after this call | ||||
|  * - `grid` points to a valid instance of `SPBrightnessGrid` | ||||
|  * - `grid` is not used concurrently or after this call | ||||
|  * - the returned `Command` instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_command_dealloc`. | ||||
|  */ | ||||
| struct sp_CCommand *sp_command_char_brightness(size_t x, | ||||
| struct SPCommand *sp_command_char_brightness(size_t x, | ||||
|                                              size_t y, | ||||
|                                                struct sp_CBrightnessGrid *byte_grid); | ||||
|                                              struct SPBrightnessGrid *grid); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::Clear` instance. | ||||
|  | @ -687,7 +670,7 @@ struct sp_CCommand *sp_command_char_brightness(size_t x, | |||
|  * - the returned `Command` instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_command_dealloc`. | ||||
|  */ | ||||
| struct sp_CCommand *sp_command_clear(void); | ||||
| struct SPCommand *sp_command_clear(void); | ||||
| 
 | ||||
| /**
 | ||||
|  * Clones a `Command` instance. | ||||
|  | @ -701,7 +684,7 @@ struct sp_CCommand *sp_command_clear(void); | |||
|  * - the returned `Command` instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_command_dealloc`. | ||||
|  */ | ||||
| struct sp_CCommand *sp_command_clone(const struct sp_CCommand *original); | ||||
| struct SPCommand *sp_command_clone(const struct SPCommand *original); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::Cp437Data` instance. | ||||
|  | @ -716,9 +699,9 @@ struct sp_CCommand *sp_command_clone(const struct sp_CCommand *original); | |||
|  * - the returned `Command` instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_command_dealloc`. | ||||
|  */ | ||||
| struct sp_CCommand *sp_command_cp437_data(size_t x, | ||||
| struct SPCommand *sp_command_cp437_data(size_t x, | ||||
|                                         size_t y, | ||||
|                                           struct sp_CCp437Grid *byte_grid); | ||||
|                                         struct SPCp437Grid *byte_grid); | ||||
| 
 | ||||
| /**
 | ||||
|  * Deallocates a `Command`. | ||||
|  | @ -731,7 +714,7 @@ struct sp_CCommand *sp_command_cp437_data(size_t x, | |||
|  * - `this` is not used concurrently or after this call | ||||
|  * - `this` was not passed to another consuming function, e.g. to create a `Packet` | ||||
|  */ | ||||
| void sp_command_dealloc(struct sp_CCommand *ptr); | ||||
| void sp_command_dealloc(struct SPCommand *ptr); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::FadeOut` instance. | ||||
|  | @ -743,7 +726,7 @@ void sp_command_dealloc(struct sp_CCommand *ptr); | |||
|  * - the returned `Command` instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_command_dealloc`. | ||||
|  */ | ||||
| struct sp_CCommand *sp_command_fade_out(void); | ||||
| struct SPCommand *sp_command_fade_out(void); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::HardReset` instance. | ||||
|  | @ -755,7 +738,7 @@ struct sp_CCommand *sp_command_fade_out(void); | |||
|  * - the returned `Command` instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_command_dealloc`. | ||||
|  */ | ||||
| struct sp_CCommand *sp_command_hard_reset(void); | ||||
| struct SPCommand *sp_command_hard_reset(void); | ||||
| 
 | ||||
| /**
 | ||||
|  * Tries to turn a `Packet` into a `Command`. The packet is deallocated in the process. | ||||
|  | @ -772,7 +755,7 @@ struct sp_CCommand *sp_command_hard_reset(void); | |||
|  * - the returned `Command` instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_command_dealloc`. | ||||
|  */ | ||||
| struct sp_CCommand *sp_command_try_from_packet(struct sp_Packet *packet); | ||||
| struct SPCommand *sp_command_try_from_packet(struct SPPacket *packet); | ||||
| 
 | ||||
| /**
 | ||||
|  * Closes and deallocates a `Connection`. | ||||
|  | @ -784,7 +767,7 @@ struct sp_CCommand *sp_command_try_from_packet(struct sp_Packet *packet); | |||
|  * - `this` points to a valid `Connection` | ||||
|  * - `this` is not used concurrently or after this call | ||||
|  */ | ||||
| void sp_connection_dealloc(struct sp_Connection *ptr); | ||||
| void sp_connection_dealloc(struct SPConnection *ptr); | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates a new instance of `Connection`. | ||||
|  | @ -802,7 +785,7 @@ void sp_connection_dealloc(struct sp_Connection *ptr); | |||
|  * - the returned instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_connection_dealloc`. | ||||
|  */ | ||||
| struct sp_Connection *sp_connection_open(const char *host); | ||||
| struct SPConnection *sp_connection_open(const char *host); | ||||
| 
 | ||||
| /**
 | ||||
|  * Sends a `Packet` to the display using the `Connection`. | ||||
|  | @ -818,8 +801,8 @@ struct sp_Connection *sp_connection_open(const char *host); | |||
|  * - `packet` points to a valid instance of `Packet` | ||||
|  * - `packet` is not used concurrently or after this call | ||||
|  */ | ||||
| bool sp_connection_send(const struct sp_Connection *connection, | ||||
|                         struct sp_Packet *packet); | ||||
| bool sp_connection_send(const struct SPConnection *connection, | ||||
|                         struct SPPacket *packet); | ||||
| 
 | ||||
| /**
 | ||||
|  * Clones a `Cp437Grid`. | ||||
|  | @ -833,7 +816,7 @@ bool sp_connection_send(const struct sp_Connection *connection, | |||
|  * - the returned instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_cp437_grid_dealloc`. | ||||
|  */ | ||||
| struct sp_CCp437Grid *sp_cp437_grid_clone(const struct sp_CCp437Grid *this_); | ||||
| struct SPCp437Grid *sp_cp437_grid_clone(const struct SPCp437Grid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Deallocates a `Cp437Grid`. | ||||
|  | @ -846,7 +829,7 @@ struct sp_CCp437Grid *sp_cp437_grid_clone(const struct sp_CCp437Grid *this_); | |||
|  * - `this` is not used concurrently or after this call | ||||
|  * - `this` was not passed to another consuming function, e.g. to create a `Command` | ||||
|  */ | ||||
| void sp_cp437_grid_dealloc(struct sp_CCp437Grid *this_); | ||||
| void sp_cp437_grid_dealloc(struct SPCp437Grid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Sets the value of all cells in the `Cp437Grid`. | ||||
|  | @ -863,7 +846,7 @@ void sp_cp437_grid_dealloc(struct sp_CCp437Grid *this_); | |||
|  * - `this` points to a valid `Cp437Grid` | ||||
|  * - `this` is not written to or read from concurrently | ||||
|  */ | ||||
| void sp_cp437_grid_fill(struct sp_CCp437Grid *this_, uint8_t value); | ||||
| void sp_cp437_grid_fill(struct SPCp437Grid *this_, uint8_t value); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the current value at the specified position. | ||||
|  | @ -884,9 +867,7 @@ void sp_cp437_grid_fill(struct sp_CCp437Grid *this_, uint8_t value); | |||
|  * - `this` points to a valid `Cp437Grid` | ||||
|  * - `this` is not written to concurrently | ||||
|  */ | ||||
| uint8_t sp_cp437_grid_get(const struct sp_CCp437Grid *this_, | ||||
|                           size_t x, | ||||
|                           size_t y); | ||||
| uint8_t sp_cp437_grid_get(const struct SPCp437Grid *this_, size_t x, size_t y); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the height of the `Cp437Grid` instance. | ||||
|  | @ -901,7 +882,7 @@ uint8_t sp_cp437_grid_get(const struct sp_CCp437Grid *this_, | |||
|  * | ||||
|  * - `this` points to a valid `Cp437Grid` | ||||
|  */ | ||||
| size_t sp_cp437_grid_height(const struct sp_CCp437Grid *this_); | ||||
| size_t sp_cp437_grid_height(const struct SPCp437Grid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Loads a `Cp437Grid` with the specified dimensions from the provided data. | ||||
|  | @ -919,7 +900,7 @@ size_t sp_cp437_grid_height(const struct sp_CCp437Grid *this_); | |||
|  * - the returned instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_cp437_grid_dealloc`. | ||||
|  */ | ||||
| struct sp_CCp437Grid *sp_cp437_grid_load(size_t width, | ||||
| struct SPCp437Grid *sp_cp437_grid_load(size_t width, | ||||
|                                        size_t height, | ||||
|                                        const uint8_t *data, | ||||
|                                        size_t data_length); | ||||
|  | @ -936,7 +917,7 @@ struct sp_CCp437Grid *sp_cp437_grid_load(size_t width, | |||
|  * - the returned instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_cp437_grid_dealloc`. | ||||
|  */ | ||||
| struct sp_CCp437Grid *sp_cp437_grid_new(size_t width, | ||||
| struct SPCp437Grid *sp_cp437_grid_new(size_t width, | ||||
|                                       size_t height); | ||||
| 
 | ||||
| /**
 | ||||
|  | @ -961,7 +942,7 @@ struct sp_CCp437Grid *sp_cp437_grid_new(size_t width, | |||
|  * - `this` points to a valid `BitVec` | ||||
|  * - `this` is not written to or read from concurrently | ||||
|  */ | ||||
| void sp_cp437_grid_set(struct sp_CCp437Grid *this_, | ||||
| void sp_cp437_grid_set(struct SPCp437Grid *this_, | ||||
|                        size_t x, | ||||
|                        size_t y, | ||||
|                        uint8_t value); | ||||
|  | @ -977,7 +958,7 @@ void sp_cp437_grid_set(struct sp_CCp437Grid *this_, | |||
|  * - the returned memory range is never accessed after the passed `Cp437Grid` has been freed | ||||
|  * - the returned memory range is never accessed concurrently, either via the `Cp437Grid` or directly | ||||
|  */ | ||||
| struct sp_CByteSlice sp_cp437_grid_unsafe_data_ref(struct sp_CCp437Grid *this_); | ||||
| struct SPByteSlice sp_cp437_grid_unsafe_data_ref(struct SPCp437Grid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the width of the `Cp437Grid` instance. | ||||
|  | @ -992,7 +973,7 @@ struct sp_CByteSlice sp_cp437_grid_unsafe_data_ref(struct sp_CCp437Grid *this_); | |||
|  * | ||||
|  * - `this` points to a valid `Cp437Grid` | ||||
|  */ | ||||
| size_t sp_cp437_grid_width(const struct sp_CCp437Grid *this_); | ||||
| size_t sp_cp437_grid_width(const struct SPCp437Grid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Clones a `Packet`. | ||||
|  | @ -1006,7 +987,7 @@ size_t sp_cp437_grid_width(const struct sp_CCp437Grid *this_); | |||
|  * - the returned instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_packet_dealloc`. | ||||
|  */ | ||||
| struct sp_Packet *sp_packet_clone(const struct sp_Packet *this_); | ||||
| struct SPPacket *sp_packet_clone(const struct SPPacket *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Deallocates a `Packet`. | ||||
|  | @ -1018,7 +999,7 @@ struct sp_Packet *sp_packet_clone(const struct sp_Packet *this_); | |||
|  * - `this` points to a valid `Packet` | ||||
|  * - `this` is not used concurrently or after this call | ||||
|  */ | ||||
| void sp_packet_dealloc(struct sp_Packet *this_); | ||||
| void sp_packet_dealloc(struct SPPacket *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Turns a `Command` into a `Packet`. | ||||
|  | @ -1033,7 +1014,7 @@ void sp_packet_dealloc(struct sp_Packet *this_); | |||
|  * - the returned `Packet` instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_packet_dealloc`. | ||||
|  */ | ||||
| struct sp_Packet *sp_packet_from_command(struct sp_CCommand *command); | ||||
| struct SPPacket *sp_packet_from_command(struct SPCommand *command); | ||||
| 
 | ||||
| /**
 | ||||
|  * Tries to load a `Packet` from the passed array with the specified length. | ||||
|  | @ -1049,7 +1030,7 @@ struct sp_Packet *sp_packet_from_command(struct sp_CCommand *command); | |||
|  * - the returned `Packet` instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_packet_dealloc`. | ||||
|  */ | ||||
| struct sp_Packet *sp_packet_try_load(const uint8_t *data, | ||||
| struct SPPacket *sp_packet_try_load(const uint8_t *data, | ||||
|                                     size_t length); | ||||
| 
 | ||||
| /**
 | ||||
|  | @ -1064,7 +1045,7 @@ struct sp_Packet *sp_packet_try_load(const uint8_t *data, | |||
|  * - the returned instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_pixel_grid_dealloc`. | ||||
|  */ | ||||
| struct sp_PixelGrid *sp_pixel_grid_clone(const struct sp_PixelGrid *this_); | ||||
| struct SPPixelGrid *sp_pixel_grid_clone(const struct SPPixelGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Deallocates a `PixelGrid`. | ||||
|  | @ -1077,7 +1058,7 @@ struct sp_PixelGrid *sp_pixel_grid_clone(const struct sp_PixelGrid *this_); | |||
|  * - `this` is not used concurrently or after this call | ||||
|  * - `this` was not passed to another consuming function, e.g. to create a `Command` | ||||
|  */ | ||||
| void sp_pixel_grid_dealloc(struct sp_PixelGrid *this_); | ||||
| void sp_pixel_grid_dealloc(struct SPPixelGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Sets the state of all pixels in the `PixelGrid`. | ||||
|  | @ -1094,7 +1075,7 @@ void sp_pixel_grid_dealloc(struct sp_PixelGrid *this_); | |||
|  * - `this` points to a valid `PixelGrid` | ||||
|  * - `this` is not written to or read from concurrently | ||||
|  */ | ||||
| void sp_pixel_grid_fill(struct sp_PixelGrid *this_, bool value); | ||||
| void sp_pixel_grid_fill(struct SPPixelGrid *this_, bool value); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the current value at the specified position in the `PixelGrid`. | ||||
|  | @ -1115,7 +1096,7 @@ void sp_pixel_grid_fill(struct sp_PixelGrid *this_, bool value); | |||
|  * - `this` points to a valid `PixelGrid` | ||||
|  * - `this` is not written to concurrently | ||||
|  */ | ||||
| bool sp_pixel_grid_get(const struct sp_PixelGrid *this_, size_t x, size_t y); | ||||
| bool sp_pixel_grid_get(const struct SPPixelGrid *this_, size_t x, size_t y); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the height in pixels of the `PixelGrid` instance. | ||||
|  | @ -1130,7 +1111,7 @@ bool sp_pixel_grid_get(const struct sp_PixelGrid *this_, size_t x, size_t y); | |||
|  * | ||||
|  * - `this` points to a valid `PixelGrid` | ||||
|  */ | ||||
| size_t sp_pixel_grid_height(const struct sp_PixelGrid *this_); | ||||
| size_t sp_pixel_grid_height(const struct SPPixelGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Loads a `PixelGrid` with the specified dimensions from the provided data. | ||||
|  | @ -1155,7 +1136,7 @@ size_t sp_pixel_grid_height(const struct sp_PixelGrid *this_); | |||
|  * - the returned instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_pixel_grid_dealloc`. | ||||
|  */ | ||||
| struct sp_PixelGrid *sp_pixel_grid_load(size_t width, | ||||
| struct SPPixelGrid *sp_pixel_grid_load(size_t width, | ||||
|                                        size_t height, | ||||
|                                        const uint8_t *data, | ||||
|                                        size_t data_length); | ||||
|  | @ -1181,7 +1162,7 @@ struct sp_PixelGrid *sp_pixel_grid_load(size_t width, | |||
|  * - the returned instance is freed in some way, either by using a consuming function or | ||||
|  *   by explicitly calling `sp_pixel_grid_dealloc`. | ||||
|  */ | ||||
| struct sp_PixelGrid *sp_pixel_grid_new(size_t width, | ||||
| struct SPPixelGrid *sp_pixel_grid_new(size_t width, | ||||
|                                       size_t height); | ||||
| 
 | ||||
| /**
 | ||||
|  | @ -1206,7 +1187,7 @@ struct sp_PixelGrid *sp_pixel_grid_new(size_t width, | |||
|  * - `this` points to a valid `PixelGrid` | ||||
|  * - `this` is not written to or read from concurrently | ||||
|  */ | ||||
| void sp_pixel_grid_set(struct sp_PixelGrid *this_, | ||||
| void sp_pixel_grid_set(struct SPPixelGrid *this_, | ||||
|                        size_t x, | ||||
|                        size_t y, | ||||
|                        bool value); | ||||
|  | @ -1222,7 +1203,7 @@ void sp_pixel_grid_set(struct sp_PixelGrid *this_, | |||
|  * - the returned memory range is never accessed after the passed `PixelGrid` has been freed | ||||
|  * - the returned memory range is never accessed concurrently, either via the `PixelGrid` or directly | ||||
|  */ | ||||
| struct sp_CByteSlice sp_pixel_grid_unsafe_data_ref(struct sp_PixelGrid *this_); | ||||
| struct SPByteSlice sp_pixel_grid_unsafe_data_ref(struct SPPixelGrid *this_); | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets the width in pixels of the `PixelGrid` instance. | ||||
|  | @ -1237,7 +1218,7 @@ struct sp_CByteSlice sp_pixel_grid_unsafe_data_ref(struct sp_PixelGrid *this_); | |||
|  * | ||||
|  * - `this` points to a valid `PixelGrid` | ||||
|  */ | ||||
| size_t sp_pixel_grid_width(const struct sp_PixelGrid *this_); | ||||
| size_t sp_pixel_grid_width(const struct SPPixelGrid *this_); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } // extern "C"
 | ||||
|  |  | |||
|  | @ -2,15 +2,15 @@ | |||
| #include "servicepoint.h" | ||||
| 
 | ||||
| int main(void) { | ||||
|     sp_Connection *connection = sp_connection_open("172.23.42.29:2342"); | ||||
|     SPConnection *connection = sp_connection_open("172.23.42.29:2342"); | ||||
|     if (connection == NULL) | ||||
|         return 1; | ||||
| 
 | ||||
|     sp_PixelGrid *pixels = sp_pixel_grid_new(sp_PIXEL_WIDTH, sp_PIXEL_HEIGHT); | ||||
|     SPPixelGrid *pixels = sp_pixel_grid_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT); | ||||
|     sp_pixel_grid_fill(pixels, true); | ||||
| 
 | ||||
|     sp_CCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed); | ||||
|     sp_Packet *packet = sp_packet_from_command(command); | ||||
|     SPCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed); | ||||
|     SPPacket *packet = sp_packet_from_command(command); | ||||
|     while (sp_connection_send(connection, sp_packet_clone(packet))); | ||||
| 
 | ||||
|     sp_packet_dealloc(packet); | ||||
|  |  | |||
|  | @ -2,34 +2,34 @@ | |||
| //!
 | ||||
| //! prefix `sp_bit_vec_`
 | ||||
| 
 | ||||
| use crate::c_slice::CByteSlice; | ||||
| use crate::c_slice::SPByteSlice; | ||||
| use servicepoint::bitvec::prelude::{BitVec, Msb0}; | ||||
| 
 | ||||
| /// cbindgen:no-export
 | ||||
| type SpBitVec = BitVec<u8, Msb0>; | ||||
| 
 | ||||
| /// A vector of bits
 | ||||
| pub struct CBitVec { | ||||
|     actual: SpBitVec, | ||||
| } | ||||
| ///
 | ||||
| /// # Examples
 | ||||
| /// ```C
 | ||||
| /// SPBitVec vec = sp_bit_vec_new(8);
 | ||||
| /// sp_bit_vec_set(vec, 5, true);
 | ||||
| /// sp_bit_vec_dealloc(vec);
 | ||||
| /// ```
 | ||||
| pub struct SPBitVec(BitVec<u8, Msb0>); | ||||
| 
 | ||||
| impl From<SpBitVec> for CBitVec { | ||||
|     fn from(actual: SpBitVec) -> Self { | ||||
|         Self { actual } | ||||
| impl From<BitVec<u8, Msb0>> for SPBitVec { | ||||
|     fn from(actual: BitVec<u8, Msb0>) -> Self { | ||||
|         Self(actual) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<CBitVec> for SpBitVec { | ||||
|     fn from(value: CBitVec) -> Self { | ||||
|         value.actual | ||||
| impl From<SPBitVec> for BitVec<u8, Msb0> { | ||||
|     fn from(value: SPBitVec) -> Self { | ||||
|         value.0 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Clone for CBitVec { | ||||
| impl Clone for SPBitVec { | ||||
|     fn clone(&self) -> Self { | ||||
|         CBitVec { | ||||
|             actual: self.actual.clone(), | ||||
|         } | ||||
|         SPBitVec(self.0.clone()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -52,10 +52,8 @@ impl Clone for CBitVec { | |||
| /// - the returned instance is freed in some way, either by using a consuming function or
 | ||||
| ///   by explicitly calling `sp_bit_vec_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_new(size: usize) -> *mut CBitVec { | ||||
|     Box::into_raw(Box::new(CBitVec { | ||||
|         actual: SpBitVec::repeat(false, size), | ||||
|     })) | ||||
| pub unsafe extern "C" fn sp_bit_vec_new(size: usize) -> *mut SPBitVec { | ||||
|     Box::into_raw(Box::new(SPBitVec(BitVec::repeat(false, size)))) | ||||
| } | ||||
| 
 | ||||
| /// Interpret the data as a series of bits and load then into a new `BitVec` instance.
 | ||||
|  | @ -72,11 +70,9 @@ pub unsafe extern "C" fn sp_bit_vec_new(size: usize) -> *mut CBitVec { | |||
| pub unsafe extern "C" fn sp_bit_vec_load( | ||||
|     data: *const u8, | ||||
|     data_length: usize, | ||||
| ) -> *mut CBitVec { | ||||
| ) -> *mut SPBitVec { | ||||
|     let data = std::slice::from_raw_parts(data, data_length); | ||||
|     Box::into_raw(Box::new(CBitVec { | ||||
|         actual: SpBitVec::from_slice(data), | ||||
|     })) | ||||
|     Box::into_raw(Box::new(SPBitVec(BitVec::from_slice(data)))) | ||||
| } | ||||
| 
 | ||||
| /// Clones a `BitVec`.
 | ||||
|  | @ -91,8 +87,8 @@ pub unsafe extern "C" fn sp_bit_vec_load( | |||
| ///   by explicitly calling `sp_bit_vec_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_clone( | ||||
|     this: *const CBitVec, | ||||
| ) -> *mut CBitVec { | ||||
|     this: *const SPBitVec, | ||||
| ) -> *mut SPBitVec { | ||||
|     Box::into_raw(Box::new((*this).clone())) | ||||
| } | ||||
| 
 | ||||
|  | @ -106,7 +102,7 @@ pub unsafe extern "C" fn sp_bit_vec_clone( | |||
| /// - `this` is not used concurrently or after this call
 | ||||
| /// - `this` was not passed to another consuming function, e.g. to create a `Command`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_dealloc(this: *mut CBitVec) { | ||||
| pub unsafe extern "C" fn sp_bit_vec_dealloc(this: *mut SPBitVec) { | ||||
|     _ = Box::from_raw(this); | ||||
| } | ||||
| 
 | ||||
|  | @ -131,10 +127,10 @@ pub unsafe extern "C" fn sp_bit_vec_dealloc(this: *mut CBitVec) { | |||
| /// - `this` is not written to concurrently
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_get( | ||||
|     this: *const CBitVec, | ||||
|     this: *const SPBitVec, | ||||
|     index: usize, | ||||
| ) -> bool { | ||||
|     *(*this).actual.get(index).unwrap() | ||||
|     *(*this).0.get(index).unwrap() | ||||
| } | ||||
| 
 | ||||
| /// Sets the value of a bit in the `BitVec`.
 | ||||
|  | @ -159,11 +155,11 @@ pub unsafe extern "C" fn sp_bit_vec_get( | |||
| /// - `this` is not written to or read from concurrently
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_set( | ||||
|     this: *mut CBitVec, | ||||
|     this: *mut SPBitVec, | ||||
|     index: usize, | ||||
|     value: bool, | ||||
| ) { | ||||
|     (*this).actual.set(index, value) | ||||
|     (*this).0.set(index, value) | ||||
| } | ||||
| 
 | ||||
| /// Sets the value of all bits in the `BitVec`.
 | ||||
|  | @ -179,8 +175,8 @@ pub unsafe extern "C" fn sp_bit_vec_set( | |||
| /// - `this` points to a valid `BitVec`
 | ||||
| /// - `this` is not written to or read from concurrently
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_fill(this: *mut CBitVec, value: bool) { | ||||
|     (*this).actual.fill(value) | ||||
| pub unsafe extern "C" fn sp_bit_vec_fill(this: *mut SPBitVec, value: bool) { | ||||
|     (*this).0.fill(value) | ||||
| } | ||||
| 
 | ||||
| /// Gets the length of the `BitVec` in bits.
 | ||||
|  | @ -191,8 +187,8 @@ pub unsafe extern "C" fn sp_bit_vec_fill(this: *mut CBitVec, value: bool) { | |||
| ///
 | ||||
| /// - `this` points to a valid `BitVec`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_len(this: *const CBitVec) -> usize { | ||||
|     (*this).actual.len() | ||||
| pub unsafe extern "C" fn sp_bit_vec_len(this: *const SPBitVec) -> usize { | ||||
|     (*this).0.len() | ||||
| } | ||||
| 
 | ||||
| /// Returns true if length is 0.
 | ||||
|  | @ -203,8 +199,8 @@ pub unsafe extern "C" fn sp_bit_vec_len(this: *const CBitVec) -> usize { | |||
| ///
 | ||||
| /// - `this` points to a valid `BitVec`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_is_empty(this: *const CBitVec) -> bool { | ||||
|     (*this).actual.is_empty() | ||||
| pub unsafe extern "C" fn sp_bit_vec_is_empty(this: *const SPBitVec) -> bool { | ||||
|     (*this).0.is_empty() | ||||
| } | ||||
| 
 | ||||
| /// Gets an unsafe reference to the data of the `BitVec` instance.
 | ||||
|  | @ -218,10 +214,10 @@ pub unsafe extern "C" fn sp_bit_vec_is_empty(this: *const CBitVec) -> bool { | |||
| /// - the returned memory range is never accessed concurrently, either via the `BitVec` or directly
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_bit_vec_unsafe_data_ref( | ||||
|     this: *mut CBitVec, | ||||
| ) -> CByteSlice { | ||||
|     let data = (*this).actual.as_raw_mut_slice(); | ||||
|     CByteSlice { | ||||
|     this: *mut SPBitVec, | ||||
| ) -> SPByteSlice { | ||||
|     let data = (*this).0.as_raw_mut_slice(); | ||||
|     SPByteSlice { | ||||
|         start: data.as_mut_ptr_range().start, | ||||
|         length: data.len(), | ||||
|     } | ||||
|  |  | |||
|  | @ -2,18 +2,32 @@ | |||
| //!
 | ||||
| //! prefix `sp_brightness_grid_`
 | ||||
| 
 | ||||
| use crate::c_slice::CByteSlice; | ||||
| use servicepoint::{Brightness, BrightnessGrid, DataRef, Grid, PrimitiveGrid}; | ||||
| use crate::c_slice::SPByteSlice; | ||||
| use servicepoint::{Brightness, DataRef, Grid, PrimitiveGrid}; | ||||
| use std::intrinsics::transmute; | ||||
| 
 | ||||
| /// C-wrapper for grid containing brightness values.
 | ||||
| pub struct CBrightnessGrid { | ||||
|     pub(crate) actual: BrightnessGrid, | ||||
| /// A grid containing brightness values.
 | ||||
| ///
 | ||||
| /// # Examples
 | ||||
| /// ```C
 | ||||
| /// SPConnection connection = sp_connection_open("127.0.0.1:2342");
 | ||||
| /// if (connection == NULL)
 | ||||
| ///     return 1;
 | ||||
| ///
 | ||||
| /// SPBrightnessGrid grid = sp_brightness_grid_new(2, 2);
 | ||||
| /// sp_brightness_grid_set(grid, 0, 0, 0);
 | ||||
| /// sp_brightness_grid_set(grid, 1, 1, 10);
 | ||||
| ///
 | ||||
| /// SPCommand command = sp_command_char_brightness(grid);
 | ||||
| /// sp_connection_dealloc(connection);
 | ||||
| /// ```
 | ||||
| pub struct SPBrightnessGrid { | ||||
|     pub(crate) actual: servicepoint::BrightnessGrid, | ||||
| } | ||||
| 
 | ||||
| impl Clone for CBrightnessGrid { | ||||
| impl Clone for SPBrightnessGrid { | ||||
|     fn clone(&self) -> Self { | ||||
|         CBrightnessGrid { | ||||
|         SPBrightnessGrid { | ||||
|             actual: self.actual.clone(), | ||||
|         } | ||||
|     } | ||||
|  | @ -33,9 +47,9 @@ impl Clone for CBrightnessGrid { | |||
| pub unsafe extern "C" fn sp_brightness_grid_new( | ||||
|     width: usize, | ||||
|     height: usize, | ||||
| ) -> *mut CBrightnessGrid { | ||||
|     Box::into_raw(Box::new(CBrightnessGrid { | ||||
|         actual: BrightnessGrid::new(width, height), | ||||
| ) -> *mut SPBrightnessGrid { | ||||
|     Box::into_raw(Box::new(SPBrightnessGrid { | ||||
|         actual: servicepoint::BrightnessGrid::new(width, height), | ||||
|     })) | ||||
| } | ||||
| 
 | ||||
|  | @ -59,12 +73,12 @@ pub unsafe extern "C" fn sp_brightness_grid_load( | |||
|     height: usize, | ||||
|     data: *const u8, | ||||
|     data_length: usize, | ||||
| ) -> *mut CBrightnessGrid { | ||||
| ) -> *mut SPBrightnessGrid { | ||||
|     let data = std::slice::from_raw_parts(data, data_length); | ||||
|     let grid = PrimitiveGrid::load(width, height, data); | ||||
|     let grid = | ||||
|         BrightnessGrid::try_from(grid).expect("invalid brightness value"); | ||||
|     Box::into_raw(Box::new(CBrightnessGrid { actual: grid })) | ||||
|     let grid = servicepoint::BrightnessGrid::try_from(grid) | ||||
|         .expect("invalid brightness value"); | ||||
|     Box::into_raw(Box::new(SPBrightnessGrid { actual: grid })) | ||||
| } | ||||
| 
 | ||||
| /// Clones a `BrightnessGrid`.
 | ||||
|  | @ -79,8 +93,8 @@ pub unsafe extern "C" fn sp_brightness_grid_load( | |||
| ///   by explicitly calling `sp_brightness_grid_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_brightness_grid_clone( | ||||
|     this: *const CBrightnessGrid, | ||||
| ) -> *mut CBrightnessGrid { | ||||
|     this: *const SPBrightnessGrid, | ||||
| ) -> *mut SPBrightnessGrid { | ||||
|     Box::into_raw(Box::new((*this).clone())) | ||||
| } | ||||
| 
 | ||||
|  | @ -95,7 +109,7 @@ pub unsafe extern "C" fn sp_brightness_grid_clone( | |||
| /// - `this` was not passed to another consuming function, e.g. to create a `Command`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_brightness_grid_dealloc( | ||||
|     this: *mut CBrightnessGrid, | ||||
|     this: *mut SPBrightnessGrid, | ||||
| ) { | ||||
|     _ = Box::from_raw(this); | ||||
| } | ||||
|  | @ -119,7 +133,7 @@ pub unsafe extern "C" fn sp_brightness_grid_dealloc( | |||
| /// - `this` is not written to concurrently
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_brightness_grid_get( | ||||
|     this: *const CBrightnessGrid, | ||||
|     this: *const SPBrightnessGrid, | ||||
|     x: usize, | ||||
|     y: usize, | ||||
| ) -> u8 { | ||||
|  | @ -149,7 +163,7 @@ pub unsafe extern "C" fn sp_brightness_grid_get( | |||
| /// - `this` is not written to or read from concurrently
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_brightness_grid_set( | ||||
|     this: *mut CBrightnessGrid, | ||||
|     this: *mut SPBrightnessGrid, | ||||
|     x: usize, | ||||
|     y: usize, | ||||
|     value: u8, | ||||
|  | @ -178,7 +192,7 @@ pub unsafe extern "C" fn sp_brightness_grid_set( | |||
| /// - `this` is not written to or read from concurrently
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_brightness_grid_fill( | ||||
|     this: *mut CBrightnessGrid, | ||||
|     this: *mut SPBrightnessGrid, | ||||
|     value: u8, | ||||
| ) { | ||||
|     let brightness = | ||||
|  | @ -199,7 +213,7 @@ pub unsafe extern "C" fn sp_brightness_grid_fill( | |||
| /// - `this` points to a valid `BrightnessGrid`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_brightness_grid_width( | ||||
|     this: *const CBrightnessGrid, | ||||
|     this: *const SPBrightnessGrid, | ||||
| ) -> usize { | ||||
|     (*this).actual.width() | ||||
| } | ||||
|  | @ -217,7 +231,7 @@ pub unsafe extern "C" fn sp_brightness_grid_width( | |||
| /// - `this` points to a valid `BrightnessGrid`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_brightness_grid_height( | ||||
|     this: *const CBrightnessGrid, | ||||
|     this: *const SPBrightnessGrid, | ||||
| ) -> usize { | ||||
|     (*this).actual.height() | ||||
| } | ||||
|  | @ -233,13 +247,13 @@ pub unsafe extern "C" fn sp_brightness_grid_height( | |||
| /// - the returned memory range is never accessed concurrently, either via the `BrightnessGrid` or directly
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref( | ||||
|     this: *mut CBrightnessGrid, | ||||
| ) -> CByteSlice { | ||||
|     this: *mut SPBrightnessGrid, | ||||
| ) -> SPByteSlice { | ||||
|     assert_eq!(std::mem::size_of::<Brightness>(), 1); | ||||
| 
 | ||||
|     let data = (*this).actual.data_ref_mut(); | ||||
|     let data: &mut [u8] = transmute(data); | ||||
|     CByteSlice { | ||||
|     SPByteSlice { | ||||
|         start: data.as_mut_ptr_range().start, | ||||
|         length: data.len(), | ||||
|     } | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ | |||
| /// - accesses to the memory pointed to with `start` is never accessed outside `length`
 | ||||
| /// - the lifetime of the `CByteSlice` does not outlive the memory it points to, as described in
 | ||||
| ///   the function returning this type.
 | ||||
| pub struct CByteSlice { | ||||
| pub struct SPByteSlice { | ||||
|     /// The start address of the memory
 | ||||
|     pub start: *mut u8, | ||||
|     /// The amount of memory in bytes
 | ||||
|  |  | |||
|  | @ -4,24 +4,33 @@ | |||
| 
 | ||||
| use std::ptr::null_mut; | ||||
| 
 | ||||
| use servicepoint::{ | ||||
|     Brightness, Command, CompressionCode, Offset, Origin, Packet, PixelGrid, | ||||
| }; | ||||
| use servicepoint::{Brightness, Origin}; | ||||
| 
 | ||||
| use crate::bit_vec::CBitVec; | ||||
| use crate::brightness_grid::CBrightnessGrid; | ||||
| use crate::cp437_grid::CCp437Grid; | ||||
| use crate::bit_vec::SPBitVec; | ||||
| use crate::brightness_grid::SPBrightnessGrid; | ||||
| use crate::constants::SPCompressionCode; | ||||
| use crate::cp437_grid::SPCp437Grid; | ||||
| use crate::packet::SPPacket; | ||||
| use crate::pixel_grid::SPPixelGrid; | ||||
| use crate::SPOffset; | ||||
| 
 | ||||
| /// A low-level display command.
 | ||||
| ///
 | ||||
| /// This struct and associated functions implement the UDP protocol for the display.
 | ||||
| ///
 | ||||
| /// To send a `CCommand`, use a `Connection`.
 | ||||
| pub struct CCommand(pub(crate) Command); | ||||
| /// To send a `CCommand`, use a `CConnection`.
 | ||||
| ///
 | ||||
| /// # Examples
 | ||||
| ///
 | ||||
| /// ```C
 | ||||
| /// sp_connection_send(connection, sp_command_clear());
 | ||||
| /// sp_connection_send(connection, sp_command_brightness(5));
 | ||||
| /// ```
 | ||||
| pub struct SPCommand(pub(crate) servicepoint::Command); | ||||
| 
 | ||||
| impl Clone for CCommand { | ||||
| impl Clone for SPCommand { | ||||
|     fn clone(&self) -> Self { | ||||
|         CCommand(self.0.clone()) | ||||
|         SPCommand(self.0.clone()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -40,12 +49,12 @@ impl Clone for CCommand { | |||
| ///   by explicitly calling `sp_command_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_try_from_packet( | ||||
|     packet: *mut Packet, | ||||
| ) -> *mut CCommand { | ||||
|     packet: *mut SPPacket, | ||||
| ) -> *mut SPCommand { | ||||
|     let packet = *Box::from_raw(packet); | ||||
|     match Command::try_from(packet) { | ||||
|     match servicepoint::Command::try_from(packet.0) { | ||||
|         Err(_) => null_mut(), | ||||
|         Ok(command) => Box::into_raw(Box::new(CCommand(command))), | ||||
|         Ok(command) => Box::into_raw(Box::new(SPCommand(command))), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -61,8 +70,8 @@ pub unsafe extern "C" fn sp_command_try_from_packet( | |||
| ///   by explicitly calling `sp_command_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_clone( | ||||
|     original: *const CCommand, | ||||
| ) -> *mut CCommand { | ||||
|     original: *const SPCommand, | ||||
| ) -> *mut SPCommand { | ||||
|     Box::into_raw(Box::new((*original).clone())) | ||||
| } | ||||
| 
 | ||||
|  | @ -75,8 +84,8 @@ pub unsafe extern "C" fn sp_command_clone( | |||
| /// - the returned `Command` instance is freed in some way, either by using a consuming function or
 | ||||
| ///   by explicitly calling `sp_command_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_clear() -> *mut CCommand { | ||||
|     Box::into_raw(Box::new(CCommand(Command::Clear))) | ||||
| pub unsafe extern "C" fn sp_command_clear() -> *mut SPCommand { | ||||
|     Box::into_raw(Box::new(SPCommand(servicepoint::Command::Clear))) | ||||
| } | ||||
| 
 | ||||
| /// Allocates a new `Command::HardReset` instance.
 | ||||
|  | @ -88,8 +97,8 @@ pub unsafe extern "C" fn sp_command_clear() -> *mut CCommand { | |||
| /// - the returned `Command` instance is freed in some way, either by using a consuming function or
 | ||||
| ///   by explicitly calling `sp_command_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_hard_reset() -> *mut CCommand { | ||||
|     Box::into_raw(Box::new(CCommand(Command::HardReset))) | ||||
| pub unsafe extern "C" fn sp_command_hard_reset() -> *mut SPCommand { | ||||
|     Box::into_raw(Box::new(SPCommand(servicepoint::Command::HardReset))) | ||||
| } | ||||
| 
 | ||||
| /// Allocates a new `Command::FadeOut` instance.
 | ||||
|  | @ -101,8 +110,8 @@ pub unsafe extern "C" fn sp_command_hard_reset() -> *mut CCommand { | |||
| /// - the returned `Command` instance is freed in some way, either by using a consuming function or
 | ||||
| ///   by explicitly calling `sp_command_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_fade_out() -> *mut CCommand { | ||||
|     Box::into_raw(Box::new(CCommand(Command::FadeOut))) | ||||
| pub unsafe extern "C" fn sp_command_fade_out() -> *mut SPCommand { | ||||
|     Box::into_raw(Box::new(SPCommand(servicepoint::Command::FadeOut))) | ||||
| } | ||||
| 
 | ||||
| /// Allocates a new `Command::Brightness` instance for setting the brightness of all tiles to the
 | ||||
|  | @ -116,36 +125,38 @@ pub unsafe extern "C" fn sp_command_fade_out() -> *mut CCommand { | |||
| ///
 | ||||
| /// The caller has to make sure that:
 | ||||
| ///
 | ||||
| /// - the returned `Command` instance is freed in some way, either by using a consuming function or
 | ||||
| /// - the returned `SPCommand` instance is freed in some way, either by using a consuming function or
 | ||||
| ///   by explicitly calling `sp_command_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_brightness( | ||||
|     brightness: u8, | ||||
| ) -> *mut CCommand { | ||||
| ) -> *mut SPCommand { | ||||
|     let brightness = | ||||
|         Brightness::try_from(brightness).expect("invalid brightness"); | ||||
|     Box::into_raw(Box::new(CCommand(Command::Brightness(brightness)))) | ||||
|     Box::into_raw(Box::new(SPCommand(servicepoint::Command::Brightness( | ||||
|         brightness, | ||||
|     )))) | ||||
| } | ||||
| 
 | ||||
| /// Allocates a new `Command::CharBrightness` instance.
 | ||||
| /// The passed `ByteGrid` gets consumed.
 | ||||
| /// The passed `SPBrightnessGrid` gets consumed.
 | ||||
| ///
 | ||||
| /// # Safety
 | ||||
| ///
 | ||||
| /// The caller has to make sure that:
 | ||||
| ///
 | ||||
| /// - `byte_grid` points to a valid instance of `ByteGrid`
 | ||||
| /// - `byte_grid` is not used concurrently or after this call
 | ||||
| /// - `grid` points to a valid instance of `SPBrightnessGrid`
 | ||||
| /// - `grid` is not used concurrently or after this call
 | ||||
| /// - the returned `Command` instance is freed in some way, either by using a consuming function or
 | ||||
| ///   by explicitly calling `sp_command_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_char_brightness( | ||||
|     x: usize, | ||||
|     y: usize, | ||||
|     byte_grid: *mut CBrightnessGrid, | ||||
| ) -> *mut CCommand { | ||||
|     let byte_grid = *Box::from_raw(byte_grid); | ||||
|     Box::into_raw(Box::new(CCommand(Command::CharBrightness( | ||||
|     grid: *mut SPBrightnessGrid, | ||||
| ) -> *mut SPCommand { | ||||
|     let byte_grid = *Box::from_raw(grid); | ||||
|     Box::into_raw(Box::new(SPCommand(servicepoint::Command::CharBrightness( | ||||
|         Origin::new(x, y), | ||||
|         byte_grid.actual, | ||||
|     )))) | ||||
|  | @ -165,15 +176,15 @@ pub unsafe extern "C" fn sp_command_char_brightness( | |||
| ///   by explicitly calling `sp_command_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_bitmap_linear( | ||||
|     offset: Offset, | ||||
|     bit_vec: *mut CBitVec, | ||||
|     compression: CompressionCode, | ||||
| ) -> *mut CCommand { | ||||
|     offset: SPOffset, | ||||
|     bit_vec: *mut SPBitVec, | ||||
|     compression: SPCompressionCode, | ||||
| ) -> *mut SPCommand { | ||||
|     let bit_vec = *Box::from_raw(bit_vec); | ||||
|     Box::into_raw(Box::new(CCommand(Command::BitmapLinear( | ||||
|     Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinear( | ||||
|         offset, | ||||
|         bit_vec.into(), | ||||
|         compression, | ||||
|         compression.try_into().expect("invalid compression code"), | ||||
|     )))) | ||||
| } | ||||
| 
 | ||||
|  | @ -191,15 +202,15 @@ pub unsafe extern "C" fn sp_command_bitmap_linear( | |||
| ///   by explicitly calling `sp_command_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_bitmap_linear_and( | ||||
|     offset: Offset, | ||||
|     bit_vec: *mut CBitVec, | ||||
|     compression: CompressionCode, | ||||
| ) -> *mut CCommand { | ||||
|     offset: SPOffset, | ||||
|     bit_vec: *mut SPBitVec, | ||||
|     compression: SPCompressionCode, | ||||
| ) -> *mut SPCommand { | ||||
|     let bit_vec = *Box::from_raw(bit_vec); | ||||
|     Box::into_raw(Box::new(CCommand(Command::BitmapLinearAnd( | ||||
|     Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearAnd( | ||||
|         offset, | ||||
|         bit_vec.into(), | ||||
|         compression, | ||||
|         compression.try_into().expect("invalid compression code"), | ||||
|     )))) | ||||
| } | ||||
| 
 | ||||
|  | @ -217,15 +228,15 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_and( | |||
| ///   by explicitly calling `sp_command_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_bitmap_linear_or( | ||||
|     offset: Offset, | ||||
|     bit_vec: *mut CBitVec, | ||||
|     compression: CompressionCode, | ||||
| ) -> *mut CCommand { | ||||
|     offset: SPOffset, | ||||
|     bit_vec: *mut SPBitVec, | ||||
|     compression: SPCompressionCode, | ||||
| ) -> *mut SPCommand { | ||||
|     let bit_vec = *Box::from_raw(bit_vec); | ||||
|     Box::into_raw(Box::new(CCommand(Command::BitmapLinearOr( | ||||
|     Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearOr( | ||||
|         offset, | ||||
|         bit_vec.into(), | ||||
|         compression, | ||||
|         compression.try_into().expect("invalid compression code"), | ||||
|     )))) | ||||
| } | ||||
| 
 | ||||
|  | @ -243,15 +254,15 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_or( | |||
| ///   by explicitly calling `sp_command_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_bitmap_linear_xor( | ||||
|     offset: Offset, | ||||
|     bit_vec: *mut CBitVec, | ||||
|     compression: CompressionCode, | ||||
| ) -> *mut CCommand { | ||||
|     offset: SPOffset, | ||||
|     bit_vec: *mut SPBitVec, | ||||
|     compression: SPCompressionCode, | ||||
| ) -> *mut SPCommand { | ||||
|     let bit_vec = *Box::from_raw(bit_vec); | ||||
|     Box::into_raw(Box::new(CCommand(Command::BitmapLinearXor( | ||||
|     Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearXor( | ||||
|         offset, | ||||
|         bit_vec.into(), | ||||
|         compression, | ||||
|         compression.try_into().expect("invalid compression code"), | ||||
|     )))) | ||||
| } | ||||
| 
 | ||||
|  | @ -270,10 +281,10 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_xor( | |||
| pub unsafe extern "C" fn sp_command_cp437_data( | ||||
|     x: usize, | ||||
|     y: usize, | ||||
|     byte_grid: *mut CCp437Grid, | ||||
| ) -> *mut CCommand { | ||||
|     byte_grid: *mut SPCp437Grid, | ||||
| ) -> *mut SPCommand { | ||||
|     let byte_grid = *Box::from_raw(byte_grid); | ||||
|     Box::into_raw(Box::new(CCommand(Command::Cp437Data( | ||||
|     Box::into_raw(Box::new(SPCommand(servicepoint::Command::Cp437Data( | ||||
|         Origin::new(x, y), | ||||
|         byte_grid.actual, | ||||
|     )))) | ||||
|  | @ -295,14 +306,16 @@ pub unsafe extern "C" fn sp_command_cp437_data( | |||
| pub unsafe extern "C" fn sp_command_bitmap_linear_win( | ||||
|     x: usize, | ||||
|     y: usize, | ||||
|     pixel_grid: *mut PixelGrid, | ||||
|     compression_code: CompressionCode, | ||||
| ) -> *mut CCommand { | ||||
|     let byte_grid = *Box::from_raw(pixel_grid); | ||||
|     Box::into_raw(Box::new(CCommand(Command::BitmapLinearWin( | ||||
|     pixel_grid: *mut SPPixelGrid, | ||||
|     compression_code: SPCompressionCode, | ||||
| ) -> *mut SPCommand { | ||||
|     let byte_grid = (*Box::from_raw(pixel_grid)).0; | ||||
|     Box::into_raw(Box::new(SPCommand(servicepoint::Command::BitmapLinearWin( | ||||
|         Origin::new(x, y), | ||||
|         byte_grid, | ||||
|         compression_code, | ||||
|         compression_code | ||||
|             .try_into() | ||||
|             .expect("invalid compression code"), | ||||
|     )))) | ||||
| } | ||||
| 
 | ||||
|  | @ -316,6 +329,6 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_win( | |||
| /// - `this` is not used concurrently or after this call
 | ||||
| /// - `this` was not passed to another consuming function, e.g. to create a `Packet`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_command_dealloc(ptr: *mut CCommand) { | ||||
| pub unsafe extern "C" fn sp_command_dealloc(ptr: *mut SPCommand) { | ||||
|     _ = Box::from_raw(ptr); | ||||
| } | ||||
|  |  | |||
|  | @ -5,7 +5,18 @@ | |||
| use std::ffi::{c_char, CStr}; | ||||
| use std::ptr::null_mut; | ||||
| 
 | ||||
| use servicepoint::{Connection, Packet}; | ||||
| use crate::packet::SPPacket; | ||||
| 
 | ||||
| /// A connection to the display.
 | ||||
| ///
 | ||||
| /// # Examples
 | ||||
| ///
 | ||||
| /// ```C
 | ||||
| /// CConnection connection = sp_connection_open("172.23.42.29:2342");
 | ||||
| /// if (connection != NULL)
 | ||||
| ///     sp_connection_send(connection, sp_command_clear());
 | ||||
| /// ```
 | ||||
| pub struct SPConnection(pub(crate) servicepoint::Connection); | ||||
| 
 | ||||
| /// Creates a new instance of `Connection`.
 | ||||
| ///
 | ||||
|  | @ -24,14 +35,14 @@ use servicepoint::{Connection, Packet}; | |||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_connection_open( | ||||
|     host: *const c_char, | ||||
| ) -> *mut Connection { | ||||
| ) -> *mut SPConnection { | ||||
|     let host = CStr::from_ptr(host).to_str().expect("Bad encoding"); | ||||
|     let connection = match Connection::open(host) { | ||||
|     let connection = match servicepoint::Connection::open(host) { | ||||
|         Err(_) => return null_mut(), | ||||
|         Ok(value) => value, | ||||
|     }; | ||||
| 
 | ||||
|     Box::into_raw(Box::new(connection)) | ||||
|     Box::into_raw(Box::new(SPConnection(connection))) | ||||
| } | ||||
| 
 | ||||
| /// Sends a `Packet` to the display using the `Connection`.
 | ||||
|  | @ -48,11 +59,11 @@ pub unsafe extern "C" fn sp_connection_open( | |||
| /// - `packet` is not used concurrently or after this call
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_connection_send( | ||||
|     connection: *const Connection, | ||||
|     packet: *mut Packet, | ||||
|     connection: *const SPConnection, | ||||
|     packet: *mut SPPacket, | ||||
| ) -> bool { | ||||
|     let packet = Box::from_raw(packet); | ||||
|     (*connection).send(*packet).is_ok() | ||||
|     (*connection).0.send((*packet).0).is_ok() | ||||
| } | ||||
| 
 | ||||
| /// Closes and deallocates a `Connection`.
 | ||||
|  | @ -64,6 +75,6 @@ pub unsafe extern "C" fn sp_connection_send( | |||
| /// - `this` points to a valid `Connection`
 | ||||
| /// - `this` is not used concurrently or after this call
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_connection_dealloc(ptr: *mut Connection) { | ||||
| pub unsafe extern "C" fn sp_connection_dealloc(ptr: *mut SPConnection) { | ||||
|     _ = Box::from_raw(ptr); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										48
									
								
								crates/servicepoint_binding_c/src/constants.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								crates/servicepoint_binding_c/src/constants.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,48 @@ | |||
| //! re-exported constants for use in C
 | ||||
| 
 | ||||
| use servicepoint::CompressionCode; | ||||
| use std::time::Duration; | ||||
| 
 | ||||
| /// size of a single tile in one dimension
 | ||||
| pub const SP_TILE_SIZE: usize = 8; | ||||
| 
 | ||||
| /// Display tile count in the x-direction
 | ||||
| pub const SP_TILE_WIDTH: usize = 56; | ||||
| 
 | ||||
| /// Display tile count in the y-direction
 | ||||
| pub const SP_TILE_HEIGHT: usize = 20; | ||||
| 
 | ||||
| /// Display width in pixels
 | ||||
| pub const SP_PIXEL_WIDTH: usize = SP_TILE_WIDTH * SP_TILE_SIZE; | ||||
| 
 | ||||
| /// Display height in pixels
 | ||||
| pub const SP_PIXEL_HEIGHT: usize = SP_TILE_HEIGHT * SP_TILE_SIZE; | ||||
| 
 | ||||
| /// pixel count on whole screen
 | ||||
| pub const SP_PIXEL_COUNT: usize = SP_PIXEL_WIDTH * SP_PIXEL_HEIGHT; | ||||
| 
 | ||||
| /// Actual hardware limit is around 28-29ms/frame. Rounded up for less dropped packets.
 | ||||
| pub const SP_FRAME_PACING_MS: u128 = Duration::from_millis(30).as_millis(); | ||||
| 
 | ||||
| /// Specifies the kind of compression to use.
 | ||||
| #[repr(u16)] | ||||
| pub enum SPCompressionCode { | ||||
|     /// no compression
 | ||||
|     Uncompressed = 0x0, | ||||
|     /// compress using flate2 with zlib header
 | ||||
|     Zlib = 0x677a, | ||||
|     /// compress using bzip2
 | ||||
|     Bzip2 = 0x627a, | ||||
|     /// compress using lzma
 | ||||
|     Lzma = 0x6c7a, | ||||
|     /// compress using Zstandard
 | ||||
|     Zstd = 0x7a73, | ||||
| } | ||||
| 
 | ||||
| impl TryFrom<SPCompressionCode> for CompressionCode { | ||||
|     type Error = (); | ||||
| 
 | ||||
|     fn try_from(value: SPCompressionCode) -> Result<Self, Self::Error> { | ||||
|         CompressionCode::try_from(value as u16) | ||||
|     } | ||||
| } | ||||
|  | @ -2,19 +2,28 @@ | |||
| //!
 | ||||
| //! prefix `sp_cp437_grid_`
 | ||||
| 
 | ||||
| use crate::c_slice::CByteSlice; | ||||
| use crate::c_slice::SPByteSlice; | ||||
| use servicepoint::{Cp437Grid, DataRef, Grid}; | ||||
| 
 | ||||
| /// A C-wrapper for grid containing codepage 437 characters.
 | ||||
| ///
 | ||||
| /// The encoding is currently not enforced.
 | ||||
| pub struct CCp437Grid { | ||||
| ///
 | ||||
| /// # Examples
 | ||||
| ///
 | ||||
| /// ```C
 | ||||
| /// Cp437Grid grid = sp_cp437_grid_new(4, 3);
 | ||||
| /// sp_cp437_grid_fill(grid, '?');
 | ||||
| /// sp_cp437_grid_set(grid, 0, 0, '!');
 | ||||
| /// sp_cp437_grid_dealloc(grid);
 | ||||
| /// ```
 | ||||
| pub struct SPCp437Grid { | ||||
|     pub(crate) actual: Cp437Grid, | ||||
| } | ||||
| 
 | ||||
| impl Clone for CCp437Grid { | ||||
| impl Clone for SPCp437Grid { | ||||
|     fn clone(&self) -> Self { | ||||
|         CCp437Grid { | ||||
|         SPCp437Grid { | ||||
|             actual: self.actual.clone(), | ||||
|         } | ||||
|     } | ||||
|  | @ -34,8 +43,8 @@ impl Clone for CCp437Grid { | |||
| pub unsafe extern "C" fn sp_cp437_grid_new( | ||||
|     width: usize, | ||||
|     height: usize, | ||||
| ) -> *mut CCp437Grid { | ||||
|     Box::into_raw(Box::new(CCp437Grid { | ||||
| ) -> *mut SPCp437Grid { | ||||
|     Box::into_raw(Box::new(SPCp437Grid { | ||||
|         actual: Cp437Grid::new(width, height), | ||||
|     })) | ||||
| } | ||||
|  | @ -60,9 +69,9 @@ pub unsafe extern "C" fn sp_cp437_grid_load( | |||
|     height: usize, | ||||
|     data: *const u8, | ||||
|     data_length: usize, | ||||
| ) -> *mut CCp437Grid { | ||||
| ) -> *mut SPCp437Grid { | ||||
|     let data = std::slice::from_raw_parts(data, data_length); | ||||
|     Box::into_raw(Box::new(CCp437Grid { | ||||
|     Box::into_raw(Box::new(SPCp437Grid { | ||||
|         actual: Cp437Grid::load(width, height, data), | ||||
|     })) | ||||
| } | ||||
|  | @ -79,8 +88,8 @@ pub unsafe extern "C" fn sp_cp437_grid_load( | |||
| ///   by explicitly calling `sp_cp437_grid_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_cp437_grid_clone( | ||||
|     this: *const CCp437Grid, | ||||
| ) -> *mut CCp437Grid { | ||||
|     this: *const SPCp437Grid, | ||||
| ) -> *mut SPCp437Grid { | ||||
|     Box::into_raw(Box::new((*this).clone())) | ||||
| } | ||||
| 
 | ||||
|  | @ -94,7 +103,7 @@ pub unsafe extern "C" fn sp_cp437_grid_clone( | |||
| /// - `this` is not used concurrently or after this call
 | ||||
| /// - `this` was not passed to another consuming function, e.g. to create a `Command`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_cp437_grid_dealloc(this: *mut CCp437Grid) { | ||||
| pub unsafe extern "C" fn sp_cp437_grid_dealloc(this: *mut SPCp437Grid) { | ||||
|     _ = Box::from_raw(this); | ||||
| } | ||||
| 
 | ||||
|  | @ -117,7 +126,7 @@ pub unsafe extern "C" fn sp_cp437_grid_dealloc(this: *mut CCp437Grid) { | |||
| /// - `this` is not written to concurrently
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_cp437_grid_get( | ||||
|     this: *const CCp437Grid, | ||||
|     this: *const SPCp437Grid, | ||||
|     x: usize, | ||||
|     y: usize, | ||||
| ) -> u8 { | ||||
|  | @ -146,7 +155,7 @@ pub unsafe extern "C" fn sp_cp437_grid_get( | |||
| /// - `this` is not written to or read from concurrently
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_cp437_grid_set( | ||||
|     this: *mut CCp437Grid, | ||||
|     this: *mut SPCp437Grid, | ||||
|     x: usize, | ||||
|     y: usize, | ||||
|     value: u8, | ||||
|  | @ -168,7 +177,7 @@ pub unsafe extern "C" fn sp_cp437_grid_set( | |||
| /// - `this` points to a valid `Cp437Grid`
 | ||||
| /// - `this` is not written to or read from concurrently
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_cp437_grid_fill(this: *mut CCp437Grid, value: u8) { | ||||
| pub unsafe extern "C" fn sp_cp437_grid_fill(this: *mut SPCp437Grid, value: u8) { | ||||
|     (*this).actual.fill(value); | ||||
| } | ||||
| 
 | ||||
|  | @ -184,7 +193,9 @@ pub unsafe extern "C" fn sp_cp437_grid_fill(this: *mut CCp437Grid, value: u8) { | |||
| ///
 | ||||
| /// - `this` points to a valid `Cp437Grid`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_cp437_grid_width(this: *const CCp437Grid) -> usize { | ||||
| pub unsafe extern "C" fn sp_cp437_grid_width( | ||||
|     this: *const SPCp437Grid, | ||||
| ) -> usize { | ||||
|     (*this).actual.width() | ||||
| } | ||||
| 
 | ||||
|  | @ -201,7 +212,7 @@ pub unsafe extern "C" fn sp_cp437_grid_width(this: *const CCp437Grid) -> usize { | |||
| /// - `this` points to a valid `Cp437Grid`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_cp437_grid_height( | ||||
|     this: *const CCp437Grid, | ||||
|     this: *const SPCp437Grid, | ||||
| ) -> usize { | ||||
|     (*this).actual.height() | ||||
| } | ||||
|  | @ -217,10 +228,10 @@ pub unsafe extern "C" fn sp_cp437_grid_height( | |||
| /// - the returned memory range is never accessed concurrently, either via the `Cp437Grid` or directly
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_cp437_grid_unsafe_data_ref( | ||||
|     this: *mut CCp437Grid, | ||||
| ) -> CByteSlice { | ||||
|     this: *mut SPCp437Grid, | ||||
| ) -> SPByteSlice { | ||||
|     let data = (*this).actual.data_ref_mut(); | ||||
|     CByteSlice { | ||||
|     SPByteSlice { | ||||
|         start: data.as_mut_ptr_range().start, | ||||
|         length: data.len(), | ||||
|     } | ||||
|  |  | |||
|  | @ -1,11 +1,6 @@ | |||
| //! C API wrapper for the `servicepoint` crate.
 | ||||
| 
 | ||||
| pub use servicepoint::{ | ||||
|     CompressionCode, PIXEL_COUNT, PIXEL_HEIGHT, PIXEL_WIDTH, TILE_HEIGHT, | ||||
|     TILE_SIZE, TILE_WIDTH, | ||||
| }; | ||||
| 
 | ||||
| pub use crate::c_slice::CByteSlice; | ||||
| pub use crate::c_slice::SPByteSlice; | ||||
| 
 | ||||
| pub mod bit_vec; | ||||
| 
 | ||||
|  | @ -23,5 +18,7 @@ pub mod c_slice; | |||
| 
 | ||||
| pub mod cp437_grid; | ||||
| 
 | ||||
| /// The minimum time needed for the display to refresh the screen in ms.
 | ||||
| pub const FRAME_PACING_MS: u32 = servicepoint::FRAME_PACING.as_millis() as u32; | ||||
| pub mod constants; | ||||
| 
 | ||||
| /// Type alias for documenting the meaning of the variable in enum values
 | ||||
| pub type SPOffset = usize; | ||||
|  |  | |||
|  | @ -4,8 +4,10 @@ | |||
| 
 | ||||
| use std::ptr::null_mut; | ||||
| 
 | ||||
| use crate::command::CCommand; | ||||
| use servicepoint::Packet; | ||||
| use crate::command::SPCommand; | ||||
| 
 | ||||
| /// The raw packet
 | ||||
| pub struct SPPacket(pub(crate) servicepoint::Packet); | ||||
| 
 | ||||
| /// Turns a `Command` into a `Packet`.
 | ||||
| /// The `Command` gets consumed.
 | ||||
|  | @ -20,10 +22,10 @@ use servicepoint::Packet; | |||
| ///   by explicitly calling `sp_packet_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_packet_from_command( | ||||
|     command: *mut CCommand, | ||||
| ) -> *mut Packet { | ||||
|     command: *mut SPCommand, | ||||
| ) -> *mut SPPacket { | ||||
|     let command = *Box::from_raw(command); | ||||
|     let packet = command.0.into(); | ||||
|     let packet = SPPacket(command.0.into()); | ||||
|     Box::into_raw(Box::new(packet)) | ||||
| } | ||||
| 
 | ||||
|  | @ -43,11 +45,11 @@ pub unsafe extern "C" fn sp_packet_from_command( | |||
| pub unsafe extern "C" fn sp_packet_try_load( | ||||
|     data: *const u8, | ||||
|     length: usize, | ||||
| ) -> *mut Packet { | ||||
| ) -> *mut SPPacket { | ||||
|     let data = std::slice::from_raw_parts(data, length); | ||||
|     match Packet::try_from(data) { | ||||
|     match servicepoint::Packet::try_from(data) { | ||||
|         Err(_) => null_mut(), | ||||
|         Ok(packet) => Box::into_raw(Box::new(packet)), | ||||
|         Ok(packet) => Box::into_raw(Box::new(SPPacket(packet))), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -62,8 +64,10 @@ pub unsafe extern "C" fn sp_packet_try_load( | |||
| /// - the returned instance is freed in some way, either by using a consuming function or
 | ||||
| ///   by explicitly calling `sp_packet_dealloc`.
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_packet_clone(this: *const Packet) -> *mut Packet { | ||||
|     Box::into_raw(Box::new((*this).clone())) | ||||
| pub unsafe extern "C" fn sp_packet_clone( | ||||
|     this: *const SPPacket, | ||||
| ) -> *mut SPPacket { | ||||
|     Box::into_raw(Box::new(SPPacket((*this).0.clone()))) | ||||
| } | ||||
| 
 | ||||
| /// Deallocates a `Packet`.
 | ||||
|  | @ -75,6 +79,6 @@ pub unsafe extern "C" fn sp_packet_clone(this: *const Packet) -> *mut Packet { | |||
| /// - `this` points to a valid `Packet`
 | ||||
| /// - `this` is not used concurrently or after this call
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_packet_dealloc(this: *mut Packet) { | ||||
| pub unsafe extern "C" fn sp_packet_dealloc(this: *mut SPPacket) { | ||||
|     _ = Box::from_raw(this) | ||||
| } | ||||
|  |  | |||
|  | @ -2,9 +2,21 @@ | |||
| //!
 | ||||
| //! prefix `sp_pixel_grid_`
 | ||||
| 
 | ||||
| use servicepoint::{DataRef, Grid, PixelGrid}; | ||||
| use servicepoint::{DataRef, Grid}; | ||||
| 
 | ||||
| use crate::c_slice::CByteSlice; | ||||
| use crate::c_slice::SPByteSlice; | ||||
| 
 | ||||
| /// A grid of pixels.
 | ||||
| ///
 | ||||
| /// # Examples
 | ||||
| ///
 | ||||
| /// ```C
 | ||||
| /// Cp437Grid grid = sp_pixel_grid_new(8, 3);
 | ||||
| /// sp_pixel_grid_fill(grid, true);
 | ||||
| /// sp_pixel_grid_set(grid, 0, 0, false);
 | ||||
| /// sp_pixel_grid_dealloc(grid);
 | ||||
| /// ```
 | ||||
| pub struct SPPixelGrid(pub(crate) servicepoint::PixelGrid); | ||||
| 
 | ||||
| /// Creates a new `PixelGrid` with the specified dimensions.
 | ||||
| ///
 | ||||
|  | @ -29,8 +41,10 @@ use crate::c_slice::CByteSlice; | |||
| pub unsafe extern "C" fn sp_pixel_grid_new( | ||||
|     width: usize, | ||||
|     height: usize, | ||||
| ) -> *mut PixelGrid { | ||||
|     Box::into_raw(Box::new(PixelGrid::new(width, height))) | ||||
| ) -> *mut SPPixelGrid { | ||||
|     Box::into_raw(Box::new(SPPixelGrid(servicepoint::PixelGrid::new( | ||||
|         width, height, | ||||
|     )))) | ||||
| } | ||||
| 
 | ||||
| /// Loads a `PixelGrid` with the specified dimensions from the provided data.
 | ||||
|  | @ -60,9 +74,11 @@ pub unsafe extern "C" fn sp_pixel_grid_load( | |||
|     height: usize, | ||||
|     data: *const u8, | ||||
|     data_length: usize, | ||||
| ) -> *mut PixelGrid { | ||||
| ) -> *mut SPPixelGrid { | ||||
|     let data = std::slice::from_raw_parts(data, data_length); | ||||
|     Box::into_raw(Box::new(PixelGrid::load(width, height, data))) | ||||
|     Box::into_raw(Box::new(SPPixelGrid(servicepoint::PixelGrid::load( | ||||
|         width, height, data, | ||||
|     )))) | ||||
| } | ||||
| 
 | ||||
| /// Clones a `PixelGrid`.
 | ||||
|  | @ -77,9 +93,9 @@ pub unsafe extern "C" fn sp_pixel_grid_load( | |||
| ///   by explicitly calling `sp_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())) | ||||
|     this: *const SPPixelGrid, | ||||
| ) -> *mut SPPixelGrid { | ||||
|     Box::into_raw(Box::new(SPPixelGrid((*this).0.clone()))) | ||||
| } | ||||
| 
 | ||||
| /// Deallocates a `PixelGrid`.
 | ||||
|  | @ -92,7 +108,7 @@ pub unsafe extern "C" fn sp_pixel_grid_clone( | |||
| /// - `this` is not used concurrently or after this call
 | ||||
| /// - `this` was not passed to another consuming function, e.g. to create a `Command`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_dealloc(this: *mut PixelGrid) { | ||||
| pub unsafe extern "C" fn sp_pixel_grid_dealloc(this: *mut SPPixelGrid) { | ||||
|     _ = Box::from_raw(this); | ||||
| } | ||||
| 
 | ||||
|  | @ -115,11 +131,11 @@ pub unsafe extern "C" fn sp_pixel_grid_dealloc(this: *mut PixelGrid) { | |||
| /// - `this` is not written to concurrently
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_get( | ||||
|     this: *const PixelGrid, | ||||
|     this: *const SPPixelGrid, | ||||
|     x: usize, | ||||
|     y: usize, | ||||
| ) -> bool { | ||||
|     (*this).get(x, y) | ||||
|     (*this).0.get(x, y) | ||||
| } | ||||
| 
 | ||||
| /// Sets the value of the specified position in the `PixelGrid`.
 | ||||
|  | @ -144,12 +160,12 @@ pub unsafe extern "C" fn sp_pixel_grid_get( | |||
| /// - `this` is not written to or read from concurrently
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_set( | ||||
|     this: *mut PixelGrid, | ||||
|     this: *mut SPPixelGrid, | ||||
|     x: usize, | ||||
|     y: usize, | ||||
|     value: bool, | ||||
| ) { | ||||
|     (*this).set(x, y, value); | ||||
|     (*this).0.set(x, y, value); | ||||
| } | ||||
| 
 | ||||
| /// Sets the state of all pixels in the `PixelGrid`.
 | ||||
|  | @ -166,8 +182,11 @@ pub unsafe extern "C" fn sp_pixel_grid_set( | |||
| /// - `this` points to a valid `PixelGrid`
 | ||||
| /// - `this` is not written to or read from concurrently
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_fill(this: *mut PixelGrid, value: bool) { | ||||
|     (*this).fill(value); | ||||
| pub unsafe extern "C" fn sp_pixel_grid_fill( | ||||
|     this: *mut SPPixelGrid, | ||||
|     value: bool, | ||||
| ) { | ||||
|     (*this).0.fill(value); | ||||
| } | ||||
| 
 | ||||
| /// Gets the width in pixels of the `PixelGrid` instance.
 | ||||
|  | @ -182,8 +201,10 @@ pub unsafe extern "C" fn sp_pixel_grid_fill(this: *mut PixelGrid, value: bool) { | |||
| ///
 | ||||
| /// - `this` points to a valid `PixelGrid`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_width(this: *const PixelGrid) -> usize { | ||||
|     (*this).width() | ||||
| pub unsafe extern "C" fn sp_pixel_grid_width( | ||||
|     this: *const SPPixelGrid, | ||||
| ) -> usize { | ||||
|     (*this).0.width() | ||||
| } | ||||
| 
 | ||||
| /// Gets the height in pixels of the `PixelGrid` instance.
 | ||||
|  | @ -198,8 +219,10 @@ pub unsafe extern "C" fn sp_pixel_grid_width(this: *const PixelGrid) -> usize { | |||
| ///
 | ||||
| /// - `this` points to a valid `PixelGrid`
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_height(this: *const PixelGrid) -> usize { | ||||
|     (*this).height() | ||||
| pub unsafe extern "C" fn sp_pixel_grid_height( | ||||
|     this: *const SPPixelGrid, | ||||
| ) -> usize { | ||||
|     (*this).0.height() | ||||
| } | ||||
| 
 | ||||
| /// Gets an unsafe reference to the data of the `PixelGrid` instance.
 | ||||
|  | @ -213,10 +236,10 @@ pub unsafe extern "C" fn sp_pixel_grid_height(this: *const PixelGrid) -> usize { | |||
| /// - the returned memory range is never accessed concurrently, either via the `PixelGrid` or directly
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern "C" fn sp_pixel_grid_unsafe_data_ref( | ||||
|     this: *mut PixelGrid, | ||||
| ) -> CByteSlice { | ||||
|     let data = (*this).data_ref_mut(); | ||||
|     CByteSlice { | ||||
|     this: *mut SPPixelGrid, | ||||
| ) -> SPByteSlice { | ||||
|     let data = (*this).0.data_ref_mut(); | ||||
|     SPByteSlice { | ||||
|         start: data.as_mut_ptr_range().start, | ||||
|         length: data.len(), | ||||
|     } | ||||
|  |  | |||
|  | @ -14,9 +14,9 @@ namespace ServicePoint.BindGen | |||
|     { | ||||
|         const string __DllName = "servicepoint_binding_c"; | ||||
| 
 | ||||
|         public const nuint TILE_SIZE = 8; | ||||
|         public const nuint TILE_WIDTH = 56; | ||||
|         public const nuint TILE_HEIGHT = 20; | ||||
|         public const nuint SP_TILE_SIZE = 8; | ||||
|         public const nuint SP_TILE_WIDTH = 56; | ||||
|         public const nuint SP_TILE_HEIGHT = 20; | ||||
| 
 | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -629,7 +629,7 @@ namespace ServicePoint.BindGen | |||
|         /// | ||||
|         ///  The caller has to make sure that: | ||||
|         /// | ||||
|         ///  - the returned `Command` instance is freed in some way, either by using a consuming function or | ||||
|         ///  - the returned `SPCommand` instance is freed in some way, either by using a consuming function or | ||||
|         ///    by explicitly calling `sp_command_dealloc`. | ||||
|         /// </summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp_command_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|  | @ -637,19 +637,19 @@ namespace ServicePoint.BindGen | |||
| 
 | ||||
|         /// <summary> | ||||
|         ///  Allocates a new `Command::CharBrightness` instance. | ||||
|         ///  The passed `ByteGrid` gets consumed. | ||||
|         ///  The passed `SPBrightnessGrid` gets consumed. | ||||
|         /// | ||||
|         ///  # Safety | ||||
|         /// | ||||
|         ///  The caller has to make sure that: | ||||
|         /// | ||||
|         ///  - `byte_grid` points to a valid instance of `ByteGrid` | ||||
|         ///  - `byte_grid` is not used concurrently or after this call | ||||
|         ///  - `grid` points to a valid instance of `SPBrightnessGrid` | ||||
|         ///  - `grid` is not used concurrently or after this call | ||||
|         ///  - the returned `Command` instance is freed in some way, either by using a consuming function or | ||||
|         ///    by explicitly calling `sp_command_dealloc`. | ||||
|         /// </summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp_command_char_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp_command_char_brightness(nuint x, nuint y, BrightnessGrid* byte_grid); | ||||
|         public static extern Command* sp_command_char_brightness(nuint x, nuint y, BrightnessGrid* grid); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         ///  Allocates a new `Command::BitmapLinear` instance. | ||||
|  | @ -1040,6 +1040,21 @@ namespace ServicePoint.BindGen | |||
|         [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> | ||||
|         ///  Clones a `Packet`. | ||||
|         /// | ||||
|         ///  # Safety | ||||
|         /// | ||||
|         ///  The caller has to make sure that: | ||||
|         /// | ||||
|         ///  - `this` points to a valid `Packet` | ||||
|         ///  - `this` is not written to concurrently | ||||
|         ///  - the returned instance is freed in some way, either by using a consuming function or | ||||
|         ///    by explicitly calling `sp_packet_dealloc`. | ||||
|         /// </summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp_packet_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Packet* sp_packet_clone(Packet* @this); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         ///  Deallocates a `Packet`. | ||||
|         /// | ||||
|  | @ -1076,13 +1091,6 @@ namespace ServicePoint.BindGen | |||
|     { | ||||
|     } | ||||
| 
 | ||||
|     [StructLayout(LayoutKind.Sequential)] | ||||
|     public unsafe partial struct ByteSlice | ||||
|     { | ||||
|         public byte* start; | ||||
|         public nuint length; | ||||
|     } | ||||
| 
 | ||||
|     [StructLayout(LayoutKind.Sequential)] | ||||
|     public unsafe partial struct Connection | ||||
|     { | ||||
|  | @ -1093,6 +1101,13 @@ namespace ServicePoint.BindGen | |||
|     { | ||||
|     } | ||||
| 
 | ||||
|     [StructLayout(LayoutKind.Sequential)] | ||||
|     public unsafe partial struct ByteSlice | ||||
|     { | ||||
|         public byte* start; | ||||
|         public nuint length; | ||||
|     } | ||||
| 
 | ||||
|     [StructLayout(LayoutKind.Sequential)] | ||||
|     public unsafe partial struct Packet | ||||
|     { | ||||
|  |  | |||
|  | @ -13,23 +13,18 @@ fn main() { | |||
|         .input_extern_file("../servicepoint_binding_c/src/lib.rs") | ||||
|         .input_extern_file("../servicepoint_binding_c/src/c_slice.rs") | ||||
|         .input_extern_file("../servicepoint_binding_c/src/packet.rs") | ||||
|         .input_extern_file("../servicepoint/src/command.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/packet.rs") | ||||
|         .input_extern_file("../servicepoint/src/compression_code.rs") | ||||
|         .input_extern_file("../servicepoint_binding_c/src/constants.rs") | ||||
|         .csharp_dll_name("servicepoint_binding_c") | ||||
|         .csharp_namespace("ServicePoint.BindGen") | ||||
|         .csharp_use_nint_types(true) | ||||
|         .csharp_class_accessibility("public") | ||||
|         .csharp_generate_const_filter(|_| true) | ||||
|         .csharp_type_rename(move |name| { | ||||
|             if name.len() > 1 | ||||
|                 && name.starts_with("C") | ||||
|                 && name.chars().nth(1).unwrap().is_uppercase() | ||||
|             if name.len() > 2 | ||||
|                 && name.starts_with("SP") | ||||
|                 && name.chars().nth(2).unwrap().is_uppercase() | ||||
|             { | ||||
|                 name[1..].to_string() | ||||
|                 name[2..].to_string() | ||||
|             } else { | ||||
|                 name | ||||
|             } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vinzenz Schroeter
						Vinzenz Schroeter