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); + } } /**