apply method
Applies the change and returns its inverse plus the handles it touched. Must either complete fully or leave the target unmutated.
Implementation
@override
CommandResult apply(CommandTarget target) {
final r = inner.apply(target);
final inverses = <DraftCommand>[];
final written = <Handle>{};
var stamps = 0;
try {
for (final h in r.touched) {
final DraftCommand derived;
if (_stampFor(target, h) case final stamp?) {
derived = stamp;
stamps++;
} else {
continue;
}
final result = derived.apply(target);
inverses.add(result.inverse);
written.addAll(result.touched);
}
} catch (_) {
// All or nothing: the stamps written so far, then the edit itself.
for (final inverse in inverses.reversed) {
inverse.apply(target);
}
r.inverse.apply(target);
rethrow;
}
_stamped = stamps > 0;
if (inverses.isEmpty) return r;
// A replay with the edit's own authority: undo and redo need exactly
// what the edit needed, not the stamps' `geometry` (review R-5).
return CommandResult(
inverse: ParametricReplay(
CompoundCommand([...inverses.reversed, r.inverse], label: label),
inner.capabilities),
touched: {...r.touched, ...written},
);
}