Struct undo::UndoStack [] [src]

pub struct UndoStack<'a, E> { /* fields omitted */ }

Maintains a stack of UndoCmds.

UndoStack uses dynamic dispatch so it can hold multiple types of commands at a given time.

It will notice when it's state changes to either dirty or clean, and call the user defined methods set in on_clean and on_dirty. This is useful if you want to trigger some event when the state changes, eg. enabling and disabling buttons in an ui.

The PopCmd given in the examples below is defined as:

#[derive(Clone, Copy)]
struct PopCmd {
    vec: *mut Vec<i32>,
    e: Option<i32>,
}

impl UndoCmd for PopCmd {
    type Err = ();

    fn redo(&mut self) -> undo::Result<()> {
        self.e = unsafe {
            let ref mut vec = *self.vec;
            vec.pop()
        };
        Ok(())
    }

    fn undo(&mut self) -> undo::Result<()> {
        unsafe {
            let ref mut vec = *self.vec;
            let e = self.e.ok_or(())?;
            vec.push(e);
        }
        Ok(())
    }
}

Methods

impl<'a, E: 'a> UndoStack<'a, E>
[src]

Creates a new UndoStack.

Examples

let stack = UndoStack::<()>::new();

Creates a new UndoStack with a limit on how many UndoCmds can be stored in the stack. If this limit is reached it will start popping of commands at the bottom of the stack when pushing new commands on to the stack. No limit is set by default which means it may grow indefinitely.

The stack may remove multiple commands at a time to increase performance.

Panics

Panics if limit is 0.

Examples

let mut vec = vec![1, 2, 3];
let mut stack = UndoStack::with_limit(2);
let cmd = PopCmd { vec: &mut vec, e: None };

stack.push(cmd)?;
stack.push(cmd)?;
stack.push(cmd)?; // Pops off the first cmd.

assert!(vec.is_empty());

stack.undo()?;
stack.undo()?;
stack.undo()?; // Does nothing.

assert_eq!(vec, vec![1, 2]);

Creates a new UndoStack with the specified capacity.

Examples

let stack = UndoStack::<()>::with_capacity(10);
assert_eq!(stack.capacity(), 10);

Creates a new UndoStack with the specified capacity and limit.

Panics

Panics if limit is 0.

Examples

let stack = UndoStack::<()>::with_capacity_and_limit(10, 10);
assert_eq!(stack.capacity(), 10);
assert_eq!(stack.limit(), Some(10));

Returns the limit of the UndoStack, or None if it has no limit.

Examples

let stack = UndoStack::<()>::with_limit(10);
assert_eq!(stack.limit(), Some(10));

let stack = UndoStack::<()>::new();
assert_eq!(stack.limit(), None);

Returns the number of commands the stack can hold without reallocating.

Examples

let stack = UndoStack::<()>::with_capacity(10);
assert_eq!(stack.capacity(), 10);

Reserves capacity for at least additional more commands to be inserted in the given stack. The stack may reserve more space to avoid frequent reallocations.

Panics

Panics if the new capacity overflows usize.

Examples

let mut vec = vec![1, 2, 3];
let mut stack = UndoStack::new();
let cmd = PopCmd { vec: &mut vec, e: None };

stack.push(cmd)?;
stack.reserve(10);
assert!(stack.capacity() >= 11);

Shrinks the capacity of the UndoStack as much as possible.

Examples

let mut vec = vec![1, 2, 3];
let mut stack = UndoStack::with_capacity(10);
let cmd = PopCmd { vec: &mut vec, e: None };

stack.push(cmd)?;
stack.push(cmd)?;
stack.push(cmd)?;

assert_eq!(stack.capacity(), 10);
stack.shrink_to_fit();
assert!(stack.capacity() >= 3);

Sets what should happen if the state changes from dirty to clean. By default the UndoStack does nothing when the state changes.

Note: An empty stack is clean, so the first push will not trigger this method.

Examples

let mut vec = vec![1, 2, 3];
let x = Cell::new(0);
let mut stack = UndoStack::new();
stack.on_clean(|| x.set(1));
let cmd = PopCmd { vec: &mut vec, e: None };

stack.push(cmd)?;
stack.undo()?;
assert_eq!(x.get(), 0);
stack.redo()?;
assert_eq!(x.get(), 1);

Sets what should happen if the state changes from clean to dirty. By default the UndoStack does nothing when the state changes.

Examples

let mut vec = vec![1, 2, 3];
let x = Cell::new(0);
let mut stack = UndoStack::new();
stack.on_dirty(|| x.set(1));
let cmd = PopCmd { vec: &mut vec, e: None };

stack.push(cmd)?;
assert_eq!(x.get(), 0);
stack.undo()?;
assert_eq!(x.get(), 1);

Returns true if the state of the stack is clean, false otherwise.

Examples

let mut vec = vec![1, 2, 3];
let mut stack = UndoStack::new();
let cmd = PopCmd { vec: &mut vec, e: None };

assert!(stack.is_clean()); // An empty stack is always clean.
stack.push(cmd)?;
assert!(stack.is_clean());
stack.undo()?;
assert!(!stack.is_clean());

Returns true if the state of the stack is dirty, false otherwise.

Examples

let mut vec = vec![1, 2, 3];
let mut stack = UndoStack::new();
let cmd = PopCmd { vec: &mut vec, e: None };

assert!(!stack.is_dirty()); // An empty stack is always clean.
stack.push(cmd)?;
assert!(!stack.is_dirty());
stack.undo()?;
assert!(stack.is_dirty());

Pushes cmd to the top of the stack and executes its redo method. This pops off all other commands above the active command from the stack.

If cmds id is equal to the top command on the stack, the two commands are merged.

Examples

let mut vec = vec![1, 2, 3];
let mut stack = UndoStack::new();
let cmd = PopCmd { vec: &mut vec, e: None };

stack.push(cmd)?;
stack.push(cmd)?;
stack.push(cmd)?;

assert!(vec.is_empty());

Calls the redo method for the active UndoCmd and sets the next UndoCmd as the new active one.

Examples

let mut vec = vec![1, 2, 3];
let mut stack = UndoStack::new();
let cmd = PopCmd { vec: &mut vec, e: None };

stack.push(cmd)?;
stack.push(cmd)?;
stack.push(cmd)?;

assert!(vec.is_empty());

stack.undo()?;
stack.undo()?;
stack.undo()?;

assert_eq!(vec, vec![1, 2, 3]);

stack.redo()?;
stack.redo()?;
stack.redo()?;

assert!(vec.is_empty());

Calls the undo method for the active UndoCmd and sets the previous UndoCmd as the new active one.

Examples

let mut vec = vec![1, 2, 3];
let mut stack = UndoStack::new();
let cmd = PopCmd { vec: &mut vec, e: None };

stack.push(cmd)?;
stack.push(cmd)?;
stack.push(cmd)?;

assert!(vec.is_empty());

stack.undo()?;
stack.undo()?;
stack.undo()?;

assert_eq!(vec, vec![1, 2, 3]);

Trait Implementations

impl<'a, E: Default> Default for UndoStack<'a, E>
[src]

Returns the "default value" for a type. Read more

impl<'a, E> Debug for UndoStack<'a, E>
[src]

Formats the value using the given formatter.