use std::{ops::Deref, sync::Arc};
use rosidl_runtime_rs::Message;
use crate::{rcl_bindings::*, subscription::SubscriptionHandle, ToResult};
pub struct ReadOnlyLoanedMessage<T>
where
T: Message,
{
pub(super) msg_ptr: *const T::RmwMsg,
pub(super) handle: Arc<SubscriptionHandle>,
}
impl<T> Deref for ReadOnlyLoanedMessage<T>
where
T: Message,
{
type Target = T::RmwMsg;
fn deref(&self) -> &Self::Target {
unsafe { &*self.msg_ptr }
}
}
impl<T> Drop for ReadOnlyLoanedMessage<T>
where
T: Message,
{
fn drop(&mut self) {
unsafe {
rcl_return_loaned_message_from_subscription(
&*self.handle.lock(),
self.msg_ptr as *mut _,
)
.ok()
.unwrap();
}
}
}
unsafe impl<T> Send for ReadOnlyLoanedMessage<T> where T: Message {}
unsafe impl<T> Sync for ReadOnlyLoanedMessage<T> where T: Message {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn traits() {
use crate::{test_helpers::*, vendor::test_msgs};
assert_send::<ReadOnlyLoanedMessage<test_msgs::msg::rmw::BoundedSequences>>();
assert_sync::<ReadOnlyLoanedMessage<test_msgs::msg::rmw::BoundedSequences>>();
}
}