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

Side by Side Diff: pkg/scheduled_test/lib/scheduled_stream.dart

Issue 139263002: Revert revision 31820 (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 11 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 | « pkg/pkg.status ('k') | no next file » | 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 library scheduled_test.scheduled_stream; 5 library scheduled_test.scheduled_stream;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:stack_trace/stack_trace.dart'; 10 import 'package:stack_trace/stack_trace.dart';
(...skipping 22 matching lines...) Expand all
33 /// 33 ///
34 /// If this is non-null, [_pendingValues] will always be empty, since any 34 /// If this is non-null, [_pendingValues] will always be empty, since any
35 /// value coming in will be passed to this completer. 35 /// value coming in will be passed to this completer.
36 Completer<T> _nextCompleter; 36 Completer<T> _nextCompleter;
37 37
38 /// The completer for emitting a value requested by [hasNext]. 38 /// The completer for emitting a value requested by [hasNext].
39 Completer<bool> _hasNextCompleter; 39 Completer<bool> _hasNextCompleter;
40 40
41 /// The set of all streams forked from this one. 41 /// The set of all streams forked from this one.
42 final _forks = new Set<ScheduledStream<T>>(); 42 final _forks = new Set<ScheduledStream<T>>();
43 final _forkControllers = new Set<StreamController<T>>();
44 43
45 /// The queue of values emitted by [_stream] but not yet emitted through 44 /// The queue of values emitted by [_stream] but not yet emitted through
46 /// [next]. 45 /// [next].
47 final _pendingValues = new Queue<Fallible<T>>(); 46 final _pendingValues = new Queue<Fallible<T>>();
48 47
49 /// All values emitted by this stream so far. 48 /// All values emitted by this stream so far.
50 /// 49 ///
51 /// This does not include values emitted by the underlying stream but not yet 50 /// This does not include values emitted by the underlying stream but not yet
52 /// emitted through [next]. 51 /// emitted through [next].
53 List<T> get emittedValues => new UnmodifiableListView(_emittedValues); 52 List<T> get emittedValues => new UnmodifiableListView(_emittedValues);
(...skipping 12 matching lines...) Expand all
66 /// Whether the wrapped stream has been closed. 65 /// Whether the wrapped stream has been closed.
67 bool _isDone = false; 66 bool _isDone = false;
68 67
69 /// Whether [next] has been called but has not yet returned. 68 /// Whether [next] has been called but has not yet returned.
70 /// 69 ///
71 /// This is distinct from `_nextCompleter != null` when [next] is called while 70 /// This is distinct from `_nextCompleter != null` when [next] is called while
72 /// there are pending values available, until the future it returns completes. 71 /// there are pending values available, until the future it returns completes.
73 bool _isNextPending = false; 72 bool _isNextPending = false;
74 73
75 /// Creates a new scheduled stream wrapping [stream]. 74 /// Creates a new scheduled stream wrapping [stream].
76 ScheduledStream(this._stream) { 75 ScheduledStream(Stream<T> stream)
76 : _stream = stream.asBroadcastStream() {
77 _subscription = _stream.listen((value) { 77 _subscription = _stream.listen((value) {
78 for (var c in _forkControllers) {
79 c.add(value);
80 }
81 if (_hasNextCompleter != null) { 78 if (_hasNextCompleter != null) {
82 _hasNextCompleter.complete(true); 79 _hasNextCompleter.complete(true);
83 _hasNextCompleter = null; 80 _hasNextCompleter = null;
84 } 81 }
85 82
86 if (_nextCompleter != null) { 83 if (_nextCompleter != null) {
87 _nextCompleter.complete(value); 84 _nextCompleter.complete(value);
88 _emittedValues.add(value); 85 _emittedValues.add(value);
89 _nextCompleter = null; 86 _nextCompleter = null;
90 _isNextPending = false; 87 _isNextPending = false;
91 } else { 88 } else {
92 _pendingValues.add(new Fallible.withValue(value)); 89 _pendingValues.add(new Fallible.withValue(value));
93 } 90 }
94 }, onError: (error, stackTrace) { 91 }, onError: (error, stackTrace) {
95 for (var c in _forkControllers) {
96 c.addError(error, stackTrace);
97 }
98 if (_hasNextCompleter != null) { 92 if (_hasNextCompleter != null) {
99 _hasNextCompleter.completeError(error, stackTrace); 93 _hasNextCompleter.completeError(error, stackTrace);
100 _hasNextCompleter = null; 94 _hasNextCompleter = null;
101 } 95 }
102 96
103 if (_nextCompleter != null) { 97 if (_nextCompleter != null) {
104 _nextCompleter.completeError(error, stackTrace); 98 _nextCompleter.completeError(error, stackTrace);
105 _nextCompleter = null; 99 _nextCompleter = null;
106 } else { 100 } else {
107 _pendingValues.add(new Fallible.withError(error, stackTrace)); 101 _pendingValues.add(new Fallible.withError(error, stackTrace));
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 /// closed at whatever point it's currently at. 198 /// closed at whatever point it's currently at.
205 ScheduledStream<T> fork() { 199 ScheduledStream<T> fork() {
206 var controller = new StreamController<T>(); 200 var controller = new StreamController<T>();
207 for (var valueOrError in _pendingValues) { 201 for (var valueOrError in _pendingValues) {
208 if (valueOrError.hasValue) { 202 if (valueOrError.hasValue) {
209 controller.add(valueOrError.value); 203 controller.add(valueOrError.value);
210 } else { 204 } else {
211 controller.addError(valueOrError.error, valueOrError.stackTrace); 205 controller.addError(valueOrError.error, valueOrError.stackTrace);
212 } 206 }
213 } 207 }
208
214 if (_isDone) { 209 if (_isDone) {
215 controller.close(); 210 controller.close();
216 } else { 211 } else {
217 _forkControllers.add(controller); 212 _stream.pipe(controller);
218 } 213 }
219 214
220 var fork = new ScheduledStream<T>(controller.stream); 215 var fork = new ScheduledStream<T>(controller.stream);
221 _forks.add(fork); 216 _forks.add(fork);
222 return fork; 217 return fork;
223 } 218 }
224 219
225 /// Closes this stream. 220 /// Closes this stream.
226 /// 221 ///
227 /// This cancels the subscription to the underlying stream and acts as though 222 /// This cancels the subscription to the underlying stream and acts as though
228 /// [this] was closed immediately after the current position, regardless of 223 /// [this] was closed immediately after the current position, regardless of
229 /// whether the underlying stream has emitted additional events. 224 /// whether the underlying stream has emitted additional events.
230 void close() { 225 void close() {
231 _subscription.cancel(); 226 _subscription.cancel();
232 _pendingValues.clear(); 227 _pendingValues.clear();
233 228
234 for (var fork in _forks) { 229 for (var fork in _forks) {
235 fork.close(); 230 fork.close();
236 } 231 }
237 _forks.clear(); 232 _forks.clear();
238 233
239 if (!_isDone) _onDone(); 234 if (!_isDone) _onDone();
240 } 235 }
241 236
242 /// Handles a "done" event from the underlying stream, as well as [this] being 237 /// Handles a "done" event from the underlying stream, as well as [this] being
243 /// closed. 238 /// closed.
244 void _onDone() { 239 void _onDone() {
245 for (var c in _forkControllers) {
246 c.close();
247 }
248 _forkControllers.clear();
249
250 if (_hasNextCompleter != null) { 240 if (_hasNextCompleter != null) {
251 _hasNextCompleter.complete(false); 241 _hasNextCompleter.complete(false);
252 _hasNextCompleter = null; 242 _hasNextCompleter = null;
253 } 243 }
254 244
255 if (_nextCompleter != null) { 245 if (_nextCompleter != null) {
256 _nextCompleter.completeError( 246 _nextCompleter.completeError(
257 new StateError("ScheduledStream has no more elements."), 247 new StateError("ScheduledStream has no more elements."),
258 new Chain.current()); 248 new Chain.current());
259 _nextCompleter = null; 249 _nextCompleter = null;
260 _isNextPending = false; 250 _isNextPending = false;
261 } 251 }
262 252
263 _isDone = true; 253 _isDone = true;
264 } 254 }
265 } 255 }
OLDNEW
« no previous file with comments | « pkg/pkg.status ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698