| 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 // 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |