UnitResult Undo() { if (globallyRepeatableUnits.Count < 1) { throw new InvalidOperationException("No unit to undo."); } IUndoableUnit undoableUnit = globallyUndoableUnits.Pop(); IInternalUnit repeatableUnit = globallyRepeatableUnits.Pop(); var eventArgs = new CancellableUndoServiceEventArgs(undoableUnit); OnUndoing(eventArgs); if (eventArgs.Cancel) { globallyUndoableUnits.AddLast(undoableUnit); globallyRepeatableUnits.AddLast(repeatableUnit); return(UnitResult.Cancelled); } globallyRedoableUnits.AddLast(undoableUnit); UnitResult result = undoableUnit.Undo(); OnUndone(new UndoServiceEventArgs(undoableUnit)); return(result); }
/// <summary> /// Undoes the execution of a previous <see cref="IUnit"/>. /// </summary> /// <exception cref="InvalidOperationException"> /// Occurs if there are no previously executed units to undo.</exception> public UnitResult Undo(object ownerKey) { if (ownerKey == null) { return(Undo()); } if (!undoableDictionary.TryGetValue(ownerKey, out UnitCollection <IUndoableUnit> undoableUnits)) { throw new InvalidOperationException("No undoable units for the specified owner key."); } IUndoableUnit undoableUnit = undoableUnits.Pop(); if (!repeatableDictionary.TryGetValue(ownerKey, out UnitCollection <IInternalUnit> repeatableUnits)) { throw new InvalidOperationException("No repeatable units for the specified owner key."); } repeatableUnits.RemoveLast(); var eventArgs = new CancellableUndoServiceEventArgs(undoableUnit) { OwnerKey = ownerKey }; OnUndoing(eventArgs); if (eventArgs.Cancel) { undoableUnits.AddLast(undoableUnit); return(UnitResult.Cancelled); } if (!redoableDictionary.TryGetValue(ownerKey, out UnitCollection <IUndoableUnit> redoableUnits)) { redoableUnits = new UnitCollection <IUndoableUnit>(); redoableDictionary[ownerKey] = redoableUnits; } redoableUnits.AddLast(undoableUnit); var result = undoableUnit.Undo(); TrimIfRequired(ownerKey); OnUndone(new UndoServiceEventArgs(undoableUnit)); return(result); }