Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Added the multi-staging from the multipass2 branch
  • Loading branch information
me4502 committed Oct 15, 2018
1 parent dd2fcba commit aff05d6
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 43 deletions.
Expand Up @@ -36,6 +36,28 @@ public final class Blocks {
private Blocks() {
}

/**
* HashSet for shouldPlaceLate.
*/
private static final Set<BlockType> shouldPlaceLate = new HashSet<>();
static {
shouldPlaceLate.add(BlockTypes.WATER);
shouldPlaceLate.add(BlockTypes.LAVA);
shouldPlaceLate.add(BlockTypes.GRAVEL);
shouldPlaceLate.add(BlockTypes.SAND);
}
/**
* Checks to see whether a block should be placed in the final queue.
*
* This applies to blocks that can be attached to other blocks that have an attachment.
*
* @param type the type of the block
* @return whether the block is in the late queue
*/
public static boolean shouldPlaceLate(BlockType type) {
return shouldPlaceLate.contains(type);
}

/**
* HashSet for shouldPlaceLast.
*/
Expand Down
Expand Up @@ -19,7 +19,6 @@

package com.sk89q.worldedit.extent.reorder;

import com.google.common.collect.Iterables;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
Expand All @@ -38,6 +37,7 @@
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;

import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
Expand All @@ -51,29 +51,34 @@
*/
public class MultiStageReorder extends AbstractDelegateExtent implements ReorderingExtent {

private LocatedBlockList stage1 = new LocatedBlockList();
private LocatedBlockList stage2 = new LocatedBlockList();
private LocatedBlockList stage3 = new LocatedBlockList();
private static final int STAGE_COUNT = 4;

private List<LocatedBlockList> stages = new ArrayList<>();

private boolean enabled;

/**
* Create a new instance.
* Create a new instance when the re-ordering is enabled.
*
* @param extent the extent
* @param enabled true to enable
*/
public MultiStageReorder(Extent extent, boolean enabled) {
super(extent);
this.enabled = enabled;
public MultiStageReorder(Extent extent) {
this(extent, true);
}

/**
* Create a new instance when the re-ordering is enabled.
* Create a new instance.
*
* @param extent the extent
* @param enabled true to enable
*/
public MultiStageReorder(Extent extent) {
this(extent, true);
public MultiStageReorder(Extent extent, boolean enabled) {
super(extent);
this.enabled = enabled;

for (int i = 0; i < STAGE_COUNT; ++i) {
stages.add(new LocatedBlockList());
}
}

/**
Expand All @@ -94,55 +99,73 @@ public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

/**
* Gets the stage priority of the block.
*
* @param block The block
* @return The priority
*/
public int getPlacementPriority(BlockStateHolder block) {
if (Blocks.shouldPlaceLate(block.getBlockType())) {
return 1;
} else if (Blocks.shouldPlaceLast(block.getBlockType())) {
// Place torches, etc. last
return 2;
} else if (Blocks.shouldPlaceFinal(block.getBlockType())) {
// Place signs, reed, etc even later
return 3;
} else {
return 0;
}
}

@Override
public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
BlockState existing = getBlock(location);

if (!enabled) {
return super.setBlock(location, block);
}

if (Blocks.shouldPlaceLast(block.getBlockType())) {
// Place torches, etc. last
stage2.add(location.toBlockVector(), block);
return !existing.equalsFuzzy(block);
} else if (Blocks.shouldPlaceFinal(block.getBlockType())) {
// Place signs, reed, etc even later
stage3.add(location.toBlockVector(), block);
return !existing.equalsFuzzy(block);
} else if (Blocks.shouldPlaceLast(existing.getBlockType())) {
BlockState existing = getBlock(location);
int priority = getPlacementPriority(block);
int srcPriority = getPlacementPriority(existing);

if (srcPriority == 1 || srcPriority == 2) {
// Destroy torches, etc. first
super.setBlock(location, BlockTypes.AIR.getDefaultState());
return super.setBlock(location, block);
} else {
stage1.add(location.toBlockVector(), block);
return !existing.equalsFuzzy(block);
}

stages.get(priority).add(location.toBlockPoint(), block);
return !existing.equalsFuzzy(block);
}

@Override
public Operation commitBefore() {
return new OperationQueue(
new SetLocatedBlocks(
getExtent(),
Iterables.concat(stage1, stage2)),
new Stage3Committer());
List<Operation> operations = new ArrayList<>();
for (int i = 0; i < stages.size() - 1; ++i) {
operations.add(new SetLocatedBlocks(getExtent(), stages.get(i)));
}

operations.add(new FinalStageCommitter());
return new OperationQueue(operations);
}

private class Stage3Committer implements Operation {
private class FinalStageCommitter implements Operation {
private Extent extent = getExtent();

@Override
public Operation resume(RunContext run) throws WorldEditException {
Extent extent = getExtent();
private final Set<BlockVector> blocks = new HashSet<>();
private final Map<BlockVector, BlockStateHolder> blockTypes = new HashMap<>();

final Set<BlockVector> blocks = new HashSet<>();
final Map<BlockVector, BlockStateHolder> blockTypes = new HashMap<>();
for (LocatedBlock entry : stage3) {
public FinalStageCommitter() {
for (LocatedBlock entry : stages.get(stages.size() - 1)) {
final BlockVector pt = entry.getLocation().toBlockVector();
blocks.add(pt);
blockTypes.put(pt, entry.getBlock());
}
}

@Override
public Operation resume(RunContext run) throws WorldEditException {
while (!blocks.isEmpty()) {
BlockVector current = blocks.iterator().next();
if (!blocks.contains(current)) {
Expand Down Expand Up @@ -198,11 +221,14 @@ public Operation resume(RunContext run) throws WorldEditException {
}
}

stage1.clear();
stage2.clear();
stage3.clear();
if (blocks.isEmpty()) {
for (LocatedBlockList stage : stages) {
stage.clear();
}
return null;
}

return null;
return this;
}

@Override
Expand Down
Expand Up @@ -35,10 +35,24 @@ public class ArrayListHistory implements ChangeSet {

private final List<Change> changes = new ArrayList<>();

private boolean recordChanges = true;

@Override
public void add(Change change) {
checkNotNull(change);
changes.add(change);
if (recordChanges) {
changes.add(change);
}
}

@Override
public boolean isRecordingChanges() {
return recordChanges;
}

@Override
public void setRecordChanges(boolean recordChanges) {
this.recordChanges = recordChanges;
}

@Override
Expand Down
Expand Up @@ -36,6 +36,19 @@ public interface ChangeSet {
*/
void add(Change change);

/**
* Whether or not the ChangeSet is recording changes.
*
* @return whether or not the ChangeSet is set to record changes
*/
boolean isRecordingChanges();
/**
* Tell the change set whether to record changes or not.
*
* @param recordChanges whether to record changes or not
*/
void setRecordChanges(boolean recordChanges);

/**
* Get a backward directed iterator that can be used for undo.
*
Expand Down

0 comments on commit aff05d6

Please sign in to comment.