applyWithChanges method
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),
);
}