flushInflateQueue method

void flushInflateQueue()

Flushes the inflate queue so that newly inflated child handles become valid.

We use a queue instead of wrapping performInflatingLayout in a single BuildOwner.buildScope because it cannot be called reentrantly, not doing layout inside of a scope is important because a descendant Viewport, CustomBoxy, LayoutBuilder, etc. will also call it when being laid out.

Should only be called during layout inside performInflatingLayout.

Implementation

void flushInflateQueue() {
  // For some ungodly reason, eliding this call to buildScope if _inflateQueue
  // is empty causes a duplicate GlobalKey exception, only after inflating a
  // child and then moving it to another place in the tree.
  //
  // This is a symptom of us not understanding how GlobalKeys work, and/or a
  // bug in the framework, but we do have exhaustive testing that ensures
  // nothing is broken *too* badly in this regard.
  if (_inflateQueue.isEmpty && !_needsBuildScope) {
    return;
  }
  _needsBuildScope = false;
  _allowSubtreeMutation(() {
    context.owner!.buildScope(context, () {
      for (final child in _inflateQueue) {
        assert(child._widget != null);
        final element = _inflater!(child.id, child._widget!);
        child._render = element.renderObject;
        child._context = element;
      }
      _inflateQueue.clear();
    });
  });
}