/// <summary> /// Begins a complex memento for grouping. /// </summary> /// <remarks> /// From the time this method is called till the time /// <see cref=" EndCompoundDo()"/> is called, all the <i>DO</i> actions (by calling /// <see cref="Do(IMemento<T>)"/>) are added into a temporary /// <see cref="CompoundMemento<T>"/> and this memnto will be pushed into the undo /// stack when <see cref="EndCompoundDo()"/> is called. /// <br/> /// If this method is called, it's programmer's responsibility to call <see cref="EndCompoundDo()"/>, /// or else this history will be in incorrect state and stop functioning. /// <br/> /// Sample Code: /// <br/> /// <code> /// // Version 1: Without grouping /// UndoRedoHistory<Foo> history = new UndoRedoHistory<Foo>(); /// history.Clear(); /// history.Do(memento1); /// history.Do(memento2); /// history.Do(memento3); /// // history has 3 actions on its undo stack. /// /// // Version 1: With grouping /// history.BeginCompoundDo(); // starting grouping /// history.Do(memento1); /// history.Do(memento2); /// history.Do(memento3); /// hisotry.EndCompoundDo(); // must be called to finish grouping /// // history has only 1 action on its undo stack instead 3. /// // This single undo action will undo all actions memorized by memento 1 to 3. /// </code> /// </remarks> /// <exception cref="InvalidOperationException"> /// Thrown if previous grouping wasn't ended. See <see cref="EndCompoundDo"/>. /// </exception> /// <seealso cref="EndCompoundDo()"/> public void BeginCompoundDo() { if (tempMemento != null) { throw new InvalidOperationException("Previous complex memento wasn't commited."); } tempMemento = new CompoundMemento <T>(); }
/// <summary> /// Ends grouping by pushing the complext memento created by <see cref="BeginCompoundDo"/> into the undo stack. /// </summary> /// <remarks> /// For details on how <i>grouping</i> works, see <see cref="BeginCompoundDo"/>. /// </remarks> /// <exception cref="InvalidOperationException"> /// Thrown if grouping wasn't started. See <see cref="BeginCompoundDo"/>. /// </exception>/// <seealso cref="BeginCompoundDo()"/> public void EndCompoundDo() { if (tempMemento == null) { throw new InvalidOperationException("Ending a non-existing complex memento"); } _Do(tempMemento); tempMemento = null; }
/// <summary> /// Implicity implememntation of <see cref="IMemento<T>.Restore(T)"/>, which returns <see cref="CompoundMemento<T>"/> /// </summary> /// <param name="target"></param> /// <returns></returns> public CompoundMemento <T> Restore(T target) { CompoundMemento <T> inverse = new CompoundMemento <T>(); // Starts from the last action for (int i = mementos.Count - 1; i >= 0; i--) { inverse.Add(mementos[i].Restore(target)); } return(inverse); }