チェンジセット 641

差分発生行の前後
無視リスト:
コミット日時:
2008/06/14 12:14:58 (4 年前)
コミッタ:
yossy
ログメッセージ:

Thread: branches/soumen を trunk にマージ

ファイル:

凡例:

変更無し
追加
削除
更新
コピー
移動
  • as3/Thread/trunk

    • 属性の設定値: svn:ignore (登録)
      obj
      bin
  • as3/Thread/trunk/samples/urlloader/MainThread.as

    r150 r641  
    1 package 
     1package 
    22{ 
     3        import flash.events.Event; 
    34        import org.libspark.thread.Thread; 
    4          
    5         import org.libspark.utils.concurrent.Executor; 
    6         import org.libspark.utils.concurrent.SerialExecutor; 
    7          
    8         import org.libspark.net.URLLoaderThread; 
     5        import org.libspark.thread.utils.Executor; 
     6        import org.libspark.thread.utils.ParallelExecutor; 
     7        import org.libspark.thread.threads.net.URLLoaderThread; 
    98         
    109        import flash.net.URLRequest; 
     
    1413         
    1514        /** 
    16          * このスレッドは、URLLoaderThreadとSerialExecutorを用いて、平行して三つのURLからデータをダウンロードします 
     15         * このスレッドは、URLLoaderThread と ParallelExecutor を用いて、平行して三つの URL からデータをダウンロードします 
    1716         */ 
    1817        public class MainThread extends Thread 
     
    2120                 
    2221                /** 
    23                  * initializeメソッドには初期化処理を記述します 
     22                 * スレッドの処理は run メソッドをオーバーライドして記述します 
    2423                 */ 
    25                 protected override function initialize():void 
     24                override protected function run():void 
    2625                { 
    27                         // 並列してスレッドを実行するためのSerialExecutorを作成します 
    28                         _loaders = new SerialExecutor(); 
     26                        // 並列してスレッドを実行するための ParallelExecutor を作成します 
     27                        _loaders = new ParallelExecutor(); 
    2928                         
    3029                        // これに、三つのURLLoaderThreadを追加します 
     
    3231                        _loaders.addThread(new URLLoaderThread(new URLRequest('http://www.yahoo.co.jp/'))); 
    3332                        _loaders.addThread(new URLLoaderThread(new URLRequest('http://www.adobe.com/jp/'))); 
     33                         
     34                        trace('begin loading.'); 
     35                         
     36                        // ロード処理を開始 (= SerialExecutor スレッドを開始) します 
     37                        _loaders.start(); 
     38                        // スレッドが終了 (= ロードが完了) するまで、次のメソッドが実行されないように待ちます 
     39                        _loaders.join(); 
     40                         
     41                        // 次に実行されるメソッドをセットしておきます 
     42                        next(executeComplete); 
     43                        // 例外ハンドラを設定しておきます 
     44                        error(IOError, errorHandler); 
     45                        error(SecurityError, errorHandler); 
    3446                } 
    3547                 
    3648                /** 
    37                  * exeucteメソッドにはスレッドの処理を記述します 
    38                  */ 
    39                 protected override function execute():void 
    40                 { 
    41                         // 次に実行されるメソッドをセットしておきます 
    42                         switchExecuteMethod(executeComplete); 
    43                          
    44                         trace('begin loading.'); 
    45                          
    46                         // ロード処理を開始(=SerialExecutorスレッドを開始)します 
    47                         _loaders.begin(); 
    48                         // スレッドが終了(=ロードが完了)するまで、次のメソッドが実行されないように待ちます 
    49                         _loaders.join(); 
    50                 } 
    51                  
    52                 /** 
    53                  * executeCompleteメソッドには、ロード完了後の処理を書く事にします 
     49                 * executeComplete メソッドには、ロード完了後の処理を書く事にします 
    5450                 */ 
    5551                private function executeComplete():void 
     
    6460                        } 
    6561                         
    66                         // 終了 
    67                         terminate(); 
     62                        // next を設定しなければスレッドは終了します 
     63                        // 終了の前には finalize が呼び出されます 
    6864                } 
    6965                 
    7066                /** 
    71                  * finalizeメソッドには終了処理を書きます 
     67                 * スレッドの終了処理は finalize メソッドをオーバーライドして記述します 
    7268                 */ 
    7369                protected override function finalize():void 
     
    7975                 
    8076                /** 
    81                  * catchErrorメソッドには、例外処理を書きます 
    82                  * 子スレッド(=_loaders)で発生した例外もここにきます 
     77                 * 例外ハンドラ 
    8378                 * 
    84                  * @param thread 例外が発生したスレッド 
    85                  * @param e 発生した例外 
     79                 * @param      e       発生した例外 
     80                 * @param      thread  発生元のスレッド 
    8681                 */ 
    87                 protected override function catchError(thread:Thread, e:Error):void 
     82                private function errorHandler(e:IOError, t:Thread):void 
    8883                { 
    89                         try { 
    90                                 throw e; 
    91                         } 
    92                         catch (ioError:IOError) { 
    93                                 // IOErrorなので例外を出力して終了 
    94                                 trace(ioError.message); 
    95                                 terminate(); 
    96                                 return; 
    97                         } 
    98                         catch (securityError:SecurityError) { 
    99                                 // SecurityErrorなので例外を出力して終了 
    100                                 trace(securityError.message); 
    101                                 terminate(); 
    102                                 return; 
    103                         } 
     84                        trace('error!!'); 
    10485                         
    105                         // それ以外の例外はこのスレッドの管轄外なので上位スレッドに投げる 
    106                         throw e; 
    107                 } 
    108                  
    109                 public override function toString():String 
    110                 { 
    111                         return '[Main]'; 
     86                        // 例外を出力して終了 
     87                        trace(e.getStackTrace()); 
     88                        // 例外ハンドラから終了するには、明示的に next(null) を呼び出します 
     89                        next(null); 
    11290                } 
    11391        } 
  • as3/Thread/trunk/samples/urlloader/Sample.as

    r150 r641  
    1 package 
     1package 
    22{ 
    3        import flash.display.Sprite; 
    4         import flash.events.Event; 
    5          
    6        import org.libspark.thread.MasterThread
    7          
     3    import flash.display.Sprite; 
     4 
     5    import org.libspark.thread.Thread; 
     6    import org.libspark.thread.EnterFrameThreadExecutor
     7 
    88        /** 
    9          * このサンプルではURLLoaderThreadの使用方法などを学びます 
     9         * このサンプルでは URLLoaderThread の使用方法などを学びます 
    1010         * 
    11          * 詳細はMainThreadを見てください 
     11         * 詳細は MainThread を見てください 
    1212         */ 
    1313        public class Sample extends Sprite 
     
    1515                public function Sample() 
    1616                { 
    17                         // スレッドを実行するためのMasterThreadを作成します 
    18                         // 引数には一番最初に実行するスレッド(メインスレッド)を渡します。ここではMainThread 
    19                         _master = new MasterThread(new MainThread()); 
    20                          
    21                         addEventListener(Event.ENTER_FRAME, enterFrameHandler); 
    22                 } 
    23                  
    24                 private var _master:MasterThread; 
    25                  
    26                 private function enterFrameHandler(event:Event):void 
    27                 { 
    28                         // MasterThreadのexecuteActiveThreadsメソッドを呼び出すことで、スレッドが実行されます 
    29                         // 通常、EnterFrameのタイミングで呼び出すことになるでしょう 
    30                         _master.executeActiveThreads(); 
     17            // スレッドを実行するには、まずはじめに Thread#initialize をコールし、スレッドライブラリを初期化します 
     18            // Thread#initialize には、IThreadExecutor のインスタンスを渡します 
     19                        // ここでは EnterFrameExecutor を渡し、毎フレームスレッドが実行されるようにします 
     20            Thread.initialize(new EnterFrameThreadExecutor()); 
     21 
     22            // MainThread を起動します 
     23                        var main:MainThread = new MainThread(); 
     24                        main.start(); 
    3125                } 
    3226        } 
  • as3/Thread/trunk/src/org/libspark/thread/Thread.as

    r175 r641  
     1/* 
     2 * ActionScript Thread Library 
     3 *  
     4 * Licensed under the MIT License 
     5 *  
     6 * Copyright (c) 2008 BeInteractive! (www.be-interactive.org) and 
     7 *                    Spark project  (www.libspark.org) 
     8 *  
     9 * Permission is hereby granted, free of charge, to any person obtaining a copy 
     10 * of this software and associated documentation files (the "Software"), to deal 
     11 * in the Software without restriction, including without limitation the rights 
     12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
     13 * copies of the Software, and to permit persons to whom the Software is 
     14 * furnished to do so, subject to the following conditions: 
     15 *  
     16 * The above copyright notice and this permission notice shall be included in 
     17 * all copies or substantial portions of the Software. 
     18 *  
     19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
     20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
     21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
     22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
     23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
     24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
     25 * THE SOFTWARE. 
     26 *  
     27 */ 
    128package org.libspark.thread 
    229{ 
    3         import org.libspark.thread.errors.ThreadErrorHandler; 
    4  
    5         public class Thread extends MonitorObject 
     30        import flash.events.Event; 
     31        import flash.events.IEventDispatcher; 
     32        import flash.utils.Dictionary; 
     33        import flash.utils.getQualifiedClassName; 
     34        import flash.utils.getQualifiedSuperclassName; 
     35        import flash.utils.getDefinitionByName; 
     36        import org.libspark.thread.errors.CurrentThreadNotFoundError; 
     37        import org.libspark.thread.errors.IllegalThreadStateError; 
     38        import org.libspark.thread.errors.InterruptedError; 
     39        import org.libspark.thread.errors.ThreadLibraryNotInitializedError; 
     40         
     41        /** 
     42         * Thread クラスは ActionScript Thread Library 1.0 (そうめん) の核となるクラスで、擬似スレッドを実現します. 
     43         *  
     44         * <p>ここで実現される擬似スレッドは、タスクシステムと Java のスレッドモデルをベースとしています。 
     45         * 処理をいくつかのメソッドに切り分け、呼び出すメソッド (「<em>実行関数</em>」と呼びます) を切り替えつつ 
     46         * 順々に実行していくことで、処理を進めます。</p> 
     47         *  
     48         * <p>新しいスレッドを作成するためには、まず Thread クラスのサブクラスを作成します。 
     49         * このサブクラスは、 Thread クラスの run メソッドをオーバーライドする必要があります。 
     50         * たとえば、「Hello, Thread!!」と出力するスレッドは、次のようになります。</p> 
     51         * <listing>public class HelloThread extends Thread 
     52         * { 
     53         *     override protected function run():void 
     54         *     { 
     55         *         trace('Hello, Thread!!'); 
     56         *     } 
     57         * }</listing> 
     58         *  
     59         * <p>作成したスレッドを実行するためには、 Thread Library を初期化する必要があります。 
     60         * 次のように、 Thread クラスの静的メソッド initialize を呼び出すことで初期化を行います。 
     61         * このとき、引数に IThreadExecutor インターフェイスの実装クラスのインスタンスを指定します。 
     62         * この IThreadExecutor インスタンスは、「いつスレッドを実行するか」を決める重要な役割を担っています。 
     63         * ここでは、 EnterFrameThreadExecutor クラスのインスタンスを渡し、フレーム実行のタイミングで 
     64         * スレッドが実行されるようにしています。初期化処理は、アプリケーションの最初で一度だけ行えば、その後呼び出す必要はありません。</p> 
     65         * <listing>Thread.initialize(new EnterFrameThreadExecutor());</listing> 
     66         *  
     67         * <p>最後に、次のように HelloThread クラスのインスタンスを作り、 start メソッドを呼び出すことで、 
     68         * スレッドの実行を開始します。</p> 
     69         * <listing>var t:Thread = new HelloThread(); 
     70         * t.start();</listing> 
     71         *  
     72         * <p>スレッドは親子関係を形成します。この親子関係は、スレッドの実行開始時に決定されます。 
     73         * スレッドの start を呼び出したスレッド (つまりカレントスレッド) は、親スレッドとなり、 
     74         * start が呼び出されたスレッドは、その親スレッドの子スレッドとなります。 
     75         * ただし、 start の呼び出しがスレッドの外 (つまりカレントスレッドが null のとき) に行われた場合、 
     76         * start が呼び出されたスレッドはトップレベルスレッドとなります。</p> 
     77         *  
     78         * <p>スレッドの親子関係は、スレッドの実行順序と例外の伝播において重要になります。 
     79         * スレッドの実行は、一番最初に開始されたトップレベルスレッドから始まります。今、このスレッドを A と呼ぶことにします。 
     80         * A に子スレッドがいる場合、 A の実行よりも先にまず、子スレッドが、開始された順番で実行されます。 
     81         * この子スレッドが実行されるとき、その子スレッドにさらに子スレッド (Aから見て孫スレッド) がいる場合、 
     82         * その子スレッドの実行より先に孫スレッドが開始された順番で実行され、これが子スレッドがいなくなるまで続けられます。 
     83         * 全ての A の子スレッドの実行が終了すると、 A が実行され、次に、A の次に開始されたトップレベルスレッドの実行が 
     84         * 同様にして続きます。</p> 
     85         *  
     86         * <p>スレッド内で例外が発生し、その例外が、例外が発生したスレッド内で捕捉されなかった場合、 
     87         * 例外は親スレッドに伝播します。例外が発生したのがトップレベルスレッドで、親スレッドがいない場合、 
     88         * 例外は uncaughtErrorHandler に渡されます。</p> 
     89         *  
     90         * <p>子スレッドよりも先に親スレッドが終了した場合、その親スレッドの全ての子スレッドは孤児スレッドとなり、 
     91         * トップレベルスレッドとして再配置されます。</p> 
     92         *  
     93         * <p>スレッドはある時点で、以下のいずれかの状態を取ります。これらの値は ThreadState クラスで定義されており、 
     94         * state プロパティを通して知ることができます。</p> 
     95         * <ul> 
     96         * <li>NEW</li> 
     97         * <li>RUNNABLE</li> 
     98         * <li>WAITING</li> 
     99         * <li>TIMED_WAITING</li> 
     100         * <li>TERMINATING</li> 
     101         * <li>TERMINATED</li> 
     102         * </ul> 
     103         *  
     104         * <p>スレッドが生成されると、まずはじめに状態は「NEW」に設定されます。この後、 start メソッドによって 
     105         * スレッドが開始されると、状態は「RUNNABLE」に設定されます。「NEW」以外の状態のスレッドを start メソッドによって 
     106         * 開始することはできません。</p> 
     107         *  
     108         * <p>wait メソッド、 join メソッド等の呼び出しによってスレッドが待機状態になる場合、状態は「WAITING」に 
     109         * 設定されます。このとき、タイムアウトが設定されるか、sleep メソッドの呼び出しである場合、状態は「TIMED_WAITING」に 
     110         * 設定されます。待機状態が解除されると状態は元に戻ります。</p> 
     111         *  
     112         * <p>スレッドが終了フェーズに移行すると、状態は「TERMINATING」に設定されます。スレッドが終了フェーズから 
     113         * 実行フェーズに戻ることは無く、同様に状態が「TERMINATING」から「RUNNABLE」に戻ることもありません。 
     114         * 終了フェーズが終わり、完全にスレッドが終了すると、状態は「TERMINATED」に設定されます。</p> 
     115         *  
     116         * <p>スレッドの動作を視覚的に知りたい場合、以下の動作チャートを見ることをお勧めします。</p> 
     117         * <ul> 
     118         * <li>http://www.libspark.org/htdocs/as3/thread-files/behavior-chart.png</li> 
     119         * </ul> 
     120         *  
     121         * @author      yossy:beinteractive 
     122         * @see #run() 
     123         * @see #initialize() 
     124         * @see #start() 
     125         * @see #uncaughtErrorHandler() 
     126         * @see #state 
     127         * @see ThreadState 
     128         * @see http://www.libspark.org/htdocs/as3/thread-files/behavior-chart.png 
     129         */ 
     130        public class Thread extends Monitor 
    6131        { 
    7                 private static const STATE_STANDINGBY:uint = 0; 
    8                 private static const STATE_RUNNING:uint = 1 << 0; 
    9                 private static const STATE_SLEEPING:uint = 1 << 1; 
    10                 private static const STATE_SUSPENDING:uint = 1 << 2; 
    11                 private static const STATE_TERMINATED:uint = 1 << 3; 
    12                 private static const STATE_ERROR:uint = 1 << 4; 
    13                  
     132                private static var _executor:IThreadExecutor; 
     133                private static var _threadIndex:uint = 0; 
    14134                private static var _currentThread:Thread = null; 
    15                 internal static var _debug:Debug = null; 
    16                  
     135                private static var _toplevelThreads:Array = []; 
     136                private static var _uncaughtErrorHandler:Function = null; 
     137                 
     138                /** 
     139                 * スレッドライブラリを初期化します. 
     140                 *  
     141                 * <p>このメソッドは、最初に一度だけ呼び出してください。</p> 
     142                 *  
     143                 * <p>スレッドの実行は、指定された IThreadExecutor インスタンスによって行われます。 
     144                 * (このメソッド内で、 IThreadExectuor#start が呼び出されます)</p> 
     145                 *  
     146                 * @param       executor        スレッドの実行を行う IThreadExecutor 
     147                 * @see IThreadExecutor 
     148                 */ 
     149                public static function initialize(executor:IThreadExecutor):void 
     150                { 
     151                        _threadIndex = 0; 
     152                        _currentThread = null; 
     153                        _toplevelThreads.length = 0; 
     154                         
     155                        // 古い IThreadExecutor の実行を止める 
     156                        if (_executor != null) { 
     157                                _executor.stop(); 
     158                        } 
     159                         
     160                        _executor = executor; 
     161                         
     162                        // 新しい IThreadExecutor の実行を開始 
     163                        if (_executor != null) { 
     164                                _executor.start(); 
     165                        } 
     166                } 
     167                 
     168                /** 
     169                 * initialize メソッドの呼び出しによって IThreadExecutor が設定され、スレッドが実行可能な状態であれば true、そうでなければ false を返します. 
     170                 *  
     171                 * @see #initialize() 
     172                 */ 
     173                public static function get isReady():Boolean 
     174                { 
     175                        return _executor != null; 
     176                } 
     177                 
     178                /** 
     179                 * 現在実行中のスレッドを返します. 
     180                 *  
     181                 * <p>現在実行中のスレッドがない場合、 null を返します。</p> 
     182                 */ 
    17183                public static function get currentThread():Thread 
    18184                { 
     
    20186                } 
    21187                 
     188                /** 
     189                 * 現在実行中のスレッドを返します. 
     190                 *  
     191                 * <p>ただし、現在実行中のスレッドがない(currentThread が null)の場合は CurrentThreadNotFoundError をスローします。</p> 
     192                 *  
     193                 * @return      現在実行中のスレッド 
     194                 * @throws      org.libspark.thread.errors.CurrentThreadNotFoundError   現在実行中のスレッドがない場合 
     195                 * @private 
     196                 */ 
     197                internal static function getCurrentThread():Thread 
     198                { 
     199                        var t:Thread = currentThread; 
     200                         
     201                        if (t != null) { 
     202                                return t; 
     203                        } 
     204                         
     205                        throw new CurrentThreadNotFoundError('Expected Thread.currentThread is not null, but actual null.'); 
     206                } 
     207                 
     208                /** 
     209                 * どのスレッドにも捕捉されなかった例外のためのハンドラを設定します. 
     210                 *  
     211                 * <p>スレッド内で例外が発生し、処理されないままトップレベルまで到達するとこのハンドラが呼び出されます。</p> 
     212                 *  
     213                 * <p>ここに登録する関数は、第一引数に発生した例外である Object と、第二引数に発生元のスレッドである Thread を引数としてとる必要があります。</p> 
     214                 */ 
     215                public static function get uncaughtErrorHandler():Function 
     216                { 
     217                        return _uncaughtErrorHandler; 
     218                } 
     219                 
     220                /** 
     221                 * @private 
     222                 */ 
     223                public static function set uncaughtErrorHandler(value:Function):void 
     224                { 
     225                        _uncaughtErrorHandler = value; 
     226                } 
     227                 
     228                /** 
     229                 * 例外ハンドラを取得します. 
     230                 *  
     231                 * <p>ただし、ユーザーによって例外ハンドラが設定されていない場合、デフォルトのハンドラを返します。</p> 
     232                 *  
     233                 * @return      ユーザーによって設定された例外ハンドラ。無い場合はデフォルトのハンドラ。 
     234                 * @private 
     235                 */ 
     236                private static function getUncaughtErrorHandler():Function 
     237                { 
     238                        return uncaughtErrorHandler || defaultUncaughtErrorHandler; 
     239                } 
     240                 
     241                /** 
     242                 * 例外ハンドラのデフォルトの実装です. 
     243                 *  
     244                 * @param       e       発生した例外 
     245                 * @param       t       例外が発生したスレッド 
     246                 * @private 
     247                 */ 
     248                private static function defaultUncaughtErrorHandler(e:Object, t:Thread):void 
     249                { 
     250                        trace((t ? t.toString() + ' ' : '') + (e is Error ? Error(e).getStackTrace() : e.toString())); 
     251                } 
     252                 
     253                /** 
     254                 * 全てのスレッドを実行します. 
     255                 *  
     256                 * <p>通常、このメソッドは IThreadExector インターフェイスの実装クラスによって呼び出されます。</p> 
     257                 */ 
     258                public static function executeAllThreads():void 
     259                { 
     260                        // 全てのトップレベルスレッドを呼び出す 
     261                        var threads:Array = _toplevelThreads; 
     262                        var l:uint = threads.length; 
     263                        for (var i:uint = 0; i < l;) { 
     264                                var thread:Thread = Thread(threads[i]); 
     265                                if (!thread.execute()) { 
     266                                        // スレッドが終了した場合は削除 
     267                                        threads.splice(i, 1); 
     268                                        --l; 
     269                                } 
     270                                else { 
     271                                        ++i; 
     272                                } 
     273                                // 伝播すべき例外が発生している場合はキャッチされない例外ハンドラを呼び出す 
     274                                // Note: _errorThread が null の場合、この例外はまだ伝播すべきではないことを示す 
     275                                if (thread._error != null && thread._errorThread != null) { 
     276                                        try { 
     277                                                getUncaughtErrorHandler()(thread._error, thread._errorThread); 
     278                                        } 
     279                                        catch (e:Object) { 
     280                                                defaultUncaughtErrorHandler(e, null); 
     281                                        } 
     282                                        thread._error = null; 
     283                                        thread._errorThread = null; 
     284                                } 
     285                        } 
     286                } 
     287                 
     288                /** 
     289                 * 指定されたスレッドをトップレベルスレッドとして追加します. 
     290                 *  
     291                 * @param       thread  追加するスレッド 
     292                 * @private 
     293                 */ 
     294                private static function addToplevelThread(thread:Thread):void 
     295                { 
     296                        _toplevelThreads.push(thread); 
     297                } 
     298                 
     299                /** 
     300                 * 指定されたスレッドをトップレベルスレッドとして追加します. 
     301                 *  
     302                 * @param       threads 追加するスレッドの配列 
     303                 * @private 
     304                 */ 
     305                private static function addToplevelThreads(threads:Array):void 
     306                { 
     307                        _toplevelThreads.push.apply(_toplevelThreads, threads); 
     308                } 
     309                 
     310                /** 
     311                 * 現在実行中のスレッドが次に実行する実行関数を設定します. 
     312                 *  
     313                 * <p>この設定は、スレッドの実行のたびにリセットされます。</p> 
     314                 *  
     315                 * <p>このメソッドの呼び出しによって次に実行する実行関数が設定されない場合、スレッドは終了フェーズへと移行します。</p> 
     316                 *  
     317                 * @param       func    次に実行する実行関数 
     318                 */ 
     319                public static function next(func:Function):void 
     320                { 
     321                        getCurrentThread()._runHandler = func; 
     322                } 
     323                 
     324                /** 
     325                 * 現在実行中のスレッドおよびその子スレッドで例外が発生した場合に実行する実行関数を設定します. 
     326                 *  
     327                 * <p>ここで設定される実行関数は、発生した例外である Object と、例外が発生したスレッドである Thread のふたつの引数をとる関数である必要があります。</p> 
     328                 *  
     329                 * <p>この関数によって例外を処理できた (この関数内で再び例外が発生しなかった) 場合で、この関数内で 
     330                 * next メソッドによる実行関数の設定が行われなかった場合、例外が発生する前の実行関数の設定を復元します。</p> 
     331                 *  
     332                 * <p>この設定は、reset 引数が false に設定されない限り、スレッドの実行のたびにリセットされます。</p> 
     333                 *  
     334                 * @param       klass   どの型の例外が発生した場合に関数を実行するかを示すクラス 
     335                 * @param       func    例外が発生した際に実行される実行関数 
     336                 * @param       reset   次の実行のタイミングでこの設定を削除する場合には true、そうでなければ false 
     337                 */ 
     338                public static function error(klass:Class, func:Function, reset:Boolean = true):void 
     339                { 
     340                        if (func != null) { 
     341                                getCurrentThread().addErrorHandler(klass, func, reset); 
     342                        } 
     343                        else { 
     344                                getCurrentThread().removeErrorHandler(klass); 
     345                        } 
     346                } 
     347                 
     348                /** 
     349                 * 現在実行中のスレッドが待機中にタイムアウトした場合に実行する実行関数を設定します. 
     350                 *  
     351                 * <p>この設定は、スレッドの実行のたびにリセットされます。</p> 
     352                 *  
     353                 * @param       func    タイムアウトした場合に実行する実行関数 
     354                 */ 
     355                public static function timeout(func:Function):void 
     356                { 
     357                        getCurrentThread()._timeoutHandler = func; 
     358                } 
     359                 
     360                /** 
     361                 * 現在実行中のスレッドが指定されたイベントが発生した場合に実行する実行関数を設定します. 
     362                 *  
     363                 * <p>ここで設定される実行関数は、発生したイベントである Event を引数にとる関数である必要があります。</p> 
     364                 *  
     365                 * <p>このメソッドによってイベントハンドラが設定される場合、スレッドは自動的にイベントが発生するまで待機状態となります。 
     366                 * ただし、 next メソッドによって次に実行する実行関数が設定される場合、待機状態にはならず、実行が継続されます。</p> 
     367                 *  
     368                 * <p>この設定は、スレッドの実行のたびにリセットされます。</p> 
     369                 *  
     370                 * @param       dispatcher      イベントリスナーの登録先となるディスパッチャ 
     371                 * @param       type    捕捉するイベント名 
     372                 * @param       func    イベントが発生した場合に実行する実行関数 
     373                 * @param       useCapture      flash.events.IEventDispatcher#addEventListener() の該当する引数を参照してください。 
     374                 * @param       priority        flash.events.IEventDispatcher#addEventListener() の該当する引数を参照してください。 
     375                 * @param       useWeakReference        flash.events.IEventDispatcher#addEventListener() の該当する引数を参照してください。 
     376                 * @see flash.events.IEventDispatcher#addEventListener() 
     377                 */ 
     378                public static function event(dispatcher:IEventDispatcher, type:String, func:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void 
     379                { 
     380                        getCurrentThread().addEventHandler(dispatcher, type, func, useCapture, priority, useWeakReference); 
     381                } 
     382                 
     383                /** 
     384                 * 現在実行中のスレッドの実行を、指定された時間だけ中断させます. 
     385                 *  
     386                 * <p>指定された時間が経過すると、 sleep メソッドが呼び出されなかった場合と同様に実行が再開されます。</p> 
     387                 *  
     388                 * <p>スレッドの実行が中断しても、子スレッドの実行が中断されることはありません。</p> 
     389                 *  
     390                 * @param       time    実行を中断させる時間 (ミリ秒) 
     391                 */ 
     392                public static function sleep(time:uint):void 
     393                { 
     394                        // time が 0 だと永遠に待ってしまうので最低でも 1 にする 
     395                        if (time == 0) { 
     396                                time = 1; 
     397                        } 
     398                         
     399                        // カレントスレッドを取得 
     400                        var current:Thread = getCurrentThread(); 
     401                         
     402                        // sleep 用のモニタがなければ生成 
     403                        if (current._sleepMonitor == null) { 
     404                                current._sleepMonitor = new Monitor(); 
     405                        } 
     406                         
     407                        // sleep 用のモニタを使って wait をかけて指定時間眠らせる 
     408                        current._sleepMonitor.wait(time); 
     409                } 
     410                 
     411                /** 
     412                 * 現在実行中のスレッドが待機中に割り込まれた場合に実行する実行関数を設定します. 
     413                 *  
     414                 * <p>このメソッドによって割り込みハンドラが設定されていない状態で、待機中に割り込みが発生すると、 
     415                 * 例外 InterruptedError が発生します。</p> 
     416                 *  
     417                 * <p>この設定はスレッドの実行のたびにリセットされます。</p> 
     418                 *  
     419                 * @param       func    待機中に割り込まれた場合に実行する実行関数 
     420                 */ 
     421                public static function interrupted(func:Function):void 
     422                { 
     423                        getCurrentThread()._interruptedHandler = func; 
     424                } 
     425                 
     426                /** 
     427                 * 現在のスレッドが割り込まれているかどうかを調べます. 
     428                 *  
     429                 * <p>このメソッドによりスレッドの「割り込みステータス」がクリアされます。 
     430                 * つまり、このメソッドが続けて2回呼び出された場合、2回目の呼び出しは false を返します。</p> 
     431                 *  
     432                 * @return      現在のスレッドが割り込まれている場合は true、そうでない場合は false 
     433                 */ 
     434                public static function checkInterrupted():Boolean 
     435                { 
     436                        // カレントスレッドを取得 
     437                        var current:Thread = getCurrentThread(); 
     438                         
     439                        // 割り込みステータスを取得 
     440                        var status:Boolean = current._isInterrupted; 
     441                         
     442                        // ステータスが設定されている場合はクリア 
     443                        if (status) { 
     444                                current._isInterrupted = false; 
     445                        } 
     446                         
     447                        // ステータスを返す 
     448                        return status; 
     449                } 
     450                 
     451                /** 
     452                 * 新しい Thread クラスのインスタンスを生成します. 
     453                 */ 
    22454                public function Thread() 
    23455                { 
    24                         _parent = null; 
    25                         _children = []; 
    26                         _willRemove = []; 
    27                         _state = STATE_STANDINGBY; 
    28                         _executeHandler = nullHandler; 
     456                        _id = ++_threadIndex; 
     457                        _name = 'Thread' + _id; 
     458                        _state = ThreadState.NEW; 
     459                        _runningState = ThreadState.NEW; 
     460                        _children = null; 
     461                        _runHandler = null; 
     462                        _savedRunHandler = null; 
     463                        _timeoutHandler = null; 
     464                        _interruptedHandler = null; 
    29465                        _waitMonitor = null; 
    30466                        _joinMonitor = null; 
    31                         _errorHandler = null; 
    32                 } 
    33                  
    34                 internal var _parent:Thread; 
    35                 internal var _children:Array; 
    36                 private var _willRemove:Array; 
     467                        _sleepMonitor = null; 
     468                        _eventMonitor = null; 
     469                        _event = null; 
     470                        _errorHandlers = null; 
     471                        _error = null; 
     472                        _errorThread = null; 
     473                        _eventHandlers = null; 
     474                        _isInterrupted = false; 
     475                } 
     476                 
     477                private var _id:uint; 
     478                private var _name:String; 
    37479                private var _state:uint; 
    38                 internal var _executeHandler:Function; 
    39                 internal var _runHandler:Function; 
    40                 private var _waitMonitor:Monitor; 
    41                 private var _joinMonitor:Monitor; 
    42                 private var _errorHandler:ThreadErrorHandler; 
    43                  
    44                 public function get threadErrorHandler():ThreadErrorHandler 
    45                 { 
    46                         return _errorHandler; 
    47                 } 
    48                  
    49                 public function set thraedErrorHandler(value:ThreadErrorHandler):void 
    50                 { 
    51                         _errorHandler = value; 
    52                 } 
    53                  
    54                 public function get isStandingBy():Boolean 
    55                 { 
    56                         return _state == STATE_STANDINGBY; 
    57                 } 
    58                  
    59                 public function get isRunning():Boolean 
    60                 { 
    61                         return (_state & STATE_RUNNING) != 0; 
    62                 } 
    63                  
    64                 public function get isSleeping():Boolean 
    65                 { 
    66                         return (_state & STATE_SLEEPING) != 0; 
    67                 } 
    68                  
    69                 public function get isSuspending():Boolean 
    70                 { 
    71                         return (_state & STATE_SUSPENDING) != 0; 
    72                 } 
    73                  
    74                 public function get isTerminated():Boolean 
    75                 { 
    76                         return (_state & STATE_TERMINATED) != 0; 
    77                 } 
    78                  
    79                 public function get isCatchError():Boolean 
    80                 { 
    81                         return (_state & STATE_ERROR) != 0; 
    82                 } 
    83                  
    84                 internal function addChild(child:Thread):Thread 
    85                 { 
    86                         _children.push(child); 
    87                          
    88                         return child; 
    89                 } 
    90                  
    91                 internal function removeChild(child:Thread):Thread 
    92                 { 
    93                         _willRemove.push(child); 
    94                          
    95                         return child; 
    96                 } 
    97                  
    98                 public function begin():void 
    99                 { 
    100                         if (isRunning) { 
     480                private var _runningState:uint; 
     481                private var _children:Array; 
     482                private var _runHandler:Function; 
     483                private var _savedRunHandler:Function; 
     484                private var _timeoutHandler:Function; 
     485                private var _interruptedHandler:Function; 
     486                private var _waitMonitor:IMonitor; 
     487                private var _joinMonitor:IMonitor; 
     488                private var _sleepMonitor:IMonitor; 
     489                private var _eventMonitor:IMonitor; 
     490                private var _event:Event; 
     491                private var _errorHandlers:Dictionary; 
     492                private var _error:Object; 
     493                private var _errorThread:Thread; 
     494                private var _eventHandlers:Array; 
     495                private var _isInterrupted:Boolean; 
     496                 
     497                /** 
     498                 * このスレッドのユニークな識別子を返します. 
     499                 *  
     500                 * <p>initialize メソッドが呼び出されない限り、ふたつのスレッドに同じ id が割り振られることはありません。</p> 
     501                 */ 
     502                public function get id():uint 
     503                { 
     504                        return _id; 
     505                } 
     506                 
     507                /** 
     508                 * このスレッドの名前を設定します. 
     509                 */ 
     510                public function get name():String 
     511                { 
     512                        return _name; 
     513                } 
     514                 
     515                /** 
     516                 * @private 
     517                 */ 
     518                public function set name(value:String):void 
     519                { 
     520                        _name = value; 
     521                } 
     522                 
     523                /** 
     524                 * このスレッドのクラス名を返します. 
     525                 *  
     526                 * <p>デフォルトでは、 getQualifiedClassName メソッドを使用してクラス名を取得します。</p> 
     527                 */ 
     528                public function get className():String 
     529                { 
     530                        var names:Array = getQualifiedClassName(this).split(/::/); 
     531                        return names.length == 2 ? names[1] : names[0]; 
     532                } 
     533                 
     534                /** 
     535                 * このスレッドの状態を返します. 
     536                 *  
     537                 * <p>返される値は、 ThreadState クラスで定義されている定数のいずれかになります。</p> 
     538                 *  
     539                 * @see ThreadState 
     540                 */ 
     541                public function get state():uint 
     542                { 
     543                        return _state; 
     544                } 
     545                 
     546                /** 
     547                 * このスレッドが割り込まれている場合は true、そうでない場合は false を返します. 
     548                 *  
     549                 * <p>このプロパティが true を返すようになるのは、待機状態<em>でない</em>スレッドに対して、 
     550                 * interrupt メソッドで割り込んだ場合です。</p> 
     551                 *  
     552                 * @see #interrupt() 
     553                 */ 
     554                public function get isInterrupted():Boolean 
     555                { 
     556                        return _isInterrupted; 
     557                } 
     558                 
     559                /** 
     560                 * スレッドを開始します. 
     561                 *  
     562                 * <p>スレッドが既に開始されている場合 (state が NEW でない場合) は IllegalThreadStateError が 
     563                 * スローされます。</p> 
     564                 *  
     565                 * <p>スレッドライブラリが初期化されていない状態の場合 (isReady が false の場合) は ThreadLibraryNotInitializedError が 
     566                 * スローされます。</p> 
     567                 *  
     568                 * <p>あるスレッドの実行中にこのメソッドが呼び出された場合、そのスレッドはこのメソッドが呼び出されたスレッドの親スレッドとなり、 
     569                 * このメソッドが呼び出されたスレッドは子スレッドとなります。</p> 
     570                 *  
     571                 * <p>スレッドが実行中で無い場合にこのメソッドが呼び出された場合、このメソッドが呼び出されたスレッドはトップレベルスレッドとなります。</p> 
     572                 *  
     573                 * <p>このメソッドが呼び出されると、実行関数はまず run メソッドに設定されます。</p> 
     574                 *  
     575                 * @throws      org.libspark.thread.errors.IllegalThreadStateError      スレッドが既に開始されている場合 
     576                 * @throws      org.libspark.thread.errors.ThreadLibraryNotInitializedError     スレッドライブラリが初期化されていない場合 
     577                 */ 
     578                public function start():void 
     579                { 
     580                        // 初期化されていなければエラー 
     581                        if (!isReady) { 
     582                                throw new ThreadLibraryNotInitializedError('Thread Library is not initialized. Please call Thread#initialize before.'); 
     583                        } 
     584                         
     585                        // 既に実行されていたらエラー 
     586                        if (_state != ThreadState.NEW) { 
     587                                throw new IllegalThreadStateError('Thread is already running.'); 
     588                        } 
     589                         
     590                        // state を実行フェーズに切り替える 
     591                        _state = ThreadState.RUNNABLE; 
     592                        _runningState = ThreadState.RUNNABLE; 
     593                         
     594                        // 次の実行関数を run に設定 
     595                        _runHandler = run; 
     596                         
     597                        // カレントスレッドを取得 
     598                        var current:Thread = currentThread; 
     599                         
     600                        if (current != null) { 
     601                                // カレントスレッドがある(=別のスレッド内で start された)場合はそのスレッドの子となる 
     602                                current.addChildThread(this); 
     603                        } 
     604                        else { 
     605                                // カレントスレッドがない場合はトップレベルスレッドとなる 
     606                                addToplevelThread(this); 
     607                        } 
     608                } 
     609                 
     610                /** 
     611                 * このスレッドを待機状態に移行させます. 
     612                 *  
     613                 * <p>このメソッドは IMonitor インターフェイスの実装クラスによって内部的にのみ呼び出されます。</p> 
     614                 *  
     615                 * @param       timeout タイムアウト付かどうか 
     616                 * @param       monitor 待機先のモニタ 
     617                 * @private 
     618                 */ 
     619                internal function monitorWait(timeout:Boolean, monitor:IMonitor):void 
     620                { 
     621                        // wait できる状態でなければエラー 
     622                        if ((_state != ThreadState.RUNNABLE && _state != ThreadState.TERMINATING) || _waitMonitor != null) { 
     623                                throw new IllegalThreadStateError('Thread can not wait.'); 
     624                        } 
     625                         
     626                        // state を待機状態に切り替える 
     627                        _state = timeout ? ThreadState.TIMED_WAITING : ThreadState.WAITING; 
     628                         
     629                        // モニタを保存 
     630                        _waitMonitor = monitor; 
     631                } 
     632                 
     633                /** 
     634                 * このスレッドを待機状態から復帰させます. 
     635                 *  
     636                 * <p>このメソッドは IMonitor インターフェイスの実装クラスによって内部的にのみ呼び出されます。</p> 
     637                 *  
     638                 * @param       monitor 待機先のモニタ 
     639                 * @private 
     640                 */ 
     641                internal function monitorWakeup(monitor:IMonitor):void 
     642                { 
     643                        // 待機状態でなければエラー 
     644                        if ((_state != ThreadState.WAITING && _state != ThreadState.TIMED_WAITING) || _waitMonitor != monitor) { 
     645                                throw new IllegalThreadStateError('Thread can not wakeup.'); 
     646                        } 
     647                         
     648                        // state を実行状態に切り替える 
     649                        _state = _runningState; 
     650                         
     651                        // 保存されていたモニタを破棄 
     652                        _waitMonitor = null; 
     653                } 
     654                 
     655                /** 
     656                 * このスレッドを待機状態からタイムアウトさせます. 
     657                 *  
     658                 * <p>このメソッドは IMonitor インターフェイスの実装クラスによって内部的にのみ呼び出されます。</p> 
     659                 *  
     660                 * @param       monitor 待機先のモニタ 
     661                 * @private 
     662                 */ 
     663                internal function monitorTimeout(monitor:IMonitor):void 
     664                { 
     665                        // 待機時間付の待機状態でなければエラー 
     666                        if (_state != ThreadState.TIMED_WAITING || _waitMonitor != monitor) { 
     667                                throw new IllegalThreadStateError('Thread can not wakeup.'); 
     668                        } 
     669                         
     670                        // state を実行状態に切り替える 
     671                        _state = _runningState; 
     672                         
     673                        // sleep によるタイムアウトではない場合 
     674                        if (_waitMonitor != _sleepMonitor) { 
     675                                // 次に実行する実行関数をタイムアウト用のものに切り替える 
     676                                if (_timeoutHandler != null) { 
     677                                        _runHandler = _timeoutHandler; 
     678                                } 
     679                        } 
     680                         
     681                        // 保存されていたモニタを破棄 
     682                        _waitMonitor = null; 
     683                } 
     684                 
     685                /** 
     686                 * join 用のモニタを返します. 
     687                 *  
     688                 * @return      join 用のモニタ 
     689                 * @private 
     690                 */ 
     691                private function getJoinMonitor():IMonitor 
     692                { 
     693                        return _joinMonitor || (_joinMonitor = new Monitor()); 
     694                } 
     695                 
     696                /** 
     697                 * このスレッドが終了するまで、現在のスレッドを待機させます. 
     698                 *  
     699                 * @param       timeout 待機させる時間 (ミリ秒)。 0 を指定した場合、永遠に待ち続けます 
     700                 * @return      待機する必要がある場合は true、そうでない場合は false 
     701                 */ 
     702                public function join(timeout:uint = 0):Boolean 
     703                { 
     704                        // 既に終了していたらそのまま帰る 
     705                        if (_state == ThreadState.TERMINATED) { 
     706                                return false; 
     707                        } 
     708                         
     709                        // join 用のモニタで wait する 
     710                        getJoinMonitor().wait(timeout); 
     711                         
     712                        return true; 
     713                } 
     714                 
     715                /** 
     716                 * このスレッドに割り込みます. 
     717                 *  
     718                 * <p>このスレッドが待機中である場合、割り込みステータスはクリアされ、スレッドが起床します。 
     719                 * このとき、割り込みハンドラが設定されていれば実行関数を割り込みハンドラに設定して実行を再開し、 
     720                 * そうでない場合は InterruptedError を発生させます。</p> 
     721                 *  
     722                 * <p>待機中でない場合、このスレッドの割り込みステータスが設定されます。</p> 
     723                 */ 
     724                public function interrupt():void 
     725                { 
     726                        if (_state == ThreadState.WAITING || _state == ThreadState.TIMED_WAITING) { 
     727                                // 待機中の場合 
     728                                // モニタに対して待機セットから抜けることを伝える 
     729                                _waitMonitor.leave(this); 
     730                                _waitMonitor = null; 
     731                                // state を切り替える 
     732                                _state = _runningState; 
     733                                // 割り込みハンドラがあれば実行関数を割り込みハンドラに設定 
     734                                if (_interruptedHandler != null) { 
     735                                        _runHandler = _interruptedHandler; 
     736                                } 
     737                                else { 
     738                                        // 割り込みハンドラがなければ例外を発生 
     739                                        _error = new InterruptedError(); 
     740                                } 
     741                        } 
     742                        else { 
     743                                // そうでない場合は割り込みステータスを設定 
     744                                _isInterrupted = true; 
     745                        } 
     746                } 
     747                 
     748                /** 
     749                 * 子スレッドの配列を返します. 
     750                 *  
     751                 * @return      子スレッドの配列 
     752                 * @private 
     753                 */ 
     754                private function getChildren():Array 
     755                { 
     756                        return _children || (_children = []); 
     757                } 
     758                 
     759                /** 
     760                 * 子スレッドを子スレッドの配列に追加します. 
     761                 *  
     762                 * @param       thread  追加する子スレッド 
     763                 * @private 
     764                 */ 
     765                private function addChildThread(thread:Thread):void 
     766                { 
     767                        getChildren().push(thread); 
     768                } 
     769                 
     770                /** 
     771                 * エラーハンドラマップを返します. 
     772                 *  
     773                 * @return      エラーハンドラマップ 
     774                 * @private 
     775                 */ 
     776                private function getErrorHandlers():Dictionary 
     777                { 
     778                        return _errorHandlers || (_errorHandlers = new Dictionary()); 
     779                } 
     780                 
     781                /** 
     782                 * エラーハンドラをエラーハンドラマップに追加します. 
     783                 *  
     784                 * @param       klass   エラークラス 
     785                 * @param       handler エラーハンドラ 
     786                 * @param       reset   リセットするか 
     787                 * @private 
     788                 */ 
     789                private function addErrorHandler(klass:Class, handler:Function, reset:Boolean):void 
     790                { 
     791                        getErrorHandlers()[getQualifiedClassName(klass)] = new ErrorHandler(handler, reset); 
     792                } 
     793                 
     794                /** 
     795                 * エラーハンドラをエラーハンドラマップから削除します. 
     796                 *  
     797                 * @param       klass   エラークラス 
     798                 * @private 
     799                 */ 
     800                private function removeErrorHandler(klass:Class):void 
     801                { 
     802                        // ハンドラマップが存在しなければ何もしない 
     803                        if (_errorHandlers == null) { 
    101804                                return; 
    102805                        } 
    103806                         
    104                         (_parent = _currentThread).addChild(this); 
    105                          
    106                         _runHandler = execute; 
    107                         _executeHandler = beginHandler; 
    108                 } 
    109                  
    110                 public function terminate():void 
    111                 { 
    112                         if (!isRunning) { 
     807                        // ハンドラマップから削除 
     808                        delete _errorHandlers[getQualifiedClassName(klass)]; 
     809                } 
     810                 
     811                /** 
     812                 * エラーハンドラマップをリセットします. 
     813                 *  
     814                 * @private 
     815                 */ 
     816                private function resetErrorHandlers():void 
     817                { 
     818                        // ハンドラマップが存在しなければ何もしない 
     819                        if (_errorHandlers == null) { 
    113820                                return; 
    114821                        } 
    115822                         
    116                         _executeHandler = terminateHandler; 
    117                 } 
    118                  
    119                 public function join():void 
    120                 { 
    121                         if (isTerminated) { 
     823                        // 登録されているハンドラを巡回 
     824                        for (var key:String in _errorHandlers) { 
     825                                // reset が true であればハンドラを削除する 
     826                                if (ErrorHandler(_errorHandlers[key]).reset) { 
     827                                        delete _errorHandlers[key]; 
     828                                } 
     829                        } 
     830                } 
     831                 
     832                /** 
     833                 * 指定されたエラーに該当するエラーハンドラを返します. 
     834                 *  
     835                 * @param       error   エラー 
     836                 * @return      該当するエラーハンドラ。無ければ null 
     837                 * @private 
     838                 */ 
     839                private function getErrorHandler(error:Object):ErrorHandler 
     840                { 
     841                        // ハンドラマップが存在しなければ null を返す 
     842                        if (_errorHandlers == null) { 
     843                                return null; 
     844                        } 
     845                         
     846                        // error のクラス名を取得 
     847                        var className:String = getQualifiedClassName(error); 
     848                         
     849                        // クラス名が取得できる限り回す 
     850                        while (className != null) { 
     851                                // ハンドラマップからクラス名をキーにしてハンドラを検索する 
     852                                var handler:ErrorHandler = _errorHandlers[className]; 
     853                                // 見つかればそれを返す 
     854                                if (handler != null) { 
     855                                        return handler; 
     856                                } 
     857                                // 見つからなければ、スーパークラスを辿る 
     858                                try { 
     859                                        className = getQualifiedSuperclassName(getDefinitionByName(className)); 
     860                                } 
     861                                catch (e:ReferenceError) { 
     862                                        // ここで出る ReferenceError は getDefinitionByName によるもの 
     863                                        // プライベートクラス等の場合に起こりうる 
     864                                        className = null; 
     865                                } 
     866                        } 
     867                         
     868                        return null; 
     869                } 
     870                 
     871                /** 
     872                 * イベント待機用のモニタを返します. 
     873                 *  
     874                 * @return      イベント待機用のモニタ 
     875                 * @private 
     876                 */ 
     877                private function getEventMonitor():IMonitor 
     878                { 
     879                        return _eventMonitor || (_eventMonitor = new Monitor()); 
     880                } 
     881                 
     882                /** 
     883                 * イベントハンドラの配列を返します. 
     884                 *  
     885                 * @return      イベントハンドラの配列 
     886                 * @private 
     887                 */ 
     888                private function getEventHandlers():Array 
     889                { 
     890                        return _eventHandlers || (_eventHandlers = []); 
     891                } 
     892                 
     893                /** 
     894                 * イベントハンドラをイベントハンドラの配列に追加します. 
     895                 *  
     896                 * @param       dispatcher      ディスパッチャ 
     897                 * @param       type    イベントタイプ 
     898                 * @param       func    イベントハンドラ 
     899                 * @param       useCapture      addEventListener 参照 
     900                 * @param       priority        addEventListener 参照 
     901                 * @param       useWeakReference        addEventListener 参照 
     902                 * @private 
     903                 */ 
     904                private function addEventHandler(dispatcher:IEventDispatcher, type:String, func:Function, useCapture:Boolean, priority:int, useWeakReference:Boolean):void 
     905                { 
     906                        // イベントハンドラを作成してリストに追加 
     907                        getEventHandlers().push(new EventHandler(dispatcher, type, eventHandler, func, useCapture, priority, useWeakReference)); 
     908                } 
     909                 
     910                /** 
     911                 * イベントハンドラの配列をリセットします. 
     912                 *  
     913                 * @private 
     914                 */ 
     915                private function resetEventHandlers():void 
     916                { 
     917                        // イベントハンドラリストがなければ何もしない 
     918                        if (_eventHandlers == null) { 
    122919                                return; 
    123920                        } 
    124921                         
    125                         if (_joinMonitor == null) { 
    126                                 _joinMonitor = new MonitorObject(); 
    127                         } 
    128                          
    129                         _joinMonitor.wait(); 
    130                 } 
    131                  
    132                 public function suspend():void 
    133                 { 
    134                         if ((_state & (STATE_SLEEPING | STATE_SUSPENDING)) != 0) { 
     922                        // 全てのイベントハンドラの登録を解除 
     923                        for each (var handler:EventHandler in _eventHandlers) { 
     924                                handler.unregister(); 
     925                        } 
     926                         
     927                        // 配列を初期化 
     928                        _eventHandlers.length = 0; 
     929                } 
     930                 
     931                /** 
     932                 * イベントが発生した際に実行されるハンドラです. 
     933                 *  
     934                 * @param       e       発生したイベント 
     935                 * @param       handler 該当するイベントハンドラ 
     936                 * @private 
     937                 */ 
     938                private function eventHandler(e:Event, handler:EventHandler):void 
     939                { 
     940                        // 既にイベントが起こっていれば何もしない 
     941                        if (_event != null) { 
    135942                                return; 
    136943                        } 
    137944                         
    138                         _executeHandler = suspendHandler; 
    139                 } 
    140                  
    141                 public function resume():void 
    142                 { 
    143                         if (!isSuspending) { 
    144                                 return; 
    145                         } 
    146                          
    147                         _executeHandler = resumeHandler; 
    148                 } 
    149                  
    150                 public function interruput():void 
    151                 { 
     945                        // イベントを保存 
     946                        _event = e; 
     947                         
     948                        // 該当するイベントハンドラを次の実行関数に設定 
     949                        _runHandler = handler.func; 
     950                         
     951                        // イベントハンドラをリセット 
     952                        resetEventHandlers(); 
     953                         
     954                        // 待機状態である場合 
    152955                        if (_waitMonitor != null) { 
    153                                 _waitMonitor.interrupt(this); 
    154                         } 
    155                 } 
    156                  
    157                 internal function sleep(monitor:Monitor):void 
    158                 { 
    159                         if ((_state & (STATE_SLEEPING | STATE_SUSPENDING)) != 0) { 
    160                                 return; 
    161                         } 
    162                          
    163                         if (monitor == null || _waitMonitor != null) { 
    164                                 throw new Error('Can not wait.'); 
    165                         } 
    166                          
    167                         _waitMonitor = monitor; 
    168                         _state |= STATE_SLEEPING; 
    169                         _executeHandler = nullHandler; 
    170                          
    171                         if (_debug != null) { 
    172                                 _debug.threadChanged(this); 
    173                         } 
    174                 } 
    175                  
    176                 internal function wakeup(monitor:Monitor):void 
    177                 { 
    178                         if (!isSleeping) { 
    179                                 return; 
    180                         } 
    181                          
    182                         if (monitor == null || _waitMonitor != monitor) { 
    183                                 throw new Error('Can not wakeup.'); 
    184                         } 
    185                          
    186                         _waitMonitor = null; 
    187                         _state &= ~STATE_SLEEPING; 
    188                         _executeHandler = runHandler; 
    189                          
    190                         if (_debug != null) { 
    191                                 _debug.threadChanged(this); 
    192                         } 
    193                 } 
    194                  
    195                 internal function wakeupError(e:Error):void 
    196                 { 
    197                         if (!isSleeping) { 
    198                                 return; 
    199                         } 
    200                          
    201                         _waitMonitor = null; 
    202                         _state &= ~STATE_SLEEPING; 
    203                         _executeHandler = function():void 
    204                         { 
    205                                 throw e; 
    206                         }; 
    207                 } 
    208                  
    209                 internal function internalExecute():void 
    210                 { 
     956                                // モニタに対して待機セットから抜けることを伝える 
     957                                _waitMonitor.leave(this); 
     958                                // 保存されていたモニタを破棄 
     959                                _waitMonitor = null; 
     960                        } 
     961                         
     962                        // state を実行状態に切り替える 
     963                        _state = _runningState; 
     964                         
     965                        // 入れ子になる場合があるのでカレントスレッドを保存 
     966                        var current:Thread = _currentThread; 
     967                         
     968                        try { 
     969                                // そしてすぐ実行してみる 
     970                                internalExecute(null, this); 
     971                        } 
     972                        finally { 
     973                                // カレントスレッドを復元 
     974                                _currentThread = current; 
     975                        } 
     976                } 
     977                 
     978                /** 
     979                 * 子スレッドを含め、このスレッドを実行します. 
     980                 *  
     981                 * @return      このスレッドの実行が継続していれば true、そうでなければ (実行が終了したら) false 
     982                 * @private 
     983                 */ 
     984                private function execute():Boolean 
     985                { 
     986                        // まだ start していなければ何もしない 
     987                        if (_state == ThreadState.NEW) { 
     988                                return true; 
     989                        } 
     990                        // 既に終了していれば何もしない 
     991                        if (_state == ThreadState.TERMINATED) { 
     992                                return false; 
     993                        } 
     994                         
     995                        // 発生した例外 
     996                        var error:Object = _error; 
     997                        var errorThread:Thread = _errorThread || this; 
     998                         
     999                        // すべての子スレッドを呼び出す 
    2111000                        var children:Array = _children; 
    212                         var l:uint = children.length; 
    213                          
    214                         var willRemove:Array = _willRemove; 
    215                         if (willRemove.length > 0) { 
    216                                 for each (var c:Thread in willRemove) { 
    217                                         var index:uint = children.indexOf(c); 
    218                                         if (index != -1) { 
    219                                                 children.splice(index, 1); 
    220                                         } 
    221                                 } 
    222                                 willRemove.length = 0; 
    223                                 l = children.length; 
    224                         } 
    225                          
    226                         for (var i:uint = 0; i < l; ++i) { 
     1001                        if (children != null) { 
     1002                                var cl:uint = children.length; 
     1003                                for (var ci:uint = 0; ci < cl; ) { 
     1004                                        var child:Thread = Thread(children[ci]); 
     1005                                        if (!child.execute()) { 
     1006                                                // 終了したら削除 
     1007                                                children.splice(ci, 1); 
     1008                                                --cl; 
     1009                                        } 
     1010                                        else { 
     1011                                                ++ci; 
     1012                                        } 
     1013                                        // 子スレッドで例外が起きていたら一番最初のものを保存 
     1014                                        // Note: _errorThread が null の場合、その例外はまだ親に伝播するべきではないことを示す 
     1015                                        if (child._error != null && child._errorThread != null && error == null) { 
     1016                                                error = child._error; 
     1017                                                errorThread = child._errorThread; 
     1018                                                child._error = null; 
     1019                                                child._errorThread = null; 
     1020                                        } 
     1021                                } 
     1022                        } 
     1023                         
     1024                        return internalExecute(error, errorThread); 
     1025                } 
     1026                 
     1027                /** 
     1028                 * このスレッドを実行します. 
     1029                 *  
     1030                 * <p>子スレッドは実行されません。</p> 
     1031                 *  
     1032                 * @param       error   ここに来るまでに発生したエラー 
     1033                 * @param       errorThread     エラーが発生した場合、その発生元のスレッド 
     1034                 * @return      このスレッドの実行が継続していれば true、そうでなければ (実行が終了したら) false 
     1035                 * @private 
     1036                 */ 
     1037                private function internalExecute(error:Object, errorThread:Thread):Boolean 
     1038                { 
     1039                        if (_state == ThreadState.WAITING || _state == ThreadState.TIMED_WAITING) { 
     1040                                if (error != null) { 
     1041                                        // 待機状態で子スレッドによる例外発生していた場合は無理やり起きる 
     1042                                        // モニタに対して待機セットから抜けることを伝える 
     1043                                        _waitMonitor.leave(this); 
     1044                                        _waitMonitor = null; 
     1045                                        // state を切り替える 
     1046                                        _state = _runningState; 
     1047                                } 
     1048                                else { 
     1049                                        // 例外が発生していない場合はここでリターン 
     1050                                        return true; 
     1051                                } 
     1052                        } 
     1053                         
     1054                        // 今回実行する実行関数 
     1055                        var runHandler:Function = null; 
     1056                        // エラーハンドラ 
     1057                        var errorHandler:ErrorHandler = null; 
     1058                         
     1059                        if (error != null) { 
     1060                                 
     1061                                // 例外が発生していた場合は例外ハンドラを選択する 
     1062                                errorHandler = getErrorHandler(error); 
     1063                                 
     1064                                if (errorHandler != null) { 
     1065                                        // ハンドラが見つかった場合 
     1066                                        // 例外が子から伝播してきた場合、割り込まれていると考え実行関数を保存する 
     1067                                        if (errorThread != this) { 
     1068                                                _savedRunHandler = _runHandler; 
     1069                                        } 
     1070                                        else { 
     1071                                                // 子からの伝播でない場合、自力で処理したということで保存されている例外をクリア 
     1072                                                _error = null; 
     1073                                        } 
     1074                                        // 実行関数をエラーハンドラに設定 
     1075                                        runHandler = errorHandler.handler; 
     1076                                } 
     1077                                else { 
     1078                                        // 見つからなかった場合はこのスレッドは終了フェーズに移行し親に例外を伝播する 
     1079                                        if (_runningState != ThreadState.TERMINATING) { 
     1080                                                // 既に終了フェーズでない場合のみ 
     1081                                                // state を終了フェーズに切り替える 
     1082                                                _state = ThreadState.TERMINATING; 
     1083                                                _runningState = ThreadState.TERMINATING; 
     1084                                                // 実行関数を finalize に設定 
     1085                                                runHandler = finalize; 
     1086                                        } 
     1087                                        // 親に伝播するよう例外を保存 
     1088                                        _error = error; 
     1089                                        _errorThread = errorThread; 
     1090                                } 
     1091                        } 
     1092                        else { 
     1093                                // 子スレッドによる例外が発生していない場合は前回指定された実行関数を設定 
     1094                                runHandler = _runHandler; 
     1095                        } 
     1096                         
     1097                        // 実行関数をリセット 
     1098                        _runHandler = null; 
     1099                        // タイムアウトハンドラをリセット 
     1100                        _timeoutHandler = null; 
     1101                        // イベントハンドラをリセット 
     1102                        resetEventHandlers(); 
     1103                        // エラーハンドラをリセット 
     1104                        resetErrorHandlers(); 
     1105                        // 割り込みハンドラをリセット 
     1106                        _interruptedHandler = null; 
     1107                         
     1108                        // エラーハンドラが実行されようとしている場合、実行終了後に復帰できるように保存しておいた実行関数を設定 
     1109                        if (errorHandler != null) { 
     1110                                _runHandler = _savedRunHandler; 
     1111                        } 
     1112                         
     1113                        // Note: finalize の最後で wait が入って待機状態になった後に起きた等の場合に、 
     1114                        //       runHandler が null の状態でここに到達することがある 
     1115                        if (runHandler != null) { 
     1116                                 
     1117                                // カレントスレッドを設定 
     1118                                _currentThread = this; 
     1119                                 
    2271120                                try { 
    228                                         Thread(children[i]).internalExecute(); 
    229                                 } 
    230                                 catch (e:Error) { 
    231                                         handleError(e); 
    232                                 } 
    233                         } 
    234                          
    235                         try { 
    236                                 _currentThread = this; 
    237                                 _executeHandler.apply(this); 
    238                         } 
    239                         catch (e2:Error) { 
    240                                 handleError(e2); 
    241                         } 
    242                         finally { 
    243                                 _currentThread = null; 
    244                         } 
    245                 } 
    246                  
    247                 private function handleError(e:Error):void 
    248                 { 
    249                         try { 
    250                                 catchError(_currentThread, e); 
    251                         } 
    252                         catch (ee:Error) { 
    253                                 if ((ee = handleByErrorHandler(ee)) != null) { 
    254                                         terminateHandler(); 
    255                                         _state |= STATE_ERROR; 
     1121                                        // 実行関数を呼び出す 
     1122                                        if (errorHandler != null) { 
     1123                                                // エラーハンドラである場合は例外と例外の発生元のスレッドを引数として渡す 
     1124                                                runHandler.apply(this, [error, errorThread]); 
     1125                                        } 
     1126                                        else if (_event != null) { 
     1127                                                var ev:Event = _event; 
     1128                                                _event = null; 
     1129                                                // イベントハンドラである場合はイベントを渡す 
     1130                                                runHandler.apply(this, [ev]); 
     1131                                        } 
     1132                                        else { 
     1133                                                // それ以外の場合は引数なしで呼び出す 
     1134                                                runHandler.apply(this); 
     1135                                        } 
     1136                                } 
     1137                                catch (e:Object) { 
     1138                                        // 例外が発生した場合例外を保存 
     1139                                        _error = e; 
     1140                                        // エラーハンドラ以外で例外が発生し、かつ該当するエラーハンドラが存在する場合 
     1141                                        if (errorHandler == null && getErrorHandler(e) != null) { 
     1142                                                // 自力で例外を回復できる可能性があるので強制的に runHandler を非 null にして次に繰り越す 
     1143                                                // このとき、エラーハンドラ実行後に復帰するために runHandler を保存しておく 
     1144                                                // run はダミーで意味はない 
     1145                                                _savedRunHandler = _runHandler; 
     1146                                                _runHandler = run; 
     1147                                        } 
     1148                                        else { 
     1149                                                // それ以外の場合は例外を親に伝播する必要がある 
     1150                                                // 例外が親に伝播するように発生元スレッドを設定 
     1151                                                _errorThread = this; 
     1152                                                // 実行関数の設定をクリアして強制的に終了フェーズに移行させる 
     1153                                                _runHandler = null; 
     1154                                        } 
    2561155                                         
    257                                         throw ee; 
    258                                 } 
    259                         } 
    260                 } 
    261                  
    262                 private function handleByErrorHandler(e:Error):Error 
    263                 { 
    264                         if (_errorHandler != null) { 
    265                                 try { 
    266                                         _errorHandler.handleError(_currentThread, e); 
    267                                         e = null; 
    268                                 } 
    269                                 catch (ee:Error) { 
    270                                         e = ee; 
    271                                 } 
    272                         } 
    273                         return e; 
    274                 } 
    275                  
    276                 internal function nullHandler():void 
    277                 { 
    278                 } 
    279                  
    280                 internal function runHandler():void 
    281                 { 
    282                         _runHandler.apply(this); 
    283                 } 
    284                  
    285                 internal function beginHandler():void 
    286                 { 
    287                         _state = STATE_RUNNING; 
    288                         _executeHandler = runHandler; 
    289                         initialize(); 
    290                         if (_executeHandler == runHandler) { 
    291                                 runHandler(); 
    292                         } 
    293                          
    294                         if (_debug != null) { 
    295                                 _debug.threadBegin(); 
    296                         } 
    297                 } 
    298                  
    299                 internal function terminateHandler():void 
    300                 { 
    301                         var children:Array = _children.slice(); 
    302                         var l:uint = children.length; 
    303                         for (var i:uint = 0; i < l; ++i) { 
    304                                 Thread(children[i]).terminateHandler(); 
    305                         } 
    306                          
    307                         if (_parent != null) { 
    308                                 _parent.removeChild(this); 
    309                         } 
    310                         _state = STATE_TERMINATED; 
    311                         _executeHandler = nullHandler; 
    312                         finalize(); 
    313                          
    314                         if (_debug != null) { 
    315                                 _debug.threadTerminate(this); 
    316                         } 
    317                          
    318                         if (_joinMonitor != null) { 
    319                                 _joinMonitor.notifyAll(); 
    320                         } 
    321                 } 
    322                  
    323                 internal function suspendHandler():void 
    324                 { 
    325                         _state |= STATE_SUSPENDING; 
    326                         _executeHandler = nullHandler; 
    327                 } 
    328                  
    329                 internal function resumeHandler():void 
    330                 { 
    331                         _state &= ~STATE_SUSPENDING; 
    332                         _executeHandler = runHandler; 
    333                         runHandler(); 
    334                 } 
    335                  
    336                 /** 
    337                  * スレッドの処理関数を切り替えます 
    338                  *  
    339                  * @param       method  処理関数 
    340                  */ 
    341                 protected function switchExecuteMethod(method:Function):void 
    342                 { 
    343                         _runHandler = method; 
    344                 } 
    345                  
    346                 /** 
    347                  * オーバーライドして初期化処理を記述してください 
    348                  */ 
    349                 protected function initialize():void 
    350                 { 
    351                 } 
    352                  
    353                 /** 
    354                  * オーバーライドしてスレッドの処理を記述してください 
    355                  */ 
    356                 protected function execute():void 
    357                 { 
    358                 } 
    359                  
    360                 /** 
    361                  * オーバーライドして終了処理を記述してください 
     1156                                } 
     1157                                finally { 
     1158                                        // カレントスレッドを元に戻す 
     1159                                        _currentThread = null; 
     1160                                } 
     1161                        } 
     1162                         
     1163                        // 今エラーハンドラを実行し、かつエラーが発生していない場合、保存しておいた実行関数はもう必要ないので破棄 
     1164                        if (errorHandler != null && _error == null) { 
     1165                                _savedRunHandler = null; 
     1166                        } 
     1167                         
     1168                        // イベントハンドラが設定された場合 
     1169                        if (_eventHandlers != null && _eventHandlers.length > 0) { 
     1170                                // エラーが発生していなければ 
     1171                                if (_error == null) { 
     1172                                        // 全てのイベントハンドラを登録 
     1173                                        for each (var eventHandler:EventHandler in _eventHandlers) { 
     1174                                                eventHandler.register(); 
     1175                                        } 
     1176                                        // 次に実行する実行関数が設定されていない場合で 
     1177                                        if (_runHandler == null) { 
     1178                                                // まだ待機状態で無い場合、自動で待機状態に移行する 
     1179                                                if (_waitMonitor == null) { 
     1180                                                        try { 
     1181                                                                _currentThread = this; 
     1182                                                                getEventMonitor().wait(); 
     1183                                                        } 
     1184                                                        finally { 
     1185                                                                _currentThread = null; 
     1186                                                        } 
     1187                                                } 
     1188                                        } 
     1189                                } 
     1190                        } 
     1191                         
     1192                        if (_runHandler != null) { 
     1193                                // 次に実行する実行関数が設定されている場合実行を継続 
     1194                        } 
     1195                        else { 
     1196                                // 次に実行する実行関数が設定されていない場合 
     1197                                if (_state == ThreadState.WAITING || _state == ThreadState.TIMED_WAITING) { 
     1198                                        // 待機状態に入っている場合は次に繰り越す 
     1199                                } 
     1200                                else if (_runningState == ThreadState.TERMINATING) { 
     1201                                        // 終了フェーズだった場合は実行を終了する 
     1202                                        // 自分の子スレッドを、孤児スレッドとしてトップレベルに移動する 
     1203                                        if (_children != null) { 
     1204                                                addToplevelThreads(_children); 
     1205                                                // 子スレッドは破棄 
     1206                                                _children = null; 
     1207                                        } 
     1208                                        // state を終了状態に切り替える 
     1209                                        _state = ThreadState.TERMINATED; 
     1210                                        _runningState = ThreadState.TERMINATED; 
     1211                                        // join 用のモニタが存在(=join 待ちしているスレッドが存在)すれば notifyAll で起こす 
     1212                                        if (_joinMonitor != null) { 
     1213                                                _joinMonitor.notifyAll(); 
     1214                                                _joinMonitor = null; 
     1215                                        } 
     1216                                        // 終了 
     1217                                        return false; 
     1218                                } 
     1219                                else { 
     1220                                        // 終了フェーズでない場合は終了フェーズに入る 
     1221                                        // state を終了フェーズに切り替える 
     1222                                        _state = ThreadState.TERMINATING; 
     1223                                        _runningState = ThreadState.TERMINATING; 
     1224                                        // 次の実行関数を finalize に設定 
     1225                                        _runHandler = finalize; 
     1226                                } 
     1227                        } 
     1228                         
     1229                        return true; 
     1230                } 
     1231                 
     1232                /** 
     1233                 * このメソッドをオーバーライドして、スレッドの処理を記述します. 
     1234                 *  
     1235                 * <p>start メソッドが呼び出され、スレッドの実行が開始されると、まずはじめにこのメソッドが実行関数として設定され、 
     1236                 * スレッドが実行されます。</p> 
     1237                 *  
     1238                 * <p>このメソッド内で next メソッドを呼び出すことにより、次の実行関数を設定することができます。 
     1239                 * 次の実行関数が設定されない場合、スレッドは終了フェーズへと移行します。</p> 
     1240                 *  
     1241                 * <p>next メソッドのほか、 wait, join, sleep, event, timeout, error, interrupted といった 
     1242                 * メソッドを呼び出すことで、スレッドの動作を様々に制御することができます。</p> 
     1243                 *  
     1244                 * @see #next() 
     1245                 * @see #join() 
     1246                 * @see #sleep() 
     1247                 * @see #event() 
     1248                 * @see #timeout() 
     1249                 * @see #error() 
     1250                 * @see #interrupted() 
     1251                 * @see #interrupt() 
     1252                 * @see #finalize() 
     1253                 */ 
     1254                protected function run():void 
     1255                { 
     1256                         
     1257                } 
     1258                 
     1259                /** 
     1260                 * このメソッドをオーバーライドして、スレッドの終了処理を記述します. 
     1261                 *  
     1262                 * <p>スレッドが終了フェーズに移行すると、必ずこのメソッドが実行関数に設定され、スレッドが実行されます。 
     1263                 * 例外が発生したりした場合でも、必ず終了フェーズに移行するので、スレッドが終了する前にはこのメソッドが実行されることが 
     1264                 * 確実に保証されています。</p> 
     1265                 *  
     1266                 * <p>このメソッドも実行関数と同じ扱いであるため、 next をはじめとするメソッドによってスレッドを制御することが可能です。</p> 
     1267                 *  
     1268                 * <p>スレッドはこのメソッドを利用して終了処理を行い、いかなる状況でも安全に終了することを保証するべきです。</p> 
    3621269                 */ 
    3631270                protected function finalize():void 
    3641271                { 
    365                 } 
    366                  
    367                 /** 
    368                  * オーバーライドして例外処理を記述してください。 
    369                  * 処理しなかった例外は再スローしてください。 
    370                  *  
    371                  * @param       thred   例外が発生したスレッド 
    372                  * @param       error   発生した例外 
    373                  */ 
    374                 protected function catchError(thread:Thread, error:Error):void 
    375                 { 
    376                         throw error; 
    377                 } 
    378                  
     1272                         
     1273                } 
     1274                 
     1275                /** 
     1276                 * このスレッドの名前を整形して返します. 
     1277                 *  
     1278                 * <p>デフォルトでは、</p> 
     1279                 * <pre>'[' + className + ' ' + name + ']'</pre> 
     1280                 * <p>と等価な値が返されます。</p> 
     1281                 *  
     1282                 * <p>このメソッドの呼び出し結果は、 toString メソッドなどで使用されます。</p> 
     1283                 *  
     1284                 * @param       name    スレッドの名前 
     1285                 * @return      整形された名前 
     1286                 */ 
     1287                protected function formatName(name:String):String 
     1288                { 
     1289                        return '[' + className + ' ' + name + ']'; 
     1290                } 
     1291                 
     1292                /** 
     1293                 * このスレッドの文字列表現を返します. 
     1294                 *  
     1295                 * <p>デフォルトでは、 formatName メソッドを、このスレッドの名前を引数にして呼び出した結果です。</p> 
     1296                 *  
     1297                 * @return      このスレッドの文字列表現 
     1298                 */ 
    3791299                public function toString():String 
    3801300                { 
    381                         return '[Thread]'; 
    382                 } 
    383                  
    384                 public function getDebugColor():uint 
    385                 { 
    386                         if (isCatchError) { 
    387                                 return 0xff0000; 
    388                         } 
    389                         if (isSleeping || isSuspending) { 
    390                                 return 0xff9900; 
    391                         } 
    392                         if (isRunning) { 
    393                                 return 0x006666; 
    394                         } 
    395                         return 0xcccccc; 
     1301                        return formatName(name); 
    3961302                } 
    3971303        } 
    3981304} 
     1305 
     1306import flash.events.Event; 
     1307import flash.events.IEventDispatcher; 
     1308 
     1309class ErrorHandler 
     1310{ 
     1311        public function ErrorHandler(handler:Function, reset:Boolean) 
     1312        { 
     1313                this.handler = handler; 
     1314                this.reset = reset; 
     1315        } 
     1316         
     1317        public var handler:Function; 
     1318        public var reset:Boolean; 
     1319} 
     1320 
     1321class EventHandler 
     1322{ 
     1323        public function EventHandler(dispatcher:IEventDispatcher, type:String, listener:Function, func:Function, useCapture:Boolean, priority:int, useWeakReference:Boolean) 
     1324        { 
     1325                this.dispatcher = dispatcher; 
     1326                this.type = type; 
     1327                this.listener = listener; 
     1328                this.func = func; 
     1329                this.useCapture = useCapture; 
     1330                this.priority = priority; 
     1331                this.useWeakReference = useWeakReference; 
     1332        } 
     1333         
     1334        public var dispatcher:IEventDispatcher; 
     1335        public var type:String; 
     1336        public var listener:Function; 
     1337        public var func:Function; 
     1338        public var useCapture:Boolean; 
     1339        public var priority:int; 
     1340        public var useWeakReference:Boolean; 
     1341         
     1342        public function register():void 
     1343        { 
     1344                dispatcher.addEventListener(type, handler, useCapture, priority, useWeakReference); 
     1345        } 
     1346         
     1347        public function unregister():void 
     1348        { 
     1349                dispatcher.removeEventListener(type, handler, useCapture); 
     1350        } 
     1351         
     1352        private function handler(e:Event):void 
     1353        { 
     1354                listener(e, this); 
     1355        } 
     1356}