|
|
|
|
|
|
: base(controller) { |
|
|
|
} |
|
|
|
|
|
|
|
bool isBroadcast { |
|
|
|
public override bool isBroadcast { |
|
|
|
get { return true; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
// The controller._recordPause doesn't do anything for a broadcast controller,
|
|
|
|
// so we don't bother calling it.
|
|
|
|
void _onPause() { |
|
|
|
protected override void _onPause() { |
|
|
|
void _onResume() { |
|
|
|
protected override void _onResume() { |
|
|
|
} |
|
|
|
|
|
|
|
// _onCancel is inherited.
|
|
|
|
|
|
|
protected const int _STATE_CLOSED = 4; |
|
|
|
const int _STATE_ADDSTREAM = 8; |
|
|
|
|
|
|
|
_stream.ControllerCallback onListen; |
|
|
|
_stream.ControllerCancelCallback onCancel; |
|
|
|
public override _stream.ControllerCallback onListen { get; set; } |
|
|
|
public override _stream.ControllerCancelCallback onCancel { get; set; } |
|
|
|
|
|
|
|
// State of the controller.
|
|
|
|
internal int _state; |
|
|
|
|
|
|
_state = _STATE_INITIAL; |
|
|
|
} |
|
|
|
|
|
|
|
_stream.ControllerCallback onPause { |
|
|
|
public override _stream.ControllerCallback onPause { |
|
|
|
get { |
|
|
|
throw new Exception( |
|
|
|
"Broadcast stream controllers do not support pause callbacks"); |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
_stream.ControllerCallback onResume { |
|
|
|
public override _stream.ControllerCallback onResume { |
|
|
|
get { |
|
|
|
throw new Exception( |
|
|
|
"Broadcast stream controllers do not support pause callbacks"); |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/** Whether an event is being fired (sent to some, but not all, listeners). */ |
|
|
|
internal bool _isFiring { |
|
|
|
internal virtual bool _isFiring { |
|
|
|
bool _isAddingStream { |
|
|
|
internal bool _isAddingStream { |
|
|
|
internal bool _mayAddEvent { |
|
|
|
internal virtual bool _mayAddEvent { |
|
|
|
get => (_state < _STATE_CLOSED); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Linked list helpers
|
|
|
|
|
|
|
|
internal bool _isEmpty { |
|
|
|
internal virtual bool _isEmpty { |
|
|
|
get { return _firstSubscription == null; } |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
return subscription; |
|
|
|
} |
|
|
|
|
|
|
|
Future _recordCancel(StreamSubscription<T> sub) { |
|
|
|
public override Future _recordCancel(StreamSubscription<T> sub) { |
|
|
|
_BroadcastSubscription<T> subscription = (_BroadcastSubscription<T>) sub; |
|
|
|
// If already removed by the stream, don't remove it again.
|
|
|
|
if (Equals(subscription._next, subscription)) return null; |
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
void _recordPause(StreamSubscription<T> subscription) { |
|
|
|
public override void _recordPause(StreamSubscription<T> subscription) { |
|
|
|
void _recordResume(StreamSubscription<T> subscription) { |
|
|
|
public override void _recordResume(StreamSubscription<T> subscription) { |
|
|
|
} |
|
|
|
|
|
|
|
// EventSink interface.
|
|
|
|
|
|
|
return doneFuture; |
|
|
|
} |
|
|
|
|
|
|
|
Future done { |
|
|
|
public override Future done { |
|
|
|
get { return _ensureDoneFuture(); } |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
internal void _callOnCancel() { |
|
|
|
internal virtual void _callOnCancel() { |
|
|
|
D.assert(_isEmpty); |
|
|
|
if (isClosed && _doneFuture._mayComplete) { |
|
|
|
// When closed, _doneFuture is not null.
|
|
|
|
|
|
|
|
|
|
|
// EventDispatch interface.
|
|
|
|
|
|
|
|
bool _mayAddEvent { |
|
|
|
internal override bool _mayAddEvent { |
|
|
|
get { return base._mayAddEvent && !_isFiring; } |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
_pending.add(evt); |
|
|
|
} |
|
|
|
|
|
|
|
void add(T data) { |
|
|
|
public override void add(T data) { |
|
|
|
if (!isClosed && _isFiring) { |
|
|
|
_addPendingEvent(new _DelayedData<T>(data)); |
|
|
|
return; |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void addError(object error, string stackTrace) { |
|
|
|
public override void addError(object error, string stackTrace) { |
|
|
|
// ArgumentError.checkNotNull(error, "error");
|
|
|
|
stackTrace = stackTrace ?? AsyncError.defaultStackTrace(error); |
|
|
|
if (!isClosed && _isFiring) { |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Future close() { |
|
|
|
public override Future close() { |
|
|
|
if (!isClosed && _isFiring) { |
|
|
|
_addPendingEvent(new _DelayedDone<T>()); |
|
|
|
_state |= _BroadcastStreamController<T>._STATE_CLOSED; |
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
void _callOnCancel() { |
|
|
|
internal override void _callOnCancel() { |
|
|
|
if (_hasPending) { |
|
|
|
_pending.clear(); |
|
|
|
_pending = null; |
|
|
|