LowRA API Documentation Annexes |  All Packages |  All Classes |  Index |  Frames
How to use LoopCommand and IterationCommand
 

A brief introduction to loop and iteration commands

LoopCommand and IterationCommand are a representation of the traditionnal loop statements (such for and while) as asynchronous commands.

The main idea is that loop command represent the statement itself, and iteration command represent the inner statement part. For example, in the statement below :

while( i.hasNext() )
{
	trace( i.next() );
}

The part below is transformed in a LoopCommand object :

while( i.hasNext() )

All the part below is transformed in an IterationCommand :

{
	trace( i.next() );
}

Loop commands favour Iterator based statement instead of traditionnal for and for...each statements, even if it is always possible to regain these behavior with the general purpose iterators (StringIterator, ArrayIterator and ObjectIterator). You can although create your own custom iterator which doesn't need to process iteration in a regular way (iterate from 0 to size(), elements by elements).


How the LoopCommand iterate over elements

When creating a LoopCommand object, you also define the concret iteration command associated with it. When starting the loop (with the run or execute methods) the loop command get an iterator from the iteration command, and then will starts its process by register itself as listener of a TickBeacon instance. At each tick, and while the current execution time is not greater than the max execution time per tick limit of this loop command, the loop while realize as many iterations as possible. Iteration are defined as a call to the execute method of the IterationCommand instance, with an IterationEvent as argument. The iteration command now can perform its action with the data carried by the event object.

Below an example of a concret IterationCommand based on the real statement above.

package 
{
	import flash.events.Event;

	import com.bourre.commands.AbstractIterationCommand;
	import com.bourre.commands.IterationEvent;
	
	class TraceIteration extends AbstractIterationCommand
	{
		override public function execute ( e : Event = null ) : void
		{
			trace ( ( e as IterationEvent ).getValue() );
		}
	}	
}	
Afterwards, the code below creates a LoopCommand and start it :
package
{
	import flash.display.Sprite;
	import flash.event.Event;
	
	import com.bourre.collection.Iterator;
	import com.bourre.collection.ArrayIterator;
	import com.bourre.commands.LoopCommand;
	import com.bourre.commands.LoopCommandListener;
	import com.bourre.events.LoopEvent;
	
	class LoopCommandDemo extends Sprite implements LoopCommandListener
	{
		private var _oLoop : LoopCommand;
		
		public function LoopCommandDemo ()
		{
			// create an iterator over array elements
			var a : Array = new Array( 0,1,2,3,4,5,6,7,8,9 );
			var i : Iterator = new ArrayIterator( a );
			
			// create the concret iteration command
			var iteration : TraceIteration( i );
			
			// create the loop and register this as listener
			_oLoop = new LoopCommand ( iteration );
			_oLoop.addLoopCommandListener ( this );
			
			// start the loop
			_oLoop.execute();
		}
		
		public function onLoopStart( e : LoopEvent ) : void
		{
			trace ( "loop started" );
		}
		
		public function onLoopStop( e : LoopEvent ) : void
		{
			trace ( "loop stopped" );
		}
		
		public function onLoopProgress( e : LoopEvent ) : void
		{
			trace ( "loop progressed to " + e.getCount() + "iterations in one step" );
		}

		public function onLoopEnd( e : LoopEvent ) : void
		{
			trace ( "loop finished after " + e.getCount() + " iterations" );
		}
		
		public function onLoopCancel( e : LoopEvent ) : void
		{
			trace ( "loop cancelled after " + e.getCount() + " iterations" );
		}
		
		public function onCommandEnd( e : Event ) : void {}
	}
}
In the example above, the amount of iteration is not significant enough to take more time than the default execution time limit (15ms) so the output should look like that :
loop started
0
1
2
3
4
5
6
7
8
9
loop progressed to 10 iterations in one step
loop finished after 10 iterations	
Now, let say that we replace the execute method of our TraceIteration command by :
override public function execute ( e : Event = null ) : void
{
	var t : Number = getTimer();
	// forcing an execution time of 5ms
	while( getTimer() - t < 5 );
	
	trace ( ( e as IterationEvent ).getValue() );
}	
As the max execution time is set to 15 ms the output should look like :
loop started
0
1
2
loop progressed to 3 iterations in one step
3
4
5
loop progressed to 6 iterations in one step
6
7
8
loop progressed to 9 iterations in one step
9
loop progressed to 10 iterations in one step
loop finished after 10 iterations