UndoRedoStack์ ์คํ ์ทจ์์ ๋ค์ ์คํ์ ํ๊ธฐ ์ํด ๊ตฌํํ ๋์์ธ ํจํด์ด์์.
๋ค์ํ ์ํํธ์จ์ด์์ ๊ฐ์์ ๋ฐฉ๋ฒ์ผ๋ก ๊ตฌํ ๋์ด ์์ง๋ง, ์ ๋ ์กฐ๊ธ ๊ฐ๋จํ๊ฒ ํ์ํ ๊ธฐ๋ฅ๋ง ๊ตฌํํ์ฌ ๊ฐ ๊ธฐ๋ฅ๋ค์ ์ก์
(Action)์ผ๋ก ๋๋์ด ๋ณด์์ด์.
๊ทธ๋ฆฌ๊ณ ๊ฐ Action์ ๋ฌถ์ ActionBlock ํด๋์ค๋ฅผ ๋ง๋ค์ด Sequence๋ฅผ ๊ตฌํํ๋๋ก ํ์ด์.
์ด๋ฅผ ํตํด ๋ณต์กํ Undo ๋๋ Redo ์์
์ ํ๋ฒ์ ์ฒ๋ฆฌ ํ ์ ์์ด์.
public interface IUndoableAction
{
void Do();
void Undo();
}
public class ActionBlock : IUndoableAction
{
private readonly IUndoableAction[] actionSequence;
public ActionBlock(params IUndoableAction[] actionSequence)
{
this.actionSequence = actionSequence;
}
public void Do()
{
foreach (var action in actionSequence)
action.Do();
}
public void Undo()
{
foreach (var action in actionSequence.Reverse())
action.Undo();
}
public override string ToString()
{
return string.Join(",", actionSequence.Select(a => a.ToString()));
}
}
public class UndoRedoStack
{
private readonly Stack<IUndoableAction> undoStack = new Stack<IUndoableAction>();
private readonly Stack<IUndoableAction> redoStack = new Stack<IUndoableAction>();
/// <summary>
/// ์๋ก์ด ์ก์
์ ์
๋ ฅ๋ฐ์์๋ ๊ฐ IUndoableAction์
/// Implementํ ํด๋์ค์ ์ก์
์ ์ํํ๊ณ ๊ธฐ์กด์ Redo ์คํ์ ์ง์์ง๋ค.
/// Undo ๋ฐ Redo ๋ฉ์๋ ์ํ ์ Implement ๋ ํด๋์ค์ ๋ด์ฉ์ ์ํํ๋ค.
/// </summary>
/// <param name="action"></param>
public void Do(IUndoableAction action)
{
action.Do();
undoStack.Push(action);
redoStack.Clear();
}
public void Undo()
{
RunAction(undoStack, redoStack, f => f.Undo());
}
public void Redo()
{
RunAction(redoStack, undoStack, f => f.Do());
}
private static void RunAction(Stack<IUndoableAction> source, Stack<IUndoableAction> target, Action<IUndoableAction> undoRedo)
{
if (source.Count <= 0)
return;
var action = source.Pop();
undoRedo(action);
target.Push(action);
}
}