| 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 /** Abstract and private interface for a place to put events. */ | 7 /** Abstract and private interface for a place to put events. */ |
| 8 abstract class _EventSink<T> { | 8 abstract class _EventSink<T> { |
| 9 void _add(T data); | 9 void _add(T data); |
| 10 void _addError(Object error, StackTrace stackTrace); | 10 void _addError(Object error, StackTrace stackTrace); |
| (...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 newPrevious._next = this; | 722 newPrevious._next = this; |
| 723 newNext._previous = _previous; | 723 newNext._previous = _previous; |
| 724 _previous._next = newNext; | 724 _previous._next = newNext; |
| 725 _previous = newPrevious; | 725 _previous = newPrevious; |
| 726 } | 726 } |
| 727 } | 727 } |
| 728 | 728 |
| 729 typedef void _broadcastCallback(StreamSubscription subscription); | 729 typedef void _broadcastCallback(StreamSubscription subscription); |
| 730 | 730 |
| 731 /** | 731 /** |
| 732 * Dummy subscription that will never receive any events. | 732 * Done subscription that will send one done event as soon as possible. |
| 733 */ | 733 */ |
| 734 class _DummyStreamSubscription<T> implements StreamSubscription<T> { | 734 class _DoneStreamSubscription<T> implements StreamSubscription<T> { |
| 735 int _pauseCounter = 0; | 735 static const int _DONE_SENT = 1; |
| 736 static const int _SCHEDULED = 2; |
| 737 static const int _PAUSED = 4; |
| 738 |
| 739 final Zone _zone; |
| 740 int _state = 0; |
| 741 _DoneHandler _onDone; |
| 742 |
| 743 _DoneStreamSubscription(this._onDone) : _zone = Zone.current { |
| 744 _schedule(); |
| 745 } |
| 746 |
| 747 bool get _isSent => (_state & _DONE_SENT) != 0; |
| 748 bool get _isScheduled => (_state & _SCHEDULED) != 0; |
| 749 bool get isPaused => _state >= _PAUSED; |
| 750 |
| 751 void _schedule() { |
| 752 if (_isScheduled) return; |
| 753 _zone.scheduleMicrotask(_sendDone); |
| 754 _state |= _SCHEDULED; |
| 755 } |
| 736 | 756 |
| 737 void onData(void handleData(T data)) {} | 757 void onData(void handleData(T data)) {} |
| 738 void onError(Function handleError) {} | 758 void onError(Function handleError) {} |
| 739 void onDone(void handleDone()) {} | 759 void onDone(void handleDone()) { _onDone = handleDone; } |
| 740 | 760 |
| 741 void pause([Future resumeSignal]) { | 761 void pause([Future resumeSignal]) { |
| 742 _pauseCounter++; | 762 _state += _PAUSED; |
| 743 if (resumeSignal != null) resumeSignal.then((_) { resume(); }); | 763 if (resumeSignal != null) resumeSignal.whenComplete(resume); |
| 744 } | 764 } |
| 765 |
| 745 void resume() { | 766 void resume() { |
| 746 if (_pauseCounter > 0) _pauseCounter--; | 767 if (isPaused) { |
| 768 _state -= _PAUSED; |
| 769 if (!isPaused && !_isSent) { |
| 770 _schedule(); |
| 771 } |
| 772 } |
| 747 } | 773 } |
| 774 |
| 748 Future cancel() => null; | 775 Future cancel() => null; |
| 749 bool get isPaused => _pauseCounter > 0; | |
| 750 | 776 |
| 751 Future asFuture([futureValue]) => new _Future(); | 777 Future asFuture([futureValue]) { |
| 778 _Future result = new _Future(); |
| 779 _onDone = () { result._completeWithValue(null); } |
| 780 return result; |
| 781 } |
| 782 |
| 783 void _sendDone() { |
| 784 _state &= ~_SCHEDULED; |
| 785 if (isPaused) return; |
| 786 _state |= _DONE_SENT; |
| 787 _zone.runGuarded(_onDone); |
| 788 } |
| 752 } | 789 } |
| 753 | 790 |
| 754 class _AsBroadcastStream<T> extends Stream<T> { | 791 class _AsBroadcastStream<T> extends Stream<T> { |
| 755 final Stream<T> _source; | 792 final Stream<T> _source; |
| 756 final _broadcastCallback _onListenHandler; | 793 final _broadcastCallback _onListenHandler; |
| 757 final _broadcastCallback _onCancelHandler; | 794 final _broadcastCallback _onCancelHandler; |
| 758 final Zone _zone; | 795 final Zone _zone; |
| 759 | 796 |
| 760 _AsBroadcastStreamController<T> _controller; | 797 _AsBroadcastStreamController<T> _controller; |
| 761 StreamSubscription<T> _subscription; | 798 StreamSubscription<T> _subscription; |
| 762 | 799 |
| 763 _AsBroadcastStream(this._source, | 800 _AsBroadcastStream(this._source, |
| 764 void onListenHandler(StreamSubscription subscription), | 801 void onListenHandler(StreamSubscription subscription), |
| 765 void onCancelHandler(StreamSubscription subscription)) | 802 void onCancelHandler(StreamSubscription subscription)) |
| 766 : _onListenHandler = Zone.current.registerUnaryCallback(onListenHandler), | 803 : _onListenHandler = Zone.current.registerUnaryCallback(onListenHandler), |
| 767 _onCancelHandler = Zone.current.registerUnaryCallback(onCancelHandler), | 804 _onCancelHandler = Zone.current.registerUnaryCallback(onCancelHandler), |
| 768 _zone = Zone.current { | 805 _zone = Zone.current { |
| 769 _controller = new _AsBroadcastStreamController<T>(_onListen, _onCancel); | 806 _controller = new _AsBroadcastStreamController<T>(_onListen, _onCancel); |
| 770 } | 807 } |
| 771 | 808 |
| 772 bool get isBroadcast => true; | 809 bool get isBroadcast => true; |
| 773 | 810 |
| 774 StreamSubscription<T> listen(void onData(T data), | 811 StreamSubscription<T> listen(void onData(T data), |
| 775 { Function onError, | 812 { Function onError, |
| 776 void onDone(), | 813 void onDone(), |
| 777 bool cancelOnError}) { | 814 bool cancelOnError}) { |
| 778 if (_controller == null) { | 815 if (_controller == null || _controller.isClosed) { |
| 779 // Return a dummy subscription backed by nothing, since | 816 // Return a dummy subscription backed by nothing, since |
| 780 // it won't ever receive any events. | 817 // it will only ever send one done event. |
| 781 return new _DummyStreamSubscription<T>(); | 818 return new _DoneStreamSubscription<T>(onDone); |
| 782 } | 819 } |
| 783 if (_subscription == null) { | 820 if (_subscription == null) { |
| 784 _subscription = _source.listen(_controller.add, | 821 _subscription = _source.listen(_controller.add, |
| 785 onError: _controller.addError, | 822 onError: _controller.addError, |
| 786 onDone: _controller.close); | 823 onDone: _controller.close); |
| 787 } | 824 } |
| 788 cancelOnError = identical(true, cancelOnError); | 825 cancelOnError = identical(true, cancelOnError); |
| 789 StreamSubscription<T> result = _controller._subscribe(cancelOnError); | 826 StreamSubscription<T> result = _controller._subscribe(cancelOnError); |
| 790 result.onData(onData); | 827 result.onData(onData); |
| 791 result.onError(onError); | 828 result.onError(onError); |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1029 _Future<bool> hasNext = _futureOrPrefetch; | 1066 _Future<bool> hasNext = _futureOrPrefetch; |
| 1030 _clear(); | 1067 _clear(); |
| 1031 hasNext._complete(false); | 1068 hasNext._complete(false); |
| 1032 return; | 1069 return; |
| 1033 } | 1070 } |
| 1034 _subscription.pause(); | 1071 _subscription.pause(); |
| 1035 _futureOrPrefetch = null; | 1072 _futureOrPrefetch = null; |
| 1036 _state = _STATE_EXTRA_DONE; | 1073 _state = _STATE_EXTRA_DONE; |
| 1037 } | 1074 } |
| 1038 } | 1075 } |
| OLD | NEW |