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 |