Author Topic: PJSR Timer example  (Read 4365 times)

Offline kwiechen

  • PixInsight Addict
  • ***
  • Posts: 186
PJSR Timer example
« on: 2014 September 01 11:31:18 »
Is there a small code example to use the PJSR Timer object?

Best regards,

Kai


Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Re: PJSR Timer example
« Reply #1 on: 2014 September 10 04:12:43 »
Hi Kai,

Sorry for the late answer. Here we go:

Code: [Select]
/*
 * Timer object demo script.
 */

#include <pjsr/TextAlign.jsh>

function TimerDemoDialog()
{
   this.__base__ = Dialog;
   this.__base__();

   //

   this.currentTime_Label = new Label( this );
   this.currentTime_Label.text = (new Date).toLocaleString();
   this.currentTime_Label.styleSheet = "QLabel { font-size: 24pt; }";
   this.currentTime_Label.restyle();
   this.currentTime_Label.minWidth = this.currentTime_Label.font.width( this.currentTime_Label.text + "MMM" );
   this.currentTime_Label.textAlignment = TextAlign_Center|TextAlign_VertCenter;

   //

   this.currentTime_Timer = new Timer;
   this.currentTime_Timer.interval = 1.0;  // timing interval in seconds
   this.currentTime_Timer.periodic = true; // periodic or single shot timer
   this.currentTime_Timer.dialog = this;   // necessary because Timer is not a Control object
   this.currentTime_Timer.onTimeout = function()
   {
      this.dialog.currentTime_Label.text = (new Date).toLocaleString();
   };

   //

   this.ok_Button = new PushButton( this );
   this.ok_Button.text = "OK";
   this.ok_Button.onClick = function()
   {
      this.dialog.ok();
   };

   this.buttons_Sizer = new HorizontalSizer;
   this.buttons_Sizer.addStretch();
   this.buttons_Sizer.add( this.ok_Button );
   this.buttons_Sizer.addStretch();

   //

   this.sizer = new VerticalSizer;
   this.sizer.margin = 8;
   this.sizer.spacing = 8;
   this.sizer.add( this.currentTime_Label );
   this.sizer.add( this.buttons_Sizer );

   this.windowTitle = "Timer Demo";
   this.adjustToContents();
   this.setFixedSize();

   //

   this.onShow = function()
   {
      this.currentTime_Timer.start();
   };

   this.onHide = function()
   {
      this.currentTime_Timer.stop();
   };
}

TimerDemoDialog.prototype = new Dialog;

(new TimerDemoDialog()).execute();

Using the Timer object is pretty straightforward. The following points are worth mentioning in the above script:

- Call the Timer.start() method to fire up the timer. The object's Timer.onTimeout() event handler will be called as soon as its Timer.interval has elapsed. If the Timer.periodic property has been set to true, onTimeout() will be called successively at regular intervals (this is a periodic timer). Otherwise it will only be called once (that's what we know as a single shot timer).

- Call the Timer.stop() method to stop the timer. Very important: Do this for all timers you have created before your script terminates execution. The best and most secure way to stop timers is in a Dialog.onHide() event handler, as shown on the demo script.

- Timer.onTimeout() will always be called asynchronously. This means that the event handler can be called anywhere during your script's execution. However, Timer relies on a dialog's event loop to generate timer events, so if you block normal UI event processing for too long, one or more calls to onTimeout() may be missed. Once normal event processing is restored, Timer will try to do its best to continue generation of timer events with the required frequency. If this causes problems during long calculation routines, you can call processEvents() from within a long running loop to allow delivery of pending events.

- Unfortunately, there's a small bug in version 1.9.8 of the PixInsight Core application that affects Timer's constructor:

new Timer( [Number interval=1.0[, Boolean periodic=true]] )

The bug consists in that the constructor's arguments are swapped internally, so Boolean and Number are expected in this order, which is the opposite to what it should be. This has been fixed in the next version that we'll release soon. To avoid this bug, either use conditional preprocessor directives, or simply assign the Timer.interval and Timer.periodic properties individually, as I've done in the demo script.

Let me know if this helps.
Juan Conejero
PixInsight Development Team
http://pixinsight.com/