| 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 * Call stack associated with [_exception], if one was provided. |
| 21 */ |
| 22 var _callStack; |
| 23 |
| 24 /** |
| 20 * true, if any onException handler handled the exception. | 25 * true, if any onException handler handled the exception. |
| 21 */ | 26 */ |
| 22 bool _exceptionHandled = false; | 27 bool _exceptionHandled = false; |
| 23 | 28 |
| 24 /** | 29 /** |
| 25 * Listeners waiting to receive the value of this future. | 30 * Listeners waiting to receive the value of this future. |
| 26 */ | 31 */ |
| 27 final List<Function> _successListeners; | 32 final List<Function> _successListeners; |
| 28 | 33 |
| 29 /** | 34 /** |
| (...skipping 27 matching lines...) Expand all Loading... |
| 57 return _value; | 62 return _value; |
| 58 } | 63 } |
| 59 | 64 |
| 60 Object get exception() { | 65 Object get exception() { |
| 61 if (!isComplete) { | 66 if (!isComplete) { |
| 62 throw new FutureNotCompleteException(); | 67 throw new FutureNotCompleteException(); |
| 63 } | 68 } |
| 64 return _exception; | 69 return _exception; |
| 65 } | 70 } |
| 66 | 71 |
| 72 get callStack() { |
| 73 if (!isComplete) { |
| 74 throw new FutureNotCompleteException(); |
| 75 } |
| 76 return _callStack; |
| 77 } |
| 78 |
| 67 bool get isComplete() { | 79 bool get isComplete() { |
| 68 return _isComplete; | 80 return _isComplete; |
| 69 } | 81 } |
| 70 | 82 |
| 71 bool get hasValue() { | 83 bool get hasValue() { |
| 72 return isComplete && _exception === null; | 84 return isComplete && _exception === null; |
| 73 } | 85 } |
| 74 | 86 |
| 75 void then(void onSuccess(T value)) { | 87 void then(void onSuccess(T value)) { |
| 76 if (hasValue) { | 88 if (hasValue) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 } else { | 137 } else { |
| 126 if (!_exceptionHandled && _successListeners.length > 0) { | 138 if (!_exceptionHandled && _successListeners.length > 0) { |
| 127 throw _exception; | 139 throw _exception; |
| 128 } | 140 } |
| 129 } | 141 } |
| 130 } finally { | 142 } finally { |
| 131 for (Function listener in _completionListeners) { | 143 for (Function listener in _completionListeners) { |
| 132 try { | 144 try { |
| 133 listener(this); | 145 listener(this); |
| 134 } catch (final e) {} | 146 } catch (final e) {} |
| 135 } | 147 } |
| 136 } | 148 } |
| 137 } | 149 } |
| 138 | 150 |
| 139 void _setValue(T value) { | 151 void _setValue(T value) { |
| 140 if (_isComplete) { | 152 if (_isComplete) { |
| 141 throw new FutureAlreadyCompleteException(); | 153 throw new FutureAlreadyCompleteException(); |
| 142 } | 154 } |
| 143 _value = value; | 155 _value = value; |
| 144 _complete(); | 156 _complete(); |
| 145 } | 157 } |
| 146 | 158 |
| 147 void _setException(var exception) { | 159 void _setException(Object exception, Object callStack) { |
| 148 if (exception === null) { | 160 if (exception === null) { |
| 149 // null is not a legal value for the exception of a Future | 161 // null is not a legal value for the exception of a Future. |
| 150 throw new IllegalArgumentException(null); | 162 throw new IllegalArgumentException(null); |
| 151 } | 163 } |
| 152 if (_isComplete) { | 164 if (_isComplete) { |
| 153 throw new FutureAlreadyCompleteException(); | 165 throw new FutureAlreadyCompleteException(); |
| 154 } | 166 } |
| 155 _exception = exception; | 167 _exception = exception; |
| 168 _callStack = callStack; |
| 156 _complete(); | 169 _complete(); |
| 157 } | 170 } |
| 158 | 171 |
| 159 Future transform(Function transformation) { | 172 Future transform(Function transformation) { |
| 160 final completer = new Completer(); | 173 final completer = new Completer(); |
| 161 handleException((e) { | 174 handleException((e) { |
| 162 completer.completeException(e); | 175 completer.completeException(e); |
| 163 return true; | 176 return true; |
| 164 }); | 177 }); |
| 165 then((v) { | 178 then((v) { |
| 166 var transformed = null; | 179 var transformed = null; |
| 167 try { | 180 try { |
| 168 transformed = transformation(v); | 181 transformed = transformation(v); |
| 169 } catch (final e) { | 182 } catch (final ex, final callStack) { |
| 170 completer.completeException(e); | 183 completer.completeException(ex, callStack); |
| 171 return; | 184 return; |
| 172 } | 185 } |
| 173 completer.complete(transformed); | 186 completer.complete(transformed); |
| 174 }); | 187 }); |
| 175 return completer.future; | 188 return completer.future; |
| 176 } | 189 } |
| 177 | 190 |
| 178 Future chain(Function transformation) { | 191 Future chain(Function transformation) { |
| 179 final completer = new Completer(); | 192 final completer = new Completer(); |
| 180 handleException((e) { | 193 handleException((e) { |
| 181 completer.completeException(e); | 194 completer.completeException(e); |
| 182 return true; | 195 return true; |
| 183 }); | 196 }); |
| 184 then((v) { | 197 then((v) { |
| 185 var future = null; | 198 var future = null; |
| 186 try { | 199 try { |
| 187 future = transformation(v); | 200 future = transformation(v); |
| 188 } catch (final e) { | 201 } catch (final ex, final callStack) { |
| 189 completer.completeException(e); | 202 completer.completeException(ex, callStack); |
| 190 return; | 203 return; |
| 191 } | 204 } |
| 192 future.handleException((e) { | 205 future.handleException((e) { |
| 193 completer.completeException(e); | 206 completer.completeException(e); |
| 194 return true; | 207 return true; |
| 195 }); | 208 }); |
| 196 future.then((b) => completer.complete(b)); | 209 future.then((b) => completer.complete(b)); |
| 197 }); | 210 }); |
| 198 return completer.future; | 211 return completer.future; |
| 199 } | 212 } |
| 200 } | 213 } |
| 201 | 214 |
| 202 class CompleterImpl<T> implements Completer<T> { | 215 class CompleterImpl<T> implements Completer<T> { |
| 203 | 216 |
| 204 final FutureImpl<T> _futureImpl; | 217 final FutureImpl<T> _futureImpl; |
| 205 | 218 |
| 206 CompleterImpl() : _futureImpl = new FutureImpl() {} | 219 CompleterImpl() : _futureImpl = new FutureImpl() {} |
| 207 | 220 |
| 208 Future<T> get future() { | 221 Future<T> get future() { |
| 209 return _futureImpl; | 222 return _futureImpl; |
| 210 } | 223 } |
| 211 | 224 |
| 212 void complete(T value) { | 225 void complete(T value) { |
| 213 _futureImpl._setValue(value); | 226 _futureImpl._setValue(value); |
| 214 } | 227 } |
| 215 | 228 |
| 216 void completeException(var exception) { | 229 void completeException(Object exception, [Object callStack]) { |
| 217 _futureImpl._setException(exception); | 230 _futureImpl._setException(exception, callStack); |
| 218 } | 231 } |
| 219 } | 232 } |
| OLD | NEW |