| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 import "dart:async"; | 5 import "dart:async"; |
| 6 | 6 |
| 7 /// A single-subscription [stream] where the contents are provided later. | 7 /// A single-subscription [stream] where the contents are provided later. |
| 8 /// | 8 /// |
| 9 /// It is generally recommended that you never create a `Future<Stream>` | 9 /// It is generally recommended that you never create a `Future<Stream>` |
| 10 /// because you can just directly create a stream that doesn't do anything | 10 /// because you can just directly create a stream that doesn't do anything |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 final _stream = new _CompleterStream<T>(); | 27 final _stream = new _CompleterStream<T>(); |
| 28 | 28 |
| 29 /// Convert a `Future<Stream>` to a `Stream`. | 29 /// Convert a `Future<Stream>` to a `Stream`. |
| 30 /// | 30 /// |
| 31 /// This creates a stream using a stream completer, | 31 /// This creates a stream using a stream completer, |
| 32 /// and sets the source stream to the result of the future when the | 32 /// and sets the source stream to the result of the future when the |
| 33 /// future completes. | 33 /// future completes. |
| 34 /// | 34 /// |
| 35 /// If the future completes with an error, the returned stream will | 35 /// If the future completes with an error, the returned stream will |
| 36 /// instead contain just that error. | 36 /// instead contain just that error. |
| 37 static Stream/*<T>*/ fromFuture/*<T>*/(Future<Stream/*<T>*/> streamFuture) { | 37 static Stream<T> fromFuture<T>(Future<Stream<T>> streamFuture) { |
| 38 var completer = new StreamCompleter/*<T>*/(); | 38 var completer = new StreamCompleter<T>(); |
| 39 streamFuture.then(completer.setSourceStream, | 39 streamFuture.then(completer.setSourceStream, onError: completer.setError); |
| 40 onError: completer.setError); | |
| 41 return completer.stream; | 40 return completer.stream; |
| 42 } | 41 } |
| 43 | 42 |
| 44 /// The stream of this completer. | 43 /// The stream of this completer. |
| 45 /// | 44 /// |
| 46 /// This stream is always a single-subscription stream. | 45 /// This stream is always a single-subscription stream. |
| 47 /// | 46 /// |
| 48 /// When a source stream is provided, its events will be forwarded to | 47 /// When a source stream is provided, its events will be forwarded to |
| 49 /// listeners on this stream. | 48 /// listeners on this stream. |
| 50 /// | 49 /// |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 /// is set, or if using [_setEmpty] so there is no source stream. | 110 /// is set, or if using [_setEmpty] so there is no source stream. |
| 112 StreamController<T> _controller; | 111 StreamController<T> _controller; |
| 113 | 112 |
| 114 /// Source stream for the events provided by this stream. | 113 /// Source stream for the events provided by this stream. |
| 115 /// | 114 /// |
| 116 /// Set when the completer sets the source stream using [_setSourceStream] | 115 /// Set when the completer sets the source stream using [_setSourceStream] |
| 117 /// or [_setEmpty]. | 116 /// or [_setEmpty]. |
| 118 Stream<T> _sourceStream; | 117 Stream<T> _sourceStream; |
| 119 | 118 |
| 120 StreamSubscription<T> listen(onData(T data), | 119 StreamSubscription<T> listen(onData(T data), |
| 121 {Function onError, | 120 {Function onError, void onDone(), bool cancelOnError}) { |
| 122 void onDone(), | |
| 123 bool cancelOnError}) { | |
| 124 if (_controller == null) { | 121 if (_controller == null) { |
| 125 if (_sourceStream != null && !_sourceStream.isBroadcast) { | 122 if (_sourceStream != null && !_sourceStream.isBroadcast) { |
| 126 // If the source stream is itself single subscription, | 123 // If the source stream is itself single subscription, |
| 127 // just listen to it directly instead of creating a controller. | 124 // just listen to it directly instead of creating a controller. |
| 128 return _sourceStream.listen(onData, onError: onError, onDone: onDone, | 125 return _sourceStream.listen(onData, |
| 129 cancelOnError: cancelOnError); | 126 onError: onError, onDone: onDone, cancelOnError: cancelOnError); |
| 130 } | 127 } |
| 131 _createController(); | 128 _createController(); |
| 132 if (_sourceStream != null) { | 129 if (_sourceStream != null) { |
| 133 _linkStreamToController(); | 130 _linkStreamToController(); |
| 134 } | 131 } |
| 135 } | 132 } |
| 136 return _controller.stream.listen(onData, onError: onError, onDone: onDone, | 133 return _controller.stream.listen(onData, |
| 137 cancelOnError: cancelOnError); | 134 onError: onError, onDone: onDone, cancelOnError: cancelOnError); |
| 138 } | 135 } |
| 139 | 136 |
| 140 /// Whether a source stream has been set. | 137 /// Whether a source stream has been set. |
| 141 /// | 138 /// |
| 142 /// Used to throw an error if trying to set a source stream twice. | 139 /// Used to throw an error if trying to set a source stream twice. |
| 143 bool get _isSourceStreamSet => _sourceStream != null; | 140 bool get _isSourceStreamSet => _sourceStream != null; |
| 144 | 141 |
| 145 /// Sets the source stream providing the events for this stream. | 142 /// Sets the source stream providing the events for this stream. |
| 146 /// | 143 /// |
| 147 /// If set before the user listens, listen calls will be directed directly | 144 /// If set before the user listens, listen calls will be directed directly |
| 148 /// to the source stream. If the user listenes earlier, and intermediate | 145 /// to the source stream. If the user listenes earlier, and intermediate |
| 149 /// stream is created using a stream controller, and the source stream is | 146 /// stream is created using a stream controller, and the source stream is |
| 150 /// linked into that stream later. | 147 /// linked into that stream later. |
| 151 void _setSourceStream(Stream<T> sourceStream) { | 148 void _setSourceStream(Stream<T> sourceStream) { |
| 152 assert(_sourceStream == null); | 149 assert(_sourceStream == null); |
| 153 _sourceStream = sourceStream; | 150 _sourceStream = sourceStream; |
| 154 if (_controller != null) { | 151 if (_controller != null) { |
| 155 // User has already listened, so provide the data through controller. | 152 // User has already listened, so provide the data through controller. |
| 156 _linkStreamToController(); | 153 _linkStreamToController(); |
| 157 } | 154 } |
| 158 } | 155 } |
| 159 | 156 |
| 160 /// Links source stream to controller when both are available. | 157 /// Links source stream to controller when both are available. |
| 161 void _linkStreamToController() { | 158 void _linkStreamToController() { |
| 162 assert(_controller != null); | 159 assert(_controller != null); |
| 163 assert(_sourceStream != null); | 160 assert(_sourceStream != null); |
| 164 _controller.addStream(_sourceStream, cancelOnError: false) | 161 _controller |
| 165 .whenComplete(_controller.close); | 162 .addStream(_sourceStream, cancelOnError: false) |
| 163 .whenComplete(_controller.close); |
| 166 } | 164 } |
| 167 | 165 |
| 168 /// Sets an empty source stream. | 166 /// Sets an empty source stream. |
| 169 /// | 167 /// |
| 170 /// Uses [_controller] for the stream, then closes the controller | 168 /// Uses [_controller] for the stream, then closes the controller |
| 171 /// immediately. | 169 /// immediately. |
| 172 void _setEmpty() { | 170 void _setEmpty() { |
| 173 assert(_sourceStream == null); | 171 assert(_sourceStream == null); |
| 174 if (_controller == null) { | 172 if (_controller == null) { |
| 175 _createController(); | 173 _createController(); |
| 176 } | 174 } |
| 177 _sourceStream = _controller.stream; // Mark stream as set. | 175 _sourceStream = _controller.stream; // Mark stream as set. |
| 178 _controller.close(); | 176 _controller.close(); |
| 179 } | 177 } |
| 180 | 178 |
| 181 // Creates the [_controller]. | 179 // Creates the [_controller]. |
| 182 void _createController() { | 180 void _createController() { |
| 183 assert(_controller == null); | 181 assert(_controller == null); |
| 184 _controller = new StreamController<T>(sync: true); | 182 _controller = new StreamController<T>(sync: true); |
| 185 } | 183 } |
| 186 } | 184 } |
| OLD | NEW |