notify method
void
notify()
Notifies all listeners of a change.
Implementation
void notify() {
if (_disposed) return;
// Ultra-fast path: Single listener + no batching/propagation active
if (_singleListener != null &&
_setListeners == null &&
_LevitReactiveCore._fastPath) {
if (LevitReactiveMiddleware.hasErrorMiddlewares) {
try {
_singleListener!();
} catch (e, s) {
LevitStateMiddlewareChain.applyOnReactiveError(
e, s, this is LxReactive ? this as LxReactive : null);
}
} else {
_singleListener!();
}
return;
}
// 0. Handle Async Batching
if (_LevitReactiveCore._asyncZoneDepth > 0) {
final asyncBatch = Zone.current[_LevitReactiveCore._batchZoneKey];
if (asyncBatch is Set<LevitReactiveNotifier>) {
asyncBatch.add(this);
return;
}
}
// 1. Handle Sync Batching
if (_LevitReactiveCore.isBatching) {
if (!_isPendingSyncBatch) {
_isPendingSyncBatch = true;
_LevitReactiveCore._batchedNotifiers.add(this);
}
return;
}
// 2. Handle Iterative Propagation (Queueing) with deduplication
// This is critical for diamond dependencies: when A->B and A->C both
// notify D, we should only process D once.
if (_LevitReactiveCore._isPropagating) {
if (!_isPendingPropagate) {
_isPendingPropagate = true;
_LevitReactiveCore._propagationQueue.add(this);
}
return;
}
// 3. Start Propagation Cycle
_LevitReactiveCore._isPropagating = true;
_LevitReactiveCore._updateFastPath();
try {
_notifyListeners();
if (_LevitReactiveCore._propagationQueue.isNotEmpty) {
var i = 0;
while (i < _LevitReactiveCore._propagationQueue.length) {
final notifier = _LevitReactiveCore._propagationQueue[i++];
notifier._isPendingPropagate = false; // Clear before processing
notifier._notifyListeners();
}
}
} finally {
_LevitReactiveCore._isPropagating = false;
_LevitReactiveCore._updateFastPath();
if (_LevitReactiveCore._propagationQueue.isNotEmpty) {
// Clear flags for any remaining items (safety)
for (final n in _LevitReactiveCore._propagationQueue) {
n._isPendingPropagate = false;
}
_LevitReactiveCore._propagationQueue.clear();
}
}
}