Skip to main content

Module cyclonedds_register

Module cyclonedds_register 

Source
Expand description

Phase 212.K.7.6.b — runtime cyclonedds type-descriptor registry hook. Per-type descriptor registration — generic seam (Phase 248 C2).

Some RMW backends (Cyclone DDS) resolve topic-type descriptors via a runtime registry instead of a static-init table. Each nros-node typed creator (create_publisher, create_subscription, create_client, create_service, create_action_*) routes through [register_type::<M>] before asking the cffi vtable to create the entity so the descriptor exists when the backend’s dds_create_topic (or equivalent) runs.

§No named-backend dependency (issue #60, Tier 1)

Previously this module depended directly on nros-rmw-cyclonedds and called nros_rmw_cyclonedds::register::<M>(), baking a concrete-RMW crate into the platform/RMW-agnostic core executor. It now forwards the message’s flattened schema through the generic nros_rmw::register_type_descriptor seam. The Cyclone backend installs its registrar from its own crate (nros-rmw-cyclonedds::install_descriptor_registrar, driven by the -sys shim’s RMW_INIT_ENTRIES self-registration); zenoh / xrce install nothing, so the seam is a no-op there.

§cfg gating (auto-detected, not feature-gated)

This module’s schema-passing body compiles to a no-op unless cfg(rmw_cyclonedds_present) is on. The cfg is emitted by nros-node/build.rs from the private internal __cyclonedds-link marker feature (no dep edge), which the umbrella nros/rmw-cyclonedds activates alongside its own dep:nros-rmw-cyclonedds-sys. Callers depend on nros = { features = ["rmw-cyclonedds"] }; the hook lights up automatically — no user-facing feature flag on nros-node. Each typed creator calls [register_type::<M>] unconditionally; the body is empty when the cfg is off so zenoh/xrce paths pay nothing. With the cfg on, the caller pays one mutex acquisition + one lookup per creator invocation (idempotent; the backend caches the descriptor on first hit).

§Trait bound — [MessageForRmw]

A descriptor-needing backend needs nros_serdes::schema::Message for the static field schema, but nros-node’s typed creators historically only constrain M: nros_core::RosMessage. Adding Message as a super-bound on RosMessage breaks every existing codegen-emitted msg crate (they impl RosMessage but not yet Message). Adding it as a per-method bound on every typed creator touches 30+ sites.

Compromise: introduce a helper trait [MessageForRmw] that is the bound the typed creators use in place of bare M: RosMessage. It is a blanket impl over RosMessage whose extra requirement is Message when cfg(rmw_cyclonedds_present) is on, and just RosMessage when off.

Net effect: a msg crate that impls RosMessage works as-is for zenoh

  • xrce builds; for cyclonedds builds it must additionally impl Message. The codegen template (nros-cli — separate repo) emits both impls for every generated msg crate.

§Error mapping

A registrar failure flattens onto crate::NodeError::Transport with nros_rmw::TransportError::PublisherCreationFailed. The choice not to add a dedicated NodeError variant is deliberate: the C/C++ FFI shim widens to a single nros_ret_t, and the failure mode (out-of-capacity registry, descriptor build error, etc.) is a “topic could not be created” from the caller’s perspective.

Traits§

MessageForRmw

Functions§

register_type
Register M’s topic-type descriptor with whichever RMW backend installed the generic descriptor seam (nros_rmw::register_type_descriptor).