proton_cpp
proton_cpp is a C++ extension of proton_core. Using the same principles and concepts as proton_core, proton_cpp provides type-safe access to the Node Manager and Signal Registry API's, as well as runtime generation of the node and registry via feature flags.
In its base form without any feature flags set, proton_cpp can be used in embedded projects as it does not use any dynamic allocation, exceptions, RTTI, or smart pointers.
Accessor Functions
proton_cpp uses the same registry structs from proton_core. But to provide more ergonomic wrapping around the C API, non-owning accessor classes exist to read and write to the Registry, as well as updating the Node Manager
Signal Access
proton_cpp provides overload methods via the SignalAccess class for better shorthand when getting/setting Signal values from the Registry
constexpr explicit SignalAccess(proton_registry_t * registry) noexcept : registry_(registry) {}
proton_status_e get(uint32_t id, double & out) const noexcept;
proton_status_e set(uint32_t id, double value) noexcept;
proton_status_e get(uint32_t id, float & out) const noexcept;
proton_status_e set(uint32_t id, float value) noexcept;
proton_status_e get(uint32_t id, int32_t & out) const noexcept;
proton_status_e set(uint32_t id, int32_t value) noexcept;
proton_status_e get(uint32_t id, int64_t & out) const noexcept;
proton_status_e set(uint32_t id, int64_t value) noexcept;
proton_status_e get(uint32_t id, uint32_t & out) const noexcept;
proton_status_e set(uint32_t id, uint32_t value) noexcept;
proton_status_e get(uint32_t id, uint64_t & out) const noexcept;
proton_status_e set(uint32_t id, uint64_t value) noexcept;
proton_status_e get(uint32_t id, bool & out) const noexcept;
proton_status_e set(uint32_t id, bool value) noexcept;
proton_status_e get(uint32_t id, char * buf, size_t cap, size_t & len) const noexcept;
proton_status_e set(uint32_t id, const char * buf, size_t len) const noexcept;
proton_status_e get(uint32_t id, uint8_t * buf, size_t cap, size_t & len) const noexcept;
proton_status_e set(uint32_t id, const uint8_t * buf, size_t len) const noexcept;
And can be used via the following pattern:
double value;
SignalAccess access(&g_proton_registry);
proton_status_e status = access.get(PROTON_SIGNAL_DEFAULT_DOUBLE_ID, value);
status = access.set(PROTON_SIGNAL_DEFAULT_DOUBLE_ID, 1.111);
Templated Signal access on a specific ID can be arranged by the Signal<T> class
Signal<double> signal(&g_proton_registry, PROTON_SIGNAL_DEFAULT_DOUBLE_ID);
double value;
proton_status_e status = signal.get(value);
status = signal.set(1.111);
Feature Flags
- PROTON_ENABLE_ALLOC
- Allow for
Signal<std::string>andSignal<std::vector<uint8_t>>to representstringandbytessignals. - Enables RTTI to enable dynamic casting a
SignalBaseto aSignal<T>via theas()method
- Allow for
SignalBase sig_base(&g_proton_registry, PROTON_SIGNAL_DEFAULT_DOUBLE_ID);
Signal<double> sig_double = sig_base.as<double>();
- C++20 and up
- Convenience methods for
bytesSignals usingstd::span<uint8_t>
- Convenience methods for
Bundle Access
Bundle functionality is largely a thin wrapper over the Bundle API's in proton_core with some ergonomics
explicit BundleAccess(proton_registry_t * registry, uint32_t id) noexcept;
uint32_t id() const noexcept { return id_; }
const bundle_desc_t * descriptor() const noexcept;
void set_period(uint32_t period_ms) noexcept;
void set_callback(proton_bundle_cb_f cb, void * ctx) noexcept;
std::optional<SignalBase> operator[](uint32_t signal_id) const noexcept;
Feature Flags
- PROTON_ENABLE_ALLOC: Enables setting Bundle callbacks with
std::function
calling BundleAccess::set_callback() with a std::function intentionally leaks memory. This is largely due to the fact that the function object is required to live as long as the Bundle (indefinitely). So the std::function is intentionally released from RAII automatic destruction to prevent dangling pointers.
Node Access
The same Node Manager API remains via NodeAccess
proton_status_e receive(const uint8_t * buffer, size_t len) noexcept
{
return proton_node_receive(node_, buffer, len);
}
uint32_t id() const noexcept { return node_->id; }
size_t num_peers() const noexcept { return node_->num_peers; }
proton_status_e update(
uint64_t uptime_ms, uint8_t * buffer, size_t buffer_len, size_t & out_len,
Endpoint * dest_peers, size_t num_dest_peers, size_t & num_selected_peers) noexcept
{
return proton_node_update(
node_, uptime_ms, buffer, buffer_len, &out_len, dest_peers, num_dest_peers,
&num_selected_peers);
}
proton_status_e trigger_bundle(uint32_t bundle_id) noexcept
{
return proton_node_trigger_bundle(node_, bundle_id);
}
Feature Flags
- PROTON_ENABLE_ALLOC: Enables
BundleAccess::on_bundle_update(uint32_t, std::function)as a passthrough for setting Bundle callbacks - C++20: Enables
std::spanoverloads for methods that usually take a pointer + length combo.