diff --git a/src/main/java/net/gensokyoreimagined/nitori/core/FastImmutableTable.java b/src/main/java/net/gensokyoreimagined/nitori/common/state/FastImmutableTable.java old mode 100755 new mode 100644 similarity index 99% rename from src/main/java/net/gensokyoreimagined/nitori/core/FastImmutableTable.java rename to src/main/java/net/gensokyoreimagined/nitori/common/state/FastImmutableTable.java index 56450f3..b40ccf7 --- a/src/main/java/net/gensokyoreimagined/nitori/core/FastImmutableTable.java +++ b/src/main/java/net/gensokyoreimagined/nitori/common/state/FastImmutableTable.java @@ -12,7 +12,7 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . -package net.gensokyoreimagined.nitori.core; +package net.gensokyoreimagined.nitori.common.state; import com.google.common.collect.Table; import it.unimi.dsi.fastutil.Hash; diff --git a/src/main/java/net/gensokyoreimagined/nitori/core/FastImmutableTableCache.java b/src/main/java/net/gensokyoreimagined/nitori/common/state/FastImmutableTableCache.java old mode 100755 new mode 100644 similarity index 97% rename from src/main/java/net/gensokyoreimagined/nitori/core/FastImmutableTableCache.java rename to src/main/java/net/gensokyoreimagined/nitori/common/state/FastImmutableTableCache.java index a8f1c9e..d8e7bfe --- a/src/main/java/net/gensokyoreimagined/nitori/core/FastImmutableTableCache.java +++ b/src/main/java/net/gensokyoreimagined/nitori/common/state/FastImmutableTableCache.java @@ -12,7 +12,7 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . -package net.gensokyoreimagined.nitori.core; +package net.gensokyoreimagined.nitori.common.state; import it.unimi.dsi.fastutil.Hash; import it.unimi.dsi.fastutil.ints.IntArrays; diff --git a/src/main/java/net/gensokyoreimagined/nitori/common/state/StatePropertyTableCache.java b/src/main/java/net/gensokyoreimagined/nitori/common/state/StatePropertyTableCache.java new file mode 100644 index 0000000..3d70ceb --- /dev/null +++ b/src/main/java/net/gensokyoreimagined/nitori/common/state/StatePropertyTableCache.java @@ -0,0 +1,41 @@ +package net.gensokyoreimagined.nitori.common.state; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.Property; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidState; + + + + +/** + * Many of the column and row key arrays in block state tables will be duplicated, leading to an unnecessary waste of + * memory. Since we have very limited options for trying to construct more optimized table types without throwing + * maintainability or mod compatibility out the window, this class acts as a dirty way to find and de-duplicate arrays + * after we construct our table types. + *

+ * While this global cache does not provide the ability to remove or clear entries from it, the reality is that it + * shouldn't matter because block state tables are only initialized once and remain loaded for the entire lifetime of + * the game. Even in the event of classloader pre-boot shenanigans, we still shouldn't leak memory as our cache will be + * dropped along with the rest of the loaded classes when the class loader is reaped. + */ +public class StatePropertyTableCache { + public static final FastImmutableTableCache, Comparable, BlockState> BLOCK_STATE_TABLE = + new FastImmutableTableCache<>(); + + public static final FastImmutableTableCache, Comparable, FluidState> FLUID_STATE_TABLE = + new FastImmutableTableCache<>(); + + @SuppressWarnings("unchecked") + public static FastImmutableTableCache, Comparable, S> getTableCache(O owner) { + if (owner instanceof Block) { + return (FastImmutableTableCache, Comparable, S>) BLOCK_STATE_TABLE; + } else if (owner instanceof Fluid) { + return (FastImmutableTableCache, Comparable, S>) FLUID_STATE_TABLE; + } else { + throw new IllegalArgumentException(""); + } + } +} + diff --git a/src/main/java/net/gensokyoreimagined/nitori/core/StateMixin.java b/src/main/java/net/gensokyoreimagined/nitori/core/StateMixin.java new file mode 100644 index 0000000..1e11235 --- /dev/null +++ b/src/main/java/net/gensokyoreimagined/nitori/core/StateMixin.java @@ -0,0 +1,35 @@ +package net.gensokyoreimagined.nitori.core; + +import com.google.common.collect.Table; +import net.gensokyoreimagined.nitori.common.state.FastImmutableTable; +import net.gensokyoreimagined.nitori.common.state.StatePropertyTableCache; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.StateHolder; +import net.minecraft.world.level.block.state.properties.Property; +import net.minecraft.world.level.material.Fluid; +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.callback.CallbackInfo; + +import java.util.Map; + +@Mixin(StateHolder.class) +public class StateMixin { + @Shadow + private Table, Comparable, S> neighbours; + + @Shadow + @Final + protected O owner; + + @Inject(method = "populateNeighbours", at = @At("RETURN")) + private void postCreateWithTable(Map, Comparable>, S> states, CallbackInfo ci) { + if (this.owner instanceof Block || this.owner instanceof Fluid) { + this.neighbours = new FastImmutableTable, Comparable, S>(this.neighbours, StatePropertyTableCache.getTableCache(this.owner)); + } + } + +} \ No newline at end of file diff --git a/src/main/resources/mixins.core.json b/src/main/resources/mixins.core.json index df12eec..72b6b3f 100755 --- a/src/main/resources/mixins.core.json +++ b/src/main/resources/mixins.core.json @@ -29,6 +29,7 @@ "MixinReobfServer", "MixinLevelStorageAccess", "MixinPlayerList", - "MixinCraftPlayer" + "MixinCraftPlayer", + "StateMixin" ] }