From a170f072ff50229dc1b40404e6e83061ce854f2e Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 2 Jun 2025 19:08:23 -0400 Subject: [PATCH] Invalidate memoization for non-category creative tabs when categories are rebuilt --- .../CreativeModeTabMixin.java | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/memoize_creative_tab_build/CreativeModeTabMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/memoize_creative_tab_build/CreativeModeTabMixin.java index c74bb4a2..989e8066 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/memoize_creative_tab_build/CreativeModeTabMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/memoize_creative_tab_build/CreativeModeTabMixin.java @@ -2,15 +2,22 @@ package org.embeddedt.modernfix.common.mixin.perf.memoize_creative_tab_build; import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.item.CreativeModeTab; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @Mixin(CreativeModeTab.class) -public class CreativeModeTabMixin { +public abstract class CreativeModeTabMixin { + @Shadow public abstract CreativeModeTab.Type getType(); + @Unique private CreativeModeTab.ItemDisplayParameters mfix$oldParameters; + @Unique + private static boolean MFIX$REBUILT_NON_CATEGORY = false; + /** * @author embeddedt * @reason Vanilla already does similar memoization in the CreativeModeTabs class, but mods often have to bypass @@ -20,9 +27,26 @@ public class CreativeModeTabMixin { */ @WrapMethod(method = "buildContents") private synchronized void buildContentsIfChanged(CreativeModeTab.ItemDisplayParameters parameters, Operation original) { - if (mfix$oldParameters == null || mfix$oldParameters.needsUpdate(parameters.enabledFeatures(), parameters.hasPermissions(), parameters.holders())) { - original.call(parameters); + synchronized (CreativeModeTab.class) { + if (mfix$oldParameters == null || mfix$oldParameters.needsUpdate(parameters.enabledFeatures(), parameters.hasPermissions(), parameters.holders())) { + original.call(parameters); + if (this.getType() == CreativeModeTab.Type.CATEGORY) { + if (MFIX$REBUILT_NON_CATEGORY) { + // We must mark every other tab that's not a category as needing rebuild. Not doing this causes mods + // that build a search tab early on without having built the dependencies to permanently leave it + // in a broken state. + for (CreativeModeTab tab : BuiltInRegistries.CREATIVE_MODE_TAB) { + if (tab.getType() != CreativeModeTab.Type.CATEGORY) { + ((CreativeModeTabMixin)(Object)tab).mfix$oldParameters = null; + } + } + MFIX$REBUILT_NON_CATEGORY = false; + } + } else { + MFIX$REBUILT_NON_CATEGORY = true; + } + } + mfix$oldParameters = parameters; } - mfix$oldParameters = parameters; } }