isNodeRetained method

bool isNodeRetained(
  1. TKey id
)

Whether the given node is retained by the current layout — i.e. it is in the cache region, a sticky header, or a phantom-exit ghost mid-slide. Used by the element to decide whether an off-screen child can be evicted. O(1) (Map containsKey + Set lookup), no allocation.

Implementation

bool isNodeRetained(TKey id) {
  // Phantom-exit ghosts: retain past visible-order purge so their
  // slide can finish. Removed from _phantomExitGhosts when their
  // slide settles, after which the next stale eviction will release
  // the render box normally.
  final ghosts = _phantomExitGhosts;
  if (ghosts != null && ghosts.containsKey(id)) return true;
  // Edge-anchor exit ghosts: retain so the parallel ghost paint pass
  // can render them. The row IS in visibleNodes (its structural is
  // still in the tree) but may sit outside the cache region; without
  // explicit retention here, layout admission would evict the child
  // and the ghost paint pass would have nothing to paint.
  final edgeGhosts = _phantomEdgeExits;
  if (edgeGhosts != null && edgeGhosts.containsKey(id)) return true;
  final nid = _controller.nidOf(id);
  if (nid < 0) return false;
  if (nid < _inCacheRegionByNid.length && _inCacheRegionByNid[nid] != 0) {
    return true;
  }
  // Mid-flight FLIP slide: the engine has a live slide entry for this
  // nid (currentDelta != 0 in either axis is the externally-observable
  // proxy — the engine clears entries whose composedY/X both reach 0
  // and the lerp only crosses zero at completion). Retain so paint can
  // continue to render the row at `structural + slideDelta` even when
  // the post-mutation structural Y has moved outside the cache region
  // (e.g. a re-moveTo mid-slide pushed the row far off-screen). Without
  // this, stale-eviction (gated only by `hasActiveAnimations`, which
  // excludes slides — see [TreeController.hasActiveAnimations] doc)
  // would drop the render box mid-slide, leaving the engine ticking a
  // slide for a child that no longer exists, so the row appears stuck
  // / vanishes during its visible transit through the viewport. Once
  // the slide settles (delta=0), this branch falls through and the
  // next eviction releases the box normally.
  if (_controller.getSlideDeltaNid(nid) != 0.0 ||
      _controller.getSlideDeltaXNid(nid) != 0.0) {
    return true;
  }
  return _sticky.isSticky(nid);
}