diff --git a/example/Makefile b/example/Makefile index 15e53d1..0a56e1a 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/undefined.c + src/moving_line.c src/random_stuff.c src/wiping_clear.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 a0bdf9a..bfdc48f 100644 --- a/example/src/announce.c +++ b/example/src/announce.c @@ -3,27 +3,27 @@ int main(void) { sock_init(); - sp_udpsocket_send_header(sock, (Header) {.command_code = COMMAND_CODE_CLEAR}); + sp_udp_send_header(sock, (Header) {.command_code = COMMAND_CODE_CLEAR}); - CharGrid *grid = sp_chargrid_new(5, 2); + CharGrid *grid = sp_char_grid_new(5, 2); if (grid == NULL) return 1; - 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'); + 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'); - Packet *packet = sp_chargrid_try_into_packet(grid, 0, 0); + Packet *packet = sp_char_grid_into_packet(grid, 0, 0); if (packet == NULL) return 1; - sp_udpsocket_send_packet(sock, packet); + sp_udp_send_packet(sock, packet); return 0; } diff --git a/example/src/brightness_tester.c b/example/src/brightness_tester.c index 921bbd0..2257162 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_bitmapcommand_from_bitmap(all_on); - Packet *packet = sp_bitmapcommand_try_into_packet(bitmapCommand); + BitmapCommand *bitmapCommand = sp_cmd_bitmap_from_bitmap(all_on); + Packet *packet = sp_cmd_bitmap_try_into_packet(bitmapCommand); if (packet != NULL) - sp_udpsocket_send_packet(sock, packet); + sp_udp_send_packet(sock, packet); } void make_brightness_pattern(BrightnessGrid *grid) { - ByteSlice slice = sp_brightnessgrid_data_ref_mut(grid); + ByteSlice slice = sp_brightness_grid_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_brightnessgrid_new(TILE_WIDTH, TILE_HEIGHT); + BrightnessGrid *grid = sp_brightness_grid_new(TILE_WIDTH, TILE_HEIGHT); make_brightness_pattern(grid); - Packet *packet = sp_brightnessgridcommand_try_into_packet(sp_brightnessgridcommand_from_grid(grid)); + Packet *packet = sp_cmd_brightness_grid_into_packet(sp_cmd_brightness_grid_from_grid(grid)); if (packet == NULL) return -2; - sp_udpsocket_send_packet(sock, packet); + sp_udp_send_packet(sock, packet); return 0; } diff --git a/example/src/header_logger.c b/example/src/header_logger.c index 5793da9..9cb3cd1 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 GenericCommand *command) { - switch (command->tag) { +bool log_command(struct Command command) { + switch (command.tag) { case COMMAND_TAG_INVALID: { printf("-> this is an invalid command\n"); break; @@ -26,14 +26,14 @@ bool log_command(struct GenericCommand *command) { return true; } case COMMAND_TAG_BITMAP: { - BitmapCommand *bitmapCommand = command->data.bitmap; + BitmapCommand *bitmapCommand = command.data.bitmap; - CompressionCode compression = sp_bitmapcommand_get_compression(bitmapCommand); + CompressionCode compression = sp_cmd_bitmap_get_compression(bitmapCommand); size_t x, y; - sp_bitmapcommand_get_origin(bitmapCommand, &x, &y); + sp_cmd_bitmap_get_origin(bitmapCommand, &x, &y); - Bitmap *bitmap = sp_bitmapcommand_get_bitmap_mut(bitmapCommand); + Bitmap *bitmap = sp_cmd_bitmap_get(bitmapCommand); size_t w = sp_bitmap_width(bitmap); size_t h = sp_bitmap_height(bitmap); @@ -42,54 +42,54 @@ bool log_command(struct GenericCommand *command) { break; } case COMMAND_TAG_BRIGHTNESS_GRID: { - BrightnessGridCommand *gridCommand = command->data.brightness_grid; + BrightnessGridCommand *gridCommand = command.data.brightness_grid; size_t x, y; - sp_brightnessgridcommand_get_origin(gridCommand, &x, &y); + sp_cmd_brightness_grid_get_origin(gridCommand, &x, &y); - BrightnessGrid *grid = sp_brightnessgridcommand_get_grid_mut(gridCommand); - size_t w = sp_brightnessgrid_width(grid); - size_t h = sp_brightnessgrid_height(grid); + BrightnessGrid *grid = sp_cmd_brightness_grid_get(gridCommand); + size_t w = sp_brightness_grid_width(grid); + size_t h = sp_brightness_grid_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_chargridcommand_get_origin(gridCommand, &x, &y); + sp_cmd_char_grid_get_origin(gridCommand, &x, &y); - CharGrid *grid = sp_chargridcommand_get_grid_mut(gridCommand); - size_t w = sp_chargrid_width(grid); - size_t h = sp_chargrid_height(grid); + CharGrid *grid = sp_cmd_char_grid_get(gridCommand); + size_t w = sp_char_grid_width(grid); + size_t h = sp_char_grid_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_cp437gridcommand_get_origin(gridCommand, &x, &y); + sp_cmd_cp437_grid_get_origin(gridCommand, &x, &y); - Cp437Grid *grid = sp_cp437gridcommand_get_grid_mut(gridCommand); - size_t w = sp_cp437grid_width(grid); - size_t h = sp_cp437grid_height(grid); + Cp437Grid *grid = sp_cmd_cp437_grid_get(gridCommand); + size_t w = sp_cp437_grid_width(grid); + size_t h = sp_cp437_grid_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.bit_vec; + BitVecCommand *bitvecCommand = command.data.bitvec; - size_t offset = sp_bitveccommand_get_offset(bitvecCommand); - CompressionCode compression = sp_bitveccommand_get_compression(bitvecCommand); + size_t offset = sp_cmd_bitvec_get_offset(bitvecCommand); + CompressionCode compression = sp_cmd_bitvec_get_compression(bitvecCommand); - BinaryOperation operation = sp_bitveccommand_get_operation(bitvecCommand); + BinaryOperation operation = sp_cmd_bitvec_get_operation(bitvecCommand); char *operationText; switch (operation) { case BINARY_OPERATION_AND: @@ -109,8 +109,8 @@ bool log_command(struct GenericCommand *command) { break; } - DisplayBitVec *bitvec = sp_bitveccommand_get_bitvec_mut(bitvecCommand); - size_t len = sp_displaybitvec_len(bitvec); + BitVec *bitvec = sp_cmd_bitvec_get(bitvecCommand); + size_t len = sp_bitvec_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 GenericCommand *command) { break; } case COMMAND_TAG_GLOBAL_BRIGHTNESS: { - Brightness brightness = sp_globalbrightnesscommand_get_brightness(command->data.global_brightness); + Brightness brightness = sp_cmd_brightness_global_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 GenericCommand *command = sp_genericcommand_try_from_packet(packet); + struct Command command = sp_cmd_generic_try_from_packet(packet); done = log_command(command); - sp_genericcommand_free(command); + sp_cmd_generic_free(command); } close(udp_socket); diff --git a/example/src/helpers.h b/example/src/helpers.h index ee415f2..bc6c119 100644 --- a/example/src/helpers.h +++ b/example/src/helpers.h @@ -10,12 +10,12 @@ static UdpSocket *sock = NULL; void sock_free() { - sp_udpsocket_free(sock); + sp_udp_free(sock); } void sock_init() { - sock = sp_udpsocket_open_ipv4(127, 0, 0, 1, 2342); - //sock = sp_udp_open_ipv4(172, 23, 42, 29, 2342); + //sock = sp_udp_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 12a1a9b..35ba20d 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_bitmapcommand_from_bitmap(sp_bitmap_clone(bitmap)); - Packet *packet = sp_bitmapcommand_try_into_packet(command); + BitmapCommand *command = sp_cmd_bitmap_from_bitmap(sp_bitmap_clone(bitmap)); + Packet *packet = sp_cmd_bitmap_try_into_packet(command); if (packet == NULL) { result = -2; goto exit; } - if (!sp_udpsocket_send_packet(sock, packet)) { + if (!sp_udp_send_packet(sock, packet)) { result = -3; goto exit; } diff --git a/example/src/random_stuff.c b/example/src/random_stuff.c index 7a58c3a..b55e42c 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_try_into_packet(pixels, 0, 0, COMPRESSION_CODE_UNCOMPRESSED); + Packet *packet = sp_bitmap_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_udpsocket_send_packet(sock, packet); + sp_udp_send_packet(sock, packet); return 0; } diff --git a/example/src/undefined.c b/example/src/undefined.c deleted file mode 100644 index b869d71..0000000 --- a/example/src/undefined.c +++ /dev/null @@ -1,22 +0,0 @@ -#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 1d0440b..a3f7017 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); } - 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); + 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); if (packet == NULL) { result = -2; goto exit; } - if (!sp_udpsocket_send_packet(sock, packet)) { + if (!sp_udp_send_packet(sock, packet)) { result = -3; goto exit; } diff --git a/include/servicepoint.h b/include/servicepoint.h index 703ab37..68d4c57 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 [`crate::Command`]s. + * The u16 command codes used for the [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 DisplayBitVec DisplayBitVec; +typedef struct BitVec BitVec; /** *
Untested
@@ -412,8 +412,6 @@ 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; @@ -476,11 +474,6 @@ 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. * @@ -547,6 +540,11 @@ 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. * @@ -560,7 +558,7 @@ typedef struct ValueGrid_u8 Cp437Grid; typedef union CommandUnion { uint8_t *null; struct BitmapCommand */*notnull*/ bitmap; - struct BitVecCommand */*notnull*/ bit_vec; + struct BitVecCommand */*notnull*/ bitvec; struct BrightnessGridCommand */*notnull*/ brightness_grid; struct CharGridCommand */*notnull*/ char_grid; struct Cp437GridCommand */*notnull*/ cp437_grid; @@ -578,7 +576,7 @@ typedef union CommandUnion { * * Rust equivalent: [TypedCommand]. */ -typedef struct GenericCommand { +typedef struct Command { /** * Specifies which kind of command struct is contained in `data` */ @@ -587,7 +585,7 @@ typedef struct GenericCommand { * The pointer to the command struct */ union CommandUnion data; -} GenericCommand; +} Command; /** * A raw header. @@ -636,44 +634,40 @@ extern "C" { #endif // __cplusplus /** - * Calls method [`servicepoint::Bitmap::clone`]. - * *Clones a [`Bitmap`] instance. * - * This function is part of the `bitmap` module. + * This function is part of the sp_bitmap module. */ struct Bitmap */*notnull*/ sp_bitmap_clone(struct Bitmap */*notnull*/ instance); /** - * Calls method [`servicepoint::Bitmap::data_ref_mut`]. + * Calls [`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 `bitmap` module. + * This function is part of the sp_bitmap module. */ struct ByteSlice sp_bitmap_data_ref_mut(struct Bitmap */*notnull*/ instance); /** - * Calls method [`servicepoint::Bitmap::fill`]. + * Calls [`servicepoint::Bitmap::fill`]. * - * Sets the state of all cells in the grid. + * Sets the state of all pixels in the [Bitmap]. * * # Arguments * - * - `value`: the value to set all cells to + * - `value`: the value to set all pixels to * - * This function is part of the `bitmap` module. + * This function is part of the sp_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 `bitmap` module. + * This function is part of the sp_bitmap module. */ void sp_bitmap_free(struct Bitmap */*notnull*/ instance); @@ -684,13 +678,12 @@ void sp_bitmap_free(struct Bitmap */*notnull*/ instance); * * Returns NULL in case of error. * - * This function is part of the `bitmap` module. + * This function is part of the sp_bitmap module. */ -struct Bitmap *sp_bitmap_from_bitvec(size_t width, - DisplayBitVec */*notnull*/ bitvec); +struct Bitmap *sp_bitmap_from_bitvec(size_t width, BitVec */*notnull*/ bitvec); /** - * Calls method [`servicepoint::Bitmap::get`]. + * Calls [`servicepoint::Bitmap::get`]. * * Gets the current value at the specified position. * @@ -702,27 +695,39 @@ struct Bitmap *sp_bitmap_from_bitvec(size_t width, * * - when accessing `x` or `y` out of bounds * - * This function is part of the `bitmap` module. + * This function is part of the sp_bitmap module. */ bool sp_bitmap_get(struct Bitmap */*notnull*/ instance, size_t x, size_t y); /** - * Calls method [`servicepoint::Bitmap::height`]. + * Calls [`servicepoint::Bitmap::height`]. * - * Gets the height. + * Gets the height in pixels. * - * This function is part of the `bitmap` module. + * This function is part of the sp_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 `bitmap` module. + * This function is part of the sp_bitmap module. */ -DisplayBitVec */*notnull*/ sp_bitmap_into_bitvec(struct Bitmap */*notnull*/ bitmap); +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); /** * Loads a [Bitmap] with the specified dimensions from the provided data. @@ -734,7 +739,7 @@ DisplayBitVec */*notnull*/ sp_bitmap_into_bitvec(struct Bitmap */*notnull*/ bitm * * returns: [Bitmap] that contains a copy of the provided data, or NULL in case of an error. * - * This function is part of the `bitmap` module. + * This function is part of the sp_bitmap module. */ struct Bitmap *sp_bitmap_load(size_t width, size_t height, @@ -765,7 +770,7 @@ struct Bitmap *sp_bitmap_load(size_t width, * sp_bitmap_free(grid); * ``` * - * This function is part of the `bitmap` module. + * This function is part of the sp_bitmap module. */ struct Bitmap *sp_bitmap_new(size_t width, size_t height); @@ -774,12 +779,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 `bitmap` module. + * This function is part of the sp_bitmap module. */ struct Bitmap */*notnull*/ sp_bitmap_new_max_sized(void); /** - * Calls method [`servicepoint::Bitmap::set`]. + * Calls [`servicepoint::Bitmap::set`]. * * Sets the value of the specified position. * @@ -792,7 +797,7 @@ struct Bitmap */*notnull*/ sp_bitmap_new_max_sized(void); * * - when accessing `x` or `y` out of bounds * - * This function is part of the `bitmap` module. + * This function is part of the sp_bitmap module. */ void sp_bitmap_set(struct Bitmap */*notnull*/ instance, size_t x, @@ -800,322 +805,189 @@ void sp_bitmap_set(struct Bitmap */*notnull*/ instance, bool value); /** - * Calls method [`servicepoint::Bitmap::try_into_packet`]. + * Calls [`servicepoint::Bitmap::width`]. * - * Creates a [BitmapCommand] and immediately turns that into a [Packet]. + * Gets the width in pixels. * - * 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. + * This function is part of the sp_bitmap module. */ size_t sp_bitmap_width(struct Bitmap */*notnull*/ instance); /** - * Calls method [`servicepoint::BitmapCommand::clone`]. + * Calls [`servicepoint::DisplayBitVec::as_raw_mut_slice`]. * - *Clones a [`BitmapCommand`] instance. + * Gets an unsafe reference to the data of the [DisplayBitVec] instance. * - * This function is part of the `bitmapcommand` module. + * The returned memory is valid for the lifetime of the bitvec. + * + * This function is part of the sp_bitvec module. */ -struct BitmapCommand */*notnull*/ sp_bitmapcommand_clone(struct BitmapCommand */*notnull*/ instance); +struct ByteSlice sp_bitvec_as_raw_mut_slice(BitVec */*notnull*/ instance); /** - * Calls method [`servicepoint::BitmapCommand::free`]. + *Clones a [`DisplayBitVec`] instance. * - *Deallocates a [`BitmapCommand`] instance. - * - * This function is part of the `bitmapcommand` module. + * This function is part of the sp_bitvec module. */ -void sp_bitmapcommand_free(struct BitmapCommand */*notnull*/ instance); +BitVec */*notnull*/ sp_bitvec_clone(BitVec */*notnull*/ instance); /** - * Move the provided [Bitmap] into a new [BitmapCommand], - * leaving other fields as their default values. + * Calls [`servicepoint::DisplayBitVec::fill`]. * - * Rust equivalent: `BitmapCommand::from(bitmap)` + * Sets the value of all bits. * - * This function is part of the `bitmapcommand` module. + * # Arguments + * + * - `value`: the value to set all bits to + * + * This function is part of the sp_bitvec module. */ -struct BitmapCommand */*notnull*/ sp_bitmapcommand_from_bitmap(struct Bitmap */*notnull*/ bitmap); +void sp_bitvec_fill(BitVec */*notnull*/ instance, bool value); /** - * Calls method [`servicepoint::BitmapCommand::get_bitmap_mut`]. + *Deallocates a [`DisplayBitVec`] instance. * - * 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. + * This function is part of the sp_bitvec module. */ -struct Bitmap */*notnull*/ sp_bitmapcommand_get_bitmap_mut(struct BitmapCommand */*notnull*/ instance); +void sp_bitvec_free(BitVec */*notnull*/ instance); /** - * Calls method [`servicepoint::BitmapCommand::get_compression`]. + * Calls [`servicepoint::DisplayBitVec::get`]. * - * Gets the value of field `compression` of the [`servicepoint::BitmapCommand`]. + * Gets the value of a bit. * - * This function is part of the `bitmapcommand` module. + * # 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. */ -CompressionCode sp_bitmapcommand_get_compression(struct BitmapCommand */*notnull*/ instance); +bool sp_bitvec_get(BitVec */*notnull*/ instance, size_t index); /** - * Calls method [`servicepoint::BitmapCommand::get_origin`]. + * Creates a [BitVecCommand] and immediately turns that into a [Packet]. * - * Reads the origin field of the [`BitmapCommand`]. + * The provided [DisplayBitVec] gets consumed. * - * This function is part of the `bitmapcommand` module. + * Returns NULL in case of an error. + * + * This function is part of the sp_bitvec module. */ -void sp_bitmapcommand_get_origin(struct BitmapCommand */*notnull*/ command, - size_t */*notnull*/ origin_x, - size_t */*notnull*/ origin_y); +struct Packet *sp_bitvec_into_packet(BitVec */*notnull*/ bitvec, + size_t offset, + BinaryOperation operation, + CompressionCode compression); /** - * Sets a window of pixels to the specified values. + * Calls [`servicepoint::DisplayBitVec::is_empty`]. * - * The passed [Bitmap] gets consumed. + * Returns true if length is 0. * - * Returns: a new [BitmapCommand] instance. - * - * This function is part of the `bitmapcommand` module. + * This function is part of the sp_bitvec module. */ -struct BitmapCommand */*notnull*/ sp_bitmapcommand_new(struct Bitmap */*notnull*/ bitmap, - size_t origin_x, - size_t origin_y, - CompressionCode compression); +bool sp_bitvec_is_empty(BitVec */*notnull*/ instance); /** - * Calls method [`servicepoint::BitmapCommand::set_bitmap`]. + * Calls [`servicepoint::DisplayBitVec::len`]. * - * Sets the value of field `bitmap` of the [`servicepoint::BitmapCommand`]. - * The provided value is moved into the instance, potentially invalidating previously taken references. + * Gets the length in bits. * - * This function is part of the `bitmapcommand` module. + * This function is part of the sp_bitvec module. */ -void sp_bitmapcommand_set_bitmap(struct BitmapCommand */*notnull*/ instance, - struct Bitmap */*notnull*/ value); +size_t sp_bitvec_len(BitVec */*notnull*/ instance); /** - * Calls method [`servicepoint::BitmapCommand::set_compression`]. + * Interpret the data as a series of bits and load then into a new [DisplayBitVec] instance. * - * Sets the value of field `compression` of the [`servicepoint::BitmapCommand`]. + * returns: [DisplayBitVec] instance containing data. * - * This function is part of the `bitmapcommand` module. + * This function is part of the sp_bitvec module. */ -void sp_bitmapcommand_set_compression(struct BitmapCommand */*notnull*/ instance, - CompressionCode value); +BitVec */*notnull*/ sp_bitvec_load(struct ByteSlice data); /** - * Calls method [`servicepoint::BitmapCommand::set_origin`]. + * Creates a new [DisplayBitVec] instance. * - * Overwrites the origin field of the [`BitmapCommand`]. + * # Arguments * - * This function is part of the `bitmapcommand` module. + * - `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. */ -void sp_bitmapcommand_set_origin(struct BitmapCommand */*notnull*/ command, - size_t origin_x, - size_t origin_y); +BitVec */*notnull*/ sp_bitvec_new(size_t size); /** - * Calls method [`servicepoint::BitmapCommand::try_into_packet`]. + * Calls [`servicepoint::DisplayBitVec::set`]. * - *Tries to turn a [`BitmapCommand`] into a [Packet]. + * Sets the value of a bit. * - * Returns: NULL or a [Packet] containing the command. + * # Arguments * - * This function is part of the `bitmapcommand` module. + * - `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. */ -struct Packet *sp_bitmapcommand_try_into_packet(struct BitmapCommand */*notnull*/ instance); +void sp_bitvec_set(BitVec */*notnull*/ instance, size_t index, bool value); /** - * 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 `brightnessgrid` module. + * This function is part of the sp_brightness_grid module. */ -BrightnessGrid */*notnull*/ sp_brightnessgrid_clone(BrightnessGrid */*notnull*/ instance); +BrightnessGrid */*notnull*/ sp_brightness_grid_clone(BrightnessGrid */*notnull*/ instance); /** - * Calls method [`servicepoint::BrightnessGrid::data_ref_mut`]. + * Calls [`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 `brightnessgrid` module. + * This function is part of the sp_brightness_grid module. */ -struct ByteSlice sp_brightnessgrid_data_ref_mut(BrightnessGrid */*notnull*/ instance); +struct ByteSlice sp_brightness_grid_data_ref_mut(BrightnessGrid */*notnull*/ instance); /** - * Calls method [`servicepoint::BrightnessGrid::fill`]. + * Calls [`servicepoint::BrightnessGrid::fill`]. * - * Sets the state of all cells in the grid. + * Sets the value of all cells. * * # Arguments * * - `value`: the value to set all cells to * - * This function is part of the `brightnessgrid` module. + * This function is part of the sp_brightness_grid module. */ -void sp_brightnessgrid_fill(BrightnessGrid */*notnull*/ instance, - Brightness value); +void sp_brightness_grid_fill(BrightnessGrid */*notnull*/ instance, + Brightness value); /** - * Calls method [`servicepoint::BrightnessGrid::free`]. - * *Deallocates a [`BrightnessGrid`] instance. * - * This function is part of the `brightnessgrid` module. + * This function is part of the sp_brightness_grid module. */ -void sp_brightnessgrid_free(BrightnessGrid */*notnull*/ instance); +void sp_brightness_grid_free(BrightnessGrid */*notnull*/ instance); /** - * Calls method [`servicepoint::BrightnessGrid::get`]. + * Calls [`servicepoint::BrightnessGrid::get`]. * * Gets the current value at the specified position. * @@ -1123,24 +995,38 @@ void sp_brightnessgrid_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. * - * - when accessing `x` or `y` out of bounds - * - * This function is part of the `brightnessgrid` module. + * This function is part of the sp_brightness_grid module. */ -Brightness sp_brightnessgrid_get(BrightnessGrid */*notnull*/ instance, - size_t x, - size_t y); +Brightness sp_brightness_grid_get(BrightnessGrid */*notnull*/ instance, + size_t x, + size_t y); /** - * Calls method [`servicepoint::BrightnessGrid::height`]. + * Calls [`servicepoint::BrightnessGrid::height`]. * - * Gets the height. + * Gets the height of the grid. * - * This function is part of the `brightnessgrid` module. + * This function is part of the sp_brightness_grid module. */ -size_t sp_brightnessgrid_height(BrightnessGrid */*notnull*/ instance); +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); /** * Loads a [BrightnessGrid] with the specified dimensions from the provided data. @@ -1149,11 +1035,11 @@ size_t sp_brightnessgrid_height(BrightnessGrid */*notnull*/ instance); * * returns: new [BrightnessGrid] instance, or NULL in case of an error. * - * This function is part of the `brightnessgrid` module. + * This function is part of the sp_brightness_grid module. */ -BrightnessGrid *sp_brightnessgrid_load(size_t width, - size_t height, - struct ByteSlice data); +BrightnessGrid *sp_brightness_grid_load(size_t width, + size_t height, + struct ByteSlice data); /** * Creates a new [BrightnessGrid] with the specified dimensions. @@ -1174,12 +1060,12 @@ BrightnessGrid *sp_brightnessgrid_load(size_t width, * sp_udp_free(connection); * ``` * - * This function is part of the `brightnessgrid` module. + * This function is part of the sp_brightness_grid module. */ -BrightnessGrid */*notnull*/ sp_brightnessgrid_new(size_t width, size_t height); +BrightnessGrid */*notnull*/ sp_brightness_grid_new(size_t width, size_t height); /** - * Calls method [`servicepoint::BrightnessGrid::set`]. + * Calls [`servicepoint::BrightnessGrid::set`]. * * Sets the value of the specified position. * @@ -1188,147 +1074,37 @@ BrightnessGrid */*notnull*/ sp_brightnessgrid_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 `brightnessgrid` module. + * This function is part of the sp_brightness_grid module. */ -void sp_brightnessgrid_set(BrightnessGrid */*notnull*/ instance, - size_t x, - size_t y, - Brightness value); +void sp_brightness_grid_set(BrightnessGrid */*notnull*/ instance, + size_t x, + size_t y, + Brightness value); /** - * Calls method [`servicepoint::BrightnessGrid::try_into_packet`]. + * Calls [`servicepoint::BrightnessGrid::width`]. * - * Creates a [BrightnessGridCommand] and immediately turns that into a [Packet]. + * Gets the width of the grid. * - * The provided [BrightnessGrid] gets consumed. - * - * Returns NULL in case of an error. - * - * This function is part of the `brightnessgrid` module. + * This function is part of the sp_brightness_grid module. */ -struct Packet *sp_brightnessgrid_try_into_packet(BrightnessGrid */*notnull*/ grid, - size_t x, - size_t y); +size_t sp_brightness_grid_width(BrightnessGrid */*notnull*/ instance); /** - * 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 `chargrid` module. + * This function is part of the sp_char_grid module. */ -CharGrid */*notnull*/ sp_chargrid_clone(CharGrid */*notnull*/ instance); +CharGrid */*notnull*/ sp_char_grid_clone(CharGrid */*notnull*/ instance); /** - * Calls method [`servicepoint::CharGrid::fill`]. + * Calls [`servicepoint::CharGrid::fill`]. * * Sets the value of all cells in the grid. * @@ -1337,21 +1113,19 @@ CharGrid */*notnull*/ sp_chargrid_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 `chargrid` module. + * This function is part of the sp_char_grid module. */ -void sp_chargrid_fill(CharGrid */*notnull*/ instance, uint32_t value); +void sp_char_grid_fill(CharGrid */*notnull*/ instance, uint32_t value); /** - * Calls method [`servicepoint::CharGrid::free`]. - * *Deallocates a [`CharGrid`] instance. * - * This function is part of the `chargrid` module. + * This function is part of the sp_char_grid module. */ -void sp_chargrid_free(CharGrid */*notnull*/ instance); +void sp_char_grid_free(CharGrid */*notnull*/ instance); /** - * Calls method [`servicepoint::CharGrid::get`]. + * Calls [`servicepoint::CharGrid::get`]. * * Returns the current value at the specified position. * @@ -1363,27 +1137,40 @@ void sp_chargrid_free(CharGrid */*notnull*/ instance); * * - when accessing `x` or `y` out of bounds * - * This function is part of the `chargrid` module. + * This function is part of the sp_char_grid module. */ -uint32_t sp_chargrid_get(CharGrid */*notnull*/ instance, size_t x, size_t y); +uint32_t sp_char_grid_get(CharGrid */*notnull*/ instance, size_t x, size_t y); /** - * Calls method [`servicepoint::CharGrid::height`]. + * Calls [`servicepoint::CharGrid::height`]. * - * Gets the height. + * Gets the height of the grid. * - * This function is part of the `chargrid` module. + * This function is part of the sp_char_grid module. */ -size_t sp_chargrid_height(CharGrid */*notnull*/ instance); +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); /** * 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 `chargrid` module. + * This function is part of the sp_char_grid module. */ -CharGrid *sp_chargrid_load(size_t width, size_t height, struct ByteSlice data); +CharGrid *sp_char_grid_load(size_t width, size_t height, struct ByteSlice data); /** * Creates a new [CharGrid] with the specified dimensions. @@ -1399,12 +1186,12 @@ CharGrid *sp_chargrid_load(size_t width, size_t height, struct ByteSlice data); * sp_char_grid_free(grid); * ``` * - * This function is part of the `chargrid` module. + * This function is part of the sp_char_grid module. */ -CharGrid */*notnull*/ sp_chargrid_new(size_t width, size_t height); +CharGrid */*notnull*/ sp_char_grid_new(size_t width, size_t height); /** - * Calls method [`servicepoint::CharGrid::set`]. + * Calls [`servicepoint::CharGrid::set`]. * * Sets the value of the specified position in the grid. * @@ -1420,85 +1207,395 @@ CharGrid */*notnull*/ sp_chargrid_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 `chargrid` module. + * This function is part of the sp_char_grid module. */ -void sp_chargrid_set(CharGrid */*notnull*/ instance, - size_t x, - size_t y, - uint32_t value); +void sp_char_grid_set(CharGrid */*notnull*/ instance, + size_t x, + size_t y, + uint32_t value); /** - * Calls method [`servicepoint::CharGrid::try_into_packet`]. + * Calls [`servicepoint::CharGrid::width`]. * - * Creates a [CharGridCommand] and immediately turns that into a [Packet]. + * Gets the width of the grid. * - * The provided [CharGrid] gets consumed. - * - * Returns NULL in case of an error. - * - * This function is part of the `chargrid` module. + * This function is part of the sp_char_grid module. */ -struct Packet *sp_chargrid_try_into_packet(CharGrid */*notnull*/ grid, - size_t x, - size_t y); +size_t sp_char_grid_width(CharGrid */*notnull*/ instance); /** - * Calls method [`servicepoint::CharGrid::width`]. + *Clones a [`BitmapCommand`] instance. * - * Gets the width. - * - * This function is part of the `chargrid` module. + * This function is part of the sp_cmd_bitmap module. */ -size_t sp_chargrid_width(CharGrid */*notnull*/ instance); +struct BitmapCommand */*notnull*/ sp_cmd_bitmap_clone(struct BitmapCommand */*notnull*/ instance); /** - * Calls method [`servicepoint::CharGridCommand::clone`]. + *Deallocates a [`BitmapCommand`] instance. * + * 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 `chargridcommand` module. + * This function is part of the sp_cmd_char_grid module. */ -struct CharGridCommand */*notnull*/ sp_chargridcommand_clone(struct CharGridCommand */*notnull*/ instance); +struct CharGridCommand */*notnull*/ sp_cmd_char_grid_clone(struct CharGridCommand */*notnull*/ instance); /** - * Calls method [`servicepoint::CharGridCommand::free`]. - * *Deallocates a [`CharGridCommand`] instance. * - * This function is part of the `chargridcommand` module. + * This function is part of the sp_cmd_char_grid module. */ -void sp_chargridcommand_free(struct CharGridCommand */*notnull*/ instance); +void sp_cmd_char_grid_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 `chargridcommand` module. + * This function is part of the sp_cmd_char_grid module. */ -struct CharGridCommand */*notnull*/ sp_chargridcommand_from_grid(CharGrid */*notnull*/ grid); +struct CharGridCommand */*notnull*/ sp_cmd_char_grid_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 `chargridcommand` module. + * This function is part of the sp_cmd_char_grid module. */ -CharGrid */*notnull*/ sp_chargridcommand_get_grid_mut(struct CharGridCommand */*notnull*/ instance); +CharGrid */*notnull*/ sp_cmd_char_grid_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 `chargridcommand` module. + * This function is part of the sp_cmd_char_grid module. */ -void sp_chargridcommand_get_origin(struct CharGridCommand */*notnull*/ command, - size_t */*notnull*/ origin_x, - size_t */*notnull*/ origin_y); +void sp_cmd_char_grid_get_origin(struct CharGridCommand */*notnull*/ command, + size_t */*notnull*/ origin_x, + size_t */*notnull*/ origin_y); /** * Show UTF-8 encoded text on the screen. @@ -1507,62 +1604,45 @@ void sp_chargridcommand_get_origin(struct CharGridCommand */*notnull*/ command, * * Returns: a new [CharGridCommand] instance. * - * This function is part of the `chargridcommand` module. + * This function is part of the sp_cmd_char_grid module. */ -struct CharGridCommand */*notnull*/ sp_chargridcommand_new(CharGrid */*notnull*/ grid, - size_t origin_x, - size_t origin_y); +struct CharGridCommand */*notnull*/ sp_cmd_char_grid_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 `chargridcommand` module. + * This function is part of the sp_cmd_char_grid module. */ -void sp_chargridcommand_set_grid(struct CharGridCommand */*notnull*/ instance, - CharGrid */*notnull*/ value); +void sp_cmd_char_grid_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 `chargridcommand` module. + * This function is part of the sp_cmd_char_grid module. */ -void sp_chargridcommand_set_origin(struct CharGridCommand */*notnull*/ command, - size_t origin_x, - size_t origin_y); +void sp_cmd_char_grid_set_origin(struct CharGridCommand */*notnull*/ command, + size_t origin_x, + size_t origin_y); /** - * Calls method [`servicepoint::CharGridCommand::try_into_packet`]. - * - *Tries to turn a [`CharGridCommand`] into a [Packet]. + * Tries to turn a [CharGridCommand] into a [Packet]. * * Returns: NULL or a [Packet] containing the command. * - * This function is part of the `chargridcommand` module. + * This function is part of the sp_cmd_char_grid module. */ -struct Packet *sp_chargridcommand_try_into_packet(struct CharGridCommand */*notnull*/ instance); +struct Packet *sp_cmd_char_grid_try_into_packet(struct CharGridCommand */*notnull*/ command); /** - * 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 `clearcommand` module. + * This function is part of the sp_cmd_clear module. */ -void sp_clearcommand_free(struct ClearCommand */*notnull*/ instance); +void sp_cmd_clear_free(struct ClearCommand */*notnull*/ instance); /** * Set all pixels to the off state. @@ -1571,65 +1651,212 @@ void sp_clearcommand_free(struct ClearCommand */*notnull*/ instance); * * Returns: a new [`ClearCommand`] instance. * - * This function is part of the `clearcommand` module. + * This function is part of the sp_cmd_clear module. */ -struct ClearCommand */*notnull*/ sp_clearcommand_new(void); +struct ClearCommand */*notnull*/ sp_cmd_clear_new(void); /** - * Calls method [`servicepoint::ClearCommand::try_into_packet`]. + *Clones a [`Cp437GridCommand`] instance. * - *Tries to turn a [`ClearCommand`] into a [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]. * * Returns: NULL or a [Packet] containing the command. * - * This function is part of the `clearcommand` module. + * This function is part of the sp_cmd_cp437_grid module. */ -struct Packet *sp_clearcommand_try_into_packet(struct ClearCommand */*notnull*/ instance); +struct Packet *sp_cmd_cp437_grid_try_into_packet(struct Cp437GridCommand */*notnull*/ command); /** - * Calls method [`servicepoint::Cp437Grid::clone`]. + *Deallocates a [`FadeOutCommand`] instance. * + * 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 `cp437grid` module. + * This function is part of the sp_cp437_grid module. */ -Cp437Grid */*notnull*/ sp_cp437grid_clone(Cp437Grid */*notnull*/ instance); +Cp437Grid */*notnull*/ sp_cp437_grid_clone(Cp437Grid */*notnull*/ instance); /** - * Calls method [`servicepoint::Cp437Grid::data_ref_mut`]. + * Calls [`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 `cp437grid` module. + * This function is part of the sp_cp437_grid module. */ -struct ByteSlice sp_cp437grid_data_ref_mut(Cp437Grid */*notnull*/ instance); +struct ByteSlice sp_cp437_grid_data_ref_mut(Cp437Grid */*notnull*/ instance); /** - * Calls method [`servicepoint::Cp437Grid::fill`]. + * Calls [`servicepoint::Cp437Grid::fill`]. * - * Sets the state of all cells in the grid. + * Sets the value 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 `cp437grid` module. + * This function is part of the sp_cp437_grid module. */ -void sp_cp437grid_fill(Cp437Grid */*notnull*/ instance, uint8_t value); +void sp_cp437_grid_fill(Cp437Grid */*notnull*/ instance, uint8_t value); /** - * Calls method [`servicepoint::Cp437Grid::free`]. - * *Deallocates a [`Cp437Grid`] instance. * - * This function is part of the `cp437grid` module. + * This function is part of the sp_cp437_grid module. */ -void sp_cp437grid_free(Cp437Grid */*notnull*/ instance); +void sp_cp437_grid_free(Cp437Grid */*notnull*/ instance); /** - * Calls method [`servicepoint::Cp437Grid::get`]. + * Calls [`servicepoint::Cp437Grid::get`]. * * Gets the current value at the specified position. * @@ -1641,518 +1868,101 @@ void sp_cp437grid_free(Cp437Grid */*notnull*/ instance); * * - when accessing `x` or `y` out of bounds * - * This function is part of the `cp437grid` module. + * This function is part of the sp_cp437_grid module. */ -uint8_t sp_cp437grid_get(Cp437Grid */*notnull*/ instance, size_t x, size_t y); +uint8_t sp_cp437_grid_get(Cp437Grid */*notnull*/ instance, size_t x, size_t y); /** - * Calls method [`servicepoint::Cp437Grid::height`]. + * Calls [`servicepoint::Cp437Grid::height`]. * - * Gets the height. + * Gets the height of the grid. * - * This function is part of the `cp437grid` module. + * This function is part of the sp_cp437_grid module. */ -size_t sp_cp437grid_height(Cp437Grid */*notnull*/ instance); +size_t sp_cp437_grid_height(Cp437Grid */*notnull*/ instance); /** - * Loads a [Cp437Grid] with the specified dimensions from the provided data. - * - * This function is part of the `cp437grid` module. - */ -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 `cp437grid` module. - */ -Cp437Grid */*notnull*/ sp_cp437grid_new(size_t width, size_t height); - -/** - * Calls method [`servicepoint::Cp437Grid::set`]. - * - * 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 - * - * This function is part of the `cp437grid` module. - */ -void sp_cp437grid_set(Cp437Grid */*notnull*/ instance, - size_t x, - size_t y, - uint8_t value); - -/** - * Calls method [`servicepoint::Cp437Grid::try_into_packet`]. - * * 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 `cp437grid` module. + * This function is part of the sp_cp437_grid module. */ -struct Packet *sp_cp437grid_try_into_packet(Cp437Grid */*notnull*/ grid, - size_t x, - size_t y); +struct Packet *sp_cp437_grid_into_packet(Cp437Grid */*notnull*/ grid, + size_t x, + size_t y); /** - * Calls method [`servicepoint::Cp437Grid::width`]. + * Loads a [Cp437Grid] with the specified dimensions from the provided data. * - * Gets the width. - * - * This function is part of the `cp437grid` module. + * This function is part of the sp_cp437_grid module. */ -size_t sp_cp437grid_width(Cp437Grid */*notnull*/ instance); +Cp437Grid *sp_cp437_grid_load(size_t width, + size_t height, + struct ByteSlice data); /** - * Calls method [`servicepoint::Cp437GridCommand::clone`]. + * Creates a new [Cp437Grid] with the specified dimensions. * - *Clones a [`Cp437GridCommand`] instance. + * returns: [Cp437Grid] initialized to 0. * - * This function is part of the `cp437gridcommand` module. + * This function is part of the sp_cp437_grid module. */ -struct Cp437GridCommand */*notnull*/ sp_cp437gridcommand_clone(struct Cp437GridCommand */*notnull*/ instance); +Cp437Grid */*notnull*/ sp_cp437_grid_new(size_t width, size_t height); /** - * Calls method [`servicepoint::Cp437GridCommand::free`]. + * Calls [`servicepoint::Cp437Grid::set`]. * - *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. + * Sets the value at the specified position. * * # Arguments * - * - `value`: the value to set all bits to + * - `x` and `y`: position of the cell + * - `value`: the value to write to the cell * - * 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 + * returns: old value of the cell * * # Panics * - * - when accessing `index` out of bounds + * - when accessing `x` or `y` out of bounds * - * This function is part of the `displaybitvec` module. + * This function is part of the sp_cp437_grid module. */ -bool sp_displaybitvec_get(DisplayBitVec */*notnull*/ instance, size_t index); +void sp_cp437_grid_set(Cp437Grid */*notnull*/ instance, + size_t x, + size_t y, + uint8_t value); /** - * Calls method [`servicepoint::DisplayBitVec::is_empty`]. + * Calls [`servicepoint::Cp437Grid::width`]. * - * Returns true if length is 0. + * Gets the width of the grid. * - * This function is part of the `displaybitvec` module. + * This function is part of the sp_cp437_grid 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); +size_t sp_cp437_grid_width(Cp437Grid */*notnull*/ instance); /** * 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 `envlogger` module. + * This function is part of the sp_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 `packet` module. + * This function is part of the sp_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 `packet` module. + * This function is part of the sp_packet module. */ void sp_packet_free(struct Packet */*notnull*/ instance); @@ -2161,77 +1971,65 @@ void sp_packet_free(struct Packet */*notnull*/ instance); * * returns: new instance. Will never return null. * - * This function is part of the `packet` module. + * This function is part of the sp_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 `packet` module. + * This function is part of the sp_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 `packet` module. + * This function is part of the sp_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 `packet` module. + * This function is part of the sp_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 `packet` module. + * This function is part of the sp_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 `packet` module. + * This function is part of the sp_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 `packet` module. + * This function is part of the sp_packet module. */ void sp_packet_set_payload(struct Packet */*notnull*/ packet, struct ByteSlice data); @@ -2241,7 +2039,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 `packet` module. + * This function is part of the sp_packet module. */ struct Packet *sp_packet_try_load(struct ByteSlice data); @@ -2250,19 +2048,17 @@ 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_sp_u16_to_command_code(uint16_t code, - CommandCode */*notnull*/ result); +bool sp_u16_to_command_code(uint16_t code, + CommandCode *result); /** - * Calls method [`servicepoint::UdpSocket::free`]. - * *Deallocates a [`UdpSocket`] instance. * - * This function is part of the `udpsocket` module. + * This function is part of the sp_udp module. */ -void sp_udpsocket_free(struct UdpSocket */*notnull*/ instance); +void sp_udp_free(struct UdpSocket */*notnull*/ instance); /** * Creates a new instance of [UdpSocket]. @@ -2277,9 +2073,9 @@ void sp_udpsocket_free(struct UdpSocket */*notnull*/ instance); * sp_udp_send_command(connection, sp_command_clear()); * ``` * - * This function is part of the `udpsocket` module. + * This function is part of the sp_udp module. */ -struct UdpSocket *sp_udpsocket_open(char */*notnull*/ host); +struct UdpSocket *sp_udp_open(char */*notnull*/ host); /** * Creates a new instance of [UdpSocket]. @@ -2294,18 +2090,16 @@ struct UdpSocket *sp_udpsocket_open(char */*notnull*/ host); * sp_udp_send_command(connection, sp_command_clear()); * ``` * - * This function is part of the `udpsocket` module. + * This function is part of the sp_udp module. */ -struct UdpSocket *sp_udpsocket_open_ipv4(uint8_t ip1, - uint8_t ip2, - uint8_t ip3, - uint8_t ip4, - uint16_t port); +struct UdpSocket *sp_udp_open_ipv4(uint8_t ip1, + uint8_t ip2, + uint8_t ip3, + uint8_t ip4, + uint16_t port); /** - * Calls method [`servicepoint::UdpSocket::send_command`]. - * - * Sends a [GenericCommand] to the display using the [UdpSocket]. + * Sends a [SPCommand] to the display using the [UdpSocket]. * * The passed `command` gets consumed. * @@ -2317,14 +2111,12 @@ struct UdpSocket *sp_udpsocket_open_ipv4(uint8_t ip1, * sp_udp_send_command(connection, sp_command_brightness(5)); * ``` * - * This function is part of the `udpsocket` module. + * This function is part of the sp_udp module. */ -bool sp_udpsocket_send_command(struct UdpSocket */*notnull*/ connection, - struct GenericCommand */*notnull*/ command); +bool sp_udp_send_command(struct UdpSocket */*notnull*/ connection, + struct Command command); /** - * Calls method [`servicepoint::UdpSocket::send_header`]. - * * Sends a [Header] to the display using the [UdpSocket]. * * returns: true in case of success @@ -2335,24 +2127,22 @@ bool sp_udpsocket_send_command(struct UdpSocket */*notnull*/ connection, * sp_udp_send_header(connection, sp_command_brightness(5)); * ``` * - * This function is part of the `udpsocket` module. + * This function is part of the sp_udp module. */ -bool sp_udpsocket_send_header(struct UdpSocket */*notnull*/ udp_connection, - struct Header header); +bool sp_udp_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 `udpsocket` module. + * This function is part of the sp_udp module. */ -bool sp_udpsocket_send_packet(struct UdpSocket */*notnull*/ connection, - struct Packet */*notnull*/ packet); +bool sp_udp_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 40fbc1c..68f6408 100644 --- a/src/commands/bitmap_command.rs +++ b/src/commands/bitmap_command.rs @@ -1,43 +1,56 @@ use crate::{ - commands::{wrap_command, wrap_origin_accessors}, - macros::{wrap_fields, wrap_functions}, + commands::wrap_origin_accessors, + macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, + mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; -use servicepoint::{Bitmap, BitmapCommand, CompressionCode, Origin}; +use servicepoint::{Bitmap, BitmapCommand, CompressionCode, Origin, Packet}; use std::ptr::NonNull; -wrap_command!(Bitmap); +wrap_clone!(sp_cmd_bitmap::BitmapCommand); +wrap_free!(sp_cmd_bitmap::BitmapCommand); -wrap_fields!(BitmapCommand; - prop bitmap: Bitmap { get mut; set move; }; - prop compression: CompressionCode { get; set; }; +wrap_fields!(sp_cmd_bitmap::BitmapCommand; + prop bitmap: Bitmap { mut get(); move set(value); }; + prop compression: CompressionCode { get(); set(value); }; ); -wrap_origin_accessors!(BitmapCommand); +wrap_origin_accessors!(sp_cmd_bitmap::BitmapCommand); -wrap_functions!(associate BitmapCommand; +wrap_functions!(sp_cmd_bitmap; /// Sets a window of pixels to the specified values. /// /// The passed [Bitmap] gets consumed. /// /// Returns: a new [BitmapCommand] instance. fn new( - bitmap: move NonNull, - origin_x: val usize, - origin_y: val usize, - compression: val CompressionCode, - ) -> move NonNull { - BitmapCommand { - bitmap, + bitmap: NonNull, + origin_x: usize, + origin_y: usize, + compression: CompressionCode, + ) -> NonNull { + heap_move_nonnull(BitmapCommand { + bitmap: unsafe { heap_remove(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: move NonNull) -> move NonNull { - bitmap.into() - }; + 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()) + } ); diff --git a/src/commands/bitvec_command.rs b/src/commands/bitvec_command.rs index f62b492..6cec313 100644 --- a/src/commands/bitvec_command.rs +++ b/src/commands/bitvec_command.rs @@ -1,22 +1,25 @@ use crate::{ - commands::wrap_command, - macros::{wrap_fields, wrap_functions}, + macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, + mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{ BinaryOperation, BitVecCommand, CompressionCode, DisplayBitVec, Offset, + Packet, }; use std::ptr::NonNull; -wrap_command!(BitVec); +wrap_clone!(sp_cmd_bitvec::BitVecCommand); +wrap_free!(sp_cmd_bitvec::BitVecCommand); -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_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_functions!(associate BitVecCommand; +wrap_functions!(sp_cmd_bitvec; + /// Set pixel data starting at the pixel offset on screen. /// /// The screen will continuously overwrite more pixel data without regarding the offset, meaning @@ -30,16 +33,26 @@ wrap_functions!(associate BitVecCommand; /// /// The contained [`DisplayBitVec`] is always uncompressed. fn new( - bitvec: move NonNull, - offset: val usize, - operation: val BinaryOperation, - compression: val CompressionCode, - ) -> move NonNull { - BitVecCommand { - bitvec, + bitvec: NonNull, + offset: usize, + operation: BinaryOperation, + compression: CompressionCode, + ) -> NonNull { + heap_move_nonnull(BitVecCommand { + bitvec: unsafe { heap_remove(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 007d645..cc26b77 100644 --- a/src/commands/brightness_grid_command.rs +++ b/src/commands/brightness_grid_command.rs @@ -1,38 +1,53 @@ use crate::{ - commands::{wrap_command, wrap_origin_accessors}, - macros::{wrap_fields, wrap_functions}, + commands::wrap_origin_accessors, + macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, + mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; -use servicepoint::{BrightnessGrid, BrightnessGridCommand, Origin}; +use servicepoint::{BrightnessGrid, BrightnessGridCommand, Origin, Packet}; use std::ptr::NonNull; -wrap_command!(BrightnessGrid); +wrap_clone!(sp_cmd_brightness_grid::BrightnessGridCommand); +wrap_free!(sp_cmd_brightness_grid::BrightnessGridCommand); -wrap_fields!(BrightnessGridCommand; - prop grid: BrightnessGrid { get mut; set move; }; +wrap_fields!(sp_cmd_brightness_grid::BrightnessGridCommand; + prop grid: BrightnessGrid { mut get(); move set(grid); }; ); -wrap_origin_accessors!(BrightnessGridCommand); +wrap_origin_accessors!(sp_cmd_brightness_grid::BrightnessGridCommand); + +wrap_functions!(sp_cmd_brightness_grid; -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: move NonNull, - origin_x: val usize, - origin_y: val usize - ) -> move NonNull { - BrightnessGridCommand { - grid, + grid: NonNull, + origin_x: usize, + origin_y: usize, + ) -> NonNull { + heap_move_nonnull(BrightnessGridCommand { + grid: unsafe { heap_remove(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: move NonNull) -> move NonNull { - grid.into() - }; + 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()) + } + ); diff --git a/src/commands/cc_only_commands.rs b/src/commands/cc_only_commands.rs index ef49fa1..f4162a0 100644 --- a/src/commands/cc_only_commands.rs +++ b/src/commands/cc_only_commands.rs @@ -1,38 +1,37 @@ -use crate::{commands::wrap_command, macros::wrap_functions}; +use crate::{ + macros::{wrap_free, wrap_functions}, + mem::heap_move_nonnull, +}; use servicepoint::{ClearCommand, FadeOutCommand, HardResetCommand}; +use std::ptr::NonNull; macro_rules! wrap_cc_only { - ($(#[$meta:meta])* $command:ident) => { - ::paste::paste!{ - wrap_command!($command); + ($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) + } + ); - wrap_functions!(associate [< $command Command >]; - $(#[$meta])* - /// - #[doc = " Returns: a new [`" [< $command Command >] "`] instance."] - fn new() -> move ::core::ptr::NonNull<[< $command Command >]> { - [< $command Command >] - }; - ); - } + wrap_free!($prefix :: $typ); }; } -wrap_cc_only!( +wrap_cc_only!(sp_cmd_clear::ClearCommand; /// Set all pixels to the off state. /// /// Does not affect brightness. - Clear ); -wrap_cc_only!( +wrap_cc_only!(sp_cmd_hard_reset::HardResetCommand; /// 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!( +wrap_cc_only!(sp_cmd_fade_out::FadeOutCommand; /// A yet-to-be-tested command. - FadeOut ); diff --git a/src/commands/char_grid_command.rs b/src/commands/char_grid_command.rs index 06f2070..fe97dc0 100644 --- a/src/commands/char_grid_command.rs +++ b/src/commands/char_grid_command.rs @@ -1,38 +1,53 @@ use crate::{ - commands::{wrap_command, wrap_origin_accessors}, - macros::{wrap_fields, wrap_functions}, + commands::wrap_origin_accessors, + macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, + mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; -use servicepoint::{CharGrid, CharGridCommand, Origin}; +use servicepoint::{CharGrid, CharGridCommand, Origin, Packet}; use std::ptr::NonNull; -wrap_command!(CharGrid); +wrap_clone!(sp_cmd_char_grid::CharGridCommand); +wrap_free!(sp_cmd_char_grid::CharGridCommand); -wrap_fields!(CharGridCommand; - prop grid: CharGrid { get mut; set move; }; +wrap_fields!(sp_cmd_char_grid::CharGridCommand; + prop grid: CharGrid { mut get(); move set(grid); }; ); -wrap_origin_accessors!(CharGridCommand); +wrap_origin_accessors!(sp_cmd_char_grid::CharGridCommand); + +wrap_functions!(sp_cmd_char_grid; -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: move NonNull, - origin_x: val usize, - origin_y: val usize, - ) -> move NonNull { - CharGridCommand { - grid, + grid: NonNull, + origin_x: usize, + origin_y: usize, + ) -> NonNull { + heap_move_nonnull(CharGridCommand { + grid: unsafe { heap_remove(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: move NonNull) -> move NonNull { - grid.into() - }; + 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()) + } + ); diff --git a/src/commands/cp437_grid_command.rs b/src/commands/cp437_grid_command.rs index d4c0e88..25294bb 100644 --- a/src/commands/cp437_grid_command.rs +++ b/src/commands/cp437_grid_command.rs @@ -1,38 +1,53 @@ use crate::{ - commands::{wrap_command, wrap_origin_accessors}, - macros::{wrap_fields, wrap_functions}, + commands::wrap_origin_accessors, + macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, + mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; -use servicepoint::{Cp437Grid, Cp437GridCommand, Origin}; +use servicepoint::{Cp437Grid, Cp437GridCommand, Origin, Packet}; use std::ptr::NonNull; -wrap_command!(Cp437Grid); +wrap_clone!(sp_cmd_cp437_grid::Cp437GridCommand); +wrap_free!(sp_cmd_cp437_grid::Cp437GridCommand); -wrap_fields!(Cp437GridCommand; - prop grid: Cp437Grid { get mut; set move; }; +wrap_fields!(sp_cmd_cp437_grid::Cp437GridCommand; + prop grid: Cp437Grid { mut get(); move set(grid); }; ); -wrap_origin_accessors!(Cp437GridCommand); +wrap_origin_accessors!(sp_cmd_cp437_grid::Cp437GridCommand); + +wrap_functions!(sp_cmd_cp437_grid; -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: move NonNull, - origin_x: val usize, - origin_y: val usize, - ) -> move NonNull { - Cp437GridCommand { - grid, + grid: NonNull, + origin_x: usize, + origin_y: usize, + ) -> NonNull { + heap_move_nonnull(Cp437GridCommand { + grid: unsafe { heap_remove(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: move NonNull) -> move NonNull { - grid.into() - }; + 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()) + } + ); diff --git a/src/commands/generic_command.rs b/src/commands/generic_command.rs index c6a1323..9734d30 100644 --- a/src/commands/generic_command.rs +++ b/src/commands/generic_command.rs @@ -1,5 +1,5 @@ use crate::{ - macros::{derive_clone, derive_free, wrap_functions, wrap_methods}, + macros::wrap_functions, 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 bit_vec: NonNull, + pub bitvec: NonNull, pub brightness_grid: NonNull, pub char_grid: NonNull, pub cp437_grid: NonNull, @@ -55,214 +55,221 @@ pub enum CommandTag { /// /// Rust equivalent: [TypedCommand]. #[repr(C)] -pub struct GenericCommand { +pub struct SPCommand { /// Specifies which kind of command struct is contained in `data` pub tag: CommandTag, /// The pointer to the command struct pub data: CommandUnion, } -impl GenericCommand { - pub(crate) const INVALID: GenericCommand = GenericCommand { +impl SPCommand { + const INVALID: SPCommand = SPCommand { tag: CommandTag::Invalid, data: CommandUnion { null: null_mut() }, }; } -derive_clone!(GenericCommand); +wrap_functions!(sp_cmd_generic; -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]. + /// Tries to turn a [Packet] into a [SPCommand]. /// /// The packet is dropped in the process. /// - /// Returns: pointer to new [GenericCommand] instance or NULL if parsing failed. - fn try_from_packet(packet: move NonNull) -> move NonNull { + /// 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()) }; servicepoint::TypedCommand::try_from(packet) .map(|value| match value { - TypedCommand::Clear(clear) => GenericCommand { + TypedCommand::Clear(clear) => SPCommand { tag: CommandTag::Clear, data: CommandUnion { clear: heap_move_nonnull(clear), }, }, - TypedCommand::CharGrid(char_grid) => GenericCommand { + TypedCommand::CharGrid(char_grid) => SPCommand { tag: CommandTag::CharGrid, data: CommandUnion { char_grid: heap_move_nonnull(char_grid), }, }, - TypedCommand::Cp437Grid(cp437_grid) => GenericCommand { + TypedCommand::Cp437Grid(cp437_grid) => SPCommand { tag: CommandTag::Cp437Grid, data: CommandUnion { cp437_grid: heap_move_nonnull(cp437_grid), }, }, - TypedCommand::Bitmap(bitmap) => GenericCommand { + TypedCommand::Bitmap(bitmap) => SPCommand { tag: CommandTag::Bitmap, data: CommandUnion { bitmap: heap_move_nonnull(bitmap), }, }, - TypedCommand::Brightness(global_brightness) => GenericCommand { + TypedCommand::Brightness(global_brightness) => SPCommand { tag: CommandTag::GlobalBrightness, data: CommandUnion { global_brightness: heap_move_nonnull(global_brightness), }, }, - TypedCommand::BrightnessGrid(brightness_grid) => GenericCommand { + TypedCommand::BrightnessGrid(brightness_grid) => SPCommand { tag: CommandTag::BrightnessGrid, data: CommandUnion { brightness_grid: heap_move_nonnull(brightness_grid), }, }, - TypedCommand::BitVec(bitvec) => GenericCommand { + TypedCommand::BitVec(bitvec) => SPCommand { tag: CommandTag::BitVec, data: CommandUnion { - bit_vec: heap_move_nonnull(bitvec), + bitvec: heap_move_nonnull(bitvec), }, }, - TypedCommand::HardReset(hard_reset) => GenericCommand { + TypedCommand::HardReset(hard_reset) => SPCommand { tag: CommandTag::HardReset, data: CommandUnion { hard_reset: heap_move_nonnull(hard_reset), }, }, - TypedCommand::FadeOut(fade_out) => GenericCommand { + TypedCommand::FadeOut(fade_out) => SPCommand { tag: CommandTag::FadeOut, data: CommandUnion { fade_out: heap_move_nonnull(fade_out), }, }, #[allow(deprecated)] - TypedCommand::BitmapLegacy(bitmap_legacy) => GenericCommand { + TypedCommand::BitmapLegacy(bitmap_legacy) => SPCommand { tag: CommandTag::BitmapLegacy, data: CommandUnion { bitmap_legacy: heap_move_nonnull(bitmap_legacy), }, }, }) - .unwrap_or_else(move |_| GenericCommand { + .unwrap_or_else(move |_| SPCommand { tag: CommandTag::Invalid, data: CommandUnion { null: null_mut() }, }) - }; -); + } -wrap_methods! { GenericCommand; - /// Tries to turn a [GenericCommand] into a [Packet]. - /// The [GenericCommand] gets consumed. + /// 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. /// /// Returns tag [CommandTag::Invalid] in case of an error. - fn try_into_packet(move command) -> val *mut Packet { + fn into_packet( + command: SPCommand, + ) -> *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.bit_vec).try_into() }) + heap_move_ok(unsafe { heap_remove(command.data.bitvec).try_into() }) } CommandTag::BrightnessGrid => heap_move_ok(unsafe { heap_remove(command.data.brightness_grid).try_into() @@ -289,5 +296,6 @@ wrap_methods! { GenericCommand; 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 6a883ab..35bcbe0 100644 --- a/src/commands/global_brightness_command.rs +++ b/src/commands/global_brightness_command.rs @@ -1,21 +1,33 @@ use crate::{ - commands::wrap_command, - macros::{wrap_fields, wrap_functions}, + macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, + mem::{heap_move_nonnull, heap_remove}, }; -use servicepoint::{Brightness, GlobalBrightnessCommand}; +use servicepoint::{Brightness, GlobalBrightnessCommand, Packet}; use std::ptr::NonNull; -wrap_functions!(associate GlobalBrightnessCommand; +wrap_functions!(sp_cmd_brightness_global; + /// Set the brightness of all tiles to the same value. /// /// Returns: a new [GlobalBrightnessCommand] instance. - fn new(brightness: val Brightness) -> move NonNull { - GlobalBrightnessCommand::from(brightness) + 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); }; ); - -wrap_command!(GlobalBrightness); - -wrap_fields!(GlobalBrightnessCommand; - prop brightness: Brightness { get; set; }; -); diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 1d6e8ff..a6fa74d 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -15,76 +15,33 @@ pub use cp437_grid_command::*; pub use generic_command::*; macro_rules! wrap_origin_accessors { - ( $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 = " 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); - }; - ); - } - }; -} - -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) - }, - } + ( $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; } } - } + + #[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); + } + } + ); }; } -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, -}; +pub(crate) use wrap_origin_accessors; diff --git a/src/containers/bitmap.rs b/src/containers/bitmap.rs index b6ed4f3..6d502d9 100644 --- a/src/containers/bitmap.rs +++ b/src/containers/bitmap.rs @@ -1,6 +1,7 @@ use crate::{ - containers::{wrap_grid, ByteSlice}, - macros::{wrap_functions, wrap_methods}, + containers::ByteSlice, + macros::{wrap_clone, wrap_free, wrap_functions, wrap_methods}, + mem::{heap_move_nonnull, heap_move_ok, heap_move_some, heap_remove}, }; use servicepoint::{ Bitmap, BitmapCommand, CompressionCode, DataRef, DisplayBitVec, Grid, @@ -8,9 +9,11 @@ use servicepoint::{ }; use std::ptr::NonNull; -wrap_grid!(Bitmap, bool); +wrap_clone!(sp_bitmap::Bitmap); +wrap_free!(sp_bitmap::Bitmap); + +wrap_functions!(sp_bitmap; -wrap_functions!(associate Bitmap; /// Creates a new [Bitmap] with the specified dimensions. /// /// # Arguments @@ -34,16 +37,16 @@ wrap_functions!(associate Bitmap; /// sp_bitmap_set(grid, 0, 0, false); /// sp_bitmap_free(grid); /// ``` - fn new(width: val usize, height: val usize) -> move_some *mut Bitmap { - Bitmap::new(width, height) - }; + fn new(width: usize, height: usize) -> *mut Bitmap { + heap_move_some(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() -> move NonNull { - Bitmap::max_sized() - }; + fn new_max_sized() -> NonNull { + heap_move_nonnull(Bitmap::max_sized()) + } /// Loads a [Bitmap] with the specified dimensions from the provided data. /// @@ -54,12 +57,13 @@ wrap_functions!(associate Bitmap; /// /// returns: [Bitmap] that contains a copy of the provided data, or NULL in case of an error. fn load( - width: val usize, - height: val usize, - data: slice ByteSlice, - ) -> move_ok *mut Bitmap { - Bitmap::load(width, height, data) - }; + width: usize, + height: usize, + data: ByteSlice, + ) -> *mut Bitmap { + let data = unsafe { data.as_slice() }; + heap_move_ok(Bitmap::load(width, height, data)) + } /// Tries to convert the BitVec to a Bitmap. /// @@ -67,34 +71,84 @@ wrap_functions!(associate Bitmap; /// /// Returns NULL in case of error. fn from_bitvec( - width: val usize, - bitvec: move NonNull, - ) -> move_ok *mut Bitmap { - Bitmap::from_bitvec(width, bitvec) - }; -); - -wrap_methods!(Bitmap; + width: usize, + bitvec: NonNull, + ) -> *mut Bitmap { + let bitvec = unsafe { heap_remove(bitvec) }; + heap_move_ok(Bitmap::from_bitvec(width, bitvec)) + } /// Consumes the Bitmap and returns the contained BitVec. - fn into_bitvec(move bitmap) -> move NonNull { - bitmap.into() - }; + fn into_bitvec( + bitmap: NonNull + ) -> NonNull { + let bitmap = unsafe { heap_remove(bitmap) }; + heap_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 try_into_packet(move bitmap, x: val usize, y: val usize, compression: val CompressionCode) -> move_ok *mut Packet { - Packet::try_from(BitmapCommand { + 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 { 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. - fn data_ref_mut(mut instance) -> slice ByteSlice; + mut fn data_ref_mut() -> ByteSlice { + + return(slice) { unsafe { ByteSlice::from_slice(slice) } }; + }; ); diff --git a/src/containers/bitvec.rs b/src/containers/bitvec.rs index b16dd92..e232ab5 100644 --- a/src/containers/bitvec.rs +++ b/src/containers/bitvec.rs @@ -1,15 +1,15 @@ use crate::{ - containers::{wrap_container, ByteSlice}, - macros::{wrap_functions, wrap_methods}, + containers::ByteSlice, + macros::{wrap_clone, wrap_free, wrap_functions, wrap_methods}, + mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{ BinaryOperation, BitVecCommand, CompressionCode, DisplayBitVec, Packet, }; use std::ptr::NonNull; -wrap_container!(DisplayBitVec); +wrap_functions!(sp_bitvec; -wrap_functions!(associate DisplayBitVec; /// Creates a new [DisplayBitVec] instance. /// /// # Arguments @@ -21,37 +21,45 @@ wrap_functions!(associate DisplayBitVec; /// # Panics /// /// - when `size` is not divisible by 8. - fn new(size: val usize) -> move NonNull { - DisplayBitVec::repeat(false, size) - }; + fn new(size: usize) -> NonNull { + heap_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: slice ByteSlice) -> move NonNull { - DisplayBitVec::from_slice(data) - }; -); + fn load(data: ByteSlice) -> NonNull { + let data = unsafe { data.as_slice() }; + heap_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 try_into_packet( - move bitvec, - offset: val usize, - operation: val BinaryOperation, - compression: val CompressionCode - ) -> move_ok *mut Packet { - Packet::try_from(BitVecCommand { + 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 { 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. /// @@ -65,10 +73,11 @@ wrap_methods!(DisplayBitVec; /// # Panics /// /// - when accessing `index` out of bounds - fn get(ref instance, index: val usize) -> val bool { - instance.get(index).map(|x| *x).unwrap_or(false) + ref fn get(index: usize) -> bool { + return(result) { result.map(|x| *x).unwrap_or(false) }; }; + /// Sets the value of a bit. /// /// # Arguments @@ -79,23 +88,25 @@ wrap_methods!(DisplayBitVec; /// # Panics /// /// - when accessing `index` out of bounds - fn set(mut instance, index: val usize, value: val bool); + mut fn set(index: usize, value: bool); /// Sets the value of all bits. /// /// # Arguments /// /// - `value`: the value to set all bits to - fn fill(mut instance, value: val bool); + mut fn fill(value: bool); /// Gets the length in bits. - fn len(ref instance) -> val usize; + ref fn len() -> usize; /// Returns true if length is 0. - fn is_empty(ref instance) -> val bool; + ref fn is_empty() -> bool; /// Gets an unsafe reference to the data of the [DisplayBitVec] instance. /// /// The returned memory is valid for the lifetime of the bitvec. - fn as_raw_mut_slice(mut instance) -> slice ByteSlice; + mut fn as_raw_mut_slice() -> ByteSlice { + return(slice) { unsafe { ByteSlice::from_slice(slice) } }; + }; ); diff --git a/src/containers/brightness_grid.rs b/src/containers/brightness_grid.rs index 19f6b7a..2374b47 100644 --- a/src/containers/brightness_grid.rs +++ b/src/containers/brightness_grid.rs @@ -1,6 +1,8 @@ +use crate::macros::wrap_functions; use crate::{ - containers::{wrap_grid, ByteSlice}, - macros::{wrap_functions, wrap_methods}, + containers::ByteSlice, + macros::{wrap_clone, wrap_free, wrap_methods}, + mem::{heap_move_nonnull, heap_move_ok, heap_move_some, heap_remove}, }; use servicepoint::{ Brightness, BrightnessGrid, BrightnessGridCommand, ByteGrid, DataRef, Grid, @@ -8,9 +10,8 @@ use servicepoint::{ }; use std::{mem::transmute, ptr::NonNull}; -wrap_grid!(BrightnessGrid, Brightness); +wrap_functions!(sp_brightness_grid; -wrap_functions!(associate BrightnessGrid; /// Creates a new [BrightnessGrid] with the specified dimensions. /// /// returns: [BrightnessGrid] initialized to 0. @@ -28,9 +29,12 @@ wrap_functions!(associate BrightnessGrid; /// TypedCommand *command = sp_command_char_brightness(grid); /// sp_udp_free(connection); /// ``` - fn new(width: val usize, height: val usize) -> move NonNull { - BrightnessGrid::new(width, height) - }; + fn new( + width: usize, + height: usize, + ) -> NonNull { + heap_move_nonnull(BrightnessGrid::new(width, height)) + } /// Loads a [BrightnessGrid] with the specified dimensions from the provided data. /// @@ -38,38 +42,90 @@ wrap_functions!(associate BrightnessGrid; /// /// returns: new [BrightnessGrid] instance, or NULL in case of an error. fn load( - 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)) - }; -); + 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)), + ) + } -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 try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet { - Packet::try_from(BrightnessGridCommand { + fn into_packet( + grid: NonNull, + x: usize, + y: usize, + ) -> *mut Packet { + let grid = unsafe { heap_remove(grid) }; + heap_move_ok(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. - fn data_ref_mut(mut instance) -> slice ByteSlice { - //noinspection RsAssertEqual - const _: () = assert!(size_of::() == 1); + mut fn data_ref_mut() -> ByteSlice { + return(br_slice) { unsafe { + //noinspection RsAssertEqual + const _: () = assert!(size_of::() == 1); - let br_slice = instance.data_ref_mut(); - unsafe { - transmute::<&mut [Brightness], &mut [u8]>(br_slice) - } + ByteSlice::from_slice(transmute::<&mut [Brightness], &mut [u8]>(br_slice)) + }}; }; ); diff --git a/src/containers/byte_slice.rs b/src/containers/byte_slice.rs index 81380e9..10ee22f 100644 --- a/src/containers/byte_slice.rs +++ b/src/containers/byte_slice.rs @@ -26,21 +26,15 @@ pub struct ByteSlice { } impl ByteSlice { - /// Represents an invalid [ByteSlice] instance. - pub const INVALID: ByteSlice = ByteSlice { + pub(crate) 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 98a2c5b..782e2aa 100644 --- a/src/containers/char_grid.rs +++ b/src/containers/char_grid.rs @@ -1,14 +1,13 @@ use crate::{ - containers::{derive_get_width_height, wrap_container, ByteSlice}, - macros::{wrap_functions, wrap_methods}, + containers::ByteSlice, + macros::{wrap_clone, wrap_free, wrap_functions, wrap_methods}, + mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{CharGrid, CharGridCommand, Grid, Origin, Packet}; use std::ptr::NonNull; -wrap_container!(CharGrid); -derive_get_width_height!(CharGrid); +wrap_functions!(sp_char_grid; -wrap_functions!(associate CharGrid; /// Creates a new [CharGrid] with the specified dimensions. /// /// returns: [CharGrid] initialized to 0. @@ -21,19 +20,49 @@ wrap_functions!(associate CharGrid; /// sp_char_grid_set(grid, 0, 0, '!'); /// sp_char_grid_free(grid); /// ``` - fn new(width: val usize, height: val usize) -> move NonNull { - CharGrid::new(width, height) - }; + fn new( + width: usize, + height: usize, + ) -> NonNull { + heap_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: val usize, height: val usize, data: slice ByteSlice) -> move_ok *mut CharGrid { - CharGrid::load_utf8(width, height, data.to_vec()) - }; + 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), + })) + } + ); -wrap_methods!(CharGrid; +wrap_clone!(sp_char_grid::CharGrid); +wrap_free!(sp_char_grid::CharGrid); + +wrap_methods!( + sp_char_grid::CharGrid; /// Returns the current value at the specified position. /// @@ -44,8 +73,8 @@ wrap_methods!(CharGrid; /// # Panics /// /// - when accessing `x` or `y` out of bounds - fn get(ref instance, x: val usize, y: val usize) -> val u32 { - instance.get(x, y) as u32 + ref fn get(x: usize, y: usize) -> u32 { + return(char) { char as u32 }; }; /// Sets the value of the specified position in the grid. @@ -61,8 +90,8 @@ wrap_methods!(CharGrid; /// /// - when accessing `x` or `y` out of bounds /// - when providing values that cannot be converted to Rust's `char`. - fn set(mut instance, x: val usize, y: val usize, value: val u32) { - instance.set(x, y, char::from_u32(value).unwrap()) + mut fn set(x: usize, y: usize, value: u32) { + prepare(value) { char::from_u32(value).unwrap() }; }; /// Sets the value of all cells in the grid. @@ -71,19 +100,13 @@ wrap_methods!(CharGrid; /// /// - `value`: the value to set all cells to /// - when providing values that cannot be converted to Rust's `char`. - fn fill(mut instance, value: val u32) { - instance.fill(char::from_u32(value).unwrap()) + mut fn fill(value: u32) { + prepare(value) { char::from_u32(value).unwrap() }; }; - /// 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), - }) - }; + /// Gets the width of the grid. + ref fn width() -> usize; + + /// Gets the height of the grid. + ref fn height() -> usize; ); diff --git a/src/containers/cp437_grid.rs b/src/containers/cp437_grid.rs index 62f0eb2..2ed9aba 100644 --- a/src/containers/cp437_grid.rs +++ b/src/containers/cp437_grid.rs @@ -1,43 +1,103 @@ +use crate::macros::wrap_functions; use crate::{ - containers::{wrap_grid, ByteSlice}, - macros::{wrap_functions, wrap_methods}, + containers::ByteSlice, + macros::{wrap_clone, wrap_free, wrap_methods}, + mem::{heap_move_nonnull, heap_move_ok, heap_move_some, heap_remove}, }; use servicepoint::{ Cp437Grid, Cp437GridCommand, DataRef, Grid, Origin, Packet, }; use std::ptr::NonNull; -wrap_grid!(Cp437Grid, u8); +wrap_functions!(sp_cp437_grid; -wrap_functions!(associate Cp437Grid; /// Creates a new [Cp437Grid] with the specified dimensions. /// /// returns: [Cp437Grid] initialized to 0. - fn new(width: val usize, height: val usize) -> move NonNull { - Cp437Grid::new(width, height) - }; + fn new( + width: usize, + height: usize, + ) -> NonNull { + heap_move_nonnull(Cp437Grid::new(width, height)) + } /// Loads a [Cp437Grid] with the specified dimensions from the provided data. - fn load(width: val usize, height: val usize, data: slice ByteSlice) -> move_some *mut Cp437Grid { - Cp437Grid::load(width, height, 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)) + } -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 try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet { - Packet::try_from(Cp437GridCommand { + fn into_packet( + grid: NonNull, + x: usize, + y: usize, + ) -> *mut Packet { + let grid = unsafe { heap_remove(grid) }; + heap_move_ok(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. - fn data_ref_mut(mut instance) -> slice ByteSlice; + mut fn data_ref_mut() -> ByteSlice { + return(slice) { unsafe { ByteSlice::from_slice(slice) } }; + }; ); diff --git a/src/containers/mod.rs b/src/containers/mod.rs index 608d038..62d51d0 100644 --- a/src/containers/mod.rs +++ b/src/containers/mod.rs @@ -11,68 +11,3 @@ 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 f884a83..344a1a2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,8 @@ //! //! # Examples //! +//! Make sure to check out [this GitHub repo](https://github.com/arfst23/ServicePoint) as well! +//! //! ```C //! #include //! #include "servicepoint.h" @@ -22,32 +24,36 @@ //! 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; -pub(crate) mod macros; +mod macros; pub(crate) mod mem; -/// Functions related to [servicepoint::Packet]. +/// Functions related to [Packet]. pub mod packet; -/// Functions related to [servicepoint::UdpSocketExt]. +/// Functions related to [UdpSocket]. 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!(envlogger; + wrap_functions!(sp_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 79cd3af..4157f28 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,270 +1,239 @@ -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_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_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! 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! 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_ref { + ($ident:ident) => { + $ident.as_ref() }; } +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 { ( - $object_type:ident; + $prefix:ident :: $object_type:ty; $( $(#[$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)?; + $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;)? + })? + ; )+ ) => { paste::paste! { - $( - $crate::macros::wrap_method!($object_type; + $crate::macros::wrap_functions!($prefix; + $( + #[doc = concat!(" Calls [`servicepoint::", stringify!($object_type), + "::", stringify!($function), "`].")] + #[doc = ""] $(#[$meta])* - fn $function($ref_or_mut $instance $(, $($param_name: $param_modifier $param_type),*)?) - $(-> $return_modifier $return_type)? - $($impl)?; + 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; + } + )+ ); - )+ - } - }; -} - -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 { ( - $object_type:ident; + $prefix:ident :: $object_type:ty; $( - prop $prop_name:ident : $prop_type:ty { $($accessor:ident $($modifier: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;)? + })?; + )? + }; )+ ) => { - $($( - ::paste::paste!{ - $crate::macros::wrap_fields_accessor! { - $($modifier)? $accessor; - $object_type :: $prop_name: $prop_type - } - } - )+)+ - }; -} - -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() } - }; -} - -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)? - { + paste::paste! { + $crate::macros::wrap_functions!($prefix; + $( $( - 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); + #[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; + } )? - result - } + + $( + #[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); + } + )? + + $( + #[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; + } + )? + + $( + #[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; + } + )? + )+ + ); } }; } macro_rules! wrap_functions { ( - $module:ident; + $prefix:ident; $( $(#[$meta:meta])+ - fn $function:ident($($param_name:ident: $param_modifier:ident $param_type:ty),*$(,)?) - $(-> $return_modifier:ident $return_type:ty)? - $block:block; + fn $function:ident($($param_name:ident: $param_type:ty),*$(,)?) + $(-> $return_type:ty)? + $block:block )+ ) => { ::paste::paste! { $( - $crate::macros::wrap_function!($module; - $(#[$meta])+ - fn $function($($param_name: $param_modifier $param_type),*) $(-> $return_modifier $return_type)? - $block; - ); + $(#[$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 + )+ } }; - ( - 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 { - apply_param_modifier, apply_return_modifier, derive_clone, derive_free, - wrap_fields, wrap_fields_accessor, wrap_function, wrap_functions, - wrap_method, wrap_methods, + nonnull_as_mut, nonnull_as_ref, wrap_clone, wrap_fields, wrap_free, + wrap_functions, wrap_methods, }; diff --git a/src/packet.rs b/src/packet.rs index bec75e5..4278fe0 100644 --- a/src/packet.rs +++ b/src/packet.rs @@ -1,89 +1,103 @@ use crate::{ containers::ByteSlice, - macros::{ - derive_clone, derive_free, wrap_fields, wrap_functions, wrap_methods, - }, + macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, + mem::{heap_move_nonnull, heap_move_ok}, }; use servicepoint::{CommandCode, Header, Packet}; use std::ptr::NonNull; -wrap_functions!(associate Packet; +wrap_functions!(sp_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: slice ByteSlice) -> move_ok *mut Packet { - servicepoint::Packet::try_from(data) - }; + fn try_load(data: ByteSlice) -> *mut Packet { + let data = unsafe { data.as_slice() }; + heap_move_ok(servicepoint::Packet::try_from(data)) + } /// Creates a raw [Packet] from parts. /// /// returns: new instance. Will never return null. - fn from_parts(header: val Header, payload: val ByteSlice) -> move NonNull { + fn from_parts(header: Header, payload: ByteSlice) -> NonNull { let payload = if payload == ByteSlice::INVALID { None } else { Some(Vec::from(unsafe { payload.as_slice() })) }; - Packet { header, payload } - }; -); + heap_move_nonnull(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(mut packet) -> val ByteSlice { - match &mut packet.payload { - None => ByteSlice::INVALID, - Some(payload) => unsafe { ByteSlice::from_slice(payload) }, + fn get_payload(packet: NonNull) -> ByteSlice { + unsafe { + match &mut (*packet.as_ptr()).payload { + None => ByteSlice::INVALID, + Some(payload) => ByteSlice::from_slice(payload), + } } - }; + } /// Sets the payload of the provided packet to the provided data. /// /// This makes previous payload pointers invalid. - fn set_payload(mut packet, data: val ByteSlice) { - packet.payload = if data == ByteSlice::INVALID { - None - } else { - Some(unsafe { data.as_slice().to_vec() }) + fn set_payload(packet: NonNull, data: ByteSlice) { + unsafe { + (*packet.as_ptr()).payload = if data == ByteSlice::INVALID { + None + } else { + Some(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(mut packet, buffer: val ByteSlice) -> val usize { + fn serialize_to(packet: NonNull, buffer: ByteSlice) -> usize { unsafe { - packet.serialize_to(buffer.as_slice_mut()).unwrap_or(0) + packet.as_ref().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: val u16, result: mut NonNull) -> val bool { + fn u16_to_command_code( + code: u16, + result: *mut CommandCode, + ) -> bool { match CommandCode::try_from(code) { Ok(code) => { - *result = code; + unsafe { + *result = code; + } true } Err(_) => false, } - }; + } + ); diff --git a/src/udp.rs b/src/udp.rs index ba9b336..cb96547 100644 --- a/src/udp.rs +++ b/src/udp.rs @@ -1,7 +1,7 @@ use crate::{ - commands::{CommandTag, GenericCommand}, - macros::{derive_free, wrap_functions, wrap_methods}, - mem::heap_remove, + commands::{CommandTag, SPCommand}, + macros::{wrap_free, wrap_functions}, + mem::{heap_move_ok, heap_remove}, }; use servicepoint::{Header, Packet, UdpSocketExt}; use std::{ @@ -10,9 +10,10 @@ use std::{ ptr::NonNull, }; -derive_free!(UdpSocket); +wrap_free!(sp_udp::UdpSocket); + +wrap_functions!(sp_udp; -wrap_functions!(associate UdpSocket; /// Creates a new instance of [UdpSocket]. /// /// returns: NULL if connection fails, or connected instance @@ -24,12 +25,13 @@ wrap_functions!(associate UdpSocket; /// if (connection != NULL) /// sp_udp_send_command(connection, sp_command_clear()); /// ``` - fn open(host: val NonNull) -> move_ok *mut UdpSocket { + fn open(host: NonNull) -> *mut UdpSocket { let host = unsafe { CStr::from_ptr(host.as_ptr()) } .to_str() .expect("Bad encoding"); - UdpSocket::bind_connect(host) - }; + + heap_move_ok(UdpSocket::bind_connect(host)) + } /// Creates a new instance of [UdpSocket]. /// @@ -42,23 +44,22 @@ wrap_functions!(associate UdpSocket; /// if (connection != NULL) /// sp_udp_send_command(connection, sp_command_clear()); /// ``` - fn open_ipv4(ip1: val u8, ip2: val u8, ip3: val u8, ip4: val u8, port: val u16) -> move_ok *mut UdpSocket { + fn open_ipv4(ip1: u8, ip2: u8, ip3: u8, ip4: u8, port: u16) -> *mut UdpSocket { let addr = SocketAddrV4::new(Ipv4Addr::from([ip1, ip2, ip3, ip4]), port); - UdpSocket::bind_connect(addr) - }; -); + heap_move_ok(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(ref connection, packet: move NonNull) -> val bool { - connection.send(&Vec::from(packet)).is_ok() - }; + fn send_packet(connection: NonNull, packet: NonNull) -> bool { + let packet = unsafe { heap_remove(packet) }; + unsafe { connection.as_ref().send(&Vec::from(packet)) }.is_ok() + } - /// Sends a [GenericCommand] to the display using the [UdpSocket]. + /// Sends a [SPCommand] to the display using the [UdpSocket]. /// /// The passed `command` gets consumed. /// @@ -69,25 +70,44 @@ wrap_methods! {UdpSocket; /// ```C /// sp_udp_send_command(connection, sp_command_brightness(5)); /// ``` - fn send_command(ref connection, command: mut NonNull) -> val bool { + fn send_command(connection: NonNull, command: SPCommand) -> bool { unsafe { - let result = match command.tag { + match command.tag { CommandTag::Invalid => return false, - 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 + 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)), + } } - }; + .is_some() + } /// Sends a [Header] to the display using the [UdpSocket]. /// @@ -98,19 +118,14 @@ wrap_methods! {UdpSocket; /// ```C /// sp_udp_send_header(connection, sp_command_brightness(5)); /// ``` - fn send_header(ref udp_connection, header: val Header) -> val bool { + fn send_header(udp_connection: NonNull, header: Header) -> bool { let packet = Packet { header, payload: None, }; - udp_connection.send(&Vec::from(packet)).is_ok() - }; -} + unsafe { udp_connection.as_ref() } + .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; -} +);