From 7f11b2800ddb557aa2f3fbedcc057ffbe0657c1d Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Tue, 4 Dec 2018 20:20:27 +1000 Subject: [PATCH] Added an option to switch reorder modes --- .../java/com/sk89q/worldedit/EditSession.java | 122 ++++++++++++++---- .../com/sk89q/worldedit/LocalSession.java | 19 +++ .../worldedit/command/GeneralCommands.java | 24 ++++ .../extent/reorder/MultiStageReorder.java | 2 +- .../extent/world/FastModeExtent.java | 9 +- 5 files changed, 145 insertions(+), 31 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 5088a2bdf..f2155a3e8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -149,6 +149,38 @@ public class EditSession implements Extent, AutoCloseable { BEFORE_CHANGE } + /** + * Reorder mode for {@link EditSession#setReorderMode(ReorderMode)}. + * + * MULTI_STAGE = Multi stage reorder, may not be great with mods. + * FAST = Use the fast mode. Good for mods. + * NONE = Place blocks without worrying about placement order. + */ + public enum ReorderMode { + MULTI_STAGE("multi"), + FAST("fast"), + NONE("none"); + + private String name; + + ReorderMode(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public static ReorderMode getFromName(String name) { + for (ReorderMode mode : values()) { + if (mode.getName().equalsIgnoreCase(name)) { + return mode; + } + } + return null; + } + } + @SuppressWarnings("ProtectedField") protected final World world; private final ChangeSet changeSet = new BlockOptimizedHistory(); @@ -170,7 +202,7 @@ public class EditSession implements Extent, AutoCloseable { private final Extent bypassHistory; private final Extent bypassNone; - private final boolean useFastModeCorrections; + private ReorderMode reorderMode = ReorderMode.MULTI_STAGE; private Mask oldMask; @@ -189,13 +221,12 @@ public class EditSession implements Extent, AutoCloseable { checkNotNull(event); this.world = world; - this.useFastModeCorrections = false; if (world != null) { Extent extent; // These extents are ALWAYS used - extent = fastModeExtent = new FastModeExtent(world, useFastModeCorrections); + extent = fastModeExtent = new FastModeExtent(world, false); extent = survivalExtent = new SurvivalModeExtent(extent, world); extent = quirkExtent = new BlockQuirkExtent(extent, world); extent = chunkLoadingExtent = new ChunkLoadingExtent(extent, world); @@ -240,13 +271,13 @@ public class EditSession implements Extent, AutoCloseable { // pkg private for TracedEditSession only, may later become public API boolean commitRequired() { - if (isQueueEnabled() && reorderExtent.commitRequired()) { + if (reorderExtent.commitRequired()) { return true; } if (isBatchingChunks() && chunkBatchingExtent.commitRequired()) { return true; } - if (hasFastMode() && fastModeExtent.commitRequired()) { + if (fastModeExtent != null && fastModeExtent.commitRequired()) { return true; } return false; @@ -254,14 +285,60 @@ public class EditSession implements Extent, AutoCloseable { /** * Turns on specific features for a normal WorldEdit session, such as - * {@link #enableQueue() queuing} and {@link #setBatchingChunks(boolean) + * {@link #setReorderMode(ReorderMode)} reordering} and {@link #setBatchingChunks(boolean) * chunk batching}. */ public void enableStandardMode() { - enableQueue(); + setReorderMode(ReorderMode.MULTI_STAGE); setBatchingChunks(true); } + /** + * Sets the {@link ReorderMode} of this EditSession. + * + * @param reorderMode The reorder mode + */ + public void setReorderMode(ReorderMode reorderMode) { + if (reorderMode == ReorderMode.FAST && fastModeExtent == null) { + throw new IllegalArgumentException("An EditSession without a fast mode tried to use it for reordering!"); + } + if (reorderMode == ReorderMode.MULTI_STAGE && reorderExtent == null) { + throw new IllegalArgumentException("An EditSession without a reorder extent tried to use it for reordering!"); + } + this.reorderMode = reorderMode; + switch (reorderMode) { + case MULTI_STAGE: + if (fastModeExtent != null) { + fastModeExtent.setPostEditSimulationEnabled(false); + } + reorderExtent.setEnabled(true); + break; + case FAST: + fastModeExtent.setPostEditSimulationEnabled(true); + if (reorderExtent != null) { + reorderExtent.setEnabled(false); + } + break; + case NONE: + if (fastModeExtent != null) { + fastModeExtent.setPostEditSimulationEnabled(false); + } + if (reorderExtent != null) { + reorderExtent.setEnabled(false); + } + break; + } + } + + /** + * Get the reorder mode. + * + * @return the reorder mode + */ + public ReorderMode getReorderMode() { + return reorderMode; + } + /** * Get the world. * @@ -305,26 +382,31 @@ public class EditSession implements Extent, AutoCloseable { * @return whether the queue is enabled */ public boolean isQueueEnabled() { - return !useFastModeCorrections && reorderExtent.isEnabled(); + return reorderMode == ReorderMode.MULTI_STAGE && reorderExtent.isEnabled(); } /** * Queue certain types of block for better reproduction of those blocks. + * + * Uses {@link ReorderMode#MULTI_STAGE} + * @deprecated Use {@link EditSession#setReorderMode(ReorderMode)} with MULTI_STAGE instead. */ + @Deprecated public void enableQueue() { - if (!useFastModeCorrections) { - reorderExtent.setEnabled(true); - } + setReorderMode(ReorderMode.MULTI_STAGE); } /** * Disable the queue. This will {@linkplain #flushSession() flush the session}. + * + * @deprecated Use {@link EditSession#setReorderMode(ReorderMode)} with another mode instead. */ + @Deprecated public void disableQueue() { if (isQueueEnabled()) { flushSession(); } - reorderExtent.setEnabled(false); + setReorderMode(ReorderMode.NONE); } /** @@ -369,14 +451,7 @@ public class EditSession implements Extent, AutoCloseable { */ public void setFastMode(boolean enabled) { if (fastModeExtent != null) { - // If fast mode corrections are enabled, we're using fast mode for - // multipass support. Thus, we do not actually ever turn the fast mode - // extent off, we instead toggle post edit simulation - if (useFastModeCorrections) { - fastModeExtent.setPostEditSimulationEnabled(!enabled); - } else { - fastModeExtent.setEnabled(enabled); - } + fastModeExtent.setEnabled(enabled); } } @@ -451,16 +526,15 @@ public class EditSession implements Extent, AutoCloseable { /** * Disable all buffering extents. * - * @see #disableQueue() + * @see #setReorderMode(ReorderMode) * @see #setBatchingChunks(boolean) */ public void disableBuffering() { // We optimize here to avoid repeated calls to flushSession. - boolean needsFlush = isQueueEnabled() || isBatchingChunks(); - if (needsFlush) { + if (commitRequired()) { flushSession(); } - reorderExtent.setEnabled(false); + setReorderMode(ReorderMode.NONE); if (chunkBatchingExtent != null) { chunkBatchingExtent.setEnabled(false); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index ee1c038fe..1133c6e7b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -93,6 +93,7 @@ public class LocalSession { private transient Mask mask; private transient TimeZone timezone = TimeZone.getDefault(); private transient BlockVector3 cuiTemporaryBlock; + private transient EditSession.ReorderMode reorderMode = EditSession.ReorderMode.MULTI_STAGE; // Saved properties private String lastScript; @@ -877,6 +878,24 @@ public class LocalSession { this.fastMode = fastMode; } + /** + * Gets the reorder mode of the session. + * + * @return The reorder mode + */ + public EditSession.ReorderMode getReorderMode() { + return reorderMode; + } + + /** + * Sets the reorder mode of the session. + * + * @param reorderMode The reorder mode + */ + public void setReorderMode(EditSession.ReorderMode reorderMode) { + this.reorderMode = reorderMode; + } + /** * Get the mask. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java index 862b4398d..a2e051493 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java @@ -115,6 +115,30 @@ public class GeneralCommands { } } + @Command( + aliases = { "/reorder" }, + usage = "[multi|fast|none]", + desc = "Sets the reorder mode of WorldEdit", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.reorder") + public void reorderMode(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + String newState = args.getString(0, null); + if (newState == null) { + player.print("The reorder mode is " + session.getReorderMode().getName()); + } else { + EditSession.ReorderMode reorderMode = EditSession.ReorderMode.getFromName(newState); + if (reorderMode == null) { + player.printError("Unknown reorder mode!"); + return; + } + + session.setReorderMode(reorderMode); + player.print("The reorder mode is now " + session.getReorderMode().getName()); + } + } + @Command( aliases = { "/drawsel" }, usage = "[on|off]", diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java index f741ff1b3..2be03cbae 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/MultiStageReorder.java @@ -99,7 +99,7 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder } public boolean commitRequired() { - return stages.stream().anyMatch(stage -> stage.size() > 0); + return enabled && stages.stream().anyMatch(stage -> stage.size() > 0); } /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/FastModeExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/FastModeExtent.java index 9ca43b63f..ad92c6a45 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/FastModeExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/FastModeExtent.java @@ -67,9 +67,6 @@ public class FastModeExtent extends AbstractDelegateExtent { checkNotNull(world); this.world = world; this.enabled = enabled; - if (enabled) { - this.postEditSimulation = true; - } } /** @@ -100,11 +97,11 @@ public class FastModeExtent extends AbstractDelegateExtent { @Override public boolean setBlock(BlockVector3 location, BlockStateHolder block) throws WorldEditException { - if (enabled) { + if (enabled || postEditSimulation) { dirtyChunks.add(BlockVector2.at(location.getBlockX() >> 4, location.getBlockZ() >> 4)); if (world.setBlock(location, block, false)) { - if (postEditSimulation) { + if (!enabled && postEditSimulation) { positions.add(location); } return true; @@ -129,7 +126,7 @@ public class FastModeExtent extends AbstractDelegateExtent { world.fixAfterFastMode(dirtyChunks); } - if (postEditSimulation) { + if (!enabled && postEditSimulation) { Iterator positionIterator = positions.iterator(); while (run.shouldContinue() && positionIterator.hasNext()) { BlockVector3 position = positionIterator.next();