Skip to content

Commit

Permalink
Unify publish and publish_ref
Browse files Browse the repository at this point in the history
  • Loading branch information
nnmm committed Mar 13, 2022
1 parent 0609686 commit 364e994
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 14 deletions.
47 changes: 35 additions & 12 deletions rclrs/src/node/publisher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ use crate::qos::QoSProfile;
use crate::rcl_bindings::*;
use crate::{Node, NodeHandle};
use alloc::sync::Arc;
use core::borrow::{Borrow};
use std::borrow::Cow;
use core::marker::PhantomData;
use cstr_core::CString;
use rosidl_runtime_rs::{Message, RmwMessage};
use std::borrow::{Borrow, Cow};

#[cfg(not(feature = "std"))]
use spin::{Mutex, MutexGuard};
Expand Down Expand Up @@ -96,16 +95,23 @@ where
})
}

pub fn publish(&self, message: T) -> Result<(), RclReturnCode> {
self.publish_cow(Cow::Owned(message))
}

pub fn publish_ref(&self, message: &T) -> Result<(), RclReturnCode> {
self.publish_cow(Cow::Borrowed(message))
}

fn publish_cow(&self, message: Cow<'_, T>) -> Result<(), RclReturnCode> {
let rmw_message = T::into_rmw_message(message);
/// Publishes a message.
///
/// The [`OwnedOrBorrowedMessage`] trait is implemented by any
/// [`Message`] as well as any reference to a `Message`.
///
/// The reason for allowing owned messages is that publishing owned messages can be more
/// efficient in the case of idiomatic messages[^note].
///
/// [^note]: See the [`Message`] trait for an explanation of "idiomatic".
///
/// Hence, when a message will not be needed anymore after publishing, pass it by value.
/// When a message will be needed again after publishing, pass it by reference, instead of cloning and passing by value.
pub fn publish<'a, M: OwnedOrBorrowedMessage<'a, T>>(
&self,
message: M,
) -> Result<(), RclReturnCode> {
let rmw_message = T::into_rmw_message(message.into_cow());
let handle = &mut *self.handle.lock();
let ret = unsafe {
rcl_publish(
Expand All @@ -117,3 +123,20 @@ where
ret.ok()
}
}

/// Convenience trait for ['Publisher::publish`].
pub trait OwnedOrBorrowedMessage<'a, T: Message> {
fn into_cow(self) -> Cow<'a, T>;
}

impl<'a, T: Message> OwnedOrBorrowedMessage<'a, T> for T {
fn into_cow(self) -> Cow<'a, T> {
Cow::Owned(self)
}
}

impl<'a, T: Message> OwnedOrBorrowedMessage<'a, T> for &'a T {
fn into_cow(self) -> Cow<'a, T> {
Cow::Borrowed(self)
}
}
2 changes: 1 addition & 1 deletion rclrs_examples/src/minimal_publisher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ fn main() -> Result<(), Error> {
while context.ok()? {
message.data = format!("Hello, world! {}", publish_count);
println!("Publishing: [{}]", message.data);
publisher.publish(message.clone())?;
publisher.publish(&message)?;
publish_count += 1;
std::thread::sleep(std::time::Duration::from_millis(500));
}
Expand Down
2 changes: 1 addition & 1 deletion rosidl_runtime_rs/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ pub trait RmwMessage: Clone + Debug + Default {
/// problem, since nothing is allocated this way.
/// The `Drop` impl for any sequence or string will call `fini()`.
pub trait Message: Clone + Debug + Default {
pub trait Message: Clone + Debug + Default + 'static {
/// The corresponding RMW-compatible message type.
type RmwMsg: RmwMessage;

Expand Down

0 comments on commit 364e994

Please sign in to comment.