Added the multi-staging from the multipass2 branch

This commit is contained in:
Matthew Miller 2018-10-15 16:12:21 +10:00 committed by IronApollo
parent 63bf01fdaf
commit 346eee8953
3 changed files with 101 additions and 70 deletions

View File

@ -36,6 +36,28 @@ public final class Blocks {
private 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. * HashSet for shouldPlaceLast.
*/ */

View File

@ -19,26 +19,24 @@
package com.sk89q.worldedit.extent.reorder; package com.sk89q.worldedit.extent.reorder;
import com.google.common.collect.Iterators;
import com.google.common.collect.Iterables;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.Blocks; import com.sk89q.worldedit.blocks.Blocks;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.operation.BlockMapEntryPlacer;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.OperationQueue; import com.sk89q.worldedit.function.operation.OperationQueue;
import com.sk89q.worldedit.function.operation.RunContext; import com.sk89q.worldedit.function.operation.RunContext;
//import com.sk89q.worldedit.function.operation.SetLocatedBlocks; import com.sk89q.worldedit.function.operation.SetLocatedBlocks;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.LocatedBlock; import com.sk89q.worldedit.util.LocatedBlock;
import com.sk89q.worldedit.util.collection.TupleArrayList; import com.sk89q.worldedit.util.collection.LocatedBlockList;
import com.sk89q.worldedit.world.block.BlockCategories; import com.sk89q.worldedit.world.block.BlockCategories;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.ArrayList;
import java.util.Deque; import java.util.Deque;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -52,11 +50,21 @@ import java.util.Set;
*/ */
public class MultiStageReorder extends AbstractDelegateExtent implements ReorderingExtent { public class MultiStageReorder extends AbstractDelegateExtent implements ReorderingExtent {
private TupleArrayList<BlockVector3, BlockStateHolder> stage1 = new TupleArrayList<>(); private static final int STAGE_COUNT = 4;
private TupleArrayList<BlockVector3, BlockStateHolder> stage2 = new TupleArrayList<>();
private TupleArrayList<BlockVector3, BlockStateHolder> stage3 = new TupleArrayList<>(); private List<LocatedBlockList> stages = new ArrayList<>();
private boolean enabled; private boolean enabled;
/**
* Create a new instance when the re-ordering is enabled.
*
* @param extent the extent
*/
public MultiStageReorder(Extent extent) {
this(extent, true);
}
/** /**
* Create a new instance. * Create a new instance.
* *
@ -66,15 +74,10 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
public MultiStageReorder(Extent extent, boolean enabled) { public MultiStageReorder(Extent extent, boolean enabled) {
super(extent); super(extent);
this.enabled = enabled; this.enabled = enabled;
}
/** for (int i = 0; i < STAGE_COUNT; ++i) {
* Create a new instance when the re-ordering is enabled. stages.add(new LocatedBlockList());
* }
* @param extent the extent
*/
public MultiStageReorder(Extent extent) {
this(extent, true);
} }
/** /**
@ -95,74 +98,77 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
this.enabled = enabled; this.enabled = enabled;
} }
public boolean commitRequired() {
return stages.stream().anyMatch(stage -> stage.size() > 0);
}
/**
* 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 @Override
public boolean setBlock(BlockVector3 location, BlockStateHolder block) throws WorldEditException { public boolean setBlock(BlockVector3 location, BlockStateHolder block) throws WorldEditException {
BlockState existing = getBlock(location);
if (!enabled) { if (!enabled) {
return super.setBlock(location, block); return super.setBlock(location, block);
} }
if (Blocks.shouldPlaceLast(block.getBlockType())) { BlockState existing = getBlock(location);
// Place torches, etc. last int priority = getPlacementPriority(block);
//<<<<<<< HEAD int srcPriority = getPlacementPriority(existing);
stage2.put(location, block);
return !existing.equalsFuzzy(block); if (srcPriority == 1 || srcPriority == 2) {
} else if (Blocks.shouldPlaceFinal(block.getBlockType())) {
// Place signs, reed, etc even later
stage3.put(location, block);
//=======
// stage2.add(location, block);
// return !existing.equalsFuzzy(block);
// } else if (Blocks.shouldPlaceFinal(block.getBlockType())) {
// // Place signs, reed, etc even later
// stage3.add(location, block);
//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
return !existing.equalsFuzzy(block);
} else if (Blocks.shouldPlaceLast(existing.getBlockType())) {
// Destroy torches, etc. first // Destroy torches, etc. first
super.setBlock(location, BlockTypes.AIR.getDefaultState()); super.setBlock(location, BlockTypes.AIR.getDefaultState());
return super.setBlock(location, block); return super.setBlock(location, block);
} else {
//<<<<<<< HEAD
stage1.put(location, block);
//=======
// stage1.add(location, block);
//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
return !existing.equalsFuzzy(block);
} }
stages.get(priority).add(location, block);
return !existing.equalsFuzzy(block);
} }
@Override @Override
public Operation commitBefore() { public Operation commitBefore() {
return new OperationQueue( List<Operation> operations = new ArrayList<>();
new BlockMapEntryPlacer( for (int i = 0; i < stages.size() - 1; ++i) {
getExtent(), operations.add(new SetLocatedBlocks(getExtent(), stages.get(i)));
Iterators.concat(stage1.iterator(), stage2.iterator())),
new Stage3Committer());
} }
private class Stage3Committer implements Operation { operations.add(new FinalStageCommitter());
return new OperationQueue(operations);
}
private class FinalStageCommitter implements Operation {
private Extent extent = getExtent();
private final Set<BlockVector3> blocks = new HashSet<>();
private final Map<BlockVector3, BlockStateHolder> blockTypes = new HashMap<>();
public FinalStageCommitter() {
for (LocatedBlock entry : stages.get(stages.size() - 1)) {
final BlockVector3 pt = entry.getLocation();
blocks.add(pt);
blockTypes.put(pt, entry.getBlock());
}
}
@Override @Override
public Operation resume(RunContext run) throws WorldEditException { public Operation resume(RunContext run) throws WorldEditException {
Extent extent = getExtent();
//<<<<<<< HEAD
final Set<BlockVector3> blocks = new HashSet<>();
final Map<BlockVector3, BlockStateHolder> blockTypes = new HashMap<>();
for (Map.Entry<BlockVector3, BlockStateHolder> entry : stage3) {
final BlockVector3 pt = entry.getKey();
//=======
// final Set<BlockVector3> blocks = new HashSet<>();
// final Map<BlockVector3, BlockStateHolder> blockTypes = new HashMap<>();
// for (LocatedBlock entry : stage3) {
// final BlockVector3 pt = entry.getLocation();
//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
blocks.add(pt);
blockTypes.put(pt, entry.getValue());
}
while (!blocks.isEmpty()) { while (!blocks.isEmpty()) {
BlockVector3 current = blocks.iterator().next(); BlockVector3 current = blocks.iterator().next();
if (!blocks.contains(current)) { if (!blocks.contains(current)) {
@ -218,13 +224,16 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
} }
} }
stage1.clear(); if (blocks.isEmpty()) {
stage2.clear(); for (LocatedBlockList stage : stages) {
stage3.clear(); stage.clear();
}
return null; return null;
} }
return this;
}
@Override @Override
public void cancel() { public void cancel() {
} }