1
- use crate :: { rcl_bindings:: * , GoalUuid , RclrsError , ToResult } ;
2
- use std:: sync:: { Arc , Mutex } ;
1
+ use crate :: { action :: ActionServer , rcl_bindings:: * , GoalUuid , RclrsError , ToResult } ;
2
+ use std:: sync:: { Arc , Mutex , Weak } ;
3
3
4
4
// Values defined by `action_msgs/msg/GoalStatus`
5
5
#[ repr( i8 ) ]
@@ -22,9 +22,10 @@ enum GoalStatus {
22
22
/// passed to the user in the associated `handle_accepted` callback.
23
23
pub struct ServerGoalHandle < ActionT >
24
24
where
25
- ActionT : rosidl_runtime_rs:: Action ,
25
+ ActionT : rosidl_runtime_rs:: Action + rosidl_runtime_rs :: ActionImpl ,
26
26
{
27
27
rcl_handle : Mutex < * mut rcl_action_goal_handle_t > ,
28
+ action_server : Weak < ActionServer < ActionT > > ,
28
29
goal_request : Arc < ActionT :: Goal > ,
29
30
uuid : GoalUuid ,
30
31
}
@@ -34,20 +35,22 @@ where
34
35
// mutex, guaranteeing that the underlying data is never simultaneously accessed on the rclrs side
35
36
// by multiple threads. Moreover, the rcl_action functions taking these handles are able to be run
36
37
// from any thread.
37
- unsafe impl < ActionT > Send for ServerGoalHandle < ActionT > where ActionT : rosidl_runtime_rs:: Action { }
38
- unsafe impl < ActionT > Sync for ServerGoalHandle < ActionT > where ActionT : rosidl_runtime_rs:: Action { }
38
+ unsafe impl < ActionT > Send for ServerGoalHandle < ActionT > where ActionT : rosidl_runtime_rs:: Action + rosidl_runtime_rs :: ActionImpl { }
39
+ unsafe impl < ActionT > Sync for ServerGoalHandle < ActionT > where ActionT : rosidl_runtime_rs:: Action + rosidl_runtime_rs :: ActionImpl { }
39
40
40
41
impl < ActionT > ServerGoalHandle < ActionT >
41
42
where
42
- ActionT : rosidl_runtime_rs:: Action ,
43
+ ActionT : rosidl_runtime_rs:: Action + rosidl_runtime_rs :: ActionImpl ,
43
44
{
44
45
pub ( crate ) fn new (
45
46
rcl_handle : * mut rcl_action_goal_handle_t ,
47
+ action_server : Weak < ActionServer < ActionT > > ,
46
48
goal_request : Arc < ActionT :: Goal > ,
47
49
uuid : GoalUuid ,
48
50
) -> Self {
49
51
Self {
50
52
rcl_handle : Mutex :: new ( rcl_handle) ,
53
+ action_server,
51
54
goal_request : Arc :: clone ( & goal_request) ,
52
55
uuid,
53
56
}
@@ -148,7 +151,10 @@ where
148
151
pub fn execute ( & self ) -> Result < ( ) , RclrsError > {
149
152
self . update_state ( rcl_action_goal_event_t:: GOAL_EVENT_EXECUTE ) ?;
150
153
151
- // TODO: Invoke on_executing callback
154
+ // Publish the state change.
155
+ if let Some ( action_server) = self . action_server . upgrade ( ) {
156
+ action_server. publish_status ( ) ?;
157
+ }
152
158
Ok ( ( ) )
153
159
}
154
160
@@ -188,14 +194,17 @@ where
188
194
///
189
195
/// Returns an error if the goal is in any state other than executing.
190
196
pub fn publish_feedback ( & self , feedback : Arc < ActionT :: Feedback > ) -> Result < ( ) , RclrsError > {
191
- // TODO: Invoke public_feedback callback
192
- todo ! ( )
197
+ // If the action server no longer exists, simply drop the message.
198
+ if let Some ( action_server) = self . action_server . upgrade ( ) {
199
+ action_server. publish_feedback ( & self . uuid , & * feedback) ?;
200
+ }
201
+ Ok ( ( ) )
193
202
}
194
203
}
195
204
196
205
impl < ActionT > Drop for ServerGoalHandle < ActionT >
197
206
where
198
- ActionT : rosidl_runtime_rs:: Action ,
207
+ ActionT : rosidl_runtime_rs:: Action + rosidl_runtime_rs :: ActionImpl ,
199
208
{
200
209
/// Cancel the goal if its handle is dropped without reaching a terminal state.
201
210
fn drop ( & mut self ) {
0 commit comments