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

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

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