use crate::error::Result;
use crate::rtps::{EntityId, GuidPrefix, Locator, GUID};
use crate::transport::Transport;
pub struct MicroParticipant<T: Transport> {
domain_id: u32,
guid_prefix: GuidPrefix,
transport: T,
next_entity_id: u32,
}
impl<T: Transport> MicroParticipant<T> {
pub fn new(domain_id: u32, mut transport: T) -> Result<Self> {
transport.init()?;
let local_locator = transport.local_locator();
let guid_prefix = Self::generate_guid_prefix(&local_locator);
Ok(Self {
domain_id,
guid_prefix,
transport,
next_entity_id: 1, })
}
pub const fn domain_id(&self) -> u32 {
self.domain_id
}
pub const fn guid_prefix(&self) -> GuidPrefix {
self.guid_prefix
}
pub const fn guid(&self) -> GUID {
GUID::new(self.guid_prefix, EntityId::PARTICIPANT)
}
pub fn local_locator(&self) -> Locator {
self.transport.local_locator()
}
pub fn allocate_entity_id(&mut self, is_writer: bool) -> EntityId {
let entity_key = self.next_entity_id;
self.next_entity_id += 1;
let kind = if is_writer { 0xc2 } else { 0xc7 };
EntityId::new([
((entity_key >> 16) & 0xff) as u8,
((entity_key >> 8) & 0xff) as u8,
(entity_key & 0xff) as u8,
kind,
])
}
pub fn transport_mut(&mut self) -> &mut T {
&mut self.transport
}
pub fn transport(&self) -> &T {
&self.transport
}
pub fn shutdown(mut self) -> Result<()> {
self.transport.shutdown()
}
fn generate_guid_prefix(locator: &Locator) -> GuidPrefix {
let mut bytes = [0u8; 12];
bytes[0..8].copy_from_slice(&locator.address[8..16]);
let port_bytes = locator.port.to_be_bytes();
bytes[8..12].copy_from_slice(&port_bytes);
GuidPrefix::new(bytes)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::transport::NullTransport;
#[test]
fn test_participant_creation() {
let transport = NullTransport::default();
let participant = MicroParticipant::new(0, transport).unwrap();
assert_eq!(participant.domain_id(), 0);
assert_ne!(participant.guid_prefix(), GuidPrefix::UNKNOWN);
}
#[test]
fn test_entity_id_allocation() {
let transport = NullTransport::default();
let mut participant = MicroParticipant::new(0, transport).unwrap();
let writer_id = participant.allocate_entity_id(true);
let reader_id = participant.allocate_entity_id(false);
assert!(writer_id.is_writer());
assert!(reader_id.is_reader());
assert_ne!(writer_id, reader_id);
}
}