@@ -40,6 +40,28 @@ pub struct Node {
40
40
pub ( crate ) subscriptions : Vec < Weak < dyn SubscriptionBase > > ,
41
41
}
42
42
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
+
43
65
impl Eq for Node { }
44
66
45
67
impl PartialEq for Node {
@@ -312,3 +334,62 @@ impl Node {
312
334
domain_id
313
335
}
314
336
}
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