package dev.kske.undoredo.core; import java.util.*; /** * A simple change manager with a linear history model backed by an array list. * * @param the change type to store in this change manager * @author Maximilian Käfer * @author Kai S. K. Engelbart * @since 0.0.1 */ public final class UnlimitedChangeManager implements ChangeManager { private final List changes = new ArrayList<>(); private int index = -1; private int markedIndex = -1; /** * @implNote As this change manager uses a linear history model, all changes behind the last * applied change will be discarded and therefore can be garbage collected. */ @Override public boolean addChange(C change) { if (!change.isIdentity()) { change.apply(); // Remove divergent changes changes.subList(index + 1, changes.size()).clear(); changes.add(change); ++index; return true; } return false; } @Override public Optional getLastChange() { return index < 0 ? Optional.empty() : Optional.of(changes.get(index)); } @Override public boolean undo() { if (isUndoAvailable()) { changes.get(index).invert().apply(); --index; return true; } return false; } @Override public boolean redo() { if (isRedoAvailable()) { changes.get(index + 1).apply(); ++index; return true; } return false; } @Override public void mark() { markedIndex = index; } @Override public void unmark() { markedIndex = -1; } @Override public boolean isAtMarkedChange() { return markedIndex == index; } @Override public boolean isUndoAvailable() { return index > -1; } @Override public boolean isRedoAvailable() { return index < changes.size() - 1; } @Override public List getChanges() { return Collections.unmodifiableList(changes); } }