From 71e03077e6a79b5badf7f44701f13ebd8c068830 Mon Sep 17 00:00:00 2001 From: Thad House Date: Mon, 1 Jun 2026 15:51:44 -0700 Subject: [PATCH] Update wpiutil and ntcore native imports --- src/ntcore/LogMessage.cs | 2 +- src/ntcore/Natives/NtCore.Datalog.cs | 2 +- src/ntcore/Natives/NtCore.Free.cs | 32 ++++++++++++++++ src/ntcore/Natives/NtCore.Listener.cs | 10 +++++ src/ntcore/NetworkMode.cs | 7 ++-- src/ntcore/PubSubOptions.cs | 39 +++++++------------- src/wpiutil/Natives/RawFrameNative.cs | 10 ++++- src/wpiutil/Natives/StringsNative.cs | 16 ++++++++ src/wpiutil/Natives/SynchronizationNative.cs | 12 +++--- src/wpiutil/PixelFormat.cs | 11 +++++- src/wpiutil/RawFrameReader.cs | 16 ++++++++ src/wpiutil/RawFrameWriter.cs | 2 + 12 files changed, 120 insertions(+), 39 deletions(-) diff --git a/src/ntcore/LogMessage.cs b/src/ntcore/LogMessage.cs index e2dced15..0a74d4ab 100644 --- a/src/ntcore/LogMessage.cs +++ b/src/ntcore/LogMessage.cs @@ -17,7 +17,7 @@ public static LogMessage ConvertToManaged(in NativeLogMessage unmanaged) { LogLevel = (int)unmanaged.level, Message = unmanaged.message.ConvertToString(), - Filename = unmanaged.message.ConvertToString(), + Filename = unmanaged.filename.ConvertToString(), Line = (int)unmanaged.line }; } diff --git a/src/ntcore/Natives/NtCore.Datalog.cs b/src/ntcore/Natives/NtCore.Datalog.cs index 2679f72f..b46bb63a 100644 --- a/src/ntcore/Natives/NtCore.Datalog.cs +++ b/src/ntcore/Natives/NtCore.Datalog.cs @@ -20,7 +20,7 @@ public static unsafe partial class NtCore [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] public static partial NtConnectionDataLogger StartConnectionDataLog(NtInst inst, OpaqueDataLog* log, WpiString name); - [LibraryImport("ntcore", EntryPoint = "NT_StopEntryDataLog")] + [LibraryImport("ntcore", EntryPoint = "NT_StopConnectionDataLog")] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] public static partial void StopConnectionDataLog(NtConnectionDataLogger logger); } diff --git a/src/ntcore/Natives/NtCore.Free.cs b/src/ntcore/Natives/NtCore.Free.cs index 6b86100f..193c7754 100644 --- a/src/ntcore/Natives/NtCore.Free.cs +++ b/src/ntcore/Natives/NtCore.Free.cs @@ -41,6 +41,38 @@ public static unsafe partial class NtCore [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] public static partial void FreeCharArray(byte* nativePtr); + [LibraryImport("ntcore", EntryPoint = "NT_AllocateBooleanArray")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static partial int* AllocateBooleanArray(nuint len); + + [LibraryImport("ntcore", EntryPoint = "NT_AllocateIntegerArray")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static partial long* AllocateIntegerArray(nuint len); + + [LibraryImport("ntcore", EntryPoint = "NT_AllocateFloatArray")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static partial float* AllocateFloatArray(nuint len); + + [LibraryImport("ntcore", EntryPoint = "NT_AllocateDoubleArray")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static partial double* AllocateDoubleArray(nuint len); + + [LibraryImport("ntcore", EntryPoint = "NT_FreeBooleanArray")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static partial void FreeBooleanArray(int* nativePtr); + + [LibraryImport("ntcore", EntryPoint = "NT_FreeIntegerArray")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static partial void FreeIntegerArray(long* nativePtr); + + [LibraryImport("ntcore", EntryPoint = "NT_FreeFloatArray")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static partial void FreeFloatArray(float* nativePtr); + + [LibraryImport("ntcore", EntryPoint = "NT_FreeDoubleArray")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static partial void FreeDoubleArray(double* nativePtr); + [LibraryImport("ntcore", EntryPoint = "NT_Meta_FreeTopicPublishers")] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] public static partial void MetaFreeTopicPublishers(void* nativePtr, nuint count); diff --git a/src/ntcore/Natives/NtCore.Listener.cs b/src/ntcore/Natives/NtCore.Listener.cs index b46fd494..89a7204e 100644 --- a/src/ntcore/Natives/NtCore.Listener.cs +++ b/src/ntcore/Natives/NtCore.Listener.cs @@ -26,6 +26,16 @@ public static NetworkTableEvent[] ReadListenerQueue(NtListenerPoller poller) [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] public static partial void DestroyListenerPoller(NtListenerPoller poller); + + [LibraryImport("ntcore", EntryPoint = "NT_WaitForListenerQueue")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + [return: MarshalAs(UnmanagedType.I4)] + public static partial bool WaitForListenerQueue(int handle, double timeout); + + [LibraryImport("ntcore", EntryPoint = "NT_AddPolledListenerSingle")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static partial NtListener AddListener(NtListenerPoller poller, WPIUtil.WpiString prefix, EventFlags flags); + [LibraryImport("ntcore", EntryPoint = "NT_AddPolledListenerMultiple")] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] internal static partial NtListener AddListener(NtListenerPoller poller, [MarshalUsing(typeof(WpiStringMarshaller), ElementIndirectionDepth = 1)] ReadOnlySpan prefixes, nuint prefixesLen, EventFlags flags); diff --git a/src/ntcore/NetworkMode.cs b/src/ntcore/NetworkMode.cs index 3ec39fb4..cbed9a18 100644 --- a/src/ntcore/NetworkMode.cs +++ b/src/ntcore/NetworkMode.cs @@ -3,10 +3,11 @@ namespace NetworkTables; [Flags] public enum NetworkMode : uint { - None = 0, + None = 0x0, Server = 0x1, - Client3 = 0x2, - Client4 = 0x4, + Client = 0x4, + Client4 = Client, Starting = 0x8, Local = 0x10, + MdnsAnnouncing = 0x20, } diff --git a/src/ntcore/PubSubOptions.cs b/src/ntcore/PubSubOptions.cs index 028144fc..3a234590 100644 --- a/src/ntcore/PubSubOptions.cs +++ b/src/ntcore/PubSubOptions.cs @@ -1,13 +1,20 @@ using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; +using NetworkTables.Handles; namespace NetworkTables; [NativeMarshalling(typeof(PubSubOptionsMarshaller))] [StructLayout(LayoutKind.Auto)] -public record struct PubSubOptions(uint PollSize, double Periodic, bool ExcludePublisher, bool SendAll, bool TopicsOnly, bool PrefixMatch, bool KeepDuplicates, bool DisableRemote, bool DisableLocal, bool ExcludeSelf, bool Hidden) +public record struct PubSubOptions(uint PollStorage, double Periodic, NtPublisher ExcludePublisher, bool SendAll, bool TopicsOnly, bool PrefixMatch, bool KeepDuplicates, bool DisableRemote, bool DisableLocal, bool ExcludeSelf, bool Hidden) { public static PubSubOptions None => new(); + + public uint PollSize + { + get => PollStorage; + set => PollStorage = value; + } } [CustomMarshaller(typeof(PubSubOptions), MarshalMode.Default, typeof(PubSubOptionsMarshaller))] @@ -18,9 +25,9 @@ public static NativePubSubOptions ConvertToUnmanaged(in PubSubOptions managed) return new NativePubSubOptions { structSize = (uint)sizeof(NativePubSubOptions), - pollSize = managed.PollSize, + pollStorage = managed.PollStorage, periodic = managed.Periodic, - excludePublisher = managed.ExcludePublisher ? 1 : 0, + excludePublisher = managed.ExcludePublisher.Handle, sendAll = managed.SendAll ? 1 : 0, topicsOnly = managed.TopicsOnly ? 1 : 0, prefixMatch = managed.PrefixMatch ? 1 : 0, @@ -36,9 +43,9 @@ public static PubSubOptions ConvertToManaged(in NativePubSubOptions unmanaged) { return new PubSubOptions { - PollSize = unmanaged.pollSize, + PollStorage = unmanaged.pollStorage, Periodic = unmanaged.periodic, - ExcludePublisher = unmanaged.excludePublisher != 0, + ExcludePublisher = new NtPublisher(unmanaged.excludePublisher), SendAll = unmanaged.sendAll != 0, TopicsOnly = unmanaged.topicsOnly != 0, PrefixMatch = unmanaged.prefixMatch != 0, @@ -54,7 +61,7 @@ public static PubSubOptions ConvertToManaged(in NativePubSubOptions unmanaged) public struct NativePubSubOptions { public uint structSize; - public uint pollSize; + public uint pollStorage; public double periodic; public int excludePublisher; public int sendAll; @@ -65,25 +72,5 @@ public struct NativePubSubOptions public int disableLocal; public int excludeSelf; public int hidden; - - public override bool Equals(object? obj) - { - throw new NotImplementedException(); - } - - public override int GetHashCode() - { - throw new NotImplementedException(); - } - - public static bool operator ==(NativePubSubOptions left, NativePubSubOptions right) - { - return left.Equals(right); - } - - public static bool operator !=(NativePubSubOptions left, NativePubSubOptions right) - { - return !(left == right); - } } } diff --git a/src/wpiutil/Natives/RawFrameNative.cs b/src/wpiutil/Natives/RawFrameNative.cs index c154a066..ed42d2ed 100644 --- a/src/wpiutil/Natives/RawFrameNative.cs +++ b/src/wpiutil/Natives/RawFrameNative.cs @@ -24,6 +24,8 @@ public void FromManaged(in RawFrameWriter managed) rawFrame.height = managed.Height; rawFrame.stride = managed.Stride; rawFrame.pixelFormat = managed.PixelFormat; + rawFrame.timestamp = managed.Timestamp; + rawFrame.timestampSrc = managed.TimestampSource; } public readonly ref readonly byte GetPinnableReference() { @@ -49,13 +51,17 @@ public unsafe partial struct NativeRawFrame { [LibraryImport("wpiutil", EntryPoint = "WPI_AllocateRawFrameData")] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] - [return: MarshalAs(UnmanagedType.U4)] + [return: MarshalAs(UnmanagedType.I4)] public static unsafe partial bool AllocateRawFrameData(ref NativeRawFrame frame, nuint requestedSize); [LibraryImport("wpiutil", EntryPoint = "WPI_FreeRawFrameData")] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] public static unsafe partial void FreeRawFrameData(ref NativeRawFrame frame); + [LibraryImport("wpiutil", EntryPoint = "WPI_SetRawFrameData")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static unsafe partial void SetRawFrameData(ref NativeRawFrame frame, void* data, nuint size, nuint capacity, void* cbdata, delegate* unmanaged[Cdecl] freeFunc); + public byte* data; public delegate* unmanaged[Cdecl] freeFunc; public void* freeCbData; @@ -65,4 +71,6 @@ public unsafe partial struct NativeRawFrame public int width; public int height; public int stride; + public ulong timestamp; + public TimestampSource timestampSrc; } diff --git a/src/wpiutil/Natives/StringsNative.cs b/src/wpiutil/Natives/StringsNative.cs index 0a360244..4b7020d4 100644 --- a/src/wpiutil/Natives/StringsNative.cs +++ b/src/wpiutil/Natives/StringsNative.cs @@ -6,6 +6,22 @@ namespace WPIUtil.Natives; public static partial class StringsNative { + [LibraryImport("wpiutil", EntryPoint = "WPI_InitString")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static unsafe partial void InitString(WpiStringMarshaller.WpiStringNative* wpiString); + + [LibraryImport("wpiutil", EntryPoint = "WPI_InitStringWithLength")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static unsafe partial void InitStringWithLength(WpiStringMarshaller.WpiStringNative* wpiString, nuint len); + + [LibraryImport("wpiutil", EntryPoint = "WPI_AllocateString")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static unsafe partial void AllocateString(WpiStringMarshaller.WpiStringNative* wpiString, nuint len); + + [LibraryImport("wpiutil", EntryPoint = "WPI_AllocateStringArray")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static unsafe partial WpiStringMarshaller.WpiStringNative* AllocateStringArray(nuint count); + [LibraryImport("wpiutil", EntryPoint = "WPI_FreeString")] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] public static unsafe partial void FreeString(WpiStringMarshaller.WpiStringNative* wpiString); diff --git a/src/wpiutil/Natives/SynchronizationNative.cs b/src/wpiutil/Natives/SynchronizationNative.cs index 98786d51..920854ec 100644 --- a/src/wpiutil/Natives/SynchronizationNative.cs +++ b/src/wpiutil/Natives/SynchronizationNative.cs @@ -7,7 +7,7 @@ namespace WPIUtil.Natives; public static partial class SynchronizationNative { - [LibraryImport("wpiutil", EntryPoint = "WPI_CreateEvent")] + [LibraryImport("wpiutil", EntryPoint = "WPI_MakeEvent")] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] public static partial WpiEventHandle CreateEvent([MarshalAs(UnmanagedType.I4)] bool manualReset, [MarshalAs(UnmanagedType.I4)] bool initialState); @@ -23,7 +23,7 @@ public static partial class SynchronizationNative [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] public static partial void ResetEvent(WpiEventHandle handle); - [LibraryImport("wpiutil", EntryPoint = "WPI_CreateSemaphore")] + [LibraryImport("wpiutil", EntryPoint = "WPI_MakeSemaphore")] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] public static partial WpiSemaphoreHandle CreateSemaphore(int initialCount, int maximumCount); @@ -33,17 +33,17 @@ public static partial class SynchronizationNative [LibraryImport("wpiutil", EntryPoint = "WPI_ReleaseSemaphore")] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] - [return: MarshalAs(UnmanagedType.U4)] + [return: MarshalAs(UnmanagedType.I4)] public static unsafe partial bool ReleaseSemaphore(WpiSemaphoreHandle handle, int releaseCount, out int prevCount); [LibraryImport("wpiutil", EntryPoint = "WPI_WaitForObject")] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] - [return: MarshalAs(UnmanagedType.U4)] + [return: MarshalAs(UnmanagedType.I4)] public static partial bool WaitForObject(int handle); [LibraryImport("wpiutil", EntryPoint = "WPI_WaitForObjectTimeout")] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] - [return: MarshalAs(UnmanagedType.U4)] + [return: MarshalAs(UnmanagedType.I4)] public static unsafe partial bool WaitForObjectTimeout(int handle, double timeout, [MarshalAs(UnmanagedType.I4)] out bool timedOut); [LibraryImport("wpiutil", EntryPoint = "WPI_WaitForObjects")] @@ -64,7 +64,7 @@ public static unsafe ReadOnlySpan WaitForObjects(ReadOnlySpan handles, [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] public static unsafe partial int WaitForObjectsTimeout(ReadOnlySpan handles, int handlesCount, Span signaled, double timeout, [MarshalAs(UnmanagedType.I4)] out bool timedOut); - [LibraryImport("wpiutil", EntryPoint = "WPI_CreateSemaphore")] + [LibraryImport("wpiutil", EntryPoint = "WPI_CreateSignalObject")] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] public static partial void CreateSignalObject(int handle, [MarshalAs(UnmanagedType.I4)] bool manualReset, [MarshalAs(UnmanagedType.I4)] bool InitialState); diff --git a/src/wpiutil/PixelFormat.cs b/src/wpiutil/PixelFormat.cs index 537da588..17e8c6a1 100644 --- a/src/wpiutil/PixelFormat.cs +++ b/src/wpiutil/PixelFormat.cs @@ -9,5 +9,14 @@ public enum PixelFormat : int Bgr, Gray, Y16, - Uyvy + Uyvy, + Bgra +} + +public enum TimestampSource : int +{ + Unknown = 0, + FrameDequeue, + V4lEof, + V4lSoe } diff --git a/src/wpiutil/RawFrameReader.cs b/src/wpiutil/RawFrameReader.cs index 9d896521..fdc80a8e 100644 --- a/src/wpiutil/RawFrameReader.cs +++ b/src/wpiutil/RawFrameReader.cs @@ -49,10 +49,24 @@ public PixelFormat PixelFormat set => internalFrame.pixelFormat = value; } + public ulong Timestamp + { + get => internalFrame.timestamp; + set => internalFrame.timestamp = value; + } + + public TimestampSource TimestampSource + { + get => internalFrame.timestampSrc; + set => internalFrame.timestampSrc = value; + } + public unsafe RawFrameReader CreateCopy() { RawFrameReader ret = new RawFrameReader(); ret.SetInfo(Width, Height, Stride, PixelFormat); + ret.Timestamp = Timestamp; + ret.TimestampSource = TimestampSource; NativeRawFrame.AllocateRawFrameData(ref ret.RawFrame, internalFrame.size); ret.internalFrame.size = internalFrame.size; new ReadOnlySpan(internalFrame.data, checked((int)internalFrame.size)).CopyTo(new Span(ret.internalFrame.data, (int)ret.internalFrame.size)); @@ -68,6 +82,8 @@ public unsafe RawFrameWriter ToWriter() Height = Height, Stride = Stride, PixelFormat = PixelFormat, + Timestamp = Timestamp, + TimestampSource = TimestampSource, }; } } diff --git a/src/wpiutil/RawFrameWriter.cs b/src/wpiutil/RawFrameWriter.cs index 147d7dee..8bc1f35d 100644 --- a/src/wpiutil/RawFrameWriter.cs +++ b/src/wpiutil/RawFrameWriter.cs @@ -13,4 +13,6 @@ public readonly ref struct RawFrameWriter public int Height { get; init; } public int Stride { get; init; } public PixelFormat PixelFormat { get; init; } + public ulong Timestamp { get; init; } + public TimestampSource TimestampSource { get; init; } }