Alec Henninger
Alec Henninger

Reputation: 360

How to add data to a synchronous broadcast StreamController from inside an event listener to that controller's Stream?

In the documentation for StreamController.broadcast():

The controller distributes any events to all currently subscribed listeners at the time when [add], [addError] or [close] is called. It is not allowed to call add, addError, or close before a previous call has returned

I understand the need for this limitation (at least, for synchronous broadcast streams), however I'd like to get around this somehow, as events triggering other events is central to my design goal (I'm open to critique on this design, if relevant).

I have tried a solution that seems to be working, but I'd like to either understand if this solution is flawed or if there is a better one. I am using an intermediary method to add data to a Stream. That method uses a future that completes when a current add call is finished. In this way, when an event listener broadcasts an event, it is "queued" until all of the other handlers for the current event being added are called. This seems to work, but I was honestly surprised it did, and am wondering if any Dart experts can poke holes in it or let me know if there is a better way.

Here is the code:

// Instance field... starts off complete on initialization
Completer _broadcasting = new Completer()..complete();

void broadcast(Event e) {
  _broadcasting.future.then((_) {
    _broadcasting = new Completer();

    _ctrl.add(e);

    _broadcasting.complete();
  });
}

Thanks!

Upvotes: 2

Views: 1046

Answers (1)

Günter Zöchbauer
Günter Zöchbauer

Reputation: 657218

I'm pretty sure this does the same as your example:

void broadcast(Event e) {
    new Future(() => _ctrl.add(e));
  });
}

Instead of synchronously adding to _ctrl it registers a callback on the event queue to do the add. This is executed after the previous sync execution is done, so this should exactly do what you need.

Upvotes: 2

Related Questions