New change interface and changeManager class

This commit is contained in:
Maximilian P. Käfer 2021-12-07 19:13:51 +01:00
parent 4a05f9a394
commit fe1009187c
Signed by: mpk
GPG Key ID: 035869C949377C5C
2 changed files with 133 additions and 0 deletions

View File

@ -0,0 +1,33 @@
package dev.kske.undoredo;
/**
* Base interface for changes to be registered in an undo manager.
*
* @author Maximilian Käfer
* @since 0.0.1
*/
public interface Change {
/**
* Performs the action implemented by this change.
*
* @since 0.0.1
*/
void apply();
/**
* Inverts this change.
*
* @implSpec This method is not supposed to alter the state of this change, but rather to create
* a new complementary change.
* @return the inverted change
* @since 0.0.1
*/
Change invert();
/**
* @return whether the application of this change would result in an identical state
* @since 0.0.1
*/
boolean isIdentity();
}

View File

@ -0,0 +1,100 @@
package dev.kske.undoredo;
import java.util.*;
/**
* @param <C> the change types to store in this change manager
* @author Maximilian K&auml;fer
* @since 0.0.1
*/
public final class ChangeManager<C extends Change> {
private final List<C> changes = new LinkedList<>();
private int index;
private int markedIndex;
/**
* Adds a change to the changes list.
*
* @param change the change to add
* @since 0.0.1
*/
public void addChange(C change) {
change.apply();
changes.add(change);
}
/**
* Undoes the change at the current index position.
*
* @return whether the operation could be executed due to one being currently available
* @since 0.1.0
*/
public boolean undo() {
if (isUndoAvailable()) {
changes.get(index).invert().apply();
--index;
return true;
}
return false;
}
/**
* Applies the change that was undone before.
*
* @return whether the operation could be executed due to one being currently available
* @since 0.0.1
*/
public boolean redo() {
if (isRedoAvailable()) {
changes.get(index + 1).apply();
++index;
return true;
}
return false;
}
/**
* Marks the current index.
*
* @since 0.0.1
*/
public void mark() {
markedIndex = index;
}
/**
* @return whether the current index was marked
* @since 0.0.1
*/
public boolean isAtMarkedIndex() {
return markedIndex == index;
}
/**
* @return whether the undo operation is currently available
* @since 0.0.1
*/
public boolean isUndoAvailable() {
return index > 0;
}
/**
* @return whether the redo operation is currently available.
* @since 0.0.1
*/
public boolean isRedoAvailable() {
return index < changes.size() - 1;
}
/**
* Provides an unmodifiable view of the changes stored in this change manager.
*
* @return all stored changes
* @since 0.0.1
*/
public List<C> getChanges() {
return Collections.unmodifiableList(changes);
}
}