The Interval class simplifies how you use timers and enter frame events when you need constant updates.
The Interval class also stores a map of the intervals created using the static Interval.getIntervalByRate( rate ) method. If you request two Intervals of the same rate using the getIntervalByRate method you will have references to the same Interval.
When an Interval is not running at the Interval.FRAME_RATE you can force screen updates using the updateAfterEvent() method in the IntervalEvent that is dispatched.
package com.iamavila.utils
{
import com.iamavila.events.IntervalEvent;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.events.TimerEvent;
import flash.utils.Timer;
/**
* The Interval class provides a simple interface for running code at a specified rate. You specify
* the rate of the Interval when creating it. The rate can be in milliseconds or the constant
* Interval.FRAME_RATE which represents the frame rate of the application. An Interval object will
* dispatch IntervalEvent.INTERVAL events for as long as an object is listening to it.
*
* The Interval class also provides a static method getIntervalByRate for retrieving a stored interval.
*
*/
public class Interval extends EventDispatcher
{
/**
* Represents the frame rate of the applicatioin.
*/
public static const FRAME_RATE:int = -1;
private static var intervals:Object;
/**
* The Interval class stores a map of all intervals created using this method so that only
* one interval object exists for each rate. If you want all animations running on the same frame
* rate interval you would request Interval.getIntervalByRate( Interval.FRAME_RATE ).
*/
public static function getIntervalByRate( rate:int ):Interval
{
if ( !intervals )
intervals = new Object();
if ( !intervals[ rate ] )
intervals[ rate ] = new Interval( rate );
return intervals[ rate ];
}
private var _rate:uint;
/**
* The rate in milliseconds at which the Interval is running. -1 represents the frame rate
* of the application.
*/
public function get rate():int { return _rate; }
private var dispatcher:IEventDispatcher;
private var intervalEventType:String;
/**
* Creates a new Interval object for the specified rate. Once an Interval object
* has been created you can begin listening for IntervalEvent.INTERVAL events.
*
* @param int The rate at which the Interval will dispatch IntervalEvent.INTERVAL events.
*/
public function Interval( rate:int )
{
initialize( rate );
}
/**
* @inheritDoc
*/
public override function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
{
// if no one is listening to the interval start listening to the dispatcher
if ( !hasEventListener( intervalEventType ) )
{
// if the dispatcher is a timer we have to start it manually
if ( rate != FRAME_RATE )
Timer( dispatcher ).start();
dispatcher.addEventListener( intervalEventType, triggered );
}
super.addEventListener( type, listener, useCapture, priority, useWeakReference );
}
/**
* @inheritDoc
*/
public override function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void
{
super.removeEventListener( type, listener, useCapture );
// if no one is listening to the interval stop listening to the dispatcher
if ( !hasEventListener( intervalEventType ) )
{
// if the dispatcher is a timer we have to stop it manually
if ( rate != FRAME_RATE )
Timer( dispatcher ).stop();
dispatcher.removeEventListener( intervalEventType, triggered );
}
}
private function initialize( rate:int ):void
{
_rate = rate;
if ( rate == FRAME_RATE )
{
dispatcher = new Sprite();
intervalEventType = Event.ENTER_FRAME;
}
else
{
dispatcher = new Timer( rate );
intervalEventType = TimerEvent.TIMER;
}
}
private function triggered( event:Event ):void
{
var e:IntervalEvent = new IntervalEvent( IntervalEvent.INTERVAL );
if ( rate != FRAME_RATE )
e.updateAfterEventSource = event as TimerEvent;
dispatchEvent( e );
}
}
}
Once an Interval is created you just have to start listening to it. An Interval will not be active while no one is listening to it.
Simple demo
package
{
import com.iamavila.events.IntervalEvent;
import com.iamavila.utils.Interval;
import flash.display.Sprite;
public class IntervalDemo extends Sprite
{
public function IntervalDemo()
{
var i:Interval = Interval.getIntervalByRate( 1000 );
i.addEventListener( IntervalEvent.INTERVAL, interval );
// to stop listening
// i.removeEventListener( IntervalEvent.INTERVAL, interval );
}
private function interval( event:IntervalEvent ):void
{
trace( "update" );
}
}
}