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

マルチスレッド(SimpleThread)

for,whileなどのループ処理の変わりにloop関数を用いることで、マルチスレッドを実現できるSimpleThreadのクラスのデモです。
素数表を作成します。
Get Adobe Flash player
by shohei909 21 Oct 2010
/**
 * Copyright shohei909 ( http://wonderfl.net/user/shohei909 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/hccL
 */

package {
    import flash.events.Event;
    /*
    SimpleThreadでは、for,whileなどのループ処理の変わりにloop関数を用いることで、
    簡単にマルチスレッドを実現できます。
    */
    import flash.display.Sprite;
    import com.bit101.components.*;
    public class FlashTest extends Sprite {
        static public var textArea:TextArea;
        private var thread:MyThread;
        public function FlashTest() {
            // write as3 code here..
            new FPSMeter(this);
            textArea = new TextArea( this,0,20 );
            textArea.setSize(465, 445); 
            
            //スレッドを実行
            thread = new MyThread();
        }
    }
}


//SimpleThread==========================================================================
import flash.utils.Timer;
import flash.utils.getTimer;
import flash.events.Event;
    
class SimpleThread extends Timer{ 
    static public var SPAN:Number = 1000/30; 
    static public var RATE:Number = 0.5;
    public var end:Boolean = false, currentLoop:Loop = null;
    
    static private var NUM:int = 0;
    private var _limit:Number = 5, _time:int = 0, _added:Boolean, currentLoops:Vector.<Loop>, loops:Vector.<Loop> = new Vector.<Loop>();
    
    function SimpleThread(){
        super(SPAN); start(); NUM++;
        addEventListener( "timer", onFrame  );
    }    
    public function loop( func:Function, onComplete:Function = null):void{
        var loop:Loop = new Loop( func, currentLoop );     
        if( currentLoop == null ){ loops.push( loop );
        }else{ currentLoop.loops.push( loop ); _added = true }
        if( onComplete != null ){
            loop = new Loop( onComplete, currentLoop );   
            if( currentLoop == null ){ loops.push( loop );
            }else{ currentLoop.loops.push( loop ); }
        }
    }    
    public function remove():void{
        NUM--; stop(); end = true;
        removeEventListener( "timer", onFrame  );
    }    
    private function onFrame(e:Event):void{
        _time = getTimer(); _limit = (SPAN * RATE) / NUM;
        all: while(true){
            if( currentLoop == null ){
                currentLoops = loops;
                if( loops.length == 0 ){ remove(); break; }
                while( currentLoops[0].loops.length != 0 ){ currentLoops = currentLoops[0].loops;  }
                currentLoop = currentLoops[0];
            }
            do{
                if( _limit < (getTimer() - _time)){ break all; }
                if( _added ){ _added = false; currentLoop = null; continue all;  }
            }while( currentLoop.func() )
            currentLoop = null;
            currentLoops.reverse(); currentLoops.pop(); currentLoops.reverse();
        }
    }
}
class Loop extends Object{
    public var func:Function, name:String, parent:Loop, loops:Vector.<Loop> = new Vector.<Loop>();
    function Loop( func:Function, parent:Loop = null, name:String = "" ){  
        this.func = func; this.parent = parent;
    }
}
//=======================================================================================




class MyThread extends SimpleThread {
    public var primes:Vector.<int> = Vector.<int>( [2,3] );
    function MyThread(){
        /*
        スレッドを用いない場合の記述。(実行するとフリーズを起こします。)
        for( var i:uint = 5; i < 100000; i+=2 ){
            var count:int = 1; 
            var prime:uint = primes[count];
            var flag:Boolean = true;
            while( prime*prime <= i ){
                if( i % prime == 0 ){ flag == false; break; }
                prime = primes[++count];
            }
            if( flag ){
                primes.push( i ) ;
            }
        } 
        FlashTest.textArea.text = "finished\n" + primes;
        

        この様なコードをSimpleThreadを使って実行したい場合、以下のように記述します。
        //*/ 

        var i:uint = 5;
        loop( 
            function _for():Boolean{
                FlashTest.textArea.text = "..." + i + "/" + 100000;
                var count:int = 1; 
                var prime:uint = primes[count];
                var flag:Boolean = true;
                loop( 
                    function _while():Boolean{ 
                        if(  !(prime*prime <= i)  ) return false;
                        
                        if( i % prime == 0 ){ flag = false; return false; }
                        prime = primes[++count];
                        return true;    
                    }, 
                    function onComplete():void { 
                        if(flag){ primes.push( i ) ; }
                        i += 2;
                    } 
                );   
                //loop処理は return false されるまで繰り返されます。
                //return false されるとonCompleteが呼び出されます。
                return i < 100000;    
            },
            function onComplete():void { 
                FlashTest.textArea.text = "finished\n" + primes;
            } 
        );
        
    }
}