bindRepeats function

void bindRepeats(
  1. SceneDocument doc
)

Rebuild the repeat closures of a document that was READ — parsed from source, or decoded from JSON — rather than compiled.

A compiled scene's binding is the closure the file wrote. A read one has only what the reader could record: which parameter the items came from, and which property of which cell reads which field (SceneNode.bindings, an ItemRef). This turns that back into the same closure, so there is one way to draw a repeat and not two.

Safe to call again whenever the items change or the tree is restored — it rebinds rather than accumulating, and a closure that outlived its node is exactly what a restore leaves behind.

Implementation

void bindRepeats(SceneDocument doc) {
  for (var (node, _) in doc.walk()) {
    if (node is! FrameNode) continue;
    var source = node.repeated?.source;
    if (source == null || source.isEmpty) continue;
    var items = doc.itemsOf(source);
    node.repeated = SceneRepeat(
      items: items,
      source: source,
      // Read off the frame's LIVE cells, every time. They are not a
      // template beside the first row — they ARE the first row, so editing
      // one has to change every row and not just the one on screen.
      row: (item) => [
        for (var cell in node.children)
          applySceneItem(deepCopyNode(cell), source, item! as SceneItem),
      ],
    );
    // Which makes the first item's values belong ON those cells, written in
    // place so the objects the editor selected and the motion writes to are
    // the same ones afterwards.
    if (items.isNotEmpty) {
      for (var cell in node.children) {
        applySceneItem(cell, source, items.first);
      }
    }
  }
}