VLink  2.0.0
A high-performance communication middleware
bag_plugin_interface.h File Reference

Unified plugin contract for rewriting bag traffic on both playback (read) and recording (write). More...

#include <cstdint>
#include <string>
#include <utility>
#include "../base/functional.h"
#include "../base/plugin.h"
#include "../impl/types.h"
Include dependency graph for bag_plugin_interface.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  vlink::BagPluginInterface
 Abstract plugin base shared by bag playback and bag recording. More...
 
struct  vlink::BagPluginInterface::VersionInfo
 Build identity returned by get_version_info(). More...
 

Namespaces

 

Detailed Description

Unified plugin contract for rewriting bag traffic on both playback (read) and recording (write).

BagPluginInterface is a dynamic plugin loaded through the VLink Plugin framework and attached either to a BagReader (via BagReader::bind_plugin_interface()) or to a BagWriter (via BagWriter::bind_plugin_interface()). A single class serves both directions; an implementation discovers which side it is bound to through get_direction() and overrides only the hooks for that side.

The two directions are symmetric: each is a frame-forwarding pipeline. The host supplies a downstream sink at bind time and the plugin re-emits every Frame – optionally transformed, dropped, fanned out, or reordered – through that sink. Plugins never touch the raw sink member directly; they emit by calling the single do_callback() helper. Read and write share one callable type (Callback, a const Frame& sink); a plugin overrides the on_read() or on_write() hook for its bound direction.

  • Read (playback). Frames originate inside the reader and flow out to the user. on_read() receives each frame and re-emits it via do_callback(). URL/type remapping is a separate, once-per-URL hook, convert_url_meta(), applied when the bag is opened. On the read side Frame::ser_type / schema_type are empty (query BagReader::get_ser_type() if needed).
  • Write (recording). Frames originate from the caller and flow into the bag. on_write() receives each frame – fully populated with ser_type / schema_type because recording persists them – and re-emits it via do_callback().

Both hooks may forward unchanged, transcode (e.g. record a raw image as compressed JPEG by emitting new Frame::data plus a new ser_type / schema_type), drop a frame (by not emitting), fan a frame out into several, or buffer frames and emit them reordered by their true data-plane time – a sliding-window reorder, identical on both sides, typically built on a BagProcessor.

Plugin contract:

Hook Dir Purpose
get_version_info() both After load: return a populated VersionInfo
bind_direction() both At bind time: stored, observable via get_direction()
register_callback() both At bind time: store the forwarding sink
convert_url_meta() read Once per URL at open: true = keep, false = drop
on_read() read Every replayed frame: re-emit via do_callback()
on_write() write Every frame before persist: re-emit via do_callback()
do_callback() both Forward one frame to the sink (drop = not call)

Lifecycle:

*   read  : load .so -> bind_direction(kRead) -> register_callback -> convert_url_meta (per URL)
*                    -> on_read (per frame) -> do_callback -> callback_ -> user
*   write : load .so -> bind_direction(kWrite) -> register_callback
*                    -> on_write (per frame) -> do_callback -> callback_ -> writer persists
* 
Read-side example (rename a topic on replay)
class MyReadPlugin : public vlink::BagPluginInterface {
public:
VersionInfo get_version_info() const override { return {"my-read", "1.0.0", __DATE__, "", ""}; }
bool convert_url_meta(std::string& url, std::string& ser_type,
vlink::SchemaType& schema_type) override {
if (url.rfind("dds://legacy/", 0) == 0) { url.replace(0, 13, "dds://v2/"); }
(void)ser_type;
(void)schema_type;
return true;
}
void on_read(const vlink::Frame& frame) override {
do_callback(frame); // forward downstream (drop by not calling)
}
};
VLINK_PLUGIN_DECLARE(MyReadPlugin, 1, 0)
#define VLINK_PLUGIN_DECLARE(ImplementType, VersionMajor, VersionMinor)
Emits the extern "C" construction and destruction entry points exported by a plugin module.
Definition: plugin.h:387
Write-side example (sliding-window reorder by true data-plane time before persist)
class MyWritePlugin : public vlink::BagPluginInterface {
public:
MyWritePlugin() {
processor_.register_output_callback([this](const vlink::Frame& frame) { do_callback(frame); });
}
VersionInfo get_version_info() const override { return {"my-write", "1.0.0", __DATE__, "", ""}; }
void on_write(const vlink::Frame& frame) override {
const int64_t data_timestamp = parse_header_time(frame.data); // plugin extracts the data-plane time
processor_.push(data_timestamp, frame); // reorder by data_timestamp; emit via
}
void flush() override { processor_.flush(); } // drain the buffered tail at teardown
private:
vlink::BagProcessor processor_;
};
VLINK_PLUGIN_DECLARE(MyWritePlugin, 1, 0)