In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Tight Loop Test

think about light weight implementation ov cancelable tight loop.
Get Adobe Flash player
by Test_Dept 19 Sep 2011
    Embed
/**
 * 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++;
    }
}