diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/QueryTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/QueryTool.java index b02dcd95b..13477713c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/QueryTool.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/QueryTool.java @@ -61,9 +61,9 @@ public class QueryTool implements BlockTool { builder.append(TextComponent.of(block.getBlockType().getName(), TextColor.YELLOW)); builder.append(TextComponent.of(" (" + block + ") ", TextColor.GRAY) .hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TranslatableComponent.of("worldedit.tool.info.blockstate.hover")))); - final OptionalInt internalId = BlockStateIdAccess.getBlockStateId(block.toImmutableState()); - if (internalId.isPresent()) { - builder.append(TextComponent.of(" (" + internalId.getAsInt() + ") ", TextColor.DARK_GRAY) + final int internalId = BlockStateIdAccess.getBlockStateId(block.toImmutableState()); + if (BlockStateIdAccess.isValidInternalId(internalId)) { + builder.append(TextComponent.of(" (" + internalId+ ") ", TextColor.DARK_GRAY) .hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TranslatableComponent.of("worldedit.tool.info.internalid.hover")))); } final int[] legacy = LegacyMapper.getInstance().getLegacyFromBlock(block.toImmutableState()); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/Int2BaseBlockMap.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/Int2BaseBlockMap.java index 36d459c12..c06a69387 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/Int2BaseBlockMap.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/Int2BaseBlockMap.java @@ -35,27 +35,30 @@ import it.unimi.dsi.fastutil.objects.ObjectSet; import java.util.NoSuchElementException; import java.util.function.BiFunction; +import javax.annotation.Nonnull; /** * Int-to-BaseBlock map, but with optimizations for common cases. */ class Int2BaseBlockMap extends AbstractInt2ObjectMap { - private static boolean hasInt(BlockState b) { - return BlockStateIdAccess.getBlockStateId(b).isPresent(); + /** + * Given a {@link BaseBlock}, retrieve the internal ID if it's useful, + * i.e. the block has no NBT data. + * + * @param block the block to get the ID for + * @return the internal ID, or {@link BlockStateIdAccess#invalidId()} if not useful + */ + private static int optimizedInternalId(BaseBlock block) { + if (block.hasNbtData()) { + return BlockStateIdAccess.invalidId(); } - private static boolean isUncommon(BaseBlock block) { - return block.hasNbtData() || !hasInt(block.toImmutableState()); - } - - private static int assumeAsInt(BlockState b) { - return BlockStateIdAccess.getBlockStateId(b) - .orElseThrow(() -> new IllegalStateException("Block state " + b + " did not have an ID")); + return BlockStateIdAccess.getBlockStateId(block.toImmutableState()); } private static BaseBlock assumeAsBlock(int id) { - if (id == Integer.MIN_VALUE) { + if (!BlockStateIdAccess.isValidInternalId(id)) { return null; } BlockState state = BlockStateIdAccess.getBlockStateById(id); @@ -65,13 +68,11 @@ class Int2BaseBlockMap extends AbstractInt2ObjectMap { return state.toBaseBlock(); } - static final Int2BaseBlockMap EMPTY = new Int2BaseBlockMap(); - private final Int2IntMap commonMap = new Int2IntOpenHashMap(64, 1f); private final Int2ObjectMap uncommonMap = new Int2ObjectOpenHashMap<>(1, 1f); { - commonMap.defaultReturnValue(Integer.MIN_VALUE); + commonMap.defaultReturnValue(BlockStateIdAccess.invalidId()); } @Override @@ -83,6 +84,7 @@ class Int2BaseBlockMap extends AbstractInt2ObjectMap { public ObjectSet> int2ObjectEntrySet() { return new AbstractObjectSet>() { @Override + @Nonnull public ObjectIterator> iterator() { return new ObjectIterator>() { @@ -122,7 +124,7 @@ class Int2BaseBlockMap extends AbstractInt2ObjectMap { @Override public BaseBlock get(int key) { int oldId = commonMap.get(key); - if (oldId == Integer.MIN_VALUE) { + if (!BlockStateIdAccess.isValidInternalId(oldId)) { return uncommonMap.get(key); } return assumeAsBlock(oldId); @@ -136,15 +138,17 @@ class Int2BaseBlockMap extends AbstractInt2ObjectMap { @Override public boolean containsValue(Object v) { BaseBlock block = (BaseBlock) v; - if (isUncommon(block)) { + int internalId = optimizedInternalId(block); + if (!BlockStateIdAccess.isValidInternalId(internalId)) { return uncommonMap.containsValue(block); } - return commonMap.containsValue(assumeAsInt(block.toImmutableState())); + return commonMap.containsValue(internalId); } @Override public BaseBlock put(int key, BaseBlock value) { - if (isUncommon(value)) { + int internalId = optimizedInternalId(value); + if (!BlockStateIdAccess.isValidInternalId(internalId)) { BaseBlock old = uncommonMap.put(key, value); if (old == null) { // ensure common doesn't have the entry too @@ -153,14 +157,14 @@ class Int2BaseBlockMap extends AbstractInt2ObjectMap { } return old; } - int oldId = commonMap.put(key, assumeAsInt(value.toImmutableState())); + int oldId = commonMap.put(key, internalId); return assumeAsBlock(oldId); } @Override public BaseBlock remove(int key) { int removed = commonMap.remove(key); - if (removed == Integer.MIN_VALUE) { + if (!BlockStateIdAccess.isValidInternalId(removed)) { return uncommonMap.remove(key); } return assumeAsBlock(removed); @@ -172,21 +176,23 @@ class Int2BaseBlockMap extends AbstractInt2ObjectMap { iter.hasNext(); ) { Int2IntMap.Entry next = iter.next(); BaseBlock value = function.apply(next.getIntKey(), assumeAsBlock(next.getIntValue())); - if (isUncommon(value)) { + int internalId = optimizedInternalId(value); + if (!BlockStateIdAccess.isValidInternalId(internalId)) { uncommonMap.put(next.getIntKey(), value); iter.remove(); } else { - next.setValue(assumeAsInt(value.toImmutableState())); + next.setValue(internalId); } } for (ObjectIterator> iter = Int2ObjectMaps.fastIterator(uncommonMap); iter.hasNext(); ) { Entry next = iter.next(); BaseBlock value = function.apply(next.getIntKey(), next.getValue()); - if (isUncommon(value)) { + int internalId = optimizedInternalId(value); + if (!BlockStateIdAccess.isValidInternalId(internalId)) { next.setValue(value); } else { - commonMap.put(next.getIntKey(), assumeAsInt(value.toImmutableState())); + commonMap.put(next.getIntKey(), internalId); iter.remove(); } }