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();
    }
  }
}