diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/BlockStateModelLoaderMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/BlockStateModelLoaderMixin.java deleted file mode 100644 index a2247c04..00000000 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/BlockStateModelLoaderMixin.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources; - -import com.google.common.collect.ImmutableList; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntMaps; -import net.minecraft.client.Minecraft; -import net.minecraft.client.color.block.BlockColors; -import net.minecraft.client.resources.model.BlockStateModelLoader; -import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.client.resources.model.UnbakedModel; -import net.minecraft.core.DefaultedRegistry; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.profiling.ProfilerFiller; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.annotation.ClientOnlyMixin; -import org.embeddedt.modernfix.duck.IBlockStateModelLoader; -import org.embeddedt.modernfix.dynamicresources.ModelBakeryHelpers; -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.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.Collections; -import java.util.Iterator; -import java.util.Map; -import java.util.function.BiConsumer; - -@Mixin(BlockStateModelLoader.class) -@ClientOnlyMixin -public abstract class BlockStateModelLoaderMixin implements IBlockStateModelLoader { - @Shadow protected abstract void loadBlockStateDefinitions(ResourceLocation resourceLocation, StateDefinition stateDefinition); - - @Shadow @Mutable @Final private Object2IntMap modelGroups; - - private ImmutableList filteredStates; - - @Inject(method = "", at = @At("RETURN")) - private void makeModelGroupsSynchronized(Map map, ProfilerFiller profilerFiller, UnbakedModel unbakedModel, BlockColors blockColors, BiConsumer biConsumer, CallbackInfo ci) { - this.modelGroups = Object2IntMaps.synchronize(this.modelGroups); - } - - @Override - public void loadSpecificBlock(ModelResourceLocation location) { - var optionalBlock = BuiltInRegistries.BLOCK.getOptional(location.id()); - if(optionalBlock.isPresent()) { - try { - // Only filter states if we are in a world and not in the loading overlay - filteredStates = (Minecraft.getInstance().getOverlay() == null && Minecraft.getInstance().level != null) ? ModelBakeryHelpers.getBlockStatesForMRL(optionalBlock.get().getStateDefinition(), location) : null; - } catch(RuntimeException e) { - ModernFix.LOGGER.error("Exception filtering states on {}", location, e); - filteredStates = null; - } - try { - this.loadBlockStateDefinitions(location.id(), optionalBlock.get().getStateDefinition()); - } finally { - filteredStates = null; - } - } - } - - @Redirect(method = "loadAllBlockStates", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/DefaultedRegistry;iterator()Ljava/util/Iterator;")) - private Iterator skipIteratingBlocks(DefaultedRegistry instance) { - return Collections.emptyIterator(); - } - - @Redirect(method = "loadBlockStateDefinitions", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/StateDefinition;getPossibleStates()Lcom/google/common/collect/ImmutableList;")) - private ImmutableList getFilteredStates(StateDefinition instance) { - return this.filteredStates != null ? this.filteredStates : instance.getPossibleStates(); - } -} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ItemModelShaperMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ItemModelShaperMixin.java index e47f5fee..0ef809b8 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ItemModelShaperMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ItemModelShaperMixin.java @@ -1,91 +1,38 @@ package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; 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.resources.ResourceLocation; -import net.minecraft.world.item.Item; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; -import org.embeddedt.modernfix.dynamicresources.DynamicModelCache; -import org.embeddedt.modernfix.dynamicresources.ModelLocationCache; -import org.embeddedt.modernfix.util.DynamicInt2ObjectMap; import org.spongepowered.asm.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.HashMap; import java.util.Map; @Mixin(ItemModelShaper.class) @ClientOnlyMixin public abstract class ItemModelShaperMixin { - - @Shadow public abstract ModelManager getModelManager(); - - @Shadow @Final @Mutable private Int2ObjectMap shapesCache; - - private Map overrideLocationsVanilla; - - public ItemModelShaperMixin() { - super(); - } - - private static final ModelResourceLocation SENTINEL_VANILLA = new ModelResourceLocation(ResourceLocation.fromNamespaceAndPath("modernfix", "sentinel"), "sentinel"); - - private final DynamicModelCache mfix$itemModelCache = new DynamicModelCache<>(k -> this.mfix$getModelForItem((Item)k), true); + @Shadow @Final @Mutable private Map modelToBakedModel; @Inject(method = "", at = @At("RETURN")) - private void replaceLocationMap(CallbackInfo ci) { - overrideLocationsVanilla = new HashMap<>(); - this.shapesCache = new DynamicInt2ObjectMap<>(index -> getModelManager().getModel(ModelLocationCache.get(Item.byId(index)))); + private void initializeLazyCache(CallbackInfo ci) { + this.modelToBakedModel = new Object2ObjectLinkedOpenHashMap<>(this.modelToBakedModel); } - @Unique - private ModelResourceLocation mfix$getLocation(Item item) { - ModelResourceLocation map = overrideLocationsVanilla.getOrDefault(item, SENTINEL_VANILLA); - if(map == SENTINEL_VANILLA) { - /* generate the appropriate location from our cache */ - map = ModelLocationCache.get(item); + /** + * @author embeddedt + * @reason Prevent all baked item models from being cached forever. We can safely mutate the map here as vanilla + * also uses computeIfAbsent, which means multithreaded access is not safe in vanilla either. + */ + @Inject(method = "getItemModel(Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/client/resources/model/BakedModel;", at = @At(value = "RETURN")) + private void limitCacheSize(ResourceLocation resourceLocation, CallbackInfoReturnable cir) { + var map = modelToBakedModel; + if (map instanceof Object2ObjectLinkedOpenHashMap linkedMap && linkedMap.size() > 1000) { + linkedMap.removeFirst(); } - return map; - } - - - private BakedModel mfix$getModelForItem(Item item) { - ModelResourceLocation map = mfix$getLocation(item); - return map == null ? null : getModelManager().getModel(map); - } - - /** - * @author embeddedt - * @reason Get the stored location for that item and meta, and get the model - * from that location from the model manager. - **/ - @Overwrite - public BakedModel getItemModel(Item item) { - return this.mfix$itemModelCache.get(item); - } - - /** - * @author embeddedt - * @reason Don't get all models during init (with dynamic loading, that would - * generate them all). Just store location instead. - **/ - @Overwrite - public void register(Item item, ModelResourceLocation location) { - overrideLocationsVanilla.put(item, location); - } - - /** - * @author embeddedt - * @reason Disable cache rebuilding (with dynamic loading, that would generate - * all models). - **/ - @Overwrite - public void rebuildCache() { - this.mfix$itemModelCache.clear(); } } diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ItemRendererMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ItemRendererMixin.java deleted file mode 100644 index 79b2d1d3..00000000 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ItemRendererMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources; - -import net.minecraft.client.renderer.ItemModelShaper; -import net.minecraft.client.renderer.entity.ItemRenderer; -import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.world.item.Item; -import org.embeddedt.modernfix.annotation.ClientOnlyMixin; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(ItemRenderer.class) -@ClientOnlyMixin -public class ItemRendererMixin { - /** - * Don't waste space putting all these locations into the cache, compute them on demand later. - */ - @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/ItemModelShaper;register(Lnet/minecraft/world/item/Item;Lnet/minecraft/client/resources/model/ModelResourceLocation;)V")) - private void skipDefaultRegistration(ItemModelShaper shaper, Item item, ModelResourceLocation mrl) { - - } -} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ModelBakeryMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ModelBakeryMixin.java deleted file mode 100644 index a72b0dd2..00000000 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ModelBakeryMixin.java +++ /dev/null @@ -1,233 +0,0 @@ -package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources; - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; -import net.minecraft.client.color.block.BlockColors; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.BlockModelRotation; -import net.minecraft.client.resources.model.BlockStateModelLoader; -import net.minecraft.client.resources.model.ModelBakery; -import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.client.resources.model.UnbakedModel; -import net.minecraft.core.DefaultedRegistry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.profiling.ProfilerFiller; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.ModernFixClient; -import org.embeddedt.modernfix.annotation.ClientOnlyMixin; -import org.embeddedt.modernfix.api.entrypoint.ModernFixClientIntegration; -import org.embeddedt.modernfix.duck.IBlockStateModelLoader; -import org.embeddedt.modernfix.duck.IExtendedModelBakery; -import org.embeddedt.modernfix.util.DynamicOverridableMap; -import org.embeddedt.modernfix.util.LRUMap; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -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.util.Collections; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.locks.ReentrantLock; - -@Mixin(ModelBakery.class) -@ClientOnlyMixin -public abstract class ModelBakeryMixin implements IExtendedModelBakery { - @Unique - private BlockStateModelLoader dynamicLoader; - - @Unique - private final ReentrantLock modelBakeryLock = new ReentrantLock(); - - @Unique - private ModelBakery.TextureGetter textureGetter; - - @Unique - private BakedModel bakedMissingModel; - - @Shadow abstract UnbakedModel getModel(ResourceLocation resourceLocation); - - @Shadow @Final private UnbakedModel missingModel; - - @Unique - private static final boolean DEBUG_MODEL_LOADS = Boolean.getBoolean("modernfix.debugDynamicModelLoading"); - - /** - * Bake a model using the provided texture getter and location. The model is stored in {@link ModelBakeryMixin#bakedTopLevelModels}. - */ - @Shadow(aliases = "lambda$bakeModels$6") protected abstract void method_61072(ModelBakery.TextureGetter getter, ModelResourceLocation location, UnbakedModel model); - - @Shadow @Mutable @Final private Map bakedTopLevelModels; - @Shadow @Mutable @Final public Map topLevelModels; - @Shadow @Mutable @Final private Map unbakedCache; - @Shadow @Mutable @Final public Map bakedCache; - - @Shadow protected abstract void loadItemModelAndDependencies(ResourceLocation resourceLocation); - - - @Shadow @Final public static ModelResourceLocation MISSING_MODEL_VARIANT; - - private final Map mfix$emulatedBakedRegistry = new DynamicOverridableMap<>(ModelResourceLocation.class, this::loadBakedModelDynamic); - - @Override - public UnbakedModel mfix$loadUnbakedModelDynamic(ModelResourceLocation location) { - if(location.equals(MISSING_MODEL_VARIANT)) { - return missingModel; - } - modelBakeryLock.lock(); - try { - UnbakedModel existing = this.topLevelModels.get(location); - if (existing != null) { - return existing; - } - if(DEBUG_MODEL_LOADS) { - ModernFix.LOGGER.info("Loading model {}", location); - } - if(location.variant().equals("inventory")) { - this.loadItemModelAndDependencies(location.id()); - } else { - ((IBlockStateModelLoader)dynamicLoader).loadSpecificBlock(location); - } - return this.topLevelModels.getOrDefault(location, this.missingModel); - } finally { - modelBakeryLock.unlock(); - } - } - - @Override - public UnbakedModel mfix$getMissingModel() { - return missingModel; - } - - @Unique - private BakedModel loadBakedModelDynamic(ModelResourceLocation location) { - if(location.equals(MISSING_MODEL_VARIANT)) { - return bakedMissingModel; - } - BakedModel model; - modelBakeryLock.lock(); - try { - model = bakedTopLevelModels.get(location); - if(model == null) { - UnbakedModel prototype = mfix$loadUnbakedModelDynamic(location); - if(prototype == missingModel) { - model = bakedMissingModel; - } else { - prototype.resolveDependencies(this::getModel); - if(DEBUG_MODEL_LOADS) { - ModernFix.LOGGER.info("Baking model {}", location); - } - this.method_61072(this.textureGetter, location, prototype); - model = bakedTopLevelModels.remove(location); - if(model == null) { - ModernFix.LOGGER.error("Failed to load model " + location); - model = bakedMissingModel; - } - for(ModernFixClientIntegration integration : ModernFixClient.CLIENT_INTEGRATIONS) { - model = integration.onBakedModelLoad(location, prototype, model, BlockModelRotation.X0_Y0, (ModelBakery)(Object)this, this.textureGetter); - } - } - } - } finally { - modelBakeryLock.unlock(); - } - return model; - } - - @ModifyExpressionValue(method = "", at = @At(value = "CONSTANT", args = "stringValue=missing_model")) - private String replaceBackingMaps(String original) { - this.unbakedCache = new LRUMap<>(this.unbakedCache); - this.bakedCache = new LRUMap<>(this.bakedCache); - this.topLevelModels = new LRUMap<>(this.topLevelModels); - this.bakedTopLevelModels = new LRUMap<>(this.bakedTopLevelModels); - return original; - } - - @WrapOperation(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/model/BlockStateModelLoader;loadAllBlockStates()V")) - private void noInitialBlockStateLoad(BlockStateModelLoader instance, Operation original) { - dynamicLoader = instance; - original.call(instance); - } - - @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/DefaultedRegistry;keySet()Ljava/util/Set;")) - private Set skipLoadingItems(DefaultedRegistry instance) { - return Collections.emptySet(); - } - - - @Inject(method = "bakeModels", at = @At("HEAD")) - private void storeTextureGetterAndBakeMissing(ModelBakery.TextureGetter textureGetter, CallbackInfo ci) { - this.textureGetter = textureGetter; - this.method_61072(textureGetter, MISSING_MODEL_VARIANT, Objects.requireNonNull(this.topLevelModels.get(MISSING_MODEL_VARIANT))); - this.bakedMissingModel = this.bakedTopLevelModels.get(MISSING_MODEL_VARIANT); - } - - private boolean inInitialLoad = true; - - @Inject(method = "bakeModels", at = @At("RETURN")) - private void onInitialBakeFinish(ModelBakery.TextureGetter textureGetter, CallbackInfo ci) { - var permanentMRLs = new ObjectOpenHashSet<>(this.bakedTopLevelModels.keySet()); - ((LRUMap)this.bakedTopLevelModels).setPermanentEntries(permanentMRLs); - ModernFix.LOGGER.info("Dynamic model bakery initial baking finished, with {} permanent top level baked models", this.bakedTopLevelModels.size()); - } - - @Inject(method = "", at = @At("RETURN")) - private void onInitialLoadFinish(BlockColors blockColors, ProfilerFiller profilerFiller, Map map, Map map2, CallbackInfo ci) { - var permanentMRLs = new ObjectOpenHashSet<>(this.topLevelModels.keySet()); - ((LRUMap)this.topLevelModels).setPermanentEntries(permanentMRLs); - ModernFix.LOGGER.info("Dynamic model bakery loading finished, with {} permanent top level models", this.topLevelModels.size()); - } - - @Unique - private int tickCount; - - @Unique - private static final int MAXIMUM_CACHE_SIZE = 1000; - - private void runCleanup() { - ((LRUMap)this.unbakedCache).dropEntriesToMeetSize(MAXIMUM_CACHE_SIZE); - ((LRUMap)this.bakedCache).dropEntriesToMeetSize(MAXIMUM_CACHE_SIZE); - ((LRUMap)this.topLevelModels).dropEntriesToMeetSize(MAXIMUM_CACHE_SIZE); - ((LRUMap)this.bakedTopLevelModels).dropEntriesToMeetSize(MAXIMUM_CACHE_SIZE); - } - - @Override - public void mfix$finishLoading() { - inInitialLoad = false; - } - - @Override - public void mfix$tick() { - if(inInitialLoad) { - return; - } - tickCount++; - if((tickCount % 200) == 0) { - if(modelBakeryLock.tryLock()) { - try { - runCleanup(); - } finally { - modelBakeryLock.unlock(); - } - } - } - } - - /** - * @author embeddedt - * @reason We provide a fake baked registry to the rest of Minecraft, that dynamically loads models. - */ - @Overwrite - public Map getBakedTopLevelModels() { - return this.mfix$emulatedBakedRegistry; - } -} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ModelDiscoveryMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ModelDiscoveryMixin.java new file mode 100644 index 00000000..000e4e7b --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ModelDiscoveryMixin.java @@ -0,0 +1,23 @@ +package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources; + +import net.minecraft.client.resources.model.ModelDiscovery; +import net.minecraft.client.resources.model.ModelResourceLocation; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +import java.util.HashSet; +import java.util.Set; + +@Mixin(ModelDiscovery.class) +@ClientOnlyMixin +public class ModelDiscoveryMixin { + /** + * @author embeddedt + * @reason nothing is mandatory at launch, we load things dynamically + */ + @Overwrite + private static Set listMandatoryModels() { + return new HashSet<>(); + } +} 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 f8ac8d85..31a9c680 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 @@ -1,37 +1,24 @@ package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources; import com.google.common.collect.ImmutableList; -import com.llamalad7.mixinextras.sugar.Local; -import it.unimi.dsi.fastutil.objects.Object2IntMap; import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.resources.model.AtlasSet; import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.ModelBakery; +import net.minecraft.client.resources.model.BlockStateModelLoader; import net.minecraft.client.resources.model.ModelManager; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; -import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; -import org.embeddedt.modernfix.duck.IExtendedModelBakery; import org.embeddedt.modernfix.duck.IExtendedModelManager; -import org.embeddedt.modernfix.util.CacheUtil; -import org.embeddedt.modernfix.util.LambdaMap; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Coerce; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import java.io.BufferedReader; -import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -42,9 +29,6 @@ import java.util.concurrent.Executor; public class ModelManagerMixin implements IExtendedModelManager { @Shadow private Map bakedRegistry; - @Unique - private Runnable tickHandler = () -> {}; - @Inject(method = "", at = @At("RETURN")) private void injectDummyBakedRegistry(CallbackInfo ci) { if(this.bakedRegistry == null) { @@ -54,60 +38,21 @@ public class ModelManagerMixin implements IExtendedModelManager { @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) { - var cache = CacheUtil.simpleCacheForLambda(location -> loadSingleBlockModel(manager, location), 100L); - return CompletableFuture.completedFuture(new LambdaMap<>(location -> cache.getUnchecked(location))); + return CompletableFuture.completedFuture(Map.of()); } - // TODO - make blockstate unbaked model loading lazy - /* - @Redirect(method = "reload", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/model/ModelManager;loadBlockStates(Lnet/minecraft/server/packs/resources/ResourceManager;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;")) - private CompletableFuture>> deferBlockStateLoad(ResourceManager manager, Executor executor) { - var cache = CacheUtil.>simpleCacheForLambda(location -> loadSingleBlockState(manager, location), 100L); - return CompletableFuture.completedFuture(new LambdaMap<>(location -> cache.getUnchecked(location))); + @Redirect(method = "reload", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/model/ModelManager;loadBlockStates(Lnet/minecraft/client/resources/model/BlockStateModelLoader;Lnet/minecraft/server/packs/resources/ResourceManager;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;")) + private CompletableFuture deferBlockStateLoad(BlockStateModelLoader blockStateModelLoader, ResourceManager resourceManager, Executor executor) { + return CompletableFuture.completedFuture(new BlockStateModelLoader.LoadedModels(Map.of())); } - */ @Redirect(method = "loadModels", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/StateDefinition;getPossibleStates()Lcom/google/common/collect/ImmutableList;")) private ImmutableList skipCollection(StateDefinition definition) { return ImmutableList.of(); } - private BlockModel loadSingleBlockModel(ResourceManager manager, ResourceLocation location) { - return manager.getResource(location).map(resource -> { - try (BufferedReader reader = resource.openAsReader()) { - return BlockModel.fromStream(reader); - } catch(IOException e) { - ModernFix.LOGGER.error("Couldn't load model", e); - return null; - } - }).orElse(null); - } - - /* - private List loadSingleBlockState(ResourceManager manager, ResourceLocation location) { - return manager.getResourceStack(location).stream().map(resource -> { - try (BufferedReader reader = resource.openAsReader()) { - return new BlockStateModelLoader.LoadedJson(resource.sourcePackId(), GsonHelper.parse(reader)); - } catch(IOException e) { - ModernFix.LOGGER.error("Couldn't load blockstate", e); - return null; - } - }).filter(Objects::nonNull).collect(Collectors.toList()); - } - */ - - @Inject(method = "loadModels", at = @At("RETURN")) - private void storeTicker(ProfilerFiller profilerFiller, Map map, ModelBakery modelBakery, Object2IntMap object2IntMap, CallbackInfoReturnable cir) { - tickHandler = ((IExtendedModelBakery)modelBakery)::mfix$tick; - } - - @Inject(method = "apply", at = @At("RETURN")) - private void freezeBakery(@Coerce Object reloadState, ProfilerFiller profilerFiller, CallbackInfo ci, @Local(ordinal = 0) ModelBakery bakery) { - ((IExtendedModelBakery)bakery).mfix$finishLoading(); - } - @Override public void mfix$tick() { - tickHandler.run(); + } } diff --git a/common/src/main/resources/modernfix.accesswidener b/common/src/main/resources/modernfix.accesswidener index 7610aad7..48200305 100644 --- a/common/src/main/resources/modernfix.accesswidener +++ b/common/src/main/resources/modernfix.accesswidener @@ -32,7 +32,6 @@ accessible field net/minecraft/client/renderer/texture/Stitcher$Holder width I accessible field net/minecraft/client/renderer/texture/Stitcher$Holder height I accessible field net/minecraft/network/syncher/EntityDataAccessor id I mutable field net/minecraft/network/syncher/EntityDataAccessor id I -accessible method net/minecraft/Util makeExecutor (Ljava/lang/String;)Ljava/util/concurrent/ExecutorService; accessible field net/minecraft/server/level/ChunkMap updatingChunkMap Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap; accessible field net/minecraft/server/level/ChunkMap visibleChunkMap Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap; accessible field net/minecraft/server/level/ChunkMap pendingUnloads Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap; @@ -43,15 +42,10 @@ accessible class net/minecraft/client/resources/model/ModelBakery$BakedCacheKey accessible method net/minecraft/client/resources/model/ModelBakery$BakedCacheKey (Lnet/minecraft/resources/ResourceLocation;Lcom/mojang/math/Transformation;Z)V accessible class net/minecraft/client/resources/model/ModelBakery$ModelBakerImpl accessible method net/minecraft/client/resources/model/ModelBakery$ModelBakerImpl (Lnet/minecraft/client/resources/model/ModelBakery;Lnet/minecraft/client/resources/model/ModelBakery$TextureGetter;Lnet/minecraft/client/resources/model/ModelResourceLocation;)V -accessible method net/minecraft/client/resources/model/ModelBakery getModel (Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/client/resources/model/UnbakedModel; accessible class net/minecraft/world/level/chunk/PalettedContainer$Data accessible field net/minecraft/server/MinecraftServer resources Lnet/minecraft/server/MinecraftServer$ReloadableResources; accessible class net/minecraft/server/MinecraftServer$ReloadableResources accessible method net/minecraft/client/gui/screens/Screen addRenderableWidget (Lnet/minecraft/client/gui/components/events/GuiEventListener;)Lnet/minecraft/client/gui/components/events/GuiEventListener; accessible field net/minecraft/client/KeyMapping ALL Ljava/util/Map; -accessible field net/minecraft/client/renderer/block/model/multipart/MultiPart definition Lnet/minecraft/world/level/block/state/StateDefinition; -accessible field net/minecraft/client/renderer/block/model/ItemOverrides$BakedOverride model Lnet/minecraft/client/resources/model/BakedModel; -mutable field net/minecraft/client/renderer/block/model/ItemOverrides$BakedOverride model Lnet/minecraft/client/resources/model/BakedModel; -accessible field net/minecraft/client/renderer/entity/EnderDragonRenderer$DragonModel entity Lnet/minecraft/world/entity/boss/enderdragon/EnderDragon; accessible method net/minecraft/world/level/block/state/StateDefinition appendPropertyCodec (Lcom/mojang/serialization/MapCodec;Ljava/util/function/Supplier;Ljava/lang/String;Lnet/minecraft/world/level/block/state/properties/Property;)Lcom/mojang/serialization/MapCodec; accessible class net/minecraft/client/multiplayer/SessionSearchTrees$Key \ No newline at end of file