diff --git a/common/src/main/java/org/embeddedt/modernfix/blockstate/FerriteCorePostProcess.java b/common/src/main/java/org/embeddedt/modernfix/blockstate/FerriteCorePostProcess.java new file mode 100644 index 00000000..372fb27d --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/blockstate/FerriteCorePostProcess.java @@ -0,0 +1,56 @@ +package org.embeddedt.modernfix.blockstate; + +import it.unimi.dsi.fastutil.objects.Object2IntArrayMap; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntMaps; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.StateHolder; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Field; + +public class FerriteCorePostProcess { + private static final boolean willPostProcess; + + private static final MethodHandle theTable, toKeyIndex; + + static { + boolean success = true; + MethodHandle table = null, keyIndex = null; + try { + Class fastMap = Class.forName("malte0811.ferritecore.fastmap.FastMap"); + Field field = fastMap.getDeclaredField("toKeyIndex"); + field.setAccessible(true); + keyIndex = MethodHandles.publicLookup().unreflectSetter(field); + field = StateHolder.class.getDeclaredField("ferritecore_globalTable"); + field.setAccessible(true); + table = MethodHandles.publicLookup().unreflectGetter(field); + } catch(ReflectiveOperationException | RuntimeException e) { + e.printStackTrace(); + success = false; + } + willPostProcess = success; + theTable = table; + toKeyIndex = keyIndex; + } + + private static final Object2IntMap EMPTY_MAP = Object2IntMaps.unmodifiable(new Object2IntArrayMap<>()); + + public static > void postProcess(StateDefinition state) { + if(!willPostProcess) + return; + try { + if(state.getProperties().size() == 0) { + for(S holder : state.getPossibleStates()) { + // deduplicate Object2IntMap objects from FerriteCore + // will probably be fixed upstream at some point, but likely not for older versions + Object table = theTable.invoke(holder); + toKeyIndex.invoke(table, EMPTY_MAP); + } + } + } catch(Throwable e) { + e.printStackTrace(); + } + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/state_definition_construct/StateDefinitionMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/state_definition_construct/StateDefinitionMixin.java index 1d32168d..cf7f3dfb 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/state_definition_construct/StateDefinitionMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/state_definition_construct/StateDefinitionMixin.java @@ -6,11 +6,14 @@ import net.minecraft.world.level.block.state.StateHolder; import net.minecraft.world.level.block.state.properties.Property; import org.embeddedt.modernfix.annotation.RequiresMod; import org.embeddedt.modernfix.blockstate.FakeStateMap; +import org.embeddedt.modernfix.blockstate.FerriteCorePostProcess; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.Map; @@ -27,4 +30,9 @@ public class StateDefinitionMixin> { } return new FakeStateMap<>(numStates); } + + @Inject(method = "", at = @At("TAIL")) + private void postProcess(CallbackInfo ci) { + FerriteCorePostProcess.postProcess((StateDefinition)(Object)this); + } }