/** * そうめんのサンプル FlickrSphere にある PhotoImageQueue が便利なので、 * なるだけ解りやすくシンプルにしてみたサンプル作ってみたよ。 * * @see http://www.libspark.org/browser/as3/Thread/trunk/samples/flickrsphere/src/org/libspark/flickrsphere/threads/flickr/PhotoImageQueue.as */ package { import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageQuality; import flash.display.StageScaleMode; import flash.events.Event; import org.libspark.thread.EnterFrameThreadExecutor; import org.libspark.thread.Thread; [SWF(frameRate=30, width=465, height=465, backgroundColor=0xffffff)] /** * ドキュメントクラス */ public class Tmp extends Sprite { /** * コンストラクタ */ public function Tmp() { // ステージ上で会いましょう addEventListener(Event.ADDED_TO_STAGE, initialize); } /** * 初期化する */ private function initialize(evt:Event):void { removeEventListener(Event.ADDED_TO_STAGE, initialize); stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; // そうめんの初期化がまだなら if (!Thread.isReady) { // ココで初期化しませう Thread.initialize(new EnterFrameThreadExecutor()); } // ではではタスクを消化しましょう!! new MainThread(this).start(); } } } import flash.display.DisplayObjectContainer; import flash.display.Stage; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; import org.libspark.thread.Monitor; import org.libspark.thread.Thread; /** * メイン処理を行うスレッド */ internal class MainThread extends Thread { private var layer:DisplayObjectContainer; /** * コンストラクタ */ public function MainThread(layer:DisplayObjectContainer) { this.layer = layer; } /** * 最初に実行される処理 */ override protected function run():void { var queue:SimpleQueue, fmt:TextFormat, txt:TextField; fmt = new TextFormat(); fmt.size = 96; fmt.bold = true; fmt.font = 'sans-serif'; fmt.color = 0x4c4c4c; txt = new TextField(); txt.autoSize = TextFieldAutoSize.LEFT; txt.selectable = false; txt.defaultTextFormat = fmt; layer.addChild(txt); // タスクを管理するキューを作成 queue = new SimpleQueue; // タスクを作るスレッドを起動 new StackTaskThread(queue, .8).start(); // タスクを消化するスレッドを起動 new OutputTaskThread(queue, txt).start(); } /** * 後始末する */ override protected function finalize():void { layer = null; } } /** * タスクをスタックするキュー */ internal class SimpleQueue { private var queue:Vector.<String>; private var monitor:Monitor; /** * キューが空かどうかを判別する */ public function get isEmpty():Boolean { return queue.length == 0; } /** * コンストラクタ */ public function SimpleQueue() { queue = new Vector.<String>(); monitor = new Monitor(); } /** * 消化出来るタスクがあるかを判別する */ public function checkPoll():Boolean { var retval:Boolean = true; // キューが空なら if (isEmpty) { retval = false; // 現在のスレッドを待機させる monitor.wait(); } return retval; } /** * タスクを一つ返す * ココの返り値の型が決められないがために、 * コイツはライブラリ化されてないんだろうなぁ。と思う */ public function poll():String { // 先頭のタスクを返す return queue.shift(); } /** * 新しいタスクをスタックし、それを消費者にオファーする */ public function offer(value:String):void { // 与えられたタスクをスタック queue.push(value); // 待ち状態のスレッドを起こす monitor.notifyAll(); } } /** * ひたすらキューにタスクを詰め込むスレッド */ internal class StackTaskThread extends Thread { private var queue:SimpleQueue; private var threshold:Number = 0; /** * コンストラクタ */ public function StackTaskThread(queue:SimpleQueue, threshold:Number=0) { // キューを受け取る this.queue = queue; // スレッショルドが NaN で無ければ if (!isNaN(threshold)) { // 設定に反映する this.threshold = threshold; } } /** * 最初に実行される処理 */ override protected function run():void { // 割り込まれてたらおしまい if (checkInterrupted()) return; // 乱数が敷居値を越えていれば if (Math.random() >= threshold) { var code:uint; // 65 ~ 90 -> a - z code = Math.floor(Math.random() * 26) + 65; // 適当な文字を一文字タスクに入れる queue.offer(String.fromCharCode(code)); } // 次もまたこの処理を呼ぶように登録 next(run); } /** * 後始末する */ override protected function finalize():void { queue = null; } } /** * キューにスタックされたタスクを消化するスレッド */ internal class OutputTaskThread extends Thread { private var queue:SimpleQueue; private var target:TextField; private var stage:Stage; /** * コンストラクタ */ public function OutputTaskThread(queue:SimpleQueue, target:TextField) { this.queue = queue; this.target = target; this.stage = target.stage; } /** * 最初に実行される処理 */ override protected function run():void { // キューにタスクがスタックされていれば if (queue.checkPoll()) { // それをアウトプット target.text = queue.poll(); // x, y の値をセンターに補正 target.x = (stage.stageWidth - target.width) / 2; target.y = (stage.stageHeight - target.height) / 2; } // 次のタスクを登録する next(run); } /** * 後始末する */ override protected function finalize():void { queue = null; target = null; stage = null; } } そうめんで Queue とか