Permalink
Browse files

Made undo/redo use a queue.

  • Loading branch information...
me4502 committed Aug 24, 2018
1 parent 384ee8c commit ac074ed797c449bb159ea88e19ea1d9e67346edf
@@ -290,9 +290,8 @@ public void remember(Player player, EditSession editSession) {
com.sk89q.worldedit.entity.Player wePlayer = wrapPlayer(player);
LocalSession session = WorldEdit.getInstance().getSessionManager().get(wePlayer);
editSession.flushQueue(wePlayer);
session.remember(editSession);
editSession.flushQueue();
WorldEdit.getInstance().flushBlockBag(wePlayer, editSession);
}
@@ -288,7 +288,7 @@ public void enableQueue() {
*/
public void disableQueue() {
if (isQueueEnabled()) {
flushQueue();
flushQueue(null);
}
reorderExtent.setEnabled(true);
}
@@ -532,25 +532,27 @@ public Entity createEntity(com.sk89q.worldedit.util.Location location, BaseEntit
/**
* Restores all blocks to their initial state.
*
* @param actor The actor, if present
* @param editSession a new {@link EditSession} to perform the undo in
* @return The undo task
*/
public void undo(EditSession editSession) {
public Task<EditSession> undo(@Nullable Actor actor, EditSession editSession) {
UndoContext context = new UndoContext();
context.setExtent(editSession.bypassHistory);
Operations.completeBlindly(ChangeSetExecutor.createUndo(changeSet, context));
editSession.flushQueue();
return Operations.<EditSession>completeQueued(ChangeSetExecutor.createUndo(changeSet, context), actor, editSession).withSupplier(() -> editSession);
}
/**
* Sets to new state.
*
* @param actor The actor, if present
* @param editSession a new {@link EditSession} to perform the redo in
* @return The redo task
*/
public void redo(EditSession editSession) {
public Task<EditSession> redo(@Nullable Actor actor, EditSession editSession) {
UndoContext context = new UndoContext();
context.setExtent(editSession.bypassHistory);
Operations.completeBlindly(ChangeSetExecutor.createRedo(changeSet, context));
editSession.flushQueue();
return Operations.<EditSession>completeQueued(ChangeSetExecutor.createRedo(changeSet, context), actor, editSession).withSupplier(() -> editSession);
}
/**
@@ -585,8 +587,10 @@ public Vector getMaximumPoint() {
/**
* Finish off the queue.
*/
public void flushQueue() {
Operations.completeBlindly(commit());
public Task<Void> flushQueue(Actor actor) {
Task<Void> task = new Task<>(commit());
WorldEdit.getInstance().getTaskManager().getTaskQueue(actor).offerNext(task);
return task;
}
@Override
@@ -36,6 +36,7 @@
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.task.Task;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import com.sk89q.worldedit.internal.cui.CUIRegion;
import com.sk89q.worldedit.internal.cui.SelectionShapeEvent;
@@ -219,7 +220,7 @@ public void remember(EditSession editSession) {
* @param player the player
* @return whether anything was undone
*/
public EditSession undo(@Nullable BlockBag newBlockBag, Player player) {
public Task<EditSession> undo(@Nullable BlockBag newBlockBag, Player player) {
checkNotNull(player);
--historyPointer;
if (historyPointer >= 0) {
@@ -228,8 +229,9 @@ public EditSession undo(@Nullable BlockBag newBlockBag, Player player) {
.getEditSession(editSession.getWorld(), -1, newBlockBag, player);
newEditSession.enableQueue();
newEditSession.setFastMode(fastMode);
editSession.undo(newEditSession);
return editSession;
Task<EditSession> task = editSession.undo(player, newEditSession);
task.addActorConsumers(player);
return task;
} else {
historyPointer = 0;
return null;
@@ -243,17 +245,18 @@ public EditSession undo(@Nullable BlockBag newBlockBag, Player player) {
* @param player the player
* @return whether anything was redone
*/
public EditSession redo(@Nullable BlockBag newBlockBag, Player player) {
public Task<EditSession> redo(@Nullable BlockBag newBlockBag, Player player) {
checkNotNull(player);
if (historyPointer < history.size()) {
EditSession editSession = history.get(historyPointer);
EditSession newEditSession = WorldEdit.getInstance().getEditSessionFactory()
.getEditSession(editSession.getWorld(), -1, newBlockBag, player);
newEditSession.enableQueue();
newEditSession.setFastMode(fastMode);
editSession.redo(newEditSession);
Task<EditSession> task = editSession.redo(player, newEditSession);
task.addActorConsumers(player);
++historyPointer;
return editSession;
return task;
}
return null;
@@ -639,7 +639,7 @@ public void runScript(Player player, File f, String[] args) throws WorldEditExce
logger.log(Level.WARNING, "Failed to execute script", e);
} finally {
for (EditSession editSession : scriptContext.getEditSessions()) {
editSession.flushQueue();
editSession.flushQueue(player);
session.remember(editSession);
}
}
@@ -29,6 +29,7 @@
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.function.task.Task;
/**
* Commands to undo, redo, and clear history.
@@ -55,10 +56,10 @@ public HistoryCommands(WorldEdit worldEdit) {
max = 2
)
@CommandPermissions("worldedit.history.undo")
public void undo(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
public void undo(Player player, LocalSession session, CommandContext args) throws WorldEditException {
int times = Math.max(1, args.getInteger(0, 1));
for (int i = 0; i < times; ++i) {
EditSession undone;
Task<EditSession> undone;
if (args.argsLength() < 2) {
undone = session.undo(session.getBlockBag(player), player);
} else {
@@ -71,8 +72,7 @@ public void undo(Player player, LocalSession session, EditSession editSession, C
undone = sess.undo(session.getBlockBag(player), player);
}
if (undone != null) {
player.print("Undo successful.");
worldEdit.flushBlockBag(player, undone);
undone.withConsumer(undoneSession -> player.print("Undo successful."));
} else {
player.printError("Nothing left to undo.");
break;
@@ -88,12 +88,12 @@ public void undo(Player player, LocalSession session, EditSession editSession, C
max = 2
)
@CommandPermissions("worldedit.history.redo")
public void redo(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
public void redo(Player player, LocalSession session, CommandContext args) throws WorldEditException {
int times = Math.max(1, args.getInteger(0, 1));
for (int i = 0; i < times; ++i) {
EditSession redone;
Task<EditSession> redone;
if (args.argsLength() < 2) {
redone = session.redo(session.getBlockBag(player), player);
} else {
@@ -106,8 +106,7 @@ public void redo(Player player, LocalSession session, EditSession editSession, C
redone = sess.redo(session.getBlockBag(player), player);
}
if (redone != null) {
player.print("Redo successful.");
worldEdit.flushBlockBag(player, redone);
redone.withConsumer(redoneSession -> player.print("Redo successful."));
} else {
player.printError("Nothing left to redo.");
}
@@ -455,7 +455,7 @@ public void butcher(Actor actor, CommandContext args) throws WorldEditException
if (editSession != null) {
session.remember(editSession);
editSession.flushQueue();
editSession.flushQueue(actor);
}
}
@@ -515,7 +515,7 @@ public void remove(Actor actor, CommandContext args) throws WorldEditException,
if (editSession != null) {
session.remember(editSession);
editSession.flushQueue();
editSession.flushQueue(actor);
}
}
@@ -83,7 +83,7 @@ public boolean actPrimary(Platform server, LocalConfiguration config, Player pla
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
} finally {
editSession.flushQueue();
editSession.flushQueue(player);
session.remember(editSession);
}
@@ -75,7 +75,7 @@ public boolean actPrimary(Platform server, LocalConfiguration config, Player pla
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
} finally {
editSession.flushQueue();
editSession.flushQueue(player);
session.remember(editSession);
}
@@ -57,7 +57,7 @@ public boolean actPrimary(Platform server, LocalConfiguration config, Player pla
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
} finally {
editSession.flushQueue();
editSession.flushQueue(player);
}
world.playEffect(clicked.toVector(), 2001, blockType.getLegacyId());
@@ -64,16 +64,25 @@ private ChangeSetExecutor(ChangeSet changeSet, Type type, UndoContext context) {
@Override
public Operation resume(RunContext run) throws WorldEditException {
long start = System.currentTimeMillis();
int count = 0;
while (iterator.hasNext()) {
Change change = iterator.next();
if (type == Type.UNDO) {
change.undo(context);
} else {
change.redo(context);
}
count ++;
if (count % 100 == 0 && System.currentTimeMillis() - start > 50) {
break;
}
}
return null;
return iterator.hasNext() ? this : null;
}
@Override
@@ -41,7 +41,7 @@ public FlushOperation(Actor actor, EditSession editSession) {
public Operation resume(RunContext run) throws WorldEditException {
LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor);
session.remember(editSession);
editSession.flushQueue();
editSession.flushQueue(actor);
WorldEdit.getInstance().flushBlockBag(actor, editSession);
@@ -72,6 +72,17 @@ public void offer(Task task) {
queue.offer(task);
}
/**
* Add a new task to the queue, performed next.
*
* @param task the task
*/
public void offerNext(Task task) {
checkNotNull(task);
queue.offerFirst(task);
}
public Task resume(RunContext run) {
if (paused) {
return current;

0 comments on commit ac074ed

Please sign in to comment.