Mercurial > repos > IBBoard
view Commands/CommandStack.cs @ 13:6b762694f051
Check size of dictionary so that we don't have to get the values when we've got an empty dictionary
no-open-ticket
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Tue, 06 Jan 2009 19:27:47 +0000 |
parents | 961030992bd2 |
children | 0352fa33ee8f |
line wrap: on
line source
using System; using System.Collections; namespace IBBoard.Commands { /// <summary> /// Summary description for CommandStack. /// </summary> public class CommandStack { private ArrayList commandStack; private int listPos = -1; private int listMax = -1; private int cleanPos; public event MethodInvoker CommandStackUpdated; public CommandStack() { commandStack = new ArrayList(10); cleanPos = -1; } public bool IsDirty() { return listPos!=cleanPos; } public void setCleanMark() { cleanPos = listPos; } public bool IsEmpty() { return listMax == -1; } public bool CanUndo() { return listPos > -1; } public int UndoLength { get { return listPos + 1; } } public int RedoLength { get { return listMax - listPos; } } public bool CanRedo() { return listPos < listMax; } public void Reset() { commandStack.Clear(); listMax = -1; listPos = -1; DoCommandStackUpdated(); } public void Undo() { if (CanUndo()) { ((Command)commandStack[listPos]).Undo(); listPos--; DoCommandStackUpdated(); } else { throw new InvalidOperationException("Cannot undo action on empty command stack"); } } public void Redo() { if (CanRedo()) { ((Command)commandStack[listPos+1]).Redo(); listPos++; DoCommandStackUpdated(); } else { throw new InvalidOperationException("No actions to redo"); } } public bool Execute(Command cmd) { if (cmd.CanExecute()) { if (cmd.Execute()) { //if we can't redo, i.e. there's no commands beyond our current point, add to the end else insert if (!CanRedo()) { commandStack.Add(cmd); listPos++; } else { if (cleanPos>listPos) { cleanPos = -2; } //else overwrite at our current position, setting the listMax value will ignore any commands we could have redone beyond here commandStack[++listPos] = cmd; } listMax = listPos; DoCommandStackUpdated(); return true; } else { throw new InvalidOperationException("Executable command failed to execute"); } } else { return false; } } protected void DoCommandStackUpdated() { if (CommandStackUpdated!=null) { CommandStackUpdated(); } } public Command PeekUndoCommand() { return PeekUndoCommand(1); } public Command PeekUndoCommand(int backCount) { backCount = backCount - 1; if (backCount > -1 && backCount <= listPos) { return (Command)commandStack[listPos-backCount]; } else { return null; } } public Command PeekRedoCommand() { return PeekRedoCommand(1); } public Command PeekRedoCommand(int forwardCount) { if (forwardCount > 0 && listPos+forwardCount <= listMax) { return (Command)commandStack[listPos+forwardCount]; } else { return null; } } } }