Skip to content

Commit

Permalink
iox-#23 Refine publisher API
Browse files Browse the repository at this point in the history
  • Loading branch information
elBoberido committed Jun 27, 2022
1 parent 08b520f commit b5c1462
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 103 deletions.
15 changes: 4 additions & 11 deletions examples/publisher_simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,24 @@
// SPDX-FileCopyrightText: © Contributors to the iceoryx-rs project
// SPDX-FileContributor: Mathias Kraus

use iceoryx_rs::pb::{TopicBuilder, POD};
use iceoryx_rs::pb::{PublisherBuilder, POD};
use iceoryx_rs::Runtime;

use std::error::Error;
use std::thread;
use std::time::Duration;

#[repr(C)]
struct CounterTopic {
struct Counter {
counter: u32,
}

unsafe impl POD for CounterTopic {}
unsafe impl POD for Counter {}

fn main() -> Result<(), Box<dyn Error>> {
Runtime::init("publisher_simple");

let topic = TopicBuilder::<CounterTopic>::new("Radar", "FrontLeft", "Counter").build()?;

let publisher = topic.offer();

// wait until RouDi runs the discovery loop
while !publisher.is_offered() {
thread::sleep(Duration::from_millis(10));
}
let publisher = PublisherBuilder::<Counter>::new("Radar", "FrontLeft", "Counter").create()?;

let mut counter = 0u32;
loop {
Expand Down
4 changes: 2 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use thiserror::Error;
pub enum IceOryxError {
#[error("could not alloce a chunk")]
ChunkAllocationFailed,
#[error("could not create a publisher topic")]
PublisherTopicCreationFailed,
#[error("could not create a publisher")]
PublisherCreationFailed,
#[error("number of allowed chunks to hold is exhausted")]
TooManyChunksHoldInParallel,
}
4 changes: 1 addition & 3 deletions src/pb/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ mod ffi;
mod publisher;
mod publisher_options;
mod sample;
mod topic;

pub use publisher::Publisher;
pub use publisher::{PublisherBuilder, InactivePublisher, Publisher};
pub use sample::POD;
pub use topic::{Topic, TopicBuilder};

use publisher_options::PublisherOptions;
101 changes: 89 additions & 12 deletions src/pb/publisher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,122 @@
// SPDX-FileCopyrightText: © Contributors to the iceoryx-rs project
// SPDX-FileContributor: Mathias Kraus

use super::{sample::SampleMut, Topic, POD};
use super::{ffi::Publisher as FfiPublisher, sample::SampleMut, PublisherOptions, POD};
use crate::IceOryxError;

use std::marker::PhantomData;

pub struct PublisherBuilder<'a, T: POD> {
service: &'a str,
instance: &'a str,
event: &'a str,
options: PublisherOptions,
phantom: PhantomData<T>,
}

impl<'a, T: POD> PublisherBuilder<'a, T> {
pub fn new(service: &'a str, instance: &'a str, event: &'a str) -> Self {
Self {
service,
instance,
event,
options: PublisherOptions::default(),
phantom: PhantomData,
}
}

pub fn history_capacity(mut self, history_capacity: u64) -> Self {
self.options.history_capacity = history_capacity;
self
}

pub fn node_name(mut self, node_name: String) -> Self {
self.options.node_name = node_name;
self
}

pub fn create(mut self) -> Result<Publisher<T>, IceOryxError> {
self.options.offer_on_create = true;
let ffi_pub = FfiPublisher::new(self.service, self.instance, self.event, &self.options)
.ok_or(IceOryxError::PublisherCreationFailed)?;

Ok(Publisher {
ffi_pub,
phantom: PhantomData,
})
}

pub fn create_without_offer(mut self) -> Result<InactivePublisher<T>, IceOryxError> {
self.options.offer_on_create = false;
let ffi_pub = FfiPublisher::new(self.service, self.instance, self.event, &self.options)
.ok_or(IceOryxError::PublisherCreationFailed)?;

Ok(InactivePublisher {
ffi_pub,
phantom: PhantomData,
})
}
}

pub struct InactivePublisher<T: POD> {
ffi_pub: Box<FfiPublisher>,
phantom: PhantomData<T>,
}

impl<T: POD> InactivePublisher<T> {
fn new_from_publisher(publisher: Publisher<T>) -> Self {
Self {
ffi_pub: publisher.ffi_pub,
phantom: PhantomData,
}
}

pub fn offer(self) -> Publisher<T> {
self.ffi_pub.offer();
Publisher::new_from_inactive_publisher(self)
}
}

pub struct Publisher<T: POD> {
publisher: Topic<T>,
ffi_pub: Box<FfiPublisher>,
phantom: PhantomData<T>,
}

impl<T: POD> Publisher<T> {
pub(super) fn new(publisher: Topic<T>) -> Self {
Publisher { publisher }
fn new_from_inactive_publisher(publisher: InactivePublisher<T>) -> Self {
Self {
ffi_pub: publisher.ffi_pub,
phantom: PhantomData,
}
}

pub fn is_offered(&self) -> bool {
self.publisher.ffi_pub.is_offered()
self.ffi_pub.is_offered()
}

pub fn stop(self) -> Topic<T> {
self.publisher.ffi_pub.stop_offer();
self.publisher
pub fn stop(self) -> InactivePublisher<T> {
self.ffi_pub.stop_offer();
InactivePublisher::new_from_publisher(self)
}

pub fn has_subscribers(&self) -> bool {
self.publisher.ffi_pub.has_subscribers()
self.ffi_pub.has_subscribers()
}

pub fn allocate_sample(&self) -> Result<SampleMut<T>, IceOryxError> {
Ok(SampleMut {
data: Some(self.publisher.ffi_pub.allocate_chunk()?),
data: Some(self.ffi_pub.allocate_chunk()?),
service: self,
})
}

pub fn publish(&self, mut sample: SampleMut<T>) {
if let Some(chunk) = sample.data.take() {
sample.service.publisher.ffi_pub.send_chunk(chunk)
sample.service.ffi_pub.send_chunk(chunk)
}
}

pub(super) fn release_chunk(&self, chunk: Box<T>) {
self.publisher.ffi_pub.free_chunk(chunk);
self.ffi_pub.free_chunk(chunk);
}
}
70 changes: 0 additions & 70 deletions src/pb/topic.rs

This file was deleted.

9 changes: 4 additions & 5 deletions src/tests/basic_pub_sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,26 @@ use crate::Runtime;
use anyhow::{anyhow, Result};

#[repr(C)]
struct CounterTopic {
struct Counter {
counter: u32,
}

unsafe impl POD for CounterTopic {}
unsafe impl POD for Counter {}

#[test]
fn basic_pub_sub() -> Result<()> {
let _roudi = RouDiEnvironment::new();

Runtime::init("basic_pub_sub");

let topic = sb::TopicBuilder::<CounterTopic>::new("Test", "BasicPubSub", "Counter")
let topic = sb::TopicBuilder::<Counter>::new("Test", "BasicPubSub", "Counter")
.queue_capacity(5)
.build();

let (subscriber, sample_receive_token) = topic.subscribe();

let topic = pb::TopicBuilder::<CounterTopic>::new("Test", "BasicPubSub", "Counter").build()?;
let publisher = pb::PublisherBuilder::<Counter>::new("Test", "BasicPubSub", "Counter").create()?;

let publisher = topic.offer();
let mut sample = publisher.allocate_sample()?;

const SEND_COUNTER: u32 = 42;
Expand Down

0 comments on commit b5c1462

Please sign in to comment.