Skip to content

Commit

Permalink
Update comments. Some minor changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasMikula committed Apr 27, 2017
1 parent 4a67b7b commit 6f9b5ad
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 78 deletions.
124 changes: 66 additions & 58 deletions undofx/src/main/java/org/fxmisc/undo/UndoManagerFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@
public interface UndoManagerFactory {

/**
* Creates an {@link UndoManager} where changes will never be merged and every change emitted from the
* changeStream is considered to be a non-identity change.
* Creates an {@link UndoManager} that tracks changes emitted from {@code changeStream}.
*
* @param <C> the type of change object to use
* @param <C> representation of a change
* @param invert Inverts a change, so that applying the inverted change ({@code apply.accept(invert.apply(c))})
* has the effect of undoing the original change ({@code c}). Inverting a change twice should
* result in the original change ({@code invert.apply(invert.apply(c)).equals(c)}).
* @param apply Used to apply a change. From the point of view of {@code apply}, {@code C}
* describes an action to be performed. Calling {@code apply.accept(c)}
* <em>must</em> cause {@code c} to be emitted from {@code changeStream}.
*/
default <C> UndoManager create(
EventStream<C> changeStream,
Expand All @@ -29,10 +34,17 @@ default <C> UndoManager create(
}

/**
* Creates an {@link UndoManager} where every change emitted from the changeStream is considered to be a
* non-identity change
* Creates an {@link UndoManager} that tracks and optionally merges changes emitted from {@code changeStream}.
*
* @param <C> the type of change object to use
* @param <C> representation of a change
* @param invert Inverts a change, so that applying the inverted change ({@code apply.accept(invert.apply(c))})
* has the effect of undoing the original change ({@code c}). Inverting a change twice should
* result in the original change ({@code invert.apply(invert.apply(c)).equals(c)}).
* @param apply Used to apply a change. From the point of view of {@code apply}, {@code C}
* describes an action to be performed. Calling {@code apply.accept(c)}
* <em>must</em> cause {@code c} to be emitted from {@code changeStream}.
* @param merge Used to merge two subsequent changes into one.
* Returns an empty {@linkplain Optional} when the changes cannot or should not be merged.
*/
default <C> UndoManager create(
EventStream<C> changeStream,
Expand All @@ -43,15 +55,22 @@ default <C> UndoManager create(
}

/**
* Creates an {@link UndoManager}.
* Creates an {@link UndoManager} that tracks and optionally merges changes emitted from {@code changeStream}.
*
* @param merge merges the next undo and the most recently pushed change. If the resulting change is an identity
* change, neither of the changes will be stored (even the next undo).
* @param isIdentity determines whether change is an identity change (e.g. {@link Function#identity()}). For
* example, {@code 0} is the identity change in
* {@code BiFunction<Integer, Integer, Integer> plus = (i, j) -> i + j} because
* {@code 4 == 4 + 0 == plus.apply(4, 0)}
* @param <C> the type of change object to use
* @param <C> representation of a change
* @param invert Inverts a change, so that applying the inverted change ({@code apply.accept(invert.apply(c))})
* has the effect of undoing the original change ({@code c}). Inverting a change twice should
* result in the original change ({@code invert.apply(invert.apply(c)).equals(c)}).
* @param apply Used to apply a change. From the point of view of {@code apply}, {@code C}
* describes an action to be performed. Calling {@code apply.accept(c)}
* <em>must</em> cause {@code c} to be emitted from {@code changeStream}.
* @param merge Used to merge two subsequent changes into one.
* Returns an empty {@linkplain Optional} when the changes cannot or should not be merged.
* If two changes "annihilate" (i.e. {@code merge.apply(c1, c2).isPresen()} and
* {@code isIdentity.test(merge.apply(c1, c2).get())} are both {@code true}), it should
* be the case that one is inverse of the other ({@code invert.apply(c1).equals(c2)}).
* @param isIdentity returns true for changes whose application would have no effect, thereby equivalent
* to an identity function ({@link Function#identity()}) on the underlying model.
*/
<C> UndoManager create(
EventStream<C> changeStream,
Expand All @@ -61,10 +80,9 @@ <C> UndoManager create(
Predicate<C> isIdentity);

/**
* Creates an {@link UndoManager} with an unlimited history where no changes will ever be merged and every change
* emitted by the changeStream is considered a non-identity change.
* Creates an {@link UndoManager} with unlimited history.
*
* @param <C> the type of change object to use
* For description of parameters, see {@link #create(EventStream, Function, Consumer)}.
*/
public static <C> UndoManager unlimitedHistoryUndoManager(
EventStream<C> changeStream,
Expand All @@ -74,10 +92,9 @@ public static <C> UndoManager unlimitedHistoryUndoManager(
}

/**
* Creates an {@link UndoManager} with an unlimited history where every change emitted by the changeStream
* is considered a non-identity change
* Creates an {@link UndoManager} with unlimited history.
*
* @param <C> the type of change object to use
* For description of parameters, see {@link #create(EventStream, Function, Consumer, BiFunction)}.
*/
public static <C> UndoManager unlimitedHistoryUndoManager(
EventStream<C> changeStream,
Expand All @@ -87,15 +104,9 @@ public static <C> UndoManager unlimitedHistoryUndoManager(
return unlimitedHistoryUndoManager(changeStream, invert, apply, merge, c -> false);
}
/**
* Creates an {@link UndoManager} with an unlimited history.
* Creates an {@link UndoManager} with unlimited history.
*
* @param merge merges the next undo and the most recently pushed change. If the resulting change is an identity
* change, neither of the changes will be stored.
* @param isIdentity determines whether change is an identity change (e.g. {@link Function#identity()}). For
* example, {@code 0} is the identity change in
* {@code BiFunction<Integer, Integer, Integer> plus = (i, j) -> i + j} because
* {@code 4 == 4 + 0 == plus.apply(4, 0)}
* @param <C> the type of change object to use
* For description of parameters, see {@link #create(EventStream, Function, Consumer, BiFunction, Predicate)}.
*/
public static <C> UndoManager unlimitedHistoryUndoManager(
EventStream<C> changeStream,
Expand All @@ -108,8 +119,7 @@ public static <C> UndoManager unlimitedHistoryUndoManager(
}

/**
* Creates an {@link UndoManagerFactory} whose {@code create} methods will create an {@link UndoManager} with
* an unlimited history.
* Creates a factory for {@link UndoManager}s with unlimited history.
*/
public static UndoManagerFactory unlimitedHistoryFactory() {
return new UndoManagerFactory() {
Expand All @@ -126,11 +136,12 @@ public <C> UndoManager create(
}

/**
* Creates an {@link UndoManager} with a limited history where changes are never merged and every change emitted
* from the changeStream is considered to be a non-identity change; when at full capacity, a new change will
* cause the oldest change to be forgotten.
* Creates an {@link UndoManager} with bounded history.
* When at full capacity, a new change will cause the oldest change to be forgotten.
*
* @param <C> the type of change object to use
* <p>For description of the remaining parameters, see {@link #create(EventStream, Function, Consumer)}.</p>
*
* @param capacity maximum number of changes the returned UndoManager can store
*/
public static <C> UndoManager fixedSizeHistoryUndoManager(
EventStream<C> changeStream,
Expand All @@ -141,11 +152,12 @@ public static <C> UndoManager fixedSizeHistoryUndoManager(
}

/**
* Creates an {@link UndoManager} with a limited history where every change emitted from the changeStream
* is considered to be a non-identity change; when at full capacity, a new change will cause the oldest
* change to be forgotten.
* Creates an {@link UndoManager} with bounded history.
* When at full capacity, a new change will cause the oldest change to be forgotten.
*
* <p>For description of the remaining parameters, see {@link #create(EventStream, Function, Consumer, BiFunction)}.</p>
*
* @param <C> the type of change object to use
* @param capacity maximum number of changes the returned UndoManager can store
*/
public static <C> UndoManager fixedSizeHistoryUndoManager(
EventStream<C> changeStream,
Expand All @@ -157,16 +169,12 @@ public static <C> UndoManager fixedSizeHistoryUndoManager(
}

/**
* Creates an {@link UndoManager} with a limited history; when at full capacity, a new change will cause the
* oldest change to be forgotten.
* Creates an {@link UndoManager} with bounded history.
* When at full capacity, a new change will cause the oldest change to be forgotten.
*
* <p>For description of the remaining parameters, see {@link #create(EventStream, Function, Consumer, BiFunction, Predicate)}.</p>
*
* @param merge merges the next undo and the most recently pushed change. If the resulting change is an identity
* change, neither of the changes will be stored.
* @param isIdentity determines whether change is an identity change (e.g. {@link Function#identity()}). For
* example, {@code 0} is the identity change in
* {@code BiFunction<Integer, Integer, Integer> plus = (i, j) -> i + j} because
* {@code 4 == 4 + 0 == plus.apply(4, 0)}
* @param <C> the type of change object to use
* @param capacity maximum number of changes the returned UndoManager can store
*/
public static <C> UndoManager fixedSizeHistoryUndoManager(
EventStream<C> changeStream,
Expand All @@ -180,8 +188,8 @@ public static <C> UndoManager fixedSizeHistoryUndoManager(
}

/**
* Creates an {@link UndoManagerFactory} whose {@code create} methods will create an {@link UndoManager} with
* a limited history; when at full capacity, a new change will cause the oldest change to be forgotten.
* Creates a factory for {@link UndoManager}s with bounded history.
* When at full capacity, a new change will cause the oldest change to be forgotten.
*/
public static UndoManagerFactory fixedSizeHistoryFactory(int capacity) {
return new UndoManagerFactory() {
Expand All @@ -198,22 +206,22 @@ public <C> UndoManager create(
}

/**
* Creates an {@link UndoManager} with no history where all changes emitted from the EventStream will be
* considered non-identity changes and each emitted change will change the
* {@link UndoManager#atMarkedPositionProperty()}; the {@link UndoManager} will never be able to undo/redo a change
* emitted from the changeStream.
*
* @param <C> the type of change object to use
* Creates an {@link UndoManager} with no history: all changes emitted from {@code changeStream} will be
* immediately forgotten. Therefore, the returned {@linkplain UndoManager} will never be able to undo/redo
* any change emitted from {@code changeStream}.
* However, the (imaginary) current position will keep advancing, so that one can still use
* {@link UndoManager#atMarkedPositionProperty()} to determine whether any change has occurred since the last
* {@link UndoManager#mark()} (e.g. since the last save).
*/
public static <C> UndoManager zeroHistoryUndoManager(EventStream<C> changeStream) {
ChangeQueue<C> queue = new ZeroSizeChangeQueue<>();
return new UndoManagerImpl<>(queue, c -> c, c -> {}, (c1, c2) -> Optional.empty(), c -> false, changeStream);
}

/**
* Creates an {@link UndoManagerFactory} whose {@code create} methods will create an {@link UndoManager} with
* no history: all changes will change the {@link UndoManager#atMarkedPositionProperty()}, but
* it will never be able to undo/redo a change emitted from the changeStream.
* Creates a factory for {@link UndoManager}s with no history.
*
* @see #zeroHistoryUndoManager(EventStream)
*/
public static UndoManagerFactory zeroHistoryFactory() {
return new UndoManagerFactory() {
Expand Down
22 changes: 2 additions & 20 deletions undofx/src/main/java/org/fxmisc/undo/impl/UndoManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,6 @@ protected boolean computeValue() {
private QueuePosition mark;
private C expectedChange = null;

/**
* Creates an {@link UndoManager}.
*
* @param queue the queue that stores the changes to undo/redo
* @param invert inverts the change
* @param apply applies the change (undo/redo)
* @param merge merges two changes into one change. If the resulting change is an identity change, the two
* changes will not be merged.
* @param isIdentity determines whether change is an identity change (e.g. {@link Function#identity()}). For
* example, {@code 0} is the identity change in
* {@code BiFunction<Integer, Integer, Integer> plus = (i, j) -> i + j} because
* {@code 4 == 4 + 0 == plus.apply(4, 0)}
* @param changeSource the {@link EventStream} that emits changes
*/
public UndoManagerImpl(
ChangeQueue<C> queue,
Function<? super C, ? extends C> invert,
Expand Down Expand Up @@ -218,22 +204,18 @@ private void addChange(C change) {
C prev = queue.prev();

// attempt to merge the changes
Object[] changeArray;
Optional<C> merged = merge.apply(prev, change);
if(merged.isPresent()) {
if (isIdentity.test(merged.get())) {
canMerge = false;
changeArray = new Object[0];
} else {
canMerge = true;
changeArray = new Object[] { merged.get() };
queue.push(merged.get());
}
} else {
canMerge = true;
changeArray = new Object[] { prev, change };
queue.push(prev, change);
}

queue.push((C[]) changeArray);
} else {
queue.push(change);
canMerge = true;
Expand Down

0 comments on commit 6f9b5ad

Please sign in to comment.