Skip to content

Commit d8d7972

Browse files
authored
Implement functions to get parameters from global arguments (#176)
1 parent 975c99c commit d8d7972

File tree

9 files changed

+485
-21
lines changed

9 files changed

+485
-21
lines changed

rclrs/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ parking_lot = "0.11.2"
1818
# Needed for the Message trait, among others
1919
rosidl_runtime_rs = "*"
2020

21+
[dev-dependencies]
22+
# Needed for e.g. writing yaml files in tests
23+
tempfile = "3.3.0"
24+
2125
[build-dependencies]
2226
# Needed for FFI
2327
bindgen = "0.59.1"

rclrs/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ fn main() {
9292
}
9393

9494
println!("cargo:rustc-link-lib=dylib=rcl");
95+
println!("cargo:rustc-link-lib=dylib=rcl_yaml_param_parser");
9596
println!("cargo:rustc-link-lib=dylib=rcutils");
9697
println!("cargo:rustc-link-lib=dylib=rmw");
9798
println!("cargo:rustc-link-lib=dylib=rmw_implementation");

rclrs/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
mod context;
99
mod error;
1010
mod node;
11+
mod parameter;
1112
mod qos;
1213
mod wait;
1314

@@ -16,6 +17,7 @@ mod rcl_bindings;
1617
pub use context::*;
1718
pub use error::*;
1819
pub use node::*;
20+
pub use parameter::*;
1921
pub use qos::*;
2022
pub use wait::*;
2123

rclrs/src/node.rs

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ pub use self::publisher::*;
66
pub use self::subscription::*;
77

88
use crate::rcl_bindings::*;
9-
use crate::{Context, QoSProfile, RclrsError, ToResult};
10-
use std::ffi::CStr;
9+
use crate::{Context, ParameterOverrideMap, QoSProfile, RclrsError, ToResult};
1110

1211
use std::cmp::PartialEq;
12+
use std::ffi::CStr;
1313
use std::fmt;
1414
use std::sync::{Arc, Weak};
1515
use std::vec::Vec;
@@ -69,6 +69,7 @@ pub struct Node {
6969
rcl_node_mtx: Arc<Mutex<rcl_node_t>>,
7070
pub(crate) rcl_context_mtx: Arc<Mutex<rcl_context_t>>,
7171
pub(crate) subscriptions: Vec<Weak<dyn SubscriptionBase>>,
72+
_parameter_map: ParameterOverrideMap,
7273
}
7374

7475
impl Eq for Node {}
@@ -116,7 +117,7 @@ impl Node {
116117
/// # Ok::<(), RclrsError>(())
117118
/// ```
118119
pub fn name(&self) -> String {
119-
self.get_string(rcl_node_get_name)
120+
self.call_string_getter(rcl_node_get_name)
120121
}
121122

122123
/// Returns the namespace of the node.
@@ -142,7 +143,7 @@ impl Node {
142143
/// # Ok::<(), RclrsError>(())
143144
/// ```
144145
pub fn namespace(&self) -> String {
145-
self.get_string(rcl_node_get_namespace)
146+
self.call_string_getter(rcl_node_get_namespace)
146147
}
147148

148149
/// Returns the fully qualified name of the node.
@@ -162,26 +163,15 @@ impl Node {
162163
/// # Ok::<(), RclrsError>(())
163164
/// ```
164165
pub fn fully_qualified_name(&self) -> String {
165-
self.get_string(rcl_node_get_fully_qualified_name)
166+
self.call_string_getter(rcl_node_get_fully_qualified_name)
166167
}
167168

168169
// Helper for name(), namespace(), fully_qualified_name()
169-
fn get_string(
170+
fn call_string_getter(
170171
&self,
171172
getter: unsafe extern "C" fn(*const rcl_node_t) -> *const c_char,
172173
) -> String {
173-
let char_ptr = unsafe {
174-
// SAFETY: The rcl_node is valid.
175-
getter(&*self.rcl_node_mtx.lock())
176-
};
177-
debug_assert!(!char_ptr.is_null());
178-
let cstr = unsafe {
179-
// SAFETY: The returned CStr is immediately converted to an owned string,
180-
// so the lifetime is no issue. The ptr is valid as per the documentation
181-
// of rcl_node_get_name.
182-
CStr::from_ptr(char_ptr)
183-
};
184-
cstr.to_string_lossy().into_owned()
174+
unsafe { call_string_getter_with_handle(&*self.rcl_node_mtx.lock(), getter) }
185175
}
186176

187177
/// Creates a [`Publisher`][1].
@@ -279,3 +269,20 @@ impl Node {
279269
NodeBuilder::new(context, node_name)
280270
}
281271
}
272+
273+
// Helper used to implement call_string_getter(), but also used to get the FQN in the Node::new()
274+
// function, which is why it's not merged into Node::call_string_getter().
275+
// This function is unsafe since it's possible to pass in an rcl_node_t with dangling
276+
// pointers etc.
277+
unsafe fn call_string_getter_with_handle(
278+
rcl_node: &rcl_node_t,
279+
getter: unsafe extern "C" fn(*const rcl_node_t) -> *const c_char,
280+
) -> String {
281+
let char_ptr = getter(rcl_node);
282+
debug_assert!(!char_ptr.is_null());
283+
// SAFETY: The returned CStr is immediately converted to an owned string,
284+
// so the lifetime is no issue. The ptr is valid as per the documentation
285+
// of rcl_node_get_name.
286+
let cstr = CStr::from_ptr(char_ptr);
287+
cstr.to_string_lossy().into_owned()
288+
}

rclrs/src/node/builder.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
use crate::rcl_bindings::*;
2-
use crate::{Context, Node, RclrsError, ToResult};
2+
use crate::{
3+
node::call_string_getter_with_handle, resolve_parameter_overrides, Context, Node, RclrsError,
4+
ToResult,
5+
};
36

47
use std::ffi::CString;
8+
use std::sync::Arc;
59

610
use parking_lot::Mutex;
7-
use std::sync::Arc;
811

912
/// A builder for creating a [`Node`][1].
1013
///
@@ -261,16 +264,25 @@ impl NodeBuilder {
261264
.ok()?;
262265
};
263266

267+
let _parameter_map = unsafe {
268+
let fqn = call_string_getter_with_handle(&rcl_node, rcl_node_get_fully_qualified_name);
269+
resolve_parameter_overrides(
270+
&fqn,
271+
&rcl_node_options.arguments,
272+
&rcl_context.global_arguments,
273+
)?
274+
};
264275
let rcl_node_mtx = Arc::new(Mutex::new(rcl_node));
265276

266277
Ok(Node {
267278
rcl_node_mtx,
268279
rcl_context_mtx: self.context.clone(),
269280
subscriptions: std::vec![],
281+
_parameter_map,
270282
})
271283
}
272284

273-
/// Creates node options.
285+
/// Creates a rcl_node_options_t struct from this builder.
274286
///
275287
/// Any fields not present in the builder will have their default value.
276288
/// For detail about default values, see [`NodeBuilder`][1] docs.

rclrs/src/parameter.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
mod override_map;
2+
mod value;
3+
4+
pub(crate) use override_map::*;
5+
pub use value::*;

0 commit comments

Comments
 (0)