OLD | NEW |
---|---|
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 _js_helper; | 5 library _js_helper; |
6 | 6 |
7 import 'dart:_async_await_error_codes' as async_error_codes; | 7 import 'dart:_async_await_error_codes' as async_error_codes; |
8 | 8 |
9 import 'dart:_js_embedded_names' show | 9 import 'dart:_js_embedded_names' show |
10 DEFERRED_LIBRARY_URIS, | 10 DEFERRED_LIBRARY_URIS, |
(...skipping 3723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3734 return; | 3734 return; |
3735 } | 3735 } |
3736 | 3736 |
3737 if (object is IterationMarker) { | 3737 if (object is IterationMarker) { |
3738 if (controller.cancelationCompleter != null) { | 3738 if (controller.cancelationCompleter != null) { |
3739 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, | 3739 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, |
3740 async_error_codes.STREAM_WAS_CANCELED)(null); | 3740 async_error_codes.STREAM_WAS_CANCELED)(null); |
3741 return; | 3741 return; |
3742 } | 3742 } |
3743 if (object.state == IterationMarker.YIELD_SINGLE) { | 3743 if (object.state == IterationMarker.YIELD_SINGLE) { |
3744 controller.isWaitingForYield = true; | |
3744 controller.add(object.value); | 3745 controller.add(object.value); |
3745 // If the controller is paused we stop producing more values. | 3746 // If the controller is paused we stop producing more values. |
3746 if (controller.isPaused) { | 3747 if (controller.isPaused) { |
3747 return; | 3748 return; |
3748 } | 3749 } |
3749 // TODO(sigurdm): We should not suspend here according to the spec. | 3750 // TODO(sigurdm): We should not suspend here according to the spec. |
Lasse Reichstein Nielsen
2015/04/08 14:12:14
Isn't the spec allowing you to do so, but not requ
sigurdm
2015/04/09 11:24:08
Yes I think so - this is an outdated comment. Remo
| |
3750 scheduleMicrotask(() { | 3751 scheduleMicrotask(() { |
3752 controller.isWaitingForYield = false; | |
Lasse Reichstein Nielsen
2015/04/08 14:12:15
I think this line should be moved outside of the s
sigurdm
2015/04/09 11:24:08
Done.
| |
3751 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, | 3753 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, |
3752 async_error_codes.SUCCESS) | 3754 async_error_codes.SUCCESS) |
3753 (null); | 3755 (null); |
3754 }); | 3756 }); |
Lasse Reichstein Nielsen
2015/04/08 14:12:14
I think I would prefer waiting until the scheduleM
sigurdm
2015/04/09 11:24:08
Done.
| |
3755 return; | 3757 return; |
3756 } else if (object.state == IterationMarker.YIELD_STAR) { | 3758 } else if (object.state == IterationMarker.YIELD_STAR) { |
3757 Stream stream = object.value; | 3759 Stream stream = object.value; |
3758 controller.isAdding = true; | 3760 controller.isAdding = true; |
3759 // Errors of [stream] are passed though to the main stream. (see | 3761 // Errors of [stream] are passed though to the main stream. (see |
3760 // [AsyncStreamController.addStream]. | 3762 // [AsyncStreamController.addStream]. |
Lasse Reichstein Nielsen
2015/04/08 14:12:15
Missing end-paren :)
sigurdm
2015/04/09 11:24:08
Thanks!
| |
3761 // TODO(sigurdm): The spec is not very clear here. Clarify with Gilad. | 3763 // TODO(sigurdm): The spec is not very clear here. Clarify with Gilad. |
3762 controller.addStream(stream).then((_) { | 3764 controller.addStream(stream).then((_) { |
3763 controller.isAdding = false; | 3765 controller.isAdding = false; |
3764 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, | 3766 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, |
3765 async_error_codes.SUCCESS)(null); | 3767 async_error_codes.SUCCESS)(null); |
3766 }); | 3768 }); |
3767 return; | 3769 return; |
3768 } | 3770 } |
3769 } | 3771 } |
3770 | 3772 |
(...skipping 18 matching lines...) Expand all Loading... | |
3789 /// | 3791 /// |
3790 /// Also has a subSubscription that when not null will provide events for the | 3792 /// Also has a subSubscription that when not null will provide events for the |
3791 /// stream, and will be paused and resumed along with this controller. | 3793 /// stream, and will be paused and resumed along with this controller. |
3792 class AsyncStarStreamController { | 3794 class AsyncStarStreamController { |
3793 StreamController controller; | 3795 StreamController controller; |
3794 Stream get stream => controller.stream; | 3796 Stream get stream => controller.stream; |
3795 Completer cancelationCompleter = null; | 3797 Completer cancelationCompleter = null; |
3796 bool get isCanceled => cancelationCompleter != null; | 3798 bool get isCanceled => cancelationCompleter != null; |
3797 bool isAdding = false; | 3799 bool isAdding = false; |
3798 bool isPaused = false; | 3800 bool isPaused = false; |
3801 bool isWaitingForYield = false; | |
floitsch
2015/04/08 14:01:25
isAtYield ?
Add comment what exactly this means.
sigurdm
2015/04/08 14:07:40
Done.
Lasse Reichstein Nielsen
2015/04/08 14:12:14
Consider documenting these fields, preferably by d
sigurdm
2015/04/09 11:24:08
Good advice!
I realized I can leave out `isAdding`
| |
3802 | |
3799 add(event) => controller.add(event); | 3803 add(event) => controller.add(event); |
3800 addStream(Stream stream) { | 3804 addStream(Stream stream) { |
3801 return controller.addStream(stream, cancelOnError: false); | 3805 return controller.addStream(stream, cancelOnError: false); |
3802 } | 3806 } |
3803 addError(error, stackTrace) => controller.addError(error, stackTrace); | 3807 addError(error, stackTrace) => controller.addError(error, stackTrace); |
3804 close() => controller.close(); | 3808 close() => controller.close(); |
3805 | 3809 |
3806 AsyncStarStreamController(body) { | 3810 AsyncStarStreamController(body) { |
3807 controller = new StreamController( | 3811 controller = new StreamController( |
3808 onListen: () { | 3812 onListen: () { |
3809 scheduleMicrotask(() { | 3813 scheduleMicrotask(() { |
3810 Function wrapped = _wrapJsFunctionForAsync(body, | 3814 Function wrapped = |
3811 async_error_codes.SUCCESS); | 3815 _wrapJsFunctionForAsync(body, async_error_codes.SUCCESS); |
3812 wrapped(null); | 3816 wrapped(null); |
3813 }); | 3817 }); |
3814 }, | 3818 }, |
3815 onPause: () { | 3819 onPause: () { |
3816 isPaused = true; | 3820 isPaused = true; |
3817 }, onResume: () { | 3821 }, onResume: () { |
3818 isPaused = false; | 3822 isPaused = false; |
3819 if (!isAdding) { | 3823 if (!isAdding && isWaitingForYield) { |
Lasse Reichstein Nielsen
2015/04/08 14:12:15
I don't think this is safe enough.
If the stream
Lasse Reichstein Nielsen
2015/04/08 14:12:15
Maybe name it "isWaitingForResume"? You have alrea
sigurdm
2015/04/09 11:24:08
It is now isSuspended
| |
3820 asyncStarHelper(null, body, this); | 3824 asyncStarHelper(null, body, this); |
3821 } | 3825 } |
3822 }, onCancel: () { | 3826 }, onCancel: () { |
3823 if (!controller.isClosed) { | 3827 if (!controller.isClosed) { |
3824 cancelationCompleter = new Completer(); | 3828 cancelationCompleter = new Completer(); |
3825 if (isPaused) asyncStarHelper(null, body, this); | 3829 if (isPaused) asyncStarHelper(null, body, this); |
Lasse Reichstein Nielsen
2015/04/08 14:12:14
Are you sure this is safe?
You can have a call to
sigurdm
2015/04/09 11:24:08
True - I need a better mechanism for this.
Now I o
| |
3826 | 3830 |
3827 return cancelationCompleter.future; | 3831 return cancelationCompleter.future; |
3828 } | 3832 } |
3829 }); | 3833 }); |
3830 } | 3834 } |
3831 } | 3835 } |
3832 | 3836 |
3833 makeAsyncStarController(body) { | 3837 makeAsyncStarController(body) { |
3834 return new AsyncStarStreamController(body); | 3838 return new AsyncStarStreamController(body); |
3835 } | 3839 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3932 // This is a function that will return a helper function that does the | 3936 // This is a function that will return a helper function that does the |
3933 // iteration of the sync*. | 3937 // iteration of the sync*. |
3934 // | 3938 // |
3935 // Each invocation should give a body with fresh state. | 3939 // Each invocation should give a body with fresh state. |
3936 final dynamic /* js function */ _outerHelper; | 3940 final dynamic /* js function */ _outerHelper; |
3937 | 3941 |
3938 SyncStarIterable(this._outerHelper); | 3942 SyncStarIterable(this._outerHelper); |
3939 | 3943 |
3940 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); | 3944 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); |
3941 } | 3945 } |
OLD | NEW |