Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart.async; | 5 part of dart.async; |
| 6 | 6 |
| 7 // ------------------------------------------------------------------- | 7 // ------------------------------------------------------------------- |
| 8 // Core Stream types | 8 // Core Stream types |
| 9 // ------------------------------------------------------------------- | 9 // ------------------------------------------------------------------- |
| 10 | 10 |
| (...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 642 return new _TakeStream(this, count); | 642 return new _TakeStream(this, count); |
| 643 } | 643 } |
| 644 | 644 |
| 645 /** | 645 /** |
| 646 * Forwards data events while [test] is successful. | 646 * Forwards data events while [test] is successful. |
| 647 * | 647 * |
| 648 * The returned stream provides the same events as this stream as long | 648 * The returned stream provides the same events as this stream as long |
| 649 * as [test] returns [:true:] for the event data. The stream is done | 649 * as [test] returns [:true:] for the event data. The stream is done |
| 650 * when either this stream is done, or when this stream first provides | 650 * when either this stream is done, or when this stream first provides |
| 651 * a value that [test] doesn't accept. | 651 * a value that [test] doesn't accept. |
| 652 * | 652 * |
| 653 * Stops listening to the stream after the accepted elements. | 653 * Stops listening to the stream after the accepted elements. |
| 654 * | 654 * |
| 655 * Internally the method cancels its subscription after these elements. This | 655 * Internally the method cancels its subscription after these elements. This |
| 656 * means that single-subscription (non-broadcast) streams are closed and | 656 * means that single-subscription (non-broadcast) streams are closed and |
| 657 * cannot be reused after a call to this method. | 657 * cannot be reused after a call to this method. |
| 658 */ | 658 */ |
| 659 Stream<T> takeWhile(bool test(T element)) { | 659 Stream<T> takeWhile(bool test(T element)) { |
| 660 return new _TakeWhileStream(this, test); | 660 return new _TakeWhileStream(this, test); |
| 661 } | 661 } |
| 662 | 662 |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 953 } | 953 } |
| 954 index -= 1; | 954 index -= 1; |
| 955 }, | 955 }, |
| 956 onError: future._completeError, | 956 onError: future._completeError, |
| 957 onDone: () { | 957 onDone: () { |
| 958 future._completeError(new RangeError.value(index)); | 958 future._completeError(new RangeError.value(index)); |
| 959 }, | 959 }, |
| 960 cancelOnError: true); | 960 cancelOnError: true); |
| 961 return future; | 961 return future; |
| 962 } | 962 } |
| 963 | |
| 964 /** | |
| 965 * Creates a new stream with the same events as this stream. | |
| 966 * | |
| 967 * Whenever more than [timeLimit] passes between two events from this stream, | |
| 968 * the [onTimeout] function is called. | |
| 969 * | |
| 970 * The countdown doesn't start until the returned stream is listened to. | |
| 971 * The countdown is reset every time an event is forwarded from this stream, | |
| 972 * or when the stream is paused and resumed. | |
| 973 * | |
| 974 * The [onTimeout] function is called with one argument: an | |
| 975 * [EventSink] that allows putting events into the returned stream. | |
| 976 * This `EventSink` is only valid during the call to `onTimeout`. | |
| 977 * | |
| 978 * If `onTimeout` is omitted, a timeout will just put a [TimeoutException] | |
| 979 * into the error channel of the returned stream. | |
| 980 */ | |
| 981 Stream timeout(Duration timeLimit, {void onTimeout(EventSink sink)}) { | |
| 982 StreamSubscription<T> subscription; | |
| 983 _StreamController controller; | |
| 984 // The following variables are set on listen. | |
| 985 Timer timer; | |
| 986 Zone zone; | |
| 987 Function timeout; | |
| 988 | |
| 989 void onData(T event) { | |
| 990 timer.cancel(); | |
| 991 controller.add(event); | |
| 992 timer = zone.createTimer(timeLimit, timeout); | |
| 993 } | |
| 994 void onError(error, StackTrace stackTrace) { | |
| 995 timer.cancel(); | |
| 996 controller.addError(error, stackTrace); | |
| 997 timer = zone.createTimer(timeLimit, timeout); | |
| 998 } | |
| 999 void onDone() { | |
| 1000 timer.cancel(); | |
| 1001 controller.close(); | |
| 1002 } | |
| 1003 controller = new _SyncStreamController( | |
| 1004 () { | |
| 1005 zone = Zone.current; | |
|
floitsch
2013/12/05 12:37:38
As discussed:
we should just use the subscription'
Lasse Reichstein Nielsen
2013/12/05 13:28:44
That is what we are doing now.
The zone is being s
floitsch
2013/12/05 14:20:49
yes. didn't see that the code was already changed.
| |
| 1006 if (onTimeout == null) { | |
| 1007 timeout = () { | |
| 1008 controller.addError(new TimeoutException("No stream event", | |
| 1009 timeLimit)); | |
| 1010 }; | |
| 1011 } else { | |
| 1012 onTimeout = zone.registerUnaryCallback(onTimeout); | |
| 1013 _ControllerEventSinkWrapper wrapper = | |
| 1014 new _ControllerEventSinkWrapper(null); | |
| 1015 timeout = () { | |
| 1016 wrapper._sink = controller; // Only valid during call. | |
| 1017 zone.runUnaryGuarded(onTimeout, wrapper); | |
|
floitsch
2013/12/05 14:20:49
It's actually not runUnaryGuarded.
If the onTimeou
Lasse Reichstein Nielsen
2013/12/05 14:57:54
I can see the point.
I actually preferred to have
| |
| 1018 wrapper._sink = null; | |
| 1019 }; | |
| 1020 } | |
| 1021 | |
| 1022 subscription = this.listen(onData, onError: onError, onDone: onDone); | |
| 1023 timer = zone.createTimer(timeLimit, timeout); | |
| 1024 }, | |
| 1025 () { | |
| 1026 timer.cancel(); | |
| 1027 subscription.pause(); | |
| 1028 }, | |
| 1029 () { | |
| 1030 subscription.resume(); | |
| 1031 timer = zone.createTimer(timeLimit, timeout); | |
| 1032 }, | |
| 1033 () { | |
| 1034 timer.cancel(); | |
| 1035 Future result = subscription.cancel(); | |
| 1036 subscription = null; | |
| 1037 return result; | |
| 1038 }); | |
| 1039 return controller.stream; | |
| 1040 } | |
| 963 } | 1041 } |
| 964 | 1042 |
| 965 /** | 1043 /** |
| 966 * A control object for the subscription on a [Stream]. | 1044 * A control object for the subscription on a [Stream]. |
| 967 * | 1045 * |
| 968 * When you subscribe on a [Stream] using [Stream.listen], | 1046 * When you subscribe on a [Stream] using [Stream.listen], |
| 969 * a [StreamSubscription] object is returned. This object | 1047 * a [StreamSubscription] object is returned. This object |
| 970 * is used to later unsubscribe again, or to temporarily pause | 1048 * is used to later unsubscribe again, or to temporarily pause |
| 971 * the stream's events. | 1049 * the stream's events. |
| 972 */ | 1050 */ |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1275 * | 1353 * |
| 1276 * If you need to stop listening for values before the stream iterator is | 1354 * If you need to stop listening for values before the stream iterator is |
| 1277 * automatically closed, you must call [cancel] to ensure that the stream | 1355 * automatically closed, you must call [cancel] to ensure that the stream |
| 1278 * is properly closed. | 1356 * is properly closed. |
| 1279 * | 1357 * |
| 1280 * Returns a future if the cancel-operation is not completed synchronously. | 1358 * Returns a future if the cancel-operation is not completed synchronously. |
| 1281 * Otherwise returns `null`. | 1359 * Otherwise returns `null`. |
| 1282 */ | 1360 */ |
| 1283 Future cancel(); | 1361 Future cancel(); |
| 1284 } | 1362 } |
| 1363 | |
| 1364 | |
| 1365 /** | |
| 1366 * Wraps an [_EventSink] so it exposes only the [EventSink] interface. | |
| 1367 */ | |
| 1368 class _ControllerEventSinkWrapper<T> implements EventSink<T> { | |
| 1369 EventSink _sink; | |
| 1370 _ControllerEventSinkWrapper(this._sink); | |
| 1371 | |
| 1372 void add(T data) { _sink.add(data); } | |
| 1373 void addError(error, [StackTrace stackTrace]) { | |
| 1374 _sink.addError(error, stackTrace); | |
| 1375 } | |
| 1376 void close() { _sink.close(); } | |
| 1377 } | |
| OLD | NEW |