@@ -256,8 +256,13 @@ class Node extends rclnodejs.ShadowNode {
256256
257257 timersReady . forEach ( ( timer ) => {
258258 if ( timer . isReady ( ) ) {
259- rclnodejs . callTimer ( timer . handle ) ;
260- timer . callback ( ) ;
259+ let timerInfo ;
260+ if ( typeof rclnodejs . callTimerWithInfo === 'function' ) {
261+ timerInfo = rclnodejs . callTimerWithInfo ( timer . handle ) ;
262+ } else {
263+ rclnodejs . callTimer ( timer . handle ) ;
264+ }
265+ timer . callback ( timerInfo ) ;
261266 }
262267 } ) ;
263268
@@ -628,15 +633,43 @@ class Node extends rclnodejs.ShadowNode {
628633 /**
629634 * Create a Timer.
630635 * @param {bigint } period - The number representing period in nanoseconds.
631- * @param {function } callback - The callback to be called when timeout.
632- * @param {Clock } [clock] - The clock which the timer gets time from.
636+ * @param {function } callback - The callback to be called when the timer fires.
637+ * On distros with native support, the callback receives a `TimerInfo` object
638+ * describing the expected and actual call time.
639+ * @param {object|Clock } [optionsOrClock] - Timer options or the clock which the timer gets time from.
640+ * Supported options: `{ autostart?: boolean }`.
641+ * @param {Clock } [clock] - The clock which the timer gets time from when options are provided.
633642 * @return {Timer } - An instance of Timer.
634643 */
635- createTimer ( period , callback , clock = null ) {
636- if ( arguments . length === 3 && ! ( arguments [ 2 ] instanceof Clock ) ) {
637- clock = null ;
638- } else if ( arguments . length === 4 ) {
639- clock = arguments [ 3 ] ;
644+ createTimer ( period , callback , optionsOrClock = null , clock = null ) {
645+ let options = { } ;
646+
647+ if ( optionsOrClock instanceof Clock . Clock ) {
648+ clock = optionsOrClock ;
649+ } else if ( optionsOrClock === null || optionsOrClock === undefined ) {
650+ // Keep the 4th argument as the clock when the 3rd argument is omitted or explicitly null.
651+ } else {
652+ if ( typeof optionsOrClock !== 'object' || Array . isArray ( optionsOrClock ) ) {
653+ throw new TypeValidationError (
654+ 'options' ,
655+ optionsOrClock ,
656+ 'object or Clock' ,
657+ {
658+ nodeName : this . name ( ) ,
659+ }
660+ ) ;
661+ }
662+ options = optionsOrClock ;
663+ }
664+
665+ if (
666+ arguments . length === 4 &&
667+ clock !== null &&
668+ ! ( clock instanceof Clock . Clock )
669+ ) {
670+ throw new TypeValidationError ( 'clock' , clock , 'Clock' , {
671+ nodeName : this . name ( ) ,
672+ } ) ;
640673 }
641674
642675 if ( typeof period !== 'bigint' ) {
@@ -649,12 +682,27 @@ class Node extends rclnodejs.ShadowNode {
649682 nodeName : this . name ( ) ,
650683 } ) ;
651684 }
685+ if (
686+ options . autostart !== undefined &&
687+ typeof options . autostart !== 'boolean'
688+ ) {
689+ throw new TypeValidationError (
690+ 'options.autostart' ,
691+ options . autostart ,
692+ 'boolean' ,
693+ {
694+ nodeName : this . name ( ) ,
695+ }
696+ ) ;
697+ }
652698
653699 const timerClock = clock || this . _clock ;
700+ const autostart = options . autostart ?? true ;
654701 let timerHandle = rclnodejs . createTimer (
655702 timerClock . handle ,
656703 this . context . handle ,
657- period
704+ period ,
705+ autostart
658706 ) ;
659707 let timer = new Timer ( timerHandle , period , callback ) ;
660708 debug ( 'Finish creating timer, period = %d.' , period ) ;
0 commit comments