From cfc67965f397a7d1b930f4212eba07120a43b5f9 Mon Sep 17 00:00:00 2001 From: md_5 Date: Mon, 6 Aug 2018 14:40:06 +1000 Subject: Add merging and matching of parsed BlockData --- .../craftbukkit/block/data/CraftBlockData.java | 50 +++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'src/main/java/org') diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java index cfe5903c..472e89c4 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java +++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java @@ -27,6 +27,7 @@ import org.bukkit.craftbukkit.util.CraftMagicNumbers; public class CraftBlockData implements BlockData { private IBlockData state; + private Set> parsedStates; protected CraftBlockData() { throw new AssertionError("Template Constructor"); @@ -86,9 +87,51 @@ public class CraftBlockData implements BlockData { * @param the NMS type */ protected , N extends Enum & INamable> void set(BlockStateEnum nms, Enum bukkit) { + this.parsedStates = null; this.state = this.state.set(nms, toNMS(bukkit, nms.b())); } + @Override + public BlockData merge(BlockData data) { + CraftBlockData craft = (CraftBlockData) data; + Preconditions.checkArgument(craft.parsedStates != null, "Data not created via string parsing"); + Preconditions.checkArgument(this.state.getBlock() == craft.state.getBlock(), "States have different types (got %s, expected %s)", data, this); + + CraftBlockData clone = (CraftBlockData) this.clone(); + clone.parsedStates = null; + + for (IBlockState parsed : craft.parsedStates) { + clone.state = clone.state.set(parsed, craft.state.get(parsed)); + } + + return clone; + } + + @Override + public boolean matches(BlockData data) { + if (data == null) { + return false; + } + if (!(data instanceof CraftBlockData)) { + return false; + } + + CraftBlockData craft = (CraftBlockData) data; + if (this.state.getBlock() != craft.state.getBlock()) { + return false; + } + + // Fastpath an exact match + boolean exactMatch = this.equals(data); + + // If that failed, do a merge and check + if (!exactMatch && craft.parsedStates != null) { + return this.merge(data).equals(this); + } + + return exactMatch; + } + private static final Map, Enum>> classMappings = new HashMap<>(); /** @@ -187,6 +230,7 @@ public class CraftBlockData implements BlockData { */ public , V extends T> void set(IBlockState ibs, V v) { // Straight integer or boolean setter + this.parsedStates = null; this.state = this.state.set(ibs, v); } @@ -421,6 +465,7 @@ public class CraftBlockData implements BlockData { IBlockData blockData; Block block = CraftMagicNumbers.getBlock(material); + Set> parsed = null; // Data provided, use it if (data != null) { @@ -435,6 +480,7 @@ public class CraftBlockData implements BlockData { Preconditions.checkArgument(!reader.canRead(), "Spurious trailing data"); blockData = arg.b(); + parsed = arg.a().keySet(); } catch (CommandSyntaxException ex) { throw new IllegalArgumentException("Could not parse data: " + data, ex); } @@ -442,7 +488,9 @@ public class CraftBlockData implements BlockData { blockData = block.getBlockData(); } - return fromData(blockData); + CraftBlockData craft = fromData(blockData); + craft.parsedStates = parsed; + return craft; } public static CraftBlockData fromData(IBlockData data) { -- cgit v1.2.3