diff --git a/src/main/java/fermiummixins/mixin/vanilla/BlockStateBase_IdentityMixin.java b/src/main/java/fermiummixins/mixin/vanilla/BlockStateBase_IdentityMixin.java index a66ac22..263d9be 100644 --- a/src/main/java/fermiummixins/mixin/vanilla/BlockStateBase_IdentityMixin.java +++ b/src/main/java/fermiummixins/mixin/vanilla/BlockStateBase_IdentityMixin.java @@ -1,7 +1,6 @@ package fermiummixins.mixin.vanilla; import fermiummixins.wrapper.IBlockStateIdentity; -import fermiummixins.wrapper.BlockStateIdentityPatchWrapper; import net.minecraft.block.state.BlockStateBase; import net.minecraft.block.state.IBlockState; import org.spongepowered.asm.mixin.Mixin; @@ -10,9 +9,14 @@ @Mixin(BlockStateBase.class) public abstract class BlockStateBase_IdentityMixin implements IBlockState, IBlockStateIdentity { - //Registry is reference based, so each init is a new id + //ID for unknown state is -1 @Unique - private int fermiummixins$blockStateID = BlockStateIdentityPatchWrapper.getNewID(); + private int fermiummixins$blockStateID = -1; + + @Override + public void fermiummixins$setIdentityKey(int id) { + this.fermiummixins$blockStateID = id; + } @Override public int fermiummixins$getIdentityKey() { diff --git a/src/main/java/fermiummixins/wrapper/BlockStateIdentityPatchWrapper.java b/src/main/java/fermiummixins/wrapper/BlockStateIdentityPatchWrapper.java index 8708eb4..e330081 100644 --- a/src/main/java/fermiummixins/wrapper/BlockStateIdentityPatchWrapper.java +++ b/src/main/java/fermiummixins/wrapper/BlockStateIdentityPatchWrapper.java @@ -1,66 +1,39 @@ package fermiummixins.wrapper; -import com.google.common.collect.Lists; import net.minecraft.block.state.IBlockState; import net.minecraft.util.ObjectIntIdentityMap; import javax.annotation.Nullable; -import java.util.ArrayList; public abstract class BlockStateIdentityPatchWrapper { - //https://en.wikipedia.org/wiki/Jesus_nut - private static int currentID = 0; - - public static int getNewID() { - return currentID++; - } - public static class ClearableObjectIntIdentityMapPatched extends ObjectIntIdentityMap { - private final ArrayList identityArray; private int size = 0; public ClearableObjectIntIdentityMapPatched() { - //TODO May be worth it to set expected size through config based on post-load totals? - //Default vanilla size is 512 but RLCraft test was ~40k-50k - //TODO test how expected size practically affects performance/alloc, just guessed for now - this(65536); + this(512); } public ClearableObjectIntIdentityMapPatched(int expectedSize) { super(expectedSize); - this.identityArray = Lists.newArrayListWithExpectedSize(expectedSize); } @Override public void put(IBlockState key, int value) { if(key == null) return; - int fixKey = ((IBlockStateIdentity)key).fermiummixins$getIdentityKey(); - while(this.identityArray.size() <= fixKey) { - this.identityArray.add(null); - } - if(this.identityArray.set(fixKey, value) == null) this.size++; + ((IBlockStateIdentity) key).fermiummixins$setIdentityKey(value); //objectList can have multiple values return the same state ref but total size is based on total state refs while(this.objectList.size() <= value) { this.objectList.add(null); } - this.objectList.set(value, key); + if(this.objectList.set(value, key) == null) this.size++; } @Override public int get(@Nullable IBlockState key) { if(key == null) return -1; - Integer integer = this.get(((IBlockStateIdentity)key).fermiummixins$getIdentityKey()); - if(integer == null) { - integer = this.get(key.getBlock().getStateFromMeta(key.getBlock().getMetaFromState(key))); - } - return integer; - } - - private Integer get(int key) { - if(key >= this.identityArray.size()) return null; - return this.identityArray.get(key); + return ((IBlockStateIdentity) key).fermiummixins$getIdentityKey(); } @Override @@ -70,19 +43,15 @@ public int size() { public void clear() { this.objectList.clear(); - this.identityArray.clear(); this.size = 0; } public void remove(IBlockState key) { if(key == null) return; - int fixKey = ((IBlockStateIdentity)key).fermiummixins$getIdentityKey(); + int value = ((IBlockStateIdentity)key).fermiummixins$getIdentityKey(); //Do not use remove, will shift array - Integer prev = this.get(fixKey); - if(prev != null) { - this.identityArray.set(fixKey, null); - this.objectList.set(prev, null); - this.size--; + if(value >= 0 && value < this.objectList.size()) { + if(this.objectList.set(value, null) != null) this.size--; } } } diff --git a/src/main/java/fermiummixins/wrapper/IBlockStateIdentity.java b/src/main/java/fermiummixins/wrapper/IBlockStateIdentity.java index 1761a08..df21df8 100644 --- a/src/main/java/fermiummixins/wrapper/IBlockStateIdentity.java +++ b/src/main/java/fermiummixins/wrapper/IBlockStateIdentity.java @@ -5,6 +5,8 @@ public interface IBlockStateIdentity { + void fermiummixins$setIdentityKey(int id); + default int fermiummixins$getIdentityKey() { FermiumMixins.LOGGER.log(Level.ERROR, "FermiumMixins BlockState Identity Registry Patch has encountered unexpected behavior, disable this patch."); return 0;