NodeStore<TKey, TData> class

Dense ECS-style storage for the tree's structural state.

Hands out stable integer "nids" (via the embedded NodeIdRegistry) and keeps every structural property in a typed-data array indexed by nid. Reads cost an O(1) array access; writes update the array in place.

All mutators are intentionally low-level: they update the local arrays and propagate the _ancestorsExpandedByNid cache where relevant, but they do not update the visible-order buffer or the visible-subtree-size cache. The owning controller wraps these calls when those side effects are required.

Constructors

NodeStore({void onCapacityGrew(int newCapacity)?})

Properties

ancestorsExpandedByNid → Uint8List
Read-only view of the ancestors-expanded cache.
no setter
capacity → int
Capacity high-water mark (number of nid slots ever allocated, including freed ones in the recycle pool). Per-nid arrays maintained externally must have at least this many slots.
no setter
depthByNid → Int32List
Read-only view of the depth-by-nid array.
no setter
expandedByNid → Uint8List
Read-only view of the expanded-flag array.
no setter
hashCode → int
The hash code for this object.
no setterinherited
nids → NodeIdRegistry<TKey>
Bidirectional key-to-nid registry with free-list recycling. Owned here, and injected into every component that keeps per-nid arrays.
final
onCapacityGrew → void Function(int newCapacity)?
Optional callback fired when _ensureDenseCapacity reallocates the per-nid arrays. The argument is the new capacity, in slots. The controller uses this to grow its own per-nid arrays (the order buffer's reverse index, animation-state mirrors, etc.) in lockstep.
final
onParentChanged ↔ ParentChangedCallback?
Optional observer fired by setParent after the parent write. Mutable so the owner can wire it up after construction (avoiding late-final initialization cycles when the subscriber's late field references this store). See ParentChangedCallback for invocation semantics.
getter/setter pair
parentByNid → Int32List
Read-only view of the parent-nid array. Hot-path consumers (e.g. the visible-subtree-size walker) read directly to skip per-call dispatch. Caller must not mutate.
no setter
rawDataLength → int
Length of the raw data list, for those same checks. Equals capacity whenever the store is consistent.
no setter
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

adopt(TKey key) → ({bool grew, bool isNew, int nid})
Allocates a nid for key (or returns the existing one) and resets every dense per-nid slot to its default. Grows the dense arrays via _ensureDenseCapacity when a fresh slot is appended; the onCapacityGrew callback fires from inside that path.
ancestorsExpandedFast(TKey key) → bool
O(1) "are all ancestors of key expanded?" check. Returns true for roots and unregistered keys.
childListOf(TKey key) → List<TKey>?
Child key list for key, or null when key has no list allocated yet (or is unregistered).
childListOrCreate(TKey key) → List<TKey>
Child key list for key, allocating an empty list when none exists. key must be registered.
clear() → void
Releases all nids and zeros every dense array. The onCapacityGrew callback is not fired; callers that maintain external per-nid arrays are responsible for clearing them too.
collapseAllInRegistry(int? maxDepth, List<TKey> roots, {bool collectFlipped = false}) → List<TKey>?
Clears the expanded flag for every registered node whose depth is less than maxDepth (or for every node when maxDepth is null), then rebuilds the ancestors-expanded cache from roots.
dataOf(TKey key) → TreeNode<TKey, TData>?
Node payload for key, or null when unregistered.
debugAssertConsistent() → void
Debug: verify per-nid data slots match the registry. Throws StateError on inconsistency. Wrapped in assert at call sites so release builds pay nothing.
depthOf(TKey key) → int
Depth of key, or 0 when unregistered.
depthOfNid(int nid) → int
Depth of the live nid nid.
has(TKey key) → bool
Whether key is currently registered.
isExpanded(TKey key) → bool
Whether key is expanded. False for unregistered keys.
keyOf(int nid) → TKey?
Reverse lookup: key for nid, or null if the slot is free.
keyOfUnchecked(int nid) → TKey
Hot-path reverse lookup. nid must refer to a live slot.
nidOf(TKey key) → int?
Nid for key, or null when unregistered.
nidOfOrSentinel(TKey key) → int
Nid for key, or NodeIdRegistry.noNid when unregistered. Hot path.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
parentNidOf(TKey key) → int
Parent nid for key, or kNoParentNid for roots and unregistered keys. Hot path: no allocation, and never throws.
parentOf(TKey key) → TKey?
Parent key for key, or null for roots / unregistered keys.
rawDataAtNid(int nid) → TreeNode<TKey, TData>?
The raw data slot at nid, null for a freed slot. Exists for the debug consistency checks, which need to see freed slots rather than have them filtered out.
rebuildAllAncestorsExpanded(List<TKey> roots) → void
Rebuilds _ancestorsExpandedByNid wholesale in a single pass starting from roots. Used by bulk operations that bypass per-call propagation.
release(TKey key) → int?
Releases the nid associated with key back to the pool and clears every dense slot. Returns the released nid, or null if key wasn't registered.
setChildList(TKey key, List<TKey> list) → void
Replaces the child list for key. key must be registered.
setData(TKey key, TreeNode<TKey, TData> node) → void
Sets the node payload for key. key must be registered.
setDepth(TKey key, int depth) → void
Sets the depth of key. key must be registered.
setExpanded(TKey key, bool expanded, {bool propagate = true}) → void
Sets the expansion flag for key. key must be registered.
setParent(TKey key, TKey? parent) → void
Sets the parent of key to parent, or null for a root, refreshes the cached ancestors-expanded bit for key, and propagates that change through key's subtree.
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited