@@ -29,12 +29,14 @@ use async_std::future::timeout;
2929use  rosidl_runtime_rs:: Message ; 
3030
3131use  crate :: { 
32-     rcl_bindings:: * ,  Client ,  ClientOptions ,  ClientState ,  Clock ,  ContextHandle ,  ExecutorCommands , 
33-     IntoAsyncServiceCallback ,  IntoAsyncSubscriptionCallback ,  IntoNodeServiceCallback , 
34-     IntoNodeSubscriptionCallback ,  LogParams ,  Logger ,  ParameterBuilder ,  ParameterInterface , 
35-     ParameterVariant ,  Parameters ,  Promise ,  Publisher ,  PublisherOptions ,  PublisherState ,  RclrsError , 
36-     Service ,  ServiceOptions ,  ServiceState ,  Subscription ,  SubscriptionOptions ,  SubscriptionState , 
37-     TimeSource ,  ToLogParams ,  Worker ,  WorkerOptions ,  WorkerState ,  ENTITY_LIFECYCLE_MUTEX , 
32+     rcl_bindings:: * ,  AnyTimerCallback ,  Client ,  ClientOptions ,  ClientState ,  Clock ,  ContextHandle , 
33+     ExecutorCommands ,  IntoAsyncServiceCallback ,  IntoAsyncSubscriptionCallback , 
34+     IntoNodeServiceCallback ,  IntoNodeSubscriptionCallback ,  IntoNodeTimerOneshotCallback , 
35+     IntoNodeTimerRepeatingCallback ,  IntoTimerOptions ,  LogParams ,  Logger ,  ParameterBuilder , 
36+     ParameterInterface ,  ParameterVariant ,  Parameters ,  Promise ,  Publisher ,  PublisherOptions , 
37+     PublisherState ,  RclrsError ,  Service ,  ServiceOptions ,  ServiceState ,  Subscription , 
38+     SubscriptionOptions ,  SubscriptionState ,  TimeSource ,  Timer ,  TimerState ,  ToLogParams ,  Worker , 
39+     WorkerOptions ,  WorkerState ,  ENTITY_LIFECYCLE_MUTEX , 
3840} ; 
3941
4042/// A processing unit that can communicate with other nodes. See the API of 
@@ -908,6 +910,229 @@ impl NodeState {
908910        ) 
909911    } 
910912
913+     /// Create a [`Timer`] with a repeating callback. 
914+ /// 
915+ /// This has similar behavior to `rclcpp::Node::create_timer` by periodically 
916+ /// triggering the callback of the timer. For a one-shot timer alternative, 
917+ /// see [`NodeState::create_timer_oneshot`]. 
918+ /// 
919+ /// See also: 
920+ /// * [`Self::create_timer_oneshot`] 
921+ /// * [`Self::create_timer_inert`] 
922+ /// 
923+ /// # Behavior 
924+ /// 
925+ /// While the callback of this timer is running, no other callbacks associated 
926+ /// with this node will be able to run. This is in contrast to callbacks given 
927+ /// to [`Self::create_subscription`] which can run multiple times in parallel. 
928+ /// 
929+ /// Since the callback of this timer may block other callbacks from being able 
930+ /// to run, it is strongly recommended to ensure that the callback returns 
931+ /// quickly. If the callback needs to trigger long-running behavior then you 
932+ /// can consider using [`std::thread::spawn`], or for async behaviors you can 
933+ /// capture an [`ExecutorCommands`] in your callback and use [`ExecutorCommands::run`] 
934+ /// to issue a task for the executor to run in its async task pool. 
935+ /// 
936+ /// Since these callbacks are blocking, you may use [`FnMut`] here instead of 
937+ /// being limited to [`Fn`]. 
938+ /// 
939+ /// # Timer Options 
940+ /// 
941+ /// You can choose both 
942+ /// 1. a timer period (duration) which determines how often the callback is triggered 
943+ /// 2. a clock to measure the passage of time 
944+ /// 
945+ /// Both of these choices are expressed by [`TimerOptions`][1]. 
946+ /// 
947+ /// By default the steady clock time will be used, but you could choose 
948+ /// node time instead if you want the timer to automatically use simulated 
949+ /// time when running as part of a simulation: 
950+ /// ``` 
951+ /// # use rclrs::*; 
952+ /// # let executor = Context::default().create_basic_executor(); 
953+ /// # let node = executor.create_node("my_node").unwrap(); 
954+ /// use std::time::Duration; 
955+ /// 
956+ /// let timer = node.create_timer_repeating( 
957+ ///     TimerOptions::new(Duration::from_secs(1)) 
958+ ///     .node_time(), 
959+ ///     || { 
960+ ///         println!("Triggering once each simulated second"); 
961+ ///     }, 
962+ /// )?; 
963+ /// # Ok::<(), RclrsError>(()) 
964+ /// ``` 
965+ /// 
966+ /// If there is a specific manually-driven clock you want to use, you can 
967+ /// also select that: 
968+ /// ``` 
969+ /// # use rclrs::*; 
970+ /// # let executor = Context::default().create_basic_executor(); 
971+ /// # let node = executor.create_node("my_node").unwrap(); 
972+ /// use std::time::Duration; 
973+ /// 
974+ /// let (my_clock, my_source) = Clock::with_source(); 
975+ /// 
976+ /// let timer = node.create_timer_repeating( 
977+ ///     TimerOptions::new(Duration::from_secs(1)) 
978+ ///     .clock(&my_clock), 
979+ ///     || { 
980+ ///         println!("Triggering once each simulated second"); 
981+ ///     }, 
982+ /// )?; 
983+ /// 
984+ /// my_source.set_ros_time_override(1_500_000_000); 
985+ /// # Ok::<(), RclrsError>(()) 
986+ /// ``` 
987+ /// 
988+ /// If you are okay with the default choice of clock (steady clock) then you 
989+ /// can choose to simply pass a duration in as the options: 
990+ /// ``` 
991+ /// # use rclrs::*; 
992+ /// # let executor = Context::default().create_basic_executor(); 
993+ /// # let node = executor.create_node("my_node").unwrap(); 
994+ /// use std::time::Duration; 
995+ /// 
996+ /// let timer = node.create_timer_repeating( 
997+ ///     Duration::from_secs(1), 
998+ ///     || { 
999+ ///         println!("Triggering per steady clock second"); 
1000+ ///     }, 
1001+ /// )?; 
1002+ /// # Ok::<(), RclrsError>(()) 
1003+ /// ``` 
1004+ /// 
1005+ /// # Node Timer Repeating Callbacks 
1006+ /// 
1007+ /// Node Timer repeating callbacks support three signatures: 
1008+ /// - <code>[FnMut] ()</code> 
1009+ /// - <code>[FnMut] ([Time][2])</code> 
1010+ /// - <code>[FnMut] (&[Timer])</code> 
1011+ /// 
1012+ /// You can choose to receive the current time when the callback is being 
1013+ /// triggered. 
1014+ /// 
1015+ /// Or instead of the current time, you can get a borrow of the [`Timer`] 
1016+ /// itself, that way if you need to access it from inside the callback, you 
1017+ /// do not need to worry about capturing a [`Weak`][3] and then locking it. 
1018+ /// This is useful if you need to change the callback of the timer from inside 
1019+ /// the callback of the timer. 
1020+ /// 
1021+ /// For an [`FnOnce`] instead of [`FnMut`], use [`Self::create_timer_oneshot`]. 
1022+ /// 
1023+ /// [1]: crate::TimerOptions 
1024+ /// [2]: crate::Time 
1025+ /// [3]: std::sync::Weak 
1026+ pub  fn  create_timer_repeating < ' a ,  Args > ( 
1027+         self :  & Arc < Self > , 
1028+         options :  impl  IntoTimerOptions < ' a > , 
1029+         callback :  impl  IntoNodeTimerRepeatingCallback < Args > , 
1030+     )  -> Result < Timer ,  RclrsError >  { 
1031+         self . create_timer_internal ( options,  callback. into_node_timer_repeating_callback ( ) ) 
1032+     } 
1033+ 
1034+     /// Create a [`Timer`] whose callback will be triggered once after the period 
1035+ /// of the timer has elapsed. After that you will need to use 
1036+ /// [`TimerState::set_repeating`] or [`TimerState::set_oneshot`] or else 
1037+ /// nothing will happen the following times that the `Timer` elapses. 
1038+ /// 
1039+ /// This does not have an equivalent in `rclcpp`. 
1040+ /// 
1041+ /// See also: 
1042+ /// * [`Self::create_timer_repeating`] 
1043+ /// * [`Self::create_timer_inert`] 
1044+ /// 
1045+ /// # Behavior 
1046+ /// 
1047+ /// While the callback of this timer is running, no other callbacks associated 
1048+ /// with this node will be able to run. This is in contrast to callbacks given 
1049+ /// to [`Self::create_subscription`] which can run multiple times in parallel. 
1050+ /// 
1051+ /// Since the callback of this timer may block other callbacks from being able 
1052+ /// to run, it is strongly recommended to ensure that the callback returns 
1053+ /// quickly. If the callback needs to trigger long-running behavior then you 
1054+ /// can consider using [`std::thread::spawn`], or for async behaviors you can 
1055+ /// capture an [`ExecutorCommands`] in your callback and use [`ExecutorCommands::run`] 
1056+ /// to issue a task for the executor to run in its async task pool. 
1057+ /// 
1058+ /// Since these callbacks will only be triggered once, you may use [`FnOnce`] here. 
1059+ /// 
1060+ /// # Timer Options 
1061+ /// 
1062+ /// See [`NodeSate::create_timer_repeating`][3] for examples of setting the 
1063+ /// timer options. 
1064+ /// 
1065+ /// # Node Timer Oneshot Callbacks 
1066+ /// 
1067+ /// Node Timer OneShot callbacks support three signatures: 
1068+ /// - <code>[FnOnce] ()</code> 
1069+ /// - <code>[FnOnce] ([Time][2])</code> 
1070+ /// - <code>[FnOnce] (&[Timer])</code> 
1071+ /// 
1072+ /// You can choose to receive the current time when the callback is being 
1073+ /// triggered. 
1074+ /// 
1075+ /// Or instead of the current time, you can get a borrow of the [`Timer`] 
1076+ /// itself, that way if you need to access it from inside the callback, you 
1077+ /// do not need to worry about capturing a [`Weak`][3] and then locking it. 
1078+ /// This is useful if you need to change the callback of the timer from inside 
1079+ /// the callback of the timer. 
1080+ /// 
1081+ /// [2]: crate::Time 
1082+ /// [3]: std::sync::Weak 
1083+ pub  fn  create_timer_oneshot < ' a ,  Args > ( 
1084+         self :  & Arc < Self > , 
1085+         options :  impl  IntoTimerOptions < ' a > , 
1086+         callback :  impl  IntoNodeTimerOneshotCallback < Args > , 
1087+     )  -> Result < Timer ,  RclrsError >  { 
1088+         self . create_timer_internal ( options,  callback. into_node_timer_oneshot_callback ( ) ) 
1089+     } 
1090+ 
1091+     /// Create a [`Timer`] without a callback. Nothing will happen when this 
1092+ /// `Timer` elapses until you use [`TimerState::set_repeating`] or 
1093+ /// [`TimerState::set_oneshot`]. 
1094+ /// 
1095+ /// This function is not usually what you want. An inert timer is usually 
1096+ /// just a follow-up state to a oneshot timer which is waiting to be given 
1097+ /// a new callback to run. However, you could use this method to declare a 
1098+ /// timer whose callbacks you will start to feed in at a later. 
1099+ /// 
1100+ /// There is no equivalent to this function in `rclcpp`. 
1101+ /// 
1102+ /// See also: 
1103+ /// * [`Self::create_timer_repeating`] 
1104+ /// * [`Self::create_timer_oneshot`] 
1105+ pub  fn  create_timer_inert < ' a > ( 
1106+         self :  & Arc < Self > , 
1107+         options :  impl  IntoTimerOptions < ' a > , 
1108+     )  -> Result < Timer ,  RclrsError >  { 
1109+         self . create_timer_internal ( options,  AnyTimerCallback :: Inert ) 
1110+     } 
1111+ 
1112+     /// Used internally to create any kind of [`Timer`]. 
1113+ /// 
1114+ /// Downstream users should instead use: 
1115+ /// * [`Self::create_timer_repeating`] 
1116+ /// * [`Self::create_timer_oneshot`] 
1117+ /// * [`Self::create_timer_inert`] 
1118+ fn  create_timer_internal < ' a > ( 
1119+         self :  & Arc < Self > , 
1120+         options :  impl  IntoTimerOptions < ' a > , 
1121+         callback :  AnyTimerCallback < Node > , 
1122+     )  -> Result < Timer ,  RclrsError >  { 
1123+         let  options = options. into_timer_options ( ) ; 
1124+         let  clock = options. clock . as_clock ( self ) ; 
1125+         let  node = options. clock . is_node_time ( ) . then ( || Arc :: clone ( self ) ) ; 
1126+         TimerState :: create ( 
1127+             options. period , 
1128+             clock, 
1129+             callback, 
1130+             self . commands . async_worker_commands ( ) , 
1131+             & self . handle . context_handle , 
1132+             node, 
1133+         ) 
1134+     } 
1135+ 
9111136    /// Returns the ROS domain ID that the node is using. 
9121137/// 
9131138/// The domain ID controls which nodes can send messages to each other, see the [ROS 2 concept article][1]. 
0 commit comments