Chromium Code Reviews| 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 * true, if any onException handler handled the exception. | 20 * true, if any onException handler handled the exception. |
| 21 */ | 21 */ |
| 22 bool _exceptionHandled = false; | 22 bool _exceptionHandled = false; |
| 23 | 23 |
| 24 /** | 24 /** |
| 25 * Listeners waiting to receive the value of this future. | 25 * Listeners waiting to receive the value of this future. |
| 26 */ | 26 */ |
| 27 final List<Function> _listeners; | 27 final List<Function> _successListeners; |
| 28 | 28 |
| 29 /** | 29 /** |
| 30 * Exception handlers waiting for exceptions. | 30 * Exception handlers waiting for exceptions. |
| 31 */ | 31 */ |
| 32 final List<Function> _exceptionHandlers; | 32 final List<Function> _exceptionHandlers; |
| 33 | 33 |
| 34 /** | |
| 35 * Listeners waiting to be called when the future completes. | |
| 36 */ | |
| 37 final List<Function> _completionListeners; | |
| 38 | |
| 34 FutureImpl() | 39 FutureImpl() |
| 35 : _listeners = [], | 40 : _successListeners = [], |
| 36 _exceptionHandlers = []; | 41 _exceptionHandlers = [], |
| 42 _completionListeners = []; | |
| 37 | 43 |
| 38 factory FutureImpl.immediate(T value) { | 44 factory FutureImpl.immediate(T value) { |
| 39 final res = new FutureImpl(); | 45 final res = new FutureImpl(); |
| 40 res._setValue(value); | 46 res._setValue(value); |
| 41 return res; | 47 return res; |
| 42 } | 48 } |
| 43 | 49 |
| 44 T get value() { | 50 T get value() { |
| 45 if (!isComplete) { | 51 if (!isComplete) { |
| 46 throw new FutureNotCompleteException(); | 52 throw new FutureNotCompleteException(); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 59 } | 65 } |
| 60 | 66 |
| 61 bool get isComplete() { | 67 bool get isComplete() { |
| 62 return _isComplete; | 68 return _isComplete; |
| 63 } | 69 } |
| 64 | 70 |
| 65 bool get hasValue() { | 71 bool get hasValue() { |
| 66 return isComplete && _exception === null; | 72 return isComplete && _exception === null; |
| 67 } | 73 } |
| 68 | 74 |
| 69 void then(void onComplete(T value)) { | 75 void then(void onSuccess(T value)) { |
|
Siggi Cherem (dart-lang)
2012/06/06 20:42:49
onSuccess => onValue (to match what you had in the
| |
| 70 if (hasValue) { | 76 if (hasValue) { |
| 71 onComplete(value); | 77 onSuccess(value); |
| 72 } else if (!isComplete) { | 78 } else if (!isComplete) { |
| 73 _listeners.add(onComplete); | 79 _successListeners.add(onSuccess); |
| 74 } else if (!_exceptionHandled) { | 80 } else if (!_exceptionHandled) { |
| 75 throw _exception; | 81 throw _exception; |
| 76 } | 82 } |
| 77 } | 83 } |
| 78 | 84 |
| 79 void handleException(bool onException(Object exception)) { | 85 void handleException(bool onException(Object exception)) { |
| 80 if (_exceptionHandled) return; | 86 if (_exceptionHandled) return; |
| 81 if (_isComplete) { | 87 if (_isComplete) { |
| 82 if (_exception != null) { | 88 if (_exception != null) { |
| 83 _exceptionHandled = onException(_exception); | 89 _exceptionHandled = onException(_exception); |
| 84 } | 90 } |
| 85 } else { | 91 } else { |
| 86 _exceptionHandlers.add(onException); | 92 _exceptionHandlers.add(onException); |
| 87 } | 93 } |
| 88 } | 94 } |
| 89 | 95 |
| 96 void onComplete(void complete(Future<T> future)) { | |
| 97 if (_isComplete) { | |
| 98 try { | |
| 99 complete(this); | |
| 100 } catch (final e) {} | |
| 101 } else { | |
| 102 _completionListeners.add(complete); | |
| 103 } | |
| 104 } | |
| 105 | |
| 90 void _complete() { | 106 void _complete() { |
| 91 _isComplete = true; | 107 _isComplete = true; |
| 92 if (_exception !== null) { | 108 |
| 93 for (Function handler in _exceptionHandlers) { | 109 try { |
| 94 // Explicitly check for true here so that if the handler returns null, | 110 if (_exception !== null) { |
| 95 // we don't get an exception in checked mode. | 111 for (Function handler in _exceptionHandlers) { |
| 96 if (handler(_exception) == true) { | 112 // Explicitly check for true here so that if the handler returns null, |
| 97 _exceptionHandled = true; | 113 // we don't get an exception in checked mode. |
| 98 break; | 114 if (handler(_exception) == true) { |
| 115 _exceptionHandled = true; | |
| 116 break; | |
| 117 } | |
| 99 } | 118 } |
| 100 } | 119 } |
| 101 } | |
| 102 | 120 |
| 103 if (hasValue) { | 121 if (hasValue) { |
| 104 for (Function listener in _listeners) { | 122 for (Function listener in _successListeners) { |
| 105 listener(value); | 123 listener(value); |
| 124 } | |
| 125 } else { | |
| 126 if (!_exceptionHandled && _successListeners.length > 0) { | |
| 127 throw _exception; | |
| 128 } | |
| 106 } | 129 } |
| 107 } else { | 130 } finally { |
| 108 if (!_exceptionHandled && _listeners.length > 0) { | 131 for (Function listener in _completionListeners) { |
| 109 throw _exception; | 132 try { |
| 110 } | 133 listener(this); |
| 134 } catch (final e) {} | |
| 135 } | |
| 111 } | 136 } |
| 112 } | 137 } |
| 113 | 138 |
| 114 void _setValue(T value) { | 139 void _setValue(T value) { |
| 115 if (_isComplete) { | 140 if (_isComplete) { |
| 116 throw new FutureAlreadyCompleteException(); | 141 throw new FutureAlreadyCompleteException(); |
| 117 } | 142 } |
| 118 _value = value; | 143 _value = value; |
| 119 _complete(); | 144 _complete(); |
| 120 } | 145 } |
| 121 | 146 |
| 122 void _setException(var exception) { | 147 void _setException(var exception) { |
| 123 if (exception === null) { | 148 if (exception === null) { |
| 124 // null is not a legal value for the exception of a Future | 149 // null is not a legal value for the exception of a Future |
| 125 throw new IllegalArgumentException(null); | 150 throw new IllegalArgumentException(null); |
| 126 } | 151 } |
| 127 if (_isComplete) { | 152 if (_isComplete) { |
| 128 throw new FutureAlreadyCompleteException(); | 153 throw new FutureAlreadyCompleteException(); |
| 129 } | 154 } |
| 130 _exception = exception; | 155 _exception = exception; |
| 131 _complete(); | 156 _complete(); |
| 132 } | 157 } |
| 133 | 158 |
| 134 Future transform(Function transformation) { | 159 Future transform(Function transformation) { |
| 135 final completer = new Completer(); | 160 final completer = new Completer(); |
| 136 handleException((e) { | 161 onComplete((f) { |
| 137 completer.completeException(e); | 162 if (!f.hasValue) { |
| 138 return true; | 163 completer.completeException(f.exception); |
| 139 }); | 164 return; |
| 140 then((v) { | 165 } |
| 141 var transformed = null; | 166 var transformed = null; |
| 142 try { | 167 try { |
| 143 transformed = transformation(v); | 168 transformed = transformation(f.value); |
| 144 } catch (final e) { | 169 } catch (final e) { |
| 145 completer.completeException(e); | 170 completer.completeException(e); |
| 146 return; | 171 return; |
| 147 } | 172 } |
| 148 completer.complete(transformed); | 173 completer.complete(transformed); |
| 149 }); | 174 }); |
| 150 return completer.future; | 175 return completer.future; |
| 151 } | 176 } |
| 152 | 177 |
| 153 Future chain(Function transformation) { | 178 Future chain(Function transformation) { |
| 154 final completer = new Completer(); | 179 final completer = new Completer(); |
| 155 handleException((e) { | 180 onComplete((f) { |
| 156 completer.completeException(e); | 181 if (!f.hasValue) { |
| 157 return true; | 182 completer.completeException(f.exception); |
| 158 }); | 183 return; |
| 159 then((v) { | 184 } |
| 160 var future = null; | 185 var future = null; |
| 161 try { | 186 try { |
| 162 future = transformation(v); | 187 future = transformation(f.value); |
| 163 } catch (final e) { | 188 } catch (final e) { |
| 164 completer.completeException(e); | 189 completer.completeException(e); |
| 165 return; | 190 return; |
| 166 } | 191 } |
| 167 future.handleException((e) { | 192 future.onComplete((g) => g.hasValue |
| 168 completer.completeException(e); | 193 ? completer.complete(g.value) |
| 169 return true; | 194 : completer.completeException(g.exception)); |
| 170 }); | |
| 171 future.then((b) => completer.complete(b)); | |
| 172 }); | 195 }); |
| 173 return completer.future; | 196 return completer.future; |
| 174 } | 197 } |
| 175 } | 198 } |
| 176 | 199 |
| 177 class CompleterImpl<T> implements Completer<T> { | 200 class CompleterImpl<T> implements Completer<T> { |
| 178 | 201 |
| 179 final FutureImpl<T> _futureImpl; | 202 final FutureImpl<T> _futureImpl; |
| 180 | 203 |
| 181 CompleterImpl() : _futureImpl = new FutureImpl() {} | 204 CompleterImpl() : _futureImpl = new FutureImpl() {} |
| 182 | 205 |
| 183 Future<T> get future() { | 206 Future<T> get future() { |
| 184 return _futureImpl; | 207 return _futureImpl; |
| 185 } | 208 } |
| 186 | 209 |
| 187 void complete(T value) { | 210 void complete(T value) { |
| 188 _futureImpl._setValue(value); | 211 _futureImpl._setValue(value); |
| 189 } | 212 } |
| 190 | 213 |
| 191 void completeException(var exception) { | 214 void completeException(var exception) { |
| 192 _futureImpl._setException(exception); | 215 _futureImpl._setException(exception); |
| 193 } | 216 } |
| 194 } | 217 } |
| OLD | NEW |