isNodeRetained method
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);
}