4 using System.Collections.Generic;
7 namespace SiliconStudio.ActionStack
14 private readonly
object lockObject =
new object();
15 private readonly
int capacity;
16 private readonly List<IActionItem> actionItems =
new List<IActionItem>();
23 : this(capacity, null)
34 this.capacity = capacity;
36 if (initialActionsItems != null)
38 foreach (var originalActionItem
in initialActionsItems)
39 actionItems.Add(originalActionItem);
51 public int Capacity {
get {
return capacity; } }
56 public bool CanUndo {
get {
return CurrentIndex > 0; } }
61 public bool CanRedo {
get {
return CurrentIndex < actionItems.Count; } }
81 public event EventHandler<ActionItemsEventArgs<IActionItem>>
Undone;
86 public event EventHandler<ActionItemsEventArgs<IActionItem>>
Redone;
91 protected int CurrentIndex {
get;
private set; }
102 throw new ArgumentNullException(
"item");
104 var items =
new[] { item };
107 OnActionItemsDiscarded(
new DiscardedActionItemsEventArgs<IActionItem>(
ActionItemDiscardType.UndoRedoInProgress, items));
111 InternalAddRange(items);
118 throw new ArgumentNullException(
"items");
120 var cachedItems = items.ToArray();
121 if (cachedItems.Length == 0)
124 InternalAddRange(cachedItems);
131 OnActionItemsCleared();
137 if (markActionsAsSaved)
140 foreach (var action
in actionItems)
142 action.IsSaved = i++ < CurrentIndex;
158 if (CanUndo ==
false)
161 action = actionItems[--CurrentIndex];
165 OnUndone(
new ActionItemsEventArgs<IActionItem>(action));
183 if (CanRedo ==
false)
186 action = actionItems[CurrentIndex++];
189 OnRedone(
new ActionItemsEventArgs<IActionItem>(action));
204 var handler = ActionItemsDiscarded;
215 var handler = ActionItemsAdded;
225 var handler = ActionItemsCleared;
234 protected virtual void OnUndone(ActionItemsEventArgs<IActionItem> e)
236 var handler = Undone;
245 protected virtual void OnRedone(ActionItemsEventArgs<IActionItem> e)
247 var handler = Redone;
252 private void InternalClear()
258 OnActionItemsCleared();
262 private void InternalAddRange(IActionItem[] items)
267 UnsafeDisbranchedCleanup();
270 foreach (var item
in items)
271 actionItems.Add(item);
274 IActionItem[] discarded = null;
275 if (capacity >= 0 && actionItems.Count > capacity)
278 discarded = actionItems
279 .Take(actionItems.Count - capacity)
281 int itemsToRemove = actionItems.Count - capacity;
282 for (
int i = 0; i < itemsToRemove; ++i)
284 actionItems[0].Freeze();
285 actionItems.RemoveAt(0);
292 if (discarded != null)
294 OnActionItemsDiscarded(
new DiscardedActionItemsEventArgs<IActionItem>(
301 if (capacity >= 0 && items.Length > capacity)
302 added = items.Skip(items.Length - capacity).ToArray();
304 OnActionItemsAdded(
new ActionItemsEventArgs<IActionItem>(added));
308 private void UnsafeDisbranchedCleanup()
310 if (CurrentIndex < 0)
313 var discarded = actionItems.ToArray();
317 OnActionItemsDiscarded(
new DiscardedActionItemsEventArgs<IActionItem>(
ActionItemDiscardType.Disbranched, discarded));
319 else if (actionItems.Count - CurrentIndex > 0)
323 var discardedItems = actionItems.Skip(CurrentIndex).Take(actionItems.Count - CurrentIndex).ToArray();
326 int itemsToRemove = actionItems.Count - CurrentIndex;
327 for (
int i = 0; i < itemsToRemove; ++i)
328 actionItems.RemoveAt(CurrentIndex);
332 OnActionItemsDiscarded(
new DiscardedActionItemsEventArgs<IActionItem>(
ActionItemDiscardType.Disbranched, discardedItems));
336 private void ResetIndexOnTop()
338 CurrentIndex = actionItems.Count;
EventHandler< ActionItemsEventArgs< IActionItem > > ActionItemsAdded
Raised whenever action items are added to the stack.
EventHandler< ActionItemsEventArgs< IActionItem > > Redone
Raised when an action item is redone.
ActionItemDiscardType
This enum describes how an action item is being discarded when the ActionStack.ActionItemsDiscarded e...
EventHandler ActionItemsCleared
Raised whenever the action stack is cleared.
EventHandler< DiscardedActionItemsEventArgs< IActionItem > > ActionItemsDiscarded
Raised whenever action items are discarded from the stack.
Represents a save point marker in the undo/redo action items stack.
void Clear()
Clears the action stack.
static readonly SavePoint Empty
Empty save point.
virtual void Add(IActionItem item)
Adds an action item to the stack. Discards any action item that is currently undone. The action item to add to the stack.
ActionStack(int capacity)
Initializes a new instance of the ActionStack class with the given capacity.
EventHandler< ActionItemsEventArgs< IActionItem > > Undone
Raised when an action item is undone.
virtual void OnActionItemsDiscarded(DiscardedActionItemsEventArgs< IActionItem > e)
Invoked whenever action items are discarded from the stack.
void AddRange(IEnumerable< IActionItem > items)
Adds multiple action items on the stack. Discards any action item that is currently undone...
Base interface for action items.
ActionStack(int capacity, IEnumerable< IActionItem > initialActionsItems)
Initializes a new instance of the ActionStack class with the given capacity and existing action items...
virtual SavePoint CreateSavePoint(bool markActionsAsSaved)
Creates a save point at the current index of the action stack. Indicate whether to set the IActionIte...
virtual void OnRedone(ActionItemsEventArgs< IActionItem > e)
Invoked Raised when an action item is redone.
Base interface to for an action stack.
virtual bool Redo()
Redoes the first action item that is currently undone. True if an action could be redone...
virtual void OnActionItemsCleared()
Invoked whenever the action stack is cleared.
virtual void OnUndone(ActionItemsEventArgs< IActionItem > e)
Invoked Raised when an action item is undone.
Item discarded because an undo/redo operation is currently in progress.
This class represents a thread-safe stack of action items that can be undone/redone.
virtual bool Undo()
Undoes the last action item that is currently done. True if an action could be undone, False otherwise.
virtual void OnActionItemsAdded(ActionItemsEventArgs< IActionItem > e)
Invoked whenever action items are added to the stack.