generate most of the c# binding with a fork of csbindgen

This commit is contained in:
Vinzenz Schroeter 2024-10-19 14:21:50 +02:00
parent 91cc982394
commit 67969d5b43
34 changed files with 791 additions and 819 deletions

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "crates/servicepoint_csbindgen"]
path = crates/servicepoint_csbindgen
url = https://github.com/kaesaecracker/servicepoint_csbindgen.git

19
Cargo.lock generated
View file

@ -208,6 +208,15 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" 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]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.14" version = "0.2.14"
@ -239,9 +248,8 @@ dependencies = [
[[package]] [[package]]
name = "csbindgen" name = "csbindgen"
version = "1.9.3" version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c26b9831049b947d154bba920e4124053def72447be6fb106a96f483874b482a"
dependencies = [ dependencies = [
"convert_case",
"regex", "regex",
"syn", "syn",
] ]
@ -636,6 +644,7 @@ dependencies = [
name = "servicepoint_binding_cs" name = "servicepoint_binding_cs"
version = "0.10.0" version = "0.10.0"
dependencies = [ dependencies = [
"convert_case",
"csbindgen", "csbindgen",
"servicepoint", "servicepoint",
"servicepoint_binding_c", "servicepoint_binding_c",
@ -778,6 +787,12 @@ version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "unicode-segmentation"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
[[package]] [[package]]
name = "utf-8" name = "utf-8"
version = "0.7.6" version = "0.7.6"

View file

@ -1,8 +1,11 @@
[workspace] [workspace]
resolver = "2" resolver = "2"
members = [ members = [
"crates/*", "crates/servicepoint",
"crates/servicepoint_binding_c/examples/lang_c" "crates/servicepoint_binding_c",
"crates/servicepoint_binding_c/examples/lang_c",
"crates/servicepoint_binding_cs",
"crates/servicepoint_csbindgen/csbindgen"
] ]
[workspace.package] [workspace.package]

View file

@ -31,11 +31,8 @@ fn main() {
let mut filled_grid = Bitmap::max_sized(); let mut filled_grid = Bitmap::max_sized();
filled_grid.fill(true); filled_grid.fill(true);
let command = BitmapLinearWin( let command =
Origin::ZERO, BitmapLinearWin(Origin::ZERO, filled_grid, CompressionCode::Lzma);
filled_grid,
CompressionCode::Lzma,
);
connection.send(command).expect("send failed"); connection.send(command).expect("send failed");
} }

View file

@ -2,9 +2,9 @@
//! //!
//! prefix `sp_bitvec_` //! prefix `sp_bitvec_`
use std::ptr::NonNull;
use crate::SPByteSlice; use crate::SPByteSlice;
use servicepoint::bitvec::prelude::{BitVec, Msb0}; use servicepoint::bitvec::prelude::{BitVec, Msb0};
use std::ptr::NonNull;
/// A vector of bits /// A vector of bits
/// ///

View file

@ -2,8 +2,8 @@
//! //!
//! prefix `sp_bitmap_` //! prefix `sp_bitmap_`
use std::ptr::NonNull;
use servicepoint::{DataRef, Grid}; use servicepoint::{DataRef, Grid};
use std::ptr::NonNull;
use crate::byte_slice::SPByteSlice; use crate::byte_slice::SPByteSlice;
@ -43,9 +43,7 @@ pub unsafe extern "C" fn sp_bitmap_new(
width: usize, width: usize,
height: usize, height: usize,
) -> NonNull<SPBitmap> { ) -> NonNull<SPBitmap> {
let result = Box::new(SPBitmap(servicepoint::Bitmap::new( let result = Box::new(SPBitmap(servicepoint::Bitmap::new(width, height)));
width, height,
)));
NonNull::from(Box::leak(result)) NonNull::from(Box::leak(result))
} }
@ -80,9 +78,8 @@ pub unsafe extern "C" fn sp_bitmap_load(
) -> NonNull<SPBitmap> { ) -> NonNull<SPBitmap> {
assert!(!data.is_null()); assert!(!data.is_null());
let data = std::slice::from_raw_parts(data, data_length); let data = std::slice::from_raw_parts(data, data_length);
let result = Box::new(SPBitmap(servicepoint::Bitmap::load( let result =
width, height, data, Box::new(SPBitmap(servicepoint::Bitmap::load(width, height, data)));
)));
NonNull::from(Box::leak(result)) NonNull::from(Box::leak(result))
} }

View file

@ -48,9 +48,9 @@ pub unsafe extern "C" fn sp_brightness_grid_new(
width: usize, width: usize,
height: usize, height: usize,
) -> NonNull<SPBrightnessGrid> { ) -> NonNull<SPBrightnessGrid> {
let result = Box::new(SPBrightnessGrid( let result = Box::new(SPBrightnessGrid(servicepoint::BrightnessGrid::new(
servicepoint::BrightnessGrid::new(width, height), width, height,
)); )));
NonNull::from(Box::leak(result)) NonNull::from(Box::leak(result))
} }

View file

@ -164,9 +164,8 @@ pub unsafe extern "C" fn sp_command_brightness(
) -> NonNull<SPCommand> { ) -> NonNull<SPCommand> {
let brightness = let brightness =
Brightness::try_from(brightness).expect("invalid brightness"); Brightness::try_from(brightness).expect("invalid brightness");
let result = Box::new(SPCommand( let result =
servicepoint::Command::Brightness(brightness), Box::new(SPCommand(servicepoint::Command::Brightness(brightness)));
));
NonNull::from(Box::leak(result)) NonNull::from(Box::leak(result))
} }
@ -196,9 +195,10 @@ pub unsafe extern "C" fn sp_command_char_brightness(
) -> NonNull<SPCommand> { ) -> NonNull<SPCommand> {
assert!(!grid.is_null()); assert!(!grid.is_null());
let byte_grid = *Box::from_raw(grid); let byte_grid = *Box::from_raw(grid);
let result = Box::new(SPCommand( let result = Box::new(SPCommand(servicepoint::Command::CharBrightness(
servicepoint::Command::CharBrightness(Origin::new(x, y), byte_grid.0), Origin::new(x, y),
)); byte_grid.0,
)));
NonNull::from(Box::leak(result)) NonNull::from(Box::leak(result))
} }
@ -235,13 +235,11 @@ pub unsafe extern "C" fn sp_command_bitmap_linear(
) -> NonNull<SPCommand> { ) -> NonNull<SPCommand> {
assert!(!bit_vec.is_null()); assert!(!bit_vec.is_null());
let bit_vec = *Box::from_raw(bit_vec); let bit_vec = *Box::from_raw(bit_vec);
let result = Box::new(SPCommand( let result = Box::new(SPCommand(servicepoint::Command::BitmapLinear(
servicepoint::Command::BitmapLinear( offset,
offset, bit_vec.into(),
bit_vec.into(), compression.try_into().expect("invalid compression code"),
compression.try_into().expect("invalid compression code"), )));
),
));
NonNull::from(Box::leak(result)) NonNull::from(Box::leak(result))
} }
@ -278,13 +276,11 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_and(
) -> NonNull<SPCommand> { ) -> NonNull<SPCommand> {
assert!(!bit_vec.is_null()); assert!(!bit_vec.is_null());
let bit_vec = *Box::from_raw(bit_vec); let bit_vec = *Box::from_raw(bit_vec);
let result = Box::new(SPCommand( let result = Box::new(SPCommand(servicepoint::Command::BitmapLinearAnd(
servicepoint::Command::BitmapLinearAnd( offset,
offset, bit_vec.into(),
bit_vec.into(), compression.try_into().expect("invalid compression code"),
compression.try_into().expect("invalid compression code"), )));
),
));
NonNull::from(Box::leak(result)) NonNull::from(Box::leak(result))
} }
@ -321,13 +317,11 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_or(
) -> NonNull<SPCommand> { ) -> NonNull<SPCommand> {
assert!(!bit_vec.is_null()); assert!(!bit_vec.is_null());
let bit_vec = *Box::from_raw(bit_vec); let bit_vec = *Box::from_raw(bit_vec);
let result = Box::new(SPCommand( let result = Box::new(SPCommand(servicepoint::Command::BitmapLinearOr(
servicepoint::Command::BitmapLinearOr( offset,
offset, bit_vec.into(),
bit_vec.into(), compression.try_into().expect("invalid compression code"),
compression.try_into().expect("invalid compression code"), )));
),
));
NonNull::from(Box::leak(result)) NonNull::from(Box::leak(result))
} }
@ -364,13 +358,11 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_xor(
) -> NonNull<SPCommand> { ) -> NonNull<SPCommand> {
assert!(!bit_vec.is_null()); assert!(!bit_vec.is_null());
let bit_vec = *Box::from_raw(bit_vec); let bit_vec = *Box::from_raw(bit_vec);
let result = Box::new(SPCommand( let result = Box::new(SPCommand(servicepoint::Command::BitmapLinearXor(
servicepoint::Command::BitmapLinearXor( offset,
offset, bit_vec.into(),
bit_vec.into(), compression.try_into().expect("invalid compression code"),
compression.try_into().expect("invalid compression code"), )));
),
));
NonNull::from(Box::leak(result)) NonNull::from(Box::leak(result))
} }
@ -400,9 +392,10 @@ pub unsafe extern "C" fn sp_command_cp437_data(
) -> NonNull<SPCommand> { ) -> NonNull<SPCommand> {
assert!(!grid.is_null()); assert!(!grid.is_null());
let grid = *Box::from_raw(grid); let grid = *Box::from_raw(grid);
let result = Box::new(SPCommand( let result = Box::new(SPCommand(servicepoint::Command::Cp437Data(
servicepoint::Command::Cp437Data(Origin::new(x, y), grid.0), Origin::new(x, y),
)); grid.0,
)));
NonNull::from(Box::leak(result)) NonNull::from(Box::leak(result))
} }
@ -435,15 +428,13 @@ pub unsafe extern "C" fn sp_command_bitmap_linear_win(
) -> NonNull<SPCommand> { ) -> NonNull<SPCommand> {
assert!(!bitmap.is_null()); assert!(!bitmap.is_null());
let byte_grid = (*Box::from_raw(bitmap)).0; let byte_grid = (*Box::from_raw(bitmap)).0;
let result = Box::new(SPCommand( let result = Box::new(SPCommand(servicepoint::Command::BitmapLinearWin(
servicepoint::Command::BitmapLinearWin( Origin::new(x, y),
Origin::new(x, y), byte_grid,
byte_grid, compression_code
compression_code .try_into()
.try_into() .expect("invalid compression code"),
.expect("invalid compression code"), )));
),
));
NonNull::from(Box::leak(result)) NonNull::from(Box::leak(result))
} }

View file

@ -2,9 +2,9 @@
//! //!
//! prefix `sp_cp437_grid_` //! prefix `sp_cp437_grid_`
use std::ptr::NonNull;
use crate::SPByteSlice; use crate::SPByteSlice;
use servicepoint::{DataRef, Grid}; use servicepoint::{DataRef, Grid};
use std::ptr::NonNull;
/// A C-wrapper for grid containing codepage 437 characters. /// A C-wrapper for grid containing codepage 437 characters.
/// ///
@ -41,9 +41,8 @@ pub unsafe extern "C" fn sp_cp437_grid_new(
width: usize, width: usize,
height: usize, height: usize,
) -> NonNull<SPCp437Grid> { ) -> NonNull<SPCp437Grid> {
let result = Box::new(SPCp437Grid( let result =
servicepoint::Cp437Grid::new(width, height), Box::new(SPCp437Grid(servicepoint::Cp437Grid::new(width, height)));
));
NonNull::from(Box::leak(result)) NonNull::from(Box::leak(result))
} }
@ -73,9 +72,9 @@ pub unsafe extern "C" fn sp_cp437_grid_load(
) -> NonNull<SPCp437Grid> { ) -> NonNull<SPCp437Grid> {
assert!(data.is_null()); assert!(data.is_null());
let data = std::slice::from_raw_parts(data, data_length); let data = std::slice::from_raw_parts(data, data_length);
let result = Box::new(SPCp437Grid( let result = Box::new(SPCp437Grid(servicepoint::Cp437Grid::load(
servicepoint::Cp437Grid::load(width, height, data), width, height, data,
)); )));
NonNull::from(Box::leak(result)) NonNull::from(Box::leak(result))
} }

View file

@ -10,7 +10,7 @@ crate-type = ["cdylib"]
test = false test = false
[build-dependencies] [build-dependencies]
csbindgen = "1.9.3" csbindgen = { path = "../servicepoint_csbindgen/csbindgen" }
convert_case = "0.6.0" convert_case = "0.6.0"
[dependencies] [dependencies]

View file

@ -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
{
}

View file

@ -1,87 +1,12 @@
using ServicePoint.BindGen;
namespace ServicePoint; namespace ServicePoint;
public sealed class BitVec : SpNativeInstance<BindGen.BitVec> 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<byte> 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] public bool this[nuint index]
{ {
get get => Get(index);
{ set => Set(index, value);
unsafe
{
return Instance->Get(index);
}
}
set
{
unsafe
{
Instance->Set(index, value);
}
}
} }
public void Fill(bool value) public Span<byte> Data => UnsafeDataRef().AsSpan();
{
unsafe
{
Instance->Fill(value);
}
}
public nuint Length
{
get
{
unsafe
{
return Instance->Len();
}
}
}
public Span<byte> Data
{
get
{
unsafe
{
return Instance->UnsafeDataRef().AsSpan();
}
}
}
private unsafe BitVec(BindGen.BitVec* instance) : base(instance)
{
}
private protected override unsafe void Free() => Instance->Free();
} }

View file

@ -8,14 +8,95 @@ using System;
using System.Runtime.InteropServices; 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"; const string __DllName = "servicepoint_binding_c";
#nullable restore
/// <summary> /// <summary>
/// Creates a new [SPBitVec] instance. /// Creates a new [SPBitVec] instance.
/// ///
@ -37,7 +118,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_bitvec_free`. /// by explicitly calling `sp_bitvec_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitvec_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Interpret the data as a series of bits and load then into a new [SPBitVec] instance. /// 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`. /// by explicitly calling `sp_bitvec_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitvec_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Clones a [SPBitVec]. /// Clones a [SPBitVec].
@ -79,7 +160,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_bitvec_free`. /// by explicitly calling `sp_bitvec_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitvec_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Deallocates a [SPBitVec]. /// 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] /// - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand]
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitvec_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Gets the value of a bit from the [SPBitVec]. /// Gets the value of a bit from the [SPBitVec].
@ -123,7 +204,7 @@ namespace ServicePoint.BindGen
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitvec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_bitvec_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [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);
/// <summary> /// <summary>
/// Sets the value of a bit in the [SPBitVec]. /// 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 /// - `bit_vec` is not written to or read from concurrently
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitvec_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Sets the value of all bits in the [SPBitVec]. /// 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 /// - `bit_vec` is not written to or read from concurrently
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitvec_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Gets the length of the [SPBitVec] in bits. /// Gets the length of the [SPBitVec] in bits.
@ -189,7 +270,7 @@ namespace ServicePoint.BindGen
/// - `bit_vec` points to a valid [SPBitVec] /// - `bit_vec` points to a valid [SPBitVec]
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitvec_len", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Returns true if length is 0. /// Returns true if length is 0.
@ -210,7 +291,7 @@ namespace ServicePoint.BindGen
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitvec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_bitvec_is_empty", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [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);
/// <summary> /// <summary>
/// Gets an unsafe reference to the data of the [SPBitVec] instance. /// 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 /// - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitvec_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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)] [StructLayout(LayoutKind.Sequential)]
public unsafe partial struct BitVec public unsafe partial struct SPBitVec
{ {
} }

