Crate undo [−] [src]
An undo/redo library.
It uses the Command Pattern where the user implements the UndoCmd
trait for each command
and then the commands can be used with the UndoStack
.
The UndoStack
has two different states, clean and dirty. The stack is in a clean state when
there are no more commands that can be redone, otherwise it's in a dirty state. The stack
can be configured to call a given method when this state changes, using the on_clean and
on_dirty methods.
The UndoStack
also supports automatic merging of commands that has the same id.
Example
use std::rc::Rc; use std::cell::RefCell; use undo::{UndoCmd, UndoStack}; /// Pops an element from a vector. #[derive(Clone)] struct PopCmd { vec: Rc<RefCell<Vec<i32>>>, e: Option<i32>, } impl UndoCmd for PopCmd { fn redo(&mut self) { self.e = self.vec.borrow_mut().pop(); } fn undo(&mut self) { self.vec.borrow_mut().push(self.e.unwrap()); self.e = None; } } // We need to use Rc<RefCell> since all commands are going to mutate the vec. let vec = Rc::new(RefCell::new(vec![1, 2, 3])); let mut stack = UndoStack::new() .on_clean(|| println!("This is called when the stack changes from dirty to clean!")) .on_dirty(|| println!("This is called when the stack changes from clean to dirty!")); let cmd = PopCmd { vec: vec.clone(), e: None }; stack.push(cmd.clone()); stack.push(cmd.clone()); stack.push(cmd.clone()); assert!(vec.borrow().is_empty()); stack.undo(); // on_dirty is going to be called here. stack.undo(); stack.undo(); assert_eq!(vec.borrow().len(), 3);
Structs
Uid |
An unique id for an |
UndoGroup |
A collection of |
UndoStack |
|
Traits
UndoCmd |
Every command needs to implement the |