diff --git a/src/cscore/UsbCamera.cs b/src/cscore/UsbCamera.cs index 2ce3b923..a9694c30 100644 --- a/src/cscore/UsbCamera.cs +++ b/src/cscore/UsbCamera.cs @@ -29,7 +29,7 @@ public UsbCamera(string name, string path) : base(CreateUsbCameraPath(name, path public static UsbCameraInfo[] EnumerateUsbCameras() { - var info = CsNative.EnumerateUsbCameras(out var status); + var info = CsNative.EnumerateUsbCameras(); return info; } diff --git a/src/cscore/VideoEvent.cs b/src/cscore/VideoEvent.cs index 23329424..00e73a15 100644 --- a/src/cscore/VideoEvent.cs +++ b/src/cscore/VideoEvent.cs @@ -8,16 +8,10 @@ namespace CsCore; [NativeMarshalling(typeof(VideoEventMarshaller))] [StructLayout(LayoutKind.Auto)] -public readonly struct VideoEvent : INativeArrayFree +public readonly struct VideoEvent(in VideoEventMarshaller.NativeCsEvent csEvent) : INativeArrayFree { - public EventKind Kind { get; } - public CsListener Listener { get; } - - public VideoEvent(in VideoEventMarshaller.NativeCsEvent csEvent) - { - Kind = csEvent.kind; - Listener = new CsListener(csEvent.listener); - } + public EventKind Kind { get; } = csEvent.kind; + public CsListener Listener { get; } = new CsListener(csEvent.listener); public static unsafe void FreeArray(VideoEventMarshaller.NativeCsEvent* ptr, int len) { diff --git a/src/cscore/VideoListener.cs b/src/cscore/VideoListener.cs index 8859098a..203eab17 100644 --- a/src/cscore/VideoListener.cs +++ b/src/cscore/VideoListener.cs @@ -83,6 +83,7 @@ public VideoListener(Action listener, EventKind eventMask, bool imme public void Dispose() { + GC.SuppressFinalize(this); if (Handle.Handle != 0) { lock (s_listenerLock) diff --git a/src/cscore/VideoSink.cs b/src/cscore/VideoSink.cs index d30eb48c..c9d64281 100644 --- a/src/cscore/VideoSink.cs +++ b/src/cscore/VideoSink.cs @@ -110,7 +110,7 @@ public VideoProperty GetSourceProperty(string name) public static VideoSink[] EnumerateSinks() { - var handles = CsNative.EnumerateSinks(out var status); + var handles = CsNative.EnumerateSinks(); VideoSink[] rv = new VideoSink[handles.Length]; for (int i = 0; i < handles.Length; i++) @@ -122,6 +122,7 @@ public static VideoSink[] EnumerateSinks() public void Dispose() { + GC.SuppressFinalize(this); if (Handle.Handle != 0) { CsNative.ReleaseSink(Handle); diff --git a/src/cscore/VideoSource.cs b/src/cscore/VideoSource.cs index 34cd8b10..420d023e 100644 --- a/src/cscore/VideoSource.cs +++ b/src/cscore/VideoSource.cs @@ -164,7 +164,7 @@ public VideoProperty[] EnumerateProperties() public static VideoSource[] EnumerateSources() { - var handles = CsNative.EnumerateSources(out var status); + var handles = CsNative.EnumerateSources(); VideoSource[] rv = new VideoSource[handles.Length]; for (int i = 0; i < handles.Length; i++) @@ -176,6 +176,7 @@ public static VideoSource[] EnumerateSources() public void Dispose() { + GC.SuppressFinalize(this); if (Handle.Handle != 0) { CsNative.ReleaseSource(Handle); diff --git a/src/hal/Natives/HalI2C.cs b/src/hal/Natives/HalI2C.cs index b41913ea..d39e4091 100644 --- a/src/hal/Natives/HalI2C.cs +++ b/src/hal/Natives/HalI2C.cs @@ -34,7 +34,7 @@ public static Span ReadI2C(I2CPort port, int deviceAddress, Span buf [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] public static partial int TransactionI2C(I2CPort port, int deviceAddress, ReadOnlySpan dataToSend, int sendSize, Span dataReceived, int receiveSize); - public static Span TransactionI2C(I2CPort port, int deviceAddress, ReadOnlySpan dataToSend, int sendSize, Span dataReceived) + public static Span TransactionI2C(I2CPort port, int deviceAddress, ReadOnlySpan dataToSend, Span dataReceived) { int read = TransactionI2C(port, deviceAddress, dataToSend, dataToSend.Length, dataReceived, dataReceived.Length); if (read > 0) diff --git a/src/ntcore/Natives/RefNetworkTableValueMarshaller.cs b/src/ntcore/Natives/RefNetworkTableValueMarshaller.cs index a0dc0477..8f2d436a 100644 --- a/src/ntcore/Natives/RefNetworkTableValueMarshaller.cs +++ b/src/ntcore/Natives/RefNetworkTableValueMarshaller.cs @@ -13,7 +13,9 @@ public unsafe ref struct RefNetworkTableValueMarshaller public static int BufferSize => 256; private ref readonly byte m_toPin; +#pragma warning disable IDE0052 // Remove unread private members private ref Ptr m_toAssignPin; +#pragma warning restore IDE0052 // Remove unread private members private NetworkTableValueMarshaller.NativeNetworkTableValue m_nativeValue; diff --git a/src/thirdparty/Stereologue/Stereologuer.cs b/src/thirdparty/Stereologue/Stereologuer.cs index cd3a8b09..75a2a154 100644 --- a/src/thirdparty/Stereologue/Stereologuer.cs +++ b/src/thirdparty/Stereologue/Stereologuer.cs @@ -1,5 +1,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using Google.Protobuf.WellKnownTypes; using NetworkTables; using WPIUtil.Logging; using WPIUtil.Serialization.Protobuf; @@ -186,11 +187,21 @@ public void LogChar(string path, LogType logType, char value, LogLevel logLevel public void LogFloat(string path, LogType logType, float value, LogLevel logLevel = LogLevel.Default) { - ref var logs = ref CheckDoLog(path, ref logType, logLevel, doubleLogs); + ref var logs = ref CheckDoLog(path, ref logType, logLevel, floatLogs); if (Unsafe.IsNullRef(ref logs)) { return; } + if (logType.HasFlag(LogType.Nt)) + { + logs.topic ??= ntInstance.GetFloatTopic(path).Publish(PubSubOptions.None); + logs.topic.Set(value); + } + if (logType.HasFlag(LogType.File)) + { + logs.logEntry ??= new FloatLogEntry(log, path); + logs.logEntry.Append(value); + } } public void LogDouble(string path, LogType logType, double value, LogLevel logLevel = LogLevel.Default) @@ -200,6 +211,16 @@ public void LogDouble(string path, LogType logType, double value, LogLevel logLe { return; } + if (logType.HasFlag(LogType.Nt)) + { + logs.topic ??= ntInstance.GetDoubleTopic(path).Publish(PubSubOptions.None); + logs.topic.Set(value); + } + if (logType.HasFlag(LogType.File)) + { + logs.logEntry ??= new DoubleLogEntry(log, path); + logs.logEntry.Append(value); + } } public void LogString(string path, LogType logType, string value, LogLevel logLevel = LogLevel.Default) diff --git a/src/wpiutil/Marshal/WPIStringMarshaller.cs b/src/wpiutil/Marshal/WPIStringMarshaller.cs index 00b78404..e2cf39ba 100644 --- a/src/wpiutil/Marshal/WPIStringMarshaller.cs +++ b/src/wpiutil/Marshal/WPIStringMarshaller.cs @@ -141,7 +141,7 @@ public readonly ref readonly byte GetPinnableReference() return (WpiStringNative*)Unsafe.AsPointer(ref nativeString); } - public void Free() + public readonly void Free() { // Purposely empty } diff --git a/src/wpiutil/Natives/RawFrameNative.cs b/src/wpiutil/Natives/RawFrameNative.cs index e7f08ab2..c154a066 100644 --- a/src/wpiutil/Natives/RawFrameNative.cs +++ b/src/wpiutil/Natives/RawFrameNative.cs @@ -39,7 +39,7 @@ public readonly ref readonly byte GetPinnableReference() return (NativeRawFrame*)Unsafe.AsPointer(ref rawFrame); } - public void Free() + public readonly void Free() { } } diff --git a/src/wpiutil/Sendable/SendableRegistery.cs b/src/wpiutil/Sendable/SendableRegistery.cs index 7b367ced..73dbd9fa 100644 --- a/src/wpiutil/Sendable/SendableRegistery.cs +++ b/src/wpiutil/Sendable/SendableRegistery.cs @@ -128,7 +128,29 @@ public static void AddLW(ISendable sendable, string name) } } - public static void AddLW(ISendable sendable, string name, string moduleType, int moduleNumber, int channel) + public static void AddLW(ISendable sendable, string moduleType, int channel) + { + lock (s_lockObject) + { + Component comp = GetOrAdd(sendable); + if (liveWindowFactory is not null) + { + try + { + comp.m_builder?.Dispose(); + } + catch + { + // Ignore + } + comp.m_builder = liveWindowFactory(); + } + comp.m_liveWindow = true; + comp.SetName(moduleType, channel); + } + } + + public static void AddLW(ISendable sendable, string moduleType, int moduleNumber, int channel) { lock (s_lockObject) { @@ -423,7 +445,7 @@ public class CallbackData public ISendableBuilder? Builder { get; internal set; } } - private static List ForeachComponents = []; + private static readonly List ForeachComponents = []; public static void ForeachLiveWindow(int dataHandle, Action callback) { diff --git a/src/wpiutil/Serialization/Struct/DynamicStruct.cs b/src/wpiutil/Serialization/Struct/DynamicStruct.cs index a61d3472..34cb04ad 100644 --- a/src/wpiutil/Serialization/Struct/DynamicStruct.cs +++ b/src/wpiutil/Serialization/Struct/DynamicStruct.cs @@ -139,7 +139,7 @@ public string GetStringField(StructFieldDescriptor field) } } - OperationStatus result = Rune.DecodeLastFromUtf8(bytes[..stringLength], out var lastChar, out var consumed); + OperationStatus result = Rune.DecodeLastFromUtf8(bytes[..stringLength], out _, out var consumed); #pragma warning disable CS8509 // The switch expression does not handle all possible values of its input type (it is not exhaustive). ReadOnlySpan buffer = result switch { diff --git a/src/wpiutil/Serialization/Struct/Parsing/Lexer.cs b/src/wpiutil/Serialization/Struct/Parsing/Lexer.cs index a0c15070..9d124f5b 100644 --- a/src/wpiutil/Serialization/Struct/Parsing/Lexer.cs +++ b/src/wpiutil/Serialization/Struct/Parsing/Lexer.cs @@ -6,7 +6,7 @@ public ref struct Lexer(ReadOnlySpan inStr) { private Utf8CodePointEnumerator m_enumerator = new(inStr); - public int Position => m_enumerator.CurrentMark; + public readonly int Position => m_enumerator.CurrentMark; public TokenKind Scan() { diff --git a/src/wpiutil/Serialization/Struct/Parsing/ParsedSchema.cs b/src/wpiutil/Serialization/Struct/Parsing/ParsedSchema.cs index e9bcca71..8ab0338c 100644 --- a/src/wpiutil/Serialization/Struct/Parsing/ParsedSchema.cs +++ b/src/wpiutil/Serialization/Struct/Parsing/ParsedSchema.cs @@ -4,7 +4,7 @@ namespace WPIUtil.Serialization.Struct.Parsing; public sealed class ParsedSchema() { - private List m_declarations = []; + private readonly List m_declarations = []; public ReadOnlySpan Declarations => CollectionsMarshal.AsSpan(m_declarations);