VLink 2.0.0
A high-performance communication middleware
Loading...
Searching...
No Matches
message_convert_plugin.h File Reference

Plugin interface for VLink/webviz message conversion across visualization backends. More...

#include <string>
#include "../base/bytes.h"
#include "../base/plugin.h"
#include "../impl/types.h"
Include dependency graph for message_convert_plugin.h:

Go to the source code of this file.

Classes

 Describes a frontend-advertised publish channel. More...
 VLink publish destination resolved for an inbound frontend message. More...
 Abstract interface for VLink/webviz message conversion plugins supporting multiple visualization backends. More...

Namespaces

Enumerations

enum class  vlink::ConvertTarget : uint8_t { vlink::kFoxglove = 0 , vlink::kRerun = 1 }
 Identifies the visualization backend that the plugin is converting for. More...

Detailed Description

Plugin interface for VLink/webviz message conversion across visualization backends.

MessageConvertPlugin allows users to implement custom VLink/webviz message conversion logic in a shared library plugin. The plugin receives raw VLink message bytes (Protobuf, FlatBuffers, CDR, POD, or any custom serialisation) and produces a backend-specific payload along with schema/type metadata.

This interface has zero third-party dependencies – it only uses VLink base types (Bytes) and standard C++ types, making it easy to implement in external projects without linking against Protobuf, FlatBuffers, Rerun SDK, or JSON libraries.

A single plugin can support multiple visualization backends by checking the ConvertTarget parameter in each method. The plugin coexists with JSON-based VLink-to-webviz mapping files. When both are present, the plugin is tried first; if it returns false for a given type, the JSON mapping pipeline takes over.

Supported targets
Target Payload format type_name meaning
kFoxglove FlatBuffer / Protobuf binary Foxglove schema name
kRerun JSON string describing components Rerun archetype name
Rerun JSON payload format
When targeting Rerun, the plugin should produce a UTF-8 JSON string as the payload. The JSON object describes the Rerun archetype components. Each archetype has its own expected fields:
// Points3D example:
{
"positions": [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]],
"colors": [[255, 0, 0, 255], [0, 255, 0, 255]],
"radii": [0.1, 0.2]
}
// EncodedImage example (binary data is base64-encoded):
{
"media_type": "image/jpeg",
"data_base64": "<base64-encoded image bytes>"
}
// GeoPoints example:
{
"lat_deg": [37.7749, 37.7750],
"lon_deg": [-122.4194, -122.4195]
}
// TextLog example:
{
"text": "Hello world",
"level": "INFO"
}
// Scalars example:
{
"value": 3.14
}
// Transform3D example:
{
"translation": [1.0, 2.0, 3.0],
"rotation_quat": [0.0, 0.0, 0.0, 1.0]
}
// Boxes3D example:
{
"half_sizes": [[1.0, 2.0, 3.0]],
"centers": [[0.0, 0.0, 0.0]],
"quaternions": [[0.0, 0.0, 0.0, 1.0]],
"colors": [[255, 0, 0, 255]],
"labels": ["box1"]
}
// Pinhole example:
{
"image_from_camera": [[fx, 0, cx], [0, fy, cy], [0, 0, 1]],
"resolution": [1920, 1080]
}

Binary archetypes should carry their raw bytes in a data_base64 string. Currently the built-in Rerun JSON bridge supports this for EncodedImage, Image, DepthImage, SegmentationImage, EncodedDepthImage, Asset3D, AssetVideo, and Tensor. Image, DepthImage, and SegmentationImage also require width/height (or resolution). Tensor additionally requires shape and may provide dim_names. Direct VLink-to-Rerun mappings still cover a broader set of archetypes than the plugin JSON bridge.

Plugin lifecycle
  1. init() is called once after loading, with an optional config string.
  2. can_convert() is called for each discovered VLink serialisation type (with the target backend) to determine if the plugin handles it.
  3. get_schema_info() is called once per type to register the channel/archetype.
  4. convert() is called for every incoming message on matched types.
  5. The plugin is destroyed when the server shuts down.
Example implementation (supports both Foxglove and Rerun)
class MyConvertPlugin : public vlink::MessageConvertPlugin {
VLINK_PLUGIN_REGISTER(MessageConvertPlugin)
public:
bool init(const std::string& config) override {
// Parse config, load schemas, etc.
return true;
}
bool can_convert(const std::string& vlink_ser, ConvertTarget target) override {
if (vlink_ser != "my_pkg.MyMessage") return false;
// Support both backends
return target == ConvertTarget::kFoxglove || target == ConvertTarget::kRerun;
}
bool get_schema_info(const std::string& vlink_ser, ConvertTarget target,
std::string& type_name, std::string& encoding,
std::string& schema_encoding,
std::string& schema_data) override {
if (target == ConvertTarget::kFoxglove) {
type_name = "foxglove.LocationFix";
encoding = "flatbuffers";
schema_encoding = "flatbuffers";
// schema_data = binary FBS schema bytes
} else if (target == ConvertTarget::kRerun) {
type_name = "GeoPoints";
encoding = "json";
// schema_encoding and schema_data are unused for Rerun
}
return true;
}
bool convert(const std::string& vlink_ser, const vlink::Bytes& raw,
ConvertTarget target, vlink::Bytes& payload) override {
if (target == ConvertTarget::kFoxglove) {
// Build Foxglove FlatBuffer payload
} else if (target == ConvertTarget::kRerun) {
// Build JSON: {"lat_deg":[37.77], "lon_deg":[-122.41]}
std::string json = R"({"lat_deg":[37.77],"lon_deg":[-122.41]})";
payload = vlink::Bytes::deep_copy(json.data(), json.size());
}
return true;
}
};
VLINK_PLUGIN_DECLARE(MyConvertPlugin, 4, 0)
Plugin interface for VLink/webviz message conversion across visualization backends.
#define VLINK_PLUGIN_DECLARE(ImplementType, VersionMajor, VersionMinor)
Declares a plugin creation and destruction interface.
Definition plugin.h:380
#define VLINK_PLUGIN_REGISTER(InterfaceType)
Macro to register a plugin, automatically deriving its ID from the interface type name.
Definition plugin.h:343