RenderObjectData.capture constructor

RenderObjectData.capture(
  1. RenderObject renderObject
)

Captures the RenderObjectData for the given renderObject and its children.

Implementation

factory RenderObjectData.capture(RenderObject renderObject) {
  // Note on performance: If this function becomes a bottleneck, we can
  // consider capturing geometry data only for render objects we are going
  // to display. For all others, we would not need to calculate the transform
  // and paint bounds in global coordinates.

  Timeline.startSync('RenderObjectData.capture', arguments: <String, Object?>{
    'renderObject': renderObject.runtimeType.toString(),
  });

  // The RenderObjects for which to capture data, mapped to the data of their
  // parents.
  final workingSet = HashMap<RenderObject, RenderObjectData>();

  RenderObjectData createData(
    RenderObject renderObject,
    RenderObjectData? parent,
  ) {
    var transform = renderObject.getTransformTo(parent?._renderObject);
    if (parent != null) {
      transform = (parent._transform * transform) as Matrix4;
    }

    final data = RenderObjectData(
      type: renderObject.runtimeType.toString(),
      paintBounds:
          MatrixUtils.transformRect(transform, renderObject.paintBounds),
    )
      .._renderObject = renderObject
      .._transform = transform;

    if (parent != null) {
      parent.addChild(data);
    }

    renderObject.visitChildren((child) {
      workingSet[child] = data;
    });

    return data;
  }

  final rootData = createData(renderObject, null);

  while (workingSet.isNotEmpty) {
    final renderObject = workingSet.keys.first;
    final parentData = workingSet.remove(renderObject);
    createData(renderObject, parentData);
  }

  Timeline.finishSync();

  return rootData;
}