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

Commit 4662d49

Browse files
pavelgjmhevery
authored andcommitted
fix(scope): should allow removing listener during an event
Closes #695
1 parent 9019aa6 commit 4662d49

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
@@ -681,6 +681,16 @@ void main() {
681681
expect(args.length).toBe(4);
682682
expect(args).toEqual(['do', 're', 'me', 'fa']);
683683
}));
684+
685+
it('should allow removing listener during an event', inject((RootScope rootScope) {
686+
StreamSubscription subscription;
687+
subscription = rootScope.on('foo').listen((_) {
688+
subscription.cancel();
689+
});
690+
expect(() {
691+
rootScope.broadcast('foo');
692+
}).not.toThrow();
693+
}));
684694
});
685695
});
686696
});

0 commit comments

Comments
 (0)