| 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 // ------------------------------------------------------------------- | 7 // ------------------------------------------------------------------- |
| 8 // Controller for creating and adding events to a stream. | 8 // Controller for creating and adding events to a stream. |
| 9 // ------------------------------------------------------------------- | 9 // ------------------------------------------------------------------- |
| 10 | 10 |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 */ | 337 */ |
| 338 Error _badEventState() { | 338 Error _badEventState() { |
| 339 if (isClosed) { | 339 if (isClosed) { |
| 340 return new StateError("Cannot add event after closing"); | 340 return new StateError("Cannot add event after closing"); |
| 341 } | 341 } |
| 342 assert(_isAddingStream); | 342 assert(_isAddingStream); |
| 343 return new StateError("Cannot add event while adding a stream"); | 343 return new StateError("Cannot add event while adding a stream"); |
| 344 } | 344 } |
| 345 | 345 |
| 346 // StreamSink interface. | 346 // StreamSink interface. |
| 347 Future addStream(Stream<T> source) { | 347 /** |
| 348 * Receives events from [source] and puts them into this controller's stream. |
| 349 * |
| 350 * Returns a future which completes when the stream adding is done. |
| 351 * |
| 352 * Events must not be added directly to this controller using [add], |
| 353 * [addError], [close] or [addStream], until the returned future |
| 354 * is complete. |
| 355 * |
| 356 * Data and error events are forwarded to this controller's stream. A done |
| 357 * event on the source will end the `addStream` operation and complete the |
| 358 * returned future. |
| 359 * |
| 360 * If [cancelOnError] is true, only the first error on [source] is |
| 361 * forwarded to the controller's stream, and the `addStream` ends |
| 362 * after theis. If [cancelOnError] is false, all errors are forwarded |
| 363 * and only a done event from |
| 364 */ |
| 365 Future addStream(Stream<T> source, { bool cancelOnError: true }) { |
| 348 if (!_mayAddEvent) throw _badEventState(); | 366 if (!_mayAddEvent) throw _badEventState(); |
| 349 if (_isCanceled) return new _Future.immediate(null); | 367 if (_isCanceled) return new _Future.immediate(null); |
| 350 _StreamControllerAddStreamState addState = | 368 _StreamControllerAddStreamState addState = |
| 351 new _StreamControllerAddStreamState(this, _varData, source); | 369 new _StreamControllerAddStreamState(this, _varData, source, |
| 370 cancelOnError); |
| 352 _varData = addState; | 371 _varData = addState; |
| 353 _state |= _STATE_ADDSTREAM; | 372 _state |= _STATE_ADDSTREAM; |
| 354 return addState.addStreamFuture; | 373 return addState.addStreamFuture; |
| 355 } | 374 } |
| 356 | 375 |
| 357 Future get done => _ensureDoneFuture(); | 376 Future get done => _ensureDoneFuture(); |
| 358 | 377 |
| 359 Future _ensureDoneFuture() { | 378 Future _ensureDoneFuture() { |
| 360 if (_doneFuture == null) { | 379 if (_doneFuture == null) { |
| 361 _doneFuture = new _Future(); | 380 _doneFuture = new _Future(); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 throw new StateError("Stream has already been listened to."); | 466 throw new StateError("Stream has already been listened to."); |
| 448 } | 467 } |
| 449 _ControllerSubscription subscription = | 468 _ControllerSubscription subscription = |
| 450 new _ControllerSubscription(this, cancelOnError); | 469 new _ControllerSubscription(this, cancelOnError); |
| 451 | 470 |
| 452 _PendingEvents pendingEvents = _pendingEvents; | 471 _PendingEvents pendingEvents = _pendingEvents; |
| 453 _state |= _STATE_SUBSCRIBED; | 472 _state |= _STATE_SUBSCRIBED; |
| 454 if (_isAddingStream) { | 473 if (_isAddingStream) { |
| 455 _StreamControllerAddStreamState addState = _varData; | 474 _StreamControllerAddStreamState addState = _varData; |
| 456 addState.varData = subscription; | 475 addState.varData = subscription; |
| 476 addState.resume(); |
| 457 } else { | 477 } else { |
| 458 _varData = subscription; | 478 _varData = subscription; |
| 459 } | 479 } |
| 460 subscription._setPendingEvents(pendingEvents); | 480 subscription._setPendingEvents(pendingEvents); |
| 461 subscription._guardCallback(() { | 481 subscription._guardCallback(() { |
| 462 _runGuarded(_onListen); | 482 _runGuarded(_onListen); |
| 463 }); | 483 }); |
| 464 | 484 |
| 465 return subscription; | 485 return subscription; |
| 466 } | 486 } |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 } | 646 } |
| 627 | 647 |
| 628 void _onResume() { | 648 void _onResume() { |
| 629 _controller._recordResume(this); | 649 _controller._recordResume(this); |
| 630 } | 650 } |
| 631 } | 651 } |
| 632 | 652 |
| 633 | 653 |
| 634 /** A class that exposes only the [StreamSink] interface of an object. */ | 654 /** A class that exposes only the [StreamSink] interface of an object. */ |
| 635 class _StreamSinkWrapper<T> implements StreamSink<T> { | 655 class _StreamSinkWrapper<T> implements StreamSink<T> { |
| 636 final StreamSink _target; | 656 final StreamController _target; |
| 637 _StreamSinkWrapper(this._target); | 657 _StreamSinkWrapper(this._target); |
| 638 void add(T data) { _target.add(data); } | 658 void add(T data) { _target.add(data); } |
| 639 void addError(Object error, [StackTrace stackTrace]) { | 659 void addError(Object error, [StackTrace stackTrace]) { |
| 640 _target.addError(error); | 660 _target.addError(error); |
| 641 } | 661 } |
| 642 Future close() => _target.close(); | 662 Future close() => _target.close(); |
| 643 Future addStream(Stream<T> source) => _target.addStream(source); | 663 Future addStream(Stream<T> source, { bool cancelOnError: true}) |
| 664 => _target.addStream(source, cancelOnError: cancelOnError); |
| 644 Future get done => _target.done; | 665 Future get done => _target.done; |
| 645 } | 666 } |
| 646 | 667 |
| 647 /** | 668 /** |
| 648 * Object containing the state used to handle [StreamController.addStream]. | 669 * Object containing the state used to handle [StreamController.addStream]. |
| 649 */ | 670 */ |
| 650 class _AddStreamState<T> { | 671 class _AddStreamState<T> { |
| 651 // [_Future] returned by call to addStream. | 672 // [_Future] returned by call to addStream. |
| 652 _Future addStreamFuture; | 673 final _Future addStreamFuture; |
| 653 | 674 |
| 654 // Subscription on stream argument to addStream. | 675 // Subscription on stream argument to addStream. |
| 655 StreamSubscription addSubscription; | 676 final StreamSubscription addSubscription; |
| 656 | 677 |
| 657 _AddStreamState(_EventSink<T> controller, Stream source) | 678 _AddStreamState(_EventSink<T> controller, Stream source, bool cancelOnError) |
| 658 : addStreamFuture = new _Future(), | 679 : addStreamFuture = new _Future(), |
| 659 addSubscription = source.listen(controller._add, | 680 addSubscription = source.listen(controller._add, |
| 660 onError: controller._addError, | 681 onError: cancelOnError |
| 682 ? makeErrorHandler(controller) |
| 683 : controller._addError, |
| 661 onDone: controller._close, | 684 onDone: controller._close, |
| 662 cancelOnError: true); | 685 cancelOnError: cancelOnError); |
| 686 |
| 687 static makeErrorHandler(_EventSink controller) => |
| 688 (e, StackTrace s) { |
| 689 controller._addError(e, s); |
| 690 controller._close(); |
| 691 }; |
| 663 | 692 |
| 664 void pause() { | 693 void pause() { |
| 665 addSubscription.pause(); | 694 addSubscription.pause(); |
| 666 } | 695 } |
| 667 | 696 |
| 668 void resume() { | 697 void resume() { |
| 669 addSubscription.resume(); | 698 addSubscription.resume(); |
| 670 } | 699 } |
| 671 | 700 |
| 672 void cancel() { | 701 void cancel() { |
| 673 addSubscription.cancel(); | 702 addSubscription.cancel(); |
| 674 complete(); | 703 complete(); |
| 675 } | 704 } |
| 676 | 705 |
| 677 void complete() { | 706 void complete() { |
| 678 addStreamFuture._asyncComplete(null); | 707 addStreamFuture._asyncComplete(null); |
| 679 } | 708 } |
| 680 } | 709 } |
| 681 | 710 |
| 682 class _StreamControllerAddStreamState<T> extends _AddStreamState<T> { | 711 class _StreamControllerAddStreamState<T> extends _AddStreamState<T> { |
| 683 // The subscription or pending data of a _StreamController. | 712 // The subscription or pending data of a _StreamController. |
| 684 // Stored here because we reuse the `_varData` field in the _StreamController | 713 // Stored here because we reuse the `_varData` field in the _StreamController |
| 685 // to store this state object. | 714 // to store this state object. |
| 686 var varData; | 715 var varData; |
| 687 | 716 |
| 688 _StreamControllerAddStreamState(_StreamController controller, | 717 _StreamControllerAddStreamState(_StreamController controller, |
| 689 this.varData, | 718 this.varData, |
| 690 Stream source) : super(controller, source) { | 719 Stream source, |
| 720 bool cancelOnError) |
| 721 : super(controller, source, cancelOnError) { |
| 691 if (controller.isPaused) { | 722 if (controller.isPaused) { |
| 692 addSubscription.pause(); | 723 addSubscription.pause(); |
| 693 } | 724 } |
| 694 } | 725 } |
| 695 } | 726 } |
| OLD | NEW |