/**
* Encapsulates the setInterval() and clearInterval() calls into a handy class.
*
* @author David Nadlinger
* @version $Id: Timer.as 3 2006-12-18 19:13:35Z aule $
*/
class at.klickverbot.util.Timer {
/**
* Constructor.
* @param interval The timer interval.
* @param numTriggerings The number of triggerings after which the timer is stopped
* @param numTriggerings (null for no limit).
* @param callback The callback function when the timer triggers.
*/
public function Timer( interval :Number, numTriggerings :Number,
callback :Function ) {
m_running = false;
m_interval = interval;
m_triggeringCount = 0;
m_numTriggerings = numTriggerings;
m_callbackFunctions = new Array();
if ( callback != null ) {
addCallback( callback );
}
}
/**
* Starts the timer.
* Keep in mind that this function doesn't reset the triggering count.
* @return If the timer could be started (resp. if it was not already running)
* @see #stop
* @see #resetCount
*/
public function start() :Boolean {
// We can't start the timer if it's already running
if ( m_running ) {
return false;
}
m_timerId = setInterval( this, "intervalCallback", m_interval );
m_running = true;
}
/**
* Stops the timer.
* Keep in mind that this function doesn't reset the triggering count.
* @return If the timer could be stopped (resp. if it was running)
* @see #start
* @see #resetCount
*/
public function stop() :Boolean {
// We can't stop the timer if it isn't running
if ( !m_running ) {
return false;
}
clearInterval( m_timerId );
m_running = false;
}
/**
* Resets the triggering count to zero.
* Timer must be stopped to do this.
* @see #triggeringCount
* @see #numTriggerings
*/
public function resetCount() :Boolean {
// The triggering count can't be reset when the timer is running.
// This is a design choice – it may cause two extra code lines, but it is
// better understandable.
if ( m_running ) {
return false;
}
m_triggeringCount = 0;
}
/**
* Adds a function to the list of callback functions.
* The callback functions get called when the timer triggers.
* The 'callback'-parameter of the constuctor is the first item in the list,
* but you can add multiple other functions.
* @param callback The callback function to add to the list.
* @see #removeCallback
*/
public function addCallback( callback :Function ) :Void {
removeCallback( callback );
m_callbackFunctions.push( callback );
}
/**
* Remove a function from the list of callback functions.
* @param callback The callback function to remove from the list.
* @return If the function could be removed (resp. if it was in the list).
* @see #addCallback
*/
public function removeCallback( callback :Function ) :Boolean {
for ( var i :Number = 0; i < m_callbackFunctions.length; ++i ) {
if ( m_callbackFunctions[ i ] === callback ) {
m_callbackFunctions.splice( i, 1 );
return true;
}
}
return false;
}
/**
* The interval between timer triggerings in milliseconds.
*/
public function get interval() :Number {
return m_interval;
}
public function set interval( to :Number ) :Void {
// No interval shorter than one millisecond is possible
if ( to < 1 ) {
return;
}
m_interval = to;
if ( m_running ) {
this.stop();
this.start();
}
}
/**
* The number of triggerings after which the timer is stopped
* (zero for no limit).
*/
public function get numTriggerings() :Number {
return m_numTriggerings;
}
public function set numTriggerings( to :Number ) :Void {
// So trigger limit smaller than 0 (which means no limit) is possible
if ( to < 0 ) {
return;
}
m_numTriggerings = to;
}
/**
* The current triggering count. (read-only)
* @see #numTriggerings
*/
public function get triggeringCount() :Number {
return m_triggeringCount;
}
/**
* Internal callback function.
*/
private function intervalCallback() :Void {
++m_triggeringCount;
if ( m_triggeringCount == m_numTriggerings ) {
this.stop();
}
for ( var i :Number = 0; i < m_callbackFunctions.length; i++ ) {
m_callbackFunctions[ i ]( m_triggeringCount );
}
}
private var m_interval :Number;
private var m_triggeringCount :Number;
private var m_numTriggerings :Number;
private var m_running :Boolean;
private var m_timerId :Number;
private var m_callbackFunctions :Array;
}