Struct redo::RedoStack [] [src]

pub struct RedoStack<'a, T> { /* fields omitted */ }

Maintains a stack of RedoCmds.

RedoStack uses static dispatch so it can only hold one type of command 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 RedoCmd for PopCmd {
    type Err = ();

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

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

Methods

impl<'a, T> RedoStack<'a, T>
[src]

Creates a new RedoStack.

Examples

let mut stack = RedoStack::new();

Creates a new RedoStack with a limit on how many RedoCmds 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 = RedoStack::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 RedoStack with the specified capacity.

Examples

let mut stack = RedoStack::with_capacity(10);
assert_eq!(stack.capacity(), 10);

Creates a new RedoStack with the specified capacity and limit.

Panics

Panics if limit is 0.

Examples

let mut stack = RedoStack::with_capacity_and_limit(10, 10);
assert_eq!(stack.capacity(), 10);
assert_eq!(stack.limit(), Some(10));

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

Examples

let mut stack = RedoStack::with_limit(10);
assert_eq!(stack.limit(), Some(10));

let mut stack = RedoStack::new();
assert_eq!(stack.limit(), None);

Returns the capacity of the RedoStack.

Examples

let mut stack = RedoStack::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 = RedoStack::new();
let cmd = PopCmd { vec: &mut vec, e: None };

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

Shrinks the capacity of the RedoStack as much as possible.

Examples

let mut vec = vec![1, 2, 3];
let mut stack = RedoStack::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 RedoStack 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 = RedoStack::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 RedoStack does nothing when the state changes.

Examples

let mut vec = vec![1, 2, 3];
let x = Cell::new(0);
let mut stack = RedoStack::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 = RedoStack::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 = RedoStack::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());

impl<'a, T: RedoCmd> RedoStack<'a, T>
[src]

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.

Examples

let mut vec = vec![1, 2, 3];
let mut stack = RedoStack::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 RedoCmd and sets the next RedoCmd as the new active one.

Examples

let mut vec = vec![1, 2, 3];
let mut stack = RedoStack::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 RedoCmd and sets the previous RedoCmd as the new active one.

Examples

let mut vec = vec![1, 2, 3];
let mut stack = RedoStack::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, T: Default> Default for RedoStack<'a, T>
[src]

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

impl<'a, T: Debug> Debug for RedoStack<'a, T>
[src]

Formats the value using the given formatter.