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 } ;
33
44// Values defined by `action_msgs/msg/GoalStatus`
55#[ repr( i8 ) ]
@@ -22,9 +22,10 @@ enum GoalStatus {
2222/// passed to the user in the associated `handle_accepted` callback.
2323pub struct ServerGoalHandle < ActionT >
2424where
25- ActionT : rosidl_runtime_rs:: Action ,
25+ ActionT : rosidl_runtime_rs:: Action + rosidl_runtime_rs :: ActionImpl ,
2626{
2727 rcl_handle : Mutex < * mut rcl_action_goal_handle_t > ,
28+ action_server : Weak < ActionServer < ActionT > > ,
2829 goal_request : Arc < ActionT :: Goal > ,
2930 uuid : GoalUuid ,
3031}
@@ -34,20 +35,22 @@ where
3435// mutex, guaranteeing that the underlying data is never simultaneously accessed on the rclrs side
3536// by multiple threads. Moreover, the rcl_action functions taking these handles are able to be run
3637// 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 { }
3940
4041impl < ActionT > ServerGoalHandle < ActionT >
4142where
42- ActionT : rosidl_runtime_rs:: Action ,
43+ ActionT : rosidl_runtime_rs:: Action + rosidl_runtime_rs :: ActionImpl ,
4344{
4445 pub ( crate ) fn new (
4546 rcl_handle : * mut rcl_action_goal_handle_t ,
47+ action_server : Weak < ActionServer < ActionT > > ,
4648 goal_request : Arc < ActionT :: Goal > ,
4749 uuid : GoalUuid ,
4850 ) -> Self {
4951 Self {
5052 rcl_handle : Mutex :: new ( rcl_handle) ,
53+ action_server,
5154 goal_request : Arc :: clone ( & goal_request) ,
5255 uuid,
5356 }
@@ -148,7 +151,10 @@ where
148151 pub fn execute ( & self ) -> Result < ( ) , RclrsError > {
149152 self . update_state ( rcl_action_goal_event_t:: GOAL_EVENT_EXECUTE ) ?;
150153
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+ }
152158 Ok ( ( ) )
153159 }
154160
@@ -188,14 +194,17 @@ where
188194 ///
189195 /// Returns an error if the goal is in any state other than executing.
190196 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 ( ( ) )
193202 }
194203}
195204
196205impl < ActionT > Drop for ServerGoalHandle < ActionT >
197206where
198- ActionT : rosidl_runtime_rs:: Action ,
207+ ActionT : rosidl_runtime_rs:: Action + rosidl_runtime_rs :: ActionImpl ,
199208{
200209 /// Cancel the goal if its handle is dropped without reaching a terminal state.
201210 fn drop ( & mut self ) {
0 commit comments