EditSession: Split off a queueFinal, which contains only blocks that can be attached to other attached blocks.

This a speed improvement, since the recursive attachment checker turned out to be quite slow.
This commit is contained in:
TomyLobo 2011-11-01 17:43:59 +01:00
parent 2ee36f7484
commit 2edf3559d8
2 changed files with 60 additions and 18 deletions

View File

@ -56,34 +56,41 @@ public class EditSession {
* Random number generator. * Random number generator.
*/ */
private static Random prng = new Random(); private static Random prng = new Random();
/** /**
* World. * World.
*/ */
protected LocalWorld world; protected LocalWorld world;
/** /**
* Stores the original blocks before modification. * Stores the original blocks before modification.
*/ */
private DoubleArrayList<BlockVector, BaseBlock> original = private DoubleArrayList<BlockVector, BaseBlock> original =
new DoubleArrayList<BlockVector, BaseBlock>( new DoubleArrayList<BlockVector, BaseBlock>(true);
true);
/** /**
* Stores the current blocks. * Stores the current blocks.
*/ */
private DoubleArrayList<BlockVector, BaseBlock> current = private DoubleArrayList<BlockVector, BaseBlock> current =
new DoubleArrayList<BlockVector, BaseBlock>( new DoubleArrayList<BlockVector, BaseBlock>(false);
false);
/** /**
* Blocks that should be placed before last. * Blocks that should be placed before last.
*/ */
private DoubleArrayList<BlockVector, BaseBlock> queueAfter = private DoubleArrayList<BlockVector, BaseBlock> queueAfter =
new DoubleArrayList<BlockVector, BaseBlock>( new DoubleArrayList<BlockVector, BaseBlock>(false);
false);
/** /**
* Blocks that should be placed last. * Blocks that should be placed last.
*/ */
private DoubleArrayList<BlockVector, BaseBlock> queueLast = private DoubleArrayList<BlockVector, BaseBlock> queueLast =
new DoubleArrayList<BlockVector, BaseBlock>( new DoubleArrayList<BlockVector, BaseBlock>(false);
false);
/**
* Blocks that should be placed after all other blocks.
*/
private DoubleArrayList<BlockVector, BaseBlock> queueFinal =
new DoubleArrayList<BlockVector, BaseBlock>(false);
/** /**
* The maximum number of blocks to change at a time. If this number is * The maximum number of blocks to change at a time. If this number is
@ -317,13 +324,18 @@ public class EditSession {
*/ */
public boolean smartSetBlock(Vector pt, BaseBlock block) { public boolean smartSetBlock(Vector pt, BaseBlock block) {
if (queued) { if (queued) {
// Place torches, etc. last
if (BlockType.shouldPlaceLast(block.getType())) { if (BlockType.shouldPlaceLast(block.getType())) {
// Place torches, etc. last
queueLast.put(pt.toBlockVector(), block); queueLast.put(pt.toBlockVector(), block);
return !(getBlockType(pt) == block.getType() return !(getBlockType(pt) == block.getType()
&& getBlockData(pt) == block.getData()); && getBlockData(pt) == block.getData());
// Destroy torches, etc. first } else if (BlockType.shouldPlaceFinal(block.getType())) {
// Place signs, reed, etc even later
queueFinal.put(pt.toBlockVector(), block);
return !(getBlockType(pt) == block.getType()
&& getBlockData(pt) == block.getData());
} else if (BlockType.shouldPlaceLast(getBlockType(pt))) { } else if (BlockType.shouldPlaceLast(getBlockType(pt))) {
// Destroy torches, etc. first
rawSetBlock(pt, new BaseBlock(BlockID.AIR)); rawSetBlock(pt, new BaseBlock(BlockID.AIR));
} else { } else {
queueAfter.put(pt.toBlockVector(), block); queueAfter.put(pt.toBlockVector(), block);
@ -729,9 +741,19 @@ public class EditSession {
// We don't want to place these blocks if other blocks were missing // We don't want to place these blocks if other blocks were missing
// because it might cause the items to drop // because it might cause the items to drop
if (blockBag == null || missingBlocks.size() == 0) { if (blockBag == null || missingBlocks.size() == 0) {
for (Map.Entry<BlockVector, BaseBlock> entry : queueLast) {
BlockVector pt = (BlockVector) entry.getKey();
rawSetBlock(pt, (BaseBlock) entry.getValue());
// TODO: use ChunkStore.toChunk(pt) after optimizing it.
if (fastMode) {
dirtyChunks.add(new BlockVector2D(pt.getBlockX() >> 4, pt.getBlockZ() >> 4));
}
}
final Set<BlockVector> blocks = new HashSet<BlockVector>(); final Set<BlockVector> blocks = new HashSet<BlockVector>();
final Map<BlockVector, BaseBlock> blockTypes = new HashMap<BlockVector, BaseBlock>(); final Map<BlockVector, BaseBlock> blockTypes = new HashMap<BlockVector, BaseBlock>();
for (Map.Entry<BlockVector, BaseBlock> entry : queueLast) { for (Map.Entry<BlockVector, BaseBlock> entry : queueFinal) {
final BlockVector pt = entry.getKey(); final BlockVector pt = entry.getKey();
blocks.add(pt); blocks.add(pt);
blockTypes.put(pt, entry.getValue()); blockTypes.put(pt, entry.getValue());
@ -802,6 +824,7 @@ public class EditSession {
queueAfter.clear(); queueAfter.clear();
queueLast.clear(); queueLast.clear();
queueFinal.clear();
} }
/** /**

View File

@ -303,23 +303,16 @@ public enum BlockType {
shouldPlaceLast.add(BlockID.FIRE); shouldPlaceLast.add(BlockID.FIRE);
shouldPlaceLast.add(BlockID.REDSTONE_WIRE); shouldPlaceLast.add(BlockID.REDSTONE_WIRE);
shouldPlaceLast.add(BlockID.CROPS); shouldPlaceLast.add(BlockID.CROPS);
shouldPlaceLast.add(BlockID.SIGN_POST);
shouldPlaceLast.add(BlockID.WOODEN_DOOR);
shouldPlaceLast.add(BlockID.LADDER); shouldPlaceLast.add(BlockID.LADDER);
shouldPlaceLast.add(BlockID.MINECART_TRACKS); shouldPlaceLast.add(BlockID.MINECART_TRACKS);
shouldPlaceLast.add(BlockID.WALL_SIGN);
shouldPlaceLast.add(BlockID.LEVER); shouldPlaceLast.add(BlockID.LEVER);
shouldPlaceLast.add(BlockID.STONE_PRESSURE_PLATE); shouldPlaceLast.add(BlockID.STONE_PRESSURE_PLATE);
shouldPlaceLast.add(BlockID.IRON_DOOR);
shouldPlaceLast.add(BlockID.WOODEN_PRESSURE_PLATE); shouldPlaceLast.add(BlockID.WOODEN_PRESSURE_PLATE);
shouldPlaceLast.add(BlockID.REDSTONE_TORCH_OFF); shouldPlaceLast.add(BlockID.REDSTONE_TORCH_OFF);
shouldPlaceLast.add(BlockID.REDSTONE_TORCH_ON); shouldPlaceLast.add(BlockID.REDSTONE_TORCH_ON);
shouldPlaceLast.add(BlockID.STONE_BUTTON); shouldPlaceLast.add(BlockID.STONE_BUTTON);
shouldPlaceLast.add(BlockID.SNOW); shouldPlaceLast.add(BlockID.SNOW);
shouldPlaceLast.add(BlockID.CACTUS);
shouldPlaceLast.add(BlockID.REED);
shouldPlaceLast.add(BlockID.PORTAL); shouldPlaceLast.add(BlockID.PORTAL);
shouldPlaceLast.add(BlockID.CAKE_BLOCK);
shouldPlaceLast.add(BlockID.REDSTONE_REPEATER_OFF); shouldPlaceLast.add(BlockID.REDSTONE_REPEATER_OFF);
shouldPlaceLast.add(BlockID.REDSTONE_REPEATER_ON); shouldPlaceLast.add(BlockID.REDSTONE_REPEATER_ON);
shouldPlaceLast.add(BlockID.TRAP_DOOR); shouldPlaceLast.add(BlockID.TRAP_DOOR);
@ -347,6 +340,32 @@ public enum BlockType {
return shouldPlaceLast.contains(id); return shouldPlaceLast.contains(id);
} }
/**
* HashSet for shouldPlaceLast.
*/
private static final Set<Integer> shouldPlaceFinal = new HashSet<Integer>();
static {
shouldPlaceLast.add(BlockID.SIGN_POST);
shouldPlaceLast.add(BlockID.WOODEN_DOOR);
shouldPlaceLast.add(BlockID.WALL_SIGN);
shouldPlaceLast.add(BlockID.IRON_DOOR);
shouldPlaceLast.add(BlockID.CACTUS);
shouldPlaceLast.add(BlockID.REED);
shouldPlaceLast.add(BlockID.CAKE_BLOCK);
}
/**
* 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 id
* @return
*/
public static boolean shouldPlaceFinal(int id) {
return shouldPlaceFinal.contains(id);
}
/** /**
* HashSet for canPassThrough. * HashSet for canPassThrough.
*/ */