| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2011 Google Inc. All Rights Reserved. |
| 2 // Dart core library. |
| 3 |
| 4 /** |
| 5 * Thrown if client tries to obtain value or exception |
| 6 * before a future has completed. |
| 7 */ |
| 8 class FutureNotCompleteException implements Exception { |
| 9 FutureNotCompleteException() {} |
| 10 } |
| 11 |
| 12 /** |
| 13 * Thrown if a completer tries to set the value on |
| 14 * a future that is already complete. |
| 15 */ |
| 16 class FutureAlreadyCompleteException implements Exception { |
| 17 FutureAlreadyCompleteException() {} |
| 18 } |
| 19 |
| 20 |
| 21 class FutureImpl<T> implements Future<T> { |
| 22 |
| 23 bool _isComplete; |
| 24 |
| 25 /** |
| 26 * Value that was provided to this Future by the Completer |
| 27 */ |
| 28 T _value; |
| 29 |
| 30 /** |
| 31 * Exception that occured, if there was a problem providing |
| 32 * Value. |
| 33 */ |
| 34 Object _exception; |
| 35 |
| 36 /** |
| 37 * true, if any onException handler handled the exception. |
| 38 */ |
| 39 bool _exceptionHandled; |
| 40 |
| 41 /** |
| 42 * Listeners waiting to receive the value of this future. |
| 43 */ |
| 44 final Array<Function> _listeners; |
| 45 |
| 46 /** |
| 47 * Exception handlers waiting for exceptions. |
| 48 */ |
| 49 final Array<Function> _exceptionHandlers; |
| 50 |
| 51 FutureImpl() : _listeners = new Array(), _exceptionHandlers = new Array() { |
| 52 _isComplete = false; |
| 53 } |
| 54 |
| 55 T get value() { |
| 56 if (!isComplete) { |
| 57 throw new FutureNotCompleteException(); |
| 58 } |
| 59 if (_exception != null) { |
| 60 throw _exception; |
| 61 } |
| 62 return _value; |
| 63 } |
| 64 |
| 65 Object get exception() { |
| 66 if (!isComplete) { |
| 67 throw new FutureNotCompleteException(); |
| 68 } |
| 69 return _exception; |
| 70 } |
| 71 |
| 72 bool get isComplete() { |
| 73 return _isComplete; |
| 74 } |
| 75 |
| 76 bool get hasValue() { |
| 77 return isComplete && exception == null; |
| 78 } |
| 79 |
| 80 void then(void onComplete(T value)) { |
| 81 if (hasValue) { |
| 82 onComplete(value); |
| 83 } else { |
| 84 _listeners.add(onComplete); |
| 85 } |
| 86 } |
| 87 |
| 88 void handleException(void onException(Object exception)) { |
| 89 _exceptionHandlers.add(onException); |
| 90 } |
| 91 |
| 92 void _complete() { |
| 93 _isComplete = true; |
| 94 if (_exception != null) { |
| 95 for (Function handler in _exceptionHandlers) { |
| 96 if (handler(_exception)) { |
| 97 _exceptionHandled = true; |
| 98 } |
| 99 } |
| 100 } |
| 101 if (hasValue) { |
| 102 for (Function listener in _listeners) { |
| 103 listener(value); |
| 104 } |
| 105 } else { |
| 106 if (!_exceptionHandled && _listeners.length > 0) { |
| 107 throw _exception; |
| 108 } |
| 109 } |
| 110 } |
| 111 |
| 112 void _setValue(T value) { |
| 113 if (_isComplete) { |
| 114 throw new FutureAlreadyCompleteException(); |
| 115 } |
| 116 _value = value; |
| 117 _complete(); |
| 118 } |
| 119 |
| 120 void _setException(var exception) { |
| 121 if (exception == null) { |
| 122 // null is not a legal value for the exception of a Future |
| 123 throw new IllegalArgumentException(null); |
| 124 } |
| 125 if (_isComplete) { |
| 126 throw new FutureAlreadyCompleteException(); |
| 127 } |
| 128 _exception = exception; |
| 129 _complete(); |
| 130 } |
| 131 } |
| 132 |
| 133 class CompleterImpl<T> implements Completer<T> { |
| 134 |
| 135 final FutureImpl<T> _futureImpl; |
| 136 |
| 137 CompleterImpl() : _futureImpl = new FutureImpl() {} |
| 138 |
| 139 Future<T> get future() { |
| 140 return _futureImpl; |
| 141 } |
| 142 |
| 143 void setValue(T value) { |
| 144 _futureImpl._setValue(value); |
| 145 } |
| 146 |
| 147 void setException(var exception) { |
| 148 _futureImpl._setException(exception); |
| 149 } |
| 150 |
| 151 void complete(var valueOrException) { |
| 152 if (valueOrException is Exception) { |
| 153 setException(valueOrException); |
| 154 } else { |
| 155 setValue(valueOrException); |
| 156 } |
| 157 } |
| 158 } |
| OLD | NEW |