ResolvedScene constructor
ResolvedScene({
- required String documentId,
- required int revision,
- int textLayoutRevision = 0,
- String? defaultFontFamily,
- required List<
ResolvedElement> elements, - ResolvedScene? previous,
- FrameCollapseProjection? collapseProjection,
Implementation
factory ResolvedScene({
required String documentId,
required int revision,
int textLayoutRevision = 0,
String? defaultFontFamily,
required List<ResolvedElement> elements,
ResolvedScene? previous,
List<ResolvedElement> hiddenElements = const [],
FrameCollapseProjection? collapseProjection,
}) {
final preservesOrder =
previous != null &&
previous.documentId == documentId &&
previous.elements.length == elements.length &&
Iterable.generate(elements.length).every(
(index) =>
previous._sourceElements[index].id == elements[index].id &&
previous._sourceElements[index].zIndex == elements[index].zIndex,
);
// Compare source order with source order. Paint order may differ whenever
// frames/connectors have different z-values. Retain the permutation only
// after checking every identity and z-value; arbitrary callers cannot assert
// that ordering is unchanged. Equal z-values keep their input order.
final paintOrder = preservesOrder
? previous._paintOrder
: _scenePaintOrder(
elements,
previous?.documentId == documentId ? previous : null,
);
final sorted = DiagramPersistentList<ResolvedElement>.snapshot(
paintOrder.map((index) => elements[index]).toList(),
);
final changedIndexes = preservesOrder
? <int>[
for (var index = 0; index < sorted.length; index += 1)
if (!identical(previous.elements[index], sorted[index])) index,
]
: null;
final sameSources =
previous != null &&
previous._sourceElements.length == elements.length &&
Iterable.generate(elements.length)
.every((i) => previous._sourceElements[i].id == elements[i].id);
final sourceChanges = sameSources
? [
for (var i = 0; i < elements.length; i++)
if (!identical(previous._sourceElements[i], elements[i])) i,
]
: null;
var boundsIndex = sameSources
? previous._boundsIndex
: _SceneBounds.build(elements);
if (sourceChanges != null) {
for (final i in sourceChanges) {
boundsIndex = boundsIndex!.replace(i, elements[i].bounds);
}
}
// Identity/order is stable for ordinary edits. Retain only the index map:
// lookups read this revision's sorted elements, so moving one element does
// not copy an entire ID-to-element map or retain stale resolved objects.
final elementIndexes = preservesOrder
? previous._elementIndexes
: Map<String, int>.unmodifiable({
for (var index = 0; index < sorted.length; index++)
sorted[index].id: index,
});
return ResolvedScene._(
elementIndexes,
DiagramPersistentList<ResolvedElement>.snapshot(elements),
paintOrder,
documentId: documentId,
revision: revision,
textLayoutRevision: textLayoutRevision,
defaultFontFamily: defaultFontFamily,
elements: sorted,
boundsIndex: boundsIndex,
collapseProjection: collapseProjection,
hiddenElements: DiagramPersistentList.snapshot(hiddenElements),
hiddenIndexes: Map.unmodifiable({
for (var i = 0; i < hiddenElements.length; i++) hiddenElements[i].id: i,
}),
spatialIndex: preservesOrder
? DiagramSpatialIndex.incremental(
previous.spatialIndex,
sorted,
changedIndexes: changedIndexes,
)
: previous != null && previous.documentId == documentId
? DiagramSpatialIndex.incremental(
previous.spatialIndex,
sorted,
changedIds: sourceChanges?.map((i) => elements[i].id),
)
: DiagramSpatialIndex(sorted),
);
}