View file

@ -1,100 +1,12 @@
using ServicePoint.BindGen;
namespace ServicePoint; namespace ServicePoint;
public sealed class Bitmap : SpNativeInstance<BindGen.Bitmap> 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<byte> 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] public bool this[nuint x, nuint y]
{ {
get get => Get(x, y);
{ set => Set(x, y, value);
unsafe
{
return Instance->Get(x, y);
}
}
set
{
unsafe
{
Instance->Set(x, y, value);
}
}
} }
public void Fill(bool value) public Span<byte> Data => UnsafeDataRef().AsSpan();
{
unsafe
{
Instance->Fill(value);
}
}
public nuint Width
{
get
{
unsafe
{
return Instance->Width();
}
}
}
public nuint Height
{
get
{
unsafe
{
return Instance->Height();
}
}
}
public Span<byte> Data
{
get
{
unsafe
{
var slice = Instance->UnsafeDataRef();
return new Span<byte>(slice.start, (int)slice.length);
}
}
}
private unsafe Bitmap(BindGen.Bitmap* instance) : base(instance)
{
}
private protected override unsafe void Free() => Instance->Free();
} }

View file

@ -8,14 +8,95 @@ using System;
using System.Runtime.InteropServices; 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"; const string __DllName = "servicepoint_binding_c";
#nullable restore
/// <summary> /// <summary>
/// Creates a new [SPBitmap] with the specified dimensions. /// Creates a new [SPBitmap] with the specified dimensions.
/// ///
@ -38,7 +119,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_bitmap_free`. /// by explicitly calling `sp_bitmap_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitmap_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Loads a [SPBitmap] with the specified dimensions from the provided data. /// Loads a [SPBitmap] with the specified dimensions from the provided data.
@ -65,7 +146,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_bitmap_free`. /// by explicitly calling `sp_bitmap_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitmap_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Clones a [SPBitmap]. /// Clones a [SPBitmap].
@ -86,7 +167,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_bitmap_free`. /// by explicitly calling `sp_bitmap_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitmap_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Deallocates a [SPBitmap]. /// Deallocates a [SPBitmap].
@ -104,7 +185,7 @@ namespace ServicePoint.BindGen
/// - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand] /// - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand]
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitmap_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Gets the current value at the specified position in the [SPBitmap]. /// Gets the current value at the specified position in the [SPBitmap].
@ -128,7 +209,7 @@ namespace ServicePoint.BindGen
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitmap_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_bitmap_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [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);
/// <summary> /// <summary>
/// Sets the value of the specified position in the [SPBitmap]. /// 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 /// - `bitmap` is not written to or read from concurrently
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitmap_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Sets the state of all pixels in the [SPBitmap]. /// 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 /// - `bitmap` is not written to or read from concurrently
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitmap_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Gets the width in pixels of the [SPBitmap] instance. /// Gets the width in pixels of the [SPBitmap] instance.
@ -196,7 +277,7 @@ namespace ServicePoint.BindGen
/// - `bitmap` points to a valid [SPBitmap] /// - `bitmap` points to a valid [SPBitmap]
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitmap_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Gets the height in pixels of the [SPBitmap] instance. /// Gets the height in pixels of the [SPBitmap] instance.
@ -216,7 +297,7 @@ namespace ServicePoint.BindGen
/// - `bitmap` points to a valid [SPBitmap] /// - `bitmap` points to a valid [SPBitmap]
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitmap_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Gets an unsafe reference to the data of the [SPBitmap] instance. /// 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 /// - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_bitmap_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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)] [StructLayout(LayoutKind.Sequential)]
public unsafe partial struct Bitmap public unsafe partial struct SPBitmap
{ {
} }

View file

@ -1,99 +1,12 @@
using ServicePoint.BindGen;
namespace ServicePoint; namespace ServicePoint;
public sealed class BrightnessGrid : SpNativeInstance<BindGen.BrightnessGrid> 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<byte> 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] public byte this[nuint x, nuint y]
{ {
get get => Get(x, y);
{ set => Set(x, y, value);
unsafe
{
return Instance->Get(x, y);
}
}
set
{
unsafe
{
Instance->Set(x, y, value);
}
}
} }
public void Fill(byte value) public Span<byte> Data => UnsafeDataRef().AsSpan();
{
unsafe
{
Instance->Fill(value);
}
}
public nuint Width
{
get
{
unsafe
{
return Instance->Width();
}
}
}
public nuint Height
{
get
{
unsafe
{
return Instance->Height();
}
}
}
public Span<byte> Data
{
get
{
unsafe
{
return Instance->UnsafeDataRef().AsSpan();
}
}
}
private unsafe BrightnessGrid(BindGen.BrightnessGrid* instance) : base(instance)
{
}
private protected override unsafe void Free() => Instance->Free();
} }

View file

@ -8,7 +8,7 @@ using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace ServicePoint.BindGen namespace ServicePoint
{ {
public static unsafe partial class BrightnessGridNative public static unsafe partial class BrightnessGridNative
{ {
@ -19,6 +19,95 @@ namespace ServicePoint.BindGen
public const byte SP_BRIGHTNESS_LEVELS = 12; 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
/// <summary> /// <summary>
/// Creates a new [SPBrightnessGrid] with the specified dimensions. /// Creates a new [SPBrightnessGrid] with the specified dimensions.
/// ///
@ -32,7 +121,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_brightness_grid_free`. /// by explicitly calling `sp_brightness_grid_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_brightness_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Loads a [SPBrightnessGrid] with the specified dimensions from the provided data. /// 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`. /// by explicitly calling `sp_brightness_grid_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_brightness_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Clones a [SPBrightnessGrid]. /// Clones a [SPBrightnessGrid].
@ -79,7 +168,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_brightness_grid_free`. /// by explicitly calling `sp_brightness_grid_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_brightness_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Deallocates a [SPBrightnessGrid]. /// 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] /// - `brightness_grid` was not passed to another consuming function, e.g. to create a [SPCommand]
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_brightness_grid_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Gets the current value at the specified position. /// Gets the current value at the specified position.
@ -126,7 +215,7 @@ namespace ServicePoint.BindGen
/// - `brightness_grid` is not written to concurrently /// - `brightness_grid` is not written to concurrently
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_brightness_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Sets the value of the specified position in the [SPBrightnessGrid]. /// 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 /// - `brightness_grid` is not written to or read from concurrently
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_brightness_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Sets the value of all cells in the [SPBrightnessGrid]. /// 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 /// - `brightness_grid` is not written to or read from concurrently
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_brightness_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Gets the width of the [SPBrightnessGrid] instance. /// Gets the width of the [SPBrightnessGrid] instance.
@ -198,7 +287,7 @@ namespace ServicePoint.BindGen
/// - `brightness_grid` points to a valid [SPBrightnessGrid] /// - `brightness_grid` points to a valid [SPBrightnessGrid]
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_brightness_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Gets the height of the [SPBrightnessGrid] instance. /// Gets the height of the [SPBrightnessGrid] instance.
@ -220,7 +309,7 @@ namespace ServicePoint.BindGen
/// - `brightness_grid` points to a valid [SPBrightnessGrid] /// - `brightness_grid` points to a valid [SPBrightnessGrid]
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_brightness_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Gets an unsafe reference to the data of the [SPBrightnessGrid] instance. /// 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 /// - the returned memory range is never accessed concurrently, either via the [SPBrightnessGrid] or directly
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_brightness_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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)] [StructLayout(LayoutKind.Sequential)]
public unsafe partial struct BrightnessGrid public unsafe partial struct SPBrightnessGrid
{ {
} }

View file

@ -8,12 +8,12 @@ using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace ServicePoint.BindGen namespace ServicePoint
{ {
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public unsafe partial struct ByteSlice public unsafe partial struct SPByteSlice
{ {
public byte* start; public byte* start;
public nuint length; public nuint length;

View file

@ -1,129 +1,11 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using ServicePoint.BindGen;
namespace ServicePoint; namespace ServicePoint;
public sealed class Command : SpNativeInstance<BindGen.Command> public sealed partial class Command
{ {
public static bool TryFromPacket(Packet packet, [MaybeNullWhen(false)] out Command command) public static bool TryFromPacket(Packet packet, [MaybeNullWhen(false)] out Command command)
{ {
unsafe return (command = TryFromPacket(packet)) != null;
{
var result = CommandNative.sp_command_try_from_packet(packet.Into());
if (result == null)
{
command = null;
return false;
}
command = new Command(result);
return true;
}
} }
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();
} }

View file

@ -8,14 +8,119 @@ using System;
using System.Runtime.InteropServices; 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"; const string __DllName = "servicepoint_binding_c";
#nullable restore
/// <summary> /// <summary>
/// Tries to turn a [SPPacket] into a [SPCommand]. /// Tries to turn a [SPPacket] into a [SPCommand].
/// ///
@ -38,7 +143,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_command_free`. /// by explicitly calling `sp_command_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_try_from_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Clones a [SPCommand] instance. /// Clones a [SPCommand] instance.
@ -59,7 +164,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_command_free`. /// by explicitly calling `sp_command_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Set all pixels to the off state. /// Set all pixels to the off state.
@ -82,7 +187,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_command_free`. /// by explicitly calling `sp_command_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_clear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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();
/// <summary> /// <summary>
/// Kills the udp daemon on the display, which usually results in a restart. /// 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`. /// by explicitly calling `sp_command_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_hard_reset", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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();
/// <summary> /// <summary>
/// A yet-to-be-tested command. /// A yet-to-be-tested command.
@ -114,7 +219,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_command_free`. /// by explicitly calling `sp_command_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_fade_out", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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();
/// <summary> /// <summary>
/// Set the brightness of all tiles to the same value. /// Set the brightness of all tiles to the same value.
@ -133,7 +238,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_command_free`. /// by explicitly calling `sp_command_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Set the brightness of individual tiles in a rectangular area of the display. /// 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`. /// by explicitly calling `sp_command_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_char_brightness", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Set pixel data starting at the pixel offset on screen. /// Set pixel data starting at the pixel offset on screen.
@ -186,7 +291,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_command_free`. /// by explicitly calling `sp_command_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Set pixel data according to an and-mask starting at the offset. /// 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`. /// by explicitly calling `sp_command_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_and", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Set pixel data according to an or-mask starting at the offset. /// 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`. /// by explicitly calling `sp_command_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_or", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Set pixel data according to a xor-mask starting at the offset. /// 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`. /// by explicitly calling `sp_command_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_xor", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Show text on the screen. /// Show text on the screen.
@ -299,7 +404,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_command_free`. /// by explicitly calling `sp_command_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_cp437_data", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Sets a window of pixels to the specified values. /// Sets a window of pixels to the specified values.
@ -324,7 +429,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_command_free`. /// by explicitly calling `sp_command_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_bitmap_linear_win", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Deallocates a [SPCommand]. /// Deallocates a [SPCommand].
@ -349,13 +454,13 @@ namespace ServicePoint.BindGen
/// - `command` was not passed to another consuming function, e.g. to create a [SPPacket] /// - `command` was not passed to another consuming function, e.g. to create a [SPPacket]
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_command_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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)] [StructLayout(LayoutKind.Sequential)]
public unsafe partial struct Command public unsafe partial struct SPCommand
{ {
} }

View file

@ -1,40 +1,21 @@
using System.Text; using System.Text;
using ServicePoint.BindGen;
namespace ServicePoint; namespace ServicePoint;
public sealed class Connection : SpNativeInstance<BindGen.Connection> public sealed partial class Connection
{ {
public static Connection Open(string host) public static Connection? Open(string host)
{ {
unsafe unsafe
{ {
fixed (byte* bytePtr = Encoding.UTF8.GetBytes(host)) fixed (byte* bytePtr = Encoding.UTF8.GetBytes(host))
{ {
return new Connection(ConnectionNative.sp_connection_open(bytePtr)); return Open(bytePtr);
} }
} }
} }
public bool Send(Packet packet) public bool Send(Packet packet) => SendPacket(packet);
{
unsafe
{
return Instance->SendPacket(packet.Into());
}
}
public bool Send(Command command) public bool Send(Command command) => SendCommand(command);
{
unsafe
{
return Instance->SendCommand(command.Into());
}
}
private protected override unsafe void Free() => Instance->Free();
private unsafe Connection(BindGen.Connection* instance) : base(instance)
{
}
} }

View file

@ -8,14 +8,69 @@ using System;
using System.Runtime.InteropServices; 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"; const string __DllName = "servicepoint_binding_c";
#nullable restore
/// <summary> /// <summary>
/// Creates a new instance of [SPConnection]. /// Creates a new instance of [SPConnection].
/// ///
@ -33,7 +88,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_connection_free`. /// by explicitly calling `sp_connection_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_connection_open", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Sends a [SPPacket] to the display using the [SPConnection]. /// Sends a [SPPacket] to the display using the [SPConnection].
@ -57,7 +112,7 @@ namespace ServicePoint.BindGen
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_connection_send_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_connection_send_packet", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [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);
/// <summary> /// <summary>
/// Sends a [SPCommand] to the display using the [SPConnection]. /// Sends a [SPCommand] to the display using the [SPConnection].
@ -81,7 +136,7 @@ namespace ServicePoint.BindGen
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_connection_send_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [DllImport(__DllName, EntryPoint = "sp_connection_send_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.U1)] [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);
/// <summary> /// <summary>
/// Closes and deallocates a [SPConnection]. /// Closes and deallocates a [SPConnection].
@ -98,13 +153,13 @@ namespace ServicePoint.BindGen
/// - `connection` is not used concurrently or after this call /// - `connection` is not used concurrently or after this call
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_connection_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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)] [StructLayout(LayoutKind.Sequential)]
public unsafe partial struct Connection public unsafe partial struct SPConnection
{ {
} }

View file

@ -1,5 +1,3 @@
using ServicePoint.BindGen;
namespace ServicePoint; namespace ServicePoint;
public static class Constants public static class Constants

View file

@ -8,7 +8,7 @@ using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace ServicePoint.BindGen namespace ServicePoint
{ {
public static unsafe partial class ConstantsNative public static unsafe partial class ConstantsNative
{ {
@ -23,6 +23,7 @@ namespace ServicePoint.BindGen
} }
public enum CompressionCode : ushort public enum CompressionCode : ushort
{ {
Uncompressed = 0, Uncompressed = 0,

View file

@ -1,61 +1,20 @@
using System.Text; using System.Text;
using ServicePoint.BindGen;
namespace ServicePoint; namespace ServicePoint;
public sealed class Cp437Grid : SpNativeInstance<BindGen.Cp437Grid> 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<byte> 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] public byte this[nuint x, nuint y]
{ {
get get => Get(x, y);
{ set => Set(x, y, value);
unsafe
{
return Instance->Get(x, y);
}
}
set
{
unsafe
{
Instance->Set(x, y, value);
}
}
} }
public string this[nuint y] public string this[nuint y]
{ {
set set
{ {
var width = Width; var width = Width();
ArgumentOutOfRangeException.ThrowIfGreaterThan((nuint)value.Length, width); ArgumentOutOfRangeException.ThrowIfGreaterThan((nuint)value.Length, width);
nuint x = 0; nuint x = 0;
@ -69,7 +28,8 @@ public sealed class Cp437Grid : SpNativeInstance<BindGen.Cp437Grid>
get get
{ {
var sb = new StringBuilder(); 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]; var val = this[x, y];
if (val == 0) if (val == 0)
@ -81,50 +41,5 @@ public sealed class Cp437Grid : SpNativeInstance<BindGen.Cp437Grid>
} }
} }
public void Fill(byte value) public Span<byte> Data => UnsafeDataRef().AsSpan();
{
unsafe
{
Instance->Fill(value);
}
}
public nuint Width
{
get
{
unsafe
{
return Instance->Width();
}
}
}
public nuint Height
{
get
{
unsafe
{
return Instance->Height();
}
}
}
public Span<byte> Data
{
get
{
unsafe
{
return Instance->UnsafeDataRef().AsSpan();
}
}
}
private unsafe Cp437Grid(BindGen.Cp437Grid* instance) : base(instance)
{
}
private protected override unsafe void Free() => Instance->Free();
} }

View file

@ -8,14 +8,95 @@ using System;
using System.Runtime.InteropServices; 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"; const string __DllName = "servicepoint_binding_c";
#nullable restore
/// <summary> /// <summary>
/// Creates a new [SPCp437Grid] with the specified dimensions. /// Creates a new [SPCp437Grid] with the specified dimensions.
/// ///
@ -29,7 +110,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_cp437_grid_free`. /// by explicitly calling `sp_cp437_grid_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_cp437_grid_new", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Loads a [SPCp437Grid] with the specified dimensions from the provided data. /// 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`. /// by explicitly calling `sp_cp437_grid_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_cp437_grid_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Clones a [SPCp437Grid]. /// Clones a [SPCp437Grid].
@ -72,7 +153,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_cp437_grid_free`. /// by explicitly calling `sp_cp437_grid_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_cp437_grid_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Deallocates a [SPCp437Grid]. /// 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] /// - `cp437_grid` was not passed to another consuming function, e.g. to create a [SPCommand]
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_cp437_grid_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Gets the current value at the specified position. /// Gets the current value at the specified position.
@ -113,7 +194,7 @@ namespace ServicePoint.BindGen
/// - `cp437_grid` is not written to concurrently /// - `cp437_grid` is not written to concurrently
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_cp437_grid_get", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Sets the value of the specified position in the [SPCp437Grid]. /// 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 /// - `cp437_grid` is not written to or read from concurrently
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_cp437_grid_set", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Sets the value of all cells in the [SPCp437Grid]. /// 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 /// - `cp437_grid` is not written to or read from concurrently
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_cp437_grid_fill", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Gets the width of the [SPCp437Grid] instance. /// Gets the width of the [SPCp437Grid] instance.
@ -181,7 +262,7 @@ namespace ServicePoint.BindGen
/// - `cp437_grid` points to a valid [SPCp437Grid] /// - `cp437_grid` points to a valid [SPCp437Grid]
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_cp437_grid_width", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Gets the height of the [SPCp437Grid] instance. /// Gets the height of the [SPCp437Grid] instance.
@ -201,7 +282,7 @@ namespace ServicePoint.BindGen
/// - `cp437_grid` points to a valid [SPCp437Grid] /// - `cp437_grid` points to a valid [SPCp437Grid]
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_cp437_grid_height", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Gets an unsafe reference to the data of the [SPCp437Grid] instance. /// 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 /// - the returned memory range is never accessed concurrently, either via the [SPCp437Grid] or directly
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_cp437_grid_unsafe_data_ref", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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)] [StructLayout(LayoutKind.Sequential)]
public unsafe partial struct Cp437Grid public unsafe partial struct SPCp437Grid
{ {
} }

View file

@ -1,36 +1,18 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using ServicePoint.BindGen;
namespace ServicePoint; namespace ServicePoint;
public sealed class Packet : SpNativeInstance<BindGen.Packet> 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<byte> bytes, [MaybeNullWhen(false)] out Packet packet) public static bool TryFromBytes(Span<byte> bytes, [MaybeNullWhen(false)] out Packet packet)
{ {
unsafe unsafe
{ {
fixed (byte* bytesPtr = bytes) fixed (byte* bytesPtr = bytes)
{ {
var instance = PacketNative.sp_packet_try_load(bytesPtr, (nuint)bytes.Length); packet = TryLoad(bytesPtr, (nuint)bytes.Length);
packet = instance == null
? null
: new Packet(instance);
return packet != null; return packet != null;
} }
} }
} }
private unsafe Packet(BindGen.Packet* instance) : base(instance)
{
}
private protected override unsafe void Free() => Instance->Free();
} }

View file

@ -8,14 +8,69 @@ using System;
using System.Runtime.InteropServices; 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"; const string __DllName = "servicepoint_binding_c";
#nullable restore
/// <summary> /// <summary>
/// Turns a [SPCommand] into a [SPPacket]. /// Turns a [SPCommand] into a [SPPacket].
/// The [SPCommand] gets consumed. /// The [SPCommand] gets consumed.
@ -36,7 +91,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_packet_free`. /// by explicitly calling `sp_packet_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_packet_from_command", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Tries to load a [SPPacket] from the passed array with the specified length. /// 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`. /// by explicitly calling `sp_packet_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_packet_try_load", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Clones a [SPPacket]. /// Clones a [SPPacket].
@ -78,7 +133,7 @@ namespace ServicePoint.BindGen
/// by explicitly calling `sp_packet_free`. /// by explicitly calling `sp_packet_free`.
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_packet_clone", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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);
/// <summary> /// <summary>
/// Deallocates a [SPPacket]. /// Deallocates a [SPPacket].
@ -95,13 +150,13 @@ namespace ServicePoint.BindGen
/// - `packet` is not used concurrently or after this call /// - `packet` is not used concurrently or after this call
/// </summary> /// </summary>
[DllImport(__DllName, EntryPoint = "sp_packet_free", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] [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)] [StructLayout(LayoutKind.Sequential)]
public unsafe partial struct Packet public unsafe partial struct SPPacket
{ {
} }

View file

@ -52,11 +52,6 @@
</Content> </Content>
</ItemGroup> </ItemGroup>
<!--additional csbindgen code generators-->
<ItemGroup>
<PackageReference Include="csbindgen" Version="1.9.3" PrivateAssets="All"/>
</ItemGroup>
<ItemGroup> <ItemGroup>
<!-- include link to source code at revision --> <!-- include link to source code at revision -->
<None Include="../README.md" Pack="true" PackagePath="\"/> <None Include="../README.md" Pack="true" PackagePath="\"/>

View file

@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using ServicePoint.BindGen;
namespace ServicePoint; namespace ServicePoint;
@ -15,7 +14,7 @@ public static class ServicePointExtensions
return Command.TryFromPacket(packet, out command); return Command.TryFromPacket(packet, out command);
} }
public unsafe static Span<byte> AsSpan(this ByteSlice slice) public unsafe static Span<byte> AsSpan(this SPByteSlice slice)
{ {
return new Span<byte>(slice.start, (int)slice.length); return new Span<byte>(slice.start, (int)slice.length);
} }

View file

@ -1,51 +0,0 @@
namespace ServicePoint;
public abstract class SpNativeInstance<T>
: 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();
}
}

View file

@ -17,32 +17,44 @@ fn main() {
for path in &paths { for path in &paths {
println!("cargo:rerun-if-changed={}", path.display()); println!("cargo:rerun-if-changed={}", path.display());
let file: &str = Path::new(path).file_stem().unwrap().to_str().unwrap(); let file: &str = Path::new(path).file_stem().unwrap().to_str().unwrap();
if file == "lib"{ if file == "lib" {
continue; continue;
} }
let class = file.to_case(Case::UpperCamel) + "Native"; let class = file.to_case(Case::UpperCamel);
csbindgen::Builder::default() csbindgen::Builder::default()
.input_extern_file(path) .input_extern_file(path)
.csharp_class_name(&class) .csharp_class_name(format!("{class}Native"))
.csharp_dll_name("servicepoint_binding_c") .csharp_dll_name("servicepoint_binding_c")
.csharp_namespace("ServicePoint.BindGen") .csharp_namespace("ServicePoint")
.csharp_use_nint_types(true) .csharp_use_nint_types(true)
.csharp_class_accessibility("public") .csharp_class_accessibility("public")
.csharp_generate_const_filter(|_| true) .csharp_generate_const_filter(|_| true)
.always_included_types(["SPByteSlice", "SPCompressionCode"]) .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| { .csharp_type_rename(move |name| {
if name.len() > 2 if name == "SPCompressionCode"
&& name.starts_with("SP")
&& name.chars().nth(2).unwrap().is_uppercase()
{ {
name[2..].to_string() "CompressionCode".to_string()
} else { } else {
name name
} }
}) })
.generate_csharp_file(format!("ServicePoint/BindGen/{}.g.cs", &class)) .generate_csharp_file(format!("ServicePoint/{class}.g.cs"))
.unwrap(); .unwrap();
} }
} }

View file

@ -1,20 +1,24 @@
using ServicePoint; using ServicePoint;
using CompressionCode = ServicePoint.BindGen.CompressionCode;
using var connection = Connection.Open("127.0.0.1:2342"); 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.Clear().IntoPacket());
connection.Send(Command.Brightness(128).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++) for (nuint offset = 0; offset < nuint.MaxValue; offset++)
{ {
pixels.Fill(false); 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; 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); Thread.Sleep(14);
} }

@ -0,0 +1 @@
Subproject commit 2dcf44a5c398925249cf96e9bbf724dd551e5b76