checkDirty method
Checks if a node is dirty by examining its dependencies.
Traverses sub's dependencies starting from link to determine if
any have changed. If a dependency is dirty or pending, recursively
checks its dependencies.
This pull-based checking ensures values are only recomputed when actually needed, avoiding unnecessary calculations.
Returns true if any dependency has changed, requiring sub to update,
or false if all dependencies are clean.
Implementation
@pragma('vm:align-loops')
bool checkDirty(Link link, ReactiveNode sub) {
Stack<Link>? stack;
int checkDepth = 0;
bool dirty = false;
top:
do {
final dep = link.dep, flags = dep.flags;
if ((sub.flags & ReactiveFlags.dirty) != ReactiveFlags.none) {
dirty = true;
} else if ((flags &
17 /*(ReactiveFlags.mutable | ReactiveFlags.dirty)*/) ==
17 /*(ReactiveFlags.mutable | ReactiveFlags.dirty)*/) {
if (update(dep)) {
final subs = dep.subs!;
if (subs.nextSub != null) {
shallowPropagate(subs);
}
dirty = true;
}
} else if ((flags &
33 /*(ReactiveFlags.mutable | ReactiveFlags.pending)*/) ==
33 /*(ReactiveFlags.mutable | ReactiveFlags.pending)*/) {
if (link.nextSub != null || link.prevSub != null) {
stack = Stack(value: link, prev: stack);
}
link = dep.deps!;
sub = dep;
++checkDepth;
continue;
}
if (!dirty) {
final nextDep = link.nextDep;
if (nextDep != null) {
link = nextDep;
continue;
}
}
while ((checkDepth--) > 0) {
final firstSub = sub.subs!, hasMultipleSubs = firstSub.nextSub != null;
if (hasMultipleSubs) {
link = stack!.value;
stack = stack.prev;
} else {
link = firstSub;
}
if (dirty) {
if (update(sub)) {
if (hasMultipleSubs) {
shallowPropagate(firstSub);
}
sub = link.sub;
continue;
}
dirty = false;
} else {
sub.flags &= -33 /*~ReactiveFlags.pending*/;
}
sub = link.sub;
final nextDep = link.nextDep;
if (nextDep != null) {
link = nextDep;
continue top;
}
}
return dirty;
} while (true);
}