マルチスレッド(SimpleThread)
for,whileなどのループ処理の変わりにloop関数を用いることで、マルチスレッドを実現できるSimpleThreadのクラスのデモです。
素数表を作成します。
/**
* 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;
}
);
}
}