From 69ab1781c6b1070669173288abf0b5af9eb31925 Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Mon, 20 Aug 2018 15:57:42 +1000 Subject: [PATCH] Replace FuzzyBlockMask with BlockMask, and added BlockTypeMask as a more performant mask for just block types. --- .../java/com/sk89q/worldedit/EditSession.java | 14 +-- .../worldedit/command/BrushCommands.java | 4 +- .../worldedit/function/block/Naturalizer.java | 9 +- .../worldedit/function/mask/BlockMask.java | 4 +- .../function/mask/BlockTypeMask.java | 106 ++++++++++++++++++ .../function/mask/FuzzyBlockMask.java | 45 -------- .../sk89q/worldedit/world/AbstractWorld.java | 6 +- 7 files changed, 121 insertions(+), 67 deletions(-) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockTypeMask.java delete mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/FuzzyBlockMask.java diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index 722c88d71..fdbbb8e3b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -25,7 +25,6 @@ import static com.sk89q.worldedit.regions.Regions.asFlatRegion; import static com.sk89q.worldedit.regions.Regions.maximumBlockY; import static com.sk89q.worldedit.regions.Regions.minimumBlockY; -import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.event.extent.EditSessionEvent; @@ -51,9 +50,9 @@ import com.sk89q.worldedit.function.block.Counter; import com.sk89q.worldedit.function.block.Naturalizer; import com.sk89q.worldedit.function.generator.GardenPatchGenerator; import com.sk89q.worldedit.function.mask.BlockMask; +import com.sk89q.worldedit.function.mask.BlockTypeMask; import com.sk89q.worldedit.function.mask.BoundedHeightMask; import com.sk89q.worldedit.function.mask.ExistingBlockMask; -import com.sk89q.worldedit.function.mask.FuzzyBlockMask; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.MaskIntersection; import com.sk89q.worldedit.function.mask.MaskUnion; @@ -102,6 +101,7 @@ import com.sk89q.worldedit.util.eventbus.EventBus; import com.sk89q.worldedit.world.NullWorld; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BaseBiome; +import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockCategories; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; @@ -601,7 +601,7 @@ public class EditSession implements Extent { * @return the number of blocks that matched the pattern */ public int countBlocks(Region region, Set searchBlocks) { - FuzzyBlockMask mask = new FuzzyBlockMask(this, searchBlocks); + BlockMask mask = new BlockMask(this, searchBlocks); Counter count = new Counter(); RegionMaskingFilter filter = new RegionMaskingFilter(mask, count); RegionVisitor visitor = new RegionVisitor(region, filter); @@ -725,7 +725,7 @@ public class EditSession implements Extent { checkNotNull(position); checkArgument(apothem >= 1, "apothem >= 1"); - Mask mask = new FuzzyBlockMask(this, blockType.getDefaultState().toFuzzy()); + Mask mask = new BlockTypeMask(this, blockType); Vector adjustment = new Vector(1, 1, 1).multiply(apothem - 1); Region region = new CuboidRegion( getWorld(), // Causes clamping of Y range @@ -790,7 +790,7 @@ public class EditSession implements Extent { * @throws MaxChangedBlocksException thrown if too many blocks are changed */ public int replaceBlocks(Region region, Set filter, Pattern pattern) throws MaxChangedBlocksException { - Mask mask = filter == null ? new ExistingBlockMask(this) : new FuzzyBlockMask(this, filter); + Mask mask = filter == null ? new ExistingBlockMask(this) : new BlockMask(this, filter); return replaceBlocks(region, mask, pattern); } @@ -1141,10 +1141,10 @@ public class EditSession implements Extent { checkArgument(radius >= 0, "radius >= 0 required"); // Our origins can only be liquids - BlockMask liquidMask = new BlockMask(this, fluid.getDefaultState().toFuzzy()); + Mask liquidMask = new BlockTypeMask(this, fluid); // But we will also visit air blocks - MaskIntersection blockMask = new MaskUnion(liquidMask, new BlockMask(this, BlockTypes.AIR.getDefaultState())); + MaskIntersection blockMask = new MaskUnion(liquidMask, Masks.negate(new ExistingBlockMask(this))); // There are boundaries that the routine needs to stay in MaskIntersection mask = new MaskIntersection( diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index 045dc6fbe..126653046 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -42,7 +42,7 @@ import com.sk89q.worldedit.command.tool.brush.SphereBrush; import com.sk89q.worldedit.command.util.CreatureButcher; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extent.clipboard.Clipboard; -import com.sk89q.worldedit.function.mask.BlockMask; +import com.sk89q.worldedit.function.mask.BlockTypeMask; import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.session.ClipboardHolder; @@ -192,7 +192,7 @@ public class BrushCommands { Pattern fill = new BlockPattern(BlockTypes.AIR.getDefaultState()); tool.setFill(fill); tool.setSize(radius); - tool.setMask(new BlockMask(editSession, BlockTypes.FIRE.getDefaultState().toFuzzy())); + tool.setMask(new BlockTypeMask(editSession, BlockTypes.FIRE)); tool.setBrush(new SphereBrush(), "worldedit.brush.ex"); player.print(String.format("Extinguisher equipped (%.0f).", radius)); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java index 1c56d8a4f..ba2cf9a3d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java @@ -21,12 +21,11 @@ package com.sk89q.worldedit.function.block; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.collect.Sets; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.function.LayerFunction; -import com.sk89q.worldedit.function.mask.BlockMask; +import com.sk89q.worldedit.function.mask.BlockTypeMask; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.world.block.BlockTypes; @@ -49,11 +48,7 @@ public class Naturalizer implements LayerFunction { public Naturalizer(EditSession editSession) { checkNotNull(editSession); this.editSession = editSession; - this.mask = new BlockMask(editSession, Sets.newHashSet( - BlockTypes.GRASS_BLOCK.getDefaultState(), - BlockTypes.DIRT.getDefaultState(), - BlockTypes.STONE.getDefaultState() - )); + this.mask = new BlockTypeMask(editSession, BlockTypes.GRASS_BLOCK, BlockTypes.DIRT, BlockTypes.STONE); } /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java index 0eee90887..d200f3f30 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java @@ -36,8 +36,8 @@ import javax.annotation.Nullable; * A mask that checks whether blocks at the given positions are matched by * a block in a list. * - *

This mask checks for both an exact block ID and data value match, as well - * for a block with the same ID but a data value of -1.

+ *

This mask checks for both an exact block type and state value match, + * respecting fuzzy status of the BlockState.

*/ public class BlockMask extends AbstractExtentMask { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockTypeMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockTypeMask.java new file mode 100644 index 000000000..0e2ab590e --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockTypeMask.java @@ -0,0 +1,106 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.function.mask; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.world.block.BlockType; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import javax.annotation.Nullable; + +/** + * A mask that checks whether blocks at the given positions are matched by + * a block in a list. + * + *

This mask checks for ONLY the block type. If state should also be checked, + * use {@link BlockMask}.

+ */ +public class BlockTypeMask extends AbstractExtentMask { + + private final Set blocks = new HashSet<>(); + + /** + * Create a new block mask. + * + * @param extent the extent + * @param blocks a list of blocks to match + */ + public BlockTypeMask(Extent extent, Collection blocks) { + super(extent); + checkNotNull(blocks); + this.blocks.addAll(blocks); + } + + /** + * Create a new block mask. + * + * @param extent the extent + * @param block an array of blocks to match + */ + public BlockTypeMask(Extent extent, BlockType... block) { + this(extent, Arrays.asList(checkNotNull(block))); + } + + /** + * Add the given blocks to the list of criteria. + * + * @param blocks a list of blocks + */ + public void add(Collection blocks) { + checkNotNull(blocks); + this.blocks.addAll(blocks); + } + + /** + * Add the given blocks to the list of criteria. + * + * @param block an array of blocks + */ + public void add(BlockType... block) { + add(Arrays.asList(checkNotNull(block))); + } + + /** + * Get the list of blocks that are tested with. + * + * @return a list of blocks + */ + public Collection getBlocks() { + return blocks; + } + + @Override + public boolean test(Vector vector) { + return blocks.contains(getExtent().getBlock(vector).getBlockType()); + } + + @Nullable + @Override + public Mask2D toMask2D() { + return null; + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/FuzzyBlockMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/FuzzyBlockMask.java deleted file mode 100644 index 8b47e2c2c..000000000 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/FuzzyBlockMask.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.function.mask; - -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.blocks.Blocks; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.world.block.BlockStateHolder; - -import java.util.Collection; - -public class FuzzyBlockMask extends BlockMask { - - public FuzzyBlockMask(Extent extent, Collection blocks) { - super(extent, blocks); - } - - public FuzzyBlockMask(Extent extent, BlockStateHolder... block) { - super(extent, block); - } - - @Override - public boolean test(Vector vector) { - Extent extent = getExtent(); - Collection blocks = getBlocks(); - return Blocks.containsFuzzy(blocks, extent.getFullBlock(vector)); - } -} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java index d0c399c0d..4007125f6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java @@ -25,7 +25,7 @@ import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.extension.platform.Platform; -import com.sk89q.worldedit.function.mask.BlockMask; +import com.sk89q.worldedit.function.mask.BlockTypeMask; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.util.Direction; @@ -62,9 +62,7 @@ public abstract class AbstractWorld implements World { @Override public Mask createLiquidMask() { - return new BlockMask(this, - BlockTypes.LAVA.getDefaultState().toFuzzy(), - BlockTypes.WATER.getDefaultState().toFuzzy()); + return new BlockTypeMask(this, BlockTypes.LAVA, BlockTypes.WATER); } @Override