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 |