From 960f12ebc54a7ea3605c3b1c93468669fb5eb77e Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Mon, 4 Nov 2024 21:06:01 +0100 Subject: [PATCH] make BitVec type alias pub, uniffi bitvec original c# example equivalent works add uniffi bitvec original c# example now works with a few tweaks via uniffi --- .../csharp/ServicePoint.Example/Program.cs | 20 +- .../servicepoint_binding_uniffi.cs | 314 ++++++++++++++++++ .../servicepoint_binding_uniffi/src/bitmap.rs | 29 +- .../servicepoint_binding_uniffi/src/bitvec.rs | 46 +++ .../src/command.rs | 74 ++++- .../src/connection.rs | 15 +- .../servicepoint_binding_uniffi/src/errors.rs | 7 +- crates/servicepoint_binding_uniffi/src/lib.rs | 3 +- 8 files changed, 482 insertions(+), 26 deletions(-) create mode 100644 crates/servicepoint_binding_uniffi/src/bitvec.rs diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs index ad4a868..48462a5 100644 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/Program.cs @@ -1,5 +1,19 @@ -using ServicePoint; +using System.Threading; +using ServicePoint; var connection = new Connection("127.0.0.1:2342"); -var clear = Command.Clear(); -connection.Send(clear); +connection.Send(Command.Clear()); + +connection.Send(Command.Brightness(5)); + +var pixels = Bitmap.NewMaxSized(); +for (ulong offset = 0; offset < ulong.MaxValue; offset++) +{ + pixels.Fill(false); + + for (ulong y = 0; y < pixels.Height(); y++) + pixels.Set((y + offset) % pixels.Width(), y, true); + + connection.Send(Command.BitmapLinearWin(0, 0, pixels)); + Thread.Sleep(14); +} diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs index b72b1b1..9aaf721 100644 --- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs +++ b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint/servicepoint_binding_uniffi.cs @@ -428,11 +428,44 @@ static class _UniFFILib { } + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_free_bitvec( + IntPtr ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern BitVecSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_load(RustBuffer @data,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern BitVecSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_new(ulong @size,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_method_bitvec_fill(BitVecSafeHandle @ptr,sbyte @value,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern sbyte uniffi_servicepoint_binding_uniffi_fn_method_bitvec_get(BitVecSafeHandle @ptr,ulong @index,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ulong uniffi_servicepoint_binding_uniffi_fn_method_bitvec_len(BitVecSafeHandle @ptr,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern void uniffi_servicepoint_binding_uniffi_fn_method_bitvec_set(BitVecSafeHandle @ptr,ulong @index,sbyte @value,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern void uniffi_servicepoint_binding_uniffi_fn_free_bitmap( IntPtr ptr,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern BitmapSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_load(ulong @width,ulong @height,RustBuffer @data,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern BitmapSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_new(ulong @width,ulong @height,ref RustCallStatus _uniffi_out_err ); @@ -466,10 +499,26 @@ static class _UniFFILib { IntPtr ptr,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear(ulong @offset,BitVecSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_and(ulong @offset,BitVecSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_or(ulong @offset,BitVecSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_win(ulong @offsetX,ulong @offsetY,BitmapSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_xor(ulong @offset,BitVecSafeHandle @bitmap,ref RustCallStatus _uniffi_out_err + ); + [DllImport("servicepoint_binding_uniffi")] public static extern CommandSafeHandle uniffi_servicepoint_binding_uniffi_fn_constructor_command_brightness(byte @brightness,ref RustCallStatus _uniffi_out_err ); @@ -731,6 +780,22 @@ static class _UniFFILib { public static extern void ffi_servicepoint_binding_uniffi_rust_future_complete_void(IntPtr @handle,ref RustCallStatus _uniffi_out_err ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_fill( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_get( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_len( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_set( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_fill( ); @@ -755,6 +820,18 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_method_connection_send( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_load( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_new( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_load( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new( ); @@ -763,10 +840,26 @@ static class _UniFFILib { public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new_max_sized( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_and( + ); + + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_or( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_win( ); + [DllImport("servicepoint_binding_uniffi")] + public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_xor( + ); + [DllImport("servicepoint_binding_uniffi")] public static extern ushort uniffi_servicepoint_binding_uniffi_checksum_constructor_command_brightness( ); @@ -805,6 +898,30 @@ static class _UniFFILib { } static void uniffiCheckApiChecksums() { + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_fill(); + if (checksum != 12255) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_fill` checksum `12255`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_get(); + if (checksum != 43835) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_get` checksum `43835`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_len(); + if (checksum != 22196) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_len` checksum `22196`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_set(); + if (checksum != 16307) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_set` checksum `16307`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_fill(); if (checksum != 43887) { @@ -841,6 +958,24 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_method_connection_send` checksum `23796`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_load(); + if (checksum != 48913) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_load` checksum `48913`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_new(); + if (checksum != 11865) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_new` checksum `11865`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_load(); + if (checksum != 24109) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_load` checksum `24109`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new(); if (checksum != 49832) { @@ -853,12 +988,36 @@ static class _UniFFILib { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new_max_sized` checksum `63762`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear(); + if (checksum != 14881) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear` checksum `14881`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_and(); + if (checksum != 7352) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_and` checksum `7352`, library returned `{checksum}`"); + } + } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_or(); + if (checksum != 7046) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_or` checksum `7046`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_win(); if (checksum != 51700) { throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_win` checksum `51700`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_xor(); + if (checksum != 54209) { + throw new UniffiContractChecksumException($"ServicePoint: uniffi bindings expected function `uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_xor` checksum `54209`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_servicepoint_binding_uniffi_checksum_constructor_command_brightness(); if (checksum != 11291) { @@ -1031,6 +1190,27 @@ class FfiConverterString: FfiConverter { +class FfiConverterByteArray: FfiConverterRustBuffer { + public static FfiConverterByteArray INSTANCE = new FfiConverterByteArray(); + + public override byte[] Read(BigEndianStream stream) { + var length = stream.ReadInt(); + return stream.ReadBytes(length); + } + + public override int AllocationSize(byte[] value) { + return 4 + value.Length; + } + + public override void Write(byte[] value, BigEndianStream stream) { + stream.WriteInt(value.Length); + stream.WriteBytes(value); + } +} + + + + // `SafeHandle` implements the semantics outlined below, i.e. its thread safe, and the dispose // method will only be called once, once all outstanding native calls have completed. // https://github.com/mozilla/uniffi-rs/blob/0dc031132d9493ca812c3af6e7dd60ad2ea95bf0/uniffi_bindgen/src/bindings/kotlin/templates/ObjectRuntime.kt#L31 @@ -1115,6 +1295,105 @@ static class FFIObjectUtil { } } } +public interface IBitVec { + + void Fill(bool @value); + + bool Get(ulong @index); + + ulong Len(); + + void Set(ulong @index, bool @value); + +} + +public class BitVecSafeHandle: FFISafeHandle { + public BitVecSafeHandle(): base() { + } + public BitVecSafeHandle(IntPtr pointer): base(pointer) { + } + override protected bool ReleaseHandle() { + _UniffiHelpers.RustCall((ref RustCallStatus status) => { + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_free_bitvec(this.handle, ref status); + }); + return true; + } +} +public class BitVec: FFIObject, IBitVec { + public BitVec(BitVecSafeHandle pointer): base(pointer) {} + public BitVec(ulong @size) : + this( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_new(FfiConverterUInt64.INSTANCE.Lower(@size), ref _status) +)) {} + + + public void Fill(bool @value) { + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitvec_fill(this.GetHandle(), FfiConverterBoolean.INSTANCE.Lower(@value), ref _status) +); + } + + + public bool Get(ulong @index) { + return FfiConverterBoolean.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitvec_get(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@index), ref _status) +)); + } + + public ulong Len() { + return FfiConverterUInt64.INSTANCE.Lift( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitvec_len(this.GetHandle(), ref _status) +)); + } + + public void Set(ulong @index, bool @value) { + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_method_bitvec_set(this.GetHandle(), FfiConverterUInt64.INSTANCE.Lower(@index), FfiConverterBoolean.INSTANCE.Lower(@value), ref _status) +); + } + + + + + public static BitVec Load(byte[] @data) { + return new BitVec( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_load(FfiConverterByteArray.INSTANCE.Lower(@data), ref _status) +)); + } + + +} + +class FfiConverterTypeBitVec: FfiConverter { + public static FfiConverterTypeBitVec INSTANCE = new FfiConverterTypeBitVec(); + + public override BitVecSafeHandle Lower(BitVec value) { + return value.GetHandle(); + } + + public override BitVec Lift(BitVecSafeHandle value) { + return new BitVec(value); + } + + public override BitVec Read(BigEndianStream stream) { + return Lift(new BitVecSafeHandle(new IntPtr(stream.ReadLong()))); + } + + public override int AllocationSize(BitVec value) { + return 8; + } + + public override void Write(BitVec value, BigEndianStream stream) { + stream.WriteLong(Lower(value).DangerousGetRawFfiValue().ToInt64()); + } +} + + + public interface IBitmap { void Fill(bool @value); @@ -1187,6 +1466,13 @@ public class Bitmap: FFIObject, IBitmap { + public static Bitmap Load(ulong @width, ulong @height, byte[] @data) { + return new Bitmap( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_load(FfiConverterUInt64.INSTANCE.Lower(@width), FfiConverterUInt64.INSTANCE.Lower(@height), FfiConverterByteArray.INSTANCE.Lower(@data), ref _status) +)); + } + public static Bitmap NewMaxSized() { return new Bitmap( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => @@ -1245,6 +1531,27 @@ public class Command: FFIObject, ICommand { + public static Command BitmapLinear(ulong @offset, BitVec @bitmap) { + return new Command( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), ref _status) +)); + } + + public static Command BitmapLinearAnd(ulong @offset, BitVec @bitmap) { + return new Command( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_and(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), ref _status) +)); + } + + public static Command BitmapLinearOr(ulong @offset, BitVec @bitmap) { + return new Command( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_or(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), ref _status) +)); + } + public static Command BitmapLinearWin(ulong @offsetX, ulong @offsetY, Bitmap @bitmap) { return new Command( _UniffiHelpers.RustCall( (ref RustCallStatus _status) => @@ -1252,6 +1559,13 @@ public class Command: FFIObject, ICommand { )); } + public static Command BitmapLinearXor(ulong @offset, BitVec @bitmap) { + return new Command( + _UniffiHelpers.RustCall( (ref RustCallStatus _status) => + _UniFFILib.uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_xor(FfiConverterUInt64.INSTANCE.Lower(@offset), FfiConverterTypeBitVec.INSTANCE.Lower(@bitmap), ref _status) +)); + } + /// public static Command Brightness(byte @brightness) { return new Command( diff --git a/crates/servicepoint_binding_uniffi/src/bitmap.rs b/crates/servicepoint_binding_uniffi/src/bitmap.rs index 8e6fc0b..e0ebea4 100644 --- a/crates/servicepoint_binding_uniffi/src/bitmap.rs +++ b/crates/servicepoint_binding_uniffi/src/bitmap.rs @@ -1,5 +1,5 @@ -use std::sync::{Arc, RwLock}; use servicepoint::Grid; +use std::sync::{Arc, RwLock}; #[derive(uniffi::Object)] pub struct Bitmap { @@ -7,8 +7,10 @@ pub struct Bitmap { } impl Bitmap { - fn internal_new(actual: servicepoint::Bitmap)-> Arc { - Arc::new(Self { actual: RwLock::new(actual) }) + fn internal_new(actual: servicepoint::Bitmap) -> Arc { + Arc::new(Self { + actual: RwLock::new(actual), + }) } } @@ -16,7 +18,10 @@ impl Bitmap { impl Bitmap { #[uniffi::constructor] pub fn new(width: u64, height: u64) -> Arc { - Self::internal_new(servicepoint::Bitmap::new(width as usize, height as usize)) + Self::internal_new(servicepoint::Bitmap::new( + width as usize, + height as usize, + )) } #[uniffi::constructor] @@ -24,8 +29,20 @@ impl Bitmap { Self::internal_new(servicepoint::Bitmap::max_sized()) } + #[uniffi::constructor] + pub fn load(width: u64, height: u64, data: Vec) -> Arc { + Self::internal_new(servicepoint::Bitmap::load( + width as usize, + height as usize, + &data, + )) + } + pub fn set(&self, x: u64, y: u64, value: bool) { - self.actual.write().unwrap().set(x as usize, y as usize, value) + self.actual + .write() + .unwrap() + .set(x as usize, y as usize, value) } pub fn get(&self, x: u64, y: u64) -> bool { @@ -38,7 +55,7 @@ impl Bitmap { pub fn width(&self) -> u64 { self.actual.read().unwrap().width() as u64 } - + pub fn height(&self) -> u64 { self.actual.read().unwrap().height() as u64 } diff --git a/crates/servicepoint_binding_uniffi/src/bitvec.rs b/crates/servicepoint_binding_uniffi/src/bitvec.rs new file mode 100644 index 0000000..f495958 --- /dev/null +++ b/crates/servicepoint_binding_uniffi/src/bitvec.rs @@ -0,0 +1,46 @@ +use std::sync::{Arc, RwLock}; + +#[derive(uniffi::Object)] +pub struct BitVec { + pub(crate) actual: RwLock, +} + +impl BitVec { + fn internal_new(actual: servicepoint::BitVec) -> Arc { + Arc::new(Self { + actual: RwLock::new(actual), + }) + } +} + +#[uniffi::export] +impl BitVec { + #[uniffi::constructor] + pub fn new(size: u64) -> Arc { + Self::internal_new(servicepoint::BitVec::repeat(false, size as usize)) + } + #[uniffi::constructor] + pub fn load(data: Vec) -> Arc { + Self::internal_new(servicepoint::BitVec::from_slice(&data)) + } + + pub fn set(&self, index: u64, value: bool) { + self.actual.write().unwrap().set(index as usize, value) + } + + pub fn get(&self, index: u64) -> bool { + self.actual + .read() + .unwrap() + .get(index as usize) + .is_some_and(move |bit| *bit) + } + + pub fn fill(&self, value: bool) { + self.actual.write().unwrap().fill(value) + } + + pub fn len(&self) -> u64 { + self.actual.read().unwrap().len() as u64 + } +} diff --git a/crates/servicepoint_binding_uniffi/src/command.rs b/crates/servicepoint_binding_uniffi/src/command.rs index 78b6f2f..ad4be53 100644 --- a/crates/servicepoint_binding_uniffi/src/command.rs +++ b/crates/servicepoint_binding_uniffi/src/command.rs @@ -1,15 +1,16 @@ -use std::sync::Arc; -use servicepoint::{CompressionCode, Origin}; use crate::bitmap::Bitmap; +use crate::bitvec::BitVec; use crate::errors::ServicePointError; +use servicepoint::{CompressionCode, Origin}; +use std::sync::Arc; #[derive(uniffi::Object)] pub struct Command { - pub(crate)actual: servicepoint::Command + pub(crate) actual: servicepoint::Command, } impl Command { - fn internal_new(actual: servicepoint::Command)-> Arc { + fn internal_new(actual: servicepoint::Command) -> Arc { Arc::new(Command { actual }) } } @@ -24,7 +25,9 @@ impl Command { #[uniffi::constructor] pub fn brightness(brightness: u8) -> Result, ServicePointError> { servicepoint::Brightness::try_from(brightness) - .map_err(move |value| ServicePointError::InvalidBrightness{value}) + .map_err(move |value| ServicePointError::InvalidBrightness { + value, + }) .map(servicepoint::Command::Brightness) .map(Self::internal_new) } @@ -38,13 +41,68 @@ impl Command { pub fn hard_reset() -> Arc { Self::internal_new(servicepoint::Command::HardReset) } - + #[uniffi::constructor] - pub fn bitmap_linear_win(offset_x: u64, offset_y: u64, bitmap: &Arc) -> Arc { + pub fn bitmap_linear_win( + offset_x: u64, + offset_y: u64, + bitmap: &Arc, + ) -> Arc { let origin = Origin::new(offset_x as usize, offset_y as usize); let bitmap = bitmap.actual.read().unwrap().clone(); // TODO: compression codes - let actual = servicepoint::Command::BitmapLinearWin(origin, bitmap, CompressionCode::Uncompressed); + let actual = servicepoint::Command::BitmapLinearWin( + origin, + bitmap, + CompressionCode::Uncompressed, + ); + Self::internal_new(actual) + } + + #[uniffi::constructor] + pub fn bitmap_linear(offset: u64, bitmap: &Arc) -> Arc { + let bitmap = bitmap.actual.read().unwrap().clone(); + // TODO: compression codes + let actual = servicepoint::Command::BitmapLinear( + offset as usize, + bitmap, + CompressionCode::Uncompressed, + ); + Self::internal_new(actual) + } + + #[uniffi::constructor] + pub fn bitmap_linear_and(offset: u64, bitmap: &Arc) -> Arc { + let bitmap = bitmap.actual.read().unwrap().clone(); + // TODO: compression codes + let actual = servicepoint::Command::BitmapLinearAnd( + offset as usize, + bitmap, + CompressionCode::Uncompressed, + ); + Self::internal_new(actual) + } + + #[uniffi::constructor] + pub fn bitmap_linear_or(offset: u64, bitmap: &Arc) -> Arc { + let bitmap = bitmap.actual.read().unwrap().clone(); + // TODO: compression codes + let actual = servicepoint::Command::BitmapLinearOr( + offset as usize, + bitmap, + CompressionCode::Uncompressed, + ); + Self::internal_new(actual) + } + #[uniffi::constructor] + pub fn bitmap_linear_xor(offset: u64, bitmap: &Arc) -> Arc { + let bitmap = bitmap.actual.read().unwrap().clone(); + // TODO: compression codes + let actual = servicepoint::Command::BitmapLinearXor( + offset as usize, + bitmap, + CompressionCode::Uncompressed, + ); Self::internal_new(actual) } } diff --git a/crates/servicepoint_binding_uniffi/src/connection.rs b/crates/servicepoint_binding_uniffi/src/connection.rs index a578135..6ba4e07 100644 --- a/crates/servicepoint_binding_uniffi/src/connection.rs +++ b/crates/servicepoint_binding_uniffi/src/connection.rs @@ -14,16 +14,23 @@ impl Connection { pub fn new(host: String) -> Result, ServicePointError> { servicepoint::Connection::open(host) .map(|actual| Arc::new(Connection { actual })) - .map_err(|err| ServicePointError::IoError { error: err.to_string() }) + .map_err(|err| ServicePointError::IoError { + error: err.to_string(), + }) } #[uniffi::constructor] pub fn new_fake() -> Arc { - Arc::new(Self { actual: servicepoint::Connection::Fake }) + Arc::new(Self { + actual: servicepoint::Connection::Fake, + }) } pub fn send(&self, command: Arc) -> Result<(), ServicePointError> { - self.actual.send(command.actual.clone()) - .map_err(|err| ServicePointError::IoError { error: format!("{err:?}") }) + self.actual.send(command.actual.clone()).map_err(|err| { + ServicePointError::IoError { + error: format!("{err:?}"), + } + }) } } diff --git a/crates/servicepoint_binding_uniffi/src/errors.rs b/crates/servicepoint_binding_uniffi/src/errors.rs index e602342..9c28f5f 100644 --- a/crates/servicepoint_binding_uniffi/src/errors.rs +++ b/crates/servicepoint_binding_uniffi/src/errors.rs @@ -1,8 +1,7 @@ - #[derive(uniffi::Error, thiserror::Error, Debug)] pub enum ServicePointError { #[error("An IO error occurred: {error}")] - IoError {error: String}, + IoError { error: String }, #[error("The specified brightness value {value} is out of range")] - InvalidBrightness {value:u8}, -} \ No newline at end of file + InvalidBrightness { value: u8 }, +} diff --git a/crates/servicepoint_binding_uniffi/src/lib.rs b/crates/servicepoint_binding_uniffi/src/lib.rs index 65f283f..865a82e 100644 --- a/crates/servicepoint_binding_uniffi/src/lib.rs +++ b/crates/servicepoint_binding_uniffi/src/lib.rs @@ -1,6 +1,7 @@ uniffi::setup_scaffolding!(); +mod bitmap; +mod bitvec; mod command; mod connection; mod errors; -mod bitmap;