Skip to content

Commit 7d93965

Browse files
committed
Add missing functions for timer (#1108)
This PR adds missing timer functionalities and their corresponding unit tests. The key changes include: - New unit tests for timer operations in test/test-timer.js. - New timer binding functions in src/rcl_timer_bindings.cpp to support period retrieval, timer period change, and timer call information. - New Timer class methods and getter in lib/timer.js to expose the newly added timer functionalities. Fix: #1109
1 parent d90996a commit 7d93965

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

lib/timer.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,31 @@ class Timer {
8686
timeUntilNextCall() {
8787
return rclnodejs.timerGetTimeUntilNextCall(this._handle);
8888
}
89+
90+
/**
91+
* Change the timer period.
92+
* @param {bigint} period - The new period in nanoseconds.
93+
* @return {undefined}
94+
*/
95+
changeTimerPeriod(period) {
96+
rclnodejs.changeTimerPeriod(this._handle, period);
97+
}
98+
99+
/**
100+
* Get the timer period.
101+
* @return {bigint} - The period in nanoseconds.
102+
*/
103+
get timerPeriod() {
104+
return rclnodejs.getTimerPeriod(this._handle);
105+
}
106+
107+
/**
108+
* Call a timer and starts counting again, retrieves actual and expected call time.
109+
* @return {object} - The timer information.
110+
*/
111+
callTimerWithInfo() {
112+
return rclnodejs.callTimerWithInfo(this._handle);
113+
}
89114
}
90115

91116
module.exports = Timer;

src/rcl_timer_bindings.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,60 @@ Napi::Value TimerGetTimeSinceLastCall(const Napi::CallbackInfo& info) {
159159
return Napi::BigInt::New(env, elapsed_time);
160160
}
161161

162+
Napi::Value ChangeTimerPeriod(const Napi::CallbackInfo& info) {
163+
Napi::Env env = info.Env();
164+
165+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
166+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
167+
168+
if (!info[1].IsBigInt()) {
169+
Napi::TypeError::New(env, "Timer period must be a BigInt")
170+
.ThrowAsJavaScriptException();
171+
return env.Undefined();
172+
}
173+
174+
bool lossless;
175+
int64_t period_nsec = info[1].As<Napi::BigInt>().Int64Value(&lossless);
176+
int64_t old_period;
177+
THROW_ERROR_IF_NOT_EQUAL(
178+
RCL_RET_OK, rcl_timer_exchange_period(timer, period_nsec, &old_period),
179+
rcl_get_error_string().str);
180+
181+
return env.Undefined();
182+
}
183+
184+
Napi::Value GetTimerPeriod(const Napi::CallbackInfo& info) {
185+
Napi::Env env = info.Env();
186+
187+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
188+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
189+
int64_t period_nsec = 0;
190+
191+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK,
192+
rcl_timer_get_period(timer, &period_nsec),
193+
rcl_get_error_string().str);
194+
195+
return Napi::BigInt::New(env, period_nsec);
196+
}
197+
198+
Napi::Value CallTimerWithInfo(const Napi::CallbackInfo& info) {
199+
Napi::Env env = info.Env();
200+
RclHandle* timer_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
201+
rcl_timer_t* timer = reinterpret_cast<rcl_timer_t*>(timer_handle->ptr());
202+
rcl_timer_call_info_t call_info;
203+
204+
THROW_ERROR_IF_NOT_EQUAL(RCL_RET_OK,
205+
rcl_timer_call_with_info(timer, &call_info),
206+
rcl_get_error_string().str);
207+
208+
Napi::Object timer_info = Napi::Object::New(env);
209+
timer_info.Set("expectedCallTime",
210+
Napi::BigInt::New(env, call_info.expected_call_time));
211+
timer_info.Set("actualCallTime",
212+
Napi::BigInt::New(env, call_info.actual_call_time));
213+
return timer_info;
214+
}
215+
162216
Napi::Object InitTimerBindings(Napi::Env env, Napi::Object exports) {
163217
exports.Set("createTimer", Napi::Function::New(env, CreateTimer));
164218
exports.Set("isTimerReady", Napi::Function::New(env, IsTimerReady));
@@ -170,6 +224,9 @@ Napi::Object InitTimerBindings(Napi::Env env, Napi::Object exports) {
170224
Napi::Function::New(env, TimerGetTimeSinceLastCall));
171225
exports.Set("timerGetTimeUntilNextCall",
172226
Napi::Function::New(env, TimerGetTimeUntilNextCall));
227+
exports.Set("changeTimerPeriod", Napi::Function::New(env, ChangeTimerPeriod));
228+
exports.Set("getTimerPeriod", Napi::Function::New(env, GetTimerPeriod));
229+
exports.Set("callTimerWithInfo", Napi::Function::New(env, CallTimerWithInfo));
173230
return exports;
174231
}
175232

test/test-timer.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,5 +137,29 @@ describe('rclnodejs Timer class testing', function () {
137137
});
138138
rclnodejs.spin(node);
139139
});
140+
141+
it('timer.timerPeriod', function (done) {
142+
const timer = node.createTimer(BigInt('100000000'), () => {});
143+
assert.deepStrictEqual(timer.timerPeriod, BigInt('100000000'));
144+
timer.cancel();
145+
done();
146+
});
147+
148+
it('timer.changeTimerPeriod', function (done) {
149+
const timer = node.createTimer(BigInt('100000000'), () => {});
150+
timer.changeTimerPeriod(BigInt('200000000'));
151+
assert.deepStrictEqual(timer.timerPeriod, BigInt('200000000'));
152+
timer.cancel();
153+
done();
154+
});
155+
156+
it('timer.callTimerWithInfo', function (done) {
157+
const timer = node.createTimer(BigInt('100000000'), () => {});
158+
const info = timer.callTimerWithInfo();
159+
assert.deepStrictEqual(typeof info.expectedCallTime, 'bigint');
160+
assert.deepStrictEqual(typeof info.actualCallTime, 'bigint');
161+
timer.cancel();
162+
done();
163+
});
140164
});
141165
});

0 commit comments

Comments
 (0)