From 8b0622ff5c00b4bb0e8fb6c8426bf0c851478f01 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 14 May 2025 22:19:10 -0400 Subject: [PATCH 1/4] Log when model universe is restricted --- .../modernfix/forge/dynresources/ModelBakeEventHelper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java b/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java index d3b9467a..b520de86 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java @@ -154,6 +154,7 @@ public class ModelBakeEventHelper { modIdsToInclude.remove("minecraft"); Set ourModelLocations; if (config == UniverseVisibility.SELF_AND_DEPS) { + ModernFix.LOGGER.debug("Mod {} is restricted to seeing models from mods: [{}]", modId, String.join(", ", modIdsToInclude)); ourModelLocations = Sets.filter(this.topLevelModelLocations, loc -> modIdsToInclude.contains(loc.getNamespace())); } else { ourModelLocations = this.topLevelModelLocations; From c11867536927ab0bbbd76dcd4b5bdae69a9cc57d Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 15 May 2025 18:53:47 -0400 Subject: [PATCH 2/4] Fix concurrency issues in vanilla RegistryOps.memoizeLookup --- .../RegistryOpsMemoizedMixin.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/registry_ops_cme/RegistryOpsMemoizedMixin.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/registry_ops_cme/RegistryOpsMemoizedMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/registry_ops_cme/RegistryOpsMemoizedMixin.java new file mode 100644 index 00000000..f4ac000b --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/registry_ops_cme/RegistryOpsMemoizedMixin.java @@ -0,0 +1,27 @@ +package org.embeddedt.modernfix.common.mixin.bugfix.registry_ops_cme; + +import net.minecraft.core.Registry; +import net.minecraft.resources.RegistryOps; +import net.minecraft.resources.ResourceKey; +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.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + +@Mixin(targets = {"net/minecraft/resources/RegistryOps$1"}) +public class RegistryOpsMemoizedMixin { + @Shadow @Final @Mutable + private Map>, Optional>> lookups; + + @Inject(method = "", at = @At("RETURN")) + private void useConcurrentMap(RegistryOps.RegistryInfoLookup registryInfoLookup, CallbackInfo ci) { + this.lookups = new ConcurrentHashMap<>(this.lookups); + } +} From 3ad4e2478e6965e902d1a77e2483d770d0a363d3 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 15 May 2025 20:21:34 -0400 Subject: [PATCH 3/4] Optimize MultiVariant.resolveParents --- .../MultiVariantMixin.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/model_optimizations/MultiVariantMixin.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/model_optimizations/MultiVariantMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/model_optimizations/MultiVariantMixin.java new file mode 100644 index 00000000..9e762b0f --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/model_optimizations/MultiVariantMixin.java @@ -0,0 +1,41 @@ +package org.embeddedt.modernfix.common.mixin.perf.model_optimizations; + +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import net.minecraft.client.renderer.block.model.MultiVariant; +import net.minecraft.client.renderer.block.model.Variant; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.resources.ResourceLocation; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.List; +import java.util.function.Function; + +@Mixin(value = MultiVariant.class, priority = 700) +@ClientOnlyMixin +public abstract class MultiVariantMixin { + @Shadow public abstract List getVariants(); + + /** + * @author embeddedt + * @reason avoid streams, try to optimize for common case + */ + @Overwrite + public void resolveParents(Function modelGetter) { + var variants = this.getVariants(); + // There is usually only a single variant + if (variants.size() == 1) { + modelGetter.apply(variants.get(0).getModelLocation()).resolveParents(modelGetter); + } else if(variants.size() > 1) { + ObjectOpenHashSet seenLocations = new ObjectOpenHashSet<>(variants.size()); + for (var variant : variants) { + var location = variant.getModelLocation(); + if (seenLocations.add(location)) { + modelGetter.apply(location).resolveParents(modelGetter); + } + } + } + } +} From 588b56530e0863697a0290796b0948e61351f842 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 15 May 2025 20:22:29 -0400 Subject: [PATCH 4/4] Support clearing model registry in dev for testing purposes --- .../modernfix/duck/IExtendedModelBakery.java | 1 + .../dynamicresources/DynamicBakedModelProvider.java | 10 +++++++++- .../perf/dynamic_resources/ModelBakeryMixin.java | 6 ++++++ .../perf/dynamic_resources/ModelBakeryMixin.java | 13 +++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/duck/IExtendedModelBakery.java b/common/src/main/java/org/embeddedt/modernfix/duck/IExtendedModelBakery.java index b6fb8947..c2532596 100644 --- a/common/src/main/java/org/embeddedt/modernfix/duck/IExtendedModelBakery.java +++ b/common/src/main/java/org/embeddedt/modernfix/duck/IExtendedModelBakery.java @@ -14,4 +14,5 @@ public interface IExtendedModelBakery { ImmutableList getBlockStatesForMRL(StateDefinition stateDefinition, ModelResourceLocation location); BakedModel bakeDefault(ResourceLocation modelLocation, ModelState state); UnbakedModel mfix$getUnbakedMissingModel(); + void mfix$clearModels(); } diff --git a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java index d31ac804..288b4028 100644 --- a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java +++ b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java @@ -19,6 +19,7 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import org.embeddedt.modernfix.duck.IExtendedModelBakery; import org.embeddedt.modernfix.ModernFix; +import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -194,7 +195,14 @@ public class DynamicBakedModelProvider implements Map void onModelRemoved(RemovalNotification notification) { if(!debugDynamicModelLoading) return; + // If the entry was replaced (happens because of the Minecraft model loading code structure), or + // was explicitly removed, we don't really care. + var reason = notification.getCause(); + if (reason == RemovalCause.REPLACED || reason == RemovalCause.EXPLICIT) { + return; + } Object k = notification.getKey(); if(k == null) return; @@ -341,4 +348,10 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { public UnbakedModel mfix$getUnbakedMissingModel() { return missingModel; } + + @Override + public void mfix$clearModels() { + loadedModels.invalidateAll(); + loadedBakedModels.invalidateAll(); + } }