From 67969d5b43849b8eb70463209739af49b298b71c Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 19 Oct 2024 14:21:50 +0200 Subject: [PATCH] generate most of the c# binding with a fork of csbindgen --- .gitmodules | 3 + Cargo.lock | 19 ++- Cargo.toml | 7 +- .../examples/random_brightness.rs | 7 +- crates/servicepoint_binding_c/src/bit_vec.rs | 2 +- crates/servicepoint_binding_c/src/bitmap.rs | 11 +- .../src/brightness_grid.rs | 6 +- crates/servicepoint_binding_c/src/command.rs | 83 +++++----- .../servicepoint_binding_c/src/cp437_grid.rs | 13 +- crates/servicepoint_binding_cs/Cargo.toml | 2 +- .../ServicePoint/BindGen/Extensions.cs | 49 ------ .../ServicePoint/BitVec.cs | 83 +--------- .../BitVecNative.g.cs => BitVec.g.cs} | 113 ++++++++++++-- .../ServicePoint/Bitmap.cs | 96 +----------- .../BitmapNative.g.cs => Bitmap.g.cs} | 113 ++++++++++++-- .../ServicePoint/BrightnessGrid.cs | 95 +----------- ...essGridNative.g.cs => BrightnessGrid.g.cs} | 113 ++++++++++++-- .../ByteSliceNative.g.cs => ByteSlice.g.cs} | 6 +- .../ServicePoint/Command.cs | 122 +-------------- .../CommandNative.g.cs => Command.g.cs} | 145 +++++++++++++++--- .../ServicePoint/Connection.cs | 29 +--- .../ConnectionNative.g.cs => Connection.g.cs} | 75 +++++++-- .../ServicePoint/Constants.cs | 2 - .../ConstantsNative.g.cs => Constants.g.cs} | 3 +- .../ServicePoint/Cp437Grid.cs | 99 +----------- .../Cp437GridNative.g.cs => Cp437Grid.g.cs} | 113 ++++++++++++-- .../ServicePoint/Packet.cs | 22 +-- .../PacketNative.g.cs => Packet.g.cs} | 75 +++++++-- .../ServicePoint/ServicePoint.csproj | 5 - .../ServicePoint/ServicePointExtensions.cs | 3 +- .../ServicePoint/SpNativeInstance.cs | 51 ------ crates/servicepoint_binding_cs/build.rs | 32 ++-- .../examples/lang_cs/Program.cs | 12 +- crates/servicepoint_csbindgen | 1 + 34 files changed, 791 insertions(+), 819 deletions(-) create mode 100644 .gitmodules delete mode 100644 crates/servicepoint_binding_cs/ServicePoint/BindGen/Extensions.cs rename crates/servicepoint_binding_cs/ServicePoint/{BindGen/BitVecNative.g.cs => BitVec.g.cs} (72%) rename crates/servicepoint_binding_cs/ServicePoint/{BindGen/BitmapNative.g.cs => Bitmap.g.cs} (72%) rename crates/servicepoint_binding_cs/ServicePoint/{BindGen/BrightnessGridNative.g.cs => BrightnessGrid.g.cs} (71%) rename crates/servicepoint_binding_cs/ServicePoint/{BindGen/ByteSliceNative.g.cs => ByteSlice.g.cs} (81%) rename crates/servicepoint_binding_cs/ServicePoint/{BindGen/CommandNative.g.cs => Command.g.cs} (74%) rename crates/servicepoint_binding_cs/ServicePoint/{BindGen/ConnectionNative.g.cs => Connection.g.cs} (63%) rename crates/servicepoint_binding_cs/ServicePoint/{BindGen/ConstantsNative.g.cs => Constants.g.cs} (95%) rename crates/servicepoint_binding_cs/ServicePoint/{BindGen/Cp437GridNative.g.cs => Cp437Grid.g.cs} (70%) rename crates/servicepoint_binding_cs/ServicePoint/{BindGen/PacketNative.g.cs => Packet.g.cs} (64%) delete mode 100644 crates/servicepoint_binding_cs/ServicePoint/SpNativeInstance.cs create mode 160000 crates/servicepoint_csbindgen diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..684ec88 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "crates/servicepoint_csbindgen"] + path = crates/servicepoint_csbindgen + url = https://github.com/kaesaecracker/servicepoint_csbindgen.git diff --git a/Cargo.lock b/Cargo.lock index 5bc28b4..6d0ad17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -208,6 +208,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "cpufeatures" version = "0.2.14" @@ -239,9 +248,8 @@ dependencies = [ [[package]] name = "csbindgen" version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c26b9831049b947d154bba920e4124053def72447be6fb106a96f483874b482a" dependencies = [ + "convert_case", "regex", "syn", ] @@ -636,6 +644,7 @@ dependencies = [ name = "servicepoint_binding_cs" version = "0.10.0" dependencies = [ + "convert_case", "csbindgen", "servicepoint", "servicepoint_binding_c", @@ -778,6 +787,12 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + [[package]] name = "utf-8" version = "0.7.6" diff --git a/Cargo.toml b/Cargo.toml index 6e534de..b9641cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,11 @@ [workspace] resolver = "2" members = [ - "crates/*", - "crates/servicepoint_binding_c/examples/lang_c" + "crates/servicepoint", + "crates/servicepoint_binding_c", + "crates/servicepoint_binding_c/examples/lang_c", + "crates/servicepoint_binding_cs", + "crates/servicepoint_csbindgen/csbindgen" ] [workspace.package] diff --git a/crates/servicepoint/examples/random_brightness.rs b/crates/servicepoint/examples/random_brightness.rs index f47cf72..00f4d56 100644 --- a/crates/servicepoint/examples/random_brightness.rs +++ b/crates/servicepoint/examples/random_brightness.rs @@ -31,11 +31,8 @@ fn main() { let mut filled_grid = Bitmap::max_sized(); filled_grid.fill(true); - let command = BitmapLinearWin( - Origin::ZERO, - filled_grid, - CompressionCode::Lzma, - ); + let command = + BitmapLinearWin(Origin::ZERO, filled_grid, CompressionCode::Lzma); connection.send(command).expect("send failed"); } diff --git a/crates/servicepoint_binding_c/src/bit_vec.rs b/crates/servicepoint_binding_c/src/bit_vec.rs index 7f2258a..23429ba 100644 --- a/crates/servicepoint_binding_c/src/bit_vec.rs +++ b/crates/servicepoint_binding_c/src/bit_vec.rs @@ -2,9 +2,9 @@ //! //! prefix `sp_bitvec_` -use std::ptr::NonNull; use crate::SPByteSlice; use servicepoint::bitvec::prelude::{BitVec, Msb0}; +use std::ptr::NonNull; /// A vector of bits /// diff --git a/crates/servicepoint_binding_c/src/bitmap.rs b/crates/servicepoint_binding_c/src/bitmap.rs index b327fd2..aac605d 100644 --- a/crates/servicepoint_binding_c/src/bitmap.rs +++ b/crates/servicepoint_binding_c/src/bitmap.rs @@ -2,8 +2,8 @@ //! //! prefix `sp_bitmap_` -use std::ptr::NonNull; use servicepoint::{DataRef, Grid}; +use std::ptr::NonNull; use crate::byte_slice::SPByteSlice; @@ -43,9 +43,7 @@ pub unsafe extern "C" fn sp_bitmap_new( width: usize, height: usize, ) -> NonNull { - let result = Box::new(SPBitmap(servicepoint::Bitmap::new( - width, height, - ))); + let result = Box::new(SPBitmap(servicepoint::Bitmap::new(width, height))); NonNull::from(Box::leak(result)) } @@ -80,9 +78,8 @@ pub unsafe extern "C" fn sp_bitmap_load( ) -> NonNull { assert!(!data.is_null()); let data = std::slice::from_raw_parts(data, data_length); - let result = Box::new(SPBitmap(servicepoint::Bitmap::load( - width, height, data, - ))); + let result = + Box::new(SPBitmap(servicepoint::Bitmap::load(width, height, data))); NonNull::from(Box::leak(result)) } diff --git a/crates/servicepoint_binding_c/src/brightness_grid.rs b/crates/servicepoint_binding_c/src/brightness_grid.rs index 3c94b57..977c976 100644 --- a/crates/servicepoint_binding_c/src/brightness_grid.rs +++ b/crates/servicepoint_binding_c/src/brightness_grid.rs @@ -48,9 +48,9 @@ pub unsafe extern "C" fn sp_brightness_grid_new( width: usize, height: usize, ) -> NonNull { - let result = Box::new(SPBrightnessGrid( - servicepoint::BrightnessGrid::new(width, height), - )); + let result = Box::new(SPBrightnessGrid(servicepoint::BrightnessGrid::new( + width, height, + ))); NonNull::from(Box::leak(result)) } diff --git a/crates/servicepoint_binding_c/src/command.rs b/crates/servicepoint_binding_c/src/command.rs index a4ebc1a..24b733f 100644 --- a/crates/servicepoint_binding_c/src/command.rs +++ b/crates/servicepoint_binding_c/src/command.rs @@ -164,9 +164,8 @@ pub unsafe extern "C" fn sp_command_brightness( ) -> NonNull { let brightness = Brightness::try_from(brightness).expect("invalid brightness"); - let result = Box::new(SPCommand( - servicepoint::Command::Brightness(brightness), - )); + let result = + Box::new(SPCommand(servicepoint::Command::Brightness(brightness))); NonNull::from(Box::leak(result)) } @@ -196,9 +195,10 @@ pub unsafe extern "C" fn sp_command_char_brightness( ) -> NonNull { assert!(!grid.is_null()); let byte_grid = *Box::from_raw(grid); - let result = Box::new(SPCommand( - servicepoint::Command::CharBrightness(Origin::new(x, y), byte_grid.0), - )); + let result = Box::new(SPCommand(servicepoint::Command::CharBrightness( + Origin::new(x, y), + byte_grid.0, + ))); NonNull::from(Box::leak(result)) } @@ -235,13 +235,11 @@ pub unsafe extern "C" fn sp_command_bitmap_linear( ) -> NonNull { assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - let result = Box::new(SPCommand( - servicepoint::Command::BitmapLinear( - offset, - bit_vec.into(), - compression.try_into().expect("invalid compression code"), - ), - )); + let result = Box::new(SPCommand(servicepoint::Command::BitmapLinear( + offset, + bit_vec.into(), + compression.try_into().expect("invalid compression code"), + ))); NonNull::from(Box::leak(result)) } @@ -278,13 +276,11 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_and( ) -> NonNull { assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - let result = Box::new(SPCommand( - servicepoint::Command::BitmapLinearAnd( - offset, - bit_vec.into(), - compression.try_into().expect("invalid compression code"), - ), - )); + let result = Box::new(SPCommand(servicepoint::Command::BitmapLinearAnd( + offset, + bit_vec.into(), + compression.try_into().expect("invalid compression code"), + ))); NonNull::from(Box::leak(result)) } @@ -321,13 +317,11 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_or( ) -> NonNull { assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - let result = Box::new(SPCommand( - servicepoint::Command::BitmapLinearOr( - offset, - bit_vec.into(), - compression.try_into().expect("invalid compression code"), - ), - )); + let result = Box::new(SPCommand(servicepoint::Command::BitmapLinearOr( + offset, + bit_vec.into(), + compression.try_into().expect("invalid compression code"), + ))); NonNull::from(Box::leak(result)) } @@ -364,13 +358,11 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_xor( ) -> NonNull { assert!(!bit_vec.is_null()); let bit_vec = *Box::from_raw(bit_vec); - let result = Box::new(SPCommand( - servicepoint::Command::BitmapLinearXor( - offset, - bit_vec.into(), - compression.try_into().expect("invalid compression code"), - ), - )); + let result = Box::new(SPCommand(servicepoint::Command::BitmapLinearXor( + offset, + bit_vec.into(), + compression.try_into().expect("invalid compression code"), + ))); NonNull::from(Box::leak(result)) } @@ -400,9 +392,10 @@ pub unsafe extern "C" fn sp_command_cp437_data( ) -> NonNull { assert!(!grid.is_null()); let grid = *Box::from_raw(grid); - let result = Box::new(SPCommand( - servicepoint::Command::Cp437Data(Origin::new(x, y), grid.0), - )); + let result = Box::new(SPCommand(servicepoint::Command::Cp437Data( + Origin::new(x, y), + grid.0, + ))); NonNull::from(Box::leak(result)) } @@ -435,15 +428,13 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_win( ) -> NonNull { assert!(!bitmap.is_null()); let byte_grid = (*Box::from_raw(bitmap)).0; - let result = Box::new(SPCommand( - servicepoint::Command::BitmapLinearWin( - Origin::new(x, y), - byte_grid, - compression_code - .try_into() - .expect("invalid compression code"), - ), - )); + let result = Box::new(SPCommand(servicepoint::Command::BitmapLinearWin( + Origin::new(x, y), + byte_grid, + compression_code + .try_into() + .expect("invalid compression code"), + ))); NonNull::from(Box::leak(result)) } diff --git a/crates/servicepoint_binding_c/src/cp437_grid.rs b/crates/servicepoint_binding_c/src/cp437_grid.rs index b940ae4..e2836ce 100644 --- a/crates/servicepoint_binding_c/src/cp437_grid.rs +++ b/crates/servicepoint_binding_c/src/cp437_grid.rs @@ -2,9 +2,9 @@ //! //! prefix `sp_cp437_grid_` -use std::ptr::NonNull; use crate::SPByteSlice; use servicepoint::{DataRef, Grid}; +use std::ptr::NonNull; /// A C-wrapper for grid containing codepage 437 characters. /// @@ -41,9 +41,8 @@ pub unsafe extern "C" fn sp_cp437_grid_new( width: usize, height: usize, ) -> NonNull { - let result = Box::new(SPCp437Grid( - servicepoint::Cp437Grid::new(width, height), - )); + let result = + Box::new(SPCp437Grid(servicepoint::Cp437Grid::new(width, height))); NonNull::from(Box::leak(result)) } @@ -73,9 +72,9 @@ pub unsafe extern "C" fn sp_cp437_grid_load( ) -> NonNull { assert!(data.is_null()); let data = std::slice::from_raw_parts(data, data_length); - let result = Box::new(SPCp437Grid( - servicepoint::Cp437Grid::load(width, height, data), - )); + let result = Box::new(SPCp437Grid(servicepoint::Cp437Grid::load( + width, height, data, + ))); NonNull::from(Box::leak(result)) } diff --git a/crates/servicepoint_binding_cs/Cargo.toml b/crates/servicepoint_binding_cs/Cargo.toml index ffceefd..94a174f 100644 --- a/crates/servicepoint_binding_cs/Cargo.toml +++ b/crates/servicepoint_binding_cs/Cargo.toml @@ -10,7 +10,7 @@ crate-type = ["cdylib"] test = false [build-dependencies] -csbindgen = "1.9.3" +csbindgen = { path = "../servicepoint_csbindgen/csbindgen" } convert_case = "0.6.0" [dependencies] diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/Extensions.cs b/crates/servicepoint_binding_cs/ServicePoint/BindGen/Extensions.cs deleted file mode 100644 index 20f9436..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/Extensions.cs +++ /dev/null @@ -1,49 +0,0 @@ -using GroupedNativeMethodsGenerator; - -namespace ServicePoint.BindGen; - -[GroupedNativeMethods(removePrefix: "sp_bitmap_")] -public static unsafe partial class BitmapNative -{ -} - -[GroupedNativeMethods(removePrefix: "sp_bitvec_")] -public static unsafe partial class BitVecNative -{ -} - -[GroupedNativeMethods(removePrefix: "sp_brightness_grid")] -public static unsafe partial class BrightnessGridNative -{ -} - -[GroupedNativeMethods(removePrefix: "sp_byte_slice")] -public static unsafe partial class ByteSliceNative -{ -} - -[GroupedNativeMethods(removePrefix: "sp_command_")] -public static unsafe partial class CommandNative -{ -} - -[GroupedNativeMethods(removePrefix: "sp_connection_")] -public static unsafe partial class ConnectionNative -{ -} - -[GroupedNativeMethods(removePrefix: "sp_constants_")] -public static unsafe partial class ConstantsNative -{ -} - - -[GroupedNativeMethods(removePrefix: "sp_cp437_grid_")] -public static unsafe partial class Cp437GridNative -{ -} - -[GroupedNativeMethods(removePrefix: "sp_packet_")] -public static unsafe partial class PacketNative -{ -} diff --git a/crates/servicepoint_binding_cs/ServicePoint/BitVec.cs b/crates/servicepoint_binding_cs/ServicePoint/BitVec.cs index c086f75..8bb2d43 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BitVec.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/BitVec.cs @@ -1,87 +1,12 @@ -using ServicePoint.BindGen; - namespace ServicePoint; -public sealed class BitVec : SpNativeInstance +public sealed partial class BitVec { - public static BitVec New(nuint size) - { - unsafe - { - return new BitVec(BitVecNative.sp_bitvec_new(size)); - } - } - - public static BitVec Load(Span bytes) - { - unsafe - { - fixed (byte* bytesPtr = bytes) - { - return new BitVec(BitVecNative.sp_bitvec_load(bytesPtr, (nuint)bytes.Length)); - } - } - } - - public BitVec Clone() - { - unsafe - { - return new BitVec(Instance->Clone()); - } - } - public bool this[nuint index] { - get - { - unsafe - { - return Instance->Get(index); - } - } - set - { - unsafe - { - Instance->Set(index, value); - } - } + get => Get(index); + set => Set(index, value); } - public void Fill(bool value) - { - unsafe - { - Instance->Fill(value); - } - } - - public nuint Length - { - get - { - unsafe - { - return Instance->Len(); - } - } - } - - public Span Data - { - get - { - unsafe - { - return Instance->UnsafeDataRef().AsSpan(); - } - } - } - - private unsafe BitVec(BindGen.BitVec* instance) : base(instance) - { - } - - private protected override unsafe void Free() => Instance->Free(); + public Span Data => UnsafeDataRef().AsSpan(); } diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/BitVecNative.g.cs b/crates/servicepoint_binding_cs/ServicePoint/BitVec.g.cs similarity index 72% rename from crates/servicepoint_binding_cs/ServicePoint/BindGen/BitVecNative.g.cs rename to crates/servicepoint_binding_cs/ServicePoint/BitVec.g.cs index b43ba3e..83eaeb5 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/BitVecNative.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/BitVec.g.cs @@ -8,14 +8,95 @@ using System; using System.Runtime.InteropServices; -namespace ServicePoint.BindGen +namespace ServicePoint { - public static unsafe partial class BitVecNative + + public unsafe sealed partial class BitVec: IDisposable { +#nullable enable + public BitVec(nuint size) : this(sp_bitvec_new(size)) {} + + public static BitVec Load(byte* data, nuint data_length) + { + return new BitVec(BitVec.sp_bitvec_load(data, data_length)); + } + + public BitVec Clone() + { + return new BitVec(BitVec.sp_bitvec_clone(Instance)); + } + + public bool Get(nuint index) + { + return BitVec.sp_bitvec_get(Instance, index); + } + + public void Set(nuint index, bool value) + { + BitVec.sp_bitvec_set(Instance, index, value); + } + + public void Fill(bool value) + { + BitVec.sp_bitvec_fill(Instance, value); + } + + public nuint Len() + { + return BitVec.sp_bitvec_len(Instance); + } + + public bool IsEmpty() + { + return BitVec.sp_bitvec_is_empty(Instance); + } + + public SPByteSlice UnsafeDataRef() + { + return BitVec.sp_bitvec_unsafe_data_ref(Instance); + } + + + private SPBitVec* _instance; + internal SPBitVec* Instance + { + get + { + if (_instance == null) + throw new NullReferenceException("instance is null"); + return _instance; + } + } + + private BitVec(SPBitVec* instance) + { + ArgumentNullException.ThrowIfNull(instance); + _instance = instance; + } + + internal SPBitVec* Into() + { + var instance = Instance; + _instance = null; + return instance; + } + + private void Free() + { + if (_instance != null) + BitVec.sp_bitvec_free(Into()); + } + + public void Dispose() + { + Free(); + GC.SuppressFinalize(this); + } + + ~BitVec() => Free(); + const string __DllName = "servicepoint_binding_c"; - - - +#nullable restore /// /// Creates a new [SPBitVec] instance. /// @@ -37,7 +118,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_bitvec_free`. /// [DllImport(__DllName, EntryPoint = "sp_bitvec_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp_bitvec_new(nuint size); + private static extern SPBitVec* sp_bitvec_new(nuint size); /// /// Interpret the data as a series of bits and load then into a new [SPBitVec] instance. @@ -58,7 +139,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_bitvec_free`. /// [DllImport(__DllName, EntryPoint = "sp_bitvec_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp_bitvec_load(byte* data, nuint data_length); + private static extern SPBitVec* sp_bitvec_load(byte* data, nuint data_length); /// /// Clones a [SPBitVec]. @@ -79,7 +160,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_bitvec_free`. /// [DllImport(__DllName, EntryPoint = "sp_bitvec_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BitVec* sp_bitvec_clone(BitVec* bit_vec); + private static extern SPBitVec* sp_bitvec_clone(SPBitVec* bit_vec); /// /// Deallocates a [SPBitVec]. @@ -97,7 +178,7 @@ namespace ServicePoint.BindGen /// - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand] /// [DllImport(__DllName, EntryPoint = "sp_bitvec_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitvec_free(BitVec* bit_vec); + private static extern void sp_bitvec_free(SPBitVec* bit_vec); /// /// Gets the value of a bit from the [SPBitVec]. @@ -123,7 +204,7 @@ namespace ServicePoint.BindGen /// [DllImport(__DllName, EntryPoint = "sp_bitvec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_bitvec_get(BitVec* bit_vec, nuint index); + private static extern bool sp_bitvec_get(SPBitVec* bit_vec, nuint index); /// /// Sets the value of a bit in the [SPBitVec]. @@ -147,7 +228,7 @@ namespace ServicePoint.BindGen /// - `bit_vec` is not written to or read from concurrently /// [DllImport(__DllName, EntryPoint = "sp_bitvec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitvec_set(BitVec* bit_vec, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); + private static extern void sp_bitvec_set(SPBitVec* bit_vec, nuint index, [MarshalAs(UnmanagedType.U1)] bool value); /// /// Sets the value of all bits in the [SPBitVec]. @@ -169,7 +250,7 @@ namespace ServicePoint.BindGen /// - `bit_vec` is not written to or read from concurrently /// [DllImport(__DllName, EntryPoint = "sp_bitvec_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitvec_fill(BitVec* bit_vec, [MarshalAs(UnmanagedType.U1)] bool value); + private static extern void sp_bitvec_fill(SPBitVec* bit_vec, [MarshalAs(UnmanagedType.U1)] bool value); /// /// Gets the length of the [SPBitVec] in bits. @@ -189,7 +270,7 @@ namespace ServicePoint.BindGen /// - `bit_vec` points to a valid [SPBitVec] /// [DllImport(__DllName, EntryPoint = "sp_bitvec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_bitvec_len(BitVec* bit_vec); + private static extern nuint sp_bitvec_len(SPBitVec* bit_vec); /// /// Returns true if length is 0. @@ -210,7 +291,7 @@ namespace ServicePoint.BindGen /// [DllImport(__DllName, EntryPoint = "sp_bitvec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_bitvec_is_empty(BitVec* bit_vec); + private static extern bool sp_bitvec_is_empty(SPBitVec* bit_vec); /// /// Gets an unsafe reference to the data of the [SPBitVec] instance. @@ -232,13 +313,13 @@ namespace ServicePoint.BindGen /// - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly /// [DllImport(__DllName, EntryPoint = "sp_bitvec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_bitvec_unsafe_data_ref(BitVec* bit_vec); + private static extern SPByteSlice sp_bitvec_unsafe_data_ref(SPBitVec* bit_vec); } [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct BitVec + public unsafe partial struct SPBitVec { } diff --git a/crates/servicepoint_binding_cs/ServicePoint/Bitmap.cs b/crates/servicepoint_binding_cs/ServicePoint/Bitmap.cs index 1f39689..27be715 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/Bitmap.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Bitmap.cs @@ -1,100 +1,12 @@ -using ServicePoint.BindGen; - namespace ServicePoint; -public sealed class Bitmap : SpNativeInstance +public sealed partial class Bitmap { - public static Bitmap New(nuint width, nuint height) - { - unsafe - { - return new Bitmap(BitmapNative.sp_bitmap_new(width, height)); - } - } - - public static Bitmap Load(nuint width, nuint height, Span bytes) - { - unsafe - { - fixed (byte* bytesPtr = bytes) - { - return new Bitmap(BitmapNative.sp_bitmap_load(width, height, bytesPtr, - (nuint)bytes.Length)); - } - } - } - - public Bitmap Clone() - { - unsafe - { - return new Bitmap(Instance->Clone()); - } - } - public bool this[nuint x, nuint y] { - get - { - unsafe - { - return Instance->Get(x, y); - } - } - set - { - unsafe - { - Instance->Set(x, y, value); - } - } + get => Get(x, y); + set => Set(x, y, value); } - public void Fill(bool value) - { - unsafe - { - Instance->Fill(value); - } - } - - public nuint Width - { - get - { - unsafe - { - return Instance->Width(); - } - } - } - - public nuint Height - { - get - { - unsafe - { - return Instance->Height(); - } - } - } - - public Span Data - { - get - { - unsafe - { - var slice = Instance->UnsafeDataRef(); - return new Span(slice.start, (int)slice.length); - } - } - } - - private unsafe Bitmap(BindGen.Bitmap* instance) : base(instance) - { - } - - private protected override unsafe void Free() => Instance->Free(); + public Span Data => UnsafeDataRef().AsSpan(); } diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/BitmapNative.g.cs b/crates/servicepoint_binding_cs/ServicePoint/Bitmap.g.cs similarity index 72% rename from crates/servicepoint_binding_cs/ServicePoint/BindGen/BitmapNative.g.cs rename to crates/servicepoint_binding_cs/ServicePoint/Bitmap.g.cs index 9d8c1ac..e3023ef 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/BitmapNative.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Bitmap.g.cs @@ -8,14 +8,95 @@ using System; using System.Runtime.InteropServices; -namespace ServicePoint.BindGen +namespace ServicePoint { - public static unsafe partial class BitmapNative + + public unsafe sealed partial class Bitmap: IDisposable { +#nullable enable + public Bitmap(nuint width, nuint height) : this(sp_bitmap_new(width, height)) {} + + public static Bitmap Load(nuint width, nuint height, byte* data, nuint data_length) + { + return new Bitmap(Bitmap.sp_bitmap_load(width, height, data, data_length)); + } + + public Bitmap Clone() + { + return new Bitmap(Bitmap.sp_bitmap_clone(Instance)); + } + + public bool Get(nuint x, nuint y) + { + return Bitmap.sp_bitmap_get(Instance, x, y); + } + + public void Set(nuint x, nuint y, bool value) + { + Bitmap.sp_bitmap_set(Instance, x, y, value); + } + + public void Fill(bool value) + { + Bitmap.sp_bitmap_fill(Instance, value); + } + + public nuint Width() + { + return Bitmap.sp_bitmap_width(Instance); + } + + public nuint Height() + { + return Bitmap.sp_bitmap_height(Instance); + } + + public SPByteSlice UnsafeDataRef() + { + return Bitmap.sp_bitmap_unsafe_data_ref(Instance); + } + + + private SPBitmap* _instance; + internal SPBitmap* Instance + { + get + { + if (_instance == null) + throw new NullReferenceException("instance is null"); + return _instance; + } + } + + private Bitmap(SPBitmap* instance) + { + ArgumentNullException.ThrowIfNull(instance); + _instance = instance; + } + + internal SPBitmap* Into() + { + var instance = Instance; + _instance = null; + return instance; + } + + private void Free() + { + if (_instance != null) + Bitmap.sp_bitmap_free(Into()); + } + + public void Dispose() + { + Free(); + GC.SuppressFinalize(this); + } + + ~Bitmap() => Free(); + const string __DllName = "servicepoint_binding_c"; - - - +#nullable restore /// /// Creates a new [SPBitmap] with the specified dimensions. /// @@ -38,7 +119,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_bitmap_free`. /// [DllImport(__DllName, EntryPoint = "sp_bitmap_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Bitmap* sp_bitmap_new(nuint width, nuint height); + private static extern SPBitmap* sp_bitmap_new(nuint width, nuint height); /// /// Loads a [SPBitmap] with the specified dimensions from the provided data. @@ -65,7 +146,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_bitmap_free`. /// [DllImport(__DllName, EntryPoint = "sp_bitmap_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Bitmap* sp_bitmap_load(nuint width, nuint height, byte* data, nuint data_length); + private static extern SPBitmap* sp_bitmap_load(nuint width, nuint height, byte* data, nuint data_length); /// /// Clones a [SPBitmap]. @@ -86,7 +167,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_bitmap_free`. /// [DllImport(__DllName, EntryPoint = "sp_bitmap_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Bitmap* sp_bitmap_clone(Bitmap* bitmap); + private static extern SPBitmap* sp_bitmap_clone(SPBitmap* bitmap); /// /// Deallocates a [SPBitmap]. @@ -104,7 +185,7 @@ namespace ServicePoint.BindGen /// - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand] /// [DllImport(__DllName, EntryPoint = "sp_bitmap_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitmap_free(Bitmap* bitmap); + private static extern void sp_bitmap_free(SPBitmap* bitmap); /// /// Gets the current value at the specified position in the [SPBitmap]. @@ -128,7 +209,7 @@ namespace ServicePoint.BindGen /// [DllImport(__DllName, EntryPoint = "sp_bitmap_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_bitmap_get(Bitmap* bitmap, nuint x, nuint y); + private static extern bool sp_bitmap_get(SPBitmap* bitmap, nuint x, nuint y); /// /// Sets the value of the specified position in the [SPBitmap]. @@ -154,7 +235,7 @@ namespace ServicePoint.BindGen /// - `bitmap` is not written to or read from concurrently /// [DllImport(__DllName, EntryPoint = "sp_bitmap_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitmap_set(Bitmap* bitmap, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value); + private static extern void sp_bitmap_set(SPBitmap* bitmap, nuint x, nuint y, [MarshalAs(UnmanagedType.U1)] bool value); /// /// Sets the state of all pixels in the [SPBitmap]. @@ -176,7 +257,7 @@ namespace ServicePoint.BindGen /// - `bitmap` is not written to or read from concurrently /// [DllImport(__DllName, EntryPoint = "sp_bitmap_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_bitmap_fill(Bitmap* bitmap, [MarshalAs(UnmanagedType.U1)] bool value); + private static extern void sp_bitmap_fill(SPBitmap* bitmap, [MarshalAs(UnmanagedType.U1)] bool value); /// /// Gets the width in pixels of the [SPBitmap] instance. @@ -196,7 +277,7 @@ namespace ServicePoint.BindGen /// - `bitmap` points to a valid [SPBitmap] /// [DllImport(__DllName, EntryPoint = "sp_bitmap_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_bitmap_width(Bitmap* bitmap); + private static extern nuint sp_bitmap_width(SPBitmap* bitmap); /// /// Gets the height in pixels of the [SPBitmap] instance. @@ -216,7 +297,7 @@ namespace ServicePoint.BindGen /// - `bitmap` points to a valid [SPBitmap] /// [DllImport(__DllName, EntryPoint = "sp_bitmap_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_bitmap_height(Bitmap* bitmap); + private static extern nuint sp_bitmap_height(SPBitmap* bitmap); /// /// Gets an unsafe reference to the data of the [SPBitmap] instance. @@ -234,13 +315,13 @@ namespace ServicePoint.BindGen /// - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly /// [DllImport(__DllName, EntryPoint = "sp_bitmap_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_bitmap_unsafe_data_ref(Bitmap* bitmap); + private static extern SPByteSlice sp_bitmap_unsafe_data_ref(SPBitmap* bitmap); } [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Bitmap + public unsafe partial struct SPBitmap { } diff --git a/crates/servicepoint_binding_cs/ServicePoint/BrightnessGrid.cs b/crates/servicepoint_binding_cs/ServicePoint/BrightnessGrid.cs index efe3c0f..c6590e6 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BrightnessGrid.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/BrightnessGrid.cs @@ -1,99 +1,12 @@ -using ServicePoint.BindGen; - namespace ServicePoint; -public sealed class BrightnessGrid : SpNativeInstance +public sealed partial class BrightnessGrid { - public static BrightnessGrid New(nuint width, nuint height) - { - unsafe - { - return new BrightnessGrid(BrightnessGridNative.sp_brightness_grid_new(width, height)); - } - } - - public static BrightnessGrid Load(nuint width, nuint height, Span bytes) - { - unsafe - { - fixed (byte* bytesPtr = bytes) - { - return new BrightnessGrid(BrightnessGridNative.sp_brightness_grid_load(width, height, bytesPtr, - (nuint)bytes.Length)); - } - } - } - - public BrightnessGrid Clone() - { - unsafe - { - return new BrightnessGrid(Instance->Clone()); - } - } - public byte this[nuint x, nuint y] { - get - { - unsafe - { - return Instance->Get(x, y); - } - } - set - { - unsafe - { - Instance->Set(x, y, value); - } - } + get => Get(x, y); + set => Set(x, y, value); } - public void Fill(byte value) - { - unsafe - { - Instance->Fill(value); - } - } - - public nuint Width - { - get - { - unsafe - { - return Instance->Width(); - } - } - } - - public nuint Height - { - get - { - unsafe - { - return Instance->Height(); - } - } - } - - public Span Data - { - get - { - unsafe - { - return Instance->UnsafeDataRef().AsSpan(); - } - } - } - - private unsafe BrightnessGrid(BindGen.BrightnessGrid* instance) : base(instance) - { - } - - private protected override unsafe void Free() => Instance->Free(); + public Span Data => UnsafeDataRef().AsSpan(); } diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/BrightnessGridNative.g.cs b/crates/servicepoint_binding_cs/ServicePoint/BrightnessGrid.g.cs similarity index 71% rename from crates/servicepoint_binding_cs/ServicePoint/BindGen/BrightnessGridNative.g.cs rename to crates/servicepoint_binding_cs/ServicePoint/BrightnessGrid.g.cs index 9c9586f..0cad03a 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/BrightnessGridNative.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/BrightnessGrid.g.cs @@ -8,7 +8,7 @@ using System; using System.Runtime.InteropServices; -namespace ServicePoint.BindGen +namespace ServicePoint { public static unsafe partial class BrightnessGridNative { @@ -19,6 +19,95 @@ namespace ServicePoint.BindGen public const byte SP_BRIGHTNESS_LEVELS = 12; + + } + + public unsafe sealed partial class BrightnessGrid: IDisposable + { +#nullable enable + public BrightnessGrid(nuint width, nuint height) : this(sp_brightness_grid_new(width, height)) {} + + public static BrightnessGrid Load(nuint width, nuint height, byte* data, nuint data_length) + { + return new BrightnessGrid(BrightnessGrid.sp_brightness_grid_load(width, height, data, data_length)); + } + + public BrightnessGrid Clone() + { + return new BrightnessGrid(BrightnessGrid.sp_brightness_grid_clone(Instance)); + } + + public byte Get(nuint x, nuint y) + { + return BrightnessGrid.sp_brightness_grid_get(Instance, x, y); + } + + public void Set(nuint x, nuint y, byte value) + { + BrightnessGrid.sp_brightness_grid_set(Instance, x, y, value); + } + + public void Fill(byte value) + { + BrightnessGrid.sp_brightness_grid_fill(Instance, value); + } + + public nuint Width() + { + return BrightnessGrid.sp_brightness_grid_width(Instance); + } + + public nuint Height() + { + return BrightnessGrid.sp_brightness_grid_height(Instance); + } + + public SPByteSlice UnsafeDataRef() + { + return BrightnessGrid.sp_brightness_grid_unsafe_data_ref(Instance); + } + + + private SPBrightnessGrid* _instance; + internal SPBrightnessGrid* Instance + { + get + { + if (_instance == null) + throw new NullReferenceException("instance is null"); + return _instance; + } + } + + private BrightnessGrid(SPBrightnessGrid* instance) + { + ArgumentNullException.ThrowIfNull(instance); + _instance = instance; + } + + internal SPBrightnessGrid* Into() + { + var instance = Instance; + _instance = null; + return instance; + } + + private void Free() + { + if (_instance != null) + BrightnessGrid.sp_brightness_grid_free(Into()); + } + + public void Dispose() + { + Free(); + GC.SuppressFinalize(this); + } + + ~BrightnessGrid() => Free(); + + const string __DllName = "servicepoint_binding_c"; +#nullable restore /// /// Creates a new [SPBrightnessGrid] with the specified dimensions. /// @@ -32,7 +121,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_brightness_grid_free`. /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BrightnessGrid* sp_brightness_grid_new(nuint width, nuint height); + private static extern SPBrightnessGrid* sp_brightness_grid_new(nuint width, nuint height); /// /// Loads a [SPBrightnessGrid] with the specified dimensions from the provided data. @@ -54,7 +143,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_brightness_grid_free`. /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BrightnessGrid* sp_brightness_grid_load(nuint width, nuint height, byte* data, nuint data_length); + private static extern SPBrightnessGrid* sp_brightness_grid_load(nuint width, nuint height, byte* data, nuint data_length); /// /// Clones a [SPBrightnessGrid]. @@ -79,7 +168,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_brightness_grid_free`. /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern BrightnessGrid* sp_brightness_grid_clone(BrightnessGrid* brightness_grid); + private static extern SPBrightnessGrid* sp_brightness_grid_clone(SPBrightnessGrid* brightness_grid); /// /// Deallocates a [SPBrightnessGrid]. @@ -101,7 +190,7 @@ namespace ServicePoint.BindGen /// - `brightness_grid` was not passed to another consuming function, e.g. to create a [SPCommand] /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_brightness_grid_free(BrightnessGrid* brightness_grid); + private static extern void sp_brightness_grid_free(SPBrightnessGrid* brightness_grid); /// /// Gets the current value at the specified position. @@ -126,7 +215,7 @@ namespace ServicePoint.BindGen /// - `brightness_grid` is not written to concurrently /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern byte sp_brightness_grid_get(BrightnessGrid* brightness_grid, nuint x, nuint y); + private static extern byte sp_brightness_grid_get(SPBrightnessGrid* brightness_grid, nuint x, nuint y); /// /// Sets the value of the specified position in the [SPBrightnessGrid]. @@ -153,7 +242,7 @@ namespace ServicePoint.BindGen /// - `brightness_grid` is not written to or read from concurrently /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_brightness_grid_set(BrightnessGrid* brightness_grid, nuint x, nuint y, byte value); + private static extern void sp_brightness_grid_set(SPBrightnessGrid* brightness_grid, nuint x, nuint y, byte value); /// /// Sets the value of all cells in the [SPBrightnessGrid]. @@ -176,7 +265,7 @@ namespace ServicePoint.BindGen /// - `brightness_grid` is not written to or read from concurrently /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_brightness_grid_fill(BrightnessGrid* brightness_grid, byte value); + private static extern void sp_brightness_grid_fill(SPBrightnessGrid* brightness_grid, byte value); /// /// Gets the width of the [SPBrightnessGrid] instance. @@ -198,7 +287,7 @@ namespace ServicePoint.BindGen /// - `brightness_grid` points to a valid [SPBrightnessGrid] /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_brightness_grid_width(BrightnessGrid* brightness_grid); + private static extern nuint sp_brightness_grid_width(SPBrightnessGrid* brightness_grid); /// /// Gets the height of the [SPBrightnessGrid] instance. @@ -220,7 +309,7 @@ namespace ServicePoint.BindGen /// - `brightness_grid` points to a valid [SPBrightnessGrid] /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_brightness_grid_height(BrightnessGrid* brightness_grid); + private static extern nuint sp_brightness_grid_height(SPBrightnessGrid* brightness_grid); /// /// Gets an unsafe reference to the data of the [SPBrightnessGrid] instance. @@ -244,13 +333,13 @@ namespace ServicePoint.BindGen /// - the returned memory range is never accessed concurrently, either via the [SPBrightnessGrid] or directly /// [DllImport(__DllName, EntryPoint = "sp_brightness_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_brightness_grid_unsafe_data_ref(BrightnessGrid* brightness_grid); + private static extern SPByteSlice sp_brightness_grid_unsafe_data_ref(SPBrightnessGrid* brightness_grid); } [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct BrightnessGrid + public unsafe partial struct SPBrightnessGrid { } diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ByteSliceNative.g.cs b/crates/servicepoint_binding_cs/ServicePoint/ByteSlice.g.cs similarity index 81% rename from crates/servicepoint_binding_cs/ServicePoint/BindGen/ByteSliceNative.g.cs rename to crates/servicepoint_binding_cs/ServicePoint/ByteSlice.g.cs index 017b58f..0224040 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ByteSliceNative.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/ByteSlice.g.cs @@ -8,12 +8,12 @@ using System; using System.Runtime.InteropServices; -namespace ServicePoint.BindGen +namespace ServicePoint { - + [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct ByteSlice + public unsafe partial struct SPByteSlice { public byte* start; public nuint length; diff --git a/crates/servicepoint_binding_cs/ServicePoint/Command.cs b/crates/servicepoint_binding_cs/ServicePoint/Command.cs index 53ac982..3e65d0d 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/Command.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Command.cs @@ -1,129 +1,11 @@ using System.Diagnostics.CodeAnalysis; -using ServicePoint.BindGen; namespace ServicePoint; -public sealed class Command : SpNativeInstance +public sealed partial class Command { public static bool TryFromPacket(Packet packet, [MaybeNullWhen(false)] out Command command) { - unsafe - { - var result = CommandNative.sp_command_try_from_packet(packet.Into()); - if (result == null) - { - command = null; - return false; - } - - command = new Command(result); - return true; - } + return (command = TryFromPacket(packet)) != null; } - - public Command Clone() - { - unsafe - { - return new Command(Instance->Clone()); - } - } - - public static Command Clear() - { - unsafe - { - return new Command(CommandNative.sp_command_clear()); - } - } - - public static Command HardReset() - { - unsafe - { - return new Command(CommandNative.sp_command_hard_reset()); - } - } - - public static Command FadeOut() - { - unsafe - { - return new Command(CommandNative.sp_command_fade_out()); - } - } - - public static Command Brightness(byte brightness) - { - unsafe - { - return new Command(CommandNative.sp_command_brightness(brightness)); - } - } - - public static Command CharBrightness(ushort x, ushort y, BrightnessGrid grid) - { - unsafe - { - return new Command(CommandNative.sp_command_char_brightness(x, y, grid.Into())); - } - } - - public static Command BitmapLinear(ushort offset, BitVec bitVec, CompressionCode compressionCode) - { - unsafe - { - return new Command( - CommandNative.sp_command_bitmap_linear(offset, bitVec.Into(), compressionCode)); - } - } - - public static Command BitmapLinearAnd(ushort offset, BitVec bitVec, CompressionCode compressionCode) - { - unsafe - { - return new Command( - CommandNative.sp_command_bitmap_linear_and(offset, bitVec.Into(), compressionCode)); - } - } - - public static Command BitmapLinearOr(ushort offset, BitVec bitVec, CompressionCode compressionCode) - { - unsafe - { - return new Command( - CommandNative.sp_command_bitmap_linear_or(offset, bitVec.Into(), compressionCode)); - } - } - - public static Command BitmapLinearXor(ushort offset, BitVec bitVec, CompressionCode compressionCode) - { - unsafe - { - return new Command( - CommandNative.sp_command_bitmap_linear_xor(offset, bitVec.Into(), compressionCode)); - } - } - - public static Command BitmapLinearWin(ushort x, ushort y, Bitmap bitmap, CompressionCode compression) - { - unsafe - { - return new Command(CommandNative.sp_command_bitmap_linear_win(x, y, bitmap.Into(), compression)); - } - } - - public static Command Cp437Data(ushort x, ushort y, Cp437Grid byteGrid) - { - unsafe - { - return new Command(CommandNative.sp_command_cp437_data(x, y, byteGrid.Into())); - } - } - - private unsafe Command(BindGen.Command* instance) : base(instance) - { - } - - private protected override unsafe void Free() => Instance->Free(); } diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/CommandNative.g.cs b/crates/servicepoint_binding_cs/ServicePoint/Command.g.cs similarity index 74% rename from crates/servicepoint_binding_cs/ServicePoint/BindGen/CommandNative.g.cs rename to crates/servicepoint_binding_cs/ServicePoint/Command.g.cs index eb9eb25..4749448 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/CommandNative.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Command.g.cs @@ -8,14 +8,119 @@ using System; using System.Runtime.InteropServices; -namespace ServicePoint.BindGen +namespace ServicePoint { - public static unsafe partial class CommandNative + + public unsafe sealed partial class Command: IDisposable { +#nullable enable + public static Command? TryFromPacket(Packet packet) + { + var native = Command.sp_command_try_from_packet(packet.Instance); + return native == null ? null : new Command(native); + } + + public Command Clone() + { + return new Command(Command.sp_command_clone(Instance)); + } + + public static Command Clear() + { + return new Command(Command.sp_command_clear()); + } + + public static Command HardReset() + { + return new Command(Command.sp_command_hard_reset()); + } + + public static Command FadeOut() + { + return new Command(Command.sp_command_fade_out()); + } + + public static Command Brightness(byte brightness) + { + return new Command(Command.sp_command_brightness(brightness)); + } + + public static Command CharBrightness(nuint x, nuint y, BrightnessGrid grid) + { + return new Command(Command.sp_command_char_brightness(x, y, grid.Instance)); + } + + public static Command BitmapLinear(nuint offset, BitVec bit_vec, CompressionCode compression) + { + return new Command(Command.sp_command_bitmap_linear(offset, bit_vec.Instance, compression)); + } + + public static Command BitmapLinearAnd(nuint offset, BitVec bit_vec, CompressionCode compression) + { + return new Command(Command.sp_command_bitmap_linear_and(offset, bit_vec.Instance, compression)); + } + + public static Command BitmapLinearOr(nuint offset, BitVec bit_vec, CompressionCode compression) + { + return new Command(Command.sp_command_bitmap_linear_or(offset, bit_vec.Instance, compression)); + } + + public static Command BitmapLinearXor(nuint offset, BitVec bit_vec, CompressionCode compression) + { + return new Command(Command.sp_command_bitmap_linear_xor(offset, bit_vec.Instance, compression)); + } + + public static Command Cp437Data(nuint x, nuint y, Cp437Grid grid) + { + return new Command(Command.sp_command_cp437_data(x, y, grid.Instance)); + } + + public static Command BitmapLinearWin(nuint x, nuint y, Bitmap bitmap, CompressionCode compression_code) + { + return new Command(Command.sp_command_bitmap_linear_win(x, y, bitmap.Instance, compression_code)); + } + + + private SPCommand* _instance; + internal SPCommand* Instance + { + get + { + if (_instance == null) + throw new NullReferenceException("instance is null"); + return _instance; + } + } + + private Command(SPCommand* instance) + { + ArgumentNullException.ThrowIfNull(instance); + _instance = instance; + } + + internal SPCommand* Into() + { + var instance = Instance; + _instance = null; + return instance; + } + + private void Free() + { + if (_instance != null) + Command.sp_command_free(Into()); + } + + public void Dispose() + { + Free(); + GC.SuppressFinalize(this); + } + + ~Command() => Free(); + const string __DllName = "servicepoint_binding_c"; - - - +#nullable restore /// /// Tries to turn a [SPPacket] into a [SPCommand]. /// @@ -38,7 +143,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_command_free`. /// [DllImport(__DllName, EntryPoint = "sp_command_try_from_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_try_from_packet(Packet* packet); + private static extern SPCommand* sp_command_try_from_packet(SPPacket* packet); /// /// Clones a [SPCommand] instance. @@ -59,7 +164,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_command_free`. /// [DllImport(__DllName, EntryPoint = "sp_command_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_clone(Command* command); + private static extern SPCommand* sp_command_clone(SPCommand* command); /// /// Set all pixels to the off state. @@ -82,7 +187,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_command_free`. /// [DllImport(__DllName, EntryPoint = "sp_command_clear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_clear(); + private static extern SPCommand* sp_command_clear(); /// /// Kills the udp daemon on the display, which usually results in a restart. @@ -99,7 +204,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_command_free`. /// [DllImport(__DllName, EntryPoint = "sp_command_hard_reset", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_hard_reset(); + private static extern SPCommand* sp_command_hard_reset(); /// /// A yet-to-be-tested command. @@ -114,7 +219,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_command_free`. /// [DllImport(__DllName, EntryPoint = "sp_command_fade_out", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_fade_out(); + private static extern SPCommand* sp_command_fade_out(); /// /// Set the brightness of all tiles to the same value. @@ -133,7 +238,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_command_free`. /// [DllImport(__DllName, EntryPoint = "sp_command_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_brightness(byte brightness); + private static extern SPCommand* sp_command_brightness(byte brightness); /// /// Set the brightness of individual tiles in a rectangular area of the display. @@ -156,7 +261,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_command_free`. /// [DllImport(__DllName, EntryPoint = "sp_command_char_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_char_brightness(nuint x, nuint y, BrightnessGrid* grid); + private static extern SPCommand* sp_command_char_brightness(nuint x, nuint y, SPBrightnessGrid* grid); /// /// Set pixel data starting at the pixel offset on screen. @@ -186,7 +291,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_command_free`. /// [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_bitmap_linear(nuint offset, BitVec* bit_vec, CompressionCode compression); + private static extern SPCommand* sp_command_bitmap_linear(nuint offset, SPBitVec* bit_vec, CompressionCode compression); /// /// Set pixel data according to an and-mask starting at the offset. @@ -216,7 +321,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_command_free`. /// [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_and", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_bitmap_linear_and(nuint offset, BitVec* bit_vec, CompressionCode compression); + private static extern SPCommand* sp_command_bitmap_linear_and(nuint offset, SPBitVec* bit_vec, CompressionCode compression); /// /// Set pixel data according to an or-mask starting at the offset. @@ -246,7 +351,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_command_free`. /// [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_or", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_bitmap_linear_or(nuint offset, BitVec* bit_vec, CompressionCode compression); + private static extern SPCommand* sp_command_bitmap_linear_or(nuint offset, SPBitVec* bit_vec, CompressionCode compression); /// /// Set pixel data according to a xor-mask starting at the offset. @@ -276,7 +381,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_command_free`. /// [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_xor", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_bitmap_linear_xor(nuint offset, BitVec* bit_vec, CompressionCode compression); + private static extern SPCommand* sp_command_bitmap_linear_xor(nuint offset, SPBitVec* bit_vec, CompressionCode compression); /// /// Show text on the screen. @@ -299,7 +404,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_command_free`. /// [DllImport(__DllName, EntryPoint = "sp_command_cp437_data", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_cp437_data(nuint x, nuint y, Cp437Grid* grid); + private static extern SPCommand* sp_command_cp437_data(nuint x, nuint y, SPCp437Grid* grid); /// /// Sets a window of pixels to the specified values. @@ -324,7 +429,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_command_free`. /// [DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_win", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Command* sp_command_bitmap_linear_win(nuint x, nuint y, Bitmap* bitmap, CompressionCode compression_code); + private static extern SPCommand* sp_command_bitmap_linear_win(nuint x, nuint y, SPBitmap* bitmap, CompressionCode compression_code); /// /// Deallocates a [SPCommand]. @@ -349,13 +454,13 @@ namespace ServicePoint.BindGen /// - `command` was not passed to another consuming function, e.g. to create a [SPPacket] /// [DllImport(__DllName, EntryPoint = "sp_command_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_command_free(Command* command); + private static extern void sp_command_free(SPCommand* command); } [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Command + public unsafe partial struct SPCommand { } diff --git a/crates/servicepoint_binding_cs/ServicePoint/Connection.cs b/crates/servicepoint_binding_cs/ServicePoint/Connection.cs index 120ae6f..46527a9 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/Connection.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Connection.cs @@ -1,40 +1,21 @@ using System.Text; -using ServicePoint.BindGen; namespace ServicePoint; -public sealed class Connection : SpNativeInstance +public sealed partial class Connection { - public static Connection Open(string host) + public static Connection? Open(string host) { unsafe { fixed (byte* bytePtr = Encoding.UTF8.GetBytes(host)) { - return new Connection(ConnectionNative.sp_connection_open(bytePtr)); + return Open(bytePtr); } } } - public bool Send(Packet packet) - { - unsafe - { - return Instance->SendPacket(packet.Into()); - } - } + public bool Send(Packet packet) => SendPacket(packet); - public bool Send(Command command) - { - unsafe - { - return Instance->SendCommand(command.Into()); - } - } - - private protected override unsafe void Free() => Instance->Free(); - - private unsafe Connection(BindGen.Connection* instance) : base(instance) - { - } + public bool Send(Command command) => SendCommand(command); } diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ConnectionNative.g.cs b/crates/servicepoint_binding_cs/ServicePoint/Connection.g.cs similarity index 63% rename from crates/servicepoint_binding_cs/ServicePoint/BindGen/ConnectionNative.g.cs rename to crates/servicepoint_binding_cs/ServicePoint/Connection.g.cs index 4ce780b..07bccc0 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ConnectionNative.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Connection.g.cs @@ -8,14 +8,69 @@ using System; using System.Runtime.InteropServices; -namespace ServicePoint.BindGen +namespace ServicePoint { - public static unsafe partial class ConnectionNative + + public unsafe sealed partial class Connection: IDisposable { +#nullable enable + public static Connection? Open(byte* host) + { + var native = Connection.sp_connection_open(host); + return native == null ? null : new Connection(native); + } + + public bool SendPacket(Packet packet) + { + return Connection.sp_connection_send_packet(Instance, packet.Instance); + } + + public bool SendCommand(Command command) + { + return Connection.sp_connection_send_command(Instance, command.Instance); + } + + + private SPConnection* _instance; + internal SPConnection* Instance + { + get + { + if (_instance == null) + throw new NullReferenceException("instance is null"); + return _instance; + } + } + + private Connection(SPConnection* instance) + { + ArgumentNullException.ThrowIfNull(instance); + _instance = instance; + } + + internal SPConnection* Into() + { + var instance = Instance; + _instance = null; + return instance; + } + + private void Free() + { + if (_instance != null) + Connection.sp_connection_free(Into()); + } + + public void Dispose() + { + Free(); + GC.SuppressFinalize(this); + } + + ~Connection() => Free(); + const string __DllName = "servicepoint_binding_c"; - - - +#nullable restore /// /// Creates a new instance of [SPConnection]. /// @@ -33,7 +88,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_connection_free`. /// [DllImport(__DllName, EntryPoint = "sp_connection_open", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Connection* sp_connection_open(byte* host); + private static extern SPConnection* sp_connection_open(byte* host); /// /// Sends a [SPPacket] to the display using the [SPConnection]. @@ -57,7 +112,7 @@ namespace ServicePoint.BindGen /// [DllImport(__DllName, EntryPoint = "sp_connection_send_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_connection_send_packet(Connection* connection, Packet* packet); + private static extern bool sp_connection_send_packet(SPConnection* connection, SPPacket* packet); /// /// Sends a [SPCommand] to the display using the [SPConnection]. @@ -81,7 +136,7 @@ namespace ServicePoint.BindGen /// [DllImport(__DllName, EntryPoint = "sp_connection_send_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool sp_connection_send_command(Connection* connection, Command* command); + private static extern bool sp_connection_send_command(SPConnection* connection, SPCommand* command); /// /// Closes and deallocates a [SPConnection]. @@ -98,13 +153,13 @@ namespace ServicePoint.BindGen /// - `connection` is not used concurrently or after this call /// [DllImport(__DllName, EntryPoint = "sp_connection_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_connection_free(Connection* connection); + private static extern void sp_connection_free(SPConnection* connection); } [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Connection + public unsafe partial struct SPConnection { } diff --git a/crates/servicepoint_binding_cs/ServicePoint/Constants.cs b/crates/servicepoint_binding_cs/ServicePoint/Constants.cs index b0f0f06..dd94fe5 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/Constants.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Constants.cs @@ -1,5 +1,3 @@ -using ServicePoint.BindGen; - namespace ServicePoint; public static class Constants diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ConstantsNative.g.cs b/crates/servicepoint_binding_cs/ServicePoint/Constants.g.cs similarity index 95% rename from crates/servicepoint_binding_cs/ServicePoint/BindGen/ConstantsNative.g.cs rename to crates/servicepoint_binding_cs/ServicePoint/Constants.g.cs index da06983..ffc30d4 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/ConstantsNative.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Constants.g.cs @@ -8,7 +8,7 @@ using System; using System.Runtime.InteropServices; -namespace ServicePoint.BindGen +namespace ServicePoint { public static unsafe partial class ConstantsNative { @@ -23,6 +23,7 @@ namespace ServicePoint.BindGen } + public enum CompressionCode : ushort { Uncompressed = 0, diff --git a/crates/servicepoint_binding_cs/ServicePoint/Cp437Grid.cs b/crates/servicepoint_binding_cs/ServicePoint/Cp437Grid.cs index 6b45147..a3c6ba7 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/Cp437Grid.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Cp437Grid.cs @@ -1,61 +1,20 @@ using System.Text; -using ServicePoint.BindGen; namespace ServicePoint; -public sealed class Cp437Grid : SpNativeInstance +public sealed partial class Cp437Grid { - public static Cp437Grid New(nuint width, nuint height) - { - unsafe - { - return new Cp437Grid(Cp437GridNative.sp_cp437_grid_new(width, height)); - } - } - - public static Cp437Grid Load(nuint width, nuint height, Span bytes) - { - unsafe - { - fixed (byte* bytesPtr = bytes) - { - return new Cp437Grid(Cp437GridNative.sp_cp437_grid_load(width, height, bytesPtr, - (nuint)bytes.Length)); - } - } - } - - public Cp437Grid Clone() - { - unsafe - { - return new Cp437Grid(Instance->Clone()); - } - } - public byte this[nuint x, nuint y] { - get - { - unsafe - { - return Instance->Get(x, y); - } - } - set - { - unsafe - { - Instance->Set(x, y, value); - } - } + get => Get(x, y); + set => Set(x, y, value); } public string this[nuint y] { set { - var width = Width; + var width = Width(); ArgumentOutOfRangeException.ThrowIfGreaterThan((nuint)value.Length, width); nuint x = 0; @@ -69,7 +28,8 @@ public sealed class Cp437Grid : SpNativeInstance get { var sb = new StringBuilder(); - for (nuint x = 0; x < Width; x++) + var width = Width(); + for (nuint x = 0; x < width; x++) { var val = this[x, y]; if (val == 0) @@ -81,50 +41,5 @@ public sealed class Cp437Grid : SpNativeInstance } } - public void Fill(byte value) - { - unsafe - { - Instance->Fill(value); - } - } - - public nuint Width - { - get - { - unsafe - { - return Instance->Width(); - } - } - } - - public nuint Height - { - get - { - unsafe - { - return Instance->Height(); - } - } - } - - public Span Data - { - get - { - unsafe - { - return Instance->UnsafeDataRef().AsSpan(); - } - } - } - - private unsafe Cp437Grid(BindGen.Cp437Grid* instance) : base(instance) - { - } - - private protected override unsafe void Free() => Instance->Free(); + public Span Data => UnsafeDataRef().AsSpan(); } diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/Cp437GridNative.g.cs b/crates/servicepoint_binding_cs/ServicePoint/Cp437Grid.g.cs similarity index 70% rename from crates/servicepoint_binding_cs/ServicePoint/BindGen/Cp437GridNative.g.cs rename to crates/servicepoint_binding_cs/ServicePoint/Cp437Grid.g.cs index 41f3aee..13e1fa6 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/Cp437GridNative.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Cp437Grid.g.cs @@ -8,14 +8,95 @@ using System; using System.Runtime.InteropServices; -namespace ServicePoint.BindGen +namespace ServicePoint { - public static unsafe partial class Cp437GridNative + + public unsafe sealed partial class Cp437Grid: IDisposable { +#nullable enable + public Cp437Grid(nuint width, nuint height) : this(sp_cp437_grid_new(width, height)) {} + + public static Cp437Grid Load(nuint width, nuint height, byte* data, nuint data_length) + { + return new Cp437Grid(Cp437Grid.sp_cp437_grid_load(width, height, data, data_length)); + } + + public Cp437Grid Clone() + { + return new Cp437Grid(Cp437Grid.sp_cp437_grid_clone(Instance)); + } + + public byte Get(nuint x, nuint y) + { + return Cp437Grid.sp_cp437_grid_get(Instance, x, y); + } + + public void Set(nuint x, nuint y, byte value) + { + Cp437Grid.sp_cp437_grid_set(Instance, x, y, value); + } + + public void Fill(byte value) + { + Cp437Grid.sp_cp437_grid_fill(Instance, value); + } + + public nuint Width() + { + return Cp437Grid.sp_cp437_grid_width(Instance); + } + + public nuint Height() + { + return Cp437Grid.sp_cp437_grid_height(Instance); + } + + public SPByteSlice UnsafeDataRef() + { + return Cp437Grid.sp_cp437_grid_unsafe_data_ref(Instance); + } + + + private SPCp437Grid* _instance; + internal SPCp437Grid* Instance + { + get + { + if (_instance == null) + throw new NullReferenceException("instance is null"); + return _instance; + } + } + + private Cp437Grid(SPCp437Grid* instance) + { + ArgumentNullException.ThrowIfNull(instance); + _instance = instance; + } + + internal SPCp437Grid* Into() + { + var instance = Instance; + _instance = null; + return instance; + } + + private void Free() + { + if (_instance != null) + Cp437Grid.sp_cp437_grid_free(Into()); + } + + public void Dispose() + { + Free(); + GC.SuppressFinalize(this); + } + + ~Cp437Grid() => Free(); + const string __DllName = "servicepoint_binding_c"; - - - +#nullable restore /// /// Creates a new [SPCp437Grid] with the specified dimensions. /// @@ -29,7 +110,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_cp437_grid_free`. /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Cp437Grid* sp_cp437_grid_new(nuint width, nuint height); + private static extern SPCp437Grid* sp_cp437_grid_new(nuint width, nuint height); /// /// Loads a [SPCp437Grid] with the specified dimensions from the provided data. @@ -51,7 +132,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_cp437_grid_free`. /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Cp437Grid* sp_cp437_grid_load(nuint width, nuint height, byte* data, nuint data_length); + private static extern SPCp437Grid* sp_cp437_grid_load(nuint width, nuint height, byte* data, nuint data_length); /// /// Clones a [SPCp437Grid]. @@ -72,7 +153,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_cp437_grid_free`. /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Cp437Grid* sp_cp437_grid_clone(Cp437Grid* cp437_grid); + private static extern SPCp437Grid* sp_cp437_grid_clone(SPCp437Grid* cp437_grid); /// /// Deallocates a [SPCp437Grid]. @@ -90,7 +171,7 @@ namespace ServicePoint.BindGen /// - `cp437_grid` was not passed to another consuming function, e.g. to create a [SPCommand] /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_cp437_grid_free(Cp437Grid* cp437_grid); + private static extern void sp_cp437_grid_free(SPCp437Grid* cp437_grid); /// /// Gets the current value at the specified position. @@ -113,7 +194,7 @@ namespace ServicePoint.BindGen /// - `cp437_grid` is not written to concurrently /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern byte sp_cp437_grid_get(Cp437Grid* cp437_grid, nuint x, nuint y); + private static extern byte sp_cp437_grid_get(SPCp437Grid* cp437_grid, nuint x, nuint y); /// /// Sets the value of the specified position in the [SPCp437Grid]. @@ -139,7 +220,7 @@ namespace ServicePoint.BindGen /// - `cp437_grid` is not written to or read from concurrently /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_cp437_grid_set(Cp437Grid* cp437_grid, nuint x, nuint y, byte value); + private static extern void sp_cp437_grid_set(SPCp437Grid* cp437_grid, nuint x, nuint y, byte value); /// /// Sets the value of all cells in the [SPCp437Grid]. @@ -161,7 +242,7 @@ namespace ServicePoint.BindGen /// - `cp437_grid` is not written to or read from concurrently /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_cp437_grid_fill(Cp437Grid* cp437_grid, byte value); + private static extern void sp_cp437_grid_fill(SPCp437Grid* cp437_grid, byte value); /// /// Gets the width of the [SPCp437Grid] instance. @@ -181,7 +262,7 @@ namespace ServicePoint.BindGen /// - `cp437_grid` points to a valid [SPCp437Grid] /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_cp437_grid_width(Cp437Grid* cp437_grid); + private static extern nuint sp_cp437_grid_width(SPCp437Grid* cp437_grid); /// /// Gets the height of the [SPCp437Grid] instance. @@ -201,7 +282,7 @@ namespace ServicePoint.BindGen /// - `cp437_grid` points to a valid [SPCp437Grid] /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern nuint sp_cp437_grid_height(Cp437Grid* cp437_grid); + private static extern nuint sp_cp437_grid_height(SPCp437Grid* cp437_grid); /// /// Gets an unsafe reference to the data of the [SPCp437Grid] instance. @@ -221,13 +302,13 @@ namespace ServicePoint.BindGen /// - the returned memory range is never accessed concurrently, either via the [SPCp437Grid] or directly /// [DllImport(__DllName, EntryPoint = "sp_cp437_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern ByteSlice sp_cp437_grid_unsafe_data_ref(Cp437Grid* cp437_grid); + private static extern SPByteSlice sp_cp437_grid_unsafe_data_ref(SPCp437Grid* cp437_grid); } [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Cp437Grid + public unsafe partial struct SPCp437Grid { } diff --git a/crates/servicepoint_binding_cs/ServicePoint/Packet.cs b/crates/servicepoint_binding_cs/ServicePoint/Packet.cs index 1eb0a41..aff3c1f 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/Packet.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Packet.cs @@ -1,36 +1,18 @@ using System.Diagnostics.CodeAnalysis; -using ServicePoint.BindGen; namespace ServicePoint; -public sealed class Packet : SpNativeInstance +public sealed partial class Packet { - public static Packet FromCommand(Command command) - { - unsafe - { - return new Packet(PacketNative.sp_packet_from_command(command.Into())); - } - } - public static bool TryFromBytes(Span bytes, [MaybeNullWhen(false)] out Packet packet) { unsafe { fixed (byte* bytesPtr = bytes) { - var instance = PacketNative.sp_packet_try_load(bytesPtr, (nuint)bytes.Length); - packet = instance == null - ? null - : new Packet(instance); + packet = TryLoad(bytesPtr, (nuint)bytes.Length); return packet != null; } } } - - private unsafe Packet(BindGen.Packet* instance) : base(instance) - { - } - - private protected override unsafe void Free() => Instance->Free(); } diff --git a/crates/servicepoint_binding_cs/ServicePoint/BindGen/PacketNative.g.cs b/crates/servicepoint_binding_cs/ServicePoint/Packet.g.cs similarity index 64% rename from crates/servicepoint_binding_cs/ServicePoint/BindGen/PacketNative.g.cs rename to crates/servicepoint_binding_cs/ServicePoint/Packet.g.cs index e805c6a..ceaa982 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/BindGen/PacketNative.g.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/Packet.g.cs @@ -8,14 +8,69 @@ using System; using System.Runtime.InteropServices; -namespace ServicePoint.BindGen +namespace ServicePoint { - public static unsafe partial class PacketNative + + public unsafe sealed partial class Packet: IDisposable { +#nullable enable + public static Packet FromCommand(Command command) + { + return new Packet(Packet.sp_packet_from_command(command.Instance)); + } + + public static Packet? TryLoad(byte* data, nuint length) + { + var native = Packet.sp_packet_try_load(data, length); + return native == null ? null : new Packet(native); + } + + public Packet Clone() + { + return new Packet(Packet.sp_packet_clone(Instance)); + } + + + private SPPacket* _instance; + internal SPPacket* Instance + { + get + { + if (_instance == null) + throw new NullReferenceException("instance is null"); + return _instance; + } + } + + private Packet(SPPacket* instance) + { + ArgumentNullException.ThrowIfNull(instance); + _instance = instance; + } + + internal SPPacket* Into() + { + var instance = Instance; + _instance = null; + return instance; + } + + private void Free() + { + if (_instance != null) + Packet.sp_packet_free(Into()); + } + + public void Dispose() + { + Free(); + GC.SuppressFinalize(this); + } + + ~Packet() => Free(); + const string __DllName = "servicepoint_binding_c"; - - - +#nullable restore /// /// Turns a [SPCommand] into a [SPPacket]. /// The [SPCommand] gets consumed. @@ -36,7 +91,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_packet_free`. /// [DllImport(__DllName, EntryPoint = "sp_packet_from_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Packet* sp_packet_from_command(Command* command); + private static extern SPPacket* sp_packet_from_command(SPCommand* command); /// /// Tries to load a [SPPacket] from the passed array with the specified length. @@ -57,7 +112,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_packet_free`. /// [DllImport(__DllName, EntryPoint = "sp_packet_try_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Packet* sp_packet_try_load(byte* data, nuint length); + private static extern SPPacket* sp_packet_try_load(byte* data, nuint length); /// /// Clones a [SPPacket]. @@ -78,7 +133,7 @@ namespace ServicePoint.BindGen /// by explicitly calling `sp_packet_free`. /// [DllImport(__DllName, EntryPoint = "sp_packet_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern Packet* sp_packet_clone(Packet* packet); + private static extern SPPacket* sp_packet_clone(SPPacket* packet); /// /// Deallocates a [SPPacket]. @@ -95,13 +150,13 @@ namespace ServicePoint.BindGen /// - `packet` is not used concurrently or after this call /// [DllImport(__DllName, EntryPoint = "sp_packet_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void sp_packet_free(Packet* packet); + private static extern void sp_packet_free(SPPacket* packet); } [StructLayout(LayoutKind.Sequential)] - public unsafe partial struct Packet + public unsafe partial struct SPPacket { } diff --git a/crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj b/crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj index 1e5fecd..854e5a6 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj +++ b/crates/servicepoint_binding_cs/ServicePoint/ServicePoint.csproj @@ -52,11 +52,6 @@ - - - - - diff --git a/crates/servicepoint_binding_cs/ServicePoint/ServicePointExtensions.cs b/crates/servicepoint_binding_cs/ServicePoint/ServicePointExtensions.cs index 07ce28a..9bb8b58 100644 --- a/crates/servicepoint_binding_cs/ServicePoint/ServicePointExtensions.cs +++ b/crates/servicepoint_binding_cs/ServicePoint/ServicePointExtensions.cs @@ -1,5 +1,4 @@ using System.Diagnostics.CodeAnalysis; -using ServicePoint.BindGen; namespace ServicePoint; @@ -15,7 +14,7 @@ public static class ServicePointExtensions return Command.TryFromPacket(packet, out command); } - public unsafe static Span AsSpan(this ByteSlice slice) + public unsafe static Span AsSpan(this SPByteSlice slice) { return new Span(slice.start, (int)slice.length); } diff --git a/crates/servicepoint_binding_cs/ServicePoint/SpNativeInstance.cs b/crates/servicepoint_binding_cs/ServicePoint/SpNativeInstance.cs deleted file mode 100644 index b6c492e..0000000 --- a/crates/servicepoint_binding_cs/ServicePoint/SpNativeInstance.cs +++ /dev/null @@ -1,51 +0,0 @@ -namespace ServicePoint; - -public abstract class SpNativeInstance - : IDisposable - where T : unmanaged -{ - private unsafe T* _instance; - - internal unsafe T* Instance - { - get - { - if (_instance == null) - throw new NullReferenceException("instance is null"); - return _instance; - } - } - - private protected unsafe SpNativeInstance(T* instance) - { - ArgumentNullException.ThrowIfNull(instance); - _instance = instance; - } - - private protected abstract void Free(); - - internal unsafe T* Into() - { - var instance = _instance; - _instance = null; - return instance; - } - - private unsafe void ReleaseUnmanagedResources() - { - if (_instance != null) - Free(); - _instance = null; - } - - public void Dispose() - { - ReleaseUnmanagedResources(); - GC.SuppressFinalize(this); - } - - ~SpNativeInstance() - { - ReleaseUnmanagedResources(); - } -} diff --git a/crates/servicepoint_binding_cs/build.rs b/crates/servicepoint_binding_cs/build.rs index bd49a78..edb2fbc 100644 --- a/crates/servicepoint_binding_cs/build.rs +++ b/crates/servicepoint_binding_cs/build.rs @@ -17,32 +17,44 @@ fn main() { for path in &paths { println!("cargo:rerun-if-changed={}", path.display()); let file: &str = Path::new(path).file_stem().unwrap().to_str().unwrap(); - if file == "lib"{ + if file == "lib" { continue; } - let class = file.to_case(Case::UpperCamel) + "Native"; + let class = file.to_case(Case::UpperCamel); csbindgen::Builder::default() .input_extern_file(path) - .csharp_class_name(&class) + .csharp_class_name(format!("{class}Native")) .csharp_dll_name("servicepoint_binding_c") - .csharp_namespace("ServicePoint.BindGen") + .csharp_namespace("ServicePoint") .csharp_use_nint_types(true) .csharp_class_accessibility("public") .csharp_generate_const_filter(|_| true) .always_included_types(["SPByteSlice", "SPCompressionCode"]) + .csharp_group_methods("sp_bitmap_", "Bitmap", "SPBitmap") + .csharp_group_methods("sp_bitvec_", "BitVec", "SPBitVec") + .csharp_group_methods("sp_command_", "Command", "SPCommand") + .csharp_group_methods( + "sp_connection_", + "Connection", + "SPConnection", + ) + .csharp_group_methods("sp_cp437_grid_", "Cp437Grid", "SPCp437Grid") + .csharp_group_methods("sp_packet_", "Packet", "SPPacket") + .csharp_group_methods( + "sp_brightness_grid_", + "BrightnessGrid", + "SPBrightnessGrid", + ) .csharp_type_rename(move |name| { - if name.len() > 2 - && name.starts_with("SP") - && name.chars().nth(2).unwrap().is_uppercase() + if name == "SPCompressionCode" { - name[2..].to_string() + "CompressionCode".to_string() } else { name } }) - .generate_csharp_file(format!("ServicePoint/BindGen/{}.g.cs", &class)) + .generate_csharp_file(format!("ServicePoint/{class}.g.cs")) .unwrap(); } - } diff --git a/crates/servicepoint_binding_cs/examples/lang_cs/Program.cs b/crates/servicepoint_binding_cs/examples/lang_cs/Program.cs index a1ff7fe..234ede8 100644 --- a/crates/servicepoint_binding_cs/examples/lang_cs/Program.cs +++ b/crates/servicepoint_binding_cs/examples/lang_cs/Program.cs @@ -1,20 +1,24 @@ using ServicePoint; -using CompressionCode = ServicePoint.BindGen.CompressionCode; using var connection = Connection.Open("127.0.0.1:2342"); +if (connection == null) +{ + Console.Error.WriteLine("could not connect"); + return; +} connection.Send(Command.Clear().IntoPacket()); connection.Send(Command.Brightness(128).IntoPacket()); -using var pixels = Bitmap.New(Constants.PixelWidth, Constants.PixelHeight); +using var pixels = new Bitmap(Constants.PixelWidth, Constants.PixelHeight); for (nuint offset = 0; offset < nuint.MaxValue; offset++) { pixels.Fill(false); - for (nuint y = 0; y < pixels.Height; y++) + for (nuint y = 0; y < pixels.Height(); y++) pixels[(y + offset) % Constants.PixelWidth, y] = true; - connection.Send(Command.BitmapLinearWin(0, 0, pixels.Clone(), CompressionCode.Lzma).IntoPacket()); + connection.Send(Command.BitmapLinearWin(0, 0, pixels.Clone(), CompressionCode.Lzma)); Thread.Sleep(14); } diff --git a/crates/servicepoint_csbindgen b/crates/servicepoint_csbindgen new file mode 160000 index 0000000..2dcf44a --- /dev/null +++ b/crates/servicepoint_csbindgen @@ -0,0 +1 @@ +Subproject commit 2dcf44a5c398925249cf96e9bbf724dd551e5b76