applyWithChanges method

({DiagramChangeSet changes, DiagramEditorState state}) applyWithChanges(
  1. DiagramEditorState state
)

Applies every step and reports the element changes they made.

Consecutive element steps share one batch, so the result carries direct change evidence. A document replacement adds a derivation hop; the changes stay incremental while every hop is proven and otherwise fall back to a complete comparison.

Implementation

({DiagramEditorState state, DiagramChangeSet changes}) applyWithChanges(
  DiagramEditorState state,
) {
  final before = state.document;
  var document = before;
  final hops = <DiagramDocument>[];
  DiagramDocumentBatch? batch;
  void flush() {
    if (batch == null) return;
    document = batch!.build();
    batch = null;
    hops.add(document);
  }

  for (final step in steps) {
    if (step is _BatchStep) {
      step.applyTo(batch ??= DiagramDocumentBatch(document));
    } else {
      flush();
      document = step.apply(document);
      hops.add(document);
    }
  }
  flush();
  final proven = hops.isEmpty
      ? DiagramChangeSet.empty
      : DiagramChangeSet.proven(
          before,
          document,
          through: hops.sublist(0, hops.length - 1),
        );
  assert(
    proven != null ||
        steps.any((step) => step is! _BatchStep) ||
        before.elementsById.length != before.elements.length,
    'Element steps lost incremental change evidence for "$label".',
  );
  return (
    state: state.copyWith(
      document: document,
      selection: selectionAfter ?? state.selection,
    ),
    changes: proven ?? DiagramChangeSet(before, document),
  );
}