From 7c8a36f3ebd65bd725bd3681bb4d7cc8cd0d8e11 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sat, 1 Jun 2024 11:58:53 -0700 Subject: [PATCH] [wpiutil] Add Struct and Protobuf clone and immutable checks (#6686) --- .../math/geometry/proto/Pose2dProto.java | 5 +++ .../math/geometry/proto/Pose3dProto.java | 5 +++ .../math/geometry/proto/QuaternionProto.java | 5 +++ .../math/geometry/proto/Rotation2dProto.java | 5 +++ .../math/geometry/proto/Rotation3dProto.java | 5 +++ .../math/geometry/proto/Transform2dProto.java | 5 +++ .../math/geometry/proto/Transform3dProto.java | 5 +++ .../geometry/proto/Translation2dProto.java | 5 +++ .../geometry/proto/Translation3dProto.java | 5 +++ .../math/geometry/struct/Pose2dStruct.java | 5 +++ .../math/geometry/struct/Pose3dStruct.java | 5 +++ .../geometry/struct/QuaternionStruct.java | 5 +++ .../geometry/struct/Rotation2dStruct.java | 5 +++ .../geometry/struct/Rotation3dStruct.java | 5 +++ .../geometry/struct/Transform2dStruct.java | 5 +++ .../geometry/struct/Transform3dStruct.java | 5 +++ .../geometry/struct/Translation2dStruct.java | 5 +++ .../geometry/struct/Translation3dStruct.java | 5 +++ .../edu/wpi/first/util/protobuf/Protobuf.java | 33 +++++++++++++++++++ .../edu/wpi/first/util/struct/Struct.java | 33 +++++++++++++++++++ 20 files changed, 156 insertions(+) diff --git a/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Pose2dProto.java b/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Pose2dProto.java index 7921100d6e..9dcfb34f8a 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Pose2dProto.java +++ b/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Pose2dProto.java @@ -44,4 +44,9 @@ public class Pose2dProto implements Protobuf { Translation2d.proto.pack(msg.getMutableTranslation(), value.getTranslation()); Rotation2d.proto.pack(msg.getMutableRotation(), value.getRotation()); } + + @Override + public boolean isImmutable() { + return true; + } } diff --git a/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Pose3dProto.java b/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Pose3dProto.java index 69d6ba2926..d908a46f94 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Pose3dProto.java +++ b/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Pose3dProto.java @@ -44,4 +44,9 @@ public class Pose3dProto implements Protobuf { Translation3d.proto.pack(msg.getMutableTranslation(), value.getTranslation()); Rotation3d.proto.pack(msg.getMutableRotation(), value.getRotation()); } + + @Override + public boolean isImmutable() { + return true; + } } diff --git a/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/QuaternionProto.java b/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/QuaternionProto.java index c464ba270c..51cd3d95e1 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/QuaternionProto.java +++ b/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/QuaternionProto.java @@ -37,4 +37,9 @@ public class QuaternionProto implements Protobuf msg.setY(value.getY()); msg.setZ(value.getZ()); } + + @Override + public boolean isImmutable() { + return true; + } } diff --git a/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Rotation2dProto.java b/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Rotation2dProto.java index 98ad5c7bcf..e0b168a171 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Rotation2dProto.java +++ b/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Rotation2dProto.java @@ -34,4 +34,9 @@ public class Rotation2dProto implements Protobuf public void pack(ProtobufRotation2d msg, Rotation2d value) { msg.setValue(value.getRadians()); } + + @Override + public boolean isImmutable() { + return true; + } } diff --git a/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Rotation3dProto.java b/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Rotation3dProto.java index 9c9b01a93b..28ace95503 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Rotation3dProto.java +++ b/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Rotation3dProto.java @@ -40,4 +40,9 @@ public class Rotation3dProto implements Protobuf public void pack(ProtobufRotation3d msg, Rotation3d value) { Quaternion.proto.pack(msg.getMutableQ(), value.getQuaternion()); } + + @Override + public boolean isImmutable() { + return true; + } } diff --git a/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Transform2dProto.java b/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Transform2dProto.java index ecc05287cf..8714a7044b 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Transform2dProto.java +++ b/wpimath/src/main/java/edu/wpi/first/math/geometry/proto/Transform2dProto.java @@ -44,4 +44,9 @@ public class Transform2dProto implements Protobuf { Translation2d.struct.pack(bb, value.getTranslation()); Rotation2d.struct.pack(bb, value.getRotation()); } + + @Override + public boolean isImmutable() { + return true; + } } diff --git a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Pose3dStruct.java b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Pose3dStruct.java index db380f6f90..8e24818915 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Pose3dStruct.java +++ b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Pose3dStruct.java @@ -48,4 +48,9 @@ public class Pose3dStruct implements Struct { Translation3d.struct.pack(bb, value.getTranslation()); Rotation3d.struct.pack(bb, value.getRotation()); } + + @Override + public boolean isImmutable() { + return true; + } } diff --git a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/QuaternionStruct.java b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/QuaternionStruct.java index fec8452b0e..93b8598414 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/QuaternionStruct.java +++ b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/QuaternionStruct.java @@ -45,4 +45,9 @@ public class QuaternionStruct implements Struct { bb.putDouble(value.getY()); bb.putDouble(value.getZ()); } + + @Override + public boolean isImmutable() { + return true; + } } diff --git a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Rotation2dStruct.java b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Rotation2dStruct.java index b22e3d15eb..8dc36462a8 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Rotation2dStruct.java +++ b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Rotation2dStruct.java @@ -39,4 +39,9 @@ public class Rotation2dStruct implements Struct { public void pack(ByteBuffer bb, Rotation2d value) { bb.putDouble(value.getRadians()); } + + @Override + public boolean isImmutable() { + return true; + } } diff --git a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Rotation3dStruct.java b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Rotation3dStruct.java index 4184990a22..3d9fba0a25 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Rotation3dStruct.java +++ b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Rotation3dStruct.java @@ -45,4 +45,9 @@ public class Rotation3dStruct implements Struct { public void pack(ByteBuffer bb, Rotation3d value) { Quaternion.struct.pack(bb, value.getQuaternion()); } + + @Override + public boolean isImmutable() { + return true; + } } diff --git a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Transform2dStruct.java b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Transform2dStruct.java index 298d6db4e2..5e3bb30505 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Transform2dStruct.java +++ b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Transform2dStruct.java @@ -48,4 +48,9 @@ public class Transform2dStruct implements Struct { Translation2d.struct.pack(bb, value.getTranslation()); Rotation2d.struct.pack(bb, value.getRotation()); } + + @Override + public boolean isImmutable() { + return true; + } } diff --git a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Transform3dStruct.java b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Transform3dStruct.java index 2ad5bc153b..6e02e9e527 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Transform3dStruct.java +++ b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Transform3dStruct.java @@ -48,4 +48,9 @@ public class Transform3dStruct implements Struct { Translation3d.struct.pack(bb, value.getTranslation()); Rotation3d.struct.pack(bb, value.getRotation()); } + + @Override + public boolean isImmutable() { + return true; + } } diff --git a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Translation2dStruct.java b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Translation2dStruct.java index aac179aacb..643090a308 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Translation2dStruct.java +++ b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Translation2dStruct.java @@ -41,4 +41,9 @@ public class Translation2dStruct implements Struct { bb.putDouble(value.getX()); bb.putDouble(value.getY()); } + + @Override + public boolean isImmutable() { + return true; + } } diff --git a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Translation3dStruct.java b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Translation3dStruct.java index f4e10299fd..c4e6eeda97 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Translation3dStruct.java +++ b/wpimath/src/main/java/edu/wpi/first/math/geometry/struct/Translation3dStruct.java @@ -43,4 +43,9 @@ public class Translation3dStruct implements Struct { bb.putDouble(value.getY()); bb.putDouble(value.getZ()); } + + @Override + public boolean isImmutable() { + return true; + } } diff --git a/wpiutil/src/main/java/edu/wpi/first/util/protobuf/Protobuf.java b/wpiutil/src/main/java/edu/wpi/first/util/protobuf/Protobuf.java index b77db7acae..4501ebc678 100644 --- a/wpiutil/src/main/java/edu/wpi/first/util/protobuf/Protobuf.java +++ b/wpiutil/src/main/java/edu/wpi/first/util/protobuf/Protobuf.java @@ -97,6 +97,39 @@ public interface Protobuf> { throw new UnsupportedOperationException("object does not support unpackInto"); } + /** + * Returns whether or not objects are immutable. Immutable objects must also be comparable using + * the equals() method. Default implementation returns false. + * + * @return True if object is immutable + */ + default boolean isImmutable() { + return false; + } + + /** + * Returns whether or not objects are cloneable using the clone() method. Clonable objects must + * also be comparable using the equals() method. Default implementation returns false. + * + * @return True if object is clonable + */ + default boolean isCloneable() { + return false; + } + + /** + * Creates a (deep) clone of the object. May also return the object directly if the object is + * immutable. Default implementation throws CloneNotSupportedException. Typically this should be + * implemented by implementing clone() on the object itself, and calling it from here. + * + * @param obj object to clone + * @return Clone of object (if immutable, may be same object) + * @throws CloneNotSupportedException if clone not supported + */ + default T clone(T obj) throws CloneNotSupportedException { + throw new CloneNotSupportedException(); + } + /** * Loops over all protobuf descriptors including nested/referenced descriptors. * diff --git a/wpiutil/src/main/java/edu/wpi/first/util/struct/Struct.java b/wpiutil/src/main/java/edu/wpi/first/util/struct/Struct.java index 630ef8c0c1..99072ecfd6 100644 --- a/wpiutil/src/main/java/edu/wpi/first/util/struct/Struct.java +++ b/wpiutil/src/main/java/edu/wpi/first/util/struct/Struct.java @@ -113,4 +113,37 @@ public interface Struct { default void unpackInto(T out, ByteBuffer bb) { throw new UnsupportedOperationException("object does not support unpackInto"); } + + /** + * Returns whether or not objects are immutable. Immutable objects must also be comparable using + * the equals() method. Default implementation returns false. + * + * @return True if object is immutable + */ + default boolean isImmutable() { + return false; + } + + /** + * Returns whether or not objects are cloneable using the clone() method. Clonable objects must + * also be comparable using the equals() method. Default implementation returns false. + * + * @return True if object is clonable + */ + default boolean isCloneable() { + return false; + } + + /** + * Creates a (deep) clone of the object. May also return the object directly if the object is + * immutable. Default implementation throws CloneNotSupportedException. Typically this should be + * implemented by implementing clone() on the object itself, and calling it from here. + * + * @param obj object to clone + * @return Clone of object (if immutable, may be same object) + * @throws CloneNotSupportedException if clone not supported + */ + default T clone(T obj) throws CloneNotSupportedException { + throw new CloneNotSupportedException(); + } }