This repository has been archived on 2022-02-11. You can view files and clone it, but cannot push or open issues or pull requests.
undo-redo/core/src/main/java/dev/kske/undoredo/core/UnlimitedChangeManager.java

94 lines
1.8 KiB
Java

package dev.kske.undoredo.core;
import java.util.*;
/**
* A simple change manager with a linear history model backed by an array list.
*
* @param <C> the change type to store in this change manager
* @author Maximilian K&auml;fer
* @author Kai S. K. Engelbart
* @since 0.0.1
*/
public final class UnlimitedChangeManager<C extends Change> implements ChangeManager<C> {
private final List<C> 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<C> 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<C> getChanges() {
return Collections.unmodifiableList(changes);
}
}