From 1fa1ff895b6b22e7ffb8c0de581929942dd72fca Mon Sep 17 00:00:00 2001
From: Kenzie Togami
Date: Sat, 20 Oct 2018 18:54:58 -0700
Subject: [PATCH 1/3] Flush or disable buffers in tools
---
.../worldedit/bukkit/WorldEditPlugin.java | 2 +-
.../java/com/sk89q/worldedit/EditSession.java | 40 +++++++++++++++----
.../java/com/sk89q/worldedit/WorldEdit.java | 2 +-
.../worldedit/command/UtilityCommands.java | 4 +-
.../worldedit/command/tool/AreaPickaxe.java | 2 +-
.../worldedit/command/tool/BlockReplacer.java | 3 +-
.../worldedit/command/tool/BrushTool.java | 3 +-
.../command/tool/RecursivePickaxe.java | 2 +-
.../worldedit/command/tool/SinglePickaxe.java | 2 +-
.../extension/platform/CommandManager.java | 2 +-
10 files changed, 44 insertions(+), 18 deletions(-)
diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java
index 6da9f6821..4e74d4814 100644
--- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java
+++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java
@@ -285,7 +285,7 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
LocalSession session = WorldEdit.getInstance().getSessionManager().get(wePlayer);
session.remember(editSession);
- editSession.flushQueue();
+ editSession.flushSession();
WorldEdit.getInstance().flushBlockBag(wePlayer, editSession);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
index 1e3005f59..e9c9cf8e4 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -298,13 +298,13 @@ public class EditSession implements Extent {
}
/**
- * Disable the queue. This will flush the queue.
+ * Disable the queue. This will {@linkplain #flushSession() flush the session}.
*/
public void disableQueue() {
if (isQueueEnabled()) {
- flushQueue();
+ flushSession();
}
- reorderExtent.setEnabled(true);
+ reorderExtent.setEnabled(false);
}
/**
@@ -393,10 +393,21 @@ public class EditSession implements Extent {
return blockBagExtent.popMissing();
}
+ /**
+ * Returns chunk batching status.
+ *
+ * @return whether chunk batching is enabled
+ */
public boolean isBatchingChunks() {
return chunkBatchingExtent != null && chunkBatchingExtent.isEnabled();
}
+ /**
+ * Enable or disable chunk batching. Disabling will
+ * {@linkplain #flushSession() flush the session}.
+ *
+ * @param batchingChunks {@code true} to enable, {@code false} to disable
+ */
public void setBatchingChunks(boolean batchingChunks) {
if (chunkBatchingExtent == null) {
if (batchingChunks) {
@@ -405,11 +416,23 @@ public class EditSession implements Extent {
return;
}
if (!batchingChunks) {
- flushQueue();
+ flushSession();
}
chunkBatchingExtent.setEnabled(batchingChunks);
}
+ /**
+ * Disable all buffering extents.
+ *
+ * @see #disableQueue()
+ * @see #setBatchingChunks(boolean)
+ */
+ public void disableBuffering() {
+ // We optimize here to avoid double calls to flushSession.
+ reorderExtent.setEnabled(false);
+ setBatchingChunks(false);
+ }
+
/**
* Get the number of blocks changed, including repeated block changes.
*
@@ -569,7 +592,7 @@ public class EditSession implements Extent {
UndoContext context = new UndoContext();
context.setExtent(editSession.bypassHistory);
Operations.completeBlindly(ChangeSetExecutor.createUndo(changeSet, context));
- editSession.flushQueue();
+ editSession.flushSession();
}
/**
@@ -581,7 +604,7 @@ public class EditSession implements Extent {
UndoContext context = new UndoContext();
context.setExtent(editSession.bypassHistory);
Operations.completeBlindly(ChangeSetExecutor.createRedo(changeSet, context));
- editSession.flushQueue();
+ editSession.flushSession();
}
/**
@@ -614,9 +637,10 @@ public class EditSession implements Extent {
}
/**
- * Finish off the queue.
+ * Communicate to the EditSession that all block changes are complete,
+ * and that it should apply them to the world.
*/
- public void flushQueue() {
+ public void flushSession() {
Operations.completeBlindly(commit());
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java
index c25e5a2c0..69a62a5c2 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java
@@ -628,7 +628,7 @@ public class WorldEdit {
logger.log(Level.WARNING, "Failed to execute script", e);
} finally {
for (EditSession editSession : scriptContext.getEditSessions()) {
- editSession.flushQueue();
+ editSession.flushSession();
session.remember(editSession);
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java
index f20b54d51..96e3e9875 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java
@@ -460,7 +460,7 @@ public class UtilityCommands {
if (editSession != null) {
session.remember(editSession);
- editSession.flushQueue();
+ editSession.flushSession();
}
}
@@ -520,7 +520,7 @@ public class UtilityCommands {
if (editSession != null) {
session.remember(editSession);
- editSession.flushQueue();
+ editSession.flushSession();
}
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java
index e7b64ad7e..33dcb2d81 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java
@@ -83,7 +83,7 @@ public class AreaPickaxe implements BlockTool {
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
} finally {
- editSession.flushQueue();
+ editSession.flushSession();
session.remember(editSession);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java
index 1388b66ea..1ddfae39e 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java
@@ -53,16 +53,17 @@ public class BlockReplacer implements DoubleActionBlockTool {
BlockBag bag = session.getBlockBag(player);
EditSession editSession = session.createEditSession(player);
+ editSession.disableBuffering();
try {
Vector position = clicked.toVector();
editSession.setBlock(position, pattern.apply(position));
} catch (MaxChangedBlocksException ignored) {
} finally {
+ session.remember(editSession);
if (bag != null) {
bag.flushChanges();
}
- session.remember(editSession);
}
return true;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java
index 9096a4d19..e1b6c906d 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java
@@ -193,10 +193,11 @@ public class BrushTool implements TraceTool {
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
} finally {
+ session.remember(editSession);
+ editSession.flushSession();
if (bag != null) {
bag.flushChanges();
}
- session.remember(editSession);
}
return true;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java
index b2fcf6525..3b35abf42 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java
@@ -75,7 +75,7 @@ public class RecursivePickaxe implements BlockTool {
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
} finally {
- editSession.flushQueue();
+ editSession.flushSession();
session.remember(editSession);
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java
index f3f4c9945..1ceabcbe2 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java
@@ -57,7 +57,7 @@ public class SinglePickaxe implements BlockTool {
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
} finally {
- editSession.flushQueue();
+ editSession.flushSession();
}
world.playEffect(clicked.toVector(), 2001, blockType.getLegacyId());
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java
index 12f56a81a..297ccf318 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java
@@ -316,7 +316,7 @@ public final class CommandManager {
if (editSession != null) {
session.remember(editSession);
- editSession.flushQueue();
+ editSession.flushSession();
if (config.profile) {
long time = System.currentTimeMillis() - start;
From a3f1c71d97abb42e85aceb6ff514ac75f479343a Mon Sep 17 00:00:00 2001
From: Kenzie Togami
Date: Sat, 20 Oct 2018 19:50:35 -0700
Subject: [PATCH 2/3] Make EditSession closeable for easy flushing
---
.../java/com/sk89q/worldedit/EditSession.java | 10 ++++-
.../worldedit/command/tool/AreaPickaxe.java | 36 ++++++++---------
.../worldedit/command/tool/BlockReplacer.java | 20 +++++-----
.../worldedit/command/tool/BrushTool.java | 39 ++++++++++---------
.../command/tool/RecursivePickaxe.java | 20 +++++-----
.../worldedit/command/tool/SinglePickaxe.java | 8 +---
6 files changed, 69 insertions(+), 64 deletions(-)
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
index e9c9cf8e4..aa630bfa1 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -134,7 +134,7 @@ import javax.annotation.Nullable;
* using the {@link ChangeSetExtent}.
*/
@SuppressWarnings({"FieldCanBeLocal"})
-public class EditSession implements Extent {
+public class EditSession implements Extent, AutoCloseable {
private static final Logger log = Logger.getLogger(EditSession.class.getCanonicalName());
@@ -636,6 +636,14 @@ public class EditSession implements Extent {
return bypassNone.getEntities();
}
+ /**
+ * Closing an EditSession {@linkplain #flushSession() flushes its buffers}.
+ */
+ @Override
+ public void close() {
+ flushSession();
+ }
+
/**
* Communicate to the EditSession that all block changes are complete,
* and that it should apply them to the world.
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java
index 33dcb2d81..1af33599c 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java
@@ -62,29 +62,29 @@ public class AreaPickaxe implements BlockTool {
return true;
}
- EditSession editSession = session.createEditSession(player);
- editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);
+ try (EditSession editSession = session.createEditSession(player)) {
+ editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);
- try {
- for (int x = ox - range; x <= ox + range; ++x) {
- for (int y = oy - range; y <= oy + range; ++y) {
- for (int z = oz - range; z <= oz + range; ++z) {
- Vector pos = new Vector(x, y, z);
- if (editSession.getBlock(pos).getBlockType() != initialType) {
- continue;
+ try {
+ for (int x = ox - range; x <= ox + range; ++x) {
+ for (int y = oy - range; y <= oy + range; ++y) {
+ for (int z = oz - range; z <= oz + range; ++z) {
+ Vector pos = new Vector(x, y, z);
+ if (editSession.getBlock(pos).getBlockType() != initialType) {
+ continue;
+ }
+
+ ((World) clicked.getExtent()).queueBlockBreakEffect(server, pos, initialType, clicked.toVector().distanceSq(pos));
+
+ editSession.setBlock(pos, BlockTypes.AIR.getDefaultState());
}
-
- ((World) clicked.getExtent()).queueBlockBreakEffect(server, pos, initialType, clicked.toVector().distanceSq(pos));
-
- editSession.setBlock(pos, BlockTypes.AIR.getDefaultState());
}
}
+ } catch (MaxChangedBlocksException e) {
+ player.printError("Max blocks change limit reached.");
+ } finally {
+ session.remember(editSession);
}
- } catch (MaxChangedBlocksException e) {
- player.printError("Max blocks change limit reached.");
- } finally {
- editSession.flushSession();
- session.remember(editSession);
}
return true;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java
index 1ddfae39e..38619396b 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java
@@ -52,15 +52,16 @@ public class BlockReplacer implements DoubleActionBlockTool {
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) {
BlockBag bag = session.getBlockBag(player);
- EditSession editSession = session.createEditSession(player);
- editSession.disableBuffering();
-
- try {
- Vector position = clicked.toVector();
- editSession.setBlock(position, pattern.apply(position));
- } catch (MaxChangedBlocksException ignored) {
+ try (EditSession editSession = session.createEditSession(player)) {
+ try {
+ editSession.disableBuffering();
+ Vector position = clicked.toVector();
+ editSession.setBlock(position, pattern.apply(position));
+ } catch (MaxChangedBlocksException ignored) {
+ } finally {
+ session.remember(editSession);
+ }
} finally {
- session.remember(editSession);
if (bag != null) {
bag.flushChanges();
}
@@ -72,8 +73,7 @@ public class BlockReplacer implements DoubleActionBlockTool {
@Override
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) {
- EditSession editSession = session.createEditSession(player);
- BlockStateHolder targetBlock = editSession.getBlock(clicked.toVector());
+ BlockStateHolder targetBlock = player.getWorld().getBlock(clicked.toVector());
if (targetBlock != null) {
pattern = new BlockPattern(targetBlock);
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java
index e1b6c906d..55d2947f7 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java
@@ -172,29 +172,30 @@ public class BrushTool implements TraceTool {
BlockBag bag = session.getBlockBag(player);
- EditSession editSession = session.createEditSession(player);
- Request.request().setEditSession(editSession);
- if (mask != null) {
- Mask existingMask = editSession.getMask();
+ try (EditSession editSession = session.createEditSession(player)) {
+ Request.request().setEditSession(editSession);
+ if (mask != null) {
+ Mask existingMask = editSession.getMask();
- if (existingMask == null) {
- editSession.setMask(mask);
- } else if (existingMask instanceof MaskIntersection) {
- ((MaskIntersection) existingMask).add(mask);
- } else {
- MaskIntersection newMask = new MaskIntersection(existingMask);
- newMask.add(mask);
- editSession.setMask(newMask);
+ if (existingMask == null) {
+ editSession.setMask(mask);
+ } else if (existingMask instanceof MaskIntersection) {
+ ((MaskIntersection) existingMask).add(mask);
+ } else {
+ MaskIntersection newMask = new MaskIntersection(existingMask);
+ newMask.add(mask);
+ editSession.setMask(newMask);
+ }
}
- }
- try {
- brush.build(editSession, target.toVector(), material, size);
- } catch (MaxChangedBlocksException e) {
- player.printError("Max blocks change limit reached.");
+ try {
+ brush.build(editSession, target.toVector(), material, size);
+ } catch (MaxChangedBlocksException e) {
+ player.printError("Max blocks change limit reached.");
+ } finally {
+ session.remember(editSession);
+ }
} finally {
- session.remember(editSession);
- editSession.flushSession();
if (bag != null) {
bag.flushChanges();
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java
index 3b35abf42..afeb4728d 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java
@@ -66,17 +66,17 @@ public class RecursivePickaxe implements BlockTool {
return true;
}
- EditSession editSession = session.createEditSession(player);
- editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);
+ try (EditSession editSession = session.createEditSession(player)) {
+ editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);
- try {
- recurse(server, editSession, world, clicked.toVector().toBlockVector(),
- clicked.toVector(), range, initialType, new HashSet<>());
- } catch (MaxChangedBlocksException e) {
- player.printError("Max blocks change limit reached.");
- } finally {
- editSession.flushSession();
- session.remember(editSession);
+ try {
+ recurse(server, editSession, world, clicked.toVector().toBlockVector(),
+ clicked.toVector(), range, initialType, new HashSet<>());
+ } catch (MaxChangedBlocksException e) {
+ player.printError("Max blocks change limit reached.");
+ } finally {
+ session.remember(editSession);
+ }
}
return true;
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java
index 1ceabcbe2..fbf1874ce 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java
@@ -49,15 +49,11 @@ public class SinglePickaxe implements BlockTool {
return true;
}
- EditSession editSession = session.createEditSession(player);
- editSession.getSurvivalExtent().setToolUse(config.superPickaxeDrop);
-
- try {
+ try (EditSession editSession = session.createEditSession(player)) {
+ editSession.getSurvivalExtent().setToolUse(config.superPickaxeDrop);
editSession.setBlock(clicked.toVector(), BlockTypes.AIR.getDefaultState());
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
- } finally {
- editSession.flushSession();
}
world.playEffect(clicked.toVector(), 2001, blockType.getLegacyId());
From d1312c66e1d3556cef039e5895e959842f733c0a Mon Sep 17 00:00:00 2001
From: Kenzie Togami
Date: Sat, 20 Oct 2018 19:54:13 -0700
Subject: [PATCH 3/3] Ensure we flush iff it is needed
---
.../main/java/com/sk89q/worldedit/EditSession.java | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
index aa630bfa1..bc98a20e3 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -415,7 +415,7 @@ public class EditSession implements Extent, AutoCloseable {
}
return;
}
- if (!batchingChunks) {
+ if (!batchingChunks && isBatchingChunks()) {
flushSession();
}
chunkBatchingExtent.setEnabled(batchingChunks);
@@ -428,9 +428,15 @@ public class EditSession implements Extent, AutoCloseable {
* @see #setBatchingChunks(boolean)
*/
public void disableBuffering() {
- // We optimize here to avoid double calls to flushSession.
+ // We optimize here to avoid repeated calls to flushSession.
+ boolean needsFlush = isQueueEnabled() || isBatchingChunks();
+ if (needsFlush) {
+ flushSession();
+ }
reorderExtent.setEnabled(false);
- setBatchingChunks(false);
+ if (chunkBatchingExtent != null) {
+ chunkBatchingExtent.setEnabled(false);
+ }
}
/**