Struct redo::RedoStack
[−]
[src]
pub struct RedoStack<'a, T> { /* fields omitted */ }
Maintains a stack of RedoCmd
s.
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]
fn new() -> Self
fn with_limit(limit: usize) -> Self
Creates a new RedoStack
with a limit on how many RedoCmd
s 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]);
fn with_capacity(capacity: usize) -> Self
Creates a new RedoStack
with the specified capacity.
Examples
let mut stack = RedoStack::with_capacity(10); assert_eq!(stack.capacity(), 10);
fn with_capacity_and_limit(capacity: usize, limit: usize) -> Self
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));
fn limit(&self) -> Option<usize>
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);
fn capacity(&self) -> usize
Returns the capacity of the RedoStack
.
Examples
let mut stack = RedoStack::with_capacity(10); assert_eq!(stack.capacity(), 10);
fn reserve(&mut self, additional: usize)
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);
fn shrink_to_fit(&mut self)
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);
fn on_clean<F>(&mut self, f: F) where F: FnMut() + 'a
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);
fn on_dirty<F>(&mut self, f: F) where F: FnMut() + 'a
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);
fn is_clean(&self) -> bool
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());
fn is_dirty(&self) -> bool
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]
fn push(&mut self, cmd: T) -> Result<T::Err>
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());
fn redo(&mut self) -> Result<T::Err>
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());
fn undo(&mut self) -> Result<T::Err>
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]);