Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1137)

Side by Side Diff: sdk/lib/async/stream.dart

Issue 295913003: Make Stream.where, etc., be documented as inheriting broadcast state. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/async/stream_transformers.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/async/stream_transformers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698