From c63a8fa21ecfa78bbc053bbcd37ee6dd2d36f913 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 15 Jul 2023 20:22:22 -0400 Subject: [PATCH] Deduplicate wall block shapes --- .../WallBlockMixin.java | 54 +++++++++++++++++++ .../core/config/ModernFixEarlyConfig.java | 2 + 2 files changed, 56 insertions(+) create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/deduplicate_wall_shapes/WallBlockMixin.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/deduplicate_wall_shapes/WallBlockMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/deduplicate_wall_shapes/WallBlockMixin.java new file mode 100644 index 00000000..dda1ae77 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/deduplicate_wall_shapes/WallBlockMixin.java @@ -0,0 +1,54 @@ +package org.embeddedt.modernfix.common.mixin.perf.deduplicate_wall_shapes; + +import com.google.common.collect.ImmutableMap; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.WallBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.Property; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +@Mixin(WallBlock.class) +public abstract class WallBlockMixin extends Block { + private static Map, Comparable>, VoxelShape> CACHE_BY_PROPERTIES = new HashMap<>(); + private static StateDefinition CACHED_DEFINITION = null; + private static float[] CACHED_FLOATS = null; + + public WallBlockMixin(Properties properties) { + super(properties); + } + + @Inject(method = "makeShapes", at = @At("HEAD"), cancellable = true) + private synchronized void useCachedShapeMap(float f1, float f2, float f3, float f4, float f5, float f6, CallbackInfoReturnable> cir) { + if(CACHED_DEFINITION != null) { + // check if this state container's properties exactly match the one we used for the cache + if(CACHED_DEFINITION.getProperties().equals(this.stateDefinition.getProperties()) && Arrays.equals(CACHED_FLOATS, new float[] { f1, f2, f3, f4, f5, f6 })) { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for(BlockState state : this.stateDefinition.getPossibleStates()) { + builder.put(state, CACHE_BY_PROPERTIES.get(state.getValues())); + } + cir.setReturnValue(builder.build()); + } + } + } + + @Inject(method = "makeShapes", at = @At("RETURN")) + private synchronized void storeCachedShapesByProperty(float f1, float f2, float f3, float f4, float f5, float f6, CallbackInfoReturnable> cir) { + if(CACHE_BY_PROPERTIES.size() == 0) { + Map shapeMap = cir.getReturnValue(); + for(Map.Entry entry : shapeMap.entrySet()) { + CACHE_BY_PROPERTIES.put(entry.getKey().getValues(), entry.getValue()); + } + CACHED_FLOATS = new float[] { f1, f2, f3, f4, f5, f6 }; + CACHED_DEFINITION = this.stateDefinition; + } + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index e48486de..e3413561 100644 --- a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -226,6 +226,8 @@ public class ModernFixEarlyConfig { disableIfModPresent("mixin.bugfix.remove_block_chunkloading", "performant"); disableIfModPresent("mixin.bugfix.paper_chunk_patches", "c2me"); disableIfModPresent("mixin.perf.cache_strongholds", "littletiles"); + // content overlap + disableIfModPresent("mixin.perf.deduplicate_wall_shapes", "dashloader"); disableIfModPresent("mixin.perf.nbt_memory_usage", "c2me"); // DimThread makes changes to the server chunk manager (understandably), C2ME probably does the same disableIfModPresent("mixin.bugfix.chunk_deadlock", "c2me", "dimthread");