| 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 |