Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 0597bbe

Browse files
pavelgjmhevery
authored andcommitted
fix(scope): should allow removing listener during an event
Closes #695
1 parent 265dcf0 commit 0597bbe

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

lib/core/scope.dart

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,9 @@ class ScopeStream extends async.Stream<ScopeEvent> {
740740
final _Streams _streams;
741741
final String _name;
742742
final subscriptions = <ScopeStreamSubscription>[];
743+
bool _firing = false;
744+
List<ScopeStreamSubscription> _toRemove;
745+
743746

744747
ScopeStream(this._streams, this._exceptionHandler, this._name);
745748

@@ -754,16 +757,36 @@ class ScopeStream extends async.Stream<ScopeEvent> {
754757
}
755758

756759
void _fire(ScopeEvent event) {
757-
for (ScopeStreamSubscription subscription in subscriptions) {
758-
try {
759-
subscription._onData(event);
760-
} catch (e, s) {
761-
_exceptionHandler(e, s);
760+
_firing = true;
761+
try {
762+
for (ScopeStreamSubscription subscription in subscriptions) {
763+
try {
764+
subscription._onData(event);
765+
} catch (e, s) {
766+
_exceptionHandler(e, s);
767+
}
768+
}
769+
} finally {
770+
_firing = false;
771+
if (_toRemove != null) {
772+
_toRemove.forEach(_actuallyRemove);
773+
_toRemove = null;
762774
}
763775
}
764776
}
765777

766778
void _remove(ScopeStreamSubscription subscription) {
779+
if (_firing) {
780+
if (_toRemove == null) {
781+
_toRemove = [];
782+
}
783+
_toRemove.add(subscription);
784+
} else {
785+
_actuallyRemove(subscription);
786+
}
787+
}
788+
789+
void _actuallyRemove(ScopeStreamSubscription subscription) {
767790
assert(subscription._scopeStream == this);
768791
if (subscriptions.remove(subscription)) {
769792
if (subscriptions.isEmpty) _streams._addCount(_name, -1);

test/core/scope_spec.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,16 @@ void main() {
656656
expect(args.length).toBe(4);
657657
expect(args).toEqual(['do', 're', 'me', 'fa']);
658658
}));
659+
660+
it('should allow removing listener during an event', inject((RootScope rootScope) {
661+
StreamSubscription subscription;
662+
subscription = rootScope.on('foo').listen((_) {
663+
subscription.cancel();
664+
});
665+
expect(() {
666+
rootScope.broadcast('foo');
667+
}).not.toThrow();
668+
}));
659669
});
660670
});
661671
});

0 commit comments

Comments
 (0)