OLD | NEW |
1 // Copyright 2012 Google Inc. All Rights Reserved. | 1 // Copyright 2012 Google Inc. All Rights Reserved. |
2 // Dart core library. | 2 // Dart core library. |
3 | 3 |
4 class _FutureImpl<T> implements Future<T> { | 4 class _FutureImpl<T> implements Future<T> { |
5 | 5 |
6 bool _isComplete = false; | 6 bool _isComplete = false; |
7 | 7 |
8 /** | 8 /** |
9 * Value that was provided to this Future by the Completer | 9 * Value that was provided to this Future by the Completer |
10 */ | 10 */ |
11 T _value; | 11 T _value; |
12 | 12 |
13 /** | 13 /** |
14 * Exception that occured, if there was a problem providing | 14 * Exception that occured, if there was a problem providing |
15 * Value. | 15 * Value. |
16 */ | 16 */ |
17 Object _exception; | 17 Object _exception; |
18 | 18 |
19 /** | 19 /** |
20 * Stack trace associated with [_exception], if one was provided. | 20 * Stack trace associated with [_exception], if one was provided. |
21 */ | 21 */ |
22 Object _stackTrace; | 22 Object _stackTrace; |
23 | 23 |
24 /** | 24 /** |
25 * true, if any onException handler handled the exception. | 25 * true, if any onException handler handled the exception. |
26 */ | 26 */ |
27 bool _exceptionHandled = false; | 27 bool _exceptionHandled = false; |
28 | 28 |
29 /** | 29 /** |
30 * true if an exception in this future should be thrown to the top level. | |
31 */ | |
32 bool _throwOnException = false; | |
33 | |
34 /** | |
35 * Listeners waiting to receive the value of this future. | 30 * Listeners waiting to receive the value of this future. |
36 */ | 31 */ |
37 final List<Function> _successListeners; | 32 final List<Function> _successListeners; |
38 | 33 |
39 /** | 34 /** |
40 * Exception handlers waiting for exceptions. | 35 * Exception handlers waiting for exceptions. |
41 */ | 36 */ |
42 final List<Function> _exceptionHandlers; | 37 final List<Function> _exceptionHandlers; |
43 | 38 |
44 /** | 39 /** |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 } | 81 } |
87 | 82 |
88 bool get hasValue { | 83 bool get hasValue { |
89 return isComplete && _exception == null; | 84 return isComplete && _exception == null; |
90 } | 85 } |
91 | 86 |
92 void then(void onSuccess(T value)) { | 87 void then(void onSuccess(T value)) { |
93 if (hasValue) { | 88 if (hasValue) { |
94 onSuccess(value); | 89 onSuccess(value); |
95 } else if (!isComplete) { | 90 } else if (!isComplete) { |
96 _throwOnException = true; | |
97 _successListeners.add(onSuccess); | 91 _successListeners.add(onSuccess); |
98 } else if (!_exceptionHandled) { | 92 } else if (!_exceptionHandled) { |
99 throw new FutureUnhandledException(_exception, stackTrace); | 93 throw new FutureUnhandledException(_exception, stackTrace); |
100 } | 94 } |
101 } | 95 } |
102 | 96 |
103 void _handleSuccess(void onSuccess(T value)) { | |
104 if (hasValue) { | |
105 onSuccess(value); | |
106 } else if (!isComplete) { | |
107 _successListeners.add(onSuccess); | |
108 } | |
109 } | |
110 | |
111 void handleException(bool onException(Object exception)) { | 97 void handleException(bool onException(Object exception)) { |
112 if (_exceptionHandled) return; | 98 if (_exceptionHandled) return; |
113 if (_isComplete) { | 99 if (_isComplete) { |
114 if (_exception != null) { | 100 if (_exception != null) { |
115 _exceptionHandled = onException(_exception); | 101 _exceptionHandled = onException(_exception); |
116 } | 102 } |
117 } else { | 103 } else { |
118 _exceptionHandlers.add(onException); | 104 _exceptionHandlers.add(onException); |
119 } | 105 } |
120 } | 106 } |
(...skipping 21 matching lines...) Expand all Loading... |
142 break; | 128 break; |
143 } | 129 } |
144 } | 130 } |
145 } | 131 } |
146 | 132 |
147 if (hasValue) { | 133 if (hasValue) { |
148 for (Function listener in _successListeners) { | 134 for (Function listener in _successListeners) { |
149 listener(value); | 135 listener(value); |
150 } | 136 } |
151 } else { | 137 } else { |
152 if (!_exceptionHandled && _throwOnException) { | 138 if (!_exceptionHandled && _successListeners.length > 0) { |
153 throw new FutureUnhandledException(_exception, stackTrace); | 139 throw new FutureUnhandledException(_exception, stackTrace); |
154 } | 140 } |
155 } | 141 } |
156 } finally { | 142 } finally { |
157 for (Function listener in _completionListeners) { | 143 for (Function listener in _completionListeners) { |
158 try { | 144 try { |
159 listener(this); | 145 listener(this); |
160 } catch (e) {} | 146 } catch (e) {} |
161 } | 147 } |
162 } | 148 } |
(...skipping 18 matching lines...) Expand all Loading... |
181 _exception = exception; | 167 _exception = exception; |
182 _stackTrace = stackTrace; | 168 _stackTrace = stackTrace; |
183 _complete(); | 169 _complete(); |
184 } | 170 } |
185 | 171 |
186 Future transform(Function transformation) { | 172 Future transform(Function transformation) { |
187 final completer = new Completer(); | 173 final completer = new Completer(); |
188 | 174 |
189 _forwardException(this, completer); | 175 _forwardException(this, completer); |
190 | 176 |
191 _handleSuccess((v) { | 177 then((v) { |
192 var transformed = null; | 178 var transformed = null; |
193 try { | 179 try { |
194 transformed = transformation(v); | 180 transformed = transformation(v); |
195 } catch (e, stackTrace) { | 181 } catch (e, stackTrace) { |
196 completer.completeException(e, stackTrace); | 182 completer.completeException(e, stackTrace); |
197 return; | 183 return; |
198 } | 184 } |
199 completer.complete(transformed); | 185 completer.complete(transformed); |
200 }); | 186 }); |
201 | 187 |
202 return completer.future; | 188 return completer.future; |
203 } | 189 } |
204 | 190 |
205 Future chain(Function transformation) { | 191 Future chain(Function transformation) { |
206 final completer = new Completer(); | 192 final completer = new Completer(); |
207 | 193 |
208 _forwardException(this, completer); | 194 _forwardException(this, completer); |
209 _handleSuccess((v) { | 195 then((v) { |
210 var future = null; | 196 var future = null; |
211 try { | 197 try { |
212 future = transformation(v); | 198 future = transformation(v); |
213 } catch (ex, stackTrace) { | 199 } catch (ex, stackTrace) { |
214 completer.completeException(ex, stackTrace); | 200 completer.completeException(ex, stackTrace); |
215 return; | 201 return; |
216 } | 202 } |
217 | 203 |
218 _forward(future, completer); | 204 _forward(future, completer); |
219 }); | 205 }); |
(...skipping 10 matching lines...) Expand all Loading... |
230 // If the transformation itself returns a future, then we will | 216 // If the transformation itself returns a future, then we will |
231 // complete to what that completes to. | 217 // complete to what that completes to. |
232 if (result is Future) { | 218 if (result is Future) { |
233 _forward(result, completer); | 219 _forward(result, completer); |
234 } else { | 220 } else { |
235 completer.complete(result); | 221 completer.complete(result); |
236 } | 222 } |
237 } catch (innerException, stackTrace) { | 223 } catch (innerException, stackTrace) { |
238 completer.completeException(innerException, stackTrace); | 224 completer.completeException(innerException, stackTrace); |
239 } | 225 } |
240 return false; | 226 return true; |
241 }); | 227 }); |
242 | 228 |
243 _handleSuccess(completer.complete); | 229 then(completer.complete); |
244 | 230 |
245 return completer.future; | 231 return completer.future; |
246 } | 232 } |
247 | 233 |
248 /** | 234 /** |
249 * Forwards the success or error completion from [future] to [completer]. | 235 * Forwards the success or error completion from [future] to [completer]. |
250 */ | 236 */ |
251 _forward(Future future, Completer completer) { | 237 _forward(Future future, Completer completer) { |
252 _forwardException(future, completer); | 238 _forwardException(future, completer); |
253 future._handleSuccess(completer.complete); | 239 future.then(completer.complete); |
254 } | 240 } |
255 | 241 |
256 /** | 242 /** |
257 * Forwards the exception completion from [future] to [completer]. | 243 * Forwards the exception completion from [future] to [completer]. |
258 */ | 244 */ |
259 _forwardException(Future future, Completer completer) { | 245 _forwardException(Future future, Completer completer) { |
260 future.handleException((e) { | 246 future.handleException((e) { |
261 completer.completeException(e, future.stackTrace); | 247 completer.completeException(e, future.stackTrace); |
262 return false; | 248 return true; |
263 }); | 249 }); |
264 } | 250 } |
265 } | 251 } |
266 | 252 |
267 class _CompleterImpl<T> implements Completer<T> { | 253 class _CompleterImpl<T> implements Completer<T> { |
268 | 254 |
269 final _FutureImpl<T> _futureImpl; | 255 final _FutureImpl<T> _futureImpl; |
270 | 256 |
271 _CompleterImpl() : _futureImpl = new _FutureImpl() {} | 257 _CompleterImpl() : _futureImpl = new _FutureImpl() {} |
272 | 258 |
273 Future<T> get future { | 259 Future<T> get future { |
274 return _futureImpl; | 260 return _futureImpl; |
275 } | 261 } |
276 | 262 |
277 void complete(T value) { | 263 void complete(T value) { |
278 _futureImpl._setValue(value); | 264 _futureImpl._setValue(value); |
279 } | 265 } |
280 | 266 |
281 void completeException(Object exception, [Object stackTrace]) { | 267 void completeException(Object exception, [Object stackTrace]) { |
282 _futureImpl._setException(exception, stackTrace); | 268 _futureImpl._setException(exception, stackTrace); |
283 } | 269 } |
284 } | 270 } |
285 | 271 |
OLD | NEW |