• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

RobotWebTools / rclnodejs / 20255001676

16 Dec 2025 03:01AM UTC coverage: 80.485% (-0.1%) from 80.602%
20255001676

push

github

web-flow
Add rcl_timer_set_on_reset_callback() support (#1348)

This PR adds support for the ROS 2 `rcl_timer_set_on_reset_callback()` API to rclnodejs, enabling users to register callbacks that are invoked when a timer is reset. The implementation provides both JavaScript and TypeScript APIs with corresponding native C++ bindings.

**Key Changes:**
- Added `setOnResetCallback()` and `clearOnResetCallback()` methods to the Timer class
- Implemented native C++ bindings using ThreadSafeFunction for cross-thread callback invocation
- Added comprehensive test coverage for the new callback functionality

Fix: #1330

1229 of 1704 branches covered (72.12%)

Branch coverage included in aggregate %.

4 of 8 new or added lines in 1 file covered. (50.0%)

2656 of 3123 relevant lines covered (85.05%)

456.6 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.53
/lib/timer.js
1
// Copyright (c) 2017 Intel Corporation. All rights reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
'use strict';
16

17
const rclnodejs = require('./native_loader.js');
26✔
18
const DistroUtils = require('./distro.js');
26✔
19

20
/**
21
 * @class - Class representing a Timer in ROS
22
 * @hideconstructor
23
 */
24

25
class Timer {
26
  constructor(handle, period, callback) {
27
    this._handle = handle;
59✔
28
    this._period = period;
59✔
29
    this.callback = callback;
59✔
30
  }
31

32
  /**
33
   * @type {bigint} - The period of the timer in nanoseconds.
34
   */
35
  get period() {
36
    return this._period;
3✔
37
  }
38

39
  get handle() {
40
    return this._handle;
9,274✔
41
  }
42

43
  /**
44
   * Check if the timer is ready.
45
   * @return {boolean} Return true if timer is ready, otherwise return false.
46
   */
47
  isReady() {
48
    return rclnodejs.isTimerReady(this._handle);
4,675✔
49
  }
50

51
  /**
52
   * Check if the timer is canceled.
53
   * @return {boolean} Return true if timer is canceled, otherwise return false.
54
   */
55
  isCanceled() {
56
    return rclnodejs.isTimerCanceled(this._handle);
3,008✔
57
  }
58

59
  /**
60
   * Cancel the timer.
61
   * @return {undefined}
62
   */
63
  cancel() {
64
    rclnodejs.cancelTimer(this._handle);
48✔
65
  }
66

67
  /**
68
   * Reset the timer.
69
   * @return {undefined}
70
   */
71
  reset() {
72
    rclnodejs.resetTimer(this._handle);
3✔
73
  }
74

75
  /**
76
   * Get the interval since the last call of this timer.
77
   * @return {bigint} - the interval value in nanoseconds.
78
   */
79
  timeSinceLastCall() {
80
    return rclnodejs.timerGetTimeSinceLastCall(this._handle);
1✔
81
  }
82

83
  /**
84
   * Get the interval until the next call will happen.
85
   * @return {bigint} - the interval value in nanoseconds.
86
   */
87
  timeUntilNextCall() {
88
    return rclnodejs.timerGetTimeUntilNextCall(this._handle);
1✔
89
  }
90

91
  /**
92
   * Change the timer period.
93
   * @param {bigint} period - The new period in nanoseconds.
94
   * @return {undefined}
95
   */
96
  changeTimerPeriod(period) {
97
    rclnodejs.changeTimerPeriod(this._handle, period);
1✔
98
  }
99

100
  /**
101
   * Get the timer period.
102
   * @return {bigint} - The period in nanoseconds.
103
   */
104
  get timerPeriod() {
105
    return rclnodejs.getTimerPeriod(this._handle);
2✔
106
  }
107

108
  /**
109
   * Set the on reset callback.
110
   * @param {function} callback - The callback to be called when the timer is reset.
111
   * @return {undefined}
112
   */
113
  setOnResetCallback(callback) {
114
    if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
2!
NEW
115
      console.warn(
×
116
        'setOnResetCallback is not supported by this version of ROS 2'
117
      );
NEW
118
      return;
×
119
    }
120
    rclnodejs.setTimerOnResetCallback(this._handle, callback);
2✔
121
  }
122

123
  /**
124
   * Clear the on reset callback.
125
   * @return {undefined}
126
   */
127
  clearOnResetCallback() {
128
    if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
1!
NEW
129
      console.warn(
×
130
        'clearOnResetCallback is not supported by this version of ROS 2'
131
      );
NEW
132
      return;
×
133
    }
134
    rclnodejs.clearTimerOnResetCallback(this._handle);
1✔
135
  }
136

137
  /**
138
   * Call a timer and starts counting again, retrieves actual and expected call time.
139
   * @return {object} - The timer information.
140
   */
141
  callTimerWithInfo() {
142
    if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
1!
143
      console.warn(
×
144
        'callTimerWithInfo is not supported by this version of ROS 2'
145
      );
146
      return;
×
147
    }
148
    return rclnodejs.callTimerWithInfo(this._handle);
1✔
149
  }
150
}
151

152
module.exports = Timer;
26✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc