Skip to content

Commit

Permalink
Merge pull request #432 from sk89q/feature/multipass3
Browse files Browse the repository at this point in the history
Added multi-pass fixing for MultiStageReorder, and a Fast-Mode equivalent
  • Loading branch information
me4502 committed Dec 11, 2018
2 parents 5acd0d8 + 926f6a6 commit 17f52cb
Show file tree
Hide file tree
Showing 18 changed files with 468 additions and 197 deletions.
Expand Up @@ -448,6 +448,17 @@ public BaseBlock getFullBlock(BlockVector3 position) {
}
}

@Override
public boolean notifyAndLightBlock(BlockVector3 position, com.sk89q.worldedit.world.block.BlockState previousType) throws WorldEditException {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
adapter.notifyAndLightBlock(BukkitAdapter.adapt(getWorld(), position), previousType);
return true;
}

return false;
}

@Override
public BaseBiome getBiome(BlockVector2 position) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
Expand Down
Expand Up @@ -24,6 +24,7 @@
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import org.bukkit.Location;
Expand Down Expand Up @@ -78,6 +79,15 @@ public interface BukkitImplAdapter {
*/
boolean setBlock(Location location, BlockStateHolder state, boolean notifyAndLight);

/**
* Notifies the simulation that the block at the given location has
* been changed and it must be re-lighted (and issue other events).
*
* @param position position of the block
* @param previousType the type of the previous block that was there
*/
void notifyAndLightBlock(Location position, BlockState previousType);

/**
* Get the state for the given entity.
*
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
119 changes: 108 additions & 11 deletions worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
Expand Up @@ -120,6 +120,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand Down Expand Up @@ -149,6 +150,38 @@ public enum Stage {
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 displayName;

ReorderMode(String displayName) {
this.displayName = displayName;
}

public String getDisplayName() {
return this.displayName;
}

public static Optional<ReorderMode> getFromDisplayName(String name) {
for (ReorderMode mode : values()) {
if (mode.getDisplayName().equalsIgnoreCase(name)) {
return Optional.of(mode);
}
}
return Optional.empty();
}
}

@SuppressWarnings("ProtectedField")
protected final World world;
private final ChangeSet changeSet = new BlockOptimizedHistory();
Expand All @@ -170,6 +203,8 @@ public enum Stage {
private final Extent bypassHistory;
private final Extent bypassNone;

private ReorderMode reorderMode = ReorderMode.MULTI_STAGE;

private Mask oldMask;

/**
Expand Down Expand Up @@ -226,6 +261,8 @@ public enum Stage {
this.bypassHistory = extent;
this.bypassNone = extent;
}

setReorderMode(this.reorderMode);
}

private Extent wrapExtent(Extent extent, EventBus eventBus, EditSessionEvent event, Stage stage) {
Expand All @@ -237,25 +274,77 @@ private Extent wrapExtent(Extent extent, EventBus eventBus, EditSessionEvent eve

// pkg private for TracedEditSession only, may later become public API
boolean commitRequired() {
if (isQueueEnabled() && reorderExtent.commitRequired()) {
if (reorderExtent != null && reorderExtent.commitRequired()) {
return true;
}
if (chunkBatchingExtent != null && chunkBatchingExtent.commitRequired()) {
return true;
}
if (isBatchingChunks() && chunkBatchingExtent.commitRequired()) {
if (fastModeExtent != null && fastModeExtent.commitRequired()) {
return true;
}
return false;
}

/**
* Turns on specific features for a normal WorldEdit session, such as
* {@link #enableQueue() queuing} and {@link #setBatchingChunks(boolean)
* {@link #setBatchingChunks(boolean)
* chunk batching}.
*/
public void enableStandardMode() {
enableQueue();
setBatchingChunks(true);
}

/**
* Sets the {@link ReorderMode} of this EditSession, and flushes the session.
*
* @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!");
}
if (commitRequired()) {
flushSession();
}

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.
*
Expand Down Expand Up @@ -297,26 +386,35 @@ public void setBlockChangeLimit(int limit) {
* Returns queue status.
*
* @return whether the queue is enabled
* @deprecated Use {@link EditSession#getReorderMode()} with MULTI_STAGE instead.
*/
@Deprecated
public boolean isQueueEnabled() {
return 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() {
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);
}

/**
Expand Down Expand Up @@ -436,16 +534,15 @@ public void setBatchingChunks(boolean batchingChunks) {
/**
* 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);
}
Expand Down
44 changes: 34 additions & 10 deletions worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java
Expand Up @@ -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;
Expand Down Expand Up @@ -225,11 +226,13 @@ public EditSession undo(@Nullable BlockBag newBlockBag, Player player) {
--historyPointer;
if (historyPointer >= 0) {
EditSession editSession = history.get(historyPointer);
EditSession newEditSession = WorldEdit.getInstance().getEditSessionFactory()
.getEditSession(editSession.getWorld(), -1, newBlockBag, player);
newEditSession.enableStandardMode();
newEditSession.setFastMode(fastMode);
editSession.undo(newEditSession);
try (EditSession newEditSession = WorldEdit.getInstance().getEditSessionFactory()
.getEditSession(editSession.getWorld(), -1, newBlockBag, player)) {
newEditSession.enableStandardMode();
newEditSession.setReorderMode(reorderMode);
newEditSession.setFastMode(fastMode);
editSession.undo(newEditSession);
}
return editSession;
} else {
historyPointer = 0;
Expand All @@ -248,11 +251,13 @@ public 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.enableStandardMode();
newEditSession.setFastMode(fastMode);
editSession.redo(newEditSession);
try (EditSession newEditSession = WorldEdit.getInstance().getEditSessionFactory()
.getEditSession(editSession.getWorld(), -1, newBlockBag, player)) {
newEditSession.enableStandardMode();
newEditSession.setReorderMode(reorderMode);
newEditSession.setFastMode(fastMode);
editSession.redo(newEditSession);
}
++historyPointer;
return editSession;
}
Expand Down Expand Up @@ -853,6 +858,7 @@ public EditSession createEditSession(Player player) {
.getEditSession(player.isPlayer() ? player.getWorld() : null,
getBlockChangeLimit(), blockBag, player);
editSession.setFastMode(fastMode);
editSession.setReorderMode(reorderMode);
Request.request().setEditSession(editSession);
editSession.setMask(mask);

Expand All @@ -877,6 +883,24 @@ public void setFastMode(boolean fastMode) {
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.
*
Expand Down

0 comments on commit 17f52cb

Please sign in to comment.