checkDirty function

bool checkDirty(
  1. Link theLink,
  2. ReactiveNode sub
)

Checks if a node is dirty and needs updating.

Parameters:

  • theLink: The link to check
  • sub: The subscriber node

Returns: true if the node is dirty and needs updating

Example:

final effectNode = CustomEffectNode();
final dirty = checkDirty(effectNode.deps!, effectNode);

Implementation

bool checkDirty(Link theLink, ReactiveNode sub) {
  Link? link = theLink;
  Stack<Link?>? stack;
  var checkDepth = 0;
  var dirty = false;

  top:
  // allow do-while loop
  // ignore: literal_only_boolean_expressions
  do {
    final dep = link!.dep;
    final flags = dep.flags;

    if (sub.flags & (ReactiveFlags.dirty) == (ReactiveFlags.dirty)) {
      dirty = true;
    } else if (flags & (ReactiveFlags.mutable | ReactiveFlags.dirty) ==
        (ReactiveFlags.mutable | ReactiveFlags.dirty)) {
      if (updateNode(dep)) {
        final subs = dep.subs!;
        if (subs.nextSub != null) {
          shallowPropagate(subs);
        }
        dirty = true;
      }
    } else if (flags & (ReactiveFlags.mutable | ReactiveFlags.pending) ==
        (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!;
      final hasMultipleSubs = firstSub.nextSub != null;
      if (hasMultipleSubs) {
        link = stack!.value;
        stack = stack.prev;
      } else {
        link = firstSub;
      }
      if (dirty) {
        if (updateNode(sub)) {
          if (hasMultipleSubs) {
            shallowPropagate(firstSub);
          }
          sub = link!.sub;
          continue;
        }
        dirty = false;
      } else {
        sub.flags &= ~ReactiveFlags.pending;
      }
      sub = link!.sub;
      final nextDep = link.nextDep;
      if (nextDep != null) {
        link = nextDep;
        continue top;
      }
    }

    return dirty;
  } while (true);
}