Tight Loop Test
think about light weight implementation ov cancelable tight loop.
/**
* Copyright Test_Dept ( http://wonderfl.net/user/Test_Dept )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/3JFW
*/
package {
import flash.display.Sprite;
/**
* TightLoopTest
* @author Test_Dept
*/
public class TightLoopTest extends Sprite {
public function TightLoopTest() {
addChild(new TightLoop() );
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.utils.getTimer;
class TightLoop extends Sprite {
private var _script : Script = null;
private var _bitmap : BitmapData = null;
private const _colors : Array = [
0xff0000, 0xffff00, 0x00ff00, 0x00ffff, 0x0000ff, 0xff00ff
];
private var _colorIndex : int = 0;
public function TightLoop() {
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
protected function addedToStageHandler(event : Event) : void {
_bitmap = new BitmapData(stage.stageWidth, stage.stageHeight, false);
addChild(new Bitmap(_bitmap) );
addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
protected function mouseDownHandler(event : Event) : void {
var fillColor : uint = _colors[_colorIndex];
_colorIndex = (_colorIndex + 1) % _colors.length;
var fillColor2 : uint = _colors[_colorIndex];
const cx : Number = _bitmap.width / 2;
const cy : Number = _bitmap.height / 2;
// build script
_script = new Script({});
_script.$for("y", 0, _bitmap.height - 1)(function() : void {
_script.$for("x", 0, _bitmap.width - 1)(function() : void {
_script.$call(function() : * {
var x : Number = (_script.host.x - cx) / cy;
var y : Number = (_script.host.y - cy) / cy;
var m : int = calcMandelbrot(x, y);
_bitmap.setPixel(_script.host.x, _script.host.y,
(m % 2 == 0)? fillColor: fillColor2);
// _bitmap.setPixel(_script.host.x, _script.host.y, fillColor);
} );
} );
} );
}
private function calcMandelbrot(x : Number, y : Number) : int {
const limit : int = 1000;
const x0 : Number = x;
const y0 : Number = y;
var depth : int = 0;
while (x * x + y * y < 4 && depth < limit) {
const xx : Number = x;
x = x * x - y * y + x0;
y = 2 * xx * y + y0;
depth++;
}
return depth;
}
protected function enterFrameHandler(event : Event) : void {
if (_script == null) return; // no script
_bitmap.lock();
var limit : int = 1000 / stage.frameRate; // limit in millis
var start : int = getTimer();
while (getTimer() - start < limit) {
if (!_script.step() ) {
_script = null; // end of code.
break;
}
}
_bitmap.unlock();
}
}
class Script {
private var _host : Object = null;
private var _code : Array = new Array();
private var _label : Object = new Object();
private var _pc : int = 0;
private var _result : * = null;
public function Script(host : Object) {
_host = host;
}
public function get host() : Object {
return _host;
}
public function reset() : void {
_pc = 0;
}
public function terminate() : void {
_pc = _code.length;
}
public function step() : Boolean {
if (_pc < _code.length) {
_result = _code[_pc++]();
return true;
}
return false;
}
public function $call(func : Function) : void {
_code.push(func);
}
public function $set(prop : String, value : *) : void {
$call(function() : * {
_host[prop] = value;
return _host[prop];
});
}
public function $add(prop : String, value : *) : void {
$call(function() : * {
_host[prop] += value;
return _host[prop];
});
}
public function $comp(prop : String, value : *) : void {
$call(function() : * {
return _host[prop] - value;
});
}
public function $set_label(name : String) : String {
_label[name] = _code.length;
return _label[name];
}
public function $jump(name : String, cond : Function = null) : void {
$call(function() : * {
if (cond == null || cond() ) {
_pc = _label[name];
return 0;
}
return -1;
});
}
public function $jeqz(name : String) : void {
$jump(name, function() : * { return _result == 0 });
}
public function $jnez(name : String) : void {
$jump(name, function() : * { return _result != 0 });
}
public function $jltz(name : String) : void {
$jump(name, function() : * { return _result < 0 });
}
public function $jgtz(name : String) : void {
$jump(name, function() : * { return _result > 0 });
}
public function $jlez(name : String) : void {
$jump(name, function() : * { return _result <= 0 });
}
public function $jgez(name : String) : void {
$jump(name, function() : * { return _result >= 0 });
}
// complex op
public function $for(prop : String, from : Number, to : Number, step : Number = 1) : Function {
return function(block : *) : * {
const label : String = _getNextLabel();
$set(prop, from);
$set_label(label);
block();
$add(prop, step);
$comp(prop, to);
( (from < to)? $jlez : $jgez)(label);
};
}
private var _labelId : int = 0;
private function _getNextLabel() : String {
return "_label" + _labelId++;
}
}