From 92259629831827143216aa5aaff893c40cdf714d Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 15 Apr 2023 21:26:49 -0400 Subject: [PATCH] Invalidate material cache if the texture map changes on a model --- .../modernfix/duck/ICachedMaterialsModel.java | 5 + .../BlockModelMixin.java | 108 ++++++++++++++++++ .../VanillaModelMixin.java | 8 +- src/main/resources/modernfix.mixins.json | 1 + 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/embeddedt/modernfix/duck/ICachedMaterialsModel.java create mode 100644 src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/BlockModelMixin.java diff --git a/src/main/java/org/embeddedt/modernfix/duck/ICachedMaterialsModel.java b/src/main/java/org/embeddedt/modernfix/duck/ICachedMaterialsModel.java new file mode 100644 index 00000000..855b8c3b --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/duck/ICachedMaterialsModel.java @@ -0,0 +1,5 @@ +package org.embeddedt.modernfix.duck; + +public interface ICachedMaterialsModel { + public void clearMaterialsCache(); +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/BlockModelMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/BlockModelMixin.java new file mode 100644 index 00000000..691a28e5 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/BlockModelMixin.java @@ -0,0 +1,108 @@ +package org.embeddedt.modernfix.mixin.perf.cache_model_materials; + +import com.mojang.datafixers.util.Either; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.client.resources.model.Material; +import org.embeddedt.modernfix.duck.ICachedMaterialsModel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +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.Collection; +import java.util.Map; +import java.util.Set; + +@Mixin(BlockModel.class) +public class BlockModelMixin { + @Shadow @Final @Mutable public Map> textureMap; + + /** + * @author embeddedt + * @reason detect changes to the texture map, and clear the material cache as needed + */ + @Inject(method = "", at = @At("RETURN")) + private void useTrackingTextureMap(CallbackInfo ci) { + Map> backingMap = this.textureMap; + ICachedMaterialsModel cacheHolder = (ICachedMaterialsModel)this; + this.textureMap = new Map>() { + @Override + public int size() { + return backingMap.size(); + } + + @Override + public boolean isEmpty() { + return backingMap.isEmpty(); + } + + @Override + public boolean containsKey(Object o) { + return backingMap.containsKey(o); + } + + @Override + public boolean containsValue(Object o) { + return backingMap.containsValue(o); + } + + @Override + public Either get(Object o) { + return backingMap.get(o); + } + + @Nullable + @Override + public Either put(String s, Either materialStringEither) { + Either old = backingMap.put(s, materialStringEither); + cacheHolder.clearMaterialsCache(); + return old; + } + + @Override + public Either remove(Object o) { + Either e = backingMap.remove(o); + cacheHolder.clearMaterialsCache(); + return e; + } + + @Override + public void putAll(@NotNull Map> map) { + backingMap.putAll(map); + cacheHolder.clearMaterialsCache(); + } + + @Override + public void clear() { + backingMap.clear(); + cacheHolder.clearMaterialsCache(); + } + + @NotNull + @Override + public Set keySet() { + cacheHolder.clearMaterialsCache(); + return backingMap.keySet(); + } + + @NotNull + @Override + public Collection> values() { + cacheHolder.clearMaterialsCache(); + return backingMap.values(); + } + + @NotNull + @Override + public Set>> entrySet() { + cacheHolder.clearMaterialsCache(); + return backingMap.entrySet(); + } + }; + } +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/VanillaModelMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/VanillaModelMixin.java index 6d9a9a55..54413655 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/VanillaModelMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/cache_model_materials/VanillaModelMixin.java @@ -7,6 +7,7 @@ import net.minecraft.client.resources.model.Material; import net.minecraft.client.renderer.block.model.MultiVariant; import net.minecraft.client.renderer.block.model.multipart.MultiPart; import net.minecraft.resources.ResourceLocation; +import org.embeddedt.modernfix.duck.ICachedMaterialsModel; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -18,7 +19,7 @@ import java.util.Set; import java.util.function.Function; @Mixin(value = {MultiVariant.class, MultiPart.class, BlockModel.class}) -public class VanillaModelMixin { +public class VanillaModelMixin implements ICachedMaterialsModel { private Collection materialsCache = null; @Inject(method = "getMaterials", at = @At("HEAD"), cancellable = true) @@ -33,4 +34,9 @@ public class VanillaModelMixin { if(materialsCache == null) materialsCache = Collections.unmodifiableCollection(cir.getReturnValue()); } + + @Override + public void clearMaterialsCache() { + materialsCache = null; + } } diff --git a/src/main/resources/modernfix.mixins.json b/src/main/resources/modernfix.mixins.json index 58795e9f..6464cc72 100644 --- a/src/main/resources/modernfix.mixins.json +++ b/src/main/resources/modernfix.mixins.json @@ -101,6 +101,7 @@ "perf.blast_search_trees.MinecraftMixin", "perf.blast_search_trees.IngredientFilterInvoker", "perf.cache_model_materials.VanillaModelMixin", + "perf.cache_model_materials.BlockModelMixin", "perf.cache_model_materials.MultipartMixin", "perf.faster_texture_stitching.StitcherMixin", "bugfix.packet_leak.ClientPlayNetHandlerMixin",