propagate function
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);
}