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

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

Issue 11794044: Add Stream.fromIterable (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Fix bug hit by new test. Created 7 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
OLDNEW
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 // States shared by single/multi stream implementations. 7 // States shared by single/multi stream implementations.
8 8
9 /// Initial and default state where the stream can receive and send events. 9 /// Initial and default state where the stream can receive and send events.
10 const int _STREAM_OPEN = 0; 10 const int _STREAM_OPEN = 0;
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 this, onData, onError, onDone, unsubscribeOnError); 435 this, onData, onError, onDone, unsubscribeOnError);
436 } 436 }
437 437
438 void _addListener(_StreamSubscriptionImpl subscription) { 438 void _addListener(_StreamSubscriptionImpl subscription) {
439 if (_hasSubscribers) { 439 if (_hasSubscribers) {
440 throw new StateError("Stream has already subscriber."); 440 throw new StateError("Stream has already subscriber.");
441 } 441 }
442 _subscriber = subscription; 442 _subscriber = subscription;
443 subscription._setSubscribed(0); 443 subscription._setSubscribed(0);
444 _onSubscriptionStateChange(); 444 _onSubscriptionStateChange();
445 // TODO(floitsch): Should this be delayed? 445 if (_hasPendingEvent) {
446 _handlePendingEvents(); 446 new Timer(0, (_) {
447 _handlePendingEvents();
448 });
449 }
447 } 450 }
448 451
449 /** 452 /**
450 * Handle a cancel requested from a [_StreamSubscriptionImpl]. 453 * Handle a cancel requested from a [_StreamSubscriptionImpl].
451 * 454 *
452 * This method is called from [_StreamSubscriptionImpl.cancel]. 455 * This method is called from [_StreamSubscriptionImpl.cancel].
453 * 456 *
454 * If an event is currently firing, the cancel is delayed 457 * If an event is currently firing, the cancel is delayed
455 * until after the subscriber has received the event. 458 * until after the subscriber has received the event.
456 */ 459 */
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 * This is a low-level action that doesn't call [_onSubscriptionStateChange]. 630 * This is a low-level action that doesn't call [_onSubscriptionStateChange].
628 * or [_onPauseStateChange]. 631 * or [_onPauseStateChange].
629 */ 632 */
630 void _removeListener(_StreamListener listener) { 633 void _removeListener(_StreamListener listener) {
631 int pauseCount = listener._setUnsubscribed(); 634 int pauseCount = listener._setUnsubscribed();
632 _updatePauseCount(-pauseCount); 635 _updatePauseCount(-pauseCount);
633 _InternalLinkList.remove(listener); 636 _InternalLinkList.remove(listener);
634 } 637 }
635 } 638 }
636 639
640
641 /** Abstract superclass for streams that generate their own events. */
642 abstract class _GeneratedSingleStreamImpl<T> extends _SingleStreamImpl<T> {
643 bool _isHandlingPendingEvents = false;
644 bool get _hasPendingEvent => !_isClosed;
645
646 /**
647 * Generate one (or possibly more) new events.
648 *
649 * The events should be added to the stream using [_add], [_signalError] and
650 * [_close].
651 */
652 void _generateNextEvent();
653
654 void _handlePendingEvents() {
655 // Avoid reentry from _add/_signalError/_close potentially called
656 // from _generateNextEvent.
657 if (_isHandlingPendingEvents) return;
658 _isHandlingPendingEvents = true;
659 while (!_isPaused && !_isClosed) {
660 // Call super's handle event in case _generateNextEvent generates
661 // more than one event, and the following ones are delayed.
662 super._handlePendingEvents();
663 if (!_isPaused && !_isClosed) {
664 _generateNextEvent();
665 }
666 }
667 _isHandlingPendingEvents = false;
668 }
669 }
670
671
672 /** Stream that gets its events from an [Iterable]. */
673 class _IterableSingleStreamImpl<T> extends _GeneratedSingleStreamImpl<T> {
674 Iterator<T> _iterator;
675
676 _IterableSingleStreamImpl(Iterable<T> data) : _iterator = data.iterator;
677
678 void _generateNextEvent() {
679 try {
680 if (_iterator.moveNext()) {
681 _add(_iterator.current);
682 return;
683 }
684 } catch (e, s) {
685 _signalError(new AsyncError(e, s));
686 }
687 _close();
688 }
689 }
690
691
637 /** 692 /**
638 * The subscription class that the [StreamController] uses. 693 * The subscription class that the [StreamController] uses.
639 * 694 *
640 * The [StreamController.createSubscription] method should 695 * The [StreamController.createSubscription] method should
641 * create an object of this type, or another subclass of [_StreamListener]. 696 * create an object of this type, or another subclass of [_StreamListener].
642 * A subclass of [StreamController] can specify which subclass 697 * A subclass of [StreamController] can specify which subclass
643 * of [_StreamSubscriptionImpl] it uses by overriding 698 * of [_StreamSubscriptionImpl] it uses by overriding
644 * [StreamController.createSubscription]. 699 * [StreamController.createSubscription].
645 * 700 *
646 * The subscription is in one of three states: 701 * The subscription is in one of three states:
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 if (_isComplete) { 1074 if (_isComplete) {
1020 throw new StateError("Subscription has been canceled."); 1075 throw new StateError("Subscription has been canceled.");
1021 } 1076 }
1022 if (_timer != null) { 1077 if (_timer != null) {
1023 _timer.cancel(); 1078 _timer.cancel();
1024 _timer = null; 1079 _timer = null;
1025 } 1080 }
1026 _pauseCount = 0; 1081 _pauseCount = 0;
1027 } 1082 }
1028 } 1083 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698