composeDiagramContent function

List<DiagramContentSegment> composeDiagramContent(
  1. Iterable<ResolvedElement> visible, {
  2. required bool hasBuilder(
    1. String widgetKey
    ),
  3. bool isDynamic(
    1. ResolvedElement element
    )?,
})

Consumes already ordered visible elements, without a second spatial query. Text retains its existing final local pass; global ports/markers/chrome are deliberately outside this content stream.

Implementation

List<DiagramContentSegment> composeDiagramContent(
  Iterable<ResolvedElement> visible, {
  required bool Function(String widgetKey) hasBuilder,
  bool Function(ResolvedElement element)? isDynamic,
}) {
  final result = <DiagramContentSegment>[];
  var pending = <DiagramContentOperation>[];
  void flush() {
    if (pending.isEmpty) return;
    result.add(DiagramContentBand(pending));
    pending = [];
  }

  bool? previousDynamic;
  for (final element in visible) {
    final dynamic = isDynamic?.call(element) ?? false;
    if (previousDynamic != null && previousDynamic != dynamic) flush();
    previousDynamic = dynamic;
    if (element is! ResolvedShape ||
        !element.definition.paintsContent ||
        !element.widgetSlots.any(
          (slot) => hasBuilder(slot.definition.widgetKey),
        )) {
      pending.add(DiagramContentOperation(element));
      continue;
    }
    final mounted = {
      for (final slot in element.widgetSlots)
        if (hasBuilder(slot.definition.widgetKey)) slot.definition.id: slot,
    };
    pending.add(
      DiagramContentOperation(element, phase: DiagramContentPhase.background),
    );
    var layers = <ResolvedShapeLayer>[];
    void flushLayers() {
      if (layers.isEmpty) return;
      pending.add(
        DiagramContentOperation(
          element,
          phase: DiagramContentPhase.layers,
          layers: layers,
        ),
      );
      layers = [];
    }

    final resolvedById = {
      for (final layer in element.layers) layer.definition.id: layer,
    };
    for (final definition in element.definition.layers) {
      if (definition is ShapeWidgetLayerDefinition) {
        final slot = mounted[definition.id];
        if (slot != null) {
          flushLayers();
          flush();
          result.add(DiagramWidgetPlacement(element, slot));
        } else {
          layers.addAll(
            element.layers.where(
              (layer) => layer.widgetSlotId == definition.id,
            ),
          );
        }
      } else {
        layers.add(resolvedById[definition.id]!);
      }
    }
    flushLayers();
    pending.add(
      DiagramContentOperation(element, phase: DiagramContentPhase.border),
    );
    // Match the renderer's text admission. An absent resolved paragraph cannot
    // paint text or its empty-edit placeholder; do not allocate/cache a no-op.
    if (element.text != null) {
      pending.add(
        DiagramContentOperation(
          element,
          phase: DiagramContentPhase.text,
          excludedWidgetSlotIds: mounted.keys,
        ),
      );
    }
  }
  flush();
  return List.unmodifiable(result);
}