Chromium Code Reviews| 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 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 396 * * [_onSubscriberStateChange]: Called when receiving the first subscriber or | 396 * * [_onSubscriberStateChange]: Called when receiving the first subscriber or |
| 397 * when losing the last subscriber. | 397 * when losing the last subscriber. |
| 398 * * [_onPauseStateChange]: Called when entering or leaving paused mode. | 398 * * [_onPauseStateChange]: Called when entering or leaving paused mode. |
| 399 * * [_hasSubscribers]: Test whether there are currently any subscribers. | 399 * * [_hasSubscribers]: Test whether there are currently any subscribers. |
| 400 * * [_isPaused]: Test whether the stream is currently paused. | 400 * * [_isPaused]: Test whether the stream is currently paused. |
| 401 * The user should not add new events while the stream is paused, but if it | 401 * The user should not add new events while the stream is paused, but if it |
| 402 * happens anyway, the stream will enqueue the events just as when new events | 402 * happens anyway, the stream will enqueue the events just as when new events |
| 403 * arrive while still firing an old event. | 403 * arrive while still firing an old event. |
| 404 */ | 404 */ |
| 405 class _SingleStreamImpl<T> extends _StreamImpl<T> { | 405 class _SingleStreamImpl<T> extends _StreamImpl<T> { |
| 406 _StreamSubscriptionImpl _subscriber = null; | 406 _StreamListener _subscriber = null; |
| 407 | |
| 408 Stream<T> toMultiSubscriber() { | |
| 409 _MultiStreamImpl<T> multiStream = new _MultiStreamImpl(); | |
| 410 listen(multiStream._add, | |
|
floitsch
2013/01/08 14:06:00
as discussed: don't listen right away.
Lasse Reichstein Nielsen
2013/01/09 15:19:17
Done.
| |
| 411 onError: multiStream._signalError, | |
| 412 onDone: multiStream._close); | |
| 413 return multiStream; | |
| 414 } | |
| 407 | 415 |
| 408 /** Whether one or more active subscribers have requested a pause. */ | 416 /** Whether one or more active subscribers have requested a pause. */ |
| 409 bool get _isPaused => !_hasSubscribers || super._isPaused; | 417 bool get _isPaused => !_hasSubscribers || super._isPaused; |
| 410 | 418 |
| 411 /** Whether there is currently a subscriber on this [Stream]. */ | 419 /** Whether there is currently a subscriber on this [Stream]. */ |
| 412 bool get _hasSubscribers => _subscriber != null; | 420 bool get _hasSubscribers => _subscriber != null; |
| 413 | 421 |
| 414 // ------------------------------------------------------------------- | 422 // ------------------------------------------------------------------- |
| 415 // Internal implementation. | 423 // Internal implementation. |
| 416 | 424 |
| 417 /** | 425 /** |
| 418 * Create the new subscription object. | 426 * Create the new subscription object. |
| 419 */ | 427 */ |
| 420 _StreamSubscriptionImpl<T> _createSubscription( | 428 _StreamSubscriptionImpl<T> _createSubscription( |
| 421 void onData(T data), | 429 void onData(T data), |
| 422 void onError(AsyncError error), | 430 void onError(AsyncError error), |
| 423 void onDone(), | 431 void onDone(), |
| 424 bool unsubscribeOnError) { | 432 bool unsubscribeOnError) { |
| 425 return new _StreamSubscriptionImpl<T>( | 433 return new _StreamSubscriptionImpl<T>( |
| 426 this, onData, onError, onDone, unsubscribeOnError); | 434 this, onData, onError, onDone, unsubscribeOnError); |
| 427 } | 435 } |
| 428 | 436 |
| 429 void _addListener(_StreamSubscriptionImpl subscription) { | 437 void _addListener(_StreamListener subscription) { |
| 430 if (_hasSubscribers) { | 438 if (_hasSubscribers) { |
| 431 throw new StateError("Stream has already subscriber."); | 439 throw new StateError("Stream already has subscriber."); |
| 432 } | 440 } |
| 433 _subscriber = subscription; | 441 _subscriber = subscription; |
| 434 subscription._setSubscribed(0); | 442 subscription._setSubscribed(0); |
| 435 _onSubscriptionStateChange(); | 443 _onSubscriptionStateChange(); |
| 436 // TODO(floitsch): Should this be delayed? | 444 // TODO(floitsch): Should this be delayed? |
| 437 _handlePendingEvents(); | 445 _handlePendingEvents(); |
| 438 } | 446 } |
| 439 | 447 |
| 440 /** | 448 /** |
| 441 * Handle a cancel requested from a [_StreamSubscriptionImpl]. | 449 * Handle a cancel requested from a [_StreamSubscriptionImpl]. |
| 442 * | 450 * |
| 443 * This method is called from [_StreamSubscriptionImpl.cancel]. | 451 * This method is called from [_StreamSubscriptionImpl.cancel]. |
| 444 * | 452 * |
| 445 * If an event is currently firing, the cancel is delayed | 453 * If an event is currently firing, the cancel is delayed |
| 446 * until after the subscriber has received the event. | 454 * until after the subscriber has received the event. |
| 447 */ | 455 */ |
| 448 void _cancel(_StreamSubscriptionImpl subscriber) { | 456 void _cancel(_StreamListener subscriber) { |
| 449 assert(identical(subscriber._source, this)); | 457 assert(identical(subscriber._source, this)); |
| 450 // We allow unsubscribing the currently firing subscription during | 458 // We allow unsubscribing the currently firing subscription during |
| 451 // the event firing, because it is indistinguishable from delaying it since | 459 // the event firing, because it is indistinguishable from delaying it since |
| 452 // that event has already received the event. | 460 // that event has already received the event. |
| 453 if (!identical(_subscriber, subscriber)) { | 461 if (!identical(_subscriber, subscriber)) { |
| 454 // You may unsubscribe more than once, only the first one counts. | 462 // You may unsubscribe more than once, only the first one counts. |
| 455 return; | 463 return; |
| 456 } | 464 } |
| 457 _subscriber = null; | 465 _subscriber = null; |
| 458 int timesPaused = subscriber._setUnsubscribed(); | 466 int timesPaused = subscriber._setUnsubscribed(); |
| 459 _updatePauseCount(-timesPaused); | 467 _updatePauseCount(-timesPaused); |
| 460 if (timesPaused > 0) { | 468 if (timesPaused > 0) { |
| 461 _onPauseStateChange(); | 469 _onPauseStateChange(); |
| 462 } | 470 } |
| 463 _onSubscriptionStateChange(); | 471 _onSubscriptionStateChange(); |
| 464 } | 472 } |
| 465 | 473 |
| 466 void _forEachSubscriber( | 474 void _forEachSubscriber( |
| 467 void action(_StreamSubscriptionImpl<T> subscription)) { | 475 void action(_StreamListener<T> subscription)) { |
| 468 _StreamSubscriptionImpl subscription = _subscriber; | 476 _StreamListener subscription = _subscriber; |
| 469 assert(subscription != null); | 477 assert(subscription != null); |
| 470 _startFiring(); | 478 _startFiring(); |
| 471 action(subscription); | 479 action(subscription); |
| 472 _endFiring(); | 480 _endFiring(); |
| 473 } | 481 } |
| 474 } | 482 } |
| 475 | 483 |
| 476 // ------------------------------------------------------------------- | 484 // ------------------------------------------------------------------- |
| 477 // Default implementation of a stream with subscribers. | 485 // Default implementation of a stream with subscribers. |
| 478 // ------------------------------------------------------------------- | 486 // ------------------------------------------------------------------- |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 507 class _MultiStreamImpl<T> extends _StreamImpl<T> | 515 class _MultiStreamImpl<T> extends _StreamImpl<T> |
| 508 implements _InternalLinkList { | 516 implements _InternalLinkList { |
| 509 // Link list implementation (mixin when possible). | 517 // Link list implementation (mixin when possible). |
| 510 _InternalLink _nextLink; | 518 _InternalLink _nextLink; |
| 511 _InternalLink _previousLink; | 519 _InternalLink _previousLink; |
| 512 | 520 |
| 513 _MultiStreamImpl() { | 521 _MultiStreamImpl() { |
| 514 _nextLink = _previousLink = this; | 522 _nextLink = _previousLink = this; |
| 515 } | 523 } |
| 516 | 524 |
| 525 Stream<T> toMultiSubscriber() => this; | |
| 526 | |
| 517 // ------------------------------------------------------------------ | 527 // ------------------------------------------------------------------ |
| 518 // Helper functions that can be overridden in subclasses. | 528 // Helper functions that can be overridden in subclasses. |
| 519 | 529 |
| 520 /** Whether there are currently any subscribers on this [Stream]. */ | 530 /** Whether there are currently any subscribers on this [Stream]. */ |
| 521 bool get _hasSubscribers => !_InternalLinkList.isEmpty(this); | 531 bool get _hasSubscribers => !_InternalLinkList.isEmpty(this); |
| 522 | 532 |
| 523 /** | 533 /** |
| 524 * Create the new subscription object. | 534 * Create the new subscription object. |
| 525 */ | 535 */ |
| 526 _StreamListener<T> _createSubscription( | 536 _StreamListener<T> _createSubscription( |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1008 if (_isComplete) { | 1018 if (_isComplete) { |
| 1009 throw new StateError("Subscription has been canceled."); | 1019 throw new StateError("Subscription has been canceled."); |
| 1010 } | 1020 } |
| 1011 if (_timer != null) { | 1021 if (_timer != null) { |
| 1012 _timer.cancel(); | 1022 _timer.cancel(); |
| 1013 _timer = null; | 1023 _timer = null; |
| 1014 } | 1024 } |
| 1015 _pauseCount = 0; | 1025 _pauseCount = 0; |
| 1016 } | 1026 } |
| 1017 } | 1027 } |
| OLD | NEW |