From 2edf3559d85632b26c639c9a00b23fe6437b461a Mon Sep 17 00:00:00 2001 From: TomyLobo Date: Tue, 1 Nov 2011 17:43:59 +0100 Subject: [PATCH] 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. --- .../java/com/sk89q/worldedit/EditSession.java | 45 ++++++++++++++----- .../com/sk89q/worldedit/blocks/BlockType.java | 33 +++++++++++--- 2 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java index 042773e1a..0af77f520 100644 --- a/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/src/main/java/com/sk89q/worldedit/EditSession.java @@ -56,34 +56,41 @@ public class EditSession { * Random number generator. */ private static Random prng = new Random(); + /** * World. */ protected LocalWorld world; + /** * Stores the original blocks before modification. */ private DoubleArrayList original = - new DoubleArrayList( - true); + new DoubleArrayList(true); + /** * Stores the current blocks. */ private DoubleArrayList current = - new DoubleArrayList( - false); + new DoubleArrayList(false); + /** * Blocks that should be placed before last. */ private DoubleArrayList queueAfter = - new DoubleArrayList( - false); + new DoubleArrayList(false); + /** * Blocks that should be placed last. */ private DoubleArrayList queueLast = - new DoubleArrayList( - false); + new DoubleArrayList(false); + + /** + * Blocks that should be placed after all other blocks. + */ + private DoubleArrayList queueFinal = + new DoubleArrayList(false); /** * 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) { if (queued) { - // Place torches, etc. last if (BlockType.shouldPlaceLast(block.getType())) { + // Place torches, etc. last queueLast.put(pt.toBlockVector(), block); return !(getBlockType(pt) == block.getType() && 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))) { + // Destroy torches, etc. first rawSetBlock(pt, new BaseBlock(BlockID.AIR)); } else { 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 // because it might cause the items to drop if (blockBag == null || missingBlocks.size() == 0) { + for (Map.Entry 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 blocks = new HashSet(); final Map blockTypes = new HashMap(); - for (Map.Entry entry : queueLast) { + for (Map.Entry entry : queueFinal) { final BlockVector pt = entry.getKey(); blocks.add(pt); blockTypes.put(pt, entry.getValue()); @@ -802,6 +824,7 @@ public class EditSession { queueAfter.clear(); queueLast.clear(); + queueFinal.clear(); } /** diff --git a/src/main/java/com/sk89q/worldedit/blocks/BlockType.java b/src/main/java/com/sk89q/worldedit/blocks/BlockType.java index 801b61671..9f70afe33 100644 --- a/src/main/java/com/sk89q/worldedit/blocks/BlockType.java +++ b/src/main/java/com/sk89q/worldedit/blocks/BlockType.java @@ -303,23 +303,16 @@ public enum BlockType { shouldPlaceLast.add(BlockID.FIRE); shouldPlaceLast.add(BlockID.REDSTONE_WIRE); shouldPlaceLast.add(BlockID.CROPS); - shouldPlaceLast.add(BlockID.SIGN_POST); - shouldPlaceLast.add(BlockID.WOODEN_DOOR); shouldPlaceLast.add(BlockID.LADDER); shouldPlaceLast.add(BlockID.MINECART_TRACKS); - shouldPlaceLast.add(BlockID.WALL_SIGN); shouldPlaceLast.add(BlockID.LEVER); shouldPlaceLast.add(BlockID.STONE_PRESSURE_PLATE); - shouldPlaceLast.add(BlockID.IRON_DOOR); shouldPlaceLast.add(BlockID.WOODEN_PRESSURE_PLATE); shouldPlaceLast.add(BlockID.REDSTONE_TORCH_OFF); shouldPlaceLast.add(BlockID.REDSTONE_TORCH_ON); shouldPlaceLast.add(BlockID.STONE_BUTTON); shouldPlaceLast.add(BlockID.SNOW); - shouldPlaceLast.add(BlockID.CACTUS); - shouldPlaceLast.add(BlockID.REED); shouldPlaceLast.add(BlockID.PORTAL); - shouldPlaceLast.add(BlockID.CAKE_BLOCK); shouldPlaceLast.add(BlockID.REDSTONE_REPEATER_OFF); shouldPlaceLast.add(BlockID.REDSTONE_REPEATER_ON); shouldPlaceLast.add(BlockID.TRAP_DOOR); @@ -347,6 +340,32 @@ public enum BlockType { return shouldPlaceLast.contains(id); } + /** + * HashSet for shouldPlaceLast. + */ + private static final Set shouldPlaceFinal = new HashSet(); + 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. */