Skip to content

Commit 0e21772

Browse files
committed
Add NodeBuilder
1 parent 5466525 commit 0e21772

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

rclrs/src/node/mod.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,28 @@ pub struct Node {
4040
pub(crate) subscriptions: Vec<Weak<dyn SubscriptionBase>>,
4141
}
4242

43+
/// A builder for node instantiation.
44+
///
45+
/// default value in each fields are
46+
/// - context: user defined
47+
/// - name: user defined
48+
/// - namespace: "/"
49+
///
50+
/// # Example
51+
/// ```
52+
/// # use rclrs::{Context, Node, NodeBuilder, RclReturnCode};
53+
/// let context = Context::new([])?;
54+
/// let node = NodeBuilder::new("foo_node", &context).namespace("/bar").build()?;
55+
/// assert_eq!(node.name(), "foo_node");
56+
/// assert_eq!(node.namespace(), "/bar");
57+
/// # Ok::<(), RclReturnCode>(())
58+
/// ```
59+
pub struct NodeBuilder<'a> {
60+
pub(self) context: &'a Context,
61+
pub(self) name: &'a str,
62+
pub(self) namespace: &'a str,
63+
}
64+
4365
impl Eq for Node {}
4466

4567
impl PartialEq for Node {
@@ -312,3 +334,62 @@ impl Node {
312334
domain_id
313335
}
314336
}
337+
338+
impl<'a> NodeBuilder<'a> {
339+
/// Creates new builder for Node.
340+
pub fn new(name: &'a str, context: &'a Context) -> NodeBuilder<'a> {
341+
let mut default_domain_id = 0;
342+
// SAFETY: No preconditions for this function.
343+
let ret = unsafe { rcl_get_default_domain_id(&mut default_domain_id) };
344+
debug_assert_eq!(ret, 0);
345+
346+
NodeBuilder {
347+
context,
348+
name,
349+
namespace: "/",
350+
}
351+
}
352+
353+
/// Sets node namespace.
354+
pub fn namespace(mut self, namespace: &'a str) -> Self {
355+
self.namespace = namespace;
356+
self
357+
}
358+
359+
/// Builds node instance
360+
pub fn build(&self) -> Result<Node, RclReturnCode> {
361+
let node_name = CString::new(self.name).unwrap();
362+
let node_namespace = CString::new(self.namespace).unwrap();
363+
364+
// SAFETY: No preconditions for this function.
365+
let mut node_handle = unsafe { rcl_get_zero_initialized_node() };
366+
367+
unsafe {
368+
// SAFETY: No preconditions for this function.
369+
let context_handle = &mut *self.context.handle.lock();
370+
// SAFETY: No preconditions for this function.
371+
let node_options = rcl_node_get_default_options();
372+
373+
// SAFETY: The node handle is zero-initialized as expected by this function.
374+
// The strings and node options are copied by this function, so we don't need
375+
// to keep them alive.
376+
// The context handle has to be kept alive because it is co-owned by the node.
377+
rcl_node_init(
378+
&mut node_handle,
379+
node_name.as_ptr(),
380+
node_namespace.as_ptr(),
381+
context_handle,
382+
&node_options,
383+
)
384+
.ok()?;
385+
};
386+
387+
let handle = Arc::new(Mutex::new(node_handle));
388+
389+
Ok(Node {
390+
handle,
391+
context: self.context.handle.clone(),
392+
subscriptions: std::vec![],
393+
})
394+
}
395+
}

0 commit comments

Comments
 (0)