Hello! I would like to share with you a library that I created for my own needs.
undoredo is a Rust crate for implementing Undo/Redo pattern using deltas, snapshots, or commands on arbitrary data structures.
The library has derive macros for custom data structures, and there is a large number of convenience implementations for standard library and third-party types, such as HashMap, HashSet, BTreeMap, BTreeSet, Vec, StableVec, thunderdome::Arena, rstar::RTree, rstared::RTreed. There is also plenty of documentation.
Links: repository, crate, docs
Example:
use undoredo::{Delta, Recorder, UndoRedo};
#[derive(Delta)]
pub struct Entities {
positions: Recorder<Vec<[f64; 2]>>,
velocities: Recorder<Vec<[f64; 2]>>,
healths: Recorder<Vec<i64>>,
}
fn main() {
let mut entities = Entities {
positions: Recorder::new(Vec::new()),
velocities: Recorder::new(Vec::new()),
healths: Recorder::new(Vec::new()),
};
let mut undoredo: UndoRedo<EntitiesDelta> = UndoRedo::new();
entities.positions.push([0.0, 0.0]);
entities.velocities.push([1.0, 0.0]);
entities.healths.push(100);
undoredo.commit(&mut entities);
undoredo.undo(&mut entities);
undoredo.redo(&mut entities);
}
Here's a demo animation showing Undo/Redo action over dynamically added and subtracted polygons with R-tree spatial indexing. Neither commands nor snapshots are stored, but all edits in history are made of sparse deltas of the polygon container and the associated R-tree:
