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

Commit

Permalink
fix(scope): should allow removing listener during an event
Browse files Browse the repository at this point in the history
Closes #695
  • Loading branch information
pavelgj authored and mhevery committed Mar 13, 2014
1 parent 9019aa6 commit 4662d49
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
33 changes: 28 additions & 5 deletions lib/core/scope.dart
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,9 @@ class ScopeStream extends async.Stream<ScopeEvent> {
final _Streams _streams;
final String _name;
final subscriptions = <ScopeStreamSubscription>[];
bool _firing = false;
List<ScopeStreamSubscription> _toRemove;


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

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

void _fire(ScopeEvent event) {
for (ScopeStreamSubscription subscription in subscriptions) {
try {
subscription._onData(event);
} catch (e, s) {
_exceptionHandler(e, s);
_firing = true;
try {
for (ScopeStreamSubscription subscription in subscriptions) {
try {
subscription._onData(event);
} catch (e, s) {
_exceptionHandler(e, s);
}
}
} finally {
_firing = false;
if (_toRemove != null) {
_toRemove.forEach(_actuallyRemove);
_toRemove = null;
}
}
}

void _remove(ScopeStreamSubscription subscription) {
if (_firing) {
if (_toRemove == null) {
_toRemove = [];
}
_toRemove.add(subscription);
} else {
_actuallyRemove(subscription);
}
}

void _actuallyRemove(ScopeStreamSubscription subscription) {
assert(subscription._scopeStream == this);
if (subscriptions.remove(subscription)) {
if (subscriptions.isEmpty) _streams._addCount(_name, -1);
Expand Down
10 changes: 10 additions & 0 deletions test/core/scope_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,16 @@ void main() {
expect(args.length).toBe(4);
expect(args).toEqual(['do', 're', 'me', 'fa']);
}));

it('should allow removing listener during an event', inject((RootScope rootScope) {
StreamSubscription subscription;
subscription = rootScope.on('foo').listen((_) {
subscription.cancel();
});
expect(() {
rootScope.broadcast('foo');
}).not.toThrow();
}));
});
});
});
Expand Down

0 comments on commit 4662d49

Please sign in to comment.