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