updateChildHandles method

void updateChildHandles({
  1. bool doingLayout = false,
})

Ensures childHandles and childHandleMap are ready to use outside of performLayout, useful for calculating intrinsic sizes.

Implementation

void updateChildHandles({bool doingLayout = false}) {
  if (doingLayout) {
    // We don't care about childHandleMap outside of performLayout
    childHandleMap.clear();
    assert(() {
      debugChildrenNeedingLayout.clear();
      return true;
    }());
  }

  int index = 0;
  int movingIndex = 0;
  RenderObject? child = firstChild;

  // Attempt to recycle existing child handles.
  final top = min<int>(context._children!.length, childHandles.length);
  while (index < top && child != null) {
    final parentData = child.parentData! as ParentDataType;
    var id = parentData.id;

    final oldChild = childHandles[index];
    if (oldChild.id != (id ?? movingIndex) || oldChild.render != child) {
      break;
    }

    // Assign the child an incrementing index if it does not already have one.
    id ??= movingIndex++;

    final handle = childHandles[index++];

    if (doingLayout) {
      assert(() {
        debugChildrenNeedingLayout.add(id!);
        return true;
      }());
      childHandleMap[id] = handle;
      prepareChild(handle);
    }

    child = parentData.nextSibling;
  }

  // Discard child handles that might be old
  for (int i = index; i < childHandles.length; i++) {
    childHandleMap.remove(childHandles[i].id);
  }
  childHandles.length = index;

  // Create new child handles
  while (child != null && index < context._children!.length) {
    final parentData = child.parentData! as ParentDataType;
    // Assign the child an incrementing index if it does not already have one.
    final childContext = context._children![index];
    assert(childContext.renderObject == child);
    _addChildHandle(child, childContext, parentData.id ?? movingIndex++);

    index++;
    child = parentData.nextSibling;
  }

  _indexedChildCount = movingIndex;
}