package com.project.website.canvas.client.shared; import java.util.Stack; import com.google.common.base.Objects; import com.google.common.collect.Lists; import com.project.shared.data.Pair; public class UndoManager { public interface UndoRedoPair { void redo(); void undo(); } private static UndoManager INSTANCE = new UndoManager(); private final Stack<Pair<Object, UndoRedoPair>> _future = new Stack<Pair<Object, UndoRedoPair>>(); private final Stack<Pair<Object, UndoRedoPair>> _past = new Stack<Pair<Object, UndoRedoPair>>(); public static UndoManager get() { return UndoManager.INSTANCE; } public void clear() { this._future.clear(); this._past.clear(); } public void addAndRedo(Object owner, UndoRedoPair undoRedoPair) { this.add(owner, undoRedoPair); undoRedoPair.redo(); } public void add(Object owner, UndoRedoPair undoRedoPair) { this._past.push(new Pair<Object, UndoRedoPair>(owner, undoRedoPair)); this._future.clear(); } public void removeOwner(Object owner) { UndoManager.filter(owner, this._past); UndoManager.filter(owner, this._future); } public void undo() { Pair<Object, UndoRedoPair> step = UndoManager.moveStep(this._past, this._future); if (null != step) { step.getB().undo(); } } public void redo() { Pair<Object, UndoRedoPair> step = UndoManager.moveStep(this._future, this._past); if (null != step) { step.getB().redo(); } } private static void filter(Object owner, Stack<Pair<Object, UndoRedoPair>> stack) { for (Pair<Object, UndoRedoPair> step : Lists.newArrayList(stack)) { if (Objects.equal(step.getA(), owner)) { stack.remove(step); } } } private static Pair<Object, UndoRedoPair> moveStep(final Stack<Pair<Object, UndoRedoPair>> from, final Stack<Pair<Object, UndoRedoPair>> target) { if (from.isEmpty()) { return null; } Pair<Object, UndoRedoPair> step = from.pop(); target.push(step); return step; } }