propagate function

void propagate(
  1. Link theLink,
  2. bool innerWrite
)

Propagates changes through the reactive graph.

Walks subscriber links starting at theLink and marks affected nodes pending. When innerWrite is true, writes are treated as occurring during an effect run and subscribers may receive ReactiveFlags.recursed.

Implementation

void propagate(Link theLink, bool innerWrite) {
  Link? link = theLink;

  var next = link.nextSub;
  Stack<Link?>? stack;

  top:
  do {
    final sub = link!.sub;
    var flags = sub.flags;

    if (flags &
            (ReactiveFlags.recursedCheck |
                ReactiveFlags.recursed |
                ReactiveFlags.dirty |
                ReactiveFlags.pending) ==
        0) {
      sub.flags = flags | ReactiveFlags.pending;
      if (innerWrite) {
        sub.flags |= ReactiveFlags.recursed;
      }
    } else if (flags & (ReactiveFlags.recursedCheck | ReactiveFlags.recursed) ==
        0) {
      flags = ReactiveFlags.none;
    } else if (flags & (ReactiveFlags.recursedCheck) == 0) {
      sub.flags = (flags & ~ReactiveFlags.recursed) | (ReactiveFlags.pending);
    } else if (flags & (ReactiveFlags.dirty | ReactiveFlags.pending) == 0 &&
        isValidLink(link, sub)) {
      sub.flags = flags | (ReactiveFlags.recursed | ReactiveFlags.pending);

      flags &= ReactiveFlags.mutable;
    } else {
      flags = ReactiveFlags.none;
    }

    if (flags & (ReactiveFlags.watching) != 0) {
      (sub as EffectNode).notifyEffect();
    }

    if (flags & (ReactiveFlags.mutable) != 0) {
      final subSubs = sub.subs;
      if (subSubs != null) {
        final nextSub = (link = subSubs).nextSub;
        if (nextSub != null) {
          stack = Stack(value: next, prev: stack);
          next = nextSub;
        }
        continue;
      }
    }

    if ((link = next) != null) {
      next = link!.nextSub;
      continue;
    }

    while (stack != null) {
      link = stack.value;
      stack = stack.prev;
      if (link != null) {
        next = link.nextSub;
        continue top;
      }
    }

    break;
  } while (true);
}