diff --git a/example/Makefile b/example/Makefile index 0a56e1a..15e53d1 100644 --- a/example/Makefile +++ b/example/Makefile @@ -96,7 +96,7 @@ endif # ADD NEW EXAMPLES HERE _c_src := src/announce.c src/brightness_tester.c src/header_logger.c \ - src/moving_line.c src/random_stuff.c src/wiping_clear.c + src/moving_line.c src/random_stuff.c src/wiping_clear.c src/undefined.c _programs := $(basename $(notdir $(_c_src))) _bins := $(_programs) _unstripped_bins := $(addsuffix _unstripped, $(_bins)) diff --git a/example/src/announce.c b/example/src/announce.c index bfdc48f..a0bdf9a 100644 --- a/example/src/announce.c +++ b/example/src/announce.c @@ -3,27 +3,27 @@ int main(void) { sock_init(); - sp_udp_send_header(sock, (Header) {.command_code = COMMAND_CODE_CLEAR}); + sp_udpsocket_send_header(sock, (Header) {.command_code = COMMAND_CODE_CLEAR}); - CharGrid *grid = sp_char_grid_new(5, 2); + CharGrid *grid = sp_chargrid_new(5, 2); if (grid == NULL) return 1; - sp_char_grid_set(grid, 0, 0, 'H'); - sp_char_grid_set(grid, 1, 0, 'e'); - sp_char_grid_set(grid, 2, 0, 'l'); - sp_char_grid_set(grid, 3, 0, 'l'); - sp_char_grid_set(grid, 4, 0, 'o'); - sp_char_grid_set(grid, 0, 1, 'W'); - sp_char_grid_set(grid, 1, 1, 'o'); - sp_char_grid_set(grid, 2, 1, 'r'); - sp_char_grid_set(grid, 3, 1, 'l'); - sp_char_grid_set(grid, 4, 1, 'd'); + sp_chargrid_set(grid, 0, 0, 'H'); + sp_chargrid_set(grid, 1, 0, 'e'); + sp_chargrid_set(grid, 2, 0, 'l'); + sp_chargrid_set(grid, 3, 0, 'l'); + sp_chargrid_set(grid, 4, 0, 'o'); + sp_chargrid_set(grid, 0, 1, 'W'); + sp_chargrid_set(grid, 1, 1, 'o'); + sp_chargrid_set(grid, 2, 1, 'r'); + sp_chargrid_set(grid, 3, 1, 'l'); + sp_chargrid_set(grid, 4, 1, 'd'); - Packet *packet = sp_char_grid_into_packet(grid, 0, 0); + Packet *packet = sp_chargrid_try_into_packet(grid, 0, 0); if (packet == NULL) return 1; - sp_udp_send_packet(sock, packet); + sp_udpsocket_send_packet(sock, packet); return 0; } diff --git a/example/src/brightness_tester.c b/example/src/brightness_tester.c index 2257162..921bbd0 100644 --- a/example/src/brightness_tester.c +++ b/example/src/brightness_tester.c @@ -5,14 +5,14 @@ void enable_all_pixels(void) { Bitmap *all_on = sp_bitmap_new_max_sized(); sp_bitmap_fill(all_on, true); - BitmapCommand *bitmapCommand = sp_cmd_bitmap_from_bitmap(all_on); - Packet *packet = sp_cmd_bitmap_try_into_packet(bitmapCommand); + BitmapCommand *bitmapCommand = sp_bitmapcommand_from_bitmap(all_on); + Packet *packet = sp_bitmapcommand_try_into_packet(bitmapCommand); if (packet != NULL) - sp_udp_send_packet(sock, packet); + sp_udpsocket_send_packet(sock, packet); } void make_brightness_pattern(BrightnessGrid *grid) { - ByteSlice slice = sp_brightness_grid_data_ref_mut(grid); + ByteSlice slice = sp_brightnessgrid_data_ref_mut(grid); for (size_t index = 0; index < slice.length; index++) { slice.start[index] = (uint8_t)(index % ((size_t) Brightness_MAX)); } @@ -23,13 +23,13 @@ int main(void) { enable_all_pixels(); - BrightnessGrid *grid = sp_brightness_grid_new(TILE_WIDTH, TILE_HEIGHT); + BrightnessGrid *grid = sp_brightnessgrid_new(TILE_WIDTH, TILE_HEIGHT); make_brightness_pattern(grid); - Packet *packet = sp_cmd_brightness_grid_into_packet(sp_cmd_brightness_grid_from_grid(grid)); + Packet *packet = sp_brightnessgridcommand_try_into_packet(sp_brightnessgridcommand_from_grid(grid)); if (packet == NULL) return -2; - sp_udp_send_packet(sock, packet); + sp_udpsocket_send_packet(sock, packet); return 0; } diff --git a/example/src/header_logger.c b/example/src/header_logger.c index 9cb3cd1..5793da9 100644 --- a/example/src/header_logger.c +++ b/example/src/header_logger.c @@ -15,8 +15,8 @@ void handle_error(const char *msg) { exit(EXIT_FAILURE); } -bool log_command(struct Command command) { - switch (command.tag) { +bool log_command(struct GenericCommand *command) { + switch (command->tag) { case COMMAND_TAG_INVALID: { printf("-> this is an invalid command\n"); break; @@ -26,14 +26,14 @@ bool log_command(struct Command command) { return true; } case COMMAND_TAG_BITMAP: { - BitmapCommand *bitmapCommand = command.data.bitmap; + BitmapCommand *bitmapCommand = command->data.bitmap; - CompressionCode compression = sp_cmd_bitmap_get_compression(bitmapCommand); + CompressionCode compression = sp_bitmapcommand_get_compression(bitmapCommand); size_t x, y; - sp_cmd_bitmap_get_origin(bitmapCommand, &x, &y); + sp_bitmapcommand_get_origin(bitmapCommand, &x, &y); - Bitmap *bitmap = sp_cmd_bitmap_get(bitmapCommand); + Bitmap *bitmap = sp_bitmapcommand_get_bitmap_mut(bitmapCommand); size_t w = sp_bitmap_width(bitmap); size_t h = sp_bitmap_height(bitmap); @@ -42,54 +42,54 @@ bool log_command(struct Command command) { break; } case COMMAND_TAG_BRIGHTNESS_GRID: { - BrightnessGridCommand *gridCommand = command.data.brightness_grid; + BrightnessGridCommand *gridCommand = command->data.brightness_grid; size_t x, y; - sp_cmd_brightness_grid_get_origin(gridCommand, &x, &y); + sp_brightnessgridcommand_get_origin(gridCommand, &x, &y); - BrightnessGrid *grid = sp_cmd_brightness_grid_get(gridCommand); - size_t w = sp_brightness_grid_width(grid); - size_t h = sp_brightness_grid_height(grid); + BrightnessGrid *grid = sp_brightnessgridcommand_get_grid_mut(gridCommand); + size_t w = sp_brightnessgrid_width(grid); + size_t h = sp_brightnessgrid_height(grid); printf("-> BrightnessGridCommand with params: x=%zu, y=%zu, w=%zu, h=%zu\n", x, y, w, h); break; } case COMMAND_TAG_CHAR_GRID: { - CharGridCommand *gridCommand = command.data.char_grid; + CharGridCommand *gridCommand = command->data.char_grid; size_t x, y; - sp_cmd_char_grid_get_origin(gridCommand, &x, &y); + sp_chargridcommand_get_origin(gridCommand, &x, &y); - CharGrid *grid = sp_cmd_char_grid_get(gridCommand); - size_t w = sp_char_grid_width(grid); - size_t h = sp_char_grid_height(grid); + CharGrid *grid = sp_chargridcommand_get_grid_mut(gridCommand); + size_t w = sp_chargrid_width(grid); + size_t h = sp_chargrid_height(grid); printf("-> CharGridCommand with params: x=%zu, y=%zu, w=%zu, h=%zu\n", x, y, w, h); break; } case COMMAND_TAG_CP437_GRID: { - Cp437GridCommand *gridCommand = command.data.cp437_grid; + Cp437GridCommand *gridCommand = command->data.cp437_grid; size_t x, y; - sp_cmd_cp437_grid_get_origin(gridCommand, &x, &y); + sp_cp437gridcommand_get_origin(gridCommand, &x, &y); - Cp437Grid *grid = sp_cmd_cp437_grid_get(gridCommand); - size_t w = sp_cp437_grid_width(grid); - size_t h = sp_cp437_grid_height(grid); + Cp437Grid *grid = sp_cp437gridcommand_get_grid_mut(gridCommand); + size_t w = sp_cp437grid_width(grid); + size_t h = sp_cp437grid_height(grid); printf("-> Cp437GridCommand with params: x=%zu, y=%zu, w=%zu, h=%zu\n", x, y, w, h); break; } case COMMAND_TAG_BIT_VEC: { - BitVecCommand *bitvecCommand = command.data.bitvec; + BitVecCommand *bitvecCommand = command->data.bit_vec; - size_t offset = sp_cmd_bitvec_get_offset(bitvecCommand); - CompressionCode compression = sp_cmd_bitvec_get_compression(bitvecCommand); + size_t offset = sp_bitveccommand_get_offset(bitvecCommand); + CompressionCode compression = sp_bitveccommand_get_compression(bitvecCommand); - BinaryOperation operation = sp_cmd_bitvec_get_operation(bitvecCommand); + BinaryOperation operation = sp_bitveccommand_get_operation(bitvecCommand); char *operationText; switch (operation) { case BINARY_OPERATION_AND: @@ -109,8 +109,8 @@ bool log_command(struct Command command) { break; } - BitVec *bitvec = sp_cmd_bitvec_get(bitvecCommand); - size_t len = sp_bitvec_len(bitvec); + DisplayBitVec *bitvec = sp_bitveccommand_get_bitvec_mut(bitvecCommand); + size_t len = sp_displaybitvec_len(bitvec); printf("-> BitVecCommand with params: offset=%zu, length=%zu, compression=%hu, operation=%s\n", offset, len, compression, operationText); @@ -129,12 +129,12 @@ bool log_command(struct Command command) { break; } case COMMAND_TAG_GLOBAL_BRIGHTNESS: { - Brightness brightness = sp_cmd_brightness_global_get_brightness(command.data.global_brightness); + Brightness brightness = sp_globalbrightnesscommand_get_brightness(command->data.global_brightness); printf("-> GlobalBrightnessCommand with params: brightness=%hu\n", brightness); break; } default: { - printf("-> unknown command tag %d\n", command.tag); + printf("-> unknown command tag %d\n", command->tag); break; } } @@ -198,10 +198,10 @@ int main(int argc, char **argv) { header->command_code, header->a, header->b, header->c, header->d, payload.start, payload.length); - struct Command command = sp_cmd_generic_try_from_packet(packet); + struct GenericCommand *command = sp_genericcommand_try_from_packet(packet); done = log_command(command); - sp_cmd_generic_free(command); + sp_genericcommand_free(command); } close(udp_socket); diff --git a/example/src/helpers.h b/example/src/helpers.h index bc6c119..ee415f2 100644 --- a/example/src/helpers.h +++ b/example/src/helpers.h @@ -10,12 +10,12 @@ static UdpSocket *sock = NULL; void sock_free() { - sp_udp_free(sock); + sp_udpsocket_free(sock); } void sock_init() { - //sock = sp_udp_open_ipv4(127, 0, 0, 1, 2342); - sock = sp_udp_open_ipv4(172, 23, 42, 29, 2342); + sock = sp_udpsocket_open_ipv4(127, 0, 0, 1, 2342); + //sock = sp_udp_open_ipv4(172, 23, 42, 29, 2342); if (sock == NULL) exit(-1); atexit(sock_free); diff --git a/example/src/moving_line.c b/example/src/moving_line.c index 35ba20d..12a1a9b 100644 --- a/example/src/moving_line.c +++ b/example/src/moving_line.c @@ -13,14 +13,14 @@ int main(void) { sp_bitmap_set(bitmap, (y + x) % PIXEL_WIDTH, y, true); } - BitmapCommand *command = sp_cmd_bitmap_from_bitmap(sp_bitmap_clone(bitmap)); - Packet *packet = sp_cmd_bitmap_try_into_packet(command); + BitmapCommand *command = sp_bitmapcommand_from_bitmap(sp_bitmap_clone(bitmap)); + Packet *packet = sp_bitmapcommand_try_into_packet(command); if (packet == NULL) { result = -2; goto exit; } - if (!sp_udp_send_packet(sock, packet)) { + if (!sp_udpsocket_send_packet(sock, packet)) { result = -3; goto exit; } diff --git a/example/src/random_stuff.c b/example/src/random_stuff.c index b55e42c..7a58c3a 100644 --- a/example/src/random_stuff.c +++ b/example/src/random_stuff.c @@ -11,13 +11,13 @@ int main(void) { sp_bitmap_fill(pixels, true); - Packet *packet = sp_bitmap_into_packet(pixels, 0, 0, COMPRESSION_CODE_UNCOMPRESSED); + Packet *packet = sp_bitmap_try_into_packet(pixels, 0, 0, COMPRESSION_CODE_UNCOMPRESSED); if (packet == NULL) return 1; Header *header = sp_packet_get_header_mut(packet); printf("[%d, %d, %d, %d, %d]\n", header->command_code, header->a, header->b, header->c, header->d); - sp_udp_send_packet(sock, packet); + sp_udpsocket_send_packet(sock, packet); return 0; } diff --git a/example/src/undefined.c b/example/src/undefined.c new file mode 100644 index 0000000..b869d71 --- /dev/null +++ b/example/src/undefined.c @@ -0,0 +1,22 @@ +#include +#include "servicepoint.h" +#include "helpers.h" + +/// DO NOT DO ANY OF THIS! +int main(void) { + BitmapCommand *bmcmd = sp_bitmapcommand_new(sp_bitmap_new_max_sized(), 0, 0, COMPRESSION_CODE_UNCOMPRESSED); + BitVecCommand *bvcmd = (BitVecCommand *) bmcmd; + sp_bitveccommand_free(bvcmd); + + uint8_t *data = calloc(1024, 1); + struct GenericCommand generic = { + .tag = COMMAND_TAG_BRIGHTNESS_GRID, + .data = {.null = data}, + }; + + sock_init(); + + sp_udpsocket_send_command(sock, &generic); + + return 0; +} diff --git a/example/src/wiping_clear.c b/example/src/wiping_clear.c index a3f7017..1d0440b 100644 --- a/example/src/wiping_clear.c +++ b/example/src/wiping_clear.c @@ -13,14 +13,14 @@ int main() { sp_bitmap_set(enabled_pixels, x, y, false); } - BitVec *bitvec = sp_bitmap_into_bitvec(sp_bitmap_clone(enabled_pixels)); - BitVecCommand *command = sp_cmd_bitvec_new(bitvec, 0, BINARY_OPERATION_AND, COMPRESSION_CODE_LZMA); - Packet *packet = sp_cmd_bitvec_try_into_packet(command); + DisplayBitVec *bitvec = sp_bitmap_into_bitvec(sp_bitmap_clone(enabled_pixels)); + BitVecCommand *command = sp_bitveccommand_new(bitvec, 0, BINARY_OPERATION_AND, COMPRESSION_CODE_LZMA); + Packet *packet = sp_bitveccommand_try_into_packet(command); if (packet == NULL) { result = -2; goto exit; } - if (!sp_udp_send_packet(sock, packet)) { + if (!sp_udpsocket_send_packet(sock, packet)) { result = -3; goto exit; } diff --git a/include/servicepoint.h b/include/servicepoint.h index 68d4c57..703ab37 100644 --- a/include/servicepoint.h +++ b/include/servicepoint.h @@ -99,7 +99,7 @@ typedef uint8_t BinaryOperation; #endif // __cplusplus /** - * The u16 command codes used for the [Command]s. + * The u16 command codes used for the [`crate::Command`]s. */ enum CommandCode #ifdef __cplusplus @@ -355,7 +355,7 @@ typedef struct Cp437GridCommand Cp437GridCommand; /** * This is a type only used by cbindgen to have a type for pointers. */ -typedef struct BitVec BitVec; +typedef struct DisplayBitVec DisplayBitVec; /** *
Untested
@@ -412,6 +412,8 @@ typedef struct Packet Packet; /** * This is a type only used by cbindgen to have a type for pointers. + * + * See [servicepoint::UdpSocketExt]. */ typedef struct UdpSocket UdpSocket; @@ -474,6 +476,11 @@ typedef struct ByteSlice { size_t length; } ByteSlice; +/** + * Type alias for documenting the meaning of the u16 in enum values + */ +typedef size_t Offset; + /** * A grid containing brightness values. * @@ -540,11 +547,6 @@ typedef uint8_t Brightness; */ typedef struct ValueGrid_char CharGrid; -/** - * Type alias for documenting the meaning of the u16 in enum values - */ -typedef size_t Offset; - /** * A grid containing codepage 437 characters. * @@ -558,7 +560,7 @@ typedef struct ValueGrid_u8 Cp437Grid; typedef union CommandUnion { uint8_t *null; struct BitmapCommand */*notnull*/ bitmap; - struct BitVecCommand */*notnull*/ bitvec; + struct BitVecCommand */*notnull*/ bit_vec; struct BrightnessGridCommand */*notnull*/ brightness_grid; struct CharGridCommand */*notnull*/ char_grid; struct Cp437GridCommand */*notnull*/ cp437_grid; @@ -576,7 +578,7 @@ typedef union CommandUnion { * * Rust equivalent: [TypedCommand]. */ -typedef struct Command { +typedef struct GenericCommand { /** * Specifies which kind of command struct is contained in `data` */ @@ -585,7 +587,7 @@ typedef struct Command { * The pointer to the command struct */ union CommandUnion data; -} Command; +} GenericCommand; /** * A raw header. @@ -634,40 +636,44 @@ extern "C" { #endif // __cplusplus /** + * Calls method [`servicepoint::Bitmap::clone`]. + * *Clones a [`Bitmap`] instance. * - * This function is part of the sp_bitmap module. + * This function is part of the `bitmap` module. */ struct Bitmap */*notnull*/ sp_bitmap_clone(struct Bitmap */*notnull*/ instance); /** - * Calls [`servicepoint::Bitmap::data_ref_mut`]. + * Calls method [`servicepoint::Bitmap::data_ref_mut`]. * * Gets an unsafe reference to the data of the [Bitmap] instance. * * The returned memory is valid for the lifetime of the bitmap. * - * This function is part of the sp_bitmap module. + * This function is part of the `bitmap` module. */ struct ByteSlice sp_bitmap_data_ref_mut(struct Bitmap */*notnull*/ instance); /** - * Calls [`servicepoint::Bitmap::fill`]. + * Calls method [`servicepoint::Bitmap::fill`]. * - * Sets the state of all pixels in the [Bitmap]. + * Sets the state of all cells in the grid. * * # Arguments * - * - `value`: the value to set all pixels to + * - `value`: the value to set all cells to * - * This function is part of the sp_bitmap module. + * This function is part of the `bitmap` module. */ void sp_bitmap_fill(struct Bitmap */*notnull*/ instance, bool value); /** + * Calls method [`servicepoint::Bitmap::free`]. + * *Deallocates a [`Bitmap`] instance. * - * This function is part of the sp_bitmap module. + * This function is part of the `bitmap` module. */ void sp_bitmap_free(struct Bitmap */*notnull*/ instance); @@ -678,12 +684,13 @@ void sp_bitmap_free(struct Bitmap */*notnull*/ instance); * * Returns NULL in case of error. * - * This function is part of the sp_bitmap module. + * This function is part of the `bitmap` module. */ -struct Bitmap *sp_bitmap_from_bitvec(size_t width, BitVec */*notnull*/ bitvec); +struct Bitmap *sp_bitmap_from_bitvec(size_t width, + DisplayBitVec */*notnull*/ bitvec); /** - * Calls [`servicepoint::Bitmap::get`]. + * Calls method [`servicepoint::Bitmap::get`]. * * Gets the current value at the specified position. * @@ -695,39 +702,27 @@ struct Bitmap *sp_bitmap_from_bitvec(size_t width, BitVec */*notnull*/ bitvec); * * - when accessing `x` or `y` out of bounds * - * This function is part of the sp_bitmap module. + * This function is part of the `bitmap` module. */ bool sp_bitmap_get(struct Bitmap */*notnull*/ instance, size_t x, size_t y); /** - * Calls [`servicepoint::Bitmap::height`]. + * Calls method [`servicepoint::Bitmap::height`]. * - * Gets the height in pixels. + * Gets the height. * - * This function is part of the sp_bitmap module. + * This function is part of the `bitmap` module. */ size_t sp_bitmap_height(struct Bitmap */*notnull*/ instance); /** + * Calls method [`servicepoint::Bitmap::into_bitvec`]. + * * Consumes the Bitmap and returns the contained BitVec. * - * This function is part of the sp_bitmap module. + * This function is part of the `bitmap` module. */ -BitVec */*notnull*/ sp_bitmap_into_bitvec(struct 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. - * - * This function is part of the sp_bitmap module. - */ -struct Packet *sp_bitmap_into_packet(struct Bitmap */*notnull*/ bitmap, - size_t x, - size_t y, - CompressionCode compression); +DisplayBitVec */*notnull*/ sp_bitmap_into_bitvec(struct Bitmap */*notnull*/ bitmap); /** * Loads a [Bitmap] with the specified dimensions from the provided data. @@ -739,7 +734,7 @@ struct Packet *sp_bitmap_into_packet(struct Bitmap */*notnull*/ bitmap, * * returns: [Bitmap] that contains a copy of the provided data, or NULL in case of an error. * - * This function is part of the sp_bitmap module. + * This function is part of the `bitmap` module. */ struct Bitmap *sp_bitmap_load(size_t width, size_t height, @@ -770,7 +765,7 @@ struct Bitmap *sp_bitmap_load(size_t width, * sp_bitmap_free(grid); * ``` * - * This function is part of the sp_bitmap module. + * This function is part of the `bitmap` module. */ struct Bitmap *sp_bitmap_new(size_t width, size_t height); @@ -779,12 +774,12 @@ struct Bitmap *sp_bitmap_new(size_t width, size_t height); * * returns: [Bitmap] initialized to all pixels off. * - * This function is part of the sp_bitmap module. + * This function is part of the `bitmap` module. */ struct Bitmap */*notnull*/ sp_bitmap_new_max_sized(void); /** - * Calls [`servicepoint::Bitmap::set`]. + * Calls method [`servicepoint::Bitmap::set`]. * * Sets the value of the specified position. * @@ -797,7 +792,7 @@ struct Bitmap */*notnull*/ sp_bitmap_new_max_sized(void); * * - when accessing `x` or `y` out of bounds * - * This function is part of the sp_bitmap module. + * This function is part of the `bitmap` module. */ void sp_bitmap_set(struct Bitmap */*notnull*/ instance, size_t x, @@ -805,189 +800,322 @@ void sp_bitmap_set(struct Bitmap */*notnull*/ instance, bool value); /** - * Calls [`servicepoint::Bitmap::width`]. + * Calls method [`servicepoint::Bitmap::try_into_packet`]. * - * Gets the width in pixels. + * Creates a [BitmapCommand] and immediately turns that into a [Packet]. * - * This function is part of the sp_bitmap module. + * The provided [Bitmap] gets consumed. + * + * Returns NULL in case of an error. + * + * This function is part of the `bitmap` module. + */ +struct Packet *sp_bitmap_try_into_packet(struct Bitmap */*notnull*/ bitmap, + size_t x, + size_t y, + CompressionCode compression); + +/** + * Calls method [`servicepoint::Bitmap::width`]. + * + * Gets the width. + * + * This function is part of the `bitmap` module. */ size_t sp_bitmap_width(struct Bitmap */*notnull*/ instance); /** - * Calls [`servicepoint::DisplayBitVec::as_raw_mut_slice`]. + * Calls method [`servicepoint::BitmapCommand::clone`]. * - * Gets an unsafe reference to the data of the [DisplayBitVec] instance. + *Clones a [`BitmapCommand`] instance. * - * The returned memory is valid for the lifetime of the bitvec. - * - * This function is part of the sp_bitvec module. + * This function is part of the `bitmapcommand` module. */ -struct ByteSlice sp_bitvec_as_raw_mut_slice(BitVec */*notnull*/ instance); +struct BitmapCommand */*notnull*/ sp_bitmapcommand_clone(struct BitmapCommand */*notnull*/ instance); /** - *Clones a [`DisplayBitVec`] instance. + * Calls method [`servicepoint::BitmapCommand::free`]. * - * This function is part of the sp_bitvec module. + *Deallocates a [`BitmapCommand`] instance. + * + * This function is part of the `bitmapcommand` module. */ -BitVec */*notnull*/ sp_bitvec_clone(BitVec */*notnull*/ instance); +void sp_bitmapcommand_free(struct BitmapCommand */*notnull*/ instance); /** - * Calls [`servicepoint::DisplayBitVec::fill`]. + * Move the provided [Bitmap] into a new [BitmapCommand], + * leaving other fields as their default values. * - * Sets the value of all bits. + * Rust equivalent: `BitmapCommand::from(bitmap)` * - * # Arguments - * - * - `value`: the value to set all bits to - * - * This function is part of the sp_bitvec module. + * This function is part of the `bitmapcommand` module. */ -void sp_bitvec_fill(BitVec */*notnull*/ instance, bool value); +struct BitmapCommand */*notnull*/ sp_bitmapcommand_from_bitmap(struct Bitmap */*notnull*/ bitmap); /** - *Deallocates a [`DisplayBitVec`] instance. + * Calls method [`servicepoint::BitmapCommand::get_bitmap_mut`]. * - * This function is part of the sp_bitvec module. + * Gets a reference to the field `bitmap` of the [`servicepoint::BitmapCommand`]. + * + * - The returned reference inherits the lifetime of object in which it is contained. + * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command. + * + * This function is part of the `bitmapcommand` module. */ -void sp_bitvec_free(BitVec */*notnull*/ instance); +struct Bitmap */*notnull*/ sp_bitmapcommand_get_bitmap_mut(struct BitmapCommand */*notnull*/ instance); /** - * Calls [`servicepoint::DisplayBitVec::get`]. + * Calls method [`servicepoint::BitmapCommand::get_compression`]. * - * Gets the value of a bit. + * Gets the value of field `compression` of the [`servicepoint::BitmapCommand`]. * - * # Arguments - * - * - `bit_vec`: instance to read from - * - `index`: the bit index to read - * - * returns: value of the bit - * - * # Panics - * - * - when accessing `index` out of bounds - * - * This function is part of the sp_bitvec module. + * This function is part of the `bitmapcommand` module. */ -bool sp_bitvec_get(BitVec */*notnull*/ instance, size_t index); +CompressionCode sp_bitmapcommand_get_compression(struct BitmapCommand */*notnull*/ instance); /** - * Creates a [BitVecCommand] and immediately turns that into a [Packet]. + * Calls method [`servicepoint::BitmapCommand::get_origin`]. * - * The provided [DisplayBitVec] gets consumed. + * Reads the origin field of the [`BitmapCommand`]. * - * Returns NULL in case of an error. - * - * This function is part of the sp_bitvec module. + * This function is part of the `bitmapcommand` module. */ -struct Packet *sp_bitvec_into_packet(BitVec */*notnull*/ bitvec, - size_t offset, - BinaryOperation operation, - CompressionCode compression); +void sp_bitmapcommand_get_origin(struct BitmapCommand */*notnull*/ command, + size_t */*notnull*/ origin_x, + size_t */*notnull*/ origin_y); /** - * Calls [`servicepoint::DisplayBitVec::is_empty`]. + * Sets a window of pixels to the specified values. * - * Returns true if length is 0. + * The passed [Bitmap] gets consumed. * - * This function is part of the sp_bitvec module. + * Returns: a new [BitmapCommand] instance. + * + * This function is part of the `bitmapcommand` module. */ -bool sp_bitvec_is_empty(BitVec */*notnull*/ instance); +struct BitmapCommand */*notnull*/ sp_bitmapcommand_new(struct Bitmap */*notnull*/ bitmap, + size_t origin_x, + size_t origin_y, + CompressionCode compression); /** - * Calls [`servicepoint::DisplayBitVec::len`]. + * Calls method [`servicepoint::BitmapCommand::set_bitmap`]. * - * Gets the length in bits. + * Sets the value of field `bitmap` of the [`servicepoint::BitmapCommand`]. + * The provided value is moved into the instance, potentially invalidating previously taken references. * - * This function is part of the sp_bitvec module. + * This function is part of the `bitmapcommand` module. */ -size_t sp_bitvec_len(BitVec */*notnull*/ instance); +void sp_bitmapcommand_set_bitmap(struct BitmapCommand */*notnull*/ instance, + struct Bitmap */*notnull*/ value); /** - * Interpret the data as a series of bits and load then into a new [DisplayBitVec] instance. + * Calls method [`servicepoint::BitmapCommand::set_compression`]. * - * returns: [DisplayBitVec] instance containing data. + * Sets the value of field `compression` of the [`servicepoint::BitmapCommand`]. * - * This function is part of the sp_bitvec module. + * This function is part of the `bitmapcommand` module. */ -BitVec */*notnull*/ sp_bitvec_load(struct ByteSlice data); +void sp_bitmapcommand_set_compression(struct BitmapCommand */*notnull*/ instance, + CompressionCode value); /** - * Creates a new [DisplayBitVec] instance. + * Calls method [`servicepoint::BitmapCommand::set_origin`]. * - * # Arguments + * Overwrites the origin field of the [`BitmapCommand`]. * - * - `size`: size in bits. - * - * returns: [DisplayBitVec] with all bits set to false. - * - * # Panics - * - * - when `size` is not divisible by 8. - * - * This function is part of the sp_bitvec module. + * This function is part of the `bitmapcommand` module. */ -BitVec */*notnull*/ sp_bitvec_new(size_t size); +void sp_bitmapcommand_set_origin(struct BitmapCommand */*notnull*/ command, + size_t origin_x, + size_t origin_y); /** - * Calls [`servicepoint::DisplayBitVec::set`]. + * Calls method [`servicepoint::BitmapCommand::try_into_packet`]. * - * Sets the value of a bit. + *Tries to turn a [`BitmapCommand`] into a [Packet]. * - * # Arguments + * Returns: NULL or a [Packet] containing the command. * - * - `index`: the bit index to edit - * - `value`: the value to set the bit to - * - * # Panics - * - * - when accessing `index` out of bounds - * - * This function is part of the sp_bitvec module. + * This function is part of the `bitmapcommand` module. */ -void sp_bitvec_set(BitVec */*notnull*/ instance, size_t index, bool value); +struct Packet *sp_bitmapcommand_try_into_packet(struct BitmapCommand */*notnull*/ instance); /** + * Calls method [`servicepoint::BitVecCommand::clone`]. + * + *Clones a [`BitVecCommand`] instance. + * + * This function is part of the `bitveccommand` module. + */ +struct BitVecCommand */*notnull*/ sp_bitveccommand_clone(struct BitVecCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::BitVecCommand::free`]. + * + *Deallocates a [`BitVecCommand`] instance. + * + * This function is part of the `bitveccommand` module. + */ +void sp_bitveccommand_free(struct BitVecCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::BitVecCommand::get_bitvec_mut`]. + * + * Gets a reference to the field `bitvec` of the [`servicepoint::BitVecCommand`]. + * + * - The returned reference inherits the lifetime of object in which it is contained. + * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command. + * + * This function is part of the `bitveccommand` module. + */ +DisplayBitVec */*notnull*/ sp_bitveccommand_get_bitvec_mut(struct BitVecCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::BitVecCommand::get_compression`]. + * + * Gets the value of field `compression` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the `bitveccommand` module. + */ +CompressionCode sp_bitveccommand_get_compression(struct BitVecCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::BitVecCommand::get_offset`]. + * + * Gets the value of field `offset` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the `bitveccommand` module. + */ +Offset sp_bitveccommand_get_offset(struct BitVecCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::BitVecCommand::get_operation`]. + * + * Gets the value of field `operation` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the `bitveccommand` module. + */ +BinaryOperation sp_bitveccommand_get_operation(struct BitVecCommand */*notnull*/ instance); + +/** + * Set pixel data starting at the pixel offset on screen. + * + * The screen will continuously overwrite more pixel data without regarding the offset, meaning + * once the starting row is full, overwriting will continue on column 0. + * + * The [`BinaryOperation`] will be applied on the display comparing old and sent bit. + * + * `new_bit = old_bit op sent_bit` + * + * For example, [`BinaryOperation::Or`] can be used to turn on some pixels without affecting other pixels. + * + * The contained [`DisplayBitVec`] is always uncompressed. + * + * This function is part of the `bitveccommand` module. + */ +struct BitVecCommand */*notnull*/ sp_bitveccommand_new(DisplayBitVec */*notnull*/ bitvec, + size_t offset, + BinaryOperation operation, + CompressionCode compression); + +/** + * Calls method [`servicepoint::BitVecCommand::set_bitvec`]. + * + * Sets the value of field `bitvec` of the [`servicepoint::BitVecCommand`]. + * The provided value is moved into the instance, potentially invalidating previously taken references. + * + * This function is part of the `bitveccommand` module. + */ +void sp_bitveccommand_set_bitvec(struct BitVecCommand */*notnull*/ instance, + DisplayBitVec */*notnull*/ value); + +/** + * Calls method [`servicepoint::BitVecCommand::set_compression`]. + * + * Sets the value of field `compression` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the `bitveccommand` module. + */ +void sp_bitveccommand_set_compression(struct BitVecCommand */*notnull*/ instance, + CompressionCode value); + +/** + * Calls method [`servicepoint::BitVecCommand::set_offset`]. + * + * Sets the value of field `offset` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the `bitveccommand` module. + */ +void sp_bitveccommand_set_offset(struct BitVecCommand */*notnull*/ instance, + Offset value); + +/** + * Calls method [`servicepoint::BitVecCommand::set_operation`]. + * + * Sets the value of field `operation` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the `bitveccommand` module. + */ +void sp_bitveccommand_set_operation(struct BitVecCommand */*notnull*/ instance, + BinaryOperation value); + +/** + * Calls method [`servicepoint::BitVecCommand::try_into_packet`]. + * + *Tries to turn a [`BitVecCommand`] into a [Packet]. + * + * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the `bitveccommand` module. + */ +struct Packet *sp_bitveccommand_try_into_packet(struct BitVecCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::BrightnessGrid::clone`]. + * *Clones a [`BrightnessGrid`] instance. * - * This function is part of the sp_brightness_grid module. + * This function is part of the `brightnessgrid` module. */ -BrightnessGrid */*notnull*/ sp_brightness_grid_clone(BrightnessGrid */*notnull*/ instance); +BrightnessGrid */*notnull*/ sp_brightnessgrid_clone(BrightnessGrid */*notnull*/ instance); /** - * Calls [`servicepoint::BrightnessGrid::data_ref_mut`]. + * Calls method [`servicepoint::BrightnessGrid::data_ref_mut`]. * * Gets an unsafe reference to the data of the instance. * * The returned memory is valid for the lifetime of the grid. * - * This function is part of the sp_brightness_grid module. + * This function is part of the `brightnessgrid` module. */ -struct ByteSlice sp_brightness_grid_data_ref_mut(BrightnessGrid */*notnull*/ instance); +struct ByteSlice sp_brightnessgrid_data_ref_mut(BrightnessGrid */*notnull*/ instance); /** - * Calls [`servicepoint::BrightnessGrid::fill`]. + * Calls method [`servicepoint::BrightnessGrid::fill`]. * - * Sets the value of all cells. + * Sets the state of all cells in the grid. * * # Arguments * * - `value`: the value to set all cells to * - * This function is part of the sp_brightness_grid module. + * This function is part of the `brightnessgrid` module. */ -void sp_brightness_grid_fill(BrightnessGrid */*notnull*/ instance, - Brightness value); +void sp_brightnessgrid_fill(BrightnessGrid */*notnull*/ instance, + Brightness value); /** + * Calls method [`servicepoint::BrightnessGrid::free`]. + * *Deallocates a [`BrightnessGrid`] instance. * - * This function is part of the sp_brightness_grid module. + * This function is part of the `brightnessgrid` module. */ -void sp_brightness_grid_free(BrightnessGrid */*notnull*/ instance); +void sp_brightnessgrid_free(BrightnessGrid */*notnull*/ instance); /** - * Calls [`servicepoint::BrightnessGrid::get`]. + * Calls method [`servicepoint::BrightnessGrid::get`]. * * Gets the current value at the specified position. * @@ -995,38 +1123,24 @@ void sp_brightness_grid_free(BrightnessGrid */*notnull*/ instance); * * - `x` and `y`: position of the cell to read * - * returns: value at position - * * # Panics - * - When accessing `x` or `y` out of bounds. * - * This function is part of the sp_brightness_grid module. + * - when accessing `x` or `y` out of bounds + * + * This function is part of the `brightnessgrid` module. */ -Brightness sp_brightness_grid_get(BrightnessGrid */*notnull*/ instance, - size_t x, - size_t y); +Brightness sp_brightnessgrid_get(BrightnessGrid */*notnull*/ instance, + size_t x, + size_t y); /** - * Calls [`servicepoint::BrightnessGrid::height`]. + * Calls method [`servicepoint::BrightnessGrid::height`]. * - * Gets the height of the grid. + * Gets the height. * - * This function is part of the sp_brightness_grid module. + * This function is part of the `brightnessgrid` module. */ -size_t sp_brightness_grid_height(BrightnessGrid */*notnull*/ instance); - -/** - * Creates a [BrightnessGridCommand] and immediately turns that into a [Packet]. - * - * The provided [BrightnessGrid] gets consumed. - * - * Returns NULL in case of an error. - * - * This function is part of the sp_brightness_grid module. - */ -struct Packet *sp_brightness_grid_into_packet(BrightnessGrid */*notnull*/ grid, - size_t x, - size_t y); +size_t sp_brightnessgrid_height(BrightnessGrid */*notnull*/ instance); /** * Loads a [BrightnessGrid] with the specified dimensions from the provided data. @@ -1035,11 +1149,11 @@ struct Packet *sp_brightness_grid_into_packet(BrightnessGrid */*notnull*/ grid, * * returns: new [BrightnessGrid] instance, or NULL in case of an error. * - * This function is part of the sp_brightness_grid module. + * This function is part of the `brightnessgrid` module. */ -BrightnessGrid *sp_brightness_grid_load(size_t width, - size_t height, - struct ByteSlice data); +BrightnessGrid *sp_brightnessgrid_load(size_t width, + size_t height, + struct ByteSlice data); /** * Creates a new [BrightnessGrid] with the specified dimensions. @@ -1060,12 +1174,12 @@ BrightnessGrid *sp_brightness_grid_load(size_t width, * sp_udp_free(connection); * ``` * - * This function is part of the sp_brightness_grid module. + * This function is part of the `brightnessgrid` module. */ -BrightnessGrid */*notnull*/ sp_brightness_grid_new(size_t width, size_t height); +BrightnessGrid */*notnull*/ sp_brightnessgrid_new(size_t width, size_t height); /** - * Calls [`servicepoint::BrightnessGrid::set`]. + * Calls method [`servicepoint::BrightnessGrid::set`]. * * Sets the value of the specified position. * @@ -1074,37 +1188,147 @@ BrightnessGrid */*notnull*/ sp_brightness_grid_new(size_t width, size_t height); * - `x` and `y`: position of the cell * - `value`: the value to write to the cell * - * returns: old value of the cell - * * # Panics * - * - When accessing `x` or `y` out of bounds. + * - when accessing `x` or `y` out of bounds * - * This function is part of the sp_brightness_grid module. + * This function is part of the `brightnessgrid` module. */ -void sp_brightness_grid_set(BrightnessGrid */*notnull*/ instance, - size_t x, - size_t y, - Brightness value); +void sp_brightnessgrid_set(BrightnessGrid */*notnull*/ instance, + size_t x, + size_t y, + Brightness value); /** - * Calls [`servicepoint::BrightnessGrid::width`]. + * Calls method [`servicepoint::BrightnessGrid::try_into_packet`]. * - * Gets the width of the grid. + * Creates a [BrightnessGridCommand] and immediately turns that into a [Packet]. * - * This function is part of the sp_brightness_grid module. + * The provided [BrightnessGrid] gets consumed. + * + * Returns NULL in case of an error. + * + * This function is part of the `brightnessgrid` module. */ -size_t sp_brightness_grid_width(BrightnessGrid */*notnull*/ instance); +struct Packet *sp_brightnessgrid_try_into_packet(BrightnessGrid */*notnull*/ grid, + size_t x, + size_t y); /** + * Calls method [`servicepoint::BrightnessGrid::width`]. + * + * Gets the width. + * + * This function is part of the `brightnessgrid` module. + */ +size_t sp_brightnessgrid_width(BrightnessGrid */*notnull*/ instance); + +/** + * Calls method [`servicepoint::BrightnessGridCommand::clone`]. + * + *Clones a [`BrightnessGridCommand`] instance. + * + * This function is part of the `brightnessgridcommand` module. + */ +struct BrightnessGridCommand */*notnull*/ sp_brightnessgridcommand_clone(struct BrightnessGridCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::BrightnessGridCommand::free`]. + * + *Deallocates a [`BrightnessGridCommand`] instance. + * + * This function is part of the `brightnessgridcommand` module. + */ +void sp_brightnessgridcommand_free(struct BrightnessGridCommand */*notnull*/ instance); + +/** + * Moves the provided [BrightnessGrid] into a new [BrightnessGridCommand], + * leaving other fields as their default values. + * + * This function is part of the `brightnessgridcommand` module. + */ +struct BrightnessGridCommand */*notnull*/ sp_brightnessgridcommand_from_grid(BrightnessGrid */*notnull*/ grid); + +/** + * Calls method [`servicepoint::BrightnessGridCommand::get_grid_mut`]. + * + * Gets a reference to the field `grid` of the [`servicepoint::BrightnessGridCommand`]. + * + * - The returned reference inherits the lifetime of object in which it is contained. + * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command. + * + * This function is part of the `brightnessgridcommand` module. + */ +BrightnessGrid */*notnull*/ sp_brightnessgridcommand_get_grid_mut(struct BrightnessGridCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::BrightnessGridCommand::get_origin`]. + * + * Reads the origin field of the [`BrightnessGridCommand`]. + * + * This function is part of the `brightnessgridcommand` module. + */ +void sp_brightnessgridcommand_get_origin(struct BrightnessGridCommand */*notnull*/ command, + size_t */*notnull*/ origin_x, + size_t */*notnull*/ origin_y); + +/** + * Set the brightness of individual tiles in a rectangular area of the display. + * + * The passed [BrightnessGrid] gets consumed. + * + * Returns: a new [BrightnessGridCommand] instance. + * + * This function is part of the `brightnessgridcommand` module. + */ +struct BrightnessGridCommand */*notnull*/ sp_brightnessgridcommand_new(BrightnessGrid */*notnull*/ grid, + size_t origin_x, + size_t origin_y); + +/** + * Calls method [`servicepoint::BrightnessGridCommand::set_grid`]. + * + * Sets the value of field `grid` of the [`servicepoint::BrightnessGridCommand`]. + * The provided value is moved into the instance, potentially invalidating previously taken references. + * + * This function is part of the `brightnessgridcommand` module. + */ +void sp_brightnessgridcommand_set_grid(struct BrightnessGridCommand */*notnull*/ instance, + BrightnessGrid */*notnull*/ value); + +/** + * Calls method [`servicepoint::BrightnessGridCommand::set_origin`]. + * + * Overwrites the origin field of the [`BrightnessGridCommand`]. + * + * This function is part of the `brightnessgridcommand` module. + */ +void sp_brightnessgridcommand_set_origin(struct BrightnessGridCommand */*notnull*/ command, + size_t origin_x, + size_t origin_y); + +/** + * Calls method [`servicepoint::BrightnessGridCommand::try_into_packet`]. + * + *Tries to turn a [`BrightnessGridCommand`] into a [Packet]. + * + * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the `brightnessgridcommand` module. + */ +struct Packet *sp_brightnessgridcommand_try_into_packet(struct BrightnessGridCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::CharGrid::clone`]. + * *Clones a [`CharGrid`] instance. * - * This function is part of the sp_char_grid module. + * This function is part of the `chargrid` module. */ -CharGrid */*notnull*/ sp_char_grid_clone(CharGrid */*notnull*/ instance); +CharGrid */*notnull*/ sp_chargrid_clone(CharGrid */*notnull*/ instance); /** - * Calls [`servicepoint::CharGrid::fill`]. + * Calls method [`servicepoint::CharGrid::fill`]. * * Sets the value of all cells in the grid. * @@ -1113,19 +1337,21 @@ CharGrid */*notnull*/ sp_char_grid_clone(CharGrid */*notnull*/ instance); * - `value`: the value to set all cells to * - when providing values that cannot be converted to Rust's `char`. * - * This function is part of the sp_char_grid module. + * This function is part of the `chargrid` module. */ -void sp_char_grid_fill(CharGrid */*notnull*/ instance, uint32_t value); +void sp_chargrid_fill(CharGrid */*notnull*/ instance, uint32_t value); /** + * Calls method [`servicepoint::CharGrid::free`]. + * *Deallocates a [`CharGrid`] instance. * - * This function is part of the sp_char_grid module. + * This function is part of the `chargrid` module. */ -void sp_char_grid_free(CharGrid */*notnull*/ instance); +void sp_chargrid_free(CharGrid */*notnull*/ instance); /** - * Calls [`servicepoint::CharGrid::get`]. + * Calls method [`servicepoint::CharGrid::get`]. * * Returns the current value at the specified position. * @@ -1137,40 +1363,27 @@ void sp_char_grid_free(CharGrid */*notnull*/ instance); * * - when accessing `x` or `y` out of bounds * - * This function is part of the sp_char_grid module. + * This function is part of the `chargrid` module. */ -uint32_t sp_char_grid_get(CharGrid */*notnull*/ instance, size_t x, size_t y); +uint32_t sp_chargrid_get(CharGrid */*notnull*/ instance, size_t x, size_t y); /** - * Calls [`servicepoint::CharGrid::height`]. + * Calls method [`servicepoint::CharGrid::height`]. * - * Gets the height of the grid. + * Gets the height. * - * This function is part of the sp_char_grid module. + * This function is part of the `chargrid` module. */ -size_t sp_char_grid_height(CharGrid */*notnull*/ instance); - -/** - * Creates a [CharGridCommand] and immediately turns that into a [Packet]. - * - * The provided [CharGrid] gets consumed. - * - * Returns NULL in case of an error. - * - * This function is part of the sp_char_grid module. - */ -struct Packet *sp_char_grid_into_packet(CharGrid */*notnull*/ grid, - size_t x, - size_t y); +size_t sp_chargrid_height(CharGrid */*notnull*/ instance); /** * Loads a [CharGrid] with the specified dimensions from the provided data. * * returns: new CharGrid or NULL in case of an error * - * This function is part of the sp_char_grid module. + * This function is part of the `chargrid` module. */ -CharGrid *sp_char_grid_load(size_t width, size_t height, struct ByteSlice data); +CharGrid *sp_chargrid_load(size_t width, size_t height, struct ByteSlice data); /** * Creates a new [CharGrid] with the specified dimensions. @@ -1186,12 +1399,12 @@ CharGrid *sp_char_grid_load(size_t width, size_t height, struct ByteSlice data); * sp_char_grid_free(grid); * ``` * - * This function is part of the sp_char_grid module. + * This function is part of the `chargrid` module. */ -CharGrid */*notnull*/ sp_char_grid_new(size_t width, size_t height); +CharGrid */*notnull*/ sp_chargrid_new(size_t width, size_t height); /** - * Calls [`servicepoint::CharGrid::set`]. + * Calls method [`servicepoint::CharGrid::set`]. * * Sets the value of the specified position in the grid. * @@ -1207,395 +1420,85 @@ CharGrid */*notnull*/ sp_char_grid_new(size_t width, size_t height); * - when accessing `x` or `y` out of bounds * - when providing values that cannot be converted to Rust's `char`. * - * This function is part of the sp_char_grid module. + * This function is part of the `chargrid` module. */ -void sp_char_grid_set(CharGrid */*notnull*/ instance, - size_t x, - size_t y, - uint32_t value); +void sp_chargrid_set(CharGrid */*notnull*/ instance, + size_t x, + size_t y, + uint32_t value); /** - * Calls [`servicepoint::CharGrid::width`]. + * Calls method [`servicepoint::CharGrid::try_into_packet`]. * - * Gets the width of the grid. + * Creates a [CharGridCommand] and immediately turns that into a [Packet]. * - * This function is part of the sp_char_grid module. + * The provided [CharGrid] gets consumed. + * + * Returns NULL in case of an error. + * + * This function is part of the `chargrid` module. */ -size_t sp_char_grid_width(CharGrid */*notnull*/ instance); +struct Packet *sp_chargrid_try_into_packet(CharGrid */*notnull*/ grid, + size_t x, + size_t y); /** - *Clones a [`BitmapCommand`] instance. + * Calls method [`servicepoint::CharGrid::width`]. * - * This function is part of the sp_cmd_bitmap module. + * Gets the width. + * + * This function is part of the `chargrid` module. */ -struct BitmapCommand */*notnull*/ sp_cmd_bitmap_clone(struct BitmapCommand */*notnull*/ instance); +size_t sp_chargrid_width(CharGrid */*notnull*/ instance); /** - *Deallocates a [`BitmapCommand`] instance. + * Calls method [`servicepoint::CharGridCommand::clone`]. * - * This function is part of the sp_cmd_bitmap module. - */ -void sp_cmd_bitmap_free(struct BitmapCommand */*notnull*/ instance); - -/** - * Move the provided [Bitmap] into a new [BitmapCommand], - * leaving other fields as their default values. - * - * Rust equivalent: `BitmapCommand::from(bitmap)` - * - * This function is part of the sp_cmd_bitmap module. - */ -struct BitmapCommand */*notnull*/ sp_cmd_bitmap_from_bitmap(struct Bitmap */*notnull*/ bitmap); - -/** - * Gets a reference to the field `bitmap` of the [`servicepoint::BitmapCommand`]. - * - * - The returned reference inherits the lifetime of object in which it is contained. - * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command. - * - * This function is part of the sp_cmd_bitmap module. - */ -struct Bitmap */*notnull*/ sp_cmd_bitmap_get_bitmap_mut(struct BitmapCommand */*notnull*/ instance); - -/** - * Gets the value of field `compression` of the [`servicepoint::BitmapCommand`]. - * - * This function is part of the sp_cmd_bitmap module. - */ -CompressionCode sp_cmd_bitmap_get_compression(struct BitmapCommand */*notnull*/ instance); - -/** - * Reads the origin field of the [`BitmapCommand`]. - * - * This function is part of the sp_cmd_bitmap module. - */ -void sp_cmd_bitmap_get_origin(struct BitmapCommand */*notnull*/ command, - size_t */*notnull*/ origin_x, - size_t */*notnull*/ origin_y); - -/** - * Sets a window of pixels to the specified values. - * - * The passed [Bitmap] gets consumed. - * - * Returns: a new [BitmapCommand] instance. - * - * This function is part of the sp_cmd_bitmap module. - */ -struct BitmapCommand */*notnull*/ sp_cmd_bitmap_new(struct Bitmap */*notnull*/ bitmap, - size_t origin_x, - size_t origin_y, - CompressionCode compression); - -/** - * Sets the value of field `bitmap` of the [`servicepoint::BitmapCommand`]. - * The provided value is moved into the instance, potentially invalidating previously taken references. - * - * This function is part of the sp_cmd_bitmap module. - */ -void sp_cmd_bitmap_set_bitmap(struct BitmapCommand */*notnull*/ instance, - struct Bitmap */*notnull*/ value); - -/** - * Sets the value of field `compression` of the [`servicepoint::BitmapCommand`]. - * - * This function is part of the sp_cmd_bitmap module. - */ -void sp_cmd_bitmap_set_compression(struct BitmapCommand */*notnull*/ instance, - CompressionCode value); - -/** - * Overwrites the origin field of the [`BitmapCommand`]. - * - * This function is part of the sp_cmd_bitmap module. - */ -void sp_cmd_bitmap_set_origin(struct BitmapCommand */*notnull*/ command, - size_t origin_x, - size_t origin_y); - -/** - * Tries to turn a [BitmapCommand] into a [Packet]. - * - * Returns: NULL or a [Packet] containing the command. - * - * This function is part of the sp_cmd_bitmap module. - */ -struct Packet *sp_cmd_bitmap_try_into_packet(struct BitmapCommand */*notnull*/ command); - -/** - *Clones a [`BitVecCommand`] instance. - * - * This function is part of the sp_cmd_bitvec module. - */ -struct BitVecCommand */*notnull*/ sp_cmd_bitvec_clone(struct BitVecCommand */*notnull*/ instance); - -/** - *Deallocates a [`BitVecCommand`] instance. - * - * This function is part of the sp_cmd_bitvec module. - */ -void sp_cmd_bitvec_free(struct BitVecCommand */*notnull*/ instance); - -/** - * Gets a reference to the field `bitvec` of the [`servicepoint::BitVecCommand`]. - * - * - The returned reference inherits the lifetime of object in which it is contained. - * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command. - * - * This function is part of the sp_cmd_bitvec module. - */ -BitVec */*notnull*/ sp_cmd_bitvec_get_bitvec_mut(struct BitVecCommand */*notnull*/ instance); - -/** - * Gets the value of field `compression` of the [`servicepoint::BitVecCommand`]. - * - * This function is part of the sp_cmd_bitvec module. - */ -CompressionCode sp_cmd_bitvec_get_compression(struct BitVecCommand */*notnull*/ instance); - -/** - * Gets the value of field `offset` of the [`servicepoint::BitVecCommand`]. - * - * This function is part of the sp_cmd_bitvec module. - */ -Offset sp_cmd_bitvec_get_offset(struct BitVecCommand */*notnull*/ instance); - -/** - * Gets the value of field `operation` of the [`servicepoint::BitVecCommand`]. - * - * This function is part of the sp_cmd_bitvec module. - */ -BinaryOperation sp_cmd_bitvec_get_operation(struct BitVecCommand */*notnull*/ instance); - -/** - * Set pixel data starting at the pixel offset on screen. - * - * The screen will continuously overwrite more pixel data without regarding the offset, meaning - * once the starting row is full, overwriting will continue on column 0. - * - * The [`BinaryOperation`] will be applied on the display comparing old and sent bit. - * - * `new_bit = old_bit op sent_bit` - * - * For example, [`BinaryOperation::Or`] can be used to turn on some pixels without affecting other pixels. - * - * The contained [`DisplayBitVec`] is always uncompressed. - * - * This function is part of the sp_cmd_bitvec module. - */ -struct BitVecCommand */*notnull*/ sp_cmd_bitvec_new(BitVec */*notnull*/ bitvec, - size_t offset, - BinaryOperation operation, - CompressionCode compression); - -/** - * Sets the value of field `bitvec` of the [`servicepoint::BitVecCommand`]. - * The provided value is moved into the instance, potentially invalidating previously taken references. - * - * This function is part of the sp_cmd_bitvec module. - */ -void sp_cmd_bitvec_set_bitvec(struct BitVecCommand */*notnull*/ instance, - BitVec */*notnull*/ value); - -/** - * Sets the value of field `compression` of the [`servicepoint::BitVecCommand`]. - * - * This function is part of the sp_cmd_bitvec module. - */ -void sp_cmd_bitvec_set_compression(struct BitVecCommand */*notnull*/ instance, - CompressionCode value); - -/** - * Sets the value of field `offset` of the [`servicepoint::BitVecCommand`]. - * - * This function is part of the sp_cmd_bitvec module. - */ -void sp_cmd_bitvec_set_offset(struct BitVecCommand */*notnull*/ instance, - Offset value); - -/** - * Sets the value of field `operation` of the [`servicepoint::BitVecCommand`]. - * - * This function is part of the sp_cmd_bitvec module. - */ -void sp_cmd_bitvec_set_operation(struct BitVecCommand */*notnull*/ instance, - BinaryOperation value); - -/** - * Tries to turn a [BitVecCommand] into a [Packet]. - * - * Returns: NULL or a [Packet] containing the command. - * - * This function is part of the sp_cmd_bitvec module. - */ -struct Packet *sp_cmd_bitvec_try_into_packet(struct BitVecCommand */*notnull*/ command); - -/** - *Clones a [`GlobalBrightnessCommand`] instance. - * - * This function is part of the sp_cmd_brightness_global module. - */ -struct GlobalBrightnessCommand */*notnull*/ sp_cmd_brightness_global_clone(struct GlobalBrightnessCommand */*notnull*/ instance); - -/** - *Deallocates a [`GlobalBrightnessCommand`] instance. - * - * This function is part of the sp_cmd_brightness_global module. - */ -void sp_cmd_brightness_global_free(struct GlobalBrightnessCommand */*notnull*/ instance); - -/** - * Gets the value of field `brightness` of the [`servicepoint::GlobalBrightnessCommand`]. - * - * This function is part of the sp_cmd_brightness_global module. - */ -Brightness sp_cmd_brightness_global_get_brightness(struct GlobalBrightnessCommand */*notnull*/ instance); - -/** - * Turns the command into a packet - * - * This function is part of the sp_cmd_brightness_global module. - */ -struct Packet */*notnull*/ sp_cmd_brightness_global_into_packet(struct GlobalBrightnessCommand */*notnull*/ command); - -/** - * Set the brightness of all tiles to the same value. - * - * Returns: a new [GlobalBrightnessCommand] instance. - * - * This function is part of the sp_cmd_brightness_global module. - */ -struct GlobalBrightnessCommand */*notnull*/ sp_cmd_brightness_global_new(Brightness brightness); - -/** - * Sets the value of field `brightness` of the [`servicepoint::GlobalBrightnessCommand`]. - * - * This function is part of the sp_cmd_brightness_global module. - */ -void sp_cmd_brightness_global_set_brightness(struct GlobalBrightnessCommand */*notnull*/ instance, - Brightness value); - -/** - *Clones a [`BrightnessGridCommand`] instance. - * - * This function is part of the sp_cmd_brightness_grid module. - */ -struct BrightnessGridCommand */*notnull*/ sp_cmd_brightness_grid_clone(struct BrightnessGridCommand */*notnull*/ instance); - -/** - *Deallocates a [`BrightnessGridCommand`] instance. - * - * This function is part of the sp_cmd_brightness_grid module. - */ -void sp_cmd_brightness_grid_free(struct BrightnessGridCommand */*notnull*/ instance); - -/** - * Moves the provided [BrightnessGrid] into a new [BrightnessGridCommand], - * leaving other fields as their default values. - * - * This function is part of the sp_cmd_brightness_grid module. - */ -struct BrightnessGridCommand */*notnull*/ sp_cmd_brightness_grid_from_grid(BrightnessGrid */*notnull*/ grid); - -/** - * Gets a reference to the field `grid` of the [`servicepoint::BrightnessGridCommand`]. - * - * - The returned reference inherits the lifetime of object in which it is contained. - * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command. - * - * This function is part of the sp_cmd_brightness_grid module. - */ -BrightnessGrid */*notnull*/ sp_cmd_brightness_grid_get_grid_mut(struct BrightnessGridCommand */*notnull*/ instance); - -/** - * Reads the origin field of the [`BrightnessGridCommand`]. - * - * This function is part of the sp_cmd_brightness_grid module. - */ -void sp_cmd_brightness_grid_get_origin(struct BrightnessGridCommand */*notnull*/ command, - size_t */*notnull*/ origin_x, - size_t */*notnull*/ origin_y); - -/** - * Tries to turn a [BrightnessGridCommand] into a [Packet]. - * - * Returns: NULL or a [Packet] containing the command. - * - * This function is part of the sp_cmd_brightness_grid module. - */ -struct Packet *sp_cmd_brightness_grid_into_packet(struct BrightnessGridCommand */*notnull*/ command); - -/** - * Set the brightness of individual tiles in a rectangular area of the display. - * - * The passed [BrightnessGrid] gets consumed. - * - * Returns: a new [BrightnessGridCommand] instance. - * - * This function is part of the sp_cmd_brightness_grid module. - */ -struct BrightnessGridCommand */*notnull*/ sp_cmd_brightness_grid_new(BrightnessGrid */*notnull*/ grid, - size_t origin_x, - size_t origin_y); - -/** - * Sets the value of field `grid` of the [`servicepoint::BrightnessGridCommand`]. - * The provided value is moved into the instance, potentially invalidating previously taken references. - * - * This function is part of the sp_cmd_brightness_grid module. - */ -void sp_cmd_brightness_grid_set_grid(struct BrightnessGridCommand */*notnull*/ instance, - BrightnessGrid */*notnull*/ value); - -/** - * Overwrites the origin field of the [`BrightnessGridCommand`]. - * - * This function is part of the sp_cmd_brightness_grid module. - */ -void sp_cmd_brightness_grid_set_origin(struct BrightnessGridCommand */*notnull*/ command, - size_t origin_x, - size_t origin_y); - -/** *Clones a [`CharGridCommand`] instance. * - * This function is part of the sp_cmd_char_grid module. + * This function is part of the `chargridcommand` module. */ -struct CharGridCommand */*notnull*/ sp_cmd_char_grid_clone(struct CharGridCommand */*notnull*/ instance); +struct CharGridCommand */*notnull*/ sp_chargridcommand_clone(struct CharGridCommand */*notnull*/ instance); /** + * Calls method [`servicepoint::CharGridCommand::free`]. + * *Deallocates a [`CharGridCommand`] instance. * - * This function is part of the sp_cmd_char_grid module. + * This function is part of the `chargridcommand` module. */ -void sp_cmd_char_grid_free(struct CharGridCommand */*notnull*/ instance); +void sp_chargridcommand_free(struct CharGridCommand */*notnull*/ instance); /** * Moves the provided [CharGrid] into a new [CharGridCommand], * leaving other fields as their default values. * - * This function is part of the sp_cmd_char_grid module. + * This function is part of the `chargridcommand` module. */ -struct CharGridCommand */*notnull*/ sp_cmd_char_grid_from_grid(CharGrid */*notnull*/ grid); +struct CharGridCommand */*notnull*/ sp_chargridcommand_from_grid(CharGrid */*notnull*/ grid); /** + * Calls method [`servicepoint::CharGridCommand::get_grid_mut`]. + * * Gets a reference to the field `grid` of the [`servicepoint::CharGridCommand`]. * * - The returned reference inherits the lifetime of object in which it is contained. * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command. * - * This function is part of the sp_cmd_char_grid module. + * This function is part of the `chargridcommand` module. */ -CharGrid */*notnull*/ sp_cmd_char_grid_get_grid_mut(struct CharGridCommand */*notnull*/ instance); +CharGrid */*notnull*/ sp_chargridcommand_get_grid_mut(struct CharGridCommand */*notnull*/ instance); /** + * Calls method [`servicepoint::CharGridCommand::get_origin`]. + * * Reads the origin field of the [`CharGridCommand`]. * - * This function is part of the sp_cmd_char_grid module. + * This function is part of the `chargridcommand` module. */ -void sp_cmd_char_grid_get_origin(struct CharGridCommand */*notnull*/ command, - size_t */*notnull*/ origin_x, - size_t */*notnull*/ origin_y); +void sp_chargridcommand_get_origin(struct CharGridCommand */*notnull*/ command, + size_t */*notnull*/ origin_x, + size_t */*notnull*/ origin_y); /** * Show UTF-8 encoded text on the screen. @@ -1604,45 +1507,62 @@ void sp_cmd_char_grid_get_origin(struct CharGridCommand */*notnull*/ command, * * Returns: a new [CharGridCommand] instance. * - * This function is part of the sp_cmd_char_grid module. + * This function is part of the `chargridcommand` module. */ -struct CharGridCommand */*notnull*/ sp_cmd_char_grid_new(CharGrid */*notnull*/ grid, - size_t origin_x, - size_t origin_y); +struct CharGridCommand */*notnull*/ sp_chargridcommand_new(CharGrid */*notnull*/ grid, + size_t origin_x, + size_t origin_y); /** + * Calls method [`servicepoint::CharGridCommand::set_grid`]. + * * Sets the value of field `grid` of the [`servicepoint::CharGridCommand`]. * The provided value is moved into the instance, potentially invalidating previously taken references. * - * This function is part of the sp_cmd_char_grid module. + * This function is part of the `chargridcommand` module. */ -void sp_cmd_char_grid_set_grid(struct CharGridCommand */*notnull*/ instance, - CharGrid */*notnull*/ value); +void sp_chargridcommand_set_grid(struct CharGridCommand */*notnull*/ instance, + CharGrid */*notnull*/ value); /** + * Calls method [`servicepoint::CharGridCommand::set_origin`]. + * * Overwrites the origin field of the [`CharGridCommand`]. * - * This function is part of the sp_cmd_char_grid module. + * This function is part of the `chargridcommand` module. */ -void sp_cmd_char_grid_set_origin(struct CharGridCommand */*notnull*/ command, - size_t origin_x, - size_t origin_y); +void sp_chargridcommand_set_origin(struct CharGridCommand */*notnull*/ command, + size_t origin_x, + size_t origin_y); /** - * Tries to turn a [CharGridCommand] into a [Packet]. + * Calls method [`servicepoint::CharGridCommand::try_into_packet`]. + * + *Tries to turn a [`CharGridCommand`] into a [Packet]. * * Returns: NULL or a [Packet] containing the command. * - * This function is part of the sp_cmd_char_grid module. + * This function is part of the `chargridcommand` module. */ -struct Packet *sp_cmd_char_grid_try_into_packet(struct CharGridCommand */*notnull*/ command); +struct Packet *sp_chargridcommand_try_into_packet(struct CharGridCommand */*notnull*/ instance); /** + * Calls method [`servicepoint::ClearCommand::clone`]. + * + *Clones a [`ClearCommand`] instance. + * + * This function is part of the `clearcommand` module. + */ +struct ClearCommand */*notnull*/ sp_clearcommand_clone(struct ClearCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::ClearCommand::free`]. + * *Deallocates a [`ClearCommand`] instance. * - * This function is part of the sp_cmd_clear module. + * This function is part of the `clearcommand` module. */ -void sp_cmd_clear_free(struct ClearCommand */*notnull*/ instance); +void sp_clearcommand_free(struct ClearCommand */*notnull*/ instance); /** * Set all pixels to the off state. @@ -1651,212 +1571,65 @@ void sp_cmd_clear_free(struct ClearCommand */*notnull*/ instance); * * Returns: a new [`ClearCommand`] instance. * - * This function is part of the sp_cmd_clear module. + * This function is part of the `clearcommand` module. */ -struct ClearCommand */*notnull*/ sp_cmd_clear_new(void); +struct ClearCommand */*notnull*/ sp_clearcommand_new(void); /** - *Clones a [`Cp437GridCommand`] instance. + * Calls method [`servicepoint::ClearCommand::try_into_packet`]. * - * This function is part of the sp_cmd_cp437_grid module. - */ -struct Cp437GridCommand */*notnull*/ sp_cmd_cp437_grid_clone(struct Cp437GridCommand */*notnull*/ instance); - -/** - *Deallocates a [`Cp437GridCommand`] instance. - * - * This function is part of the sp_cmd_cp437_grid module. - */ -void sp_cmd_cp437_grid_free(struct Cp437GridCommand */*notnull*/ instance); - -/** - * Moves the provided [Cp437Grid] into a new [Cp437GridCommand], - * leaving other fields as their default values. - * - * This function is part of the sp_cmd_cp437_grid module. - */ -struct Cp437GridCommand */*notnull*/ sp_cmd_cp437_grid_from_grid(Cp437Grid */*notnull*/ grid); - -/** - * Gets a reference to the field `grid` of the [`servicepoint::Cp437GridCommand`]. - * - * - The returned reference inherits the lifetime of object in which it is contained. - * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command. - * - * This function is part of the sp_cmd_cp437_grid module. - */ -Cp437Grid */*notnull*/ sp_cmd_cp437_grid_get_grid_mut(struct Cp437GridCommand */*notnull*/ instance); - -/** - * Reads the origin field of the [`Cp437GridCommand`]. - * - * This function is part of the sp_cmd_cp437_grid module. - */ -void sp_cmd_cp437_grid_get_origin(struct Cp437GridCommand */*notnull*/ command, - size_t */*notnull*/ origin_x, - size_t */*notnull*/ origin_y); - -/** - * Show text on the screen. - * - * The text is sent in the form of a 2D grid of [CP-437] encoded characters. - * - * The origin is relative to the top-left of the display. - * - * This function is part of the sp_cmd_cp437_grid module. - */ -struct Cp437GridCommand */*notnull*/ sp_cmd_cp437_grid_new(Cp437Grid */*notnull*/ grid, - size_t origin_x, - size_t origin_y); - -/** - * Sets the value of field `grid` of the [`servicepoint::Cp437GridCommand`]. - * The provided value is moved into the instance, potentially invalidating previously taken references. - * - * This function is part of the sp_cmd_cp437_grid module. - */ -void sp_cmd_cp437_grid_set_grid(struct Cp437GridCommand */*notnull*/ instance, - Cp437Grid */*notnull*/ value); - -/** - * Overwrites the origin field of the [`Cp437GridCommand`]. - * - * This function is part of the sp_cmd_cp437_grid module. - */ -void sp_cmd_cp437_grid_set_origin(struct Cp437GridCommand */*notnull*/ command, - size_t origin_x, - size_t origin_y); - -/** - * Tries to turn a [Cp437GridCommand] into a [Packet]. + *Tries to turn a [`ClearCommand`] into a [Packet]. * * Returns: NULL or a [Packet] containing the command. * - * This function is part of the sp_cmd_cp437_grid module. + * This function is part of the `clearcommand` module. */ -struct Packet *sp_cmd_cp437_grid_try_into_packet(struct Cp437GridCommand */*notnull*/ command); +struct Packet *sp_clearcommand_try_into_packet(struct ClearCommand */*notnull*/ instance); /** - *Deallocates a [`FadeOutCommand`] instance. + * Calls method [`servicepoint::Cp437Grid::clone`]. * - * This function is part of the sp_cmd_fade_out module. - */ -void sp_cmd_fade_out_free(struct FadeOutCommand */*notnull*/ instance); - -/** - * A yet-to-be-tested command. - * - * Returns: a new [`FadeOutCommand`] instance. - * - * This function is part of the sp_cmd_fade_out module. - */ -struct FadeOutCommand */*notnull*/ sp_cmd_fade_out_new(void); - -/** - * Clones an [SPCommand] instance. - * - * returns: a new [SPCommand] instance. - * - * This function is part of the sp_cmd_generic module. - */ -struct Command sp_cmd_generic_clone(struct Command command); - -/** - * Deallocates an [SPCommand]. - * - * Commands with an invalid `tag` do not have to be freed as the `data` pointer should be null. - * - * # Examples - * - * ```C - * SPCommand c = sp_cmd_clear_into_generic(sp_cmd_clear_new()); - * sp_command_free(c); - * ``` - * - * This function is part of the sp_cmd_generic module. - */ -void sp_cmd_generic_free(struct Command command); - -/** - * Tries to turn a [SPCommand] into a [Packet]. - * The [SPCommand] gets consumed. - * - * Returns tag [CommandTag::Invalid] in case of an error. - * - * This function is part of the sp_cmd_generic module. - */ -struct Packet *sp_cmd_generic_into_packet(struct Command command); - -/** - * Tries to turn a [Packet] into a [SPCommand]. - * - * The packet is dropped in the process. - * - * Returns: pointer to new [SPCommand] instance or NULL if parsing failed. - * - * This function is part of the sp_cmd_generic module. - */ -struct Command sp_cmd_generic_try_from_packet(struct Packet */*notnull*/ packet); - -/** - *Deallocates a [`HardResetCommand`] instance. - * - * This function is part of the sp_cmd_hard_reset module. - */ -void sp_cmd_hard_reset_free(struct HardResetCommand */*notnull*/ instance); - -/** - * Kills the udp daemon on the display, which usually results in a restart. - * - * Please do not send this in your normal program flow. - * - * Returns: a new [`HardResetCommand`] instance. - * - * This function is part of the sp_cmd_hard_reset module. - */ -struct HardResetCommand */*notnull*/ sp_cmd_hard_reset_new(void); - -/** *Clones a [`Cp437Grid`] instance. * - * This function is part of the sp_cp437_grid module. + * This function is part of the `cp437grid` module. */ -Cp437Grid */*notnull*/ sp_cp437_grid_clone(Cp437Grid */*notnull*/ instance); +Cp437Grid */*notnull*/ sp_cp437grid_clone(Cp437Grid */*notnull*/ instance); /** - * Calls [`servicepoint::Cp437Grid::data_ref_mut`]. + * Calls method [`servicepoint::Cp437Grid::data_ref_mut`]. * * Gets an unsafe reference to the data of the grid. * * The returned memory is valid for the lifetime of the instance. * - * This function is part of the sp_cp437_grid module. + * This function is part of the `cp437grid` module. */ -struct ByteSlice sp_cp437_grid_data_ref_mut(Cp437Grid */*notnull*/ instance); +struct ByteSlice sp_cp437grid_data_ref_mut(Cp437Grid */*notnull*/ instance); /** - * Calls [`servicepoint::Cp437Grid::fill`]. + * Calls method [`servicepoint::Cp437Grid::fill`]. * - * Sets the value of all cells in the grid. + * Sets the state of all cells in the grid. * * # Arguments * - * - `cp437_grid`: instance to write to * - `value`: the value to set all cells to * - * This function is part of the sp_cp437_grid module. + * This function is part of the `cp437grid` module. */ -void sp_cp437_grid_fill(Cp437Grid */*notnull*/ instance, uint8_t value); +void sp_cp437grid_fill(Cp437Grid */*notnull*/ instance, uint8_t value); /** + * Calls method [`servicepoint::Cp437Grid::free`]. + * *Deallocates a [`Cp437Grid`] instance. * - * This function is part of the sp_cp437_grid module. + * This function is part of the `cp437grid` module. */ -void sp_cp437_grid_free(Cp437Grid */*notnull*/ instance); +void sp_cp437grid_free(Cp437Grid */*notnull*/ instance); /** - * Calls [`servicepoint::Cp437Grid::get`]. + * Calls method [`servicepoint::Cp437Grid::get`]. * * Gets the current value at the specified position. * @@ -1868,101 +1641,518 @@ void sp_cp437_grid_free(Cp437Grid */*notnull*/ instance); * * - when accessing `x` or `y` out of bounds * - * This function is part of the sp_cp437_grid module. + * This function is part of the `cp437grid` module. */ -uint8_t sp_cp437_grid_get(Cp437Grid */*notnull*/ instance, size_t x, size_t y); +uint8_t sp_cp437grid_get(Cp437Grid */*notnull*/ instance, size_t x, size_t y); /** - * Calls [`servicepoint::Cp437Grid::height`]. + * Calls method [`servicepoint::Cp437Grid::height`]. * - * Gets the height of the grid. + * Gets the height. * - * This function is part of the sp_cp437_grid module. + * This function is part of the `cp437grid` module. */ -size_t sp_cp437_grid_height(Cp437Grid */*notnull*/ instance); - -/** - * Creates a [Cp437GridCommand] and immediately turns that into a [Packet]. - * - * The provided [Cp437Grid] gets consumed. - * - * Returns NULL in case of an error. - * - * This function is part of the sp_cp437_grid module. - */ -struct Packet *sp_cp437_grid_into_packet(Cp437Grid */*notnull*/ grid, - size_t x, - size_t y); +size_t sp_cp437grid_height(Cp437Grid */*notnull*/ instance); /** * Loads a [Cp437Grid] with the specified dimensions from the provided data. * - * This function is part of the sp_cp437_grid module. + * This function is part of the `cp437grid` module. */ -Cp437Grid *sp_cp437_grid_load(size_t width, - size_t height, - struct ByteSlice data); +Cp437Grid *sp_cp437grid_load(size_t width, + size_t height, + struct ByteSlice data); /** * Creates a new [Cp437Grid] with the specified dimensions. * * returns: [Cp437Grid] initialized to 0. * - * This function is part of the sp_cp437_grid module. + * This function is part of the `cp437grid` module. */ -Cp437Grid */*notnull*/ sp_cp437_grid_new(size_t width, size_t height); +Cp437Grid */*notnull*/ sp_cp437grid_new(size_t width, size_t height); /** - * Calls [`servicepoint::Cp437Grid::set`]. + * Calls method [`servicepoint::Cp437Grid::set`]. * - * Sets the value at the specified position. + * Sets the value of the specified position. * * # Arguments * * - `x` and `y`: position of the cell * - `value`: the value to write to the cell * - * returns: old value of the cell - * * # Panics * * - when accessing `x` or `y` out of bounds * - * This function is part of the sp_cp437_grid module. + * This function is part of the `cp437grid` module. */ -void sp_cp437_grid_set(Cp437Grid */*notnull*/ instance, - size_t x, - size_t y, - uint8_t value); +void sp_cp437grid_set(Cp437Grid */*notnull*/ instance, + size_t x, + size_t y, + uint8_t value); /** - * Calls [`servicepoint::Cp437Grid::width`]. + * Calls method [`servicepoint::Cp437Grid::try_into_packet`]. * - * Gets the width of the grid. + * Creates a [Cp437GridCommand] and immediately turns that into a [Packet]. * - * This function is part of the sp_cp437_grid module. + * The provided [Cp437Grid] gets consumed. + * + * Returns NULL in case of an error. + * + * This function is part of the `cp437grid` module. */ -size_t sp_cp437_grid_width(Cp437Grid */*notnull*/ instance); +struct Packet *sp_cp437grid_try_into_packet(Cp437Grid */*notnull*/ grid, + size_t x, + size_t y); + +/** + * Calls method [`servicepoint::Cp437Grid::width`]. + * + * Gets the width. + * + * This function is part of the `cp437grid` module. + */ +size_t sp_cp437grid_width(Cp437Grid */*notnull*/ instance); + +/** + * Calls method [`servicepoint::Cp437GridCommand::clone`]. + * + *Clones a [`Cp437GridCommand`] instance. + * + * This function is part of the `cp437gridcommand` module. + */ +struct Cp437GridCommand */*notnull*/ sp_cp437gridcommand_clone(struct Cp437GridCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::Cp437GridCommand::free`]. + * + *Deallocates a [`Cp437GridCommand`] instance. + * + * This function is part of the `cp437gridcommand` module. + */ +void sp_cp437gridcommand_free(struct Cp437GridCommand */*notnull*/ instance); + +/** + * Moves the provided [Cp437Grid] into a new [Cp437GridCommand], + * leaving other fields as their default values. + * + * This function is part of the `cp437gridcommand` module. + */ +struct Cp437GridCommand */*notnull*/ sp_cp437gridcommand_from_grid(Cp437Grid */*notnull*/ grid); + +/** + * Calls method [`servicepoint::Cp437GridCommand::get_grid_mut`]. + * + * Gets a reference to the field `grid` of the [`servicepoint::Cp437GridCommand`]. + * + * - The returned reference inherits the lifetime of object in which it is contained. + * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command. + * + * This function is part of the `cp437gridcommand` module. + */ +Cp437Grid */*notnull*/ sp_cp437gridcommand_get_grid_mut(struct Cp437GridCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::Cp437GridCommand::get_origin`]. + * + * Reads the origin field of the [`Cp437GridCommand`]. + * + * This function is part of the `cp437gridcommand` module. + */ +void sp_cp437gridcommand_get_origin(struct Cp437GridCommand */*notnull*/ command, + size_t */*notnull*/ origin_x, + size_t */*notnull*/ origin_y); + +/** + * Show text on the screen. + * + * The text is sent in the form of a 2D grid of [CP-437] encoded characters. + * + * The origin is relative to the top-left of the display. + * + * This function is part of the `cp437gridcommand` module. + */ +struct Cp437GridCommand */*notnull*/ sp_cp437gridcommand_new(Cp437Grid */*notnull*/ grid, + size_t origin_x, + size_t origin_y); + +/** + * Calls method [`servicepoint::Cp437GridCommand::set_grid`]. + * + * Sets the value of field `grid` of the [`servicepoint::Cp437GridCommand`]. + * The provided value is moved into the instance, potentially invalidating previously taken references. + * + * This function is part of the `cp437gridcommand` module. + */ +void sp_cp437gridcommand_set_grid(struct Cp437GridCommand */*notnull*/ instance, + Cp437Grid */*notnull*/ value); + +/** + * Calls method [`servicepoint::Cp437GridCommand::set_origin`]. + * + * Overwrites the origin field of the [`Cp437GridCommand`]. + * + * This function is part of the `cp437gridcommand` module. + */ +void sp_cp437gridcommand_set_origin(struct Cp437GridCommand */*notnull*/ command, + size_t origin_x, + size_t origin_y); + +/** + * Calls method [`servicepoint::Cp437GridCommand::try_into_packet`]. + * + *Tries to turn a [`Cp437GridCommand`] into a [Packet]. + * + * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the `cp437gridcommand` module. + */ +struct Packet *sp_cp437gridcommand_try_into_packet(struct Cp437GridCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::DisplayBitVec::as_raw_mut_slice`]. + * + * Gets an unsafe reference to the data of the [DisplayBitVec] instance. + * + * The returned memory is valid for the lifetime of the bitvec. + * + * This function is part of the `displaybitvec` module. + */ +struct ByteSlice sp_displaybitvec_as_raw_mut_slice(DisplayBitVec */*notnull*/ instance); + +/** + * Calls method [`servicepoint::DisplayBitVec::clone`]. + * + *Clones a [`DisplayBitVec`] instance. + * + * This function is part of the `displaybitvec` module. + */ +DisplayBitVec */*notnull*/ sp_displaybitvec_clone(DisplayBitVec */*notnull*/ instance); + +/** + * Calls method [`servicepoint::DisplayBitVec::fill`]. + * + * Sets the value of all bits. + * + * # Arguments + * + * - `value`: the value to set all bits to + * + * This function is part of the `displaybitvec` module. + */ +void sp_displaybitvec_fill(DisplayBitVec */*notnull*/ instance, bool value); + +/** + * Calls method [`servicepoint::DisplayBitVec::free`]. + * + *Deallocates a [`DisplayBitVec`] instance. + * + * This function is part of the `displaybitvec` module. + */ +void sp_displaybitvec_free(DisplayBitVec */*notnull*/ instance); + +/** + * Calls method [`servicepoint::DisplayBitVec::get`]. + * + * Gets the value of a bit. + * + * # Arguments + * + * - `bit_vec`: instance to read from + * - `index`: the bit index to read + * + * returns: value of the bit + * + * # Panics + * + * - when accessing `index` out of bounds + * + * This function is part of the `displaybitvec` module. + */ +bool sp_displaybitvec_get(DisplayBitVec */*notnull*/ instance, size_t index); + +/** + * Calls method [`servicepoint::DisplayBitVec::is_empty`]. + * + * Returns true if length is 0. + * + * This function is part of the `displaybitvec` module. + */ +bool sp_displaybitvec_is_empty(DisplayBitVec */*notnull*/ instance); + +/** + * Calls method [`servicepoint::DisplayBitVec::len`]. + * + * Gets the length in bits. + * + * This function is part of the `displaybitvec` module. + */ +size_t sp_displaybitvec_len(DisplayBitVec */*notnull*/ instance); + +/** + * Interpret the data as a series of bits and load then into a new [DisplayBitVec] instance. + * + * returns: [DisplayBitVec] instance containing data. + * + * This function is part of the `displaybitvec` module. + */ +DisplayBitVec */*notnull*/ sp_displaybitvec_load(struct ByteSlice data); + +/** + * Creates a new [DisplayBitVec] instance. + * + * # Arguments + * + * - `size`: size in bits. + * + * returns: [DisplayBitVec] with all bits set to false. + * + * # Panics + * + * - when `size` is not divisible by 8. + * + * This function is part of the `displaybitvec` module. + */ +DisplayBitVec */*notnull*/ sp_displaybitvec_new(size_t size); + +/** + * Calls method [`servicepoint::DisplayBitVec::set`]. + * + * Sets the value of a bit. + * + * # Arguments + * + * - `index`: the bit index to edit + * - `value`: the value to set the bit to + * + * # Panics + * + * - when accessing `index` out of bounds + * + * This function is part of the `displaybitvec` module. + */ +void sp_displaybitvec_set(DisplayBitVec */*notnull*/ instance, + size_t index, + bool value); + +/** + * Calls method [`servicepoint::DisplayBitVec::try_into_packet`]. + * + * Creates a [BitVecCommand] and immediately turns that into a [Packet]. + * + * The provided [DisplayBitVec] gets consumed. + * + * Returns NULL in case of an error. + * + * This function is part of the `displaybitvec` module. + */ +struct Packet *sp_displaybitvec_try_into_packet(DisplayBitVec */*notnull*/ bitvec, + size_t offset, + BinaryOperation operation, + CompressionCode compression); /** * Call this function at the beginning of main to enable rust logging controlled by the * `RUST_LOG` environment variable. See [env_logger](https://docs.rs/env_logger/latest/env_logger/). * - * This function is part of the sp_envlogger module. + * This function is part of the `envlogger` module. */ void sp_envlogger_init(void); /** + * Calls method [`servicepoint::FadeOutCommand::clone`]. + * + *Clones a [`FadeOutCommand`] instance. + * + * This function is part of the `fadeoutcommand` module. + */ +struct FadeOutCommand */*notnull*/ sp_fadeoutcommand_clone(struct FadeOutCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::FadeOutCommand::free`]. + * + *Deallocates a [`FadeOutCommand`] instance. + * + * This function is part of the `fadeoutcommand` module. + */ +void sp_fadeoutcommand_free(struct FadeOutCommand */*notnull*/ instance); + +/** + * A yet-to-be-tested command. + * + * Returns: a new [`FadeOutCommand`] instance. + * + * This function is part of the `fadeoutcommand` module. + */ +struct FadeOutCommand */*notnull*/ sp_fadeoutcommand_new(void); + +/** + * Calls method [`servicepoint::FadeOutCommand::try_into_packet`]. + * + *Tries to turn a [`FadeOutCommand`] into a [Packet]. + * + * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the `fadeoutcommand` module. + */ +struct Packet *sp_fadeoutcommand_try_into_packet(struct FadeOutCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::GenericCommand::clone`]. + * + *Clones a [`GenericCommand`] instance. + * + * This function is part of the `genericcommand` module. + */ +struct GenericCommand */*notnull*/ sp_genericcommand_clone(struct GenericCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::GenericCommand::free`]. + * + *Deallocates a [`GenericCommand`] instance. + * + * This function is part of the `genericcommand` module. + */ +void sp_genericcommand_free(struct GenericCommand */*notnull*/ instance); + +/** + * Tries to turn a [Packet] into a [GenericCommand]. + * + * The packet is dropped in the process. + * + * Returns: pointer to new [GenericCommand] instance or NULL if parsing failed. + * + * This function is part of the `genericcommand` module. + */ +struct GenericCommand */*notnull*/ sp_genericcommand_try_from_packet(struct Packet */*notnull*/ packet); + +/** + * Calls method [`servicepoint::GenericCommand::try_into_packet`]. + * + * Tries to turn a [GenericCommand] into a [Packet]. + * The [GenericCommand] gets consumed. + * + * Returns tag [CommandTag::Invalid] in case of an error. + * + * This function is part of the `genericcommand` module. + */ +struct Packet *sp_genericcommand_try_into_packet(struct GenericCommand */*notnull*/ command); + +/** + * Calls method [`servicepoint::GlobalBrightnessCommand::clone`]. + * + *Clones a [`GlobalBrightnessCommand`] instance. + * + * This function is part of the `globalbrightnesscommand` module. + */ +struct GlobalBrightnessCommand */*notnull*/ sp_globalbrightnesscommand_clone(struct GlobalBrightnessCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::GlobalBrightnessCommand::free`]. + * + *Deallocates a [`GlobalBrightnessCommand`] instance. + * + * This function is part of the `globalbrightnesscommand` module. + */ +void sp_globalbrightnesscommand_free(struct GlobalBrightnessCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::GlobalBrightnessCommand::get_brightness`]. + * + * Gets the value of field `brightness` of the [`servicepoint::GlobalBrightnessCommand`]. + * + * This function is part of the `globalbrightnesscommand` module. + */ +Brightness sp_globalbrightnesscommand_get_brightness(struct GlobalBrightnessCommand */*notnull*/ instance); + +/** + * Set the brightness of all tiles to the same value. + * + * Returns: a new [GlobalBrightnessCommand] instance. + * + * This function is part of the `globalbrightnesscommand` module. + */ +struct GlobalBrightnessCommand */*notnull*/ sp_globalbrightnesscommand_new(Brightness brightness); + +/** + * Calls method [`servicepoint::GlobalBrightnessCommand::set_brightness`]. + * + * Sets the value of field `brightness` of the [`servicepoint::GlobalBrightnessCommand`]. + * + * This function is part of the `globalbrightnesscommand` module. + */ +void sp_globalbrightnesscommand_set_brightness(struct GlobalBrightnessCommand */*notnull*/ instance, + Brightness value); + +/** + * Calls method [`servicepoint::GlobalBrightnessCommand::try_into_packet`]. + * + *Tries to turn a [`GlobalBrightnessCommand`] into a [Packet]. + * + * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the `globalbrightnesscommand` module. + */ +struct Packet *sp_globalbrightnesscommand_try_into_packet(struct GlobalBrightnessCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::HardResetCommand::clone`]. + * + *Clones a [`HardResetCommand`] instance. + * + * This function is part of the `hardresetcommand` module. + */ +struct HardResetCommand */*notnull*/ sp_hardresetcommand_clone(struct HardResetCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::HardResetCommand::free`]. + * + *Deallocates a [`HardResetCommand`] instance. + * + * This function is part of the `hardresetcommand` module. + */ +void sp_hardresetcommand_free(struct HardResetCommand */*notnull*/ instance); + +/** + * Kills the udp daemon on the display, which usually results in a restart. + * + * Please do not send this in your normal program flow. + * + * Returns: a new [`HardResetCommand`] instance. + * + * This function is part of the `hardresetcommand` module. + */ +struct HardResetCommand */*notnull*/ sp_hardresetcommand_new(void); + +/** + * Calls method [`servicepoint::HardResetCommand::try_into_packet`]. + * + *Tries to turn a [`HardResetCommand`] into a [Packet]. + * + * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the `hardresetcommand` module. + */ +struct Packet *sp_hardresetcommand_try_into_packet(struct HardResetCommand */*notnull*/ instance); + +/** + * Calls method [`servicepoint::Packet::clone`]. + * *Clones a [`Packet`] instance. * - * This function is part of the sp_packet module. + * This function is part of the `packet` module. */ struct Packet */*notnull*/ sp_packet_clone(struct Packet */*notnull*/ instance); /** + * Calls method [`servicepoint::Packet::free`]. + * *Deallocates a [`Packet`] instance. * - * This function is part of the sp_packet module. + * This function is part of the `packet` module. */ void sp_packet_free(struct Packet */*notnull*/ instance); @@ -1971,65 +2161,77 @@ void sp_packet_free(struct Packet */*notnull*/ instance); * * returns: new instance. Will never return null. * - * This function is part of the sp_packet module. + * This function is part of the `packet` module. */ struct Packet */*notnull*/ sp_packet_from_parts(struct Header header, struct ByteSlice payload); /** + * Calls method [`servicepoint::Packet::get_header`]. + * * Gets the value of field `header` of the [`servicepoint::Packet`]. * - * This function is part of the sp_packet module. + * This function is part of the `packet` module. */ struct Header sp_packet_get_header(struct Packet */*notnull*/ instance); /** + * Calls method [`servicepoint::Packet::get_header_mut`]. + * * Gets a reference to the field `header` of the [`servicepoint::Packet`]. * * - The returned reference inherits the lifetime of object in which it is contained. * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command. * - * This function is part of the sp_packet module. + * This function is part of the `packet` module. */ struct Header */*notnull*/ sp_packet_get_header_mut(struct Packet */*notnull*/ instance); /** + * Calls method [`servicepoint::Packet::get_payload`]. + * * Returns a pointer to the current payload of the provided packet. * * Returns an [ByteSlice::INVALID] instance in case the packet does not have any payload. * * The returned memory can be changed and will be valid until a new payload is set. * - * This function is part of the sp_packet module. + * This function is part of the `packet` module. */ struct ByteSlice sp_packet_get_payload(struct Packet */*notnull*/ packet); /** + * Calls method [`servicepoint::Packet::serialize_to`]. + * * Serialize the packet into the provided buffer. * * # Panics * * - if the buffer is not big enough to hold header+payload. * - * This function is part of the sp_packet module. + * This function is part of the `packet` module. */ size_t sp_packet_serialize_to(struct Packet */*notnull*/ packet, struct ByteSlice buffer); /** + * Calls method [`servicepoint::Packet::set_header`]. + * * Sets the value of field `header` of the [`servicepoint::Packet`]. * - * This function is part of the sp_packet module. + * This function is part of the `packet` module. */ void sp_packet_set_header(struct Packet */*notnull*/ instance, struct Header value); /** + * Calls method [`servicepoint::Packet::set_payload`]. + * * Sets the payload of the provided packet to the provided data. * * This makes previous payload pointers invalid. * - * This function is part of the sp_packet module. + * This function is part of the `packet` module. */ void sp_packet_set_payload(struct Packet */*notnull*/ packet, struct ByteSlice data); @@ -2039,7 +2241,7 @@ void sp_packet_set_payload(struct Packet */*notnull*/ packet, * * returns: NULL in case of an error, pointer to the allocated packet otherwise * - * This function is part of the sp_packet module. + * This function is part of the `packet` module. */ struct Packet *sp_packet_try_load(struct ByteSlice data); @@ -2048,17 +2250,19 @@ struct Packet *sp_packet_try_load(struct ByteSlice data); * * If the provided value is not valid, false is returned and result is not changed. * - * This function is part of the sp module. + * This function is part of the `sp` module. */ -bool sp_u16_to_command_code(uint16_t code, - CommandCode *result); +bool sp_sp_u16_to_command_code(uint16_t code, + CommandCode */*notnull*/ result); /** + * Calls method [`servicepoint::UdpSocket::free`]. + * *Deallocates a [`UdpSocket`] instance. * - * This function is part of the sp_udp module. + * This function is part of the `udpsocket` module. */ -void sp_udp_free(struct UdpSocket */*notnull*/ instance); +void sp_udpsocket_free(struct UdpSocket */*notnull*/ instance); /** * Creates a new instance of [UdpSocket]. @@ -2073,9 +2277,9 @@ void sp_udp_free(struct UdpSocket */*notnull*/ instance); * sp_udp_send_command(connection, sp_command_clear()); * ``` * - * This function is part of the sp_udp module. + * This function is part of the `udpsocket` module. */ -struct UdpSocket *sp_udp_open(char */*notnull*/ host); +struct UdpSocket *sp_udpsocket_open(char */*notnull*/ host); /** * Creates a new instance of [UdpSocket]. @@ -2090,16 +2294,18 @@ struct UdpSocket *sp_udp_open(char */*notnull*/ host); * sp_udp_send_command(connection, sp_command_clear()); * ``` * - * This function is part of the sp_udp module. + * This function is part of the `udpsocket` module. */ -struct UdpSocket *sp_udp_open_ipv4(uint8_t ip1, - uint8_t ip2, - uint8_t ip3, - uint8_t ip4, - uint16_t port); +struct UdpSocket *sp_udpsocket_open_ipv4(uint8_t ip1, + uint8_t ip2, + uint8_t ip3, + uint8_t ip4, + uint16_t port); /** - * Sends a [SPCommand] to the display using the [UdpSocket]. + * Calls method [`servicepoint::UdpSocket::send_command`]. + * + * Sends a [GenericCommand] to the display using the [UdpSocket]. * * The passed `command` gets consumed. * @@ -2111,12 +2317,14 @@ struct UdpSocket *sp_udp_open_ipv4(uint8_t ip1, * sp_udp_send_command(connection, sp_command_brightness(5)); * ``` * - * This function is part of the sp_udp module. + * This function is part of the `udpsocket` module. */ -bool sp_udp_send_command(struct UdpSocket */*notnull*/ connection, - struct Command command); +bool sp_udpsocket_send_command(struct UdpSocket */*notnull*/ connection, + struct GenericCommand */*notnull*/ command); /** + * Calls method [`servicepoint::UdpSocket::send_header`]. + * * Sends a [Header] to the display using the [UdpSocket]. * * returns: true in case of success @@ -2127,22 +2335,24 @@ bool sp_udp_send_command(struct UdpSocket */*notnull*/ connection, * sp_udp_send_header(connection, sp_command_brightness(5)); * ``` * - * This function is part of the sp_udp module. + * This function is part of the `udpsocket` module. */ -bool sp_udp_send_header(struct UdpSocket */*notnull*/ udp_connection, - struct Header header); +bool sp_udpsocket_send_header(struct UdpSocket */*notnull*/ udp_connection, + struct Header header); /** + * Calls method [`servicepoint::UdpSocket::send_packet`]. + * * Sends a [Packet] to the display using the [UdpSocket]. * * The passed `packet` gets consumed. * * returns: true in case of success * - * This function is part of the sp_udp module. + * This function is part of the `udpsocket` module. */ -bool sp_udp_send_packet(struct UdpSocket */*notnull*/ connection, - struct Packet */*notnull*/ packet); +bool sp_udpsocket_send_packet(struct UdpSocket */*notnull*/ connection, + struct Packet */*notnull*/ packet); #ifdef __cplusplus } // extern "C" diff --git a/src/commands/bitmap_command.rs b/src/commands/bitmap_command.rs index 68f6408..40fbc1c 100644 --- a/src/commands/bitmap_command.rs +++ b/src/commands/bitmap_command.rs @@ -1,56 +1,43 @@ use crate::{ - commands::wrap_origin_accessors, - macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, - mem::{heap_move_nonnull, heap_move_ok, heap_remove}, + commands::{wrap_command, wrap_origin_accessors}, + macros::{wrap_fields, wrap_functions}, }; -use servicepoint::{Bitmap, BitmapCommand, CompressionCode, Origin, Packet}; +use servicepoint::{Bitmap, BitmapCommand, CompressionCode, Origin}; use std::ptr::NonNull; -wrap_clone!(sp_cmd_bitmap::BitmapCommand); -wrap_free!(sp_cmd_bitmap::BitmapCommand); +wrap_command!(Bitmap); -wrap_fields!(sp_cmd_bitmap::BitmapCommand; - prop bitmap: Bitmap { mut get(); move set(value); }; - prop compression: CompressionCode { get(); set(value); }; +wrap_fields!(BitmapCommand; + prop bitmap: Bitmap { get mut; set move; }; + prop compression: CompressionCode { get; set; }; ); -wrap_origin_accessors!(sp_cmd_bitmap::BitmapCommand); +wrap_origin_accessors!(BitmapCommand); -wrap_functions!(sp_cmd_bitmap; +wrap_functions!(associate BitmapCommand; /// Sets a window of pixels to the specified values. /// /// The passed [Bitmap] gets consumed. /// /// Returns: a new [BitmapCommand] instance. fn new( - bitmap: NonNull, - origin_x: usize, - origin_y: usize, - compression: CompressionCode, - ) -> NonNull { - heap_move_nonnull(BitmapCommand { - bitmap: unsafe { heap_remove(bitmap) }, + bitmap: move NonNull, + origin_x: val usize, + origin_y: val usize, + compression: val CompressionCode, + ) -> move NonNull { + BitmapCommand { + bitmap, origin: Origin::new(origin_x, origin_y), compression, - }) - } + } + }; /// Move the provided [Bitmap] into a new [BitmapCommand], /// leaving other fields as their default values. /// /// Rust equivalent: `BitmapCommand::from(bitmap)` - fn from_bitmap( - bitmap: NonNull, - ) -> NonNull { - heap_move_nonnull(unsafe { heap_remove(bitmap) }.into()) - } - - /// Tries to turn a [BitmapCommand] into a [Packet]. - /// - /// Returns: NULL or a [Packet] containing the command. - fn try_into_packet( - command: NonNull, - ) -> *mut Packet { - heap_move_ok(unsafe { heap_remove(command) }.try_into()) - } + fn from_bitmap(bitmap: move NonNull) -> move NonNull { + bitmap.into() + }; ); diff --git a/src/commands/bitvec_command.rs b/src/commands/bitvec_command.rs index 6cec313..f62b492 100644 --- a/src/commands/bitvec_command.rs +++ b/src/commands/bitvec_command.rs @@ -1,25 +1,22 @@ use crate::{ - macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, - mem::{heap_move_nonnull, heap_move_ok, heap_remove}, + commands::wrap_command, + macros::{wrap_fields, wrap_functions}, }; use servicepoint::{ BinaryOperation, BitVecCommand, CompressionCode, DisplayBitVec, Offset, - Packet, }; use std::ptr::NonNull; -wrap_clone!(sp_cmd_bitvec::BitVecCommand); -wrap_free!(sp_cmd_bitvec::BitVecCommand); +wrap_command!(BitVec); -wrap_fields!(sp_cmd_bitvec::BitVecCommand; - prop bitvec: DisplayBitVec { mut get(); move set(value); }; - prop offset: Offset { get(); set(value); }; - prop operation: BinaryOperation { get(); set(value); }; - prop compression: CompressionCode { get(); set(value); }; +wrap_fields!(BitVecCommand; + prop bitvec: DisplayBitVec { get mut; set move; }; + prop offset: Offset { get; set; }; + prop operation: BinaryOperation { get; set; }; + prop compression: CompressionCode { get; set; }; ); -wrap_functions!(sp_cmd_bitvec; - +wrap_functions!(associate BitVecCommand; /// Set pixel data starting at the pixel offset on screen. /// /// The screen will continuously overwrite more pixel data without regarding the offset, meaning @@ -33,26 +30,16 @@ wrap_functions!(sp_cmd_bitvec; /// /// The contained [`DisplayBitVec`] is always uncompressed. fn new( - bitvec: NonNull, - offset: usize, - operation: BinaryOperation, - compression: CompressionCode, - ) -> NonNull { - heap_move_nonnull(BitVecCommand { - bitvec: unsafe { heap_remove(bitvec) }, + bitvec: move NonNull, + offset: val usize, + operation: val BinaryOperation, + compression: val CompressionCode, + ) -> move NonNull { + BitVecCommand { + bitvec, offset, operation, compression, - }) - } - - /// Tries to turn a [BitVecCommand] into a [Packet]. - /// - /// Returns: NULL or a [Packet] containing the command. - fn try_into_packet( - command: NonNull, - ) -> *mut Packet { - heap_move_ok(unsafe { heap_remove(command) }.try_into()) - } - + } + }; ); diff --git a/src/commands/brightness_grid_command.rs b/src/commands/brightness_grid_command.rs index cc26b77..007d645 100644 --- a/src/commands/brightness_grid_command.rs +++ b/src/commands/brightness_grid_command.rs @@ -1,53 +1,38 @@ use crate::{ - commands::wrap_origin_accessors, - macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, - mem::{heap_move_nonnull, heap_move_ok, heap_remove}, + commands::{wrap_command, wrap_origin_accessors}, + macros::{wrap_fields, wrap_functions}, }; -use servicepoint::{BrightnessGrid, BrightnessGridCommand, Origin, Packet}; +use servicepoint::{BrightnessGrid, BrightnessGridCommand, Origin}; use std::ptr::NonNull; -wrap_clone!(sp_cmd_brightness_grid::BrightnessGridCommand); -wrap_free!(sp_cmd_brightness_grid::BrightnessGridCommand); +wrap_command!(BrightnessGrid); -wrap_fields!(sp_cmd_brightness_grid::BrightnessGridCommand; - prop grid: BrightnessGrid { mut get(); move set(grid); }; +wrap_fields!(BrightnessGridCommand; + prop grid: BrightnessGrid { get mut; set move; }; ); -wrap_origin_accessors!(sp_cmd_brightness_grid::BrightnessGridCommand); - -wrap_functions!(sp_cmd_brightness_grid; +wrap_origin_accessors!(BrightnessGridCommand); +wrap_functions!(associate BrightnessGridCommand; /// Set the brightness of individual tiles in a rectangular area of the display. /// /// The passed [BrightnessGrid] gets consumed. /// /// Returns: a new [BrightnessGridCommand] instance. fn new( - grid: NonNull, - origin_x: usize, - origin_y: usize, - ) -> NonNull { - heap_move_nonnull(BrightnessGridCommand { - grid: unsafe { heap_remove(grid) }, + grid: move NonNull, + origin_x: val usize, + origin_y: val usize + ) -> move NonNull { + BrightnessGridCommand { + grid, origin: Origin::new(origin_x, origin_y), - }) - } + } + }; /// Moves the provided [BrightnessGrid] into a new [BrightnessGridCommand], /// leaving other fields as their default values. - fn from_grid( - grid: NonNull, - ) -> NonNull { - heap_move_nonnull(unsafe { heap_remove(grid) }.into()) - } - - /// Tries to turn a [BrightnessGridCommand] into a [Packet]. - /// - /// Returns: NULL or a [Packet] containing the command. - fn into_packet( - command: NonNull, - ) -> *mut Packet { - heap_move_ok(unsafe { heap_remove(command) }.try_into()) - } - + fn from_grid(grid: move NonNull) -> move NonNull { + grid.into() + }; ); diff --git a/src/commands/cc_only_commands.rs b/src/commands/cc_only_commands.rs index f4162a0..ef49fa1 100644 --- a/src/commands/cc_only_commands.rs +++ b/src/commands/cc_only_commands.rs @@ -1,37 +1,38 @@ -use crate::{ - macros::{wrap_free, wrap_functions}, - mem::heap_move_nonnull, -}; +use crate::{commands::wrap_command, macros::wrap_functions}; use servicepoint::{ClearCommand, FadeOutCommand, HardResetCommand}; -use std::ptr::NonNull; macro_rules! wrap_cc_only { - ($prefix:ident :: $typ:ident ; $(#[$meta:meta])*) => { - wrap_functions!($prefix; - $(#[$meta])* - /// - #[doc = concat!(" Returns: a new [`",stringify!($typ),"`] instance.")] - fn new() -> NonNull<$typ> { - heap_move_nonnull($typ) - } - ); + ($(#[$meta:meta])* $command:ident) => { + ::paste::paste!{ + wrap_command!($command); - wrap_free!($prefix :: $typ); + wrap_functions!(associate [< $command Command >]; + $(#[$meta])* + /// + #[doc = " Returns: a new [`" [< $command Command >] "`] instance."] + fn new() -> move ::core::ptr::NonNull<[< $command Command >]> { + [< $command Command >] + }; + ); + } }; } -wrap_cc_only!(sp_cmd_clear::ClearCommand; +wrap_cc_only!( /// Set all pixels to the off state. /// /// Does not affect brightness. + Clear ); -wrap_cc_only!(sp_cmd_hard_reset::HardResetCommand; +wrap_cc_only!( /// Kills the udp daemon on the display, which usually results in a restart. /// /// Please do not send this in your normal program flow. + HardReset ); -wrap_cc_only!(sp_cmd_fade_out::FadeOutCommand; +wrap_cc_only!( /// A yet-to-be-tested command. + FadeOut ); diff --git a/src/commands/char_grid_command.rs b/src/commands/char_grid_command.rs index fe97dc0..06f2070 100644 --- a/src/commands/char_grid_command.rs +++ b/src/commands/char_grid_command.rs @@ -1,53 +1,38 @@ use crate::{ - commands::wrap_origin_accessors, - macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, - mem::{heap_move_nonnull, heap_move_ok, heap_remove}, + commands::{wrap_command, wrap_origin_accessors}, + macros::{wrap_fields, wrap_functions}, }; -use servicepoint::{CharGrid, CharGridCommand, Origin, Packet}; +use servicepoint::{CharGrid, CharGridCommand, Origin}; use std::ptr::NonNull; -wrap_clone!(sp_cmd_char_grid::CharGridCommand); -wrap_free!(sp_cmd_char_grid::CharGridCommand); +wrap_command!(CharGrid); -wrap_fields!(sp_cmd_char_grid::CharGridCommand; - prop grid: CharGrid { mut get(); move set(grid); }; +wrap_fields!(CharGridCommand; + prop grid: CharGrid { get mut; set move; }; ); -wrap_origin_accessors!(sp_cmd_char_grid::CharGridCommand); - -wrap_functions!(sp_cmd_char_grid; +wrap_origin_accessors!(CharGridCommand); +wrap_functions!(associate CharGridCommand; /// Show UTF-8 encoded text on the screen. /// /// The passed [CharGrid] gets consumed. /// /// Returns: a new [CharGridCommand] instance. fn new( - grid: NonNull, - origin_x: usize, - origin_y: usize, - ) -> NonNull { - heap_move_nonnull(CharGridCommand { - grid: unsafe { heap_remove(grid) }, + grid: move NonNull, + origin_x: val usize, + origin_y: val usize, + ) -> move NonNull { + CharGridCommand { + grid, origin: Origin::new(origin_x, origin_y), - }) - } + } + }; /// Moves the provided [CharGrid] into a new [CharGridCommand], /// leaving other fields as their default values. - fn from_grid( - grid: NonNull, - ) -> NonNull { - heap_move_nonnull(unsafe { heap_remove(grid) }.into()) - } - - /// Tries to turn a [CharGridCommand] into a [Packet]. - /// - /// Returns: NULL or a [Packet] containing the command. - fn try_into_packet( - command: NonNull, - ) -> *mut Packet { - heap_move_ok(unsafe { heap_remove(command) }.try_into()) - } - + fn from_grid(grid: move NonNull) -> move NonNull { + grid.into() + }; ); diff --git a/src/commands/cp437_grid_command.rs b/src/commands/cp437_grid_command.rs index 25294bb..d4c0e88 100644 --- a/src/commands/cp437_grid_command.rs +++ b/src/commands/cp437_grid_command.rs @@ -1,53 +1,38 @@ use crate::{ - commands::wrap_origin_accessors, - macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, - mem::{heap_move_nonnull, heap_move_ok, heap_remove}, + commands::{wrap_command, wrap_origin_accessors}, + macros::{wrap_fields, wrap_functions}, }; -use servicepoint::{Cp437Grid, Cp437GridCommand, Origin, Packet}; +use servicepoint::{Cp437Grid, Cp437GridCommand, Origin}; use std::ptr::NonNull; -wrap_clone!(sp_cmd_cp437_grid::Cp437GridCommand); -wrap_free!(sp_cmd_cp437_grid::Cp437GridCommand); +wrap_command!(Cp437Grid); -wrap_fields!(sp_cmd_cp437_grid::Cp437GridCommand; - prop grid: Cp437Grid { mut get(); move set(grid); }; +wrap_fields!(Cp437GridCommand; + prop grid: Cp437Grid { get mut; set move; }; ); -wrap_origin_accessors!(sp_cmd_cp437_grid::Cp437GridCommand); - -wrap_functions!(sp_cmd_cp437_grid; +wrap_origin_accessors!(Cp437GridCommand); +wrap_functions!(associate Cp437GridCommand; /// Show text on the screen. /// /// The text is sent in the form of a 2D grid of [CP-437] encoded characters. /// /// The origin is relative to the top-left of the display. fn new( - grid: NonNull, - origin_x: usize, - origin_y: usize, - ) -> NonNull { - heap_move_nonnull(Cp437GridCommand { - grid: unsafe { heap_remove(grid) }, + grid: move NonNull, + origin_x: val usize, + origin_y: val usize, + ) -> move NonNull { + Cp437GridCommand { + grid, origin: Origin::new(origin_x, origin_y), - }) - } + } + }; /// Moves the provided [Cp437Grid] into a new [Cp437GridCommand], /// leaving other fields as their default values. - fn from_grid( - grid: NonNull, - ) -> NonNull { - heap_move_nonnull(unsafe { heap_remove(grid) }.into()) - } - - /// Tries to turn a [Cp437GridCommand] into a [Packet]. - /// - /// Returns: NULL or a [Packet] containing the command. - fn try_into_packet( - command: NonNull, - ) -> *mut Packet { - heap_move_ok(unsafe { heap_remove(command) }.try_into()) - } - + fn from_grid(grid: move NonNull) -> move NonNull { + grid.into() + }; ); diff --git a/src/commands/generic_command.rs b/src/commands/generic_command.rs index 9734d30..c6a1323 100644 --- a/src/commands/generic_command.rs +++ b/src/commands/generic_command.rs @@ -1,5 +1,5 @@ use crate::{ - macros::wrap_functions, + macros::{derive_clone, derive_free, wrap_functions, wrap_methods}, mem::{ heap_clone, heap_drop, heap_move, heap_move_nonnull, heap_move_ok, heap_remove, @@ -18,7 +18,7 @@ use std::ptr::{null_mut, NonNull}; pub union CommandUnion { pub null: *mut u8, pub bitmap: NonNull, - pub bitvec: NonNull, + pub bit_vec: NonNull, pub brightness_grid: NonNull, pub char_grid: NonNull, pub cp437_grid: NonNull, @@ -55,221 +55,214 @@ pub enum CommandTag { /// /// Rust equivalent: [TypedCommand]. #[repr(C)] -pub struct SPCommand { +pub struct GenericCommand { /// Specifies which kind of command struct is contained in `data` pub tag: CommandTag, /// The pointer to the command struct pub data: CommandUnion, } -impl SPCommand { - const INVALID: SPCommand = SPCommand { +impl GenericCommand { + pub(crate) const INVALID: GenericCommand = GenericCommand { tag: CommandTag::Invalid, data: CommandUnion { null: null_mut() }, }; } -wrap_functions!(sp_cmd_generic; +derive_clone!(GenericCommand); - /// Tries to turn a [Packet] into a [SPCommand]. +impl Clone for GenericCommand { + fn clone(&self) -> Self { + unsafe { + match self.tag { + CommandTag::Clear => GenericCommand { + tag: CommandTag::Clear, + data: CommandUnion { + clear: heap_clone(self.data.clear), + }, + }, + CommandTag::CharGrid => GenericCommand { + tag: CommandTag::CharGrid, + data: CommandUnion { + char_grid: heap_clone(self.data.char_grid), + }, + }, + CommandTag::Cp437Grid => GenericCommand { + tag: CommandTag::Cp437Grid, + data: CommandUnion { + cp437_grid: heap_clone(self.data.cp437_grid), + }, + }, + CommandTag::Bitmap => GenericCommand { + tag: CommandTag::Bitmap, + data: CommandUnion { + bitmap: heap_clone(self.data.bitmap), + }, + }, + CommandTag::GlobalBrightness => GenericCommand { + tag: CommandTag::GlobalBrightness, + data: CommandUnion { + global_brightness: heap_clone( + self.data.global_brightness, + ), + }, + }, + CommandTag::BrightnessGrid => GenericCommand { + tag: CommandTag::BrightnessGrid, + data: CommandUnion { + brightness_grid: heap_clone(self.data.brightness_grid), + }, + }, + CommandTag::BitVec => GenericCommand { + tag: CommandTag::BitVec, + data: CommandUnion { + bit_vec: heap_clone(self.data.bit_vec), + }, + }, + CommandTag::HardReset => GenericCommand { + tag: CommandTag::HardReset, + data: CommandUnion { + hard_reset: heap_clone(self.data.hard_reset), + }, + }, + CommandTag::FadeOut => GenericCommand { + tag: CommandTag::FadeOut, + data: CommandUnion { + fade_out: heap_clone(self.data.fade_out), + }, + }, + #[allow(deprecated)] + CommandTag::BitmapLegacy => GenericCommand { + tag: CommandTag::BitmapLegacy, + data: CommandUnion { + bitmap_legacy: heap_clone(self.data.bitmap_legacy), + }, + }, + CommandTag::Invalid => GenericCommand::INVALID, + } + } + } +} + +derive_free!(GenericCommand); + +impl Drop for GenericCommand { + fn drop(&mut self) { + unsafe { + match self.tag { + CommandTag::Invalid => (), + CommandTag::Bitmap => heap_drop(self.data.bitmap), + CommandTag::BitVec => heap_drop(self.data.bit_vec), + CommandTag::BrightnessGrid => { + heap_drop(self.data.brightness_grid) + } + CommandTag::CharGrid => heap_drop(self.data.char_grid), + CommandTag::Cp437Grid => heap_drop(self.data.cp437_grid), + CommandTag::GlobalBrightness => { + heap_drop(self.data.global_brightness) + } + CommandTag::Clear => heap_drop(self.data.clear), + CommandTag::HardReset => heap_drop(self.data.hard_reset), + CommandTag::FadeOut => heap_drop(self.data.fade_out), + CommandTag::BitmapLegacy => heap_drop(self.data.bitmap_legacy), + } + } + + *self = Self::INVALID; + } +} + +wrap_functions!(associate GenericCommand; + /// Tries to turn a [Packet] into a [GenericCommand]. /// /// The packet is dropped in the process. /// - /// Returns: pointer to new [SPCommand] instance or NULL if parsing failed. - fn try_from_packet( - packet: NonNull, - ) -> SPCommand { - let packet = *unsafe { Box::from_raw(packet.as_ptr()) }; + /// Returns: pointer to new [GenericCommand] instance or NULL if parsing failed. + fn try_from_packet(packet: move NonNull) -> move NonNull { servicepoint::TypedCommand::try_from(packet) .map(|value| match value { - TypedCommand::Clear(clear) => SPCommand { + TypedCommand::Clear(clear) => GenericCommand { tag: CommandTag::Clear, data: CommandUnion { clear: heap_move_nonnull(clear), }, }, - TypedCommand::CharGrid(char_grid) => SPCommand { + TypedCommand::CharGrid(char_grid) => GenericCommand { tag: CommandTag::CharGrid, data: CommandUnion { char_grid: heap_move_nonnull(char_grid), }, }, - TypedCommand::Cp437Grid(cp437_grid) => SPCommand { + TypedCommand::Cp437Grid(cp437_grid) => GenericCommand { tag: CommandTag::Cp437Grid, data: CommandUnion { cp437_grid: heap_move_nonnull(cp437_grid), }, }, - TypedCommand::Bitmap(bitmap) => SPCommand { + TypedCommand::Bitmap(bitmap) => GenericCommand { tag: CommandTag::Bitmap, data: CommandUnion { bitmap: heap_move_nonnull(bitmap), }, }, - TypedCommand::Brightness(global_brightness) => SPCommand { + TypedCommand::Brightness(global_brightness) => GenericCommand { tag: CommandTag::GlobalBrightness, data: CommandUnion { global_brightness: heap_move_nonnull(global_brightness), }, }, - TypedCommand::BrightnessGrid(brightness_grid) => SPCommand { + TypedCommand::BrightnessGrid(brightness_grid) => GenericCommand { tag: CommandTag::BrightnessGrid, data: CommandUnion { brightness_grid: heap_move_nonnull(brightness_grid), }, }, - TypedCommand::BitVec(bitvec) => SPCommand { + TypedCommand::BitVec(bitvec) => GenericCommand { tag: CommandTag::BitVec, data: CommandUnion { - bitvec: heap_move_nonnull(bitvec), + bit_vec: heap_move_nonnull(bitvec), }, }, - TypedCommand::HardReset(hard_reset) => SPCommand { + TypedCommand::HardReset(hard_reset) => GenericCommand { tag: CommandTag::HardReset, data: CommandUnion { hard_reset: heap_move_nonnull(hard_reset), }, }, - TypedCommand::FadeOut(fade_out) => SPCommand { + TypedCommand::FadeOut(fade_out) => GenericCommand { tag: CommandTag::FadeOut, data: CommandUnion { fade_out: heap_move_nonnull(fade_out), }, }, #[allow(deprecated)] - TypedCommand::BitmapLegacy(bitmap_legacy) => SPCommand { + TypedCommand::BitmapLegacy(bitmap_legacy) => GenericCommand { tag: CommandTag::BitmapLegacy, data: CommandUnion { bitmap_legacy: heap_move_nonnull(bitmap_legacy), }, }, }) - .unwrap_or_else(move |_| SPCommand { + .unwrap_or_else(move |_| GenericCommand { tag: CommandTag::Invalid, data: CommandUnion { null: null_mut() }, }) - } + }; +); - /// Clones an [SPCommand] instance. - /// - /// returns: a new [SPCommand] instance. - fn clone(command: SPCommand) -> SPCommand { - unsafe { - match command.tag { - CommandTag::Clear => SPCommand { - tag: CommandTag::Clear, - data: CommandUnion { - clear: heap_clone(command.data.clear), - }, - }, - CommandTag::CharGrid => SPCommand { - tag: CommandTag::CharGrid, - data: CommandUnion { - char_grid: heap_clone(command.data.char_grid), - }, - }, - CommandTag::Cp437Grid => SPCommand { - tag: CommandTag::Cp437Grid, - data: CommandUnion { - cp437_grid: heap_clone(command.data.cp437_grid), - }, - }, - CommandTag::Bitmap => SPCommand { - tag: CommandTag::Bitmap, - data: CommandUnion { - bitmap: heap_clone(command.data.bitmap), - }, - }, - CommandTag::GlobalBrightness => SPCommand { - tag: CommandTag::GlobalBrightness, - data: CommandUnion { - global_brightness: heap_clone( - command.data.global_brightness, - ), - }, - }, - CommandTag::BrightnessGrid => SPCommand { - tag: CommandTag::BrightnessGrid, - data: CommandUnion { - brightness_grid: heap_clone(command.data.brightness_grid), - }, - }, - CommandTag::BitVec => SPCommand { - tag: CommandTag::BitVec, - data: CommandUnion { - bitvec: heap_clone(command.data.bitvec), - }, - }, - CommandTag::HardReset => SPCommand { - tag: CommandTag::HardReset, - data: CommandUnion { - hard_reset: heap_clone(command.data.hard_reset), - }, - }, - CommandTag::FadeOut => SPCommand { - tag: CommandTag::FadeOut, - data: CommandUnion { - fade_out: heap_clone(command.data.fade_out), - }, - }, - #[allow(deprecated)] - CommandTag::BitmapLegacy => SPCommand { - tag: CommandTag::BitmapLegacy, - data: CommandUnion { - bitmap_legacy: heap_clone(command.data.bitmap_legacy), - }, - }, - CommandTag::Invalid => SPCommand::INVALID, - } - } - } - - /// Deallocates an [SPCommand]. - /// - /// Commands with an invalid `tag` do not have to be freed as the `data` pointer should be null. - /// - /// # Examples - /// - /// ```C - /// SPCommand c = sp_cmd_clear_into_generic(sp_cmd_clear_new()); - /// sp_command_free(c); - /// ``` - fn free(command: SPCommand) { - unsafe { - match command.tag { - CommandTag::Invalid => (), - CommandTag::Bitmap => heap_drop(command.data.bitmap), - CommandTag::BitVec => heap_drop(command.data.bitvec), - CommandTag::BrightnessGrid => { - heap_drop(command.data.brightness_grid) - } - CommandTag::CharGrid => heap_drop(command.data.char_grid), - CommandTag::Cp437Grid => heap_drop(command.data.cp437_grid), - CommandTag::GlobalBrightness => { - heap_drop(command.data.global_brightness) - } - CommandTag::Clear => heap_drop(command.data.clear), - CommandTag::HardReset => heap_drop(command.data.hard_reset), - CommandTag::FadeOut => heap_drop(command.data.fade_out), - CommandTag::BitmapLegacy => heap_drop(command.data.bitmap_legacy), - } - } - } - - /// Tries to turn a [SPCommand] into a [Packet]. - /// The [SPCommand] gets consumed. +wrap_methods! { GenericCommand; + /// Tries to turn a [GenericCommand] into a [Packet]. + /// The [GenericCommand] gets consumed. /// /// Returns tag [CommandTag::Invalid] in case of an error. - fn into_packet( - command: SPCommand, - ) -> *mut Packet { + fn try_into_packet(move command) -> val *mut Packet { match command.tag { CommandTag::Invalid => null_mut(), CommandTag::Bitmap => { heap_move_ok(unsafe { heap_remove(command.data.bitmap).try_into() }) } CommandTag::BitVec => { - heap_move_ok(unsafe { heap_remove(command.data.bitvec).try_into() }) + heap_move_ok(unsafe { heap_remove(command.data.bit_vec).try_into() }) } CommandTag::BrightnessGrid => heap_move_ok(unsafe { heap_remove(command.data.brightness_grid).try_into() @@ -296,6 +289,5 @@ wrap_functions!(sp_cmd_generic; heap_move(unsafe { heap_remove(command.data.bitmap_legacy).into() }) } } - } - -); + }; +} diff --git a/src/commands/global_brightness_command.rs b/src/commands/global_brightness_command.rs index 35bcbe0..6a883ab 100644 --- a/src/commands/global_brightness_command.rs +++ b/src/commands/global_brightness_command.rs @@ -1,33 +1,21 @@ use crate::{ - macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, - mem::{heap_move_nonnull, heap_remove}, + commands::wrap_command, + macros::{wrap_fields, wrap_functions}, }; -use servicepoint::{Brightness, GlobalBrightnessCommand, Packet}; +use servicepoint::{Brightness, GlobalBrightnessCommand}; use std::ptr::NonNull; -wrap_functions!(sp_cmd_brightness_global; - +wrap_functions!(associate GlobalBrightnessCommand; /// Set the brightness of all tiles to the same value. /// /// Returns: a new [GlobalBrightnessCommand] instance. - fn new(brightness: Brightness) -> NonNull { - heap_move_nonnull(GlobalBrightnessCommand::from(brightness)) - } - - /// Turns the command into a packet - fn into_packet(command: NonNull) -> NonNull { - heap_move_nonnull(unsafe { heap_remove(command) }.into()) - } - -); - -wrap_clone!(sp_cmd_brightness_global::GlobalBrightnessCommand); -wrap_free!(sp_cmd_brightness_global::GlobalBrightnessCommand); - -wrap_fields!( - sp_cmd_brightness_global::GlobalBrightnessCommand; - prop brightness: Brightness { - get(); - set(value); + fn new(brightness: val Brightness) -> move NonNull { + GlobalBrightnessCommand::from(brightness) }; ); + +wrap_command!(GlobalBrightness); + +wrap_fields!(GlobalBrightnessCommand; + prop brightness: Brightness { get; set; }; +); diff --git a/src/commands/mod.rs b/src/commands/mod.rs index a6fa74d..1d6e8ff 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -15,33 +15,76 @@ pub use cp437_grid_command::*; pub use generic_command::*; macro_rules! wrap_origin_accessors { - ( $prefix:ident :: $object_type:ty ) => { - $crate::macros::wrap_functions!($prefix; - #[doc = concat!(" Reads the origin field of the [`", stringify!($object_type), "`].")] - fn get_origin( - command: NonNull<$object_type>, - origin_x: NonNull, - origin_y: NonNull, - ) { - unsafe { - let origin = &command.as_ref().origin; - *origin_x.as_ptr() = origin.x; - *origin_y.as_ptr() = origin.y; - } - } + ( $object_type:ident ) => { + ::paste::paste! { + $crate::macros::wrap_methods!($object_type; + #[doc = " Reads the origin field of the [`" $object_type "`]."] + fn get_origin( + ref command, + origin_x: mut ::core::ptr::NonNull, + origin_y: mut ::core::ptr::NonNull + ) { + let origin = command.origin; + *origin_x = origin.x; + *origin_y = origin.y; + }; - #[doc = concat!(" Overwrites the origin field of the [`", stringify!($object_type), "`].")] - fn set_origin( - command: NonNull<$object_type>, - origin_x: usize, - origin_y: usize, - ) { - unsafe { - $crate::macros::nonnull_as_mut!(command).origin = ::servicepoint::Origin::new(origin_x, origin_y); - } - } - ); + #[doc = " Overwrites the origin field of the [`" $object_type "`]."] + fn set_origin(mut command, origin_x: val usize, origin_y: val usize) { + command.origin = ::servicepoint::Origin::new(origin_x, origin_y); + }; + ); + } }; } -pub(crate) use wrap_origin_accessors; +macro_rules! derive_command_from { + ($command:ident) => { + ::paste::paste! { + impl From<::servicepoint::[< $command Command >]> for $crate::commands::GenericCommand { + fn from(command: ::servicepoint::[< $command Command >]) -> Self { + Self { + tag: $crate::commands::CommandTag::$command, + data: $crate::commands::CommandUnion { + [< $command:snake >]: $crate::mem::heap_move_nonnull(command) + }, + } + } + } + } + }; +} + +macro_rules! derive_command_into_packet { + ($command_type:ident) => { + ::paste::paste! { + $crate::macros::wrap_method!($command_type; + #[doc = "Tries to turn a [`" $command_type "`] into a [Packet]."] + /// + /// Returns: NULL or a [Packet] containing the command. + fn try_into_packet(move instance) -> move_ok *mut ::servicepoint::Packet { + instance.try_into() + }; + ); + } + } +} + +macro_rules! wrap_command { + ($command:ident, $object_type:ident) => { + $crate::macros::derive_clone!($object_type); + $crate::macros::derive_free!($object_type); + $crate::commands::derive_command_from!($command); + $crate::commands::derive_command_into_packet!($object_type); + }; + ($command:ident) => { + ::paste::paste! { + $crate::commands::wrap_command!($command, [< $command Command >]); + } + }; +} + +pub(crate) use { + derive_command_from, derive_command_into_packet, wrap_command, + wrap_origin_accessors, +}; diff --git a/src/containers/bitmap.rs b/src/containers/bitmap.rs index 6d502d9..b6ed4f3 100644 --- a/src/containers/bitmap.rs +++ b/src/containers/bitmap.rs @@ -1,7 +1,6 @@ use crate::{ - containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_functions, wrap_methods}, - mem::{heap_move_nonnull, heap_move_ok, heap_move_some, heap_remove}, + containers::{wrap_grid, ByteSlice}, + macros::{wrap_functions, wrap_methods}, }; use servicepoint::{ Bitmap, BitmapCommand, CompressionCode, DataRef, DisplayBitVec, Grid, @@ -9,11 +8,9 @@ use servicepoint::{ }; use std::ptr::NonNull; -wrap_clone!(sp_bitmap::Bitmap); -wrap_free!(sp_bitmap::Bitmap); - -wrap_functions!(sp_bitmap; +wrap_grid!(Bitmap, bool); +wrap_functions!(associate Bitmap; /// Creates a new [Bitmap] with the specified dimensions. /// /// # Arguments @@ -37,16 +34,16 @@ wrap_functions!(sp_bitmap; /// sp_bitmap_set(grid, 0, 0, false); /// sp_bitmap_free(grid); /// ``` - fn new(width: usize, height: usize) -> *mut Bitmap { - heap_move_some(Bitmap::new(width, height)) - } + fn new(width: val usize, height: val usize) -> move_some *mut Bitmap { + Bitmap::new(width, height) + }; /// Creates a new [Bitmap] with a size matching the screen. /// /// returns: [Bitmap] initialized to all pixels off. - fn new_max_sized() -> NonNull { - heap_move_nonnull(Bitmap::max_sized()) - } + fn new_max_sized() -> move NonNull { + Bitmap::max_sized() + }; /// Loads a [Bitmap] with the specified dimensions from the provided data. /// @@ -57,13 +54,12 @@ wrap_functions!(sp_bitmap; /// /// returns: [Bitmap] that contains a copy of the provided data, or NULL in case of an error. fn load( - width: usize, - height: usize, - data: ByteSlice, - ) -> *mut Bitmap { - let data = unsafe { data.as_slice() }; - heap_move_ok(Bitmap::load(width, height, data)) - } + width: val usize, + height: val usize, + data: slice ByteSlice, + ) -> move_ok *mut Bitmap { + Bitmap::load(width, height, data) + }; /// Tries to convert the BitVec to a Bitmap. /// @@ -71,84 +67,34 @@ wrap_functions!(sp_bitmap; /// /// Returns NULL in case of error. fn from_bitvec( - width: usize, - bitvec: NonNull, - ) -> *mut Bitmap { - let bitvec = unsafe { heap_remove(bitvec) }; - heap_move_ok(Bitmap::from_bitvec(width, bitvec)) - } + width: val usize, + bitvec: move NonNull, + ) -> move_ok *mut Bitmap { + Bitmap::from_bitvec(width, bitvec) + }; +); + +wrap_methods!(Bitmap; /// Consumes the Bitmap and returns the contained BitVec. - fn into_bitvec( - bitmap: NonNull - ) -> NonNull { - let bitmap = unsafe { heap_remove(bitmap) }; - heap_move_nonnull(bitmap.into()) - } + fn into_bitvec(move bitmap) -> move NonNull { + bitmap.into() + }; /// Creates a [BitmapCommand] and immediately turns that into a [Packet]. /// /// The provided [Bitmap] gets consumed. /// /// Returns NULL in case of an error. - fn into_packet( - bitmap: NonNull, - x: usize, - y: usize, - compression: CompressionCode, - ) -> *mut Packet { - let bitmap = unsafe { heap_remove(bitmap) }; - heap_move_ok(Packet::try_from(BitmapCommand { + fn try_into_packet(move bitmap, x: val usize, y: val usize, compression: val CompressionCode) -> move_ok *mut Packet { + Packet::try_from(BitmapCommand { bitmap, origin: Origin::new(x, y), compression, - })) - } -); - -wrap_methods!( - sp_bitmap::Bitmap; - - /// Gets the current value at the specified position. - /// - /// # Arguments - /// - /// - `x` and `y`: position of the cell to read - /// - /// # Panics - /// - /// - when accessing `x` or `y` out of bounds - ref fn get(x: usize, y: usize) -> bool; - - /// Sets the value of the specified position. - /// - /// # Arguments - /// - /// - `x` and `y`: position of the cell - /// - `value`: the value to write to the cell - /// - /// # Panics - /// - /// - when accessing `x` or `y` out of bounds - mut fn set(x: usize, y: usize, value: bool); - - /// Sets the state of all pixels in the [Bitmap]. - /// - /// # Arguments - /// - /// - `value`: the value to set all pixels to - mut fn fill(value: bool); - - /// Gets the width in pixels. - ref fn width() -> usize; - - /// Gets the height in pixels. - ref fn height() -> usize; + }) + }; /// Gets an unsafe reference to the data of the [Bitmap] instance. /// /// The returned memory is valid for the lifetime of the bitmap. - mut fn data_ref_mut() -> ByteSlice { - - return(slice) { unsafe { ByteSlice::from_slice(slice) } }; - }; + fn data_ref_mut(mut instance) -> slice ByteSlice; ); diff --git a/src/containers/bitvec.rs b/src/containers/bitvec.rs index e232ab5..b16dd92 100644 --- a/src/containers/bitvec.rs +++ b/src/containers/bitvec.rs @@ -1,15 +1,15 @@ use crate::{ - containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_functions, wrap_methods}, - mem::{heap_move_nonnull, heap_move_ok, heap_remove}, + containers::{wrap_container, ByteSlice}, + macros::{wrap_functions, wrap_methods}, }; use servicepoint::{ BinaryOperation, BitVecCommand, CompressionCode, DisplayBitVec, Packet, }; use std::ptr::NonNull; -wrap_functions!(sp_bitvec; +wrap_container!(DisplayBitVec); +wrap_functions!(associate DisplayBitVec; /// Creates a new [DisplayBitVec] instance. /// /// # Arguments @@ -21,45 +21,37 @@ wrap_functions!(sp_bitvec; /// # Panics /// /// - when `size` is not divisible by 8. - fn new(size: usize) -> NonNull { - heap_move_nonnull(DisplayBitVec::repeat(false, size)) - } + fn new(size: val usize) -> move NonNull { + DisplayBitVec::repeat(false, size) + }; /// Interpret the data as a series of bits and load then into a new [DisplayBitVec] instance. /// /// returns: [DisplayBitVec] instance containing data. - fn load(data: ByteSlice) -> NonNull { - let data = unsafe { data.as_slice() }; - heap_move_nonnull(DisplayBitVec::from_slice(data)) - } + fn load(data: slice ByteSlice) -> move NonNull { + DisplayBitVec::from_slice(data) + }; +); +wrap_methods!(DisplayBitVec; /// Creates a [BitVecCommand] and immediately turns that into a [Packet]. /// /// The provided [DisplayBitVec] gets consumed. /// /// Returns NULL in case of an error. - fn into_packet( - bitvec: NonNull, - offset: usize, - operation: BinaryOperation, - compression: CompressionCode, - ) -> *mut Packet { - let bitvec = unsafe { heap_remove(bitvec) }; - heap_move_ok(Packet::try_from(BitVecCommand { + fn try_into_packet( + move bitvec, + offset: val usize, + operation: val BinaryOperation, + compression: val CompressionCode + ) -> move_ok *mut Packet { + Packet::try_from(BitVecCommand { bitvec, offset, operation, compression, - })) - } - -); - -wrap_clone!(sp_bitvec::DisplayBitVec); -wrap_free!(sp_bitvec::DisplayBitVec); - -wrap_methods!( - sp_bitvec::DisplayBitVec; + }) + }; /// Gets the value of a bit. /// @@ -73,11 +65,10 @@ wrap_methods!( /// # Panics /// /// - when accessing `index` out of bounds - ref fn get(index: usize) -> bool { - return(result) { result.map(|x| *x).unwrap_or(false) }; + fn get(ref instance, index: val usize) -> val bool { + instance.get(index).map(|x| *x).unwrap_or(false) }; - /// Sets the value of a bit. /// /// # Arguments @@ -88,25 +79,23 @@ wrap_methods!( /// # Panics /// /// - when accessing `index` out of bounds - mut fn set(index: usize, value: bool); + fn set(mut instance, index: val usize, value: val bool); /// Sets the value of all bits. /// /// # Arguments /// /// - `value`: the value to set all bits to - mut fn fill(value: bool); + fn fill(mut instance, value: val bool); /// Gets the length in bits. - ref fn len() -> usize; + fn len(ref instance) -> val usize; /// Returns true if length is 0. - ref fn is_empty() -> bool; + fn is_empty(ref instance) -> val bool; /// Gets an unsafe reference to the data of the [DisplayBitVec] instance. /// /// The returned memory is valid for the lifetime of the bitvec. - mut fn as_raw_mut_slice() -> ByteSlice { - return(slice) { unsafe { ByteSlice::from_slice(slice) } }; - }; + fn as_raw_mut_slice(mut instance) -> slice ByteSlice; ); diff --git a/src/containers/brightness_grid.rs b/src/containers/brightness_grid.rs index 2374b47..19f6b7a 100644 --- a/src/containers/brightness_grid.rs +++ b/src/containers/brightness_grid.rs @@ -1,8 +1,6 @@ -use crate::macros::wrap_functions; use crate::{ - containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_methods}, - mem::{heap_move_nonnull, heap_move_ok, heap_move_some, heap_remove}, + containers::{wrap_grid, ByteSlice}, + macros::{wrap_functions, wrap_methods}, }; use servicepoint::{ Brightness, BrightnessGrid, BrightnessGridCommand, ByteGrid, DataRef, Grid, @@ -10,8 +8,9 @@ use servicepoint::{ }; use std::{mem::transmute, ptr::NonNull}; -wrap_functions!(sp_brightness_grid; +wrap_grid!(BrightnessGrid, Brightness); +wrap_functions!(associate BrightnessGrid; /// Creates a new [BrightnessGrid] with the specified dimensions. /// /// returns: [BrightnessGrid] initialized to 0. @@ -29,12 +28,9 @@ wrap_functions!(sp_brightness_grid; /// TypedCommand *command = sp_command_char_brightness(grid); /// sp_udp_free(connection); /// ``` - fn new( - width: usize, - height: usize, - ) -> NonNull { - heap_move_nonnull(BrightnessGrid::new(width, height)) - } + fn new(width: val usize, height: val usize) -> move NonNull { + BrightnessGrid::new(width, height) + }; /// Loads a [BrightnessGrid] with the specified dimensions from the provided data. /// @@ -42,90 +38,38 @@ wrap_functions!(sp_brightness_grid; /// /// returns: new [BrightnessGrid] instance, or NULL in case of an error. fn load( - width: usize, - height: usize, - data: ByteSlice, - ) -> *mut BrightnessGrid { - let data = unsafe { data.as_slice() }; - heap_move_some( - ByteGrid::load(width, height, data) - .map(move |grid| grid.map(Brightness::saturating_from)), - ) - } + width: val usize, + height: val usize, + data: slice ByteSlice, + ) -> move_some *mut BrightnessGrid { + ByteGrid::load(width, height, data) + .map(move |grid| grid.map(Brightness::saturating_from)) + }; +); +wrap_methods!(BrightnessGrid; /// Creates a [BrightnessGridCommand] and immediately turns that into a [Packet]. /// /// The provided [BrightnessGrid] gets consumed. /// /// Returns NULL in case of an error. - fn into_packet( - grid: NonNull, - x: usize, - y: usize, - ) -> *mut Packet { - let grid = unsafe { heap_remove(grid) }; - heap_move_ok(Packet::try_from(BrightnessGridCommand { + fn try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet { + Packet::try_from(BrightnessGridCommand { grid, origin: Origin::new(x, y), - })) - } - -); - -wrap_clone!(sp_brightness_grid::BrightnessGrid); -wrap_free!(sp_brightness_grid::BrightnessGrid); - -wrap_methods!( - sp_brightness_grid::BrightnessGrid; - - /// Gets the current value at the specified position. - /// - /// # Arguments - /// - /// - `x` and `y`: position of the cell to read - /// - /// returns: value at position - /// - /// # Panics - /// - When accessing `x` or `y` out of bounds. - ref fn get(x: usize, y: usize) -> Brightness; - - /// Sets the value of the specified position. - /// - /// # Arguments - /// - /// - `x` and `y`: position of the cell - /// - `value`: the value to write to the cell - /// - /// returns: old value of the cell - /// - /// # Panics - /// - /// - When accessing `x` or `y` out of bounds. - mut fn set(x: usize, y: usize, value: Brightness); - - /// Sets the value of all cells. - /// - /// # Arguments - /// - /// - `value`: the value to set all cells to - mut fn fill(value: Brightness); - - /// Gets the width of the grid. - ref fn width() -> usize; - - /// Gets the height of the grid. - ref fn height() -> usize; + }) + }; /// Gets an unsafe reference to the data of the instance. /// /// The returned memory is valid for the lifetime of the grid. - mut fn data_ref_mut() -> ByteSlice { - return(br_slice) { unsafe { - //noinspection RsAssertEqual - const _: () = assert!(size_of::() == 1); + fn data_ref_mut(mut instance) -> slice ByteSlice { + //noinspection RsAssertEqual + const _: () = assert!(size_of::() == 1); - ByteSlice::from_slice(transmute::<&mut [Brightness], &mut [u8]>(br_slice)) - }}; + let br_slice = instance.data_ref_mut(); + unsafe { + transmute::<&mut [Brightness], &mut [u8]>(br_slice) + } }; ); diff --git a/src/containers/byte_slice.rs b/src/containers/byte_slice.rs index 10ee22f..81380e9 100644 --- a/src/containers/byte_slice.rs +++ b/src/containers/byte_slice.rs @@ -26,15 +26,21 @@ pub struct ByteSlice { } impl ByteSlice { - pub(crate) const INVALID: ByteSlice = ByteSlice { + /// Represents an invalid [ByteSlice] instance. + pub const INVALID: ByteSlice = ByteSlice { start: std::ptr::null_mut(), length: 0, }; pub(crate) unsafe fn as_slice(&self) -> &[u8] { + assert!(!self.start.is_null()); unsafe { std::slice::from_raw_parts(self.start, self.length) } } + #[allow( + clippy::mut_from_ref, + reason = "This is used to get a pointer from the C side." + )] pub(crate) unsafe fn as_slice_mut(&self) -> &mut [u8] { unsafe { std::slice::from_raw_parts_mut(self.start, self.length) } } diff --git a/src/containers/char_grid.rs b/src/containers/char_grid.rs index 782e2aa..98a2c5b 100644 --- a/src/containers/char_grid.rs +++ b/src/containers/char_grid.rs @@ -1,13 +1,14 @@ use crate::{ - containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_functions, wrap_methods}, - mem::{heap_move_nonnull, heap_move_ok, heap_remove}, + containers::{derive_get_width_height, wrap_container, ByteSlice}, + macros::{wrap_functions, wrap_methods}, }; use servicepoint::{CharGrid, CharGridCommand, Grid, Origin, Packet}; use std::ptr::NonNull; -wrap_functions!(sp_char_grid; +wrap_container!(CharGrid); +derive_get_width_height!(CharGrid); +wrap_functions!(associate CharGrid; /// Creates a new [CharGrid] with the specified dimensions. /// /// returns: [CharGrid] initialized to 0. @@ -20,49 +21,19 @@ wrap_functions!(sp_char_grid; /// sp_char_grid_set(grid, 0, 0, '!'); /// sp_char_grid_free(grid); /// ``` - fn new( - width: usize, - height: usize, - ) -> NonNull { - heap_move_nonnull(CharGrid::new(width, height)) - } + fn new(width: val usize, height: val usize) -> move NonNull { + CharGrid::new(width, height) + }; /// Loads a [CharGrid] with the specified dimensions from the provided data. /// /// returns: new CharGrid or NULL in case of an error - fn load( - width: usize, - height: usize, - data: ByteSlice, - ) -> *mut CharGrid { - let data = unsafe { data.as_slice() }; - heap_move_ok(CharGrid::load_utf8(width, height, data.to_vec())) - } - - /// Creates a [CharGridCommand] and immediately turns that into a [Packet]. - /// - /// The provided [CharGrid] gets consumed. - /// - /// Returns NULL in case of an error. - fn into_packet( - grid: NonNull, - x: usize, - y: usize, - ) -> *mut Packet { - let grid = unsafe { heap_remove(grid) }; - heap_move_ok(Packet::try_from(CharGridCommand { - grid, - origin: Origin::new(x, y), - })) - } - + fn load(width: val usize, height: val usize, data: slice ByteSlice) -> move_ok *mut CharGrid { + CharGrid::load_utf8(width, height, data.to_vec()) + }; ); -wrap_clone!(sp_char_grid::CharGrid); -wrap_free!(sp_char_grid::CharGrid); - -wrap_methods!( - sp_char_grid::CharGrid; +wrap_methods!(CharGrid; /// Returns the current value at the specified position. /// @@ -73,8 +44,8 @@ wrap_methods!( /// # Panics /// /// - when accessing `x` or `y` out of bounds - ref fn get(x: usize, y: usize) -> u32 { - return(char) { char as u32 }; + fn get(ref instance, x: val usize, y: val usize) -> val u32 { + instance.get(x, y) as u32 }; /// Sets the value of the specified position in the grid. @@ -90,8 +61,8 @@ wrap_methods!( /// /// - when accessing `x` or `y` out of bounds /// - when providing values that cannot be converted to Rust's `char`. - mut fn set(x: usize, y: usize, value: u32) { - prepare(value) { char::from_u32(value).unwrap() }; + fn set(mut instance, x: val usize, y: val usize, value: val u32) { + instance.set(x, y, char::from_u32(value).unwrap()) }; /// Sets the value of all cells in the grid. @@ -100,13 +71,19 @@ wrap_methods!( /// /// - `value`: the value to set all cells to /// - when providing values that cannot be converted to Rust's `char`. - mut fn fill(value: u32) { - prepare(value) { char::from_u32(value).unwrap() }; + fn fill(mut instance, value: val u32) { + instance.fill(char::from_u32(value).unwrap()) }; - /// Gets the width of the grid. - ref fn width() -> usize; - - /// Gets the height of the grid. - ref fn height() -> usize; + /// Creates a [CharGridCommand] and immediately turns that into a [Packet]. + /// + /// The provided [CharGrid] gets consumed. + /// + /// Returns NULL in case of an error. + fn try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet { + Packet::try_from(CharGridCommand { + grid, + origin: Origin::new(x, y), + }) + }; ); diff --git a/src/containers/cp437_grid.rs b/src/containers/cp437_grid.rs index 2ed9aba..62f0eb2 100644 --- a/src/containers/cp437_grid.rs +++ b/src/containers/cp437_grid.rs @@ -1,103 +1,43 @@ -use crate::macros::wrap_functions; use crate::{ - containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_methods}, - mem::{heap_move_nonnull, heap_move_ok, heap_move_some, heap_remove}, + containers::{wrap_grid, ByteSlice}, + macros::{wrap_functions, wrap_methods}, }; use servicepoint::{ Cp437Grid, Cp437GridCommand, DataRef, Grid, Origin, Packet, }; use std::ptr::NonNull; -wrap_functions!(sp_cp437_grid; +wrap_grid!(Cp437Grid, u8); +wrap_functions!(associate Cp437Grid; /// Creates a new [Cp437Grid] with the specified dimensions. /// /// returns: [Cp437Grid] initialized to 0. - fn new( - width: usize, - height: usize, - ) -> NonNull { - heap_move_nonnull(Cp437Grid::new(width, height)) - } + fn new(width: val usize, height: val usize) -> move NonNull { + Cp437Grid::new(width, height) + }; /// Loads a [Cp437Grid] with the specified dimensions from the provided data. - fn load( - width: usize, - height: usize, - data: ByteSlice, - ) -> *mut Cp437Grid { - let data = unsafe { data.as_slice() }; - heap_move_some(Cp437Grid::load(width, height, data)) - } + fn load(width: val usize, height: val usize, data: slice ByteSlice) -> move_some *mut Cp437Grid { + Cp437Grid::load(width, height, data) + }; +); +wrap_methods!(Cp437Grid; /// Creates a [Cp437GridCommand] and immediately turns that into a [Packet]. /// /// The provided [Cp437Grid] gets consumed. /// /// Returns NULL in case of an error. - fn into_packet( - grid: NonNull, - x: usize, - y: usize, - ) -> *mut Packet { - let grid = unsafe { heap_remove(grid) }; - heap_move_ok(Packet::try_from(Cp437GridCommand { + fn try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet { + Packet::try_from(Cp437GridCommand { grid, origin: Origin::new(x, y), - })) - } - -); - -wrap_clone!(sp_cp437_grid::Cp437Grid); -wrap_free!(sp_cp437_grid::Cp437Grid); - -wrap_methods!( - sp_cp437_grid::Cp437Grid; - /// Gets the current value at the specified position. - /// - /// # Arguments - /// - /// - `x` and `y`: position of the cell to read - /// - /// # Panics - /// - /// - when accessing `x` or `y` out of bounds - ref fn get(x: usize, y: usize) -> u8; - - /// Sets the value at the specified position. - /// - /// # Arguments - /// - /// - `x` and `y`: position of the cell - /// - `value`: the value to write to the cell - /// - /// returns: old value of the cell - /// - /// # Panics - /// - /// - when accessing `x` or `y` out of bounds - mut fn set(x: usize, y: usize, value: u8); - - /// Sets the value of all cells in the grid. - /// - /// # Arguments - /// - /// - `cp437_grid`: instance to write to - /// - `value`: the value to set all cells to - mut fn fill(value: u8); - - /// Gets the width of the grid. - ref fn width() -> usize; - - /// Gets the height of the grid. - ref fn height() -> usize; + }) + }; /// Gets an unsafe reference to the data of the grid. /// /// The returned memory is valid for the lifetime of the instance. - mut fn data_ref_mut() -> ByteSlice { - return(slice) { unsafe { ByteSlice::from_slice(slice) } }; - }; + fn data_ref_mut(mut instance) -> slice ByteSlice; ); diff --git a/src/containers/mod.rs b/src/containers/mod.rs index 62d51d0..608d038 100644 --- a/src/containers/mod.rs +++ b/src/containers/mod.rs @@ -11,3 +11,68 @@ pub use brightness_grid::*; pub use byte_slice::*; pub use char_grid::*; pub use cp437_grid::*; + +macro_rules! wrap_container { + ($object_type:ident) => { + $crate::macros::derive_clone!($object_type); + $crate::macros::derive_free!($object_type); + }; +} + +macro_rules! derive_get_width_height { + ($object_type:ident) => { + $crate::macros::wrap_methods! {$object_type; + /// Gets the width. + fn width(ref instance) -> val usize; + + /// Gets the height. + fn height(ref instance) -> val usize; + } + }; +} + +macro_rules! wrap_grid { + ($object_type:ident, $value_type:ident) => { + $crate::containers::wrap_container!($object_type); + $crate::containers::derive_get_width_height!($object_type); + $crate::macros::wrap_methods! {$object_type; + /// Gets the current value at the specified position. + /// + /// # Arguments + /// + /// - `x` and `y`: position of the cell to read + /// + /// # Panics + /// + /// - when accessing `x` or `y` out of bounds + fn get(ref instance, x: val usize, y: val usize) -> val $value_type; + + /// Sets the value of the specified position. + /// + /// # Arguments + /// + /// - `x` and `y`: position of the cell + /// - `value`: the value to write to the cell + /// + /// # Panics + /// + /// - when accessing `x` or `y` out of bounds + fn set(mut instance, x: val usize, y: val usize, value: val $value_type); + + /// Sets the state of all cells in the grid. + /// + /// # Arguments + /// + /// - `value`: the value to set all cells to + fn fill(mut instance, value: val $value_type); + } + }; +} + +pub(crate) use {derive_get_width_height, wrap_container, wrap_grid}; + +mod _hidden { + /// This is a type only used by cbindgen to have a type for pointers. + #[allow(unused)] + pub struct DisplayBitVec; +} diff --git a/src/lib.rs b/src/lib.rs index 344a1a2..f884a83 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,8 +2,6 @@ //! //! # Examples //! -//! Make sure to check out [this GitHub repo](https://github.com/arfst23/ServicePoint) as well! -//! //! ```C //! #include //! #include "servicepoint.h" @@ -24,36 +22,32 @@ //! return 0; //! } //! ``` +//! +//! There are more examples in the source repository. /// Functions related to commands. pub mod commands; /// Functions related to [servicepoint::Bitmap], [servicepoint::CharGrid] and friends. pub mod containers; -mod macros; +pub(crate) mod macros; pub(crate) mod mem; -/// Functions related to [Packet]. +/// Functions related to [servicepoint::Packet]. pub mod packet; -/// Functions related to [UdpSocket]. +/// Functions related to [servicepoint::UdpSocketExt]. pub mod udp; /// Actual hardware limit is around 28-29ms/frame. Rounded up for less dropped packets. pub const SP_FRAME_PACING_MS: u128 = 30; -/// This is a type only used by cbindgen to have a type for pointers. -pub struct UdpSocket; - -/// This is a type only used by cbindgen to have a type for pointers. -pub struct DisplayBitVec; - #[cfg(feature = "env_logger")] mod feature_env_logger { use crate::macros::wrap_functions; - wrap_functions!(sp_envlogger; + wrap_functions!(envlogger; /// Call this function at the beginning of main to enable rust logging controlled by the /// `RUST_LOG` environment variable. See [env_logger](https://docs.rs/env_logger/latest/env_logger/). fn init() { env_logger::init(); - } + }; ); } diff --git a/src/macros.rs b/src/macros.rs index 4157f28..79cd3af 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,239 +1,270 @@ -macro_rules! wrap_free { - ($prefix:ident :: $typ:ty) => { - $crate::macros::wrap_functions!($prefix; - #[doc = concat!("Deallocates a [`", stringify!($typ), "`] instance.")] - fn free(instance: NonNull<$typ>) { - unsafe { $crate::mem::heap_drop(instance) } - } - ); +macro_rules! derive_free { + ($typ:ident) => { + ::paste::paste! { + $crate::macros::wrap_method!($typ; + #[doc = "Deallocates a [`" $typ "`] instance."] + #[allow(dropping_copy_types)] + fn free(move instance) { + ::std::mem::drop(instance) + }; + ); + } }; } -macro_rules! wrap_clone { - ($prefix:ident :: $typ:ty) => { - $crate::macros::wrap_functions!($prefix; - #[doc = concat!("Clones a [`", stringify!($typ), "`] instance.")] - fn clone(instance: NonNull<$typ>) -> NonNull<$typ> { - unsafe { $crate::mem::heap_clone(instance) } - } - ); +macro_rules! derive_clone { + ($object_type:ident) => { + ::paste::paste! { + $crate::macros::wrap_method!($object_type; + #[doc = "Clones a [`" $object_type "`] instance."] + fn clone(ref instance) -> move ::core::ptr::NonNull<$object_type> { + instance.clone() + }; + ); + } }; } -macro_rules! nonnull_as_ref { - ($ident:ident) => { - $ident.as_ref() +macro_rules! wrap_method { + ( + $object_type:ident; + $(#[$meta:meta])+ + fn $function:ident($ref_or_mut:ident $instance:ident $(, $($param_name:ident: $param_modifier:ident $param_type:ty),*)?) + $(-> $return_modifier:ident $return_type:ty)?; + ) => { + ::paste::paste!{ + $crate::macros::wrap_method!( + $object_type; + $(#[$meta])+ + fn $function($ref_or_mut $instance $(, $($param_name: $param_modifier $param_type),*)?) + $(-> $return_modifier $return_type)? { + $instance.$function($($($param_name),*)?) + }; + ); + } + }; + ($object_type:ident; + $(#[$meta:meta])+ + fn $function:ident($ref_or_mut:ident $instance:ident $(, $($param_name:ident: $param_modifier:ident $param_type:ty),*)?) + $(-> $return_modifier:ident $return_type:ty)? + $impl:block; + ) => { + paste::paste! { + $crate::macros::wrap_functions!([< $object_type:lower >]; + #[doc = " Calls method [`servicepoint::" $object_type "::" $function "`]."] + /// + $(#[$meta])* + fn $function( + $instance: $ref_or_mut ::core::ptr::NonNull<$object_type> + $(,$($param_name: $param_modifier $param_type),*)? + ) $(-> $return_modifier $return_type)? + $impl; + ); + } }; } -macro_rules! nonnull_as_mut { - ($ident:ident) => { - (&mut *$ident.as_ptr()) - }; -} - -// meta required on purpose, because otherwise the added documentation would suppress warnings macro_rules! wrap_methods { ( - $prefix:ident :: $object_type:ty; + $object_type:ident; $( $(#[$meta:meta])+ - $ref_or_mut:ident fn $function:ident($($param_name:ident: $param_type:ty),*) - $(-> $return_type:ty)? - $({ - $($(prepare($param_let_name:ident) $param_let_expr:block);+;)? - $(return($it:ident) $return_expr:block;)? - })? - ; + fn $function:ident($ref_or_mut:ident $instance:ident $(, $($param_name:ident: $param_modifier:ident $param_type:ty),*)?) + $(-> $return_modifier:ident $return_type:ty)? + $($impl:block)?; )+ ) => { paste::paste! { - $crate::macros::wrap_functions!($prefix; - $( - #[doc = concat!(" Calls [`servicepoint::", stringify!($object_type), - "::", stringify!($function), "`].")] - #[doc = ""] + $( + $crate::macros::wrap_method!($object_type; $(#[$meta])* - fn $function( - instance: NonNull<$object_type>, - $($param_name: $param_type),* - ) $(-> $return_type)? { - let instance = unsafe { $crate::macros:: [< nonnull_as_ $ref_or_mut >] !(instance) }; - $($( - $(let $param_let_name = $param_let_expr;)* - )?)? - #[allow( - unused_variables, - reason = "This variable may not be used depending on macro variables" )] - let result = instance.$function($($param_name),*); - $( - $( - let $it = result; - let result = $return_expr; - )? - )? - return result; - } - )+ + fn $function($ref_or_mut $instance $(, $($param_name: $param_modifier $param_type),*)?) + $(-> $return_modifier $return_type)? + $($impl)?; ); + )+ + } + }; +} + +macro_rules! wrap_fields_accessor { + (get; $object_type:ident :: $prop_name:ident : $prop_type:ty) => { + paste::paste! { + $crate::macros::wrap_method! {$object_type; + #[doc = " Gets the value of field `" $prop_name + "` of the [`servicepoint::" $object_type "`]."] + fn [](ref instance) -> val $prop_type { + instance.$prop_name + }; + } + } + }; + (mut get; $object_type:ident :: $prop_name:ident : $prop_type:ty) => { + paste::paste! { + $crate::macros::wrap_method! {$object_type; + #[doc = " Gets a reference to the field `" $prop_name + "` of the [`servicepoint::" $object_type "`]."] + /// + /// - The returned reference inherits the lifetime of object in which it is contained. + /// - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command. + fn [](mut instance) -> val ::core::ptr::NonNull<$prop_type> { + ::core::ptr::NonNull::from(&mut instance.$prop_name) + }; + } + } + }; + (set; $object_type:ident :: $prop_name:ident : $prop_type:ty) => { + paste::paste! { + $crate::macros::wrap_method! {$object_type; + #[doc = " Sets the value of field `" $prop_name + "` of the [`servicepoint::" $object_type "`]."] + fn [](mut instance, value: val $prop_type) { + instance.$prop_name = value; + }; + } + } + }; + (move set; $object_type:ident :: $prop_name:ident : $prop_type:ty) => { + paste::paste! { + $crate::macros::wrap_method! {$object_type; + #[doc = " Sets the value of field `" $prop_name + "` of the [`servicepoint::" $object_type "`]."] + /// The provided value is moved into the instance, potentially invalidating previously taken references. + fn [](mut instance, value: move ::core::ptr::NonNull<$prop_type>) { + instance.$prop_name = value; + }; + } } }; } macro_rules! wrap_fields { ( - $prefix:ident :: $object_type:ty; + $object_type:ident; $( - prop $prop_name:ident : $prop_type:ty { - $( - get() $({ - $(#[$get_meta:meta])* - $(return $get_expr:expr;)? - })?; - )? - - $( - mut get() $({ - $(#[$get_mut_meta:meta])* - $(return $get_mut_expr:expr;)? - })?; - )? - - $( - set($value:ident) - $({ - $(#[$set_meta:meta])* - $(return $set_expr:expr;)? - })?; - )? - - $( - move set( $set_move_value:ident) - $({ - $(#[$set_move_meta:meta])* - $(return $set_move_expr:expr;)? - })?; - )? - }; + prop $prop_name:ident : $prop_type:ty { $($accessor:ident $($modifier:ident)?;)+ }; )+ ) => { - paste::paste! { - $crate::macros::wrap_functions!($prefix; - $( - $( - #[doc = concat!(" Gets the value of field `", stringify!($prop_name), - "` of the [`servicepoint::", stringify!($object_type),"`].")] - $($( - #[doc = ""] - #[$get_meta] - )*)? - fn []( - instance: ::core::ptr::NonNull<$object_type> - ) -> $prop_type { - let $prop_name = unsafe { $crate::macros::nonnull_as_ref!(instance).$prop_name }; - $($( - let $prop_name = $get_expr; - )?)? - return $prop_name; - } - )? + $($( + ::paste::paste!{ + $crate::macros::wrap_fields_accessor! { + $($modifier)? $accessor; + $object_type :: $prop_name: $prop_type + } + } + )+)+ + }; +} - $( - #[doc = concat!(" Gets a reference to the field `", stringify!($prop_name), - "` of the [`servicepoint::",stringify!($object_type),"`].")] - $($( - #[doc = ""] - #[$get_mut_meta] - )*)? - #[doc = ""] - #[doc = " - The returned reference inherits the lifetime of object in which it is contained."] - #[doc = " - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command."] - fn []( - instance: ::core::ptr::NonNull<$object_type> - ) -> ::core::ptr::NonNull<$prop_type> { - let $prop_name = unsafe { &mut $crate::macros::nonnull_as_mut!(instance).$prop_name }; - $($( - let $prop_name = $get_mut_expr; - )?)? - return ::core::ptr::NonNull::from($prop_name); - } - )? +macro_rules! apply_param_modifier { + (move, $param_name:ident) => { + unsafe { $crate::mem::heap_remove($param_name) } + }; + (val, $param_name:ident) => { + $param_name + }; + (mut, $param_name:ident) => { + unsafe { (&mut *$param_name.as_ptr()) } + }; + (ref, $param_name:ident) => { + unsafe { $param_name.as_ref() } + }; + (slice, $param_name:ident) => { + unsafe { $param_name.as_slice() } + }; +} - $( - #[doc = concat!(" Sets the value of field `", stringify!($prop_name), - "` of the [`servicepoint::",stringify!($object_type),"`].")] - $($( - #[doc = ""] - #[$set_meta] - )*)? - fn []( - instance: ::core::ptr::NonNull<$object_type>, - value: $prop_type, - ) { - let instance = unsafe { $crate::macros::nonnull_as_mut!(instance) }; - $($( - let $value = value; - let value = $set_expr; - )?)? - instance.$prop_name = value; - } - )? +macro_rules! apply_return_modifier { + (val, $result:ident) => { + $result + }; + (move, $result:ident) => { + $crate::mem::heap_move_nonnull($result) + }; + (move_ok, $result:ident) => { + $crate::mem::heap_move_ok($result) + }; + (move_some, $result:ident) => { + $crate::mem::heap_move_some($result) + }; + (slice, $result:ident) => { + unsafe { ByteSlice::from_slice($result) } + }; +} +macro_rules! wrap_function { + ( + $module:ident; + $(#[$meta:meta])+ + fn $function:ident($($param_name:ident: $param_modifier:ident $param_type:ty),*$(,)?) + $(-> $return_modifier:ident $return_type:ty)? + $block:block; + ) => { + ::paste::paste! { + $(#[$meta])+ + #[doc = ""] + #[doc = " This function is part of the `" $module "` module."] + #[no_mangle] + pub unsafe extern "C" fn [< sp_ $module _ $function >]( + $($param_name: $param_type),* + ) $(-> $return_type)? + { $( - #[doc = concat!(" Sets the value of field `", stringify!($prop_name), - "` of the [`servicepoint::",stringify!($object_type),"`].")] - #[doc = concat!(" The provided value is moved into the instance, ", - "potentially invalidating previously taken references.")] - $($( - #[doc = ""] - #[$set_move_meta] - )*)? - fn []( - instance: ::core::ptr::NonNull<$object_type>, - value: NonNull<$prop_type>, - ) { - let instance = unsafe { $crate::macros::nonnull_as_mut!(instance) }; - let value = unsafe { $crate::mem::heap_remove(value) }; - $($( - let $set_move_value = value; - let value = $set_move_expr; - )?)? - instance.$prop_name = value; - } + let $param_name = $crate::macros::apply_param_modifier!($param_modifier, $param_name); + )* + let result = $block; + $( + let result = $crate::macros::apply_return_modifier!($return_modifier, result); )? - )+ - ); + result + } } }; } macro_rules! wrap_functions { ( - $prefix:ident; + $module:ident; $( $(#[$meta:meta])+ - fn $function:ident($($param_name:ident: $param_type:ty),*$(,)?) - $(-> $return_type:ty)? - $block:block + fn $function:ident($($param_name:ident: $param_modifier:ident $param_type:ty),*$(,)?) + $(-> $return_modifier:ident $return_type:ty)? + $block:block; )+ ) => { ::paste::paste! { $( - $(#[$meta])* - #[doc = ""] - #[doc = concat!(" This function is part of the ", stringify!($prefix), " module.")] - #[no_mangle] - pub unsafe extern "C" fn [<$prefix _ $function>]( - $($param_name: $param_type),* - ) $(-> $return_type)? - $block - + $crate::macros::wrap_function!($module; + $(#[$meta])+ + fn $function($($param_name: $param_modifier $param_type),*) $(-> $return_modifier $return_type)? + $block; + ); )+ } }; + ( + associate $object_type:ident; + $( + $(#[$meta:meta])+ + fn $function:ident($($param_name:ident: $param_modifier:ident $param_type:ty),*$(,)?) + $(-> $return_modifier:ident $return_type:ty)? + $block:block; + )+ + ) => { + ::paste::paste! { + $crate::macros::wrap_functions!{[< $object_type:lower >]; + $( + $(#[$meta])+ + fn $function($($param_name: $param_modifier $param_type),*) $(-> $return_modifier $return_type)? + $block; + )+ + } + } + }; } pub(crate) use { - nonnull_as_mut, nonnull_as_ref, wrap_clone, wrap_fields, wrap_free, - wrap_functions, wrap_methods, + apply_param_modifier, apply_return_modifier, derive_clone, derive_free, + wrap_fields, wrap_fields_accessor, wrap_function, wrap_functions, + wrap_method, wrap_methods, }; diff --git a/src/packet.rs b/src/packet.rs index 4278fe0..bec75e5 100644 --- a/src/packet.rs +++ b/src/packet.rs @@ -1,103 +1,89 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, - mem::{heap_move_nonnull, heap_move_ok}, + macros::{ + derive_clone, derive_free, wrap_fields, wrap_functions, wrap_methods, + }, }; use servicepoint::{CommandCode, Header, Packet}; use std::ptr::NonNull; -wrap_functions!(sp_packet; - +wrap_functions!(associate Packet; /// Tries to load a [Packet] from the passed array with the specified length. /// /// returns: NULL in case of an error, pointer to the allocated packet otherwise - fn try_load(data: ByteSlice) -> *mut Packet { - let data = unsafe { data.as_slice() }; - heap_move_ok(servicepoint::Packet::try_from(data)) - } + fn try_load(data: slice ByteSlice) -> move_ok *mut Packet { + servicepoint::Packet::try_from(data) + }; /// Creates a raw [Packet] from parts. /// /// returns: new instance. Will never return null. - fn from_parts(header: Header, payload: ByteSlice) -> NonNull { + fn from_parts(header: val Header, payload: val ByteSlice) -> move NonNull { let payload = if payload == ByteSlice::INVALID { None } else { Some(Vec::from(unsafe { payload.as_slice() })) }; - heap_move_nonnull(Packet { header, payload }) - } + Packet { header, payload } + }; +); +derive_clone!(Packet); +derive_free!(Packet); + +wrap_fields!(Packet; + prop header: Header { get; get mut; set; }; +); + +wrap_methods! { Packet; /// Returns a pointer to the current payload of the provided packet. /// /// Returns an [ByteSlice::INVALID] instance in case the packet does not have any payload. /// /// The returned memory can be changed and will be valid until a new payload is set. - fn get_payload(packet: NonNull) -> ByteSlice { - unsafe { - match &mut (*packet.as_ptr()).payload { - None => ByteSlice::INVALID, - Some(payload) => ByteSlice::from_slice(payload), - } + fn get_payload(mut packet) -> val ByteSlice { + match &mut packet.payload { + None => ByteSlice::INVALID, + Some(payload) => unsafe { ByteSlice::from_slice(payload) }, } - } + }; /// Sets the payload of the provided packet to the provided data. /// /// This makes previous payload pointers invalid. - fn set_payload(packet: NonNull, data: ByteSlice) { - unsafe { - (*packet.as_ptr()).payload = if data == ByteSlice::INVALID { - None - } else { - Some(data.as_slice().to_vec()) - } + fn set_payload(mut packet, data: val ByteSlice) { + packet.payload = if data == ByteSlice::INVALID { + None + } else { + Some(unsafe { data.as_slice().to_vec() }) } - } + }; /// Serialize the packet into the provided buffer. /// /// # Panics /// /// - if the buffer is not big enough to hold header+payload. - fn serialize_to(packet: NonNull, buffer: ByteSlice) -> usize { + fn serialize_to(mut packet, buffer: val ByteSlice) -> val usize { unsafe { - packet.as_ref().serialize_to(buffer.as_slice_mut()).unwrap_or(0) + packet.serialize_to(buffer.as_slice_mut()).unwrap_or(0) } - } -); - -wrap_clone!(sp_packet::Packet); -wrap_free!(sp_packet::Packet); - -wrap_fields!( - sp_packet::Packet; - prop header: Header { - get(); - mut get(); - set(value); }; -); +} wrap_functions!(sp; /// Converts u16 into [CommandCode]. /// /// If the provided value is not valid, false is returned and result is not changed. - fn u16_to_command_code( - code: u16, - result: *mut CommandCode, - ) -> bool { + fn u16_to_command_code(code: val u16, result: mut NonNull) -> val bool { match CommandCode::try_from(code) { Ok(code) => { - unsafe { - *result = code; - } + *result = code; true } Err(_) => false, } - } - + }; ); diff --git a/src/udp.rs b/src/udp.rs index cb96547..ba9b336 100644 --- a/src/udp.rs +++ b/src/udp.rs @@ -1,7 +1,7 @@ use crate::{ - commands::{CommandTag, SPCommand}, - macros::{wrap_free, wrap_functions}, - mem::{heap_move_ok, heap_remove}, + commands::{CommandTag, GenericCommand}, + macros::{derive_free, wrap_functions, wrap_methods}, + mem::heap_remove, }; use servicepoint::{Header, Packet, UdpSocketExt}; use std::{ @@ -10,10 +10,9 @@ use std::{ ptr::NonNull, }; -wrap_free!(sp_udp::UdpSocket); - -wrap_functions!(sp_udp; +derive_free!(UdpSocket); +wrap_functions!(associate UdpSocket; /// Creates a new instance of [UdpSocket]. /// /// returns: NULL if connection fails, or connected instance @@ -25,13 +24,12 @@ wrap_functions!(sp_udp; /// if (connection != NULL) /// sp_udp_send_command(connection, sp_command_clear()); /// ``` - fn open(host: NonNull) -> *mut UdpSocket { + fn open(host: val NonNull) -> move_ok *mut UdpSocket { let host = unsafe { CStr::from_ptr(host.as_ptr()) } .to_str() .expect("Bad encoding"); - - heap_move_ok(UdpSocket::bind_connect(host)) - } + UdpSocket::bind_connect(host) + }; /// Creates a new instance of [UdpSocket]. /// @@ -44,22 +42,23 @@ wrap_functions!(sp_udp; /// if (connection != NULL) /// sp_udp_send_command(connection, sp_command_clear()); /// ``` - fn open_ipv4(ip1: u8, ip2: u8, ip3: u8, ip4: u8, port: u16) -> *mut UdpSocket { + fn open_ipv4(ip1: val u8, ip2: val u8, ip3: val u8, ip4: val u8, port: val u16) -> move_ok *mut UdpSocket { let addr = SocketAddrV4::new(Ipv4Addr::from([ip1, ip2, ip3, ip4]), port); - heap_move_ok(UdpSocket::bind_connect(addr)) - } + UdpSocket::bind_connect(addr) + }; +); +wrap_methods! {UdpSocket; /// Sends a [Packet] to the display using the [UdpSocket]. /// /// The passed `packet` gets consumed. /// /// returns: true in case of success - fn send_packet(connection: NonNull, packet: NonNull) -> bool { - let packet = unsafe { heap_remove(packet) }; - unsafe { connection.as_ref().send(&Vec::from(packet)) }.is_ok() - } + fn send_packet(ref connection, packet: move NonNull) -> val bool { + connection.send(&Vec::from(packet)).is_ok() + }; - /// Sends a [SPCommand] to the display using the [UdpSocket]. + /// Sends a [GenericCommand] to the display using the [UdpSocket]. /// /// The passed `command` gets consumed. /// @@ -70,44 +69,25 @@ wrap_functions!(sp_udp; /// ```C /// sp_udp_send_command(connection, sp_command_brightness(5)); /// ``` - fn send_command(connection: NonNull, command: SPCommand) -> bool { + fn send_command(ref connection, command: mut NonNull) -> val bool { unsafe { - match command.tag { + let result = match command.tag { CommandTag::Invalid => return false, - CommandTag::Bitmap => connection - .as_ref() - .send_command(heap_remove(command.data.bitmap)), - CommandTag::BitVec => connection - .as_ref() - .send_command(heap_remove(command.data.bitvec)), - CommandTag::BrightnessGrid => connection - .as_ref() - .send_command(heap_remove(command.data.brightness_grid)), - CommandTag::CharGrid => connection - .as_ref() - .send_command(heap_remove(command.data.char_grid)), - CommandTag::Cp437Grid => connection - .as_ref() - .send_command(heap_remove(command.data.cp437_grid)), - CommandTag::GlobalBrightness => connection - .as_ref() - .send_command(heap_remove(command.data.global_brightness)), - CommandTag::Clear => connection - .as_ref() - .send_command(heap_remove(command.data.clear)), - CommandTag::HardReset => connection - .as_ref() - .send_command(heap_remove(command.data.hard_reset)), - CommandTag::FadeOut => connection - .as_ref() - .send_command(heap_remove(command.data.fade_out)), - CommandTag::BitmapLegacy => connection - .as_ref() - .send_command(heap_remove(command.data.bitmap_legacy)), - } + CommandTag::Bitmap => connection.send_command(heap_remove(command.data.bitmap)), + CommandTag::BitVec => connection.send_command(heap_remove(command.data.bit_vec)), + CommandTag::BrightnessGrid => connection.send_command(heap_remove(command.data.brightness_grid)), + CommandTag::CharGrid => connection.send_command(heap_remove(command.data.char_grid)), + CommandTag::Cp437Grid => connection.send_command(heap_remove(command.data.cp437_grid)), + CommandTag::GlobalBrightness => connection.send_command(heap_remove(command.data.global_brightness)), + CommandTag::Clear => connection.send_command(heap_remove(command.data.clear)), + CommandTag::HardReset => connection.send_command(heap_remove(command.data.hard_reset)), + CommandTag::FadeOut => connection.send_command(heap_remove(command.data.fade_out)), + CommandTag::BitmapLegacy => connection.send_command(heap_remove(command.data.bitmap_legacy)), + }.is_some(); + *command = GenericCommand::INVALID; + result } - .is_some() - } + }; /// Sends a [Header] to the display using the [UdpSocket]. /// @@ -118,14 +98,19 @@ wrap_functions!(sp_udp; /// ```C /// sp_udp_send_header(connection, sp_command_brightness(5)); /// ``` - fn send_header(udp_connection: NonNull, header: Header) -> bool { + fn send_header(ref udp_connection, header: val Header) -> val bool { let packet = Packet { header, payload: None, }; - unsafe { udp_connection.as_ref() } - .send(&Vec::from(packet)) - .is_ok() - } + udp_connection.send(&Vec::from(packet)).is_ok() + }; +} -); +mod _hidden { + /// This is a type only used by cbindgen to have a type for pointers. + /// + /// See [servicepoint::UdpSocketExt]. + #[allow(unused)] + pub struct UdpSocket; +}