[wpiutil, ntcore] Add structured data support (#5391)

This adds support for two serialization formats for complex data types:

- Protobuf for complex objects with variable length internals that need forward and backward wire compatibility (lower speed, more flexible)
- Raw struct (ByteBuffer-style) for fixed-length objects (higher speed, less flexible)

Deserialization can be done either by creating a new object (for immutable objects) or overwriting the contents of an existing object (for mutable objects).

Implementing classes should provide inner classes that implement the Protobuf or Struct interface (in Java) or specialize the wpi::Protobuf or wpi::Struct struct (in C++). It is possible for classes to implement both. If the class itself does not implement serialization, it's possible for third parties/users to provide an implementation instead.

Uses the Google protobuf implementation for C++ and the QuickBuffers alternative protobuf implementation for Java.
This commit is contained in:
Peter Johnson
2023-10-19 21:41:47 -07:00
committed by GitHub
parent ecb7cfa9ef
commit cf54d9ccb7
133 changed files with 13506 additions and 90 deletions

View File

@@ -7,6 +7,8 @@
#include <Eigen/Core>
#include <wpi/SymbolExports.h>
#include <wpi/json_fwd.h>
#include <wpi/protobuf/Protobuf.h>
#include <wpi/struct/Struct.h>
#include "frc/geometry/Quaternion.h"
#include "frc/geometry/Rotation2d.h"
@@ -194,3 +196,31 @@ WPILIB_DLLEXPORT
void from_json(const wpi::json& json, Rotation3d& rotation);
} // namespace frc
template <>
struct wpi::Struct<frc::Rotation3d> {
static constexpr std::string_view kTypeString = "struct:Rotation3d";
static constexpr size_t kSize = wpi::Struct<frc::Quaternion>::kSize;
static constexpr std::string_view kSchema = "Quaternion q";
static frc::Rotation3d Unpack(std::span<const uint8_t, kSize> data) {
return frc::Rotation3d{wpi::UnpackStruct<frc::Quaternion, 0>(data)};
}
static void Pack(std::span<uint8_t, kSize> data,
const frc::Rotation3d& value) {
wpi::PackStruct<0>(data, value.GetQuaternion());
}
static void ForEachNested(
std::invocable<std::string_view, std::string_view> auto fn) {
wpi::ForEachStructSchema<frc::Quaternion>(fn);
}
};
static_assert(wpi::HasNestedStruct<frc::Rotation3d>);
template <>
struct WPILIB_DLLEXPORT wpi::Protobuf<frc::Rotation3d> {
static google::protobuf::Message* New(google::protobuf::Arena* arena);
static frc::Rotation3d Unpack(const google::protobuf::Message& msg);
static void Pack(google::protobuf::Message* msg,
const frc::Rotation3d& value);
};