From 3589a90385b7bf33f165fe8fb663f2798bd523d7 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 12 Apr 2025 22:13:29 +0200 Subject: [PATCH] add functions to convert containers directly into packet --- example/announce.c | 6 ++-- example/brightness_tester.c | 11 ++++--- example/random_stuff.c | 9 +++--- include/servicepoint.h | 61 ++++++++++++++++++++++++++++++++++++- src/bitmap.rs | 25 ++++++++++++++- src/bitvec.rs | 28 +++++++++++++++-- src/brightness_grid.rs | 5 +++ src/char_grid.rs | 25 +++++++++++++-- src/cp437_grid.rs | 25 +++++++++++++-- src/packet.rs | 3 ++ 10 files changed, 178 insertions(+), 20 deletions(-) diff --git a/example/announce.c b/example/announce.c index 9220242..737eff5 100644 --- a/example/announce.c +++ b/example/announce.c @@ -23,8 +23,10 @@ int main(void) { sp_char_grid_set(grid, 3, 1, 'l'); sp_char_grid_set(grid, 4, 1, 'd'); - TypedCommand *command = sp_command_char_grid(0, 0, grid); - sp_udp_send_command(connection, command); + Packet *packet = sp_char_grid_into_packet(grid, 0, 0); + if (packet == NULL) + return 1; + sp_udp_send_packet(connection, packet); sp_udp_free(connection); return 0; diff --git a/example/brightness_tester.c b/example/brightness_tester.c index 93e64ce..d06d30d 100644 --- a/example/brightness_tester.c +++ b/example/brightness_tester.c @@ -8,11 +8,12 @@ int main(void) { Bitmap *all_on = sp_bitmap_new_max_sized(); sp_bitmap_fill(all_on, true); - TypedCommand *cmd = sp_command_bitmap(0, 0, all_on, COMPRESSION_CODE_UNCOMPRESSED); - if (cmd == NULL) + + Packet *packet = sp_bitmap_into_packet(all_on, 0, 0, COMPRESSION_CODE_UNCOMPRESSED); + if (packet == NULL) return -1; - sp_udp_send_command(connection, cmd); + sp_udp_send_packet(connection, packet); BrightnessGrid *grid = sp_brightness_grid_new(TILE_WIDTH, TILE_HEIGHT); @@ -21,8 +22,8 @@ int main(void) { slice.start[index] = (uint8_t) (index % ((size_t) Brightness_MAX)); } - TypedCommand *command = sp_command_brightness_grid(0, 0, grid); - sp_udp_send_command(connection, command); + packet = sp_brightness_grid_into_packet(grid, 0, 0); + sp_udp_send_packet(connection, packet); sp_udp_free(connection); return 0; diff --git a/example/random_stuff.c b/example/random_stuff.c index 80c3847..ca5a14d 100644 --- a/example/random_stuff.c +++ b/example/random_stuff.c @@ -1,3 +1,4 @@ +#include #include "servicepoint.h" int main(void) { @@ -11,14 +12,12 @@ int main(void) { sp_bitmap_fill(pixels, true); - TypedCommand *command = sp_command_bitmap(0, 0, pixels, COMPRESSION_CODE_UNCOMPRESSED); - if (command == NULL) + Packet *packet = sp_bitmap_into_packet(pixels, 0, 0, COMPRESSION_CODE_UNCOMPRESSED); + if (packet == NULL) return 1; - Packet *packet = sp_packet_from_command(command); - Header *header = sp_packet_get_header(packet); - //printf("[%d, %d, %d, %d, %d]\n", header->command_code, header->a, header->b, header->c, header->d); + printf("[%d, %d, %d, %d, %d]\n", header->command_code, header->a, header->b, header->c, header->d); sp_udp_send_packet(connection, packet); diff --git a/include/servicepoint.h b/include/servicepoint.h index 1ece5e6..77d2e36 100644 --- a/include/servicepoint.h +++ b/include/servicepoint.h @@ -455,6 +455,18 @@ size_t sp_bitmap_height(Bitmap */*notnull*/ bitmap); */ SPBitVec */*notnull*/ sp_bitmap_into_bitvec(Bitmap */*notnull*/ bitmap); +/** + * Creates a [BitmapCommand] and immediately turns that into a [Packet]. + * + * The provided [Bitmap] gets consumed. + * + * Returns NULL in case of an error. + */ +Packet *sp_bitmap_into_packet(Bitmap */*notnull*/ bitmap, + size_t x, + size_t y, + CompressionCode compression); + /** * Loads a [Bitmap] with the specified dimensions from the provided data. * @@ -580,6 +592,18 @@ void sp_bitvec_free(SPBitVec */*notnull*/ bit_vec); */ bool sp_bitvec_get(SPBitVec */*notnull*/ bit_vec, size_t index); +/** + * Creates a [BitVecCommand] and immediately turns that into a [Packet]. + * + * The provided [SPBitVec] gets consumed. + * + * Returns NULL in case of an error. + */ +Packet *sp_bitvec_into_packet(SPBitVec */*notnull*/ bitvec, + size_t offset, + BinaryOperation operation, + CompressionCode compression); + /** * Returns true if length is 0. * @@ -695,6 +719,13 @@ Brightness sp_brightness_grid_get(BrightnessGrid */*notnull*/ brightness_grid, */ size_t sp_brightness_grid_height(BrightnessGrid */*notnull*/ brightness_grid); +/** + * Creates a [BrightnessGridCommand] and immediately turns that into a [Packet]. + * + * The provided [BrightnessGrid] gets consumed. + * + * Returns NULL in case of an error. + */ Packet *sp_brightness_grid_into_packet(BrightnessGrid */*notnull*/ grid, size_t x, size_t y); @@ -818,6 +849,17 @@ uint32_t sp_char_grid_get(CharGrid */*notnull*/ char_grid, size_t x, size_t y); */ size_t sp_char_grid_height(CharGrid */*notnull*/ char_grid); +/** + * Creates a [CharGridCommand] and immediately turns that into a [Packet]. + * + * The provided [CharGrid] gets consumed. + * + * Returns NULL in case of an error. + */ +Packet *sp_char_grid_into_packet(CharGrid */*notnull*/ grid, + size_t x, + size_t y); + /** * Loads a [CharGrid] with the specified dimensions from the provided data. * @@ -1045,6 +1087,17 @@ uint8_t sp_cp437_grid_get(Cp437Grid */*notnull*/ cp437_grid, */ size_t sp_cp437_grid_height(Cp437Grid */*notnull*/ cp437_grid); +/** + * Creates a [Cp437GridCommand] and immediately turns that into a [Packet]. + * + * The provided [Cp437Grid] gets consumed. + * + * Returns NULL in case of an error. + */ +Packet *sp_cp437_grid_into_packet(Cp437Grid */*notnull*/ grid, + size_t x, + size_t y); + /** * Loads a [Cp437Grid] with the specified dimensions from the provided data. */ @@ -1156,7 +1209,13 @@ void sp_packet_set_payload(Packet */*notnull*/ packet, ByteSlice data); */ Packet *sp_packet_try_load(ByteSlice data); -bool sp_u16_to_command_code(uint16_t code, CommandCode *result); +/** + * Converts u16 into [CommandCode]. + * + * If the provided value is not valid, false is returned and result is not changed. + */ +bool sp_u16_to_command_code(uint16_t code, + CommandCode *result); /** * Closes and deallocates a [UdpConnection]. diff --git a/src/bitmap.rs b/src/bitmap.rs index 71753a5..358be48 100644 --- a/src/bitmap.rs +++ b/src/bitmap.rs @@ -1,6 +1,6 @@ use crate::byte_slice::ByteSlice; use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, SPBitVec}; -use servicepoint::{Bitmap, DataRef, Grid}; +use servicepoint::{Bitmap, BitmapCommand, CompressionCode, DataRef, Grid, Origin, Packet}; use std::ptr::NonNull; /// Creates a new [Bitmap] with the specified dimensions. @@ -199,3 +199,26 @@ pub unsafe extern "C" fn sp_bitmap_into_bitvec( let bitmap = unsafe { heap_remove(bitmap) }; heap_move_nonnull(SPBitVec(bitmap.into())) } + +/// Creates a [BitmapCommand] and immediately turns that into a [Packet]. +/// +/// The provided [Bitmap] gets consumed. +/// +/// Returns NULL in case of an error. +#[no_mangle] +pub unsafe extern "C" fn sp_bitmap_into_packet( + bitmap: NonNull, + x: usize, + y: usize, + compression: CompressionCode +) -> *mut Packet { + let bitmap = unsafe { heap_remove(bitmap) }; + match Packet::try_from(BitmapCommand { + bitmap, + origin: Origin::new(x, y), + compression, + }) { + Ok(packet) => heap_move(packet), + Err(_) => std::ptr::null_mut(), + } +} diff --git a/src/bitvec.rs b/src/bitvec.rs index e5ce720..22f7545 100644 --- a/src/bitvec.rs +++ b/src/bitvec.rs @@ -1,5 +1,5 @@ -use crate::{heap_drop, heap_move_nonnull, ByteSlice}; -use servicepoint::BitVecU8Msb0; +use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice}; +use servicepoint::{BinaryOperation, BitVecCommand, BitVecU8Msb0, CompressionCode, Packet}; use std::ptr::NonNull; /// A vector of bits @@ -146,3 +146,27 @@ pub unsafe extern "C" fn sp_bitvec_unsafe_data_ref( ) -> ByteSlice { unsafe { ByteSlice::from_slice((*bit_vec.as_ptr()).0.as_raw_mut_slice()) } } + +/// Creates a [BitVecCommand] and immediately turns that into a [Packet]. +/// +/// The provided [SPBitVec] gets consumed. +/// +/// Returns NULL in case of an error. +#[no_mangle] +pub unsafe extern "C" fn sp_bitvec_into_packet( + bitvec: NonNull, + offset: usize, + operation: BinaryOperation, + compression: CompressionCode +) -> *mut Packet { + let bitvec = unsafe { heap_remove(bitvec) }.0; + match Packet::try_from(BitVecCommand { + bitvec, + offset, + operation, + compression, + }) { + Ok(packet) => heap_move(packet), + Err(_) => std::ptr::null_mut(), + } +} diff --git a/src/brightness_grid.rs b/src/brightness_grid.rs index f85602a..1099be0 100644 --- a/src/brightness_grid.rs +++ b/src/brightness_grid.rs @@ -175,6 +175,11 @@ pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref( } } +/// Creates a [BrightnessGridCommand] and immediately turns that into a [Packet]. +/// +/// The provided [BrightnessGrid] gets consumed. +/// +/// Returns NULL in case of an error. #[no_mangle] pub unsafe extern "C" fn sp_brightness_grid_into_packet( grid: NonNull, diff --git a/src/char_grid.rs b/src/char_grid.rs index cdcc4b5..bfb2585 100644 --- a/src/char_grid.rs +++ b/src/char_grid.rs @@ -1,5 +1,5 @@ -use crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice}; -use servicepoint::{CharGrid, Grid}; +use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice}; +use servicepoint::{CharGrid, CharGridCommand, Grid, Origin, Packet}; use std::ptr::NonNull; /// Creates a new [CharGrid] with the specified dimensions. @@ -132,3 +132,24 @@ pub unsafe extern "C" fn sp_char_grid_height( ) -> usize { unsafe { char_grid.as_ref().height() } } + +/// Creates a [CharGridCommand] and immediately turns that into a [Packet]. +/// +/// The provided [CharGrid] gets consumed. +/// +/// Returns NULL in case of an error. +#[no_mangle] +pub unsafe extern "C" fn sp_char_grid_into_packet( + grid: NonNull, + x: usize, + y: usize, +) -> *mut Packet { + let grid = unsafe { heap_remove(grid) }; + match Packet::try_from(CharGridCommand { + grid, + origin: Origin::new(x, y), + }) { + Ok(packet) => heap_move(packet), + Err(_) => std::ptr::null_mut(), + } +} diff --git a/src/cp437_grid.rs b/src/cp437_grid.rs index e22a0ed..01aeb1e 100644 --- a/src/cp437_grid.rs +++ b/src/cp437_grid.rs @@ -1,5 +1,5 @@ -use crate::{heap_drop, heap_move, heap_move_nonnull, ByteSlice}; -use servicepoint::{Cp437Grid, DataRef, Grid}; +use crate::{heap_drop, heap_move, heap_move_nonnull, heap_remove, ByteSlice}; +use servicepoint::{Cp437Grid, Cp437GridCommand, DataRef, Grid, Origin, Packet}; use std::ptr::NonNull; /// Creates a new [Cp437Grid] with the specified dimensions. @@ -132,3 +132,24 @@ pub unsafe extern "C" fn sp_cp437_grid_unsafe_data_ref( ) -> ByteSlice { unsafe { ByteSlice::from_slice((*cp437_grid.as_ptr()).data_ref_mut()) } } + +/// Creates a [Cp437GridCommand] and immediately turns that into a [Packet]. +/// +/// The provided [Cp437Grid] gets consumed. +/// +/// Returns NULL in case of an error. +#[no_mangle] +pub unsafe extern "C" fn sp_cp437_grid_into_packet( + grid: NonNull, + x: usize, + y: usize, +) -> *mut Packet { + let grid = unsafe { heap_remove(grid) }; + match Packet::try_from(Cp437GridCommand { + grid, + origin: Origin::new(x, y), + }) { + Ok(packet) => heap_move(packet), + Err(_) => std::ptr::null_mut(), + } +} diff --git a/src/packet.rs b/src/packet.rs index a891ee3..d8b1579 100644 --- a/src/packet.rs +++ b/src/packet.rs @@ -108,6 +108,9 @@ pub unsafe extern "C" fn sp_packet_free(packet: NonNull) { unsafe { heap_drop(packet) } } +/// Converts u16 into [CommandCode]. +/// +/// If the provided value is not valid, false is returned and result is not changed. #[no_mangle] pub unsafe extern "C" fn sp_u16_to_command_code( code: u16,