Thread(そうめん)を使って素数を探す (1)
Thread(そうめん)を使って素数を探す (1)
/**
* Copyright ProjectNya ( http://wonderfl.net/user/ProjectNya )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/s9x0
*/
////////////////////////////////////////////////////////////////////////////////
// Thread(そうめん)を使って素数を探す (1)
////////////////////////////////////////////////////////////////////////////////
package {
import flash.display.Sprite;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.display.Bitmap;
import flash.filters.BlurFilter;
import flash.display.Shape;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFieldAutoSize;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.events.FocusEvent;
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import org.libspark.thread.Thread;
import org.libspark.thread.EnterFrameThreadExecutor;
[SWF(backgroundColor="#FFFFFF", width="465", height="465", frameRate="30")]
public class Main extends Sprite {
private var filePath:String = "http://www.project-nya.jp/images/flash/photo/p010.jpg";
private var max:uint;
private var input:TextField;
private var txt:Label;
private var output:TextOutput;
private var keyCode:int = 0;
private var timer:Label;
private var thread:MainThread;
public function Main() {
//Wonderfl.capture_delay(1);
init();
}
private function init():void {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT, ready, false, 0, true);
loader.load(new URLRequest(filePath), new LoaderContext(true));
//
if (!Thread.isReady) Thread.initialize(new EnterFrameThreadExecutor());
}
private function setup():void {
var rect:Shape = new Shape();
rect.x = 70;
rect.y = 12;
addChild(rect);
rect.graphics.beginFill(0xFFFFFF, 0.3);
rect.graphics.drawRect(0, 0, 80, 20);
rect.graphics.endFill();
input = new TextField();
addChild(input);
input.x = 70;
input.y = 12;
input.width = 80;
input.height = 20;
input.type = TextFieldType.INPUT;
input.selectable = true;
//input.embedFonts = true;
//input.antiAliasType = AntiAliasType.ADVANCED;
var tf:TextFormat = new TextFormat();
tf.font = "_ゴシック";
tf.size = 12;
tf.align = TextFormatAlign.CENTER;
input.defaultTextFormat = tf;
input.textColor = 0x000000;
input.text = "10";
input.addEventListener(FocusEvent.FOCUS_IN, focusIn, false, 0, true);
input.addEventListener(FocusEvent.FOCUS_OUT, focusOut, false, 0, true);
}
private function focusIn(evt:FocusEvent):void {
input.addEventListener(KeyboardEvent.KEY_DOWN, keyDown, false, 0, true);
input.addEventListener(KeyboardEvent.KEY_UP, keyUp, false, 0, true);
}
private function focusOut(evt:FocusEvent):void {
input.removeEventListener(KeyboardEvent.KEY_DOWN, keyDown);
input.removeEventListener(KeyboardEvent.KEY_UP, keyUp, false);
}
private function keyDown(evt:KeyboardEvent):void {
keyCode = evt.charCode;
}
private function keyUp(evt:KeyboardEvent):void {
if (evt.charCode == Keyboard.ENTER) {
if (evt.charCode == keyCode) {
select();
}
}
}
private function select():void {
var str:String = input.text;
if (str == "") return;
max = uint(str);
if (max < 10) return;
start();
}
private function start():void {
thread = new MainThread(this, max, input, txt, output, timer);
thread.start();
}
private function ready(evt:Event):void {
evt.target.removeEventListener(Event.INIT, ready);
var content:Bitmap = Bitmap(evt.target.content);
content.x = int((465 - content.width)/2);
content.y = int((465 - content.height)/2);
addChild(content);
content.filters = [new BlurFilter(64, 0, 3)];
draw();
setup();
}
private function draw():void {
var label1:Label = new Label(40, 20);
addChild(label1);
label1.x = 32;
label1.y = 12;
label1.textColor = 0xFFFFFF;
label1.text = "1から";
var label2:Label = new Label(140, 20);
label2.x = 152;
label2.y = 12;
addChild(label2);
label2.textColor = 0xFFFFFF;
label2.text = "までの素数を求める。";
txt = new Label(150, 20);
txt.x = 292;
txt.y = 12;
addChild(txt);
txt.textColor = 0xCCCCCC;
txt.text = "";
//
var rect:Shape = new Shape();
rect.x = 22;
rect.y = 42;
addChild(rect);
rect.graphics.beginFill(0x000000, 0.3);
rect.graphics.drawRect(0, 0, 420, 400);
rect.graphics.endFill();
//
output = new TextOutput(400, 390);
output.x = 32;
output.y = 52;
addChild(output);
output.textColor = 0xCCCCCC;
output.text = "";
//
timer = new Label(100, 20, 10, Label.RIGHT);
timer.x = 342;
timer.y = 445;
addChild(timer);
timer.textColor = 0xCCCCCC;
timer.text = "";
}
}
}
//////////////////////////////////////////////////
// MainThreadクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import __AS3__.vec.Vector;
import flash.utils.getTimer;
import flash.text.TextField;
import org.libspark.thread.Thread;
import org.libspark.thread.utils.SerialExecutor;
class MainThread extends Thread {
private var container:Sprite;
private var max:uint;
private var input:TextField;
private var txt:Label;
private var output:TextOutput;
private var timer:Label;
private var time:Number;
private var monitor:PrimeMonitor;
public function MainThread(c:Sprite, m:uint, i:TextField, t:Label, o:TextOutput, tm:Label) {
container = c;
max = m;
input = i;
txt = t;
output = o;
timer = tm;
}
override protected function run():void {
input.selectable = false;
output.text = "";
timer.text = "";
monitor = new PrimeMonitor();
monitor.max = max;
time = getTimer();
search();
}
private function search():void {
var threads:SerialExecutor = new SerialExecutor();
for (var n:uint = 0; n < max - 1; n++) {
var thread:SearchThread = new SearchThread(n + 2, monitor, txt);
threads.addThread(thread);
}
threads.start();
threads.join();
}
override protected function finalize():void {
input.selectable = true;
var prime:uint = monitor.prime;
var primes:Vector.<uint> = monitor.primes;
txt.text = prime + " まで計算。[" + primes.length+ "個]";
output.text = String(primes);
timer.text = "(" + String((getTimer() - time)/1000) + " sec)";
}
}
//////////////////////////////////////////////////
// SearchThreadクラス
//////////////////////////////////////////////////
import org.libspark.thread.Thread;
class SearchThread extends Thread {
private var prime:uint;
private var monitor:PrimeMonitor;
private var primes:Vector.<uint>;
private var txt:Label;
public function SearchThread(p:uint, m:PrimeMonitor, t:Label) {
prime = p;
monitor = m;
primes = monitor.primes;
txt = t;
}
override protected function run():void {
var divisible:Boolean = false;
for (var n:uint = 0; n < primes.length; n++) {
if (prime%primes[n] == 0) {
divisible = true;
break;
}
}
if (!divisible) {
//素数である
primes.push(prime);
}
next(show);
}
private function show():void {
monitor.prime = prime;
monitor.primes = primes;
txt.text = prime + " まで計算中...。";
}
override protected function finalize():void {
}
}
//////////////////////////////////////////////////
// PrimeMonitorクラス
//////////////////////////////////////////////////
import org.libspark.thread.Monitor;
class PrimeMonitor extends Monitor {
public var prime:uint = 2;
public var max:uint;
public var primes:Vector.<uint>;
public function PrimeMonitor() {
primes = new Vector.<uint>();
primes.push(prime);
}
}
//////////////////////////////////////////////////
// TextOutputクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFieldAutoSize;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
class TextOutput extends Sprite {
private var txt:TextField;
private static var fontType:String = "_ゴシック";
private var _width:uint = 20;
private var _height:uint = 20;
private var size:uint = 12;
public static const LEFT:String = TextFormatAlign.LEFT;
public static const CENTER:String = TextFormatAlign.CENTER;
public static const RIGHT:String = TextFormatAlign.RIGHT;
public function TextOutput(w:uint, h:uint, s:uint = 12, align:String = LEFT) {
_width = w;
_height = h;
size = s;
draw(align);
}
private function draw(align:String):void {
txt = new TextField();
addChild(txt);
txt.width = _width;
txt.height = _height;
//txt.autoSize = align;
txt.type = TextFieldType.DYNAMIC;
txt.selectable = true;
//txt.embedFonts = true;
//txt.antiAliasType = AntiAliasType.ADVANCED;
txt.multiline = true;
txt.wordWrap = true;
var tf:TextFormat = new TextFormat();
tf.font = fontType;
tf.size = size;
tf.align = align;
txt.defaultTextFormat = tf;
textColor = 0x000000;
}
public function set text(param:String):void {
txt.text = param;
}
public function set textColor(param:uint):void {
txt.textColor = param;
}
}
//////////////////////////////////////////////////
// Labelクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFieldAutoSize;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
class Label extends Sprite {
private var txt:TextField;
private static var fontType:String = "_ゴシック";
private var _width:uint = 20;
private var _height:uint = 20;
private var size:uint = 12;
public static const LEFT:String = TextFormatAlign.LEFT;
public static const CENTER:String = TextFormatAlign.CENTER;
public static const RIGHT:String = TextFormatAlign.RIGHT;
public function Label(w:uint, h:uint, s:uint = 12, align:String = LEFT) {
_width = w;
_height = h;
size = s;
draw(align);
}
private function draw(align:String):void {
txt = new TextField();
addChild(txt);
txt.width = _width;
txt.height = _height;
txt.autoSize = align;
txt.type = TextFieldType.DYNAMIC;
txt.selectable = false;
//txt.embedFonts = true;
//txt.antiAliasType = AntiAliasType.ADVANCED;
var tf:TextFormat = new TextFormat();
tf.font = fontType;
tf.size = size;
tf.align = align;
txt.defaultTextFormat = tf;
textColor = 0x000000;
}
public function set text(param:String):void {
txt.text = param;
}
public function set textColor(param:uint):void {
txt.textColor = param;
}
}