| 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 // This is the onListen callback for of controller. |
| 1006 // It runs in the same zone that the subscription was created in. |
| 1007 // Use that zone for creating timers and running the onTimeout |
| 1008 // callback. |
| 1009 zone = Zone.current; |
| 1010 if (onTimeout == null) { |
| 1011 timeout = () { |
| 1012 controller.addError(new TimeoutException("No stream event", |
| 1013 timeLimit)); |
| 1014 }; |
| 1015 } else { |
| 1016 onTimeout = zone.registerUnaryCallback(onTimeout); |
| 1017 _ControllerEventSinkWrapper wrapper = |
| 1018 new _ControllerEventSinkWrapper(null); |
| 1019 timeout = () { |
| 1020 wrapper._sink = controller; // Only valid during call. |
| 1021 zone.runUnaryGuarded(onTimeout, wrapper); |
| 1022 wrapper._sink = null; |
| 1023 }; |
| 1024 } |
| 1025 |
| 1026 subscription = this.listen(onData, onError: onError, onDone: onDone); |
| 1027 timer = zone.createTimer(timeLimit, timeout); |
| 1028 }, |
| 1029 () { |
| 1030 timer.cancel(); |
| 1031 subscription.pause(); |
| 1032 }, |
| 1033 () { |
| 1034 subscription.resume(); |
| 1035 timer = zone.createTimer(timeLimit, timeout); |
| 1036 }, |
| 1037 () { |
| 1038 timer.cancel(); |
| 1039 Future result = subscription.cancel(); |
| 1040 subscription = null; |
| 1041 return result; |
| 1042 }); |
| 1043 return controller.stream; |
| 1044 } |
| 963 } | 1045 } |
| 964 | 1046 |
| 965 /** | 1047 /** |
| 966 * A control object for the subscription on a [Stream]. | 1048 * A control object for the subscription on a [Stream]. |
| 967 * | 1049 * |
| 968 * When you subscribe on a [Stream] using [Stream.listen], | 1050 * When you subscribe on a [Stream] using [Stream.listen], |
| 969 * a [StreamSubscription] object is returned. This object | 1051 * a [StreamSubscription] object is returned. This object |
| 970 * is used to later unsubscribe again, or to temporarily pause | 1052 * is used to later unsubscribe again, or to temporarily pause |
| 971 * the stream's events. | 1053 * the stream's events. |
| 972 */ | 1054 */ |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1275 * | 1357 * |
| 1276 * If you need to stop listening for values before the stream iterator is | 1358 * 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 | 1359 * automatically closed, you must call [cancel] to ensure that the stream |
| 1278 * is properly closed. | 1360 * is properly closed. |
| 1279 * | 1361 * |
| 1280 * Returns a future if the cancel-operation is not completed synchronously. | 1362 * Returns a future if the cancel-operation is not completed synchronously. |
| 1281 * Otherwise returns `null`. | 1363 * Otherwise returns `null`. |
| 1282 */ | 1364 */ |
| 1283 Future cancel(); | 1365 Future cancel(); |
| 1284 } | 1366 } |
| 1367 |
| 1368 |
| 1369 /** |
| 1370 * Wraps an [_EventSink] so it exposes only the [EventSink] interface. |
| 1371 */ |
| 1372 class _ControllerEventSinkWrapper<T> implements EventSink<T> { |
| 1373 EventSink _sink; |
| 1374 _ControllerEventSinkWrapper(this._sink); |
| 1375 |
| 1376 void add(T data) { _sink.add(data); } |
| 1377 void addError(error, [StackTrace stackTrace]) { |
| 1378 _sink.addError(error, stackTrace); |
| 1379 } |
| 1380 void close() { _sink.close(); } |
| 1381 } |
| OLD | NEW |