Skip to content

Instantly share code, notes, and snippets.

@vizio360
Created September 17, 2010 21:28
Show Gist options
  • Save vizio360/584993 to your computer and use it in GitHub Desktop.
Save vizio360/584993 to your computer and use it in GitHub Desktop.
Frame Distributed Loop AS3
/**
* The MIT License
*
* Copyright (c) 2010 Simone Vicentini - vizio360
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package
{
import flash.display.Stage;
import flash.events.Event;
import flash.utils.getTimer;
/**
* Class in charge of split the execution of a for loop
* onto multiple frames to don't affect the frame rate of the application.
*/
public class FrameDistributedLoop
{
protected var frameRateProvider:Stage;
protected var time:Number;
protected var iteratorValue:int;
protected var condition:Function;
protected var countingExpression:Function;
protected var onComplete:Function;
protected var percentage:Number;
protected var loopBody: Function;
/**
* @frameRateProvider Can only be a reference to the Stage.
*
* @note It can only be the stage because the class needs the
* frame rate information which is only available through the stage reference,
* and it needs to attach a listener to the ENTER_FRAME event.
*/
public function FrameDistributedLoop(frameRateProvider:Stage)
{
this.frameRateProvider = frameRateProvider;
}
private function onForILoopEnterFrame(event: Event): void
{
time = getTimer();
while (this.condition(iteratorValue))
{
this.loopBody(iteratorValue);
iteratorValue = this.countingExpression(iteratorValue);
if (getTimer() - time > this.percentage)
break;
}
if (!this.condition(iteratorValue))
{
frameRateProvider.removeEventListener(Event.ENTER_FRAME, onForILoopEnterFrame);
this.onComplete();
}
}
/**
* Resets the FrameDistributedLoop and if a loop is running it will be stopped,
* and no notification will be sent out.
*/
public function destroy():void
{
frameRateProvider.removeEventListener(Event.ENTER_FRAME, onForILoopEnterFrame);
frameRateProvider = null;
}
/**
* Executes a for i loop over multiple frames using a specific percentage of frame execution time for each frame
*
* @param percentage The percentage of frame time to use for the loop execution
* @param initValue Initial value of i
* @param condition Function to define when the loop is finished. THIS FUNCTION NEEDS TO RETURN A BOOLEAN VALUE.
* @param loopBody Function where to execute the logics for your loop.
* @param countingExpression Function where to alterate (increment, decrement) the loop iterator.
* @param onComplete Function called when the loop has finished.
*
* @note condition, body and countingExpression functions all receive the iterator i as parameter.
*
*/
public function foriLoop(percentage:Number, initValue:int, condition:Function, loopBody:Function, countingExpression:Function, onComplete:Function):void
{
iteratorValue = initValue;
this.condition = condition;
this.loopBody = loopBody;
this.countingExpression = countingExpression;
this.onComplete = onComplete;
this.percentage = 1000 / frameRateProvider.frameRate * percentage;
frameRateProvider.addEventListener(Event.ENTER_FRAME, onForILoopEnterFrame);
}
}
}
package
{
import flash.display.Sprite;
public class TestDistributedLoopsTrace extends Sprite
{
private var dl:FrameDistributedLoop;
public function TestDistributedLoopsTrace()
{
startTest();
}
protected function startTest():void
{
dl = new FrameDistributedLoop(stage);
dl.foriLoop(0.5, 0, mycondition, mylogics, mypostoperator, oncomplete);
}
private function oncomplete(): void
{
trace("Complete!");
}
private function mypostoperator(i:int): int
{
return ++i;
}
private function mylogics(i:int): void
{
trace(i);
}
private function mycondition(i:int): Boolean
{
return i < int.MAX_VALUE;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment