Skip recomputing block state cache when unnecessary

Based on https://github.com/MinecraftForge/MinecraftForge/pull/7496
This commit is contained in:
embeddedt 2023-01-02 21:56:34 -05:00
parent dff8c4cc35
commit 26915c6af4
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
9 changed files with 115 additions and 2 deletions

View File

@ -38,6 +38,9 @@ public class ModernFix {
public static ModernFix INSTANCE;
// Used to skip computing the blockstate caches twice
public static boolean runningFirstInjection = false;
public ModernFix() {
INSTANCE = this;

View File

@ -0,0 +1,7 @@
package org.embeddedt.modernfix.duck;
import org.embeddedt.modernfix.util.BakeReason;
public interface IBlockState {
void clearCache();
}

View File

@ -0,0 +1,18 @@
package org.embeddedt.modernfix.mixin;
import net.minecraft.block.AbstractBlock;
import org.embeddedt.modernfix.duck.IBlockState;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import javax.annotation.Nullable;
@Mixin(AbstractBlock.AbstractBlockState.class)
public class AbstractBlockStateMixin implements IBlockState {
@Shadow @Nullable protected AbstractBlock.AbstractBlockState.Cache cache;
@Override
public void clearCache() {
this.cache = null;
}
}

View File

@ -0,0 +1,23 @@
package org.embeddedt.modernfix.mixin;
import net.minecraft.block.BlockState;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.duck.IBlockState;
import org.embeddedt.modernfix.util.BakeReason;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(targets = { "net/minecraftforge/registries/GameData$BlockCallbacks" })
public class BlockCallbacksMixin {
@Redirect(method = "onBake", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;cacheState()V"))
private void skipCacheIfAllowed(BlockState state) {
if(BakeReason.currentBakeReason == BakeReason.FREEZE
|| BakeReason.currentBakeReason == BakeReason.REMOTE_SNAPSHOT_INJECT
|| (BakeReason.currentBakeReason == BakeReason.LOCAL_SNAPSHOT_INJECT && ModernFix.runningFirstInjection)) {
((IBlockState)state).clearCache();
} else {
state.cacheState();
}
}
}

View File

@ -0,0 +1,47 @@
package org.embeddedt.modernfix.mixin;
import com.google.common.collect.Multimap;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.registries.ForgeRegistry;
import net.minecraftforge.registries.GameData;
import org.embeddedt.modernfix.util.BakeReason;
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.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Map;
@Mixin(GameData.class)
public class GameDataMixin {
@Inject(method = "freezeData", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/BiMap;forEach(Ljava/util/function/BiConsumer;)V", ordinal = 1), remap = false)
private static void markFreezeBakeReason(CallbackInfo ci) {
BakeReason.currentBakeReason = BakeReason.FREEZE;
}
@Inject(method = "freezeData", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/registries/GameData;fireRemapEvent(Ljava/util/Map;Z)V"), remap = false)
private static void markEmptyBakeReason1(CallbackInfo ci) {
BakeReason.currentBakeReason = null;
}
@Inject(method = "revertTo", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/BiMap;forEach(Ljava/util/function/BiConsumer;)V", ordinal = 1), remap = false)
private static void markRevertBakeReason(CallbackInfo ci) {
BakeReason.currentBakeReason = BakeReason.REVERT;
}
@Inject(method = "revertTo", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/BiMap;forEach(Ljava/util/function/BiConsumer;)V", ordinal = 1, shift = At.Shift.AFTER), remap = false)
private static void markEmptyBakeReason2(CallbackInfo ci) {
BakeReason.currentBakeReason = null;
}
@Inject(method = "injectSnapshot", at = @At("HEAD"), remap = false)
private static void markSnapshotInjectBakeReason(Map<ResourceLocation, ForgeRegistry.Snapshot> snapshot, boolean injectFrozenData, boolean isLocalWorld, CallbackInfoReturnable<Multimap<ResourceLocation, ResourceLocation>> cir) {
BakeReason.currentBakeReason = isLocalWorld ? BakeReason.LOCAL_SNAPSHOT_INJECT : BakeReason.REMOTE_SNAPSHOT_INJECT;
}
@Inject(method = "injectSnapshot", at = @At("RETURN"), remap = false)
private static void markEmptyBakeReason2(Map<ResourceLocation, ForgeRegistry.Snapshot> snapshot, boolean injectFrozenData, boolean isLocalWorld, CallbackInfoReturnable<Multimap<ResourceLocation, ResourceLocation>> cir) {
BakeReason.currentBakeReason = null;
}
}

View File

@ -52,7 +52,9 @@ public abstract class MinecraftMixin {
private Minecraft.PackManager skipFirstReload(Minecraft client, DynamicRegistries.Impl dynamicRegistries, Function<SaveFormat.LevelSave, DatapackCodec> worldStorageToDatapackFunction, Function4<SaveFormat.LevelSave, DynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> quadFunction, boolean vanillaOnly, SaveFormat.LevelSave levelSave, String worldName, DynamicRegistries.Impl originalRegistries, Function<SaveFormat.LevelSave, DatapackCodec> levelSaveToDatapackFunction, Function4<SaveFormat.LevelSave, DynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> quadFunction2, boolean vanillaOnly2, Minecraft.WorldSelectionType selectionType, boolean creating) throws InterruptedException, ExecutionException {
if(!creating) {
ModernFix.LOGGER.warn("Skipping first reload, this is still experimental");
ModernFix.runningFirstInjection = true;
((ILevelSave)levelSave).runWorldPersistenceHooks();
ModernFix.runningFirstInjection = false;
return null;
} else {
/* allow reload */

View File

@ -0,0 +1,9 @@
package org.embeddedt.modernfix.util;
public enum BakeReason {
FREEZE,
REMOTE_SNAPSHOT_INJECT,
LOCAL_SNAPSHOT_INJECT,
REVERT;
public static BakeReason currentBakeReason = null;
}

View File

@ -1,3 +1,4 @@
public net.minecraft.client.Minecraft$WorldSelectionType
public net.minecraft.client.renderer.RenderType$Type
public net.minecraft.client.renderer.RenderType$Type <init>(Ljava/lang/String;Lnet/minecraft/client/renderer/vertex/VertexFormat;IIZZLnet/minecraft/client/renderer/RenderType$State;)V
public net.minecraft.client.renderer.RenderType$Type <init>(Ljava/lang/String;Lnet/minecraft/client/renderer/vertex/VertexFormat;IIZZLnet/minecraft/client/renderer/RenderType$State;)V
public net.minecraft.block.AbstractBlock$AbstractBlockState$Cache

View File

@ -9,7 +9,10 @@
"ModFileResourcePackMixin",
"VanillaPackMixin",
"LevelSaveMixin",
"SaveFormatAccessor"
"SaveFormatAccessor",
"AbstractBlockStateMixin",
"GameDataMixin",
"BlockCallbacksMixin"
],
"client": [
"MinecraftMixin",