root/as3/Thread/trunk/src/org/libspark/thread/threads/net/URLLoaderThread.as

リビジョン 641, 6.8 kB (コミッタ: yossy, コミット時期: 4 年 前)

Thread: branches/soumen を trunk にマージ

Line 
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  */
28 package org.libspark.thread.threads.net
29 {
30         import flash.events.ProgressEvent;
31         import org.libspark.thread.Thread;
32         import org.libspark.thread.utils.IProgress;
33         import org.libspark.thread.utils.IProgressNotifier;
34         import org.libspark.thread.utils.Progress;
35        
36         import flash.net.URLLoader;
37         import flash.net.URLRequest;
38        
39         import flash.events.Event;
40         import flash.events.IOErrorEvent;
41         import flash.events.SecurityErrorEvent;
42        
43         import flash.errors.IOError;
44        
45         /**
46          * URLLoader を用いてデータを読み込むためのスレッドです.
47          *
48          * <p>このスレッドを開始すると、与えられた URLRequest を用いてロード処理を開始し、
49          * ロードが完了 (Event.COMPLETE) するとスレッドが終了します。</p>
50          *
51          * <p>join メソッドを用いると、簡単にロード待ちをすることができます。</p>
52          *
53          * <p>ロード中にエラーが発生した場合は、以下の例外がスローされます。
54          * これらの例外は、このスレッドを開始したスレッド(親スレッド)で捕捉する事が出来ます。</p>
55          *
56          * <ul>
57          * <li>flash.events.IOErrorEvent.IO_ERROR: flash.errors.IOError</li>
58          * <li>flash.events.SecurityErrorEvent.SECURITY_ERROR: SecurityError</li>
59          * </ul>
60          *
61          * @author      yossy:beinteractive
62          */
63         public class URLLoaderThread extends Thread implements IProgressNotifier
64         {
65                 /**
66                  * 新しい URLLoaderThread クラスのインスタンスを生成します.
67                  *
68                  * @param request ロード対象となる URLRequest
69                  * @param loader ロードに使用する URLLoader 。省略もしくは null の場合、新たに作成した URLLoader を使用します
70                  */
71                 public function URLLoaderThread(request:URLRequest, loader:URLLoader = null)
72                 {
73                         _request = request;
74                         _loader = loader != null ? loader : new URLLoader();
75                         _progress = new Progress();
76                 }
77                
78                 private var _request:URLRequest;
79                 private var _loader:URLLoader;
80                 private var _progress:Progress;
81                
82                 /**
83                  * ロード対象となる URLRequest を返します.
84                  */
85                 public function get request():URLRequest
86                 {
87                         return _request;
88                 }
89                
90                 /**
91                  * ロードに使用する URLLoader を返します.
92                  *
93                  * <p>ロード完了(スレッドの終了)後に、ロードしたデータ (URLLoader.data) を取得したい場合などに
94                  * このプロパティを使用します。</p>
95                  */
96                 public function get loader():URLLoader
97                 {
98                         return _loader;
99                 }
100                
101                 /**
102                  * @inheritDoc
103                  */
104                 public function get progress():IProgress
105                 {
106                         return _progress;
107                 }
108                
109                 /**
110                  * ロード処理をキャンセルします.
111                  */
112                 public function cancel():void
113                 {
114                         // 割り込みをかける
115                         interrupt();
116                 }
117                
118                 /**
119                  * 実行
120                  *
121                  * @private
122                  */
123                 override protected function run():void
124                 {
125                         // イベントハンドラを設定
126                         // Note: イベントハンドラを設定した場合、自動的に wait がかかる
127                         events();
128                        
129                         // 割り込みハンドラを設定
130                         interrupted(interruptedHandler);
131                        
132                         // ロード開始
133                         _loader.load(_request);
134                 }
135                
136                 /**
137                  * イベントハンドラの登録
138                  *
139                  * @private
140                  */
141                 private function events():void
142                 {
143                         event(_loader, Event.COMPLETE, completeHandler);
144                         event(_loader, ProgressEvent.PROGRESS, progressHandler);
145                         event(_loader, IOErrorEvent.IO_ERROR, ioErrorHandler);
146                         event(_loader, SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
147                 }
148                
149                 /**
150                  * まだ開始を通知していなければ通知する
151                  *
152                  * @private
153                  */
154                 private function notifyStartIfNeeded(total:Number):void
155                 {
156                         if (!_progress.isStarted) {
157                                 _progress.start(total);
158                         }
159                 }
160                
161                 /**
162                  * ProgressEvent.PROGRESS ハンドラ
163                  *
164                  * @private
165                  */
166                 private function progressHandler(e:ProgressEvent):void
167                 {
168                         // 必要であれば開始を通知
169                         notifyStartIfNeeded(e.bytesTotal);
170                        
171                         // 進捗を通知
172                         _progress.progress(e.bytesLoaded);
173                        
174                         // 割り込みハンドラを設定
175                         interrupted(interruptedHandler);
176                        
177                         // 再びイベント待ち
178                         events();
179                 }
180                
181                 /**
182                  * Event.COMPLETE ハンドラ
183                  *
184                  * @private
185                  */
186                 private function completeHandler(e:Event):void
187                 {
188                         // 必要であれば開始を通知 (問題が発生しなければ通常 progressHandler で通知される)
189                         notifyStartIfNeeded(0);
190                        
191                         // 完了を通知
192                         _progress.complete();
193                        
194                         // ここでスレッド終了
195                 }
196                
197                 /**
198                  * IOErrorEvent.IO_ERROR ハンドラ
199                  *
200                  * @private
201                  */
202                 private function ioErrorHandler(e:IOErrorEvent):void
203                 {
204                         // 必要であれば開始を通知 (問題が発生しなければ通常 progressHandler で通知される)
205                         notifyStartIfNeeded(0);
206                        
207                         // 失敗を通知
208                         _progress.fail();
209                        
210                         // IOError をスロー
211                         throw new IOError(e.text);
212                 }
213                
214                 /**
215                  * SecurityErrorEvent.SECURITY_ERROR ハンドラ
216                  *
217                  * @private
218                  */
219                 private function securityErrorHandler(e:SecurityErrorEvent):void
220                 {
221                         // 必要であれば開始を通知 (問題が発生しなければ通常 progressHandler で通知される)
222                         notifyStartIfNeeded(0);
223                        
224                         // 失敗を通知
225                         _progress.fail();
226                        
227                         // SecurityError をスロー
228                         throw new SecurityError(e.text);
229                 }
230                
231                 /**
232                  * 割り込みハンドラ
233                  *
234                  * @private
235                  */
236                 private function interruptedHandler():void
237                 {
238                         // 必要であれば開始を通知 (問題が発生しなければ通常 progressHandler で通知される)
239                         notifyStartIfNeeded(0);
240                        
241                         // ロードをキャンセル
242                         _loader.close();
243                        
244                         // キャンセルを通知
245                         _progress.cancel();
246                 }
247         }
248 }
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。