generic wrap
This commit is contained in:
parent
5beea6151a
commit
c65b735f57
|
@ -1,43 +1,43 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
commands::{wrap_command, wrap_origin_accessors},
|
commands::{wrap_command, wrap_origin_accessors},
|
||||||
macros::{wrap, wrap_functions},
|
macros::wrap,
|
||||||
};
|
};
|
||||||
use servicepoint::{Bitmap, BitmapCommand, CompressionCode, Origin};
|
use servicepoint::{Bitmap, BitmapCommand, CompressionCode, Origin};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
wrap_command!(Bitmap);
|
wrap_command!(Bitmap);
|
||||||
|
|
||||||
wrap!(BitmapCommand;
|
|
||||||
prop bitmap: Bitmap { get mut; set move; };
|
|
||||||
prop compression: CompressionCode { get; set; };
|
|
||||||
);
|
|
||||||
|
|
||||||
wrap_origin_accessors!(BitmapCommand);
|
wrap_origin_accessors!(BitmapCommand);
|
||||||
|
|
||||||
wrap_functions!(associate BitmapCommand;
|
wrap! {
|
||||||
/// Sets a window of pixels to the specified values.
|
BitmapCommand {
|
||||||
///
|
properties:
|
||||||
/// The passed [Bitmap] gets consumed.
|
prop bitmap: Bitmap { get mut; set move; };
|
||||||
///
|
prop compression: CompressionCode { get; set; };
|
||||||
/// Returns: a new [BitmapCommand] instance.
|
functions:
|
||||||
fn new(
|
/// Sets a window of pixels to the specified values.
|
||||||
bitmap: move NonNull<Bitmap>,
|
///
|
||||||
origin_x: val usize,
|
/// The passed [Bitmap] gets consumed.
|
||||||
origin_y: val usize,
|
///
|
||||||
compression: val CompressionCode,
|
/// Returns: a new [BitmapCommand] instance.
|
||||||
) -> move NonNull<BitmapCommand> {
|
fn new(
|
||||||
BitmapCommand {
|
bitmap: move NonNull<Bitmap>,
|
||||||
bitmap,
|
origin_x: val usize,
|
||||||
origin: Origin::new(origin_x, origin_y),
|
origin_y: val usize,
|
||||||
compression,
|
compression: val CompressionCode,
|
||||||
}
|
) -> move NonNull<BitmapCommand> {
|
||||||
};
|
BitmapCommand {
|
||||||
|
bitmap,
|
||||||
|
origin: Origin::new(origin_x, origin_y),
|
||||||
|
compression,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// Move the provided [Bitmap] into a new [BitmapCommand],
|
/// Move the provided [Bitmap] into a new [BitmapCommand],
|
||||||
/// leaving other fields as their default values.
|
/// leaving other fields as their default values.
|
||||||
///
|
///
|
||||||
/// Rust equivalent: `BitmapCommand::from(bitmap)`
|
/// Rust equivalent: `BitmapCommand::from(bitmap)`
|
||||||
fn from_bitmap(bitmap: move NonNull<Bitmap>) -> move NonNull<BitmapCommand> {
|
fn from_bitmap(bitmap: move NonNull<Bitmap>) -> move NonNull<BitmapCommand> {
|
||||||
bitmap.into()
|
bitmap.into()
|
||||||
};
|
};
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
use crate::{
|
use crate::{commands::wrap_command, macros::wrap};
|
||||||
commands::wrap_command,
|
|
||||||
macros::{wrap, wrap_functions},
|
|
||||||
};
|
|
||||||
use servicepoint::{
|
use servicepoint::{
|
||||||
BinaryOperation, BitVecCommand, CompressionCode, DisplayBitVec, Offset,
|
BinaryOperation, BitVecCommand, CompressionCode, DisplayBitVec, Offset,
|
||||||
};
|
};
|
||||||
|
@ -9,37 +6,38 @@ use std::ptr::NonNull;
|
||||||
|
|
||||||
wrap_command!(BitVec);
|
wrap_command!(BitVec);
|
||||||
|
|
||||||
wrap!(BitVecCommand;
|
wrap!(
|
||||||
prop bitvec: DisplayBitVec { get mut; set move; };
|
BitVecCommand {
|
||||||
prop offset: Offset { get; set; };
|
properties:
|
||||||
prop operation: BinaryOperation { get; set; };
|
prop bitvec: DisplayBitVec { get mut; set move; };
|
||||||
prop compression: CompressionCode { get; set; };
|
prop offset: Offset { get; set; };
|
||||||
);
|
prop operation: BinaryOperation { get; set; };
|
||||||
|
prop compression: CompressionCode { get; set; };
|
||||||
wrap_functions!(associate BitVecCommand;
|
functions:
|
||||||
/// Set pixel data starting at the pixel offset on screen.
|
/// Set pixel data starting at the pixel offset on screen.
|
||||||
///
|
///
|
||||||
/// The screen will continuously overwrite more pixel data without regarding the offset, meaning
|
/// 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.
|
/// 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.
|
/// The [`BinaryOperation`] will be applied on the display comparing old and sent bit.
|
||||||
///
|
///
|
||||||
/// `new_bit = old_bit op 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.
|
/// For example, [`BinaryOperation::Or`] can be used to turn on some pixels without affecting other pixels.
|
||||||
///
|
///
|
||||||
/// The contained [`DisplayBitVec`] is always uncompressed.
|
/// The contained [`DisplayBitVec`] is always uncompressed.
|
||||||
fn new(
|
fn new(
|
||||||
bitvec: move NonNull<DisplayBitVec>,
|
bitvec: move NonNull<DisplayBitVec>,
|
||||||
offset: val usize,
|
offset: val usize,
|
||||||
operation: val BinaryOperation,
|
operation: val BinaryOperation,
|
||||||
compression: val CompressionCode,
|
compression: val CompressionCode,
|
||||||
) -> move NonNull<BitVecCommand> {
|
) -> move NonNull<BitVecCommand> {
|
||||||
BitVecCommand {
|
BitVecCommand {
|
||||||
bitvec,
|
bitvec,
|
||||||
offset,
|
offset,
|
||||||
operation,
|
operation,
|
||||||
compression,
|
compression,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,38 +1,38 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
commands::{wrap_command, wrap_origin_accessors},
|
commands::{wrap_command, wrap_origin_accessors},
|
||||||
macros::{wrap, wrap_functions},
|
macros::wrap,
|
||||||
};
|
};
|
||||||
use servicepoint::{BrightnessGrid, BrightnessGridCommand, Origin};
|
use servicepoint::{BrightnessGrid, BrightnessGridCommand, Origin};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
wrap_command!(BrightnessGrid);
|
wrap_command!(BrightnessGrid);
|
||||||
|
|
||||||
wrap!(BrightnessGridCommand;
|
|
||||||
prop grid: BrightnessGrid { get mut; set move; };
|
|
||||||
);
|
|
||||||
|
|
||||||
wrap_origin_accessors!(BrightnessGridCommand);
|
wrap_origin_accessors!(BrightnessGridCommand);
|
||||||
|
|
||||||
wrap_functions!(associate BrightnessGridCommand;
|
wrap!(
|
||||||
/// Set the brightness of individual tiles in a rectangular area of the display.
|
BrightnessGridCommand {
|
||||||
///
|
properties:
|
||||||
/// The passed [BrightnessGrid] gets consumed.
|
prop grid: BrightnessGrid { get mut; set move; };
|
||||||
///
|
functions:
|
||||||
/// Returns: a new [BrightnessGridCommand] instance.
|
/// Set the brightness of individual tiles in a rectangular area of the display.
|
||||||
fn new(
|
///
|
||||||
grid: move NonNull<BrightnessGrid>,
|
/// The passed [BrightnessGrid] gets consumed.
|
||||||
origin_x: val usize,
|
///
|
||||||
origin_y: val usize
|
/// Returns: a new [BrightnessGridCommand] instance.
|
||||||
) -> move NonNull<BrightnessGridCommand> {
|
fn new(
|
||||||
BrightnessGridCommand {
|
grid: move NonNull<BrightnessGrid>,
|
||||||
grid,
|
origin_x: val usize,
|
||||||
origin: Origin::new(origin_x, origin_y),
|
origin_y: val usize
|
||||||
}
|
) -> move NonNull<BrightnessGridCommand> {
|
||||||
};
|
BrightnessGridCommand {
|
||||||
|
grid,
|
||||||
|
origin: Origin::new(origin_x, origin_y),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// Moves the provided [BrightnessGrid] into a new [BrightnessGridCommand],
|
/// Moves the provided [BrightnessGrid] into a new [BrightnessGridCommand],
|
||||||
/// leaving other fields as their default values.
|
/// leaving other fields as their default values.
|
||||||
fn from_grid(grid: move NonNull<BrightnessGrid>) -> move NonNull<BrightnessGridCommand> {
|
fn from_grid(grid: move NonNull<BrightnessGrid>) -> move NonNull<BrightnessGridCommand> {
|
||||||
grid.into()
|
grid.into()
|
||||||
};
|
};
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{commands::wrap_command, macros::wrap_functions};
|
use crate::commands::wrap_command;
|
||||||
use servicepoint::{ClearCommand, FadeOutCommand, HardResetCommand};
|
use servicepoint::{ClearCommand, FadeOutCommand, HardResetCommand};
|
||||||
|
|
||||||
macro_rules! wrap_cc_only {
|
macro_rules! wrap_cc_only {
|
||||||
|
@ -6,14 +6,17 @@ macro_rules! wrap_cc_only {
|
||||||
::paste::paste!{
|
::paste::paste!{
|
||||||
wrap_command!($command);
|
wrap_command!($command);
|
||||||
|
|
||||||
wrap_functions!(associate [< $command Command >];
|
$crate::macros::wrap!{
|
||||||
$(#[$meta])*
|
[< $command Command >] {
|
||||||
///
|
functions:
|
||||||
#[doc = " Returns: a new [`" [< $command Command >] "`] instance."]
|
$(#[$meta])*
|
||||||
fn new() -> move ::core::ptr::NonNull<[< $command Command >]> {
|
///
|
||||||
[< $command Command >]
|
#[doc = " Returns: a new [`" [< $command Command >] "`] instance."]
|
||||||
};
|
fn new() -> move ::core::ptr::NonNull<[< $command Command >]> {
|
||||||
);
|
[< $command Command >]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +1,38 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
commands::{wrap_command, wrap_origin_accessors},
|
commands::{wrap_command, wrap_origin_accessors},
|
||||||
macros::{wrap, wrap_functions},
|
macros::wrap,
|
||||||
};
|
};
|
||||||
use servicepoint::{CharGrid, CharGridCommand, Origin};
|
use servicepoint::{CharGrid, CharGridCommand, Origin};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
wrap_command!(CharGrid);
|
wrap_command!(CharGrid);
|
||||||
|
|
||||||
wrap!(CharGridCommand;
|
|
||||||
prop grid: CharGrid { get mut; set move; };
|
|
||||||
);
|
|
||||||
|
|
||||||
wrap_origin_accessors!(CharGridCommand);
|
wrap_origin_accessors!(CharGridCommand);
|
||||||
|
|
||||||
wrap_functions!(associate CharGridCommand;
|
wrap!(
|
||||||
/// Show UTF-8 encoded text on the screen.
|
CharGridCommand {
|
||||||
///
|
properties:
|
||||||
/// The passed [CharGrid] gets consumed.
|
prop grid: CharGrid { get mut; set move; };
|
||||||
///
|
functions:
|
||||||
/// Returns: a new [CharGridCommand] instance.
|
/// Show UTF-8 encoded text on the screen.
|
||||||
fn new(
|
///
|
||||||
grid: move NonNull<CharGrid>,
|
/// The passed [CharGrid] gets consumed.
|
||||||
origin_x: val usize,
|
///
|
||||||
origin_y: val usize,
|
/// Returns: a new [CharGridCommand] instance.
|
||||||
) -> move NonNull<CharGridCommand> {
|
fn new(
|
||||||
CharGridCommand {
|
grid: move NonNull<CharGrid>,
|
||||||
grid,
|
origin_x: val usize,
|
||||||
origin: Origin::new(origin_x, origin_y),
|
origin_y: val usize,
|
||||||
}
|
) -> move NonNull<CharGridCommand> {
|
||||||
};
|
CharGridCommand {
|
||||||
|
grid,
|
||||||
|
origin: Origin::new(origin_x, origin_y),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// Moves the provided [CharGrid] into a new [CharGridCommand],
|
/// Moves the provided [CharGrid] into a new [CharGridCommand],
|
||||||
/// leaving other fields as their default values.
|
/// leaving other fields as their default values.
|
||||||
fn from_grid(grid: move NonNull<CharGrid>) -> move NonNull<CharGridCommand> {
|
fn from_grid(grid: move NonNull<CharGrid>) -> move NonNull<CharGridCommand> {
|
||||||
grid.into()
|
grid.into()
|
||||||
};
|
};
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,38 +1,38 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
commands::{wrap_command, wrap_origin_accessors},
|
commands::{wrap_command, wrap_origin_accessors},
|
||||||
macros::{wrap, wrap_functions},
|
macros::wrap,
|
||||||
};
|
};
|
||||||
use servicepoint::{Cp437Grid, Cp437GridCommand, Origin};
|
use servicepoint::{Cp437Grid, Cp437GridCommand, Origin};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
wrap_command!(Cp437Grid);
|
wrap_command!(Cp437Grid);
|
||||||
|
|
||||||
wrap!(Cp437GridCommand;
|
|
||||||
prop grid: Cp437Grid { get mut; set move; };
|
|
||||||
);
|
|
||||||
|
|
||||||
wrap_origin_accessors!(Cp437GridCommand);
|
wrap_origin_accessors!(Cp437GridCommand);
|
||||||
|
|
||||||
wrap_functions!(associate Cp437GridCommand;
|
wrap!(
|
||||||
/// Show text on the screen.
|
Cp437GridCommand {
|
||||||
///
|
properties:
|
||||||
/// The text is sent in the form of a 2D grid of [CP-437] encoded characters.
|
prop grid: Cp437Grid { get mut; set move; };
|
||||||
///
|
functions:
|
||||||
/// The origin is relative to the top-left of the display.
|
/// Show text on the screen.
|
||||||
fn new(
|
///
|
||||||
grid: move NonNull<Cp437Grid>,
|
/// The text is sent in the form of a 2D grid of [CP-437] encoded characters.
|
||||||
origin_x: val usize,
|
///
|
||||||
origin_y: val usize,
|
/// The origin is relative to the top-left of the display.
|
||||||
) -> move NonNull<Cp437GridCommand> {
|
fn new(
|
||||||
Cp437GridCommand {
|
grid: move NonNull<Cp437Grid>,
|
||||||
grid,
|
origin_x: val usize,
|
||||||
origin: Origin::new(origin_x, origin_y),
|
origin_y: val usize,
|
||||||
}
|
) -> move NonNull<Cp437GridCommand> {
|
||||||
};
|
Cp437GridCommand {
|
||||||
|
grid,
|
||||||
|
origin: Origin::new(origin_x, origin_y),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// Moves the provided [Cp437Grid] into a new [Cp437GridCommand],
|
/// Moves the provided [Cp437Grid] into a new [Cp437GridCommand],
|
||||||
/// leaving other fields as their default values.
|
/// leaving other fields as their default values.
|
||||||
fn from_grid(grid: move NonNull<Cp437Grid>) -> move NonNull<Cp437GridCommand> {
|
fn from_grid(grid: move NonNull<Cp437Grid>) -> move NonNull<Cp437GridCommand> {
|
||||||
grid.into()
|
grid.into()
|
||||||
};
|
};
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
macros::{derive_clone, derive_free, wrap, wrap_functions},
|
macros::{derive_clone, derive_free, wrap},
|
||||||
mem::{
|
mem::{
|
||||||
heap_clone, heap_drop, heap_move, heap_move_nonnull, heap_move_ok,
|
heap_clone, heap_drop, heap_move, heap_move_nonnull, heap_move_ok,
|
||||||
heap_remove,
|
heap_remove,
|
||||||
|
@ -69,8 +69,6 @@ impl GenericCommand {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
derive_clone!(GenericCommand);
|
|
||||||
|
|
||||||
impl Clone for GenericCommand {
|
impl Clone for GenericCommand {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -144,8 +142,6 @@ impl Clone for GenericCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
derive_free!(GenericCommand);
|
|
||||||
|
|
||||||
impl Drop for GenericCommand {
|
impl Drop for GenericCommand {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -172,122 +168,126 @@ impl Drop for GenericCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wrap_functions!(associate GenericCommand;
|
derive_clone!(GenericCommand);
|
||||||
/// Tries to turn a [Packet] into a [GenericCommand].
|
derive_free!(GenericCommand);
|
||||||
///
|
|
||||||
/// 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<Packet>) -> move NonNull<GenericCommand> {
|
|
||||||
servicepoint::TypedCommand::try_from(packet)
|
|
||||||
.map(|value| match value {
|
|
||||||
TypedCommand::Clear(clear) => GenericCommand {
|
|
||||||
tag: CommandTag::Clear,
|
|
||||||
data: CommandUnion {
|
|
||||||
clear: heap_move_nonnull(clear),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TypedCommand::CharGrid(char_grid) => GenericCommand {
|
|
||||||
tag: CommandTag::CharGrid,
|
|
||||||
data: CommandUnion {
|
|
||||||
char_grid: heap_move_nonnull(char_grid),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TypedCommand::Cp437Grid(cp437_grid) => GenericCommand {
|
|
||||||
tag: CommandTag::Cp437Grid,
|
|
||||||
data: CommandUnion {
|
|
||||||
cp437_grid: heap_move_nonnull(cp437_grid),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TypedCommand::Bitmap(bitmap) => GenericCommand {
|
|
||||||
tag: CommandTag::Bitmap,
|
|
||||||
data: CommandUnion {
|
|
||||||
bitmap: heap_move_nonnull(bitmap),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TypedCommand::Brightness(global_brightness) => GenericCommand {
|
|
||||||
tag: CommandTag::GlobalBrightness,
|
|
||||||
data: CommandUnion {
|
|
||||||
global_brightness: heap_move_nonnull(global_brightness),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TypedCommand::BrightnessGrid(brightness_grid) => GenericCommand {
|
|
||||||
tag: CommandTag::BrightnessGrid,
|
|
||||||
data: CommandUnion {
|
|
||||||
brightness_grid: heap_move_nonnull(brightness_grid),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TypedCommand::BitVec(bitvec) => GenericCommand {
|
|
||||||
tag: CommandTag::BitVec,
|
|
||||||
data: CommandUnion {
|
|
||||||
bit_vec: heap_move_nonnull(bitvec),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TypedCommand::HardReset(hard_reset) => GenericCommand {
|
|
||||||
tag: CommandTag::HardReset,
|
|
||||||
data: CommandUnion {
|
|
||||||
hard_reset: heap_move_nonnull(hard_reset),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TypedCommand::FadeOut(fade_out) => GenericCommand {
|
|
||||||
tag: CommandTag::FadeOut,
|
|
||||||
data: CommandUnion {
|
|
||||||
fade_out: heap_move_nonnull(fade_out),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
#[allow(deprecated)]
|
|
||||||
TypedCommand::BitmapLegacy(bitmap_legacy) => GenericCommand {
|
|
||||||
tag: CommandTag::BitmapLegacy,
|
|
||||||
data: CommandUnion {
|
|
||||||
bitmap_legacy: heap_move_nonnull(bitmap_legacy),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.unwrap_or_else(move |_| GenericCommand {
|
|
||||||
tag: CommandTag::Invalid,
|
|
||||||
data: CommandUnion { null: null_mut() },
|
|
||||||
})
|
|
||||||
};
|
|
||||||
);
|
|
||||||
|
|
||||||
wrap! { GenericCommand;
|
wrap! {
|
||||||
/// Tries to turn a [GenericCommand] into a [Packet].
|
GenericCommand {
|
||||||
/// The [GenericCommand] gets consumed.
|
functions:
|
||||||
///
|
/// Tries to turn a [Packet] into a [GenericCommand].
|
||||||
/// Returns tag [CommandTag::Invalid] in case of an error.
|
///
|
||||||
method try_into_packet(move command) -> val *mut Packet {
|
/// The packet is dropped in the process.
|
||||||
match command.tag {
|
///
|
||||||
CommandTag::Invalid => null_mut(),
|
/// Returns: pointer to new [GenericCommand] instance or NULL if parsing failed.
|
||||||
CommandTag::Bitmap => {
|
fn try_from_packet(packet: move NonNull<Packet>) -> move NonNull<GenericCommand> {
|
||||||
heap_move_ok(unsafe { heap_remove(command.data.bitmap).try_into() })
|
servicepoint::TypedCommand::try_from(packet)
|
||||||
|
.map(|value| match value {
|
||||||
|
TypedCommand::Clear(clear) => GenericCommand {
|
||||||
|
tag: CommandTag::Clear,
|
||||||
|
data: CommandUnion {
|
||||||
|
clear: heap_move_nonnull(clear),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TypedCommand::CharGrid(char_grid) => GenericCommand {
|
||||||
|
tag: CommandTag::CharGrid,
|
||||||
|
data: CommandUnion {
|
||||||
|
char_grid: heap_move_nonnull(char_grid),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TypedCommand::Cp437Grid(cp437_grid) => GenericCommand {
|
||||||
|
tag: CommandTag::Cp437Grid,
|
||||||
|
data: CommandUnion {
|
||||||
|
cp437_grid: heap_move_nonnull(cp437_grid),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TypedCommand::Bitmap(bitmap) => GenericCommand {
|
||||||
|
tag: CommandTag::Bitmap,
|
||||||
|
data: CommandUnion {
|
||||||
|
bitmap: heap_move_nonnull(bitmap),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TypedCommand::Brightness(global_brightness) => GenericCommand {
|
||||||
|
tag: CommandTag::GlobalBrightness,
|
||||||
|
data: CommandUnion {
|
||||||
|
global_brightness: heap_move_nonnull(global_brightness),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TypedCommand::BrightnessGrid(brightness_grid) => GenericCommand {
|
||||||
|
tag: CommandTag::BrightnessGrid,
|
||||||
|
data: CommandUnion {
|
||||||
|
brightness_grid: heap_move_nonnull(brightness_grid),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TypedCommand::BitVec(bitvec) => GenericCommand {
|
||||||
|
tag: CommandTag::BitVec,
|
||||||
|
data: CommandUnion {
|
||||||
|
bit_vec: heap_move_nonnull(bitvec),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TypedCommand::HardReset(hard_reset) => GenericCommand {
|
||||||
|
tag: CommandTag::HardReset,
|
||||||
|
data: CommandUnion {
|
||||||
|
hard_reset: heap_move_nonnull(hard_reset),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TypedCommand::FadeOut(fade_out) => GenericCommand {
|
||||||
|
tag: CommandTag::FadeOut,
|
||||||
|
data: CommandUnion {
|
||||||
|
fade_out: heap_move_nonnull(fade_out),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
#[allow(deprecated)]
|
||||||
|
TypedCommand::BitmapLegacy(bitmap_legacy) => GenericCommand {
|
||||||
|
tag: CommandTag::BitmapLegacy,
|
||||||
|
data: CommandUnion {
|
||||||
|
bitmap_legacy: heap_move_nonnull(bitmap_legacy),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.unwrap_or_else(move |_| GenericCommand {
|
||||||
|
tag: CommandTag::Invalid,
|
||||||
|
data: CommandUnion { null: null_mut() },
|
||||||
|
})
|
||||||
|
};
|
||||||
|
methods:
|
||||||
|
/// Tries to turn a [GenericCommand] into a [Packet].
|
||||||
|
/// The [GenericCommand] gets consumed.
|
||||||
|
///
|
||||||
|
/// Returns tag [CommandTag::Invalid] in case of an error.
|
||||||
|
fn try_into_packet(move command) -> val *mut Packet {
|
||||||
|
match command.tag {
|
||||||
|
CommandTag::Invalid => null_mut(),
|
||||||
|
CommandTag::Bitmap => {
|
||||||
|
heap_move_ok(unsafe { heap_remove(command.data.bitmap).try_into() })
|
||||||
|
}
|
||||||
|
CommandTag::BitVec => {
|
||||||
|
heap_move_ok(unsafe { heap_remove(command.data.bit_vec).try_into() })
|
||||||
|
}
|
||||||
|
CommandTag::BrightnessGrid => heap_move_ok(unsafe {
|
||||||
|
heap_remove(command.data.brightness_grid).try_into()
|
||||||
|
}),
|
||||||
|
CommandTag::CharGrid => heap_move_ok(unsafe {
|
||||||
|
heap_remove(command.data.char_grid).try_into()
|
||||||
|
}),
|
||||||
|
CommandTag::Cp437Grid => heap_move_ok(unsafe {
|
||||||
|
heap_remove(command.data.cp437_grid).try_into()
|
||||||
|
}),
|
||||||
|
CommandTag::GlobalBrightness => heap_move(unsafe {
|
||||||
|
heap_remove(command.data.global_brightness).into()
|
||||||
|
}),
|
||||||
|
CommandTag::Clear => {
|
||||||
|
heap_move(unsafe { heap_remove(command.data.clear).into() })
|
||||||
|
}
|
||||||
|
CommandTag::HardReset => {
|
||||||
|
heap_move(unsafe { heap_remove(command.data.hard_reset).into() })
|
||||||
|
}
|
||||||
|
CommandTag::FadeOut => {
|
||||||
|
heap_move(unsafe { heap_remove(command.data.fade_out).into() })
|
||||||
|
}
|
||||||
|
CommandTag::BitmapLegacy => {
|
||||||
|
heap_move(unsafe { heap_remove(command.data.bitmap_legacy).into() })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CommandTag::BitVec => {
|
};
|
||||||
heap_move_ok(unsafe { heap_remove(command.data.bit_vec).try_into() })
|
}
|
||||||
}
|
|
||||||
CommandTag::BrightnessGrid => heap_move_ok(unsafe {
|
|
||||||
heap_remove(command.data.brightness_grid).try_into()
|
|
||||||
}),
|
|
||||||
CommandTag::CharGrid => heap_move_ok(unsafe {
|
|
||||||
heap_remove(command.data.char_grid).try_into()
|
|
||||||
}),
|
|
||||||
CommandTag::Cp437Grid => heap_move_ok(unsafe {
|
|
||||||
heap_remove(command.data.cp437_grid).try_into()
|
|
||||||
}),
|
|
||||||
CommandTag::GlobalBrightness => heap_move(unsafe {
|
|
||||||
heap_remove(command.data.global_brightness).into()
|
|
||||||
}),
|
|
||||||
CommandTag::Clear => {
|
|
||||||
heap_move(unsafe { heap_remove(command.data.clear).into() })
|
|
||||||
}
|
|
||||||
CommandTag::HardReset => {
|
|
||||||
heap_move(unsafe { heap_remove(command.data.hard_reset).into() })
|
|
||||||
}
|
|
||||||
CommandTag::FadeOut => {
|
|
||||||
heap_move(unsafe { heap_remove(command.data.fade_out).into() })
|
|
||||||
}
|
|
||||||
CommandTag::BitmapLegacy => {
|
|
||||||
heap_move(unsafe { heap_remove(command.data.bitmap_legacy).into() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,19 @@
|
||||||
use crate::{
|
use crate::{commands::wrap_command, macros::wrap};
|
||||||
commands::wrap_command,
|
|
||||||
macros::{wrap, wrap_functions},
|
|
||||||
};
|
|
||||||
use servicepoint::{Brightness, GlobalBrightnessCommand};
|
use servicepoint::{Brightness, GlobalBrightnessCommand};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
wrap_functions!(associate GlobalBrightnessCommand;
|
|
||||||
/// Set the brightness of all tiles to the same value.
|
|
||||||
///
|
|
||||||
/// Returns: a new [GlobalBrightnessCommand] instance.
|
|
||||||
fn new(brightness: val Brightness) -> move NonNull<GlobalBrightnessCommand> {
|
|
||||||
GlobalBrightnessCommand::from(brightness)
|
|
||||||
};
|
|
||||||
);
|
|
||||||
|
|
||||||
wrap_command!(GlobalBrightness);
|
wrap_command!(GlobalBrightness);
|
||||||
|
|
||||||
wrap!(GlobalBrightnessCommand;
|
wrap!(
|
||||||
prop brightness: Brightness { get; set; };
|
GlobalBrightnessCommand {
|
||||||
|
properties:
|
||||||
|
prop brightness: Brightness { get; set; };
|
||||||
|
functions:
|
||||||
|
/// Set the brightness of all tiles to the same value.
|
||||||
|
///
|
||||||
|
/// Returns: a new [GlobalBrightnessCommand] instance.
|
||||||
|
fn new(brightness: val Brightness) -> move NonNull<GlobalBrightnessCommand> {
|
||||||
|
GlobalBrightnessCommand::from(brightness)
|
||||||
|
};
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
containers::{wrap_grid, ByteSlice},
|
containers::{wrap_grid, ByteSlice},
|
||||||
macros::{wrap, wrap_functions},
|
macros::wrap,
|
||||||
};
|
};
|
||||||
use servicepoint::{
|
use servicepoint::{
|
||||||
Bitmap, BitmapCommand, CompressionCode, DataRef, DisplayBitVec, Grid,
|
Bitmap, BitmapCommand, CompressionCode, DataRef, DisplayBitVec, Grid,
|
||||||
|
@ -10,91 +10,93 @@ use std::ptr::NonNull;
|
||||||
|
|
||||||
wrap_grid!(Bitmap, bool);
|
wrap_grid!(Bitmap, bool);
|
||||||
|
|
||||||
wrap_functions!(associate Bitmap;
|
wrap! {
|
||||||
/// Creates a new [Bitmap] with the specified dimensions.
|
Bitmap {
|
||||||
///
|
functions:
|
||||||
/// # Arguments
|
/// Creates a new [Bitmap] with the specified dimensions.
|
||||||
///
|
///
|
||||||
/// - `width`: size in pixels in x-direction
|
/// # Arguments
|
||||||
/// - `height`: size in pixels in y-direction
|
///
|
||||||
///
|
/// - `width`: size in pixels in x-direction
|
||||||
/// returns: [Bitmap] initialized to all pixels off, or NULL in case of an error.
|
/// - `height`: size in pixels in y-direction
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// returns: [Bitmap] initialized to all pixels off, or NULL in case of an error.
|
||||||
///
|
///
|
||||||
/// In the following cases, this function will return NULL:
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// - when the width is not dividable by 8
|
/// In the following cases, this function will return NULL:
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// - when the width is not dividable by 8
|
||||||
///
|
///
|
||||||
/// ```C
|
/// # Examples
|
||||||
/// Cp437Grid grid = sp_bitmap_new(8, 3);
|
///
|
||||||
/// sp_bitmap_fill(grid, true);
|
/// ```C
|
||||||
/// sp_bitmap_set(grid, 0, 0, false);
|
/// Cp437Grid grid = sp_bitmap_new(8, 3);
|
||||||
/// sp_bitmap_free(grid);
|
/// sp_bitmap_fill(grid, true);
|
||||||
/// ```
|
/// sp_bitmap_set(grid, 0, 0, false);
|
||||||
fn new(width: val usize, height: val usize) -> move_some *mut Bitmap {
|
/// sp_bitmap_free(grid);
|
||||||
Bitmap::new(width, height)
|
/// ```
|
||||||
};
|
fn new(width: val usize, height: val usize) -> move_some *mut Bitmap {
|
||||||
|
Bitmap::new(width, height)
|
||||||
|
};
|
||||||
|
|
||||||
/// Creates a new [Bitmap] with a size matching the screen.
|
/// Creates a new [Bitmap] with a size matching the screen.
|
||||||
///
|
///
|
||||||
/// returns: [Bitmap] initialized to all pixels off.
|
/// returns: [Bitmap] initialized to all pixels off.
|
||||||
fn new_max_sized() -> move NonNull<Bitmap> {
|
fn new_max_sized() -> move NonNull<Bitmap> {
|
||||||
Bitmap::max_sized()
|
Bitmap::max_sized()
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Loads a [Bitmap] with the specified dimensions from the provided data.
|
/// Loads a [Bitmap] with the specified dimensions from the provided data.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// - `width`: size in pixels in x-direction
|
/// - `width`: size in pixels in x-direction
|
||||||
/// - `height`: size in pixels in y-direction
|
/// - `height`: size in pixels in y-direction
|
||||||
///
|
///
|
||||||
/// returns: [Bitmap] that contains a copy of the provided data, or NULL in case of an error.
|
/// returns: [Bitmap] that contains a copy of the provided data, or NULL in case of an error.
|
||||||
fn load(
|
fn load(
|
||||||
width: val usize,
|
width: val usize,
|
||||||
height: val usize,
|
height: val usize,
|
||||||
data: slice ByteSlice,
|
data: slice ByteSlice,
|
||||||
) -> move_ok *mut Bitmap {
|
) -> move_ok *mut Bitmap {
|
||||||
Bitmap::load(width, height, data)
|
Bitmap::load(width, height, data)
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Tries to convert the BitVec to a Bitmap.
|
/// Tries to convert the BitVec to a Bitmap.
|
||||||
///
|
///
|
||||||
/// The provided BitVec gets consumed.
|
/// The provided BitVec gets consumed.
|
||||||
///
|
///
|
||||||
/// Returns NULL in case of error.
|
/// Returns NULL in case of error.
|
||||||
fn from_bitvec(
|
fn from_bitvec(
|
||||||
width: val usize,
|
width: val usize,
|
||||||
bitvec: move NonNull<DisplayBitVec>,
|
bitvec: move NonNull<DisplayBitVec>,
|
||||||
) -> move_ok *mut Bitmap {
|
) -> move_ok *mut Bitmap {
|
||||||
Bitmap::from_bitvec(width, bitvec)
|
Bitmap::from_bitvec(width, bitvec)
|
||||||
};
|
};
|
||||||
);
|
|
||||||
|
|
||||||
wrap!(Bitmap;
|
methods:
|
||||||
/// Consumes the Bitmap and returns the contained BitVec.
|
/// Consumes the Bitmap and returns the contained BitVec.
|
||||||
method into_bitvec(move bitmap) -> move NonNull<DisplayBitVec> {
|
fn into_bitvec(move bitmap) -> move NonNull<DisplayBitVec> {
|
||||||
bitmap.into()
|
bitmap.into()
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Creates a [BitmapCommand] and immediately turns that into a [Packet].
|
/// Creates a [BitmapCommand] and immediately turns that into a [Packet].
|
||||||
///
|
///
|
||||||
/// The provided [Bitmap] gets consumed.
|
/// The provided [Bitmap] gets consumed.
|
||||||
///
|
///
|
||||||
/// Returns NULL in case of an error.
|
/// Returns NULL in case of an error.
|
||||||
method try_into_packet(move bitmap, x: val usize, y: val usize, compression: val CompressionCode) -> move_ok *mut Packet {
|
fn try_into_packet(move bitmap, x: val usize, y: val usize, compression: val CompressionCode) -> move_ok *mut Packet {
|
||||||
Packet::try_from(BitmapCommand {
|
Packet::try_from(BitmapCommand {
|
||||||
bitmap,
|
bitmap,
|
||||||
origin: Origin::new(x, y),
|
origin: Origin::new(x, y),
|
||||||
compression,
|
compression,
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Gets an unsafe reference to the data of the [Bitmap] instance.
|
/// Gets an unsafe reference to the data of the [Bitmap] instance.
|
||||||
///
|
///
|
||||||
/// The returned memory is valid for the lifetime of the bitmap.
|
/// The returned memory is valid for the lifetime of the bitmap.
|
||||||
method data_ref_mut(mut instance) -> slice ByteSlice;
|
fn data_ref_mut(mut instance) -> slice ByteSlice;
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
containers::{wrap_container, ByteSlice},
|
containers::{wrap_container, ByteSlice},
|
||||||
macros::{wrap, wrap_functions},
|
macros::wrap,
|
||||||
};
|
};
|
||||||
use servicepoint::{
|
use servicepoint::{
|
||||||
BinaryOperation, BitVecCommand, CompressionCode, DisplayBitVec, Packet,
|
BinaryOperation, BitVecCommand, CompressionCode, DisplayBitVec, Packet,
|
||||||
|
@ -9,93 +9,95 @@ use std::ptr::NonNull;
|
||||||
|
|
||||||
wrap_container!(DisplayBitVec);
|
wrap_container!(DisplayBitVec);
|
||||||
|
|
||||||
wrap_functions!(associate DisplayBitVec;
|
wrap! {
|
||||||
/// Creates a new [DisplayBitVec] instance.
|
DisplayBitVec {
|
||||||
///
|
functions:
|
||||||
/// # Arguments
|
/// Creates a new [DisplayBitVec] instance.
|
||||||
///
|
///
|
||||||
/// - `size`: size in bits.
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// returns: [DisplayBitVec] with all bits set to false.
|
/// - `size`: size in bits.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// returns: [DisplayBitVec] with all bits set to false.
|
||||||
///
|
///
|
||||||
/// - when `size` is not divisible by 8.
|
/// # Panics
|
||||||
fn new(size: val usize) -> move NonNull<DisplayBitVec> {
|
///
|
||||||
DisplayBitVec::repeat(false, size)
|
/// - when `size` is not divisible by 8.
|
||||||
};
|
fn new(size: val usize) -> move NonNull<DisplayBitVec> {
|
||||||
|
DisplayBitVec::repeat(false, size)
|
||||||
|
};
|
||||||
|
|
||||||
/// Interpret the data as a series of bits and load then into a new [DisplayBitVec] instance.
|
/// Interpret the data as a series of bits and load then into a new [DisplayBitVec] instance.
|
||||||
///
|
///
|
||||||
/// returns: [DisplayBitVec] instance containing data.
|
/// returns: [DisplayBitVec] instance containing data.
|
||||||
fn load(data: slice ByteSlice) -> move NonNull<DisplayBitVec> {
|
fn load(data: slice ByteSlice) -> move NonNull<DisplayBitVec> {
|
||||||
DisplayBitVec::from_slice(data)
|
DisplayBitVec::from_slice(data)
|
||||||
};
|
};
|
||||||
);
|
|
||||||
|
|
||||||
wrap!(DisplayBitVec;
|
methods:
|
||||||
/// Creates a [BitVecCommand] and immediately turns that into a [Packet].
|
/// Creates a [BitVecCommand] and immediately turns that into a [Packet].
|
||||||
///
|
///
|
||||||
/// The provided [DisplayBitVec] gets consumed.
|
/// The provided [DisplayBitVec] gets consumed.
|
||||||
///
|
///
|
||||||
/// Returns NULL in case of an error.
|
/// Returns NULL in case of an error.
|
||||||
method try_into_packet(
|
fn try_into_packet(
|
||||||
move bitvec,
|
move bitvec,
|
||||||
offset: val usize,
|
offset: val usize,
|
||||||
operation: val BinaryOperation,
|
operation: val BinaryOperation,
|
||||||
compression: val CompressionCode
|
compression: val CompressionCode
|
||||||
) -> move_ok *mut Packet {
|
) -> move_ok *mut Packet {
|
||||||
Packet::try_from(BitVecCommand {
|
Packet::try_from(BitVecCommand {
|
||||||
bitvec,
|
bitvec,
|
||||||
offset,
|
offset,
|
||||||
operation,
|
operation,
|
||||||
compression,
|
compression,
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Gets the value of a bit.
|
/// Gets the value of a bit.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// - `bit_vec`: instance to read from
|
/// - `bit_vec`: instance to read from
|
||||||
/// - `index`: the bit index to read
|
/// - `index`: the bit index to read
|
||||||
///
|
///
|
||||||
/// returns: value of the bit
|
/// returns: value of the bit
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - when accessing `index` out of bounds
|
/// - when accessing `index` out of bounds
|
||||||
method get(ref instance, index: val usize) -> val bool {
|
fn get(ref instance, index: val usize) -> val bool {
|
||||||
instance.get(index).map(|x| *x).unwrap_or(false)
|
instance.get(index).map(|x| *x).unwrap_or(false)
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Sets the value of a bit.
|
/// Sets the value of a bit.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// - `index`: the bit index to edit
|
/// - `index`: the bit index to edit
|
||||||
/// - `value`: the value to set the bit to
|
/// - `value`: the value to set the bit to
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - when accessing `index` out of bounds
|
/// - when accessing `index` out of bounds
|
||||||
method set(mut instance, index: val usize, value: val bool);
|
fn set(mut instance, index: val usize, value: val bool);
|
||||||
|
|
||||||
/// Sets the value of all bits.
|
/// Sets the value of all bits.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// - `value`: the value to set all bits to
|
/// - `value`: the value to set all bits to
|
||||||
method fill(mut instance, value: val bool);
|
fn fill(mut instance, value: val bool);
|
||||||
|
|
||||||
/// Gets the length in bits.
|
/// Gets the length in bits.
|
||||||
method len(ref instance) -> val usize;
|
fn len(ref instance) -> val usize;
|
||||||
|
|
||||||
/// Returns true if length is 0.
|
/// Returns true if length is 0.
|
||||||
method is_empty(ref instance) -> val bool;
|
fn is_empty(ref instance) -> val bool;
|
||||||
|
|
||||||
/// Gets an unsafe reference to the data of the [DisplayBitVec] instance.
|
/// Gets an unsafe reference to the data of the [DisplayBitVec] instance.
|
||||||
///
|
///
|
||||||
/// The returned memory is valid for the lifetime of the bitvec.
|
/// The returned memory is valid for the lifetime of the bitvec.
|
||||||
method as_raw_mut_slice(mut instance) -> slice ByteSlice;
|
fn as_raw_mut_slice(mut instance) -> slice ByteSlice;
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
containers::{wrap_grid, ByteSlice},
|
containers::{wrap_grid, ByteSlice},
|
||||||
macros::{wrap, wrap_functions},
|
macros::wrap,
|
||||||
};
|
};
|
||||||
use servicepoint::{
|
use servicepoint::{
|
||||||
Brightness, BrightnessGrid, BrightnessGridCommand, ByteGrid, DataRef, Grid,
|
Brightness, BrightnessGrid, BrightnessGridCommand, ByteGrid, DataRef, Grid,
|
||||||
|
@ -10,66 +10,68 @@ use std::{mem::transmute, ptr::NonNull};
|
||||||
|
|
||||||
wrap_grid!(BrightnessGrid, Brightness);
|
wrap_grid!(BrightnessGrid, Brightness);
|
||||||
|
|
||||||
wrap_functions!(associate BrightnessGrid;
|
wrap! {
|
||||||
/// Creates a new [BrightnessGrid] with the specified dimensions.
|
BrightnessGrid {
|
||||||
///
|
functions:
|
||||||
/// returns: [BrightnessGrid] initialized to 0.
|
/// Creates a new [BrightnessGrid] with the specified dimensions.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// returns: [BrightnessGrid] initialized to 0.
|
||||||
/// ```C
|
///
|
||||||
/// UdpSocket *connection = sp_udp_open("127.0.0.1:2342");
|
/// # Examples
|
||||||
/// if (connection == NULL)
|
/// ```C
|
||||||
/// return 1;
|
/// UdpSocket *connection = sp_udp_open("127.0.0.1:2342");
|
||||||
///
|
/// if (connection == NULL)
|
||||||
/// BrightnessGrid *grid = sp_brightness_grid_new(2, 2);
|
/// return 1;
|
||||||
/// sp_brightness_grid_set(grid, 0, 0, 0);
|
///
|
||||||
/// sp_brightness_grid_set(grid, 1, 1, 10);
|
/// BrightnessGrid *grid = sp_brightness_grid_new(2, 2);
|
||||||
///
|
/// sp_brightness_grid_set(grid, 0, 0, 0);
|
||||||
/// TypedCommand *command = sp_command_char_brightness(grid);
|
/// sp_brightness_grid_set(grid, 1, 1, 10);
|
||||||
/// sp_udp_free(connection);
|
///
|
||||||
/// ```
|
/// TypedCommand *command = sp_command_char_brightness(grid);
|
||||||
fn new(width: val usize, height: val usize) -> move NonNull<BrightnessGrid> {
|
/// sp_udp_free(connection);
|
||||||
BrightnessGrid::new(width, height)
|
/// ```
|
||||||
};
|
fn new(width: val usize, height: val usize) -> move NonNull<BrightnessGrid> {
|
||||||
|
BrightnessGrid::new(width, height)
|
||||||
|
};
|
||||||
|
|
||||||
/// Loads a [BrightnessGrid] with the specified dimensions from the provided data.
|
/// Loads a [BrightnessGrid] with the specified dimensions from the provided data.
|
||||||
///
|
///
|
||||||
/// Any out of range values will be set to [Brightness::MAX] or [Brightness::MIN].
|
/// Any out of range values will be set to [Brightness::MAX] or [Brightness::MIN].
|
||||||
///
|
///
|
||||||
/// returns: new [BrightnessGrid] instance, or NULL in case of an error.
|
/// returns: new [BrightnessGrid] instance, or NULL in case of an error.
|
||||||
fn load(
|
fn load(
|
||||||
width: val usize,
|
width: val usize,
|
||||||
height: val usize,
|
height: val usize,
|
||||||
data: slice ByteSlice,
|
data: slice ByteSlice,
|
||||||
) -> move_some *mut BrightnessGrid {
|
) -> move_some *mut BrightnessGrid {
|
||||||
ByteGrid::load(width, height, data)
|
ByteGrid::load(width, height, data)
|
||||||
.map(move |grid| grid.map(Brightness::saturating_from))
|
.map(move |grid| grid.map(Brightness::saturating_from))
|
||||||
};
|
};
|
||||||
);
|
|
||||||
|
|
||||||
wrap!(BrightnessGrid;
|
methods:
|
||||||
/// Creates a [BrightnessGridCommand] and immediately turns that into a [Packet].
|
/// Creates a [BrightnessGridCommand] and immediately turns that into a [Packet].
|
||||||
///
|
///
|
||||||
/// The provided [BrightnessGrid] gets consumed.
|
/// The provided [BrightnessGrid] gets consumed.
|
||||||
///
|
///
|
||||||
/// Returns NULL in case of an error.
|
/// Returns NULL in case of an error.
|
||||||
method try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet {
|
fn try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet {
|
||||||
Packet::try_from(BrightnessGridCommand {
|
Packet::try_from(BrightnessGridCommand {
|
||||||
grid,
|
grid,
|
||||||
origin: Origin::new(x, y),
|
origin: Origin::new(x, y),
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Gets an unsafe reference to the data of the instance.
|
/// Gets an unsafe reference to the data of the instance.
|
||||||
///
|
///
|
||||||
/// The returned memory is valid for the lifetime of the grid.
|
/// The returned memory is valid for the lifetime of the grid.
|
||||||
method data_ref_mut(mut instance) -> slice ByteSlice {
|
fn data_ref_mut(mut instance) -> slice ByteSlice {
|
||||||
//noinspection RsAssertEqual
|
//noinspection RsAssertEqual
|
||||||
const _: () = assert!(size_of::<Brightness>() == 1);
|
const _: () = assert!(size_of::<Brightness>() == 1);
|
||||||
|
|
||||||
let br_slice = instance.data_ref_mut();
|
let br_slice = instance.data_ref_mut();
|
||||||
unsafe {
|
unsafe {
|
||||||
transmute::<&mut [Brightness], &mut [u8]>(br_slice)
|
transmute::<&mut [Brightness], &mut [u8]>(br_slice)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
containers::{derive_get_width_height, wrap_container, ByteSlice},
|
containers::{derive_get_width_height, wrap_container, ByteSlice},
|
||||||
macros::{wrap, wrap_functions},
|
macros::wrap,
|
||||||
};
|
};
|
||||||
use servicepoint::{CharGrid, CharGridCommand, Grid, Origin, Packet};
|
use servicepoint::{CharGrid, CharGridCommand, Grid, Origin, Packet};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
@ -8,81 +8,82 @@ use std::ptr::NonNull;
|
||||||
wrap_container!(CharGrid);
|
wrap_container!(CharGrid);
|
||||||
derive_get_width_height!(CharGrid);
|
derive_get_width_height!(CharGrid);
|
||||||
|
|
||||||
wrap_functions!(associate CharGrid;
|
wrap! {
|
||||||
/// Creates a new [CharGrid] with the specified dimensions.
|
CharGrid {
|
||||||
///
|
functions:
|
||||||
/// returns: [CharGrid] initialized to 0.
|
/// Creates a new [CharGrid] with the specified dimensions.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// returns: [CharGrid] initialized to 0.
|
||||||
///
|
///
|
||||||
/// ```C
|
/// # Examples
|
||||||
/// CharGrid grid = sp_char_grid_new(4, 3);
|
///
|
||||||
/// sp_char_grid_fill(grid, '?');
|
/// ```C
|
||||||
/// sp_char_grid_set(grid, 0, 0, '!');
|
/// CharGrid grid = sp_char_grid_new(4, 3);
|
||||||
/// sp_char_grid_free(grid);
|
/// sp_char_grid_fill(grid, '?');
|
||||||
/// ```
|
/// sp_char_grid_set(grid, 0, 0, '!');
|
||||||
fn new(width: val usize, height: val usize) -> move NonNull<CharGrid> {
|
/// sp_char_grid_free(grid);
|
||||||
CharGrid::new(width, height)
|
/// ```
|
||||||
};
|
fn new(width: val usize, height: val usize) -> move NonNull<CharGrid> {
|
||||||
|
CharGrid::new(width, height)
|
||||||
|
};
|
||||||
|
|
||||||
/// Loads a [CharGrid] with the specified dimensions from the provided data.
|
/// Loads a [CharGrid] with the specified dimensions from the provided data.
|
||||||
///
|
///
|
||||||
/// returns: new CharGrid or NULL in case of an error
|
/// 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 {
|
fn load(width: val usize, height: val usize, data: slice ByteSlice) -> move_ok *mut CharGrid {
|
||||||
CharGrid::load_utf8(width, height, data.to_vec())
|
CharGrid::load_utf8(width, height, data.to_vec())
|
||||||
};
|
};
|
||||||
);
|
methods:
|
||||||
|
/// Returns 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 u32 {
|
||||||
|
instance.get(x, y) as u32
|
||||||
|
};
|
||||||
|
|
||||||
wrap!(CharGrid;
|
/// Sets the value of the specified position in the grid.
|
||||||
/// Returns the current value at the specified position.
|
///
|
||||||
///
|
/// # Arguments
|
||||||
/// # Arguments
|
///
|
||||||
///
|
/// - `x` and `y`: position of the cell
|
||||||
/// - `x` and `y`: position of the cell to read
|
/// - `value`: the value to write to the cell
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// returns: old value of the cell
|
||||||
///
|
///
|
||||||
/// - when accessing `x` or `y` out of bounds
|
/// # Panics
|
||||||
method get(ref instance, x: val usize, y: val usize) -> val u32 {
|
///
|
||||||
instance.get(x, y) as u32
|
/// - 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())
|
||||||
|
};
|
||||||
|
|
||||||
/// Sets the value of the specified position in the grid.
|
/// Sets the value of all cells in the grid.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// - `x` and `y`: position of the cell
|
/// - `value`: the value to set all cells to
|
||||||
/// - `value`: the value to write to the cell
|
/// - when providing values that cannot be converted to Rust's `char`.
|
||||||
///
|
fn fill(mut instance, value: val u32) {
|
||||||
/// returns: old value of the cell
|
instance.fill(char::from_u32(value).unwrap())
|
||||||
///
|
};
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// - when accessing `x` or `y` out of bounds
|
|
||||||
/// - when providing values that cannot be converted to Rust's `char`.
|
|
||||||
method set(mut instance, x: val usize, y: val usize, value: val u32) {
|
|
||||||
instance.set(x, y, char::from_u32(value).unwrap())
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Sets the value of all cells in the grid.
|
/// Creates a [CharGridCommand] and immediately turns that into a [Packet].
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// The provided [CharGrid] gets consumed.
|
||||||
///
|
///
|
||||||
/// - `value`: the value to set all cells to
|
/// Returns NULL in case of an error.
|
||||||
/// - when providing values that cannot be converted to Rust's `char`.
|
fn try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet {
|
||||||
method fill(mut instance, value: val u32) {
|
Packet::try_from(CharGridCommand {
|
||||||
instance.fill(char::from_u32(value).unwrap())
|
grid,
|
||||||
};
|
origin: Origin::new(x, y),
|
||||||
|
})
|
||||||
/// Creates a [CharGridCommand] and immediately turns that into a [Packet].
|
};
|
||||||
///
|
}
|
||||||
/// The provided [CharGrid] gets consumed.
|
}
|
||||||
///
|
|
||||||
/// Returns NULL in case of an error.
|
|
||||||
method 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),
|
|
||||||
})
|
|
||||||
};
|
|
||||||
);
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
containers::{wrap_grid, ByteSlice},
|
containers::{wrap_grid, ByteSlice},
|
||||||
macros::{wrap, wrap_functions},
|
macros::wrap,
|
||||||
};
|
};
|
||||||
use servicepoint::{
|
use servicepoint::{
|
||||||
Cp437Grid, Cp437GridCommand, DataRef, Grid, Origin, Packet,
|
Cp437Grid, Cp437GridCommand, DataRef, Grid, Origin, Packet,
|
||||||
|
@ -9,35 +9,37 @@ use std::ptr::NonNull;
|
||||||
|
|
||||||
wrap_grid!(Cp437Grid, u8);
|
wrap_grid!(Cp437Grid, u8);
|
||||||
|
|
||||||
wrap_functions!(associate Cp437Grid;
|
wrap! {
|
||||||
/// Creates a new [Cp437Grid] with the specified dimensions.
|
Cp437Grid {
|
||||||
///
|
functions:
|
||||||
/// returns: [Cp437Grid] initialized to 0.
|
/// Creates a new [Cp437Grid] with the specified dimensions.
|
||||||
fn new(width: val usize, height: val usize) -> move NonNull<Cp437Grid> {
|
///
|
||||||
Cp437Grid::new(width, height)
|
/// returns: [Cp437Grid] initialized to 0.
|
||||||
};
|
fn new(width: val usize, height: val usize) -> move NonNull<Cp437Grid> {
|
||||||
|
Cp437Grid::new(width, height)
|
||||||
|
};
|
||||||
|
|
||||||
/// Loads a [Cp437Grid] with the specified dimensions from the provided data.
|
/// 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 {
|
fn load(width: val usize, height: val usize, data: slice ByteSlice) -> move_some *mut Cp437Grid {
|
||||||
Cp437Grid::load(width, height, data)
|
Cp437Grid::load(width, height, data)
|
||||||
};
|
};
|
||||||
);
|
|
||||||
|
|
||||||
wrap!(Cp437Grid;
|
methods:
|
||||||
/// Creates a [Cp437GridCommand] and immediately turns that into a [Packet].
|
/// Creates a [Cp437GridCommand] and immediately turns that into a [Packet].
|
||||||
///
|
///
|
||||||
/// The provided [Cp437Grid] gets consumed.
|
/// The provided [Cp437Grid] gets consumed.
|
||||||
///
|
///
|
||||||
/// Returns NULL in case of an error.
|
/// Returns NULL in case of an error.
|
||||||
method try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet {
|
fn try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet {
|
||||||
Packet::try_from(Cp437GridCommand {
|
Packet::try_from(Cp437GridCommand {
|
||||||
grid,
|
grid,
|
||||||
origin: Origin::new(x, y),
|
origin: Origin::new(x, y),
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Gets an unsafe reference to the data of the grid.
|
/// Gets an unsafe reference to the data of the grid.
|
||||||
///
|
///
|
||||||
/// The returned memory is valid for the lifetime of the instance.
|
/// The returned memory is valid for the lifetime of the instance.
|
||||||
method data_ref_mut(mut instance) -> slice ByteSlice;
|
fn data_ref_mut(mut instance) -> slice ByteSlice;
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -265,30 +265,54 @@ macro_rules! wrap_functions {
|
||||||
|
|
||||||
macro_rules! wrap {
|
macro_rules! wrap {
|
||||||
(
|
(
|
||||||
$object_type:ident;
|
$object_type:ident {
|
||||||
$(
|
$(
|
||||||
prop $prop_name:ident : $prop_type:ty { $($accessor:ident $($modifier:ident)?;)+ };
|
properties:
|
||||||
)*
|
$(
|
||||||
$(
|
prop $prop_name:ident : $prop_type:ty { $($accessor:ident $($modifier:ident)?;)+ };
|
||||||
$(#[$meta:meta])+
|
)*
|
||||||
method $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)?;
|
functions:
|
||||||
)*
|
$(
|
||||||
|
$(#[$fn_meta:meta])+
|
||||||
|
fn $fn_name:ident($($fn_param_name:ident: $fn_param_modifier:ident $fn_param_type:ty),*$(,)?)
|
||||||
|
$(-> $fn_return_modifier:ident $fn_return_type:ty)?
|
||||||
|
$fn_block:block;
|
||||||
|
)*
|
||||||
|
)?
|
||||||
|
$(
|
||||||
|
methods:
|
||||||
|
$(
|
||||||
|
$(#[$method_meta:meta])+
|
||||||
|
fn $method_name:ident($method_instance_modifier:ident $method_instance:ident $(, $($method_param_name:ident: $method_param_modifier:ident $method_param_type:ty),*)?)
|
||||||
|
$(-> $method_return_modifier:ident $method_return_type:ty)?
|
||||||
|
$($method_impl:block)?;
|
||||||
|
)*
|
||||||
|
)?
|
||||||
|
}
|
||||||
) => {
|
) => {
|
||||||
$(
|
$($(
|
||||||
$crate::macros::wrap_fields!($object_type;
|
$crate::macros::wrap_fields!($object_type;
|
||||||
prop $prop_name : $prop_type { $($accessor $($modifier)?;)+ };
|
prop $prop_name : $prop_type { $($accessor $($modifier)?;)+ };
|
||||||
);
|
);
|
||||||
)*
|
)*)?
|
||||||
$(
|
$($(
|
||||||
$crate::macros::wrap_method!($object_type;
|
$crate::macros::wrap_functions!(associate $object_type;
|
||||||
$(#[$meta])+
|
$(#[$fn_meta])+
|
||||||
fn $function($ref_or_mut $instance $(, $($param_name: $param_modifier $param_type),*)?)
|
fn $fn_name($($fn_param_name: $fn_param_modifier $fn_param_type),*)
|
||||||
$(-> $return_modifier $return_type)?
|
$(-> $fn_return_modifier $fn_return_type)?
|
||||||
$($impl)?;
|
$fn_block;
|
||||||
);
|
);
|
||||||
)*
|
)*)?
|
||||||
|
$($(
|
||||||
|
$crate::macros::wrap_method!($object_type;
|
||||||
|
$(#[$method_meta])+
|
||||||
|
fn $method_name($method_instance_modifier $method_instance $(, $($method_param_name: $method_param_modifier $method_param_type),*)?)
|
||||||
|
$(-> $method_return_modifier $method_return_type)?
|
||||||
|
$($method_impl)?;
|
||||||
|
);
|
||||||
|
)*)?
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
112
src/packet.rs
112
src/packet.rs
|
@ -5,71 +5,71 @@ use crate::{
|
||||||
use servicepoint::{CommandCode, Header, Packet};
|
use servicepoint::{CommandCode, Header, Packet};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
wrap_functions!(associate Packet;
|
|
||||||
/// Tries to load a [Packet] from the passed array with the specified length.
|
|
||||||
///
|
|
||||||
/// returns: NULL in case of an error, pointer to the allocated packet otherwise
|
|
||||||
fn try_load(data: slice ByteSlice) -> move_ok *mut Packet {
|
|
||||||
servicepoint::Packet::try_from(data)
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Creates a raw [Packet] from parts.
|
|
||||||
///
|
|
||||||
/// returns: new instance. Will never return null.
|
|
||||||
fn from_parts(header: val Header, payload: val ByteSlice) -> move NonNull<Packet> {
|
|
||||||
let payload = if payload == ByteSlice::INVALID {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(Vec::from(unsafe { payload.as_slice() }))
|
|
||||||
};
|
|
||||||
|
|
||||||
Packet { header, payload }
|
|
||||||
};
|
|
||||||
);
|
|
||||||
|
|
||||||
derive_clone!(Packet);
|
derive_clone!(Packet);
|
||||||
derive_free!(Packet);
|
derive_free!(Packet);
|
||||||
|
|
||||||
wrap! {Packet;
|
wrap! {
|
||||||
prop header: Header { get; get mut; set; };
|
Packet {
|
||||||
|
properties:
|
||||||
|
prop header: Header { get; get mut; set; };
|
||||||
|
functions:
|
||||||
|
/// 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)
|
||||||
|
};
|
||||||
|
|
||||||
/// Returns a pointer to the current payload of the provided packet.
|
/// Creates a raw [Packet] from parts.
|
||||||
///
|
///
|
||||||
/// Returns an [ByteSlice::INVALID] instance in case the packet does not have any payload.
|
/// returns: new instance. Will never return null.
|
||||||
///
|
fn from_parts(header: val Header, payload: val ByteSlice) -> move NonNull<Packet> {
|
||||||
/// The returned memory can be changed and will be valid until a new payload is set.
|
let payload = if payload == ByteSlice::INVALID {
|
||||||
method get_payload(mut packet) -> val ByteSlice {
|
None
|
||||||
match &mut packet.payload {
|
} else {
|
||||||
None => ByteSlice::INVALID,
|
Some(Vec::from(unsafe { payload.as_slice() }))
|
||||||
Some(payload) => unsafe { ByteSlice::from_slice(payload) },
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Sets the payload of the provided packet to the provided data.
|
Packet { header, payload }
|
||||||
///
|
};
|
||||||
/// This makes previous payload pointers invalid.
|
methods:
|
||||||
method set_payload(mut packet, data: val ByteSlice) {
|
/// Returns a pointer to the current payload of the provided packet.
|
||||||
packet.payload = if data == ByteSlice::INVALID {
|
///
|
||||||
None
|
/// Returns an [ByteSlice::INVALID] instance in case the packet does not have any payload.
|
||||||
} else {
|
///
|
||||||
Some(unsafe { data.as_slice().to_vec() })
|
/// 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) },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// Serialize the packet into the provided buffer.
|
/// Sets the payload of the provided packet to the provided data.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// This makes previous payload pointers invalid.
|
||||||
///
|
fn set_payload(mut packet, data: val ByteSlice) {
|
||||||
/// - if the buffer is not big enough to hold header+payload.
|
packet.payload = if data == ByteSlice::INVALID {
|
||||||
method serialize_to(mut packet, buffer: val ByteSlice) -> val usize {
|
None
|
||||||
unsafe {
|
} else {
|
||||||
packet.serialize_to(buffer.as_slice_mut()).unwrap_or(0)
|
Some(unsafe { data.as_slice().to_vec() })
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Serialize the packet into the provided buffer.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// - if the buffer is not big enough to hold header+payload.
|
||||||
|
fn serialize_to(mut packet, buffer: val ByteSlice) -> val usize {
|
||||||
|
unsafe {
|
||||||
|
packet.serialize_to(buffer.as_slice_mut()).unwrap_or(0)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wrap_functions!(sp;
|
wrap_functions!(sp;
|
||||||
|
|
||||||
/// Converts u16 into [CommandCode].
|
/// Converts u16 into [CommandCode].
|
||||||
///
|
///
|
||||||
/// If the provided value is not valid, false is returned and result is not changed.
|
/// If the provided value is not valid, false is returned and result is not changed.
|
||||||
|
|
187
src/udp.rs
187
src/udp.rs
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
commands::{CommandTag, GenericCommand},
|
commands::{CommandTag, GenericCommand},
|
||||||
macros::{derive_free, wrap, wrap_functions},
|
macros::{derive_free, wrap},
|
||||||
mem::heap_remove,
|
mem::heap_remove,
|
||||||
};
|
};
|
||||||
use servicepoint::{Header, Packet, UdpSocketExt};
|
use servicepoint::{Header, Packet, UdpSocketExt};
|
||||||
|
@ -12,99 +12,100 @@ use std::{
|
||||||
|
|
||||||
derive_free!(UdpSocket);
|
derive_free!(UdpSocket);
|
||||||
|
|
||||||
wrap_functions!(associate UdpSocket;
|
wrap! {
|
||||||
/// Creates a new instance of [UdpSocket].
|
UdpSocket {
|
||||||
///
|
functions:
|
||||||
/// returns: NULL if connection fails, or connected instance
|
/// Creates a new instance of [UdpSocket].
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// returns: NULL if connection fails, or connected instance
|
||||||
///
|
///
|
||||||
/// ```C
|
/// # Examples
|
||||||
/// UdpSocket connection = sp_udp_open("172.23.42.29:2342");
|
///
|
||||||
/// if (connection != NULL)
|
/// ```C
|
||||||
/// sp_udp_send_command(connection, sp_command_clear());
|
/// UdpSocket connection = sp_udp_open("172.23.42.29:2342");
|
||||||
/// ```
|
/// if (connection != NULL)
|
||||||
fn open(host: val NonNull<c_char>) -> move_ok *mut UdpSocket {
|
/// sp_udp_send_command(connection, sp_command_clear());
|
||||||
let host = unsafe { CStr::from_ptr(host.as_ptr()) }
|
/// ```
|
||||||
.to_str()
|
fn open(host: val NonNull<c_char>) -> move_ok *mut UdpSocket {
|
||||||
.expect("Bad encoding");
|
let host = unsafe { CStr::from_ptr(host.as_ptr()) }
|
||||||
UdpSocket::bind_connect(host)
|
.to_str()
|
||||||
};
|
.expect("Bad encoding");
|
||||||
|
UdpSocket::bind_connect(host)
|
||||||
/// Creates a new instance of [UdpSocket].
|
|
||||||
///
|
|
||||||
/// returns: NULL if connection fails, or connected instance
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```C
|
|
||||||
/// UdpSocket connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
|
|
||||||
/// 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 {
|
|
||||||
let addr = SocketAddrV4::new(Ipv4Addr::from([ip1, ip2, ip3, ip4]), port);
|
|
||||||
UdpSocket::bind_connect(addr)
|
|
||||||
};
|
|
||||||
);
|
|
||||||
|
|
||||||
wrap! {UdpSocket;
|
|
||||||
/// Sends a [Packet] to the display using the [UdpSocket].
|
|
||||||
///
|
|
||||||
/// The passed `packet` gets consumed.
|
|
||||||
///
|
|
||||||
/// returns: true in case of success
|
|
||||||
method send_packet(ref connection, packet: move NonNull<Packet>) -> val bool {
|
|
||||||
connection.send(&Vec::from(packet)).is_ok()
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Sends a [GenericCommand] to the display using the [UdpSocket].
|
|
||||||
///
|
|
||||||
/// The passed `command` gets consumed.
|
|
||||||
///
|
|
||||||
/// returns: true in case of success
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```C
|
|
||||||
/// sp_udp_send_command(connection, sp_command_brightness(5));
|
|
||||||
/// ```
|
|
||||||
method send_command(ref connection, command: mut NonNull<GenericCommand>) -> val bool {
|
|
||||||
unsafe {
|
|
||||||
let result = 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
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Sends a [Header] to the display using the [UdpSocket].
|
|
||||||
///
|
|
||||||
/// returns: true in case of success
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```C
|
|
||||||
/// sp_udp_send_header(connection, sp_command_brightness(5));
|
|
||||||
/// ```
|
|
||||||
method send_header(ref udp_connection, header: val Header) -> val bool {
|
|
||||||
let packet = Packet {
|
|
||||||
header,
|
|
||||||
payload: None,
|
|
||||||
};
|
};
|
||||||
udp_connection.send(&Vec::from(packet)).is_ok()
|
|
||||||
};
|
/// Creates a new instance of [UdpSocket].
|
||||||
|
///
|
||||||
|
/// returns: NULL if connection fails, or connected instance
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```C
|
||||||
|
/// UdpSocket connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
|
||||||
|
/// 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 {
|
||||||
|
let addr = SocketAddrV4::new(Ipv4Addr::from([ip1, ip2, ip3, ip4]), port);
|
||||||
|
UdpSocket::bind_connect(addr)
|
||||||
|
};
|
||||||
|
methods:
|
||||||
|
/// 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<Packet>) -> val bool {
|
||||||
|
connection.send(&Vec::from(packet)).is_ok()
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Sends a [GenericCommand] to the display using the [UdpSocket].
|
||||||
|
///
|
||||||
|
/// The passed `command` gets consumed.
|
||||||
|
///
|
||||||
|
/// returns: true in case of success
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```C
|
||||||
|
/// sp_udp_send_command(connection, sp_command_brightness(5));
|
||||||
|
/// ```
|
||||||
|
fn send_command(ref connection, command: mut NonNull<GenericCommand>) -> val bool {
|
||||||
|
unsafe {
|
||||||
|
let result = 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
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Sends a [Header] to the display using the [UdpSocket].
|
||||||
|
///
|
||||||
|
/// returns: true in case of success
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```C
|
||||||
|
/// sp_udp_send_header(connection, sp_command_brightness(5));
|
||||||
|
/// ```
|
||||||
|
fn send_header(ref udp_connection, header: val Header) -> val bool {
|
||||||
|
let packet = Packet {
|
||||||
|
header,
|
||||||
|
payload: None,
|
||||||
|
};
|
||||||
|
udp_connection.send(&Vec::from(packet)).is_ok()
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod _hidden {
|
mod _hidden {
|
||||||
|
|
Loading…
Reference in a new issue