restore method

void restore(
  1. MotionSnapshot state, {
  2. SceneDocument? scene,
})

Write state back. Groups are REVIVED by name and keys by id, the way the scene revives nodes: a bound motion holds group objects and a player holds its writers, and an undo must not detach them. Write state back, re-pointing each group at scene by the name the snapshot recorded.

scene is what makes an undo across a rename work. The scene's own restore revives nodes by name, so a node renamed since the snapshot comes back as a NEW object and a group left holding the old one would animate something nobody is drawing.

Implementation

void restore(MotionSnapshot state, {SceneDocument? scene}) {
  params
    ..clear()
    ..addAll(state._params);
  var live = {for (var g in groups) g.name: g};
  var revived = <AnimateGroup>[];
  for (var snap in state._groups) {
    var into = live[snap.name];
    if (into == null || !identical(into.node, snap.node)) {
      revived.add(snap.copy());
      continue;
    }
    _restoreTracks(into.tracks, snap.tracks);
    revived.add(into);
  }
  if (scene != null) {
    for (var (index, g) in revived.indexed) {
      if (index >= state._targets.length) continue;
      var node = scene.nodeNamed(state._targets[index]);
      if (node != null) g.node = node;
    }
  }
  groups
    ..clear()
    ..addAll(revived);
  // Same mapping in the other direction: the snapshot's arrangement names
  // the snapshot's groups, and what plays has to be the live ones.
  var back = <AnimateGroup, AnimateGroup>{};
  for (var (index, snap) in state._groups.indexed) {
    if (index < revived.length) back[snap] = revived[index];
  }
  timeline = _copyExpr(state._timeline, back);
}