|
1 | 1 | use crate::{ |
2 | 2 | clock::Clock, context::Context, error::RclrsError, rcl_bindings::*, to_rclrs_result |
3 | 3 | }; |
| 4 | +// use std::fmt::Debug; |
4 | 5 | use std::sync::{Arc, Mutex}; |
5 | 6 |
|
| 7 | +pub type TimerCallback = Box<dyn FnMut(i64) + Send + Sync>; |
6 | 8 |
|
7 | | - |
8 | | -pub trait TimerCallback { |
9 | | - fn call(time_since_last_callback_ns: i64); |
10 | | -} |
11 | | - |
12 | | -#[derive(Debug)] |
| 9 | +// #[derive(Debug)] |
13 | 10 | pub struct Timer { |
14 | 11 | rcl_timer: Arc<Mutex<rcl_timer_t>>, |
15 | | - // callback: Option<T>, |
| 12 | + callback: Option<TimerCallback>, |
16 | 13 | } |
17 | 14 |
|
18 | 15 | impl Timer { |
| 16 | + |
19 | 17 | pub fn new(clock: &Clock, context: &Context, period: i64) -> Result<Timer, RclrsError> { |
| 18 | + Self::with_callback(clock, context, period, None) |
| 19 | + } |
| 20 | + |
| 21 | + pub fn with_callback(clock: &Clock, context: &Context, period: i64, callback: Option<TimerCallback>) -> Result<Timer, RclrsError> { |
20 | 22 | let mut rcl_timer; |
21 | 23 | let timer_init_result = unsafe { |
22 | 24 | // SAFETY: Getting a default value is always safe. |
23 | 25 | rcl_timer = rcl_get_zero_initialized_timer(); |
24 | 26 | let allocator = rcutils_get_default_allocator(); |
25 | 27 | let mut rcl_clock = clock.rcl_clock.lock().unwrap(); |
26 | 28 | let mut rcl_context = context.handle.rcl_context.lock().unwrap(); |
27 | | - let callback: rcl_timer_callback_t = None; |
| 29 | + // Callbacks will be handled in the WaitSet. |
| 30 | + let rcl_timer_callback: rcl_timer_callback_t = None; |
28 | 31 | // Function will return Err(_) only if there isn't enough memory to allocate a clock |
29 | 32 | // object. |
30 | 33 | rcl_timer_init( |
31 | 34 | &mut rcl_timer, |
32 | 35 | &mut *rcl_clock, |
33 | 36 | &mut *rcl_context, |
34 | 37 | period, |
35 | | - callback, |
| 38 | + rcl_timer_callback, |
36 | 39 | allocator, |
37 | 40 | ) |
38 | 41 | }; |
39 | 42 | to_rclrs_result(timer_init_result).map(|_| { |
40 | 43 | Timer { |
41 | 44 | rcl_timer: Arc::new(Mutex::new(rcl_timer)), |
42 | | - // callback: None |
| 45 | + callback, |
43 | 46 | } |
44 | 47 | }) |
45 | 48 | } |
@@ -319,4 +322,16 @@ mod tests { |
319 | 322 | assert!(is_ready.is_ok()); |
320 | 323 | assert!(is_ready.unwrap()); |
321 | 324 | } |
| 325 | + |
| 326 | + #[test] |
| 327 | + fn test_callback_wip() { |
| 328 | + let clock = Clock::steady(); |
| 329 | + let context = Context::new(vec![]).unwrap(); |
| 330 | + let period_ns: i64 = 1e6 as i64; // 1 millisecond. |
| 331 | + let foo = Arc::new(Mutex::new(0i64)); |
| 332 | + let foo_callback = foo.clone(); |
| 333 | + let dut = Timer::with_callback(&clock, &context, period_ns, Some(Box::new(move |x| *foo_callback.lock().unwrap() = x ))).unwrap(); |
| 334 | + dut.callback.unwrap()(123); |
| 335 | + assert_eq!(*foo.lock().unwrap(), 123); |
| 336 | + } |
322 | 337 | } |
0 commit comments