From ee72d1a831630d36717d43686c9b8b993466f9fe Mon Sep 17 00:00:00 2001 From: Thad House Date: Tue, 13 Feb 2024 17:13:01 -0800 Subject: [PATCH] Slightly redo Protobuf --- src/ntcore/NetworkTableInstance.cs | 2 +- src/ntcore/ProtobufTopic.cs | 4 +- src/wpimath/Geometry/Pose2d.cs | 2 +- src/wpimath/Geometry/Quaternion.cs | 2 +- src/wpimath/Geometry/Rotation2d.cs | 2 +- src/wpimath/Geometry/Rotation3d.cs | 2 +- src/wpimath/Geometry/Translation2d.cs | 2 +- src/wpimath/Geometry/Twist2d.cs | 2 +- src/wpimath/Geometry/Twist3d.cs | 2 +- src/wpiutil/Logging/DataLog.cs | 2 +- src/wpiutil/Logging/ProtobufLogEntry.cs | 4 +- .../Serialization/Protobuf/IProtobuf.cs | 41 ++++++++++--------- .../Protobuf/IProtobufSerializable.cs | 4 +- .../Serialization/Protobuf/ProtobufBuffer.cs | 12 +++--- test/wpimath.test/GenericHelpers.cs | 6 +-- 15 files changed, 46 insertions(+), 43 deletions(-) diff --git a/src/ntcore/NetworkTableInstance.cs b/src/ntcore/NetworkTableInstance.cs index e1772231..bbd7ea8e 100644 --- a/src/ntcore/NetworkTableInstance.cs +++ b/src/ntcore/NetworkTableInstance.cs @@ -646,7 +646,7 @@ public void AddSchema(IStructBase proto) AddSchemaImpl(proto, []); } - public void AddSchema(IProtobufBase proto) + public void AddSchema(IProtobuf proto) { proto.ForEachDescriptor(HasSchema, (typeString, schema) => AddSchema(typeString, "proto:FileDescriptorProto", schema)); } diff --git a/src/ntcore/ProtobufTopic.cs b/src/ntcore/ProtobufTopic.cs index 7235e2a8..c2b91f93 100644 --- a/src/ntcore/ProtobufTopic.cs +++ b/src/ntcore/ProtobufTopic.cs @@ -9,7 +9,7 @@ namespace NetworkTables; public sealed class ProtobufTopic : Topic, IEquatable?>, IEqualityOperators?, ProtobufTopic?, bool> where T : IProtobufSerializable { - public IProtobuf Proto { get; } = T.Proto; + public IGenericProtobuf Proto { get; } = T.ProtoGeneric; private ProtobufTopic(Topic topic) : base(topic.Instance, topic.Handle) { @@ -57,7 +57,7 @@ public override bool Equals(object? obj) public bool Equals(ProtobufTopic? other) { return other is not null && - EqualityComparer>.Default.Equals(Proto, other.Proto); + EqualityComparer>.Default.Equals(Proto, other.Proto); } public override int GetHashCode() diff --git a/src/wpimath/Geometry/Pose2d.cs b/src/wpimath/Geometry/Pose2d.cs index 4fe3d76f..9bd87a7a 100644 --- a/src/wpimath/Geometry/Pose2d.cs +++ b/src/wpimath/Geometry/Pose2d.cs @@ -71,7 +71,7 @@ public partial class Pose2dJsonContext : JsonSerializerContext { public static IStruct Struct { get; } = new Pose2dStruct(); public static IProtobuf Proto { get; } = new Pose2dProto(); - static IProtobuf IProtobufSerializable.Proto { get; } = Proto.UntypedProto; + static IGenericProtobuf IProtobufSerializable.ProtoGeneric => Proto; [JsonInclude] [JsonPropertyName("translation")] diff --git a/src/wpimath/Geometry/Quaternion.cs b/src/wpimath/Geometry/Quaternion.cs index 937f88fc..d2d552d3 100644 --- a/src/wpimath/Geometry/Quaternion.cs +++ b/src/wpimath/Geometry/Quaternion.cs @@ -78,7 +78,7 @@ public partial class QuaternionJsonContext : JsonSerializerContext { public static IStruct Struct { get; } = new QuaternionStruct(); public static IProtobuf Proto { get; } = new QuaternionProto(); - static IProtobuf IProtobufSerializable.Proto => Proto.UntypedProto; + static IGenericProtobuf IProtobufSerializable.ProtoGeneric => Proto; [JsonInclude] public double W { get; init; } diff --git a/src/wpimath/Geometry/Rotation2d.cs b/src/wpimath/Geometry/Rotation2d.cs index 5aadf3e1..133fd81c 100644 --- a/src/wpimath/Geometry/Rotation2d.cs +++ b/src/wpimath/Geometry/Rotation2d.cs @@ -69,7 +69,7 @@ public partial class Rotation2dJsonContext : JsonSerializerContext { public static IStruct Struct { get; } = new Rotation2dStruct(); public static IProtobuf Proto { get; } = new Rotation2dProto(); - static IProtobuf IProtobufSerializable.Proto => Proto.UntypedProto; + static IGenericProtobuf IProtobufSerializable.ProtoGeneric => Proto; public Rotation2d(Angle angle) { diff --git a/src/wpimath/Geometry/Rotation3d.cs b/src/wpimath/Geometry/Rotation3d.cs index 0c7a284f..b45743f7 100644 --- a/src/wpimath/Geometry/Rotation3d.cs +++ b/src/wpimath/Geometry/Rotation3d.cs @@ -73,7 +73,7 @@ public partial class Rotation3dJsonContext : JsonSerializerContext { public static IStruct Struct { get; } = new Rotation3dStruct(); public static IProtobuf Proto { get; } = new Rotation3dProto(); - static IProtobuf IProtobufSerializable.Proto => Proto.UntypedProto; + static IGenericProtobuf IProtobufSerializable.ProtoGeneric => Proto; [JsonInclude] [JsonPropertyName("quaternion")] diff --git a/src/wpimath/Geometry/Translation2d.cs b/src/wpimath/Geometry/Translation2d.cs index 49f2b492..b9d5243d 100644 --- a/src/wpimath/Geometry/Translation2d.cs +++ b/src/wpimath/Geometry/Translation2d.cs @@ -72,7 +72,7 @@ public partial class Translation2dJsonContext : JsonSerializerContext { public static IStruct Struct { get; } = new Translation2dStruct(); public static IProtobuf Proto { get; } = new Translation2dProto(); - static IProtobuf IProtobufSerializable.Proto => Proto.UntypedProto; + static IGenericProtobuf IProtobufSerializable.ProtoGeneric => Proto; [JsonIgnore] public Length X { get; } diff --git a/src/wpimath/Geometry/Twist2d.cs b/src/wpimath/Geometry/Twist2d.cs index 55b260fc..eb2d0f92 100644 --- a/src/wpimath/Geometry/Twist2d.cs +++ b/src/wpimath/Geometry/Twist2d.cs @@ -72,7 +72,7 @@ public partial class Twist2dJsonContext : JsonSerializerContext { public static IStruct Struct { get; } = new Twist2dStruct(); public static IProtobuf Proto { get; } = new Twist2dProto(); - static IProtobuf IProtobufSerializable.Proto => Proto.UntypedProto; + static IGenericProtobuf IProtobufSerializable.ProtoGeneric => Proto; [JsonIgnore] public Length Dx { get; init; } diff --git a/src/wpimath/Geometry/Twist3d.cs b/src/wpimath/Geometry/Twist3d.cs index d25ed20d..443d1ef8 100644 --- a/src/wpimath/Geometry/Twist3d.cs +++ b/src/wpimath/Geometry/Twist3d.cs @@ -84,7 +84,7 @@ public partial class Twist3dJsonContext : JsonSerializerContext { public static IStruct Struct { get; } = new Twist3dStruct(); public static IProtobuf Proto { get; } = new Twist3dProto(); - static IProtobuf IProtobufSerializable.Proto => Proto.UntypedProto; + static IGenericProtobuf IProtobufSerializable.ProtoGeneric => Proto; [JsonIgnore] public Length Dx { get; init; } diff --git a/src/wpiutil/Logging/DataLog.cs b/src/wpiutil/Logging/DataLog.cs index 473b9584..fada7c0a 100644 --- a/src/wpiutil/Logging/DataLog.cs +++ b/src/wpiutil/Logging/DataLog.cs @@ -113,7 +113,7 @@ public void AddSchema(IStructBase value, long timestamp = 0) AddSchemaImpl(value, timestamp == 0 ? (long)TimestampNative.Now() : timestamp, []); } - public void AddSchema(IProtobufBase proto, long timestamp = 0) + public void AddSchema(IProtobuf proto, long timestamp = 0) { long actualTimestamp = timestamp == 0 ? (long)TimestampNative.Now() : timestamp; proto.ForEachDescriptor(HasSchema, (typeString, schema) => diff --git a/src/wpiutil/Logging/ProtobufLogEntry.cs b/src/wpiutil/Logging/ProtobufLogEntry.cs index 96d0985b..cec5d7ad 100644 --- a/src/wpiutil/Logging/ProtobufLogEntry.cs +++ b/src/wpiutil/Logging/ProtobufLogEntry.cs @@ -7,14 +7,14 @@ public sealed class ProtobufLogEntry : DataLogEntry where T : IProtobufSerial private readonly ProtobufBuffer m_storage = new(); private readonly object m_lockObject = new(); - private ProtobufLogEntry(DataLog log, string name, IProtobufBase proto, string metadata = "", long timestamp = 0) : base(log, name, proto.TypeString, metadata, timestamp) + private ProtobufLogEntry(DataLog log, string name, IProtobuf proto, string metadata = "", long timestamp = 0) : base(log, name, proto.TypeString, metadata, timestamp) { log.AddSchema(proto, timestamp); } public ProtobufLogEntry Create(DataLog log, string name, string metadata = "", long timestamp = 0) { - return new ProtobufLogEntry(log, name, T.Proto, metadata, timestamp); + return new ProtobufLogEntry(log, name, T.ProtoGeneric, metadata, timestamp); } public void Append(T value, long timestamp = 0) diff --git a/src/wpiutil/Serialization/Protobuf/IProtobuf.cs b/src/wpiutil/Serialization/Protobuf/IProtobuf.cs index f87a9ab9..1a959ab5 100644 --- a/src/wpiutil/Serialization/Protobuf/IProtobuf.cs +++ b/src/wpiutil/Serialization/Protobuf/IProtobuf.cs @@ -4,11 +4,11 @@ namespace WPIUtil.Serialization.Protobuf; -public interface IProtobufBase +public interface IProtobuf { string TypeString => $"proto:{Descriptor.FullName}"; MessageDescriptor Descriptor { get; } - IProtobufBase[] Nested => []; + IProtobuf[] Nested => []; void ForEachDescriptor(Func exists, Action fn) { @@ -30,35 +30,38 @@ private static void ForEachDescriptorImpl(FileDescriptor desc, Func : IProtobufBase +public interface IGenericProtobuf : IProtobuf { - IMessage CreateMessage(); + IMessage GenericCreateMessage(); - T Unpack(IMessage msg); + T GenericUnpack(IMessage msg); - void Pack(IMessage msg, T value); + void GenericPack(IMessage msg, T value); - void UnpackInto(ref T value, IMessage msg); + void GenericUnpackInto(ref T value, IMessage msg); } -public interface IProtobuf : IProtobufBase where MessageType : IMessage +public interface IProtobuf : IGenericProtobuf where MessageType : IMessage { - internal class ProtobufWrapper(IProtobuf proto) : IProtobuf + IMessage IGenericProtobuf.GenericCreateMessage() { - private readonly IProtobuf m_proto = proto; - - public MessageDescriptor Descriptor => m_proto.Descriptor; - - public IMessage CreateMessage() => m_proto.CreateMessage(); - - public void Pack(IMessage msg, T value) => m_proto.Pack((MessageType)msg, value); + return CreateMessage(); + } - public T Unpack(IMessage msg) => m_proto.Unpack((MessageType)msg); + T IGenericProtobuf.GenericUnpack(IMessage msg) + { + return Unpack((MessageType)msg); + } - public void UnpackInto(ref T value, IMessage msg) => m_proto.UnpackInto(ref value, (MessageType)msg); + void IGenericProtobuf.GenericPack(IMessage msg, T value) + { + Pack((MessageType)msg, value); } - public IProtobuf UntypedProto => new ProtobufWrapper(this); + void IGenericProtobuf.GenericUnpackInto(ref T value, IMessage msg) + { + UnpackInto(ref value, (MessageType)msg); + } MessageType CreateMessage(); diff --git a/src/wpiutil/Serialization/Protobuf/IProtobufSerializable.cs b/src/wpiutil/Serialization/Protobuf/IProtobufSerializable.cs index febbe802..71167d08 100644 --- a/src/wpiutil/Serialization/Protobuf/IProtobufSerializable.cs +++ b/src/wpiutil/Serialization/Protobuf/IProtobufSerializable.cs @@ -4,10 +4,10 @@ namespace WPIUtil.Serialization.Protobuf; public interface IProtobufSerializable : IWPISerializable { - public static abstract IProtobuf Proto { get; } + public static abstract IGenericProtobuf ProtoGeneric { get; } } public interface IProtobufSerializable : IProtobufSerializable where TProto : IMessage { - public static new abstract IProtobuf Proto { get; } + public static abstract IProtobuf Proto { get; } } diff --git a/src/wpiutil/Serialization/Protobuf/ProtobufBuffer.cs b/src/wpiutil/Serialization/Protobuf/ProtobufBuffer.cs index 034815e1..3bbe73b4 100644 --- a/src/wpiutil/Serialization/Protobuf/ProtobufBuffer.cs +++ b/src/wpiutil/Serialization/Protobuf/ProtobufBuffer.cs @@ -7,17 +7,17 @@ public struct ProtobufBuffer where T : IProtobufSerializable { public ProtobufBuffer() { - Proto = T.Proto; - m_msg = Proto.CreateMessage(); + Proto = T.ProtoGeneric; + m_msg = Proto.GenericCreateMessage(); } - public IProtobuf Proto { get; } + public IGenericProtobuf Proto { get; } public readonly string TypeString => Proto.TypeString; public ReadOnlySpan Write(T value) { - Proto.Pack(m_msg, value); + Proto.GenericPack(m_msg, value); int size = m_msg.CalculateSize(); if (size > m_buf.Length) { @@ -30,13 +30,13 @@ public ReadOnlySpan Write(T value) public readonly T Read(ReadOnlySpan buffer) { m_msg.MergeFrom(buffer); - return Proto.Unpack(m_msg); + return Proto.GenericUnpack(m_msg); } public readonly void ReadInto(ref T output, ReadOnlySpan buffer) { m_msg.MergeFrom(buffer); - Proto.UnpackInto(ref output, m_msg); + Proto.GenericUnpackInto(ref output, m_msg); } private readonly IMessage m_msg; diff --git a/test/wpimath.test/GenericHelpers.cs b/test/wpimath.test/GenericHelpers.cs index aba49ef2..6ee0d389 100644 --- a/test/wpimath.test/GenericHelpers.cs +++ b/test/wpimath.test/GenericHelpers.cs @@ -16,9 +16,9 @@ public static T StructRoundTrip(T start) where T : IStructSerializable public static T ProtoRoundTrip(T start) where T : IProtobufSerializable { - var proto = T.Proto.CreateMessage(); - T.Proto.Pack(proto, start); - return T.Proto.Unpack(proto); + var proto = T.ProtoGeneric.GenericCreateMessage(); + T.ProtoGeneric.GenericPack(proto, start); + return T.ProtoGeneric.GenericUnpack(proto); } public static T ProtoTypedRoundTrip(T start) where T : IProtobufSerializable where U : IMessage