11use crate :: { clock:: Clock , context:: Context , error:: RclrsError , rcl_bindings:: * , to_rclrs_result} ;
2+ // TODO: fix me when the callback type is properly defined.
23// use std::fmt::Debug;
34use std:: sync:: { atomic:: AtomicBool , Arc , Mutex } ;
45
6+ /// Type alias for the `Timer` callback.
57pub type TimerCallback = Box < dyn Fn ( i64 ) + Send + Sync > ;
68
9+ /// Struct for executing periodic events.
10+ ///
11+ /// The execution of the callbacks is tied to [`spin_once`][1] or [`spin`][2] on the timers's node.
12+ ///
13+ /// Timer can be created via [`Node::create_timer()`][3], this is to ensure that [`Node`][4]s can
14+ /// track all the timers that have been created. However, a user of a `Timer` can also
15+ /// use it standalone.
16+ ///
17+ /// [1]: crate::spin_once
18+ /// [2]: crate::spin
19+ /// [3]: crate::Node::create_timer
20+ /// [4]: crate::Node
21+ // TODO: callback type prevents us from making the Timer implement the Debug trait.
722// #[derive(Debug)]
823pub struct Timer {
924 pub ( crate ) rcl_timer : Arc < Mutex < rcl_timer_t > > ,
25+ /// The callback function that runs when the timer is due.
1026 callback : Option < TimerCallback > ,
1127 pub ( crate ) in_use_by_wait_set : Arc < AtomicBool > ,
1228}
1329
1430impl Timer {
15- /// Creates a new timer (constructor)
16- pub fn new ( clock : & Clock , context : & Context , period : i64 ) -> Result < Timer , RclrsError > {
17- Self :: new_with_callback ( clock, context, period, None )
18- }
19-
20- pub fn new_with_callback (
31+ /// Creates a new timer.
32+ pub fn new (
2133 clock : & Clock ,
2234 context : & Context ,
2335 period : i64 ,
@@ -97,6 +109,7 @@ impl Timer {
97109 to_rclrs_result ( time_until_next_call_result) . map ( |_| time_value_ns)
98110 }
99111
112+ /// Resets the timer.
100113 pub fn reset ( & self ) -> Result < ( ) , RclrsError > {
101114 let mut rcl_timer = self . rcl_timer . lock ( ) . unwrap ( ) ;
102115 to_rclrs_result ( unsafe { rcl_timer_reset ( & mut * rcl_timer) } )
@@ -119,7 +132,7 @@ impl Timer {
119132 to_rclrs_result ( is_ready_result) . map ( |_| is_ready)
120133 }
121134
122- pub fn execute ( & self ) -> Result < ( ) , RclrsError > {
135+ pub ( crate ) fn execute ( & self ) -> Result < ( ) , RclrsError > {
123136 if self . is_ready ( ) ? {
124137 let time_since_last_call = self . time_since_last_call ( ) ?;
125138 self . call ( ) ?;
@@ -157,6 +170,10 @@ mod tests {
157170 use super :: * ;
158171 use std:: { thread, time} ;
159172
173+ fn create_dummy_callback ( ) -> Option < TimerCallback > {
174+ Some ( Box :: new ( move |_| { } ) )
175+ }
176+
160177 #[ test]
161178 fn traits ( ) {
162179 use crate :: test_helpers:: * ;
@@ -170,8 +187,7 @@ mod tests {
170187 let clock = Clock :: system ( ) ;
171188 let context = Context :: new ( vec ! [ ] ) . unwrap ( ) ;
172189 let period: i64 = 1e6 as i64 ; // 1 milliseconds.
173-
174- let dut = Timer :: new ( & clock, & context, period) ;
190+ let dut = Timer :: new ( & clock, & context, period, create_dummy_callback ( ) ) ;
175191 assert ! ( dut. is_ok( ) ) ;
176192 }
177193
@@ -180,8 +196,7 @@ mod tests {
180196 let clock = Clock :: steady ( ) ;
181197 let context = Context :: new ( vec ! [ ] ) . unwrap ( ) ;
182198 let period: i64 = 1e6 as i64 ; // 1 milliseconds.
183-
184- let dut = Timer :: new ( & clock, & context, period) ;
199+ let dut = Timer :: new ( & clock, & context, period, create_dummy_callback ( ) ) ;
185200 assert ! ( dut. is_ok( ) ) ;
186201 }
187202
@@ -195,11 +210,9 @@ mod tests {
195210 source. set_ros_time_override ( set_time) ;
196211 // Ros time is set, should return the value that was set
197212 assert_eq ! ( clock. now( ) . nsec, set_time) ;
198-
199213 let context = Context :: new ( vec ! [ ] ) . unwrap ( ) ;
200214 let period: i64 = 1e6 as i64 ; // 1 milliseconds..
201-
202- let dut = Timer :: new ( & clock, & context, period) ;
215+ let dut = Timer :: new ( & clock, & context, period, create_dummy_callback ( ) ) ;
203216 assert ! ( dut. is_ok( ) ) ;
204217 }
205218
@@ -208,8 +221,7 @@ mod tests {
208221 let clock = Clock :: steady ( ) ;
209222 let context = Context :: new ( vec ! [ ] ) . unwrap ( ) ;
210223 let period: i64 = 1e6 as i64 ; // 1 milliseconds.
211-
212- let dut = Timer :: new ( & clock, & context, period) ;
224+ let dut = Timer :: new ( & clock, & context, period, create_dummy_callback ( ) ) ;
213225 assert ! ( dut. is_ok( ) ) ;
214226 let dut = dut. unwrap ( ) ;
215227 let period_result = dut. get_timer_period_ns ( ) ;
@@ -223,8 +235,7 @@ mod tests {
223235 let clock = Clock :: steady ( ) ;
224236 let context = Context :: new ( vec ! [ ] ) . unwrap ( ) ;
225237 let period: i64 = 1e6 as i64 ; // 1 milliseconds.
226-
227- let dut = Timer :: new ( & clock, & context, period) ;
238+ let dut = Timer :: new ( & clock, & context, period, create_dummy_callback ( ) ) ;
228239 assert ! ( dut. is_ok( ) ) ;
229240 let dut = dut. unwrap ( ) ;
230241 assert ! ( dut. is_canceled( ) . is_ok( ) ) ;
@@ -241,8 +252,7 @@ mod tests {
241252 let context = Context :: new ( vec ! [ ] ) . unwrap ( ) ;
242253 let period_ns: i64 = 2e6 as i64 ; // 2 milliseconds.
243254 let sleep_period_ms = time:: Duration :: from_millis ( 1 ) ;
244-
245- let dut = Timer :: new ( & clock, & context, period_ns) ;
255+ let dut = Timer :: new ( & clock, & context, period_ns, create_dummy_callback ( ) ) ;
246256 assert ! ( dut. is_ok( ) ) ;
247257 let dut = dut. unwrap ( ) ;
248258 thread:: sleep ( sleep_period_ms) ;
@@ -261,7 +271,7 @@ mod tests {
261271 let clock = Clock :: steady ( ) ;
262272 let context = Context :: new ( vec ! [ ] ) . unwrap ( ) ;
263273 let period_ns: i64 = 2e6 as i64 ; // 2 milliseconds.
264- let dut = Timer :: new ( & clock, & context, period_ns) ;
274+ let dut = Timer :: new ( & clock, & context, period_ns, create_dummy_callback ( ) ) ;
265275 assert ! ( dut. is_ok( ) ) ;
266276 let dut = dut. unwrap ( ) ;
267277 let time_until_next_call = dut. time_until_next_call ( ) ;
@@ -280,7 +290,7 @@ mod tests {
280290 let clock = Clock :: steady ( ) ;
281291 let context = Context :: new ( vec ! [ ] ) . unwrap ( ) ;
282292 let period_ns: i64 = 2e6 as i64 ; // 2 milliseconds.
283- let dut = Timer :: new ( & clock, & context, period_ns) . unwrap ( ) ;
293+ let dut = Timer :: new ( & clock, & context, period_ns, create_dummy_callback ( ) ) . unwrap ( ) ;
284294 let elapsed = period_ns - dut. time_until_next_call ( ) . unwrap ( ) ;
285295 assert ! ( elapsed < tolerance, "elapsed before reset: {}" , elapsed) ;
286296 thread:: sleep ( time:: Duration :: from_millis ( 1 ) ) ;
@@ -295,21 +305,17 @@ mod tests {
295305 let clock = Clock :: steady ( ) ;
296306 let context = Context :: new ( vec ! [ ] ) . unwrap ( ) ;
297307 let period_ns: i64 = 1e6 as i64 ; // 1 millisecond.
298- let dut = Timer :: new ( & clock, & context, period_ns) . unwrap ( ) ;
308+ let dut = Timer :: new ( & clock, & context, period_ns, create_dummy_callback ( ) ) . unwrap ( ) ;
299309 let elapsed = period_ns - dut. time_until_next_call ( ) . unwrap ( ) ;
300310 assert ! ( elapsed < tolerance, "elapsed before reset: {}" , elapsed) ;
301-
302311 thread:: sleep ( time:: Duration :: from_micros ( 1500 ) ) ;
303-
304312 let elapsed = period_ns - dut. time_until_next_call ( ) . unwrap ( ) ;
305313 assert ! (
306314 elapsed > 1500000i64 ,
307315 "time_until_next_call before call: {}" ,
308316 elapsed
309317 ) ;
310-
311318 assert ! ( dut. call( ) . is_ok( ) ) ;
312-
313319 let elapsed = dut. time_until_next_call ( ) . unwrap ( ) ;
314320 assert ! (
315321 elapsed < 500000i64 ,
@@ -323,27 +329,24 @@ mod tests {
323329 let clock = Clock :: steady ( ) ;
324330 let context = Context :: new ( vec ! [ ] ) . unwrap ( ) ;
325331 let period_ns: i64 = 1e6 as i64 ; // 1 millisecond.
326- let dut = Timer :: new ( & clock, & context, period_ns) . unwrap ( ) ;
327-
332+ let dut = Timer :: new ( & clock, & context, period_ns, create_dummy_callback ( ) ) . unwrap ( ) ;
328333 let is_ready = dut. is_ready ( ) ;
329334 assert ! ( is_ready. is_ok( ) ) ;
330335 assert ! ( !is_ready. unwrap( ) ) ;
331-
332336 thread:: sleep ( time:: Duration :: from_micros ( 1100 ) ) ;
333-
334337 let is_ready = dut. is_ready ( ) ;
335338 assert ! ( is_ready. is_ok( ) ) ;
336339 assert ! ( is_ready. unwrap( ) ) ;
337340 }
338341
339342 #[ test]
340- fn test_callback_wip ( ) {
343+ fn test_callback ( ) {
341344 let clock = Clock :: steady ( ) ;
342345 let context = Context :: new ( vec ! [ ] ) . unwrap ( ) ;
343346 let period_ns: i64 = 1e6 as i64 ; // 1 millisecond.
344347 let foo = Arc :: new ( Mutex :: new ( 0i64 ) ) ;
345348 let foo_callback = foo. clone ( ) ;
346- let dut = Timer :: new_with_callback (
349+ let dut = Timer :: new (
347350 & clock,
348351 & context,
349352 period_ns,
@@ -361,7 +364,7 @@ mod tests {
361364 let period_ns: i64 = 1e6 as i64 ; // 1 millisecond.
362365 let foo = Arc :: new ( Mutex :: new ( 0i64 ) ) ;
363366 let foo_callback = foo. clone ( ) ;
364- let dut = Timer :: new_with_callback (
367+ let dut = Timer :: new (
365368 & clock,
366369 & context,
367370 period_ns,
@@ -379,7 +382,7 @@ mod tests {
379382 let period_ns: i64 = 1e6 as i64 ; // 1 millisecond.
380383 let foo = Arc :: new ( Mutex :: new ( 0i64 ) ) ;
381384 let foo_callback = foo. clone ( ) ;
382- let dut = Timer :: new_with_callback (
385+ let dut = Timer :: new (
383386 & clock,
384387 & context,
385388 period_ns,
0 commit comments