StateCache to reduce allocation
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
package net.gensokyoreimagined.nitori.core;
|
||||
package net.gensokyoreimagined.nitori.common.state;
|
||||
|
||||
import com.google.common.collect.Table;
|
||||
import it.unimi.dsi.fastutil.Hash;
|
||||
@@ -12,7 +12,7 @@
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
package net.gensokyoreimagined.nitori.core;
|
||||
package net.gensokyoreimagined.nitori.common.state;
|
||||
|
||||
import it.unimi.dsi.fastutil.Hash;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrays;
|
||||
@@ -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.
|
||||
* <p>
|
||||
* 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<Property<?>, Comparable<?>, BlockState> BLOCK_STATE_TABLE =
|
||||
new FastImmutableTableCache<>();
|
||||
|
||||
public static final FastImmutableTableCache<Property<?>, Comparable<?>, FluidState> FLUID_STATE_TABLE =
|
||||
new FastImmutableTableCache<>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <S, O> FastImmutableTableCache<Property<?>, Comparable<?>, S> getTableCache(O owner) {
|
||||
if (owner instanceof Block) {
|
||||
return (FastImmutableTableCache<Property<?>, Comparable<?>, S>) BLOCK_STATE_TABLE;
|
||||
} else if (owner instanceof Fluid) {
|
||||
return (FastImmutableTableCache<Property<?>, Comparable<?>, S>) FLUID_STATE_TABLE;
|
||||
} else {
|
||||
throw new IllegalArgumentException("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<O, S> {
|
||||
@Shadow
|
||||
private Table<Property<?>, Comparable<?>, S> neighbours;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
protected O owner;
|
||||
|
||||
@Inject(method = "populateNeighbours", at = @At("RETURN"))
|
||||
private void postCreateWithTable(Map<Map<Property<?>, Comparable<?>>, S> states, CallbackInfo ci) {
|
||||
if (this.owner instanceof Block || this.owner instanceof Fluid) {
|
||||
this.neighbours = new FastImmutableTable<Property<?>, Comparable<?>, S>(this.neighbours, StatePropertyTableCache.getTableCache(this.owner));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,6 +29,7 @@
|
||||
"MixinReobfServer",
|
||||
"MixinLevelStorageAccess",
|
||||
"MixinPlayerList",
|
||||
"MixinCraftPlayer"
|
||||
"MixinCraftPlayer",
|
||||
"StateMixin"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user