Skip to content

Commit 655185d

Browse files
committed
Improvements to timer.
- Adds documentation. - Removes the no-callback constructor. - Removes vertical space. Signed-off-by: Agustin Alba Chicar <[email protected]>
1 parent a4c1a97 commit 655185d

File tree

3 files changed

+46
-44
lines changed

3 files changed

+46
-44
lines changed

rclrs/src/node.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ impl Node {
356356
Some(value) => value,
357357
None => self.get_clock(),
358358
};
359-
let timer = Timer::new_with_callback(&clock_used, &context, period_ns, callback)?;
359+
let timer = Timer::new(&clock_used, &context, period_ns, callback)?;
360360
let timer = Arc::new(timer);
361361
self.timers_mtx
362362
.lock()
@@ -591,12 +591,8 @@ mod tests {
591591
.namespace("test_create_timer")
592592
.build()?;
593593

594-
let _timer = dut.create_timer(
595-
timer_period_ns,
596-
&context,
597-
Some(Box::new(move |_| { })),
598-
None,
599-
)?;
594+
let _timer =
595+
dut.create_timer(timer_period_ns, &context, Some(Box::new(move |_| {})), None)?;
600596
assert_eq!(dut.live_timers().len(), 1);
601597

602598
Ok(())

rclrs/src/timer.rs

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,35 @@
11
use 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;
34
use std::sync::{atomic::AtomicBool, Arc, Mutex};
45

6+
/// Type alias for the `Timer` callback.
57
pub 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)]
823
pub 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

1430
impl 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,

rclrs/src/wait.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ impl WaitSet {
466466
mod tests {
467467
use super::*;
468468
use crate::clock::Clock;
469+
use crate::timer::TimerCallback;
469470

470471
#[test]
471472
fn traits() {
@@ -496,7 +497,8 @@ mod tests {
496497
let context = Context::new([])?;
497498
let clock = Clock::steady();
498499
let period: i64 = 1e6 as i64; // 1 millisecond.
499-
let timer = Arc::new(Timer::new(&clock, &context, period)?);
500+
let callback: Option<TimerCallback> = Some(Box::new(move |_| {}));
501+
let timer = Arc::new(Timer::new(&clock, &context, period, callback)?);
500502

501503
let mut wait_set = WaitSet::new(0, 0, 1, 0, 0, 0, &context)?;
502504
wait_set.add_timer(timer.clone())?;
@@ -512,7 +514,8 @@ mod tests {
512514
let context = Context::new([])?;
513515
let clock = Clock::steady();
514516
let period: i64 = 1e6 as i64; // 1 millisecond.
515-
let timer = Arc::new(Timer::new(&clock, &context, period)?);
517+
let callback: Option<TimerCallback> = Some(Box::new(move |_| {}));
518+
let timer = Arc::new(Timer::new(&clock, &context, period, callback)?);
516519

517520
let mut wait_set = WaitSet::new(0, 0, 1, 0, 0, 0, &context)?;
518521
wait_set.add_timer(timer.clone())?;

0 commit comments

Comments
 (0)