Skip to content

Commit c4640d3

Browse files
authored
Api and doc improvements (#155)
* Simplified importing of RustDDS. Doc improvements. * Remove DDSDuration type alias. * Deprecate dds::data_types re-export.
1 parent d432f1c commit c4640d3

File tree

23 files changed

+369
-263
lines changed

23 files changed

+369
-263
lines changed

examples/shapes_demo/logging-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ appenders:
44
stdout:
55
kind: console
66
root:
7-
# level: info
8-
level: warn
7+
level: info
8+
# level: warn
99
appenders:
1010
- stdout
1111
loggers:

examples/shapes_demo/main.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,7 @@ use log4rs::{
1414
config::{Appender, Root},
1515
Config,
1616
};
17-
use rustdds::dds::{
18-
data_types::DDSDuration,
19-
qos::{
20-
policy::{Deadline, Durability, History, Reliability},
21-
QosPolicyBuilder,
22-
},
23-
statusevents::StatusEvented,
24-
traits::{Keyed, TopicDescription},
25-
DomainParticipant, TopicKind,
26-
};
17+
use rustdds::{self, *};
2718
use serde::{Deserialize, Serialize};
2819
use clap::{App, Arg, ArgMatches}; // command line argument processing
2920
use mio::{Events, Poll, PollOpt, Ready, Token}; // polling
@@ -73,7 +64,7 @@ fn main() {
7364
let mut qos_b = QosPolicyBuilder::new()
7465
.reliability(if matches.is_present("reliable") {
7566
Reliability::Reliable {
76-
max_blocking_time: DDSDuration::DURATION_ZERO,
67+
max_blocking_time: rustdds::Duration::DURATION_ZERO,
7768
}
7869
} else {
7970
Reliability::BestEffort
@@ -97,7 +88,7 @@ fn main() {
9788
let deadline_policy = match matches.value_of("deadline") {
9889
None => None,
9990
Some(dl) => match dl.parse::<f64>() {
100-
Ok(d) => Some(Deadline(DDSDuration::from_frac_seconds(d))),
91+
Ok(d) => Some(Deadline(rustdds::Duration::from_frac_seconds(d))),
10192
Err(e) => panic!("Expected numeric value for deadline. {:?}", e),
10293
},
10394
};

examples/turtle_teleop/main.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use mio::{Events, Poll, PollOpt, Ready, Token};
1010
use mio_extras::channel as mio_channel;
1111
use rustdds::{
1212
dds::{
13-
data_types::DDSDuration,
1413
qos::{
1514
policy::{Durability, History, Liveliness, Reliability},
1615
QosPolicies, QosPolicyBuilder,
@@ -117,10 +116,10 @@ fn ros2_loop(
117116
QosPolicyBuilder::new()
118117
.durability(Durability::Volatile)
119118
.liveliness(Liveliness::Automatic {
120-
lease_duration: DDSDuration::DURATION_INFINITE,
119+
lease_duration: rustdds::Duration::DURATION_INFINITE,
121120
})
122121
.reliability(Reliability::Reliable {
123-
max_blocking_time: DDSDuration::from_millis(100),
122+
max_blocking_time: rustdds::Duration::from_millis(100),
124123
})
125124
.history(History::KeepLast { depth: 10 })
126125
.build()

src/dds/mod.rs

Lines changed: 10 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,14 @@
1-
//! DDS interface
2-
//!
3-
//! # DDS usage summary
4-
//!
5-
//! * Create a [`DomainParticipant`]. You have to choose a domain id. The
6-
//! default value is zero.
7-
//! * Create or find a [`Topic`] from the [`DomainParticipant`]. Topics have a
8-
//! name and a type.
9-
//! * Create a [`Publisher`] and/or [`Subscriber`] from the
10-
//! [`DomainParticipant`].
11-
//! * To receive data, create a [`DataReader`](with_key::DataReader) from
12-
//! [`Subscriber`] and [`Topic`].
13-
//! * To send data, create a [`DataWriter`](with_key::DataWriter) from
14-
//! [`Publisher`] and [`Topic`].
15-
//! * Data from `DataReader` can be read or taken. Taking removes the data
16-
//! samples from the DataReader, whereas reading only marks them as read.
17-
//! * Topics are either WithKey or NoKey. WithKey topics are like map data
18-
//! structures, containing multiple instances (map items), identified by key.
19-
//! The key must be something that can be extracted from the data samples.
20-
//! Instances can be created (published) and deleted (disposed). NoKey topics
21-
//! have always only one instance of the data.
22-
//! * Data is sent and received in consecutive samples. When read, a smaple is
23-
//! accompanied with metadata (SampleInfo).
24-
//!
25-
//! # Interfacing Rust data types to DDS
26-
//! * DDS takes care of serialization and deserialization.
27-
//! In order to do this, the payload data must be Serde
28-
//! serializable/deserializable.
29-
//! * If your data is to be communicated over a WithKey topic, the payload data
30-
//! type must implement [`Keyed`](traits::Keyed) trait from this crate.
31-
//! * If you are using CDR serialization (DDS default), then use [`CDRSerializerAdapter`](../serialization/CdrSerializerAdapter) and [`CdrDeserializerAdapter`](../serialization/CdrDeserializerAdapter)
32-
//! when such adapters are required. If you need to use another serialization format, then you should find or write
33-
//! a [Serde data format](https://serde.rs/data-format.html) implementation and wrap it as a (De)SerializerAdaper.
34-
//!
35-
//! ```
36-
//! use rustdds::dds::DomainParticipant;
37-
//! use rustdds::dds::{No_Key_DataReader as DataReader, No_Key_DataWriter as DataWriter, no_key::DataSample};
38-
//! use rustdds::dds::qos::QosPolicyBuilder;
39-
//! use rustdds::dds::qos::policy::Reliability;
40-
//! use rustdds::dds::data_types::DDSDuration;
41-
//! use rustdds::dds::data_types::TopicKind;
42-
//! use rustdds::serialization::{CDRSerializerAdapter, CDRDeserializerAdapter};
43-
//! use serde::{Serialize, Deserialize};
44-
//!
45-
//! // DomainParticipant is always necessary
46-
//! let domain_participant = DomainParticipant::new(0).unwrap();
47-
//!
48-
//! let qos = QosPolicyBuilder::new()
49-
//! .reliability(Reliability::Reliable { max_blocking_time: DDSDuration::DURATION_ZERO })
50-
//! .build();
51-
//!
52-
//! // DDS Subscriber, only one is necessary for each thread (slight difference to
53-
//! // DDS specification)
54-
//! let subscriber = domain_participant.create_subscriber(&qos).unwrap();
55-
//!
56-
//! // DDS Publisher, only one is necessary for each thread (slight difference to
57-
//! // DDS specification)
58-
//! let publisher = domain_participant.create_publisher(&qos).unwrap();
59-
//!
60-
//! // Some DDS Topic that we can write and read from (basically only binds readers
61-
//! // and writers together)
62-
//! let some_topic = domain_participant.create_topic("some_topic".to_string(), "SomeType".to_string(), &qos, TopicKind::NoKey).unwrap();
63-
//!
64-
//! // Used type needs Serialize for writers and Deserialize for readers
65-
//! #[derive(Serialize, Deserialize)]
66-
//! struct SomeType {
67-
//! a: i32
68-
//! }
69-
//!
70-
//! // Creating DataReader requires type and deserializer adapter (which is recommended to be CDR).
71-
//! // Reader needs to be mutable if any operations are used.
72-
//! let mut reader = subscriber
73-
//! .create_datareader_no_key::<SomeType, CDRDeserializerAdapter<SomeType>>(
74-
//! &some_topic,
75-
//! None)
76-
//! .unwrap();
77-
//!
78-
//! // Creating DataWriter required type and serializer adapter (which is recommended to be CDR).
79-
//! let writer = publisher
80-
//! .create_datawriter_no_key::<SomeType, CDRSerializerAdapter<SomeType>>(
81-
//! &some_topic,
82-
//! None)
83-
//! .unwrap();
84-
//!
85-
//! // Readers implement mio Evented trait and thus function the same way as
86-
//! // std::sync::mpcs and can be handled the same way for reading the data
87-
//!
88-
//! let some_data = SomeType { a: 1 };
89-
//!
90-
//! // This should send the data to all who listen "some_topic" topic.
91-
//! writer.write(some_data, None).unwrap();
92-
//!
93-
//! // ... Some data has arrived at some point for the reader
94-
//! let data_sample = if let Ok(Some(value)) = reader.read_next_sample() {
95-
//! value
96-
//! } else {
97-
//! // no data has arrived
98-
//! return;
99-
//! };
100-
//!
101-
//! // Getting reference to actual data from the data sample
102-
//! let actual_data = data_sample.value();
103-
//! ```
1+
//! DDS interface - Most commonly needed items should be re-exported directly to
2+
//! crate top level and modules [`no_key`](crate::no_key) and
3+
//! [`with_key`](crate::with_key).
1044
1055
mod datasample_cache;
1066
pub(crate) mod ddsdata;
1077
mod dp_event_loop;
1088
mod fragment_assembler;
1099
mod helpers;
11010
mod message_receiver;
111-
mod sampleinfo;
11+
pub mod sampleinfo;
11212

11313
/// Participating in NoKey topics.
11414
pub mod no_key;
@@ -135,23 +35,25 @@ pub mod qos;
13535
pub mod statusevents;
13636

13737
/// Datatypes needed for overall operability with this crate
38+
39+
#[deprecated(
40+
since = "0.7.0",
41+
note = "Please use re-exports directly from crate top level instead."
42+
)]
43+
#[doc(hidden)]
13844
pub mod data_types {
13945
pub use crate::{
14046
dds::sampleinfo::SampleInfo,
14147
discovery::data_types::topic_data::{DiscoveredTopicData, SubscriptionBuiltinTopicData},
14248
structure::guid::*,
14349
};
144-
#[doc(inline)]
145-
pub use crate::structure::duration::Duration as DDSDuration;
14650
pub use super::{
14751
readcondition::ReadCondition,
14852
topic::{Topic, TopicKind},
14953
traits::key::BuiltInTopicKey,
15054
};
15155
#[doc(inline)]
15256
pub use super::with_key::datareader::SelectByKey;
153-
#[doc(inline)]
154-
pub use crate::structure::time::Timestamp as DDSTimestamp;
15557
// TODO: move typedesc module somewhere better
15658
pub use crate::dds::typedesc::TypeDesc;
15759
}

src/dds/no_key/datasample.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ use crate::dds::{
33
with_key::datasample::DataSample as WithKeyDataSample,
44
};
55

6-
/// DDS spec 2.2.2.5.4
6+
/// A data sample and its associated [metadata](`SampleInfo`) received from a
7+
/// NO_KEY Topic.
78
///
8-
/// Note that no_key::DataSample and with_key::DataSample are two different but
9-
/// similar structs.
9+
/// See DDS spec version 1.4 Section 2.2.2.5.4
10+
///
11+
/// Note that [`no_key::DataSample`](crate::no_key::DataSample) and
12+
/// [`with_key::DataSample`](crate::with_key::DataSample) are two different
13+
/// structs.
1014
#[derive(PartialEq, Debug)]
1115
pub struct DataSample<D> {
1216
pub(crate) sample_info: SampleInfo, // TODO: Can we somehow make this lazily evaluated?

src/dds/participant.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ use log::{debug, error, info, trace, warn};
1616

1717
use crate::{
1818
dds::{
19-
data_types::*, dp_event_loop::DPEventLoop, pubsub::*, qos::*, reader::*, topic::*,
20-
typedesc::TypeDesc, values::result::*, writer::WriterIngredients,
19+
dp_event_loop::DPEventLoop, pubsub::*, qos::*, reader::*, topic::*, typedesc::TypeDesc,
20+
values::result::*, writer::WriterIngredients,
2121
},
2222
discovery::{
2323
data_types::topic_data::DiscoveredTopicData,
@@ -26,12 +26,23 @@ use crate::{
2626
},
2727
log_and_err_internal,
2828
network::{constant::*, udp_listener::UDPListener},
29-
structure::{dds_cache::DDSCache, entity::RTPSEntity, guid::GUID, locator::Locator},
29+
structure::{dds_cache::DDSCache, entity::RTPSEntity, guid::*, locator::Locator},
3030
};
3131
use super::dp_event_loop::DomainInfo;
3232

33-
/// DDS DomainParticipant generally only one per domain per machine should be
34-
/// active
33+
/// DDS DomainParticipant
34+
///
35+
/// It is recommended that only one DomainParticipant per OS process is created,
36+
/// as it allocates network sockets, creates background threads, and allocates
37+
/// some memory for object caches.
38+
///
39+
/// If you need to communicate to many DDS domains,
40+
/// then you must create a separate DomainParticiapnt for each of them.
41+
/// See DDS Spec v1.4 Section "2.2.1.2.2 Overall Conceptual Model" and
42+
/// "2.2.2.2.1 DomainParticipant Class" for a definition of a (DDS) domain.
43+
/// Domains are identified by a domain identifier, which is, in Rust terms, a
44+
/// `u16`. Domain identifer values are application-specific, but `0` is usually
45+
/// the default.
3546
#[derive(Clone)]
3647
// This is a smart pointer for DomainParticipantInner for easier manipulation.
3748
pub struct DomainParticipant {
@@ -42,7 +53,7 @@ pub struct DomainParticipant {
4253
impl DomainParticipant {
4354
/// # Examples
4455
/// ```
45-
/// # use rustdds::dds::DomainParticipant;
56+
/// # use rustdds::DomainParticipant;
4657
/// let domain_participant = DomainParticipant::new(0).unwrap();
4758
/// ```
4859
pub fn new(domain_id: u16) -> Result<DomainParticipant> {

src/dds/pubsub.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,20 @@ use super::{
5151

5252
/// DDS Publisher
5353
///
54+
/// The Publisher and Subscriber structures are collections of DataWriters
55+
/// and, respectively, DataReaders. They can contain DataWriters or DataReaders
56+
/// of different types, and attacehd to different Topics.
57+
///
58+
/// They can act as a domain of sample ordering or atomicity, if such QoS
59+
/// policies are used. For example, DDS participants could agree via QoS
60+
/// policies that data samples must be presented to readers in the same order as
61+
/// writers have written them, and the ordering applies also between several
62+
/// writers/readers, but within one publisher/subscriber. Analogous arrangement
63+
/// can be set up w.r.t. coherency: All the samples in a transaction are
64+
/// delivered to the readers, or none are. The transaction can span several
65+
/// readers, writers, and topics in a single publisher/subscriber.
66+
///
67+
///
5468
/// # Examples
5569
///
5670
/// ```
@@ -596,6 +610,8 @@ impl Debug for InnerPublisher {
596610

597611
/// DDS Subscriber
598612
///
613+
/// See overview at [`Publisher`].
614+
///
599615
/// # Examples
600616
///
601617
/// ```

src/dds/qos.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub enum QosPolicyId {
5252
//DurabilityService, // 22
5353
}
5454

55-
/// Utility for building [QosPolicies](struct.QosPolicies.html)
55+
/// Utility for building [QosPolicies]
5656
#[derive(Default)]
5757
pub struct QosPolicyBuilder {
5858
durability: Option<policy::Durability>,
@@ -161,7 +161,9 @@ impl QosPolicyBuilder {
161161
}
162162
}
163163

164-
/// Describes single RTPS/DDS QoS policy
164+
/// Describes a set of RTPS/DDS QoS policies
165+
///
166+
/// QosPolicies are constructed using a [`QosPolicyBuilder`]
165167
#[derive(Clone, Debug, PartialEq, Eq, Default)]
166168
pub struct QosPolicies {
167169
// pub(crate) beacuse as we want to have some builtin QoS Policies as constant.
@@ -237,6 +239,10 @@ impl QosPolicies {
237239
self.lifespan
238240
}
239241

242+
/// Merge two QosPolicies
243+
///
244+
/// Constructs a QosPolicy, where each policy is taken from `self`,
245+
/// and overwritten with those policies from `other` that are defined.
240246
pub fn modify_by(&self, other: &QosPolicies) -> QosPolicies {
241247
QosPolicies {
242248
durability: other.durability.or(self.durability),
@@ -254,16 +260,19 @@ impl QosPolicies {
254260
}
255261
}
256262

257-
// Check if policy self commplies to other.
258-
//
259-
// "self" is the "offered" (publisher) QoS
260-
// "other" is the "requested" (subscriber) QoS
261-
// yes => None (no failure, i.e. are compatible)
262-
// no => Some(policyId) , where policyId is (any) one of the policies
263-
// causing incompliance
264-
// Compliance (comaptibility) is defined in the table in DDS spec v1.4
265-
// Section "2.2.3 Supported QoS"
266-
// This is not symmetric.
263+
/// Check if policy commplies to another policy.
264+
///
265+
/// `self` is the "offered" (publisher) QoS
266+
/// `other` is the "requested" (subscriber) QoS
267+
///
268+
/// * None => Policies are compatible
269+
/// * Some(policyId) => Failure, where policyId is (any) one of the policies
270+
/// causing incompliance
271+
///
272+
/// Compliance (compatibility) is defined in the table in DDS spec v1.4
273+
/// Section "2.2.3 Supported QoS"
274+
///
275+
/// This is not symmetric.
267276
pub fn compliance_failure_wrt(&self, other: &QosPolicies) -> Option<QosPolicyId> {
268277
trace!(
269278
"QoS compatibility check - offered: {:?} - requested {:?}",
@@ -275,7 +284,7 @@ impl QosPolicies {
275284
result
276285
}
277286

278-
pub fn compliance_failure_wrt_impl(&self, other: &QosPolicies) -> Option<QosPolicyId> {
287+
fn compliance_failure_wrt_impl(&self, other: &QosPolicies) -> Option<QosPolicyId> {
279288
// TODO: Check for cases where policy is requested, but not offered (None)
280289

281290
// check Durability: Offered must be better than or equal to Requested.

src/dds/readcondition.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ use enumflags2::BitFlags;
22

33
use crate::dds::sampleinfo::*;
44

5-
// This is used to specify which samples are to be read or taken.
6-
// To be selected, the current state of the sample must be included in the
7-
// corresponding bitflags.
8-
/// DDS ReadCondition 2.2.2.5.8
5+
/// This is used to specify which samples are to be read or taken from
6+
/// a [`Datareader`](crate::with_key::DataReader)
7+
///
8+
/// To be selected, the current state of the sample must be included in the
9+
/// corresponding bitflags.
10+
/// See DDS Specification 1.4 Section "2.2.2.5.8 ReadCondition"
911
#[derive(Debug, Copy, Clone, PartialEq)]
1012
pub struct ReadCondition {
1113
sample_state_mask: BitFlags<SampleState>,

0 commit comments

Comments
 (0)