use crate::{DdsParticipant, Entity};
use cyclonedds_sys::size_t;
pub use cyclonedds_sys::{DDSError, DdsDomainId, DdsEntity};
use std::convert::From;
use std::marker::PhantomData;
pub struct DdsWaitset<T>(DdsEntity, PhantomData<T>);
impl<'a, T> DdsWaitset<T> {
pub fn create(participant: &DdsParticipant) -> Result<Self, DDSError> {
unsafe {
let p = cyclonedds_sys::dds_create_waitset(participant.entity().entity());
if p >= 0 {
Ok(DdsWaitset(DdsEntity::new(p), PhantomData))
} else {
Err(DDSError::from(p))
}
}
}
pub fn attach(&mut self, entity: &dyn Entity, x: &'a T) -> Result<(), DDSError> {
unsafe {
let p = cyclonedds_sys::dds_waitset_attach(
self.0.entity(),
entity.entity().entity(),
x as *const T as isize,
);
if p == 0 {
Ok(())
} else {
Err(DDSError::from(p))
}
}
}
pub fn detach(&mut self, entity: &dyn Entity) -> Result<(), DDSError> {
unsafe {
let p = cyclonedds_sys::dds_waitset_detach(self.0.entity(), entity.entity().entity());
if p == 0 {
Ok(())
} else {
Err(DDSError::from(p))
}
}
}
pub fn set_trigger(&mut self, trigger: bool) -> Result<(), DDSError> {
unsafe {
let p = cyclonedds_sys::dds_waitset_set_trigger(self.0.entity(), trigger);
if p == 0 {
Ok(())
} else {
Err(DDSError::from(p))
}
}
}
pub fn wait<'b>(
&mut self,
xs: &'b mut Vec<&'b T>,
timeout_us: i64,
) -> Result<&'b [&'b T], DDSError> {
let capacity = xs.capacity();
unsafe {
let p = cyclonedds_sys::dds_waitset_wait(
self.0.entity(),
xs.as_mut_ptr() as *mut isize,
capacity as size_t,
timeout_us,
);
if p == 0 {
Ok(&xs[0..0])
} else if p > 0 {
let p = p as usize;
xs.set_len(p);
Ok(&xs[0..p])
} else {
Err(DDSError::from(p))
}
}
}
}
impl<T> Entity for DdsWaitset<T> {
fn entity(&self) -> &DdsEntity {
&self.0
}
}
impl<T> Drop for DdsWaitset<T> {
fn drop(&mut self) {
unsafe {
let _ret: DDSError = cyclonedds_sys::dds_delete(self.0.entity()).into();
}
}
}