diff --git a/build.gradle b/build.gradle index 504cc599..f22c3686 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id "architectury-plugin" version "3.4-SNAPSHOT" - id "dev.architectury.loom" version "1.4-SNAPSHOT" apply false + id "dev.architectury.loom" version "1.5-SNAPSHOT" apply false id "maven-publish" id 'com.matthewprenger.cursegradle' version '1.4.0' apply false id 'com.palantir.git-version' version '1.0.0' diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ModelManagerMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ModelManagerMixin.java index 04351172..392ba1c7 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ModelManagerMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ModelManagerMixin.java @@ -2,6 +2,7 @@ package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources; import com.google.common.collect.ImmutableList; import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.client.resources.model.ModelManager; import net.minecraft.resources.ResourceLocation; @@ -14,11 +15,15 @@ import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.embeddedt.modernfix.util.LambdaMap; import org.spongepowered.asm.mixin.Mixin; +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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.io.BufferedReader; import java.io.IOException; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -29,6 +34,15 @@ import java.util.stream.Collectors; @Mixin(ModelManager.class) @ClientOnlyMixin public class ModelManagerMixin { + @Shadow private Map bakedRegistry; + + @Inject(method = "", at = @At("RETURN")) + private void injectDummyBakedRegistry(CallbackInfo ci) { + if(this.bakedRegistry == null) { + this.bakedRegistry = new HashMap<>(); + } + } + @Redirect(method = "reload", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/model/ModelManager;loadBlockModels(Lnet/minecraft/server/packs/resources/ResourceManager;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;")) private CompletableFuture> deferBlockModelLoad(ResourceManager manager, Executor executor) { return CompletableFuture.completedFuture(new LambdaMap<>(location -> loadSingleBlockModel(manager, location))); diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/BatMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/BatMixin.java new file mode 100644 index 00000000..e3cc0ddc --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/BatMixin.java @@ -0,0 +1,28 @@ +package org.embeddedt.modernfix.common.mixin.perf.ticking_chunk_alloc; + +import net.minecraft.world.entity.ambient.Bat; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.time.LocalDate; + +@Mixin(value = Bat.class, priority = 1200) +public class BatMixin { + private static long mfix$lastQueriedTime = -1L; + private static LocalDate mfix$lastQueriedDate = null; + + /** + * @author embeddedt + * @reason avoid excessive allocations from continuously querying the date, only get a new date once every 30 seconds + */ + @Redirect(method = "isHalloween", at = @At(value = "INVOKE", target = "Ljava/time/LocalDate;now()Ljava/time/LocalDate;"), require = 0) + private static LocalDate useCachedLocalDate() { + LocalDate date = mfix$lastQueriedDate; + if(date == null || Math.abs(System.currentTimeMillis() - mfix$lastQueriedTime) > 30000) { + mfix$lastQueriedDate = date = LocalDate.now(); + mfix$lastQueriedTime = System.currentTimeMillis(); + } + return date; + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkGeneratorMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkGeneratorMixin.java new file mode 100644 index 00000000..193995f4 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkGeneratorMixin.java @@ -0,0 +1,26 @@ +package org.embeddedt.modernfix.common.mixin.perf.ticking_chunk_alloc; + +import net.minecraft.world.level.chunk.ChunkGenerator; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +@Mixin(ChunkGenerator.class) +public class ChunkGeneratorMixin { + /** + * @author embeddedt + * @reason Avoid allocation if the chunk contains no structures + */ + @Redirect(method = "getMobsAt", at = @At(value = "INVOKE", target = "Ljava/util/Map;entrySet()Ljava/util/Set;"), require = 0) + private Set avoidSetAllocation(Map instance) { + if(instance.isEmpty()) { + return Collections.emptySet(); + } else { + return instance.entrySet(); + } + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkHolderMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkHolderMixin.java new file mode 100644 index 00000000..2ea7c2de --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/ticking_chunk_alloc/ChunkHolderMixin.java @@ -0,0 +1,40 @@ +package org.embeddedt.modernfix.common.mixin.perf.ticking_chunk_alloc; + +import com.mojang.datafixers.util.Either; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.world.level.chunk.LevelChunk; +import org.embeddedt.modernfix.util.EitherUtil; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.concurrent.CompletableFuture; + +@Mixin(value = ChunkHolder.class, priority = 500) +public abstract class ChunkHolderMixin { + @Shadow public abstract CompletableFuture> getTickingChunkFuture(); + + @Shadow public abstract CompletableFuture> getFullChunkFuture(); + + /** + * @author embeddedt + * @reason avoid Optional allocation + */ + @Overwrite + public LevelChunk getTickingChunk() { + CompletableFuture> completableFuture = this.getTickingChunkFuture(); + Either either = completableFuture.getNow(null); + return either == null ? null : EitherUtil.leftOrNull(either); + } + + /** + * @author embeddedt + * @reason avoid Optional allocation + */ + @Overwrite + public LevelChunk getFullChunk() { + CompletableFuture> completableFuture = this.getFullChunkFuture(); + Either either = completableFuture.getNow(null); + return either == null ? null : EitherUtil.leftOrNull(either); + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/util/EitherUtil.java b/common/src/main/java/org/embeddedt/modernfix/util/EitherUtil.java new file mode 100644 index 00000000..52bc52c2 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/util/EitherUtil.java @@ -0,0 +1,52 @@ +package org.embeddedt.modernfix.util; + +import com.mojang.datafixers.util.Either; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.Field; + +public class EitherUtil { + private static final Class LEFT, RIGHT; + private static final MethodHandle LEFT_VAL, RIGHT_VAL; + + static { + try { + LEFT = Class.forName("com.mojang.datafixers.util.Either$Left"); + RIGHT = Class.forName("com.mojang.datafixers.util.Either$Right"); + Field lvalue = LEFT.getDeclaredField("value"); + lvalue.setAccessible(true); + Field rvalue = RIGHT.getDeclaredField("value"); + rvalue.setAccessible(true); + LEFT_VAL = MethodHandles.publicLookup().unreflectGetter(lvalue).asType(MethodType.methodType(Object.class, Either.class)); + RIGHT_VAL = MethodHandles.publicLookup().unreflectGetter(rvalue).asType(MethodType.methodType(Object.class, Either.class)); + } catch(ReflectiveOperationException e) { + throw new AssertionError("Failed to hook DFU Either", e); + } + } + + @SuppressWarnings("unchecked") + public static L leftOrNull(Either either) { + if(either.getClass() == LEFT) { + try { + return (L)LEFT_VAL.invokeExact(either); + } catch(Throwable e) { + throw new RuntimeException(e); + } + } + return null; + } + + @SuppressWarnings("unchecked") + public static R rightOrNull(Either either) { + if(either.getClass() == RIGHT) { + try { + return (R)RIGHT_VAL.invokeExact(either); + } catch(Throwable e) { + throw new RuntimeException(e); + } + } + return null; + } +} diff --git a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakerImplMixin.java b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakerImplMixin.java index 9ed0bd79..43c86168 100644 --- a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakerImplMixin.java +++ b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakerImplMixin.java @@ -1,5 +1,6 @@ package org.embeddedt.modernfix.fabric.mixin.perf.dynamic_resources; +import com.google.common.collect.ImmutableList; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.fabricmc.loader.api.FabricLoader; @@ -75,9 +76,19 @@ public abstract class ModelBakerImplMixin implements IExtendedModelBaker { synchronized (this.field_40571) { /* to emulate vanilla model loading, treat as top-level */ Optional blockOpt = Objects.equals(((ModelResourceLocation)arg).getVariant(), "inventory") ? Optional.empty() : BuiltInRegistries.BLOCK.getOptional(new ResourceLocation(arg.getNamespace(), arg.getPath())); + boolean invalidMRL = false; if(blockOpt.isPresent()) { /* load via lambda for mods that expect blockstate to get loaded */ - for(BlockState state : extendedBakery.getBlockStatesForMRL(blockOpt.get().getStateDefinition(), (ModelResourceLocation)arg)) { + ImmutableList states; + try { + states = extendedBakery.getBlockStatesForMRL(blockOpt.get().getStateDefinition(), (ModelResourceLocation)arg); + } catch(RuntimeException e) { + states = ImmutableList.of(); + invalidMRL = true; + // Fall back to getModel + cir.setReturnValue(this.field_40571.getModel(arg)); + } + for(BlockState state : states) { try { blockStateLoaderHandle.invokeExact(this.field_40571, state); } catch(Throwable e) { @@ -87,9 +98,11 @@ public abstract class ModelBakerImplMixin implements IExtendedModelBaker { } else { this.field_40571.loadTopLevel((ModelResourceLocation)arg); } - cir.setReturnValue(this.field_40571.topLevelModels.getOrDefault(arg, extendedBakery.mfix$getUnbakedMissingModel())); - // avoid leaks - this.field_40571.topLevelModels.clear(); + if(!invalidMRL) { + cir.setReturnValue(this.field_40571.topLevelModels.getOrDefault(arg, extendedBakery.mfix$getUnbakedMissingModel())); + // avoid leaks + this.field_40571.topLevelModels.clear(); + } } } else cir.setReturnValue(this.field_40571.getModel(arg)); diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 280e84db..2f6a5aba 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -45,7 +45,7 @@ dependencies { modCompileOnly("me.shedaniel:RoughlyEnoughItems-forge:${rei_version}") { transitive false } modCompileOnly("dev.latvian.mods:kubejs-forge:${kubejs_version}") //modRuntimeOnly("curse.maven:ferritecore-429235:4441949") - modCompileOnly("team.chisel.ctm:CTM:${ctm_version}") + modCompileOnly files("deps/ctm.jar") modCompileOnly("curse.maven:supermartijncore-454372:4455391") modCompileOnly("vazkii.patchouli:Patchouli:1.19.2-77") diff --git a/neoforge/deps/ctm.jar b/neoforge/deps/ctm.jar new file mode 100644 index 00000000..38243093 Binary files /dev/null and b/neoforge/deps/ctm.jar differ diff --git a/neoforge/src/main/java/org/embeddedt/modernfix/neoforge/config/NightConfigWatchThrottler.java b/neoforge/src/main/java/org/embeddedt/modernfix/neoforge/config/NightConfigWatchThrottler.java new file mode 100644 index 00000000..049575da --- /dev/null +++ b/neoforge/src/main/java/org/embeddedt/modernfix/neoforge/config/NightConfigWatchThrottler.java @@ -0,0 +1,56 @@ +package org.embeddedt.modernfix.neoforge.config; + +import com.electronwill.nightconfig.core.file.FileWatcher; +import com.google.common.collect.ForwardingCollection; +import com.google.common.collect.ForwardingMap; +import net.neoforged.fml.util.ObfuscationReflectionHelper; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.LockSupport; + +/** + * Throttle NightConfig's file watching. There are reports of this consuming excessive CPU time + * (example) and the spammed iterator calls + * end up being 10% of allocations when testing in a dev environment. + */ +public class NightConfigWatchThrottler { + private static final long DELAY = TimeUnit.MILLISECONDS.toNanos(1000); + + @SuppressWarnings("rawtypes") + public static void throttle() { + Map watchedDirs = ObfuscationReflectionHelper.getPrivateValue(FileWatcher.class, FileWatcher.defaultInstance(), "watchedDirs"); + ObfuscationReflectionHelper.setPrivateValue(FileWatcher.class, FileWatcher.defaultInstance(), new ForwardingMap() { + @Override + protected Map delegate() { + return watchedDirs; + } + + private Collection cachedValues; + + @Override + public Collection values() { + if(cachedValues == null) { + Collection values = super.values(); + cachedValues = new ForwardingCollection() { + @Override + protected Collection delegate() { + return values; + } + + @Override + public Iterator iterator() { + // iterator() is called at the beginning of each iteration of the watch loop, + // so it is a good spot to inject the delay. + LockSupport.parkNanos(DELAY); + return super.iterator(); + } + }; + } + return cachedValues; + } + }, "watchedDirs"); + } +} diff --git a/neoforge/src/main/java/org/embeddedt/modernfix/neoforge/mixin/perf/dynamic_resources/ItemModelMesherForgeMixin.java b/neoforge/src/main/java/org/embeddedt/modernfix/neoforge/mixin/perf/dynamic_resources/ItemModelMesherForgeMixin.java index bb06a10a..4fe8dd4e 100644 --- a/neoforge/src/main/java/org/embeddedt/modernfix/neoforge/mixin/perf/dynamic_resources/ItemModelMesherForgeMixin.java +++ b/neoforge/src/main/java/org/embeddedt/modernfix/neoforge/mixin/perf/dynamic_resources/ItemModelMesherForgeMixin.java @@ -4,7 +4,6 @@ import net.minecraft.client.renderer.ItemModelShaper; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelManager; import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.core.Holder; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; import net.neoforged.neoforge.client.model.RegistryAwareItemModelShaper; @@ -23,11 +22,11 @@ import java.util.Map; @Mixin(RegistryAwareItemModelShaper.class) @ClientOnlyMixin public abstract class ItemModelMesherForgeMixin extends ItemModelShaper { - @Shadow(remap = false) @Final @Mutable private Map, ModelResourceLocation> locations; + @Shadow(remap = false) @Final @Mutable private Map locations; - private Map, ModelResourceLocation> overrideLocations; + private Map overrideLocations; - private final DynamicModelCache> mfix$modelCache = new DynamicModelCache<>(k -> this.mfix$getModelSlow((Holder.Reference)k), true); + private final DynamicModelCache mfix$modelCache = new DynamicModelCache<>(k -> this.mfix$getModelSlow((Item)k), true); public ItemModelMesherForgeMixin(ModelManager arg) { super(arg); @@ -43,16 +42,16 @@ public abstract class ItemModelMesherForgeMixin extends ItemModelShaper { } @Unique - private ModelResourceLocation mfix$getLocationForge(Holder.Reference item) { + private ModelResourceLocation mfix$getLocationForge(Item item) { ModelResourceLocation map = overrideLocations.getOrDefault(item, SENTINEL); if(map == SENTINEL) { /* generate the appropriate location from our cache */ - map = ModelLocationCache.get(item.value()); + map = ModelLocationCache.get(item); } return map; } - private BakedModel mfix$getModelSlow(Holder.Reference key) { + private BakedModel mfix$getModelSlow(Item key) { ModelResourceLocation map = mfix$getLocationForge(key); return map == null ? null : getModelManager().getModel(map); } @@ -65,7 +64,7 @@ public abstract class ItemModelMesherForgeMixin extends ItemModelShaper { @Overwrite @Override public BakedModel getItemModel(Item item) { - return this.mfix$modelCache.get(item.builtInRegistryHolder()); + return this.mfix$modelCache.get(item); } /** @@ -76,7 +75,7 @@ public abstract class ItemModelMesherForgeMixin extends ItemModelShaper { @Overwrite @Override public void register(Item item, ModelResourceLocation location) { - overrideLocations.put(item.builtInRegistryHolder(), location); + overrideLocations.put(item, location); } /** diff --git a/neoforge/src/main/java/org/embeddedt/modernfix/neoforge/mixin/perf/dynamic_resources/ctm/TextureMetadataHandlerMixin.java b/neoforge/src/main/java/org/embeddedt/modernfix/neoforge/mixin/perf/dynamic_resources/ctm/TextureMetadataHandlerMixin.java index 7982588a..ca9ea719 100644 --- a/neoforge/src/main/java/org/embeddedt/modernfix/neoforge/mixin/perf/dynamic_resources/ctm/TextureMetadataHandlerMixin.java +++ b/neoforge/src/main/java/org/embeddedt/modernfix/neoforge/mixin/perf/dynamic_resources/ctm/TextureMetadataHandlerMixin.java @@ -3,12 +3,15 @@ package org.embeddedt.modernfix.neoforge.mixin.perf.dynamic_resources.ctm; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import com.mojang.datafixers.util.Pair; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.*; import net.minecraft.resources.ResourceLocation; import org.embeddedt.modernfix.ModernFixClient; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.embeddedt.modernfix.annotation.RequiresMod; import org.embeddedt.modernfix.api.entrypoint.ModernFixClientIntegration; +import org.embeddedt.modernfix.neoforge.dynresources.IModelBakerImpl; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -16,6 +19,9 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import team.chisel.ctm.CTM; +import team.chisel.ctm.api.model.IModelCTM; +import team.chisel.ctm.client.model.AbstractCTMBakedModel; +import team.chisel.ctm.client.model.ModelCTM; import team.chisel.ctm.client.texture.IMetadataSectionCTM; import team.chisel.ctm.client.util.ResourceUtil; import team.chisel.ctm.client.util.TextureMetadataHandler; @@ -23,6 +29,7 @@ import team.chisel.ctm.client.util.TextureMetadataHandler; import javax.annotation.Nonnull; import java.io.IOException; import java.util.*; +import java.util.function.Function; @Mixin(TextureMetadataHandler.class) @RequiresMod("ctm") @@ -31,22 +38,21 @@ public abstract class TextureMetadataHandlerMixin implements ModernFixClientInte @Shadow(remap = false) @Nonnull protected abstract BakedModel wrap(UnbakedModel model, BakedModel object) throws IOException; - @Shadow(remap = false) @Final public static Multimap TEXTURES_SCRAPED; + @Shadow @Final private Multimap scrapedTextures; @Inject(method = "", at = @At("RETURN")) private void subscribeDynamic(CallbackInfo ci) { ModernFixClient.CLIENT_INTEGRATIONS.add(this); } - @Inject(method = { "onModelBake(Lnet/minecraftforge/client/event/ModelEvent$ModifyBakingResult;)V", "onModelBake(Lnet/minecraftforge/client/event/ModelEvent$BakingCompleted;)V" }, at = @At("HEAD"), cancellable = true, remap = false) + @Inject(method = { "onModelBake(Lnet/neoforged/neoforge/client/event/ModelEvent$ModifyBakingResult;)V", "onModelBake(Lnet/neoforged/neoforge/client/event/ModelEvent$BakingCompleted;)V" }, at = @At("HEAD"), cancellable = true, remap = false) private void noIteration(CallbackInfo ci) { ci.cancel(); } @Override public BakedModel onBakedModelLoad(ResourceLocation rl, UnbakedModel rootModel, BakedModel baked, ModelState state, ModelBakery bakery) { - if(true) throw new UnsupportedOperationException("not ported yet"); - if (rl instanceof ModelResourceLocation && false /* !(baked instanceof AbstractCTMBakedModel) && !baked.isCustomRenderer() */) { + if (rl instanceof ModelResourceLocation && !(baked instanceof AbstractCTMBakedModel) && !baked.isCustomRenderer()) { Deque dependencies = new ArrayDeque<>(); Set seenModels = new HashSet<>(); dependencies.push(rl); @@ -63,7 +69,7 @@ public abstract class TextureMetadataHandlerMixin implements ModernFixClientInte continue; } - Collection textures = Sets.newHashSet(TEXTURES_SCRAPED.get(dep)); + Collection textures = Sets.newHashSet(scrapedTextures.get(dep)); Collection newDependencies = model.getDependencies(); for (Material tex : textures) { IMetadataSectionCTM meta = null; @@ -97,8 +103,6 @@ public abstract class TextureMetadataHandlerMixin implements ModernFixClientInte } private void handleInit(ResourceLocation key, BakedModel wrappedModel, ModelBakery bakery) { - if(true) throw new UnsupportedOperationException("not ported yet"); - /* if(wrappedModel instanceof AbstractCTMBakedModel baked) { IModelCTM var10 = baked.getModel(); if (var10 instanceof ModelCTM ctmModel) { @@ -106,8 +110,8 @@ public abstract class TextureMetadataHandlerMixin implements ModernFixClientInte Function spriteGetter = (m) -> { return Minecraft.getInstance().getModelManager().getAtlas(m.atlasLocation()).getSprite(m.texture()); }; - ModelBakery.ModelBakerImpl baker = ModelBakerImplAccessor.createImpl(bakery, ($, m) -> { - return spriteGetter.apply(m); + ModelBakery.ModelBakerImpl baker = bakery.new ModelBakerImpl((rl, m) -> { + return m.sprite(); }, key); // bypass bakedCache so that dependent models get re-baked and thus retrieve their sprites again ((IModelBakerImpl)baker).mfix$ignoreCache(); @@ -115,6 +119,5 @@ public abstract class TextureMetadataHandlerMixin implements ModernFixClientInte } } } - */ } } diff --git a/neoforge/src/main/java/org/embeddedt/modernfix/platform/neoforge/ModernFixPlatformHooksImpl.java b/neoforge/src/main/java/org/embeddedt/modernfix/platform/neoforge/ModernFixPlatformHooksImpl.java index d203ae4b..5f5d1931 100644 --- a/neoforge/src/main/java/org/embeddedt/modernfix/platform/neoforge/ModernFixPlatformHooksImpl.java +++ b/neoforge/src/main/java/org/embeddedt/modernfix/platform/neoforge/ModernFixPlatformHooksImpl.java @@ -24,6 +24,7 @@ import net.neoforged.neoforge.server.ServerLifecycleHooks; import org.embeddedt.modernfix.api.constants.IntegrationConstants; import org.embeddedt.modernfix.core.ModernFixMixinPlugin; import org.embeddedt.modernfix.neoforge.config.NightConfigFixer; +import org.embeddedt.modernfix.neoforge.config.NightConfigWatchThrottler; import org.embeddedt.modernfix.neoforge.init.ModernFixForge; import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; import org.embeddedt.modernfix.spark.SparkLaunchProfiler; @@ -106,6 +107,7 @@ public class ModernFixPlatformHooksImpl implements ModernFixPlatformHooks { } NightConfigFixer.monitorFileWatcher(); + NightConfigWatchThrottler.throttle(); } public void applyASMTransformers(String mixinClassName, ClassNode targetClass) {