5
5
//!
6
6
//! [1]: https://github.com/ros2-rust/ros2_rust/blob/master/README.md
7
7
8
+ use std:: future:: Future ;
9
+ use std:: pin:: Pin ;
10
+ use std:: sync:: Arc ;
11
+ use std:: task:: Poll ;
12
+ use std:: time:: Duration ;
13
+
8
14
mod context;
9
15
mod error;
16
+ mod future;
10
17
mod node;
11
18
mod qos;
12
19
mod wait;
@@ -20,37 +27,70 @@ pub use qos::*;
20
27
pub use wait:: * ;
21
28
22
29
use rcl_bindings:: rcl_context_is_valid;
23
- use std:: time:: Duration ;
30
+
31
+ pub use rcl_bindings:: rmw_request_id_t;
32
+
33
+ use parking_lot:: Mutex ;
24
34
25
35
/// Polls the node for new messages and executes the corresponding callbacks.
26
36
///
27
37
/// See [`WaitSet::wait`] for the meaning of the `timeout` parameter.
28
38
///
29
39
/// This may under some circumstances return
30
- /// [`SubscriptionTakeFailed`][1] when the wait set spuriously wakes up.
40
+ /// [`SubscriptionTakeFailed`][1], [`ClientTakeFailed`][2], [`ServiceTakeFailed`][3] when the wait
41
+ /// set spuriously wakes up.
31
42
/// This can usually be ignored.
32
43
///
33
44
/// [1]: crate::SubscriberErrorCode
45
+ /// [2]: crate::ClientErrorCode
46
+ /// [3]: crate::ServiceErrorCode
34
47
pub fn spin_once ( node : & Node , timeout : Option < Duration > ) -> Result < ( ) , RclrsError > {
35
48
let live_subscriptions = node. live_subscriptions ( ) ;
49
+ let live_clients = node. live_clients ( ) ;
50
+ let live_services = node. live_services ( ) ;
36
51
let ctx = Context {
37
52
handle : node. context . clone ( ) ,
38
53
} ;
39
- let mut wait_set = WaitSet :: new ( live_subscriptions. len ( ) , & ctx) ?;
54
+ let mut wait_set = WaitSet :: new (
55
+ live_subscriptions. len ( ) ,
56
+ 0 ,
57
+ 0 ,
58
+ live_clients. len ( ) ,
59
+ live_services. len ( ) ,
60
+ 0 ,
61
+ & ctx,
62
+ ) ?;
40
63
41
64
for live_subscription in & live_subscriptions {
42
65
wait_set. add_subscription ( live_subscription. clone ( ) ) ?;
43
66
}
44
67
68
+ for live_client in & live_clients {
69
+ wait_set. add_client ( live_client. clone ( ) ) ?;
70
+ }
71
+
72
+ for live_service in & live_services {
73
+ wait_set. add_service ( live_service. clone ( ) ) ?;
74
+ }
75
+
45
76
let ready_entities = wait_set. wait ( timeout) ?;
77
+
46
78
for ready_subscription in ready_entities. subscriptions {
47
79
ready_subscription. execute ( ) ?;
48
80
}
49
81
82
+ for ready_client in ready_entities. clients {
83
+ ready_client. execute ( ) ?;
84
+ }
85
+
86
+ for ready_service in ready_entities. services {
87
+ ready_service. execute ( ) ?;
88
+ }
89
+
50
90
Ok ( ( ) )
51
91
}
52
92
53
- /// Convenience function for calling [`spin_once`] in a loop.
93
+ /// Convenience function for calling [`rclrs:: spin_once`] in a loop.
54
94
///
55
95
/// This function additionally checks that the context is still valid.
56
96
pub fn spin ( node : & Node ) -> Result < ( ) , RclrsError > {
@@ -70,6 +110,33 @@ pub fn spin(node: &Node) -> Result<(), RclrsError> {
70
110
} ;
71
111
}
72
112
}
73
-
74
113
Ok ( ( ) )
75
114
}
115
+
116
+ pub fn spin_until_future_complete < T : Unpin + Clone > (
117
+ node : & node:: Node ,
118
+ future : Arc < Mutex < Box < crate :: future:: RclFuture < T > > > > ,
119
+ ) -> Result < <future:: RclFuture < T > as Future >:: Output , RclrsError > {
120
+ let rclwaker = Arc :: new ( crate :: future:: RclWaker { } ) ;
121
+ let waker = crate :: future:: rclwaker_into_waker ( Arc :: into_raw ( rclwaker) ) ;
122
+ let mut cx = std:: task:: Context :: from_waker ( & waker) ;
123
+
124
+ loop {
125
+ let context_valid = unsafe { rcl_context_is_valid ( & mut * node. context . lock ( ) ) } ;
126
+ if context_valid {
127
+ if let Some ( error) = spin_once ( node, None ) . err ( ) {
128
+ match error {
129
+ RclrsError {
130
+ code : RclReturnCode :: Timeout ,
131
+ ..
132
+ } => continue ,
133
+ error => return Err ( error) ,
134
+ } ;
135
+ } ;
136
+ match Future :: poll ( Pin :: new ( & mut * future. lock ( ) ) , & mut cx) {
137
+ Poll :: Ready ( val) => break Ok ( val) ,
138
+ Poll :: Pending => continue ,
139
+ } ;
140
+ }
141
+ }
142
+ }
0 commit comments