Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 |
| 11 /** | 11 /** |
| 12 * A source of asynchronous data events. | 12 * A source of asynchronous data events. |
| 13 * | 13 * |
| 14 * A Stream provides a sequence of events. Each event is either a data event or | 14 * A Stream provides a sequence of events. Each event is either a data event or |
| 15 * an error event, representing the result of a single computation. When the | 15 * an error event, representing the result of a single computation. When the |
| 16 * Stream is exhausted, it may send a single "done" event. | 16 * Stream is exhausted, it may send a single "done" event. |
| 17 * | 17 * |
| 18 * You can [listen] on a stream to receive the events it sends. When you listen, | 18 * You can [listen] on a stream to receive the events it sends. When you listen, |
| 19 * you receive a [StreamSubscription] object that can be used to stop listening, | 19 * you receive a [StreamSubscription] object that can be used to stop listening, |
| 20 * or to temporarily pause events from the stream. | 20 * or to temporarily pause events from the stream. |
| 21 * | 21 * |
| 22 * When an event is fired, all listeners at that time are informed. | 22 * When an event is fired, the listeners at that time are informed. |
| 23 * If a listener is added or removed while an event is being fired, the change | 23 * If a listener is added or removed while an event is being fired, the change |
| 24 * will only take effect after the event is completely fired. | 24 * will only take effect after the event is completely fired. |
| 25 * | 25 * |
| 26 * Streams always respect "pause" requests. If necessary they need to buffer | 26 * Streams always respect "pause" requests. If necessary they need to buffer |
| 27 * their input, but often, and preferably, they can simply request their input | 27 * their input, but often, and preferably, they can simply request their input |
| 28 * to pause too. | 28 * to pause too. |
| 29 * | 29 * |
| 30 * There are two kinds of streams: Single-subscription streams and | 30 * There are two kinds of streams: The normal "single-subscription" streams and |
| 31 * multi-subscription streams. | 31 * "broadcast" streams. |
| 32 * | 32 * |
| 33 * A single-subscription stream allows only a single listener in its entire | 33 * A single-subscription stream allows only a single listener at a time. |
| 34 * life-cycle. It holds back events until it gets a listener, and it exhausts | 34 * It holds back events until it gets a listener, and it may exhaust |
| 35 * itself when the listener is unsubscribed, even if the stream wasn't done. | 35 * itself when the listener is unsubscribed, even if the stream wasn't done. |
| 36 * | 36 * |
| 37 * Single-subscription streams are generally used for streaming parts of | 37 * Single-subscription streams are generally used for streaming parts of |
| 38 * contiguous data like file I/O. | 38 * contiguous data like file I/O. |
| 39 * | 39 * |
| 40 * A multi-subscription stream allows any number of listeners, and it fires | 40 * A broadcast stream allows any number of listeners, and it fires |
| 41 * its events when they are ready, whether there are listeners or not. | 41 * its events when they are ready, whether there are listeners or not. |
| 42 * | 42 * |
| 43 * Multi-subscription streams are used for independent events/observers. | 43 * Braodcast streams are used for independent events/observers. |
| 44 * | 44 * |
| 45 * The default implementation of [isSingleSubscription] and | 45 * The default implementation of [isBroadcast] and |
| 46 * [asMultiSubscriptionStream] are assuming this is a single-subscription stream | 46 * [asBroadcastStream] are assuming this is a single-subscription stream |
| 47 * and a multi-subscription stream inheriting from [Stream] must override these | 47 * and a broadcast stream inheriting from [Stream] must override these |
| 48 * to return [:false:] and [:this:] respectively. | 48 * to return [:true:] and [:this:] respectively. |
| 49 */ | 49 */ |
| 50 abstract class Stream<T> { | 50 abstract class Stream<T> { |
| 51 Stream(); | 51 Stream(); |
| 52 | 52 |
| 53 /** | 53 /** |
| 54 * Creates a new single-subscription stream from the future. | 54 * Creates a new single-subscription stream from the future. |
| 55 * | 55 * |
| 56 * When the future completes, the stream will fire one event, either | 56 * When the future completes, the stream will fire one event, either |
| 57 * data or error, and then close with a done-event. | 57 * data or error, and then close with a done-event. |
| 58 */ | 58 */ |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 71 | 71 |
| 72 /** | 72 /** |
| 73 * Creates a single-subscription stream that gets its data from [data]. | 73 * Creates a single-subscription stream that gets its data from [data]. |
| 74 */ | 74 */ |
| 75 factory Stream.fromIterable(Iterable<T> data) { | 75 factory Stream.fromIterable(Iterable<T> data) { |
| 76 _PendingEvents iterableEvents = new _IterablePendingEvents<T>(data); | 76 _PendingEvents iterableEvents = new _IterablePendingEvents<T>(data); |
| 77 return new _GeneratedSingleStreamImpl<T>(iterableEvents); | 77 return new _GeneratedSingleStreamImpl<T>(iterableEvents); |
| 78 } | 78 } |
| 79 | 79 |
| 80 /** | 80 /** |
| 81 * Whether the stream is a single-subscription stream. | 81 * Whether the stream is a broadcast stream. |
| 82 */ | 82 */ |
| 83 bool get isSingleSubscription => true; | 83 bool get isBroadcast => false; |
|
Bob Nystrom
2013/01/24 17:29:14
Have you considered having an actual distinct type
| |
| 84 | 84 |
| 85 /** | 85 /** |
| 86 * Returns a multi-subscription stream that produces the same events as this. | 86 * Returns a multi-subscription stream that produces the same events as this. |
| 87 * | 87 * |
| 88 * If this stream is single-subscription, return a new stream that allows | 88 * If this stream is single-subscription, return a new stream that allows |
| 89 * multiple subscribers. It will subscribe to this stream when its first | 89 * multiple subscribers. It will subscribe to this stream when its first |
| 90 * subscriber is added, and unsubscribe again when the last subscription is | 90 * subscriber is added, and unsubscribe again when the last subscription is |
| 91 * cancelled. | 91 * cancelled. |
| 92 * | 92 * |
| 93 * If this stream is already multi-subscriber, it is returned unmodified. | 93 * If this stream is already a broadcast stream, it is returned unmodified. |
| 94 */ | 94 */ |
| 95 Stream<T> asMultiSubscriberStream() { | 95 Stream<T> asBroadcastStream() { |
| 96 return new _SingleStreamMultiplexer<T>(this); | 96 return new _SingleStreamMultiplexer<T>(this); |
| 97 } | 97 } |
| 98 | 98 |
| 99 /** | 99 /** |
| 100 * Stream that outputs events from the [sources] in cyclic order. | 100 * Stream that outputs events from the [sources] in cyclic order. |
| 101 * | 101 * |
| 102 * The merged streams are paused and resumed in order to ensure the proper | 102 * The merged streams are paused and resumed in order to ensure the proper |
| 103 * order of output events. | 103 * order of output events. |
| 104 */ | 104 */ |
| 105 factory Stream.cyclic(Iterable<Stream> sources) { | 105 factory Stream.cyclic(Iterable<Stream> sources) { |
| (...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 835 void signalError(AsyncError errorEvent); | 835 void signalError(AsyncError errorEvent); |
| 836 void close(); | 836 void close(); |
| 837 } | 837 } |
| 838 | 838 |
| 839 /** [Stream] wrapper that only exposes the [Stream] interface. */ | 839 /** [Stream] wrapper that only exposes the [Stream] interface. */ |
| 840 class StreamView<T> extends Stream<T> { | 840 class StreamView<T> extends Stream<T> { |
| 841 Stream<T> _stream; | 841 Stream<T> _stream; |
| 842 | 842 |
| 843 StreamView(this._stream); | 843 StreamView(this._stream); |
| 844 | 844 |
| 845 bool get isSingleSubscription => _stream.isSingleSubscription; | 845 bool get isBroadcast => _stream.isBroadcast; |
| 846 | |
| 847 Stream<T> asBroadcastStream() => _stream.asBroadcastStream(); | |
| 846 | 848 |
| 847 StreamSubscription<T> listen(void onData(T value), | 849 StreamSubscription<T> listen(void onData(T value), |
| 848 { void onError(AsyncError error), | 850 { void onError(AsyncError error), |
| 849 void onDone(), | 851 void onDone(), |
| 850 bool unsubscribeOnError }) { | 852 bool unsubscribeOnError }) { |
| 851 return _stream.listen(onData, onError: onError, onDone: onDone, | 853 return _stream.listen(onData, onError: onError, onDone: onDone, |
| 852 unsubscribeOnError: unsubscribeOnError); | 854 unsubscribeOnError: unsubscribeOnError); |
| 853 } | 855 } |
| 854 } | 856 } |
| 855 | 857 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 932 sink.signalError(error); | 934 sink.signalError(error); |
| 933 } | 935 } |
| 934 | 936 |
| 935 /** | 937 /** |
| 936 * Handle an incoming done event. | 938 * Handle an incoming done event. |
| 937 */ | 939 */ |
| 938 void handleDone(StreamSink<T> sink) { | 940 void handleDone(StreamSink<T> sink) { |
| 939 sink.close(); | 941 sink.close(); |
| 940 } | 942 } |
| 941 } | 943 } |
| OLD | NEW |