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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 * itself when the listener is unsubscribed, even if the stream wasn't done. | 42 * itself when the listener is unsubscribed, even if the stream wasn't done. |
| 43 * | 43 * |
| 44 * Single-subscription streams are generally used for streaming parts of | 44 * Single-subscription streams are generally used for streaming parts of |
| 45 * contiguous data like file I/O. | 45 * contiguous data like file I/O. |
| 46 * | 46 * |
| 47 * A broadcast stream allows any number of listeners, and it fires | 47 * A broadcast stream allows any number of listeners, and it fires |
| 48 * its events when they are ready, whether there are listeners or not. | 48 * its events when they are ready, whether there are listeners or not. |
| 49 * | 49 * |
| 50 * Broadcast streams are used for independent events/observers. | 50 * Broadcast streams are used for independent events/observers. |
| 51 * | 51 * |
| 52 * Stream transformations, such as [where] and [skip], always return | 52 * Stream transformations, such as [where] and [skip], |
| 53 * non-broadcast streams. If several listeners want to listen to the returned | 53 * return the same type of stream as the one the method was called on, |
| 54 * unless otherwise noted. | |
| 55 * | |
| 56 * If several listeners want to listen to the returned | |
| 54 * stream, use [asBroadcastStream] to create a broadcast stream on top of the | 57 * stream, use [asBroadcastStream] to create a broadcast stream on top of the |
| 55 * non-broadcast stream. | 58 * non-broadcast stream. |
| 56 * | 59 * |
| 57 * The default implementation of [isBroadcast] returns false. | 60 * The default implementation of [isBroadcast] returns false. |
| 58 * A broadcast stream inheriting from [Stream] must override [isBroadcast] | 61 * A broadcast stream inheriting from [Stream] must override [isBroadcast] |
| 59 * to return [:true:]. | 62 * to return [:true:]. |
| 60 */ | 63 */ |
| 61 abstract class Stream<T> { | 64 abstract class Stream<T> { |
| 62 Stream(); | 65 Stream(); |
| 63 | 66 |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 255 { Function onError, | 258 { Function onError, |
| 256 void onDone(), | 259 void onDone(), |
| 257 bool cancelOnError}); | 260 bool cancelOnError}); |
| 258 | 261 |
| 259 /** | 262 /** |
| 260 * Creates a new stream from this stream that discards some data events. | 263 * Creates a new stream from this stream that discards some data events. |
| 261 * | 264 * |
| 262 * The new stream sends the same error and done events as this stream, | 265 * The new stream sends the same error and done events as this stream, |
| 263 * but it only sends the data events that satisfy the [test]. | 266 * but it only sends the data events that satisfy the [test]. |
| 264 * | 267 * |
| 265 * The returned stream is not a broadcast stream, even if this stream is. | 268 * The returned stream is a broadcast stream if this stream is. |
| 266 */ | 269 */ |
| 267 Stream<T> where(bool test(T event)) { | 270 Stream<T> where(bool test(T event)) { |
| 268 return new _WhereStream<T>(this, test); | 271 return new _WhereStream<T>(this, test); |
| 269 } | 272 } |
| 270 | 273 |
| 271 /** | 274 /** |
| 272 * Creates a new stream that converts each element of this stream | 275 * Creates a new stream that converts each element of this stream |
| 273 * to a new value using the [convert] function. | 276 * to a new value using the [convert] function. |
| 274 * | 277 * |
| 275 * The returned stream is not a broadcast stream, even if this stream is. | 278 * The returned stream is a broadcast stream if this stream is. |
| 276 */ | 279 */ |
| 277 Stream map(convert(T event)) { | 280 Stream map(convert(T event)) { |
| 278 return new _MapStream<T, dynamic>(this, convert); | 281 return new _MapStream<T, dynamic>(this, convert); |
| 279 } | 282 } |
| 280 | 283 |
| 281 /** | 284 /** |
| 282 * Creates a new stream with each data event of this stream asynchronously | 285 * Creates a new stream with each data event of this stream asynchronously |
| 283 * mapped to a new event. | 286 * mapped to a new event. |
| 284 * | 287 * |
| 285 * This acts like [map], except that [convert] may return a [Future], | 288 * This acts like [map], except that [convert] may return a [Future], |
| 286 * and in that case, the stream waits for that future to complete before | 289 * and in that case, the stream waits for that future to complete before |
| 287 * continuing with its result. | 290 * continuing with its result. |
| 291 * | |
| 292 * The returned stream is not a broadcast stream. | |
| 288 */ | 293 */ |
| 289 Stream asyncMap(convert(T event)) { | 294 Stream asyncMap(convert(T event)) { |
| 290 StreamController controller; | 295 StreamController controller; |
| 291 StreamSubscription subscription; | 296 StreamSubscription subscription; |
| 292 controller = new StreamController( | 297 controller = new StreamController( |
| 293 onListen: () { | 298 onListen: () { |
| 294 var add = controller.add; | 299 var add = controller.add; |
| 295 var addError = controller.addError; | 300 var addError = controller.addError; |
| 296 subscription = this.listen( | 301 subscription = this.listen( |
| 297 (T event) { | 302 (T event) { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 325 /** | 330 /** |
| 326 * Creates a new stream with the events of a stream per original event. | 331 * Creates a new stream with the events of a stream per original event. |
| 327 * | 332 * |
| 328 * This acts like [expand], except that [convert] returns a [Stream] | 333 * This acts like [expand], except that [convert] returns a [Stream] |
| 329 * instead of an [Iterable]. | 334 * instead of an [Iterable]. |
| 330 * The events of the returned stream becomes the events of the returned | 335 * The events of the returned stream becomes the events of the returned |
| 331 * stream, in the order they are produced. | 336 * stream, in the order they are produced. |
| 332 * | 337 * |
| 333 * If [convert] returns `null`, no value is put on the output stream, | 338 * If [convert] returns `null`, no value is put on the output stream, |
| 334 * just as if it returned an empty stream. | 339 * just as if it returned an empty stream. |
| 340 * | |
| 341 * The returned stream is a not a broadcast stream. | |
| 335 */ | 342 */ |
| 336 Stream asyncExpand(Stream convert(T event)) { | 343 Stream asyncExpand(Stream convert(T event)) { |
| 337 StreamController controller; | 344 StreamController controller; |
| 338 StreamSubscription subscription; | 345 StreamSubscription subscription; |
| 339 controller = new StreamController( | 346 controller = new StreamController( |
| 340 onListen: () { | 347 onListen: () { |
| 341 subscription = this.listen( | 348 subscription = this.listen( |
| 342 (T event) { | 349 (T event) { |
| 343 Stream newStream; | 350 Stream newStream; |
| 344 try { | 351 try { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 381 * returns true. If [test] is omitted, every error is considered matching. | 388 * returns true. If [test] is omitted, every error is considered matching. |
| 382 * | 389 * |
| 383 * If the error is intercepted, the [handle] function can decide what to do | 390 * If the error is intercepted, the [handle] function can decide what to do |
| 384 * with it. It can throw if it wants to raise a new (or the same) error, | 391 * with it. It can throw if it wants to raise a new (or the same) error, |
| 385 * or simply return to make the stream forget the error. | 392 * or simply return to make the stream forget the error. |
| 386 * | 393 * |
| 387 * If you need to transform an error into a data event, use the more generic | 394 * If you need to transform an error into a data event, use the more generic |
| 388 * [Stream.transform] to handle the event by writing a data event to | 395 * [Stream.transform] to handle the event by writing a data event to |
| 389 * the output sink | 396 * the output sink |
| 390 * | 397 * |
| 391 * The returned stream is not a broadcast stream, even if this stream is. | 398 * The returned stream is a broadcast stream if this stream is. |
| 392 */ | 399 */ |
| 393 Stream<T> handleError(Function onError, { bool test(error) }) { | 400 Stream<T> handleError(Function onError, { bool test(error) }) { |
| 394 return new _HandleErrorStream<T>(this, onError, test); | 401 return new _HandleErrorStream<T>(this, onError, test); |
| 395 } | 402 } |
| 396 | 403 |
| 397 /** | 404 /** |
| 398 * Creates a new stream from this stream that converts each element | 405 * Creates a new stream from this stream that converts each element |
| 399 * into zero or more events. | 406 * into zero or more events. |
| 400 * | 407 * |
| 401 * Each incoming event is converted to an [Iterable] of new events, | 408 * Each incoming event is converted to an [Iterable] of new events, |
| 402 * and each of these new events are then sent by the returned stream | 409 * and each of these new events are then sent by the returned stream |
| 403 * in order. | 410 * in order. |
| 404 * | 411 * |
| 405 * The returned stream is not a broadcast stream, even if this stream is. | 412 * The returned stream is a broadcast stream if this stream is. |
| 406 */ | 413 */ |
| 407 Stream expand(Iterable convert(T value)) { | 414 Stream expand(Iterable convert(T value)) { |
| 408 return new _ExpandStream<T, dynamic>(this, convert); | 415 return new _ExpandStream<T, dynamic>(this, convert); |
| 409 } | 416 } |
| 410 | 417 |
| 411 /** | 418 /** |
| 412 * Binds this stream as the input of the provided [StreamConsumer]. | 419 * Binds this stream as the input of the provided [StreamConsumer]. |
| 413 */ | 420 */ |
| 414 Future pipe(StreamConsumer<T> streamConsumer) { | 421 Future pipe(StreamConsumer<T> streamConsumer) { |
| 415 return streamConsumer.addStream(this).then((_) => streamConsumer.close()); | 422 return streamConsumer.addStream(this).then((_) => streamConsumer.close()); |
| 416 } | 423 } |
| 417 | 424 |
| 418 /** | 425 /** |
| 419 * Chains this stream as the input of the provided [StreamTransformer]. | 426 * Chains this stream as the input of the provided [StreamTransformer]. |
| 420 * | 427 * |
| 421 * Returns the result of [:streamTransformer.bind:] itself. | 428 * Returns the result of [:streamTransformer.bind:] itself. |
| 429 * | |
| 430 * The `streamTransformer` can decide whether it wants to return a | |
| 431 * broadcast stream or not. | |
| 422 */ | 432 */ |
| 423 Stream transform(StreamTransformer<T, dynamic> streamTransformer) { | 433 Stream transform(StreamTransformer<T, dynamic> streamTransformer) { |
| 424 return streamTransformer.bind(this); | 434 return streamTransformer.bind(this); |
| 425 } | 435 } |
| 426 | 436 |
| 427 /** | 437 /** |
| 428 * Reduces a sequence of values by repeatedly applying [combine]. | 438 * Reduces a sequence of values by repeatedly applying [combine]. |
| 429 */ | 439 */ |
| 430 Future<T> reduce(T combine(T previous, T element)) { | 440 Future<T> reduce(T combine(T previous, T element)) { |
| 431 _Future<T> result = new _Future<T>(); | 441 _Future<T> result = new _Future<T>(); |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 731 * If this stream produces fewer than [count] values before it's done, | 741 * If this stream produces fewer than [count] values before it's done, |
| 732 * so will the returned stream. | 742 * so will the returned stream. |
| 733 * | 743 * |
| 734 * Stops listening to the stream after the first [n] elements have been | 744 * Stops listening to the stream after the first [n] elements have been |
| 735 * received. | 745 * received. |
| 736 * | 746 * |
| 737 * Internally the method cancels its subscription after these elements. This | 747 * Internally the method cancels its subscription after these elements. This |
| 738 * means that single-subscription (non-broadcast) streams are closed and | 748 * means that single-subscription (non-broadcast) streams are closed and |
| 739 * cannot be reused after a call to this method. | 749 * cannot be reused after a call to this method. |
| 740 * | 750 * |
| 741 * The returned stream is not a broadcast stream, even if this stream is. | 751 * The returned stream is a broadcast stream if this stream is. |
| 742 */ | 752 */ |
| 743 Stream<T> take(int count) { | 753 Stream<T> take(int count) { |
| 744 return new _TakeStream(this, count); | 754 return new _TakeStream(this, count); |
| 745 } | 755 } |
| 746 | 756 |
| 747 /** | 757 /** |
| 748 * Forwards data events while [test] is successful. | 758 * Forwards data events while [test] is successful. |
| 749 * | 759 * |
| 750 * The returned stream provides the same events as this stream as long | 760 * The returned stream provides the same events as this stream as long |
| 751 * as [test] returns [:true:] for the event data. The stream is done | 761 * as [test] returns [:true:] for the event data. The stream is done |
| 752 * when either this stream is done, or when this stream first provides | 762 * when either this stream is done, or when this stream first provides |
| 753 * a value that [test] doesn't accept. | 763 * a value that [test] doesn't accept. |
| 754 * | 764 * |
| 755 * Stops listening to the stream after the accepted elements. | 765 * Stops listening to the stream after the accepted elements. |
| 756 * | 766 * |
| 757 * Internally the method cancels its subscription after these elements. This | 767 * Internally the method cancels its subscription after these elements. This |
| 758 * means that single-subscription (non-broadcast) streams are closed and | 768 * means that single-subscription (non-broadcast) streams are closed and |
| 759 * cannot be reused after a call to this method. | 769 * cannot be reused after a call to this method. |
| 760 * | 770 * |
| 761 * The returned stream is not a broadcast stream, even if this stream is. | 771 * The returned stream is a broadcast stream if this stream is. |
| 762 */ | 772 */ |
| 763 Stream<T> takeWhile(bool test(T element)) { | 773 Stream<T> takeWhile(bool test(T element)) { |
| 764 return new _TakeWhileStream(this, test); | 774 return new _TakeWhileStream(this, test); |
| 765 } | 775 } |
| 766 | 776 |
| 767 /** | 777 /** |
| 768 * Skips the first [count] data events from this stream. | 778 * Skips the first [count] data events from this stream. |
| 769 * | 779 * |
| 770 * The returned stream is not a broadcast stream, even if this stream is. | 780 * The returned stream is a broadcast stream if this stream is. |
| 771 */ | 781 */ |
| 772 Stream<T> skip(int count) { | 782 Stream<T> skip(int count) { |
| 773 return new _SkipStream(this, count); | 783 return new _SkipStream(this, count); |
| 774 } | 784 } |
| 775 | 785 |
| 776 /** | 786 /** |
| 777 * Skip data events from this stream while they are matched by [test]. | 787 * Skip data events from this stream while they are matched by [test]. |
| 778 * | 788 * |
| 779 * Error and done events are provided by the returned stream unmodified. | 789 * Error and done events are provided by the returned stream unmodified. |
| 780 * | 790 * |
| 781 * Starting with the first data event where [test] returns false for the | 791 * Starting with the first data event where [test] returns false for the |
| 782 * event data, the returned stream will have the same events as this stream. | 792 * event data, the returned stream will have the same events as this stream. |
| 783 * | 793 * |
| 784 * The returned stream is not a broadcast stream, even if this stream is. | 794 * The returned stream is a broadcast stream if this stream is. |
| 785 */ | 795 */ |
| 786 Stream<T> skipWhile(bool test(T element)) { | 796 Stream<T> skipWhile(bool test(T element)) { |
| 787 return new _SkipWhileStream(this, test); | 797 return new _SkipWhileStream(this, test); |
| 788 } | 798 } |
| 789 | 799 |
| 790 /** | 800 /** |
| 791 * Skips data events if they are equal to the previous data event. | 801 * Skips data events if they are equal to the previous data event. |
| 792 * | 802 * |
| 793 * The returned stream provides the same events as this stream, except | 803 * The returned stream provides the same events as this stream, except |
| 794 * that it never provides two consequtive data events that are equal. | 804 * that it never provides two consequtive data events that are equal. |
| 795 * | 805 * |
| 796 * Equality is determined by the provided [equals] method. If that is | 806 * Equality is determined by the provided [equals] method. If that is |
| 797 * omitted, the '==' operator on the last provided data element is used. | 807 * omitted, the '==' operator on the last provided data element is used. |
| 798 * | 808 * |
| 799 * The returned stream is not a broadcast stream, even if this stream is. | 809 * The returned stream is a broadcast stream if this stream is. |
| 800 */ | 810 */ |
| 801 Stream<T> distinct([bool equals(T previous, T next)]) { | 811 Stream<T> distinct([bool equals(T previous, T next)]) { |
| 802 return new _DistinctStream(this, equals); | 812 return new _DistinctStream(this, equals); |
| 803 } | 813 } |
| 804 | 814 |
| 805 /** | 815 /** |
| 806 * Returns the first element of the stream. | 816 * Returns the first element of the stream. |
| 807 * | 817 * |
| 808 * Stops listening to the stream after the first element has been received. | 818 * Stops listening to the stream after the first element has been received. |
| 809 * | 819 * |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1081 * The countdown is reset every time an event is forwarded from this stream, | 1091 * The countdown is reset every time an event is forwarded from this stream, |
| 1082 * or when the stream is paused and resumed. | 1092 * or when the stream is paused and resumed. |
| 1083 * | 1093 * |
| 1084 * The [onTimeout] function is called with one argument: an | 1094 * The [onTimeout] function is called with one argument: an |
| 1085 * [EventSink] that allows putting events into the returned stream. | 1095 * [EventSink] that allows putting events into the returned stream. |
| 1086 * This `EventSink` is only valid during the call to `onTimeout`. | 1096 * This `EventSink` is only valid during the call to `onTimeout`. |
| 1087 * | 1097 * |
| 1088 * If `onTimeout` is omitted, a timeout will just put a [TimeoutException] | 1098 * If `onTimeout` is omitted, a timeout will just put a [TimeoutException] |
| 1089 * into the error channel of the returned stream. | 1099 * into the error channel of the returned stream. |
| 1090 * | 1100 * |
| 1091 * The returned stream is not a broadcast stream, even if this stream is. | 1101 * The returned stream is a broadcast stream if this stream is. |
| 1092 */ | 1102 */ |
| 1093 Stream timeout(Duration timeLimit, {void onTimeout(EventSink sink)}) { | 1103 Stream timeout(Duration timeLimit, {void onTimeout(EventSink sink)}) { |
| 1094 StreamSubscription<T> subscription; | 1104 StreamSubscription<T> subscription; |
| 1095 _StreamController controller; | 1105 _StreamController controller; |
| 1096 // The following variables are set on listen. | 1106 // The following variables are set on listen. |
| 1097 Timer timer; | 1107 Timer timer; |
| 1098 Zone zone; | 1108 Zone zone; |
| 1099 Function timeout; | 1109 Function timeout; |
| 1100 | 1110 |
| 1101 void onData(T event) { | 1111 void onData(T event) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1145 () { | 1155 () { |
| 1146 subscription.resume(); | 1156 subscription.resume(); |
| 1147 timer = zone.createTimer(timeLimit, timeout); | 1157 timer = zone.createTimer(timeLimit, timeout); |
| 1148 }, | 1158 }, |
| 1149 () { | 1159 () { |
| 1150 timer.cancel(); | 1160 timer.cancel(); |
| 1151 Future result = subscription.cancel(); | 1161 Future result = subscription.cancel(); |
| 1152 subscription = null; | 1162 subscription = null; |
| 1153 return result; | 1163 return result; |
| 1154 }); | 1164 }); |
| 1155 return controller.stream; | 1165 Stream result = controller.stream; |
| 1166 if (isBroadcast) { | |
| 1167 result = result.asBroadcastStream(); | |
|
Anders Johnsen
2014/05/20 07:11:23
Isn't this problematic? Would it be better to use
Lasse Reichstein Nielsen
2014/05/20 07:20:30
Done.
| |
| 1168 } | |
| 1169 return result; | |
| 1156 } | 1170 } |
| 1157 } | 1171 } |
| 1158 | 1172 |
| 1159 /** | 1173 /** |
| 1160 * A control object for the subscription on a [Stream]. | 1174 * A control object for the subscription on a [Stream]. |
| 1161 * | 1175 * |
| 1162 * When you subscribe on a [Stream] using [Stream.listen], | 1176 * When you subscribe on a [Stream] using [Stream.listen], |
| 1163 * a [StreamSubscription] object is returned. This object | 1177 * a [StreamSubscription] object is returned. This object |
| 1164 * is used to later unsubscribe again, or to temporarily pause | 1178 * is used to later unsubscribe again, or to temporarily pause |
| 1165 * the stream's events. | 1179 * the stream's events. |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1489 class _ControllerEventSinkWrapper<T> implements EventSink<T> { | 1503 class _ControllerEventSinkWrapper<T> implements EventSink<T> { |
| 1490 EventSink _sink; | 1504 EventSink _sink; |
| 1491 _ControllerEventSinkWrapper(this._sink); | 1505 _ControllerEventSinkWrapper(this._sink); |
| 1492 | 1506 |
| 1493 void add(T data) { _sink.add(data); } | 1507 void add(T data) { _sink.add(data); } |
| 1494 void addError(error, [StackTrace stackTrace]) { | 1508 void addError(error, [StackTrace stackTrace]) { |
| 1495 _sink.addError(error, stackTrace); | 1509 _sink.addError(error, stackTrace); |
| 1496 } | 1510 } |
| 1497 void close() { _sink.close(); } | 1511 void close() { _sink.close(); } |
| 1498 } | 1512 } |
| OLD | NEW |