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