diff --git a/src/main/java/org/embeddedt/modernfix/ModernFixClient.java b/src/main/java/org/embeddedt/modernfix/ModernFixClient.java index 4270f094..06fc2635 100644 --- a/src/main/java/org/embeddedt/modernfix/ModernFixClient.java +++ b/src/main/java/org/embeddedt/modernfix/ModernFixClient.java @@ -27,14 +27,11 @@ import net.minecraftforge.fml.util.ObfuscationReflectionHelper; import net.minecraftforge.network.NetworkEvent; import org.embeddedt.modernfix.core.ModernFixMixinPlugin; import org.embeddedt.modernfix.core.config.ModernFixConfig; -import org.embeddedt.modernfix.load.LoadEvents; import org.embeddedt.modernfix.packet.EntityIDSyncPacket; -import org.embeddedt.modernfix.screen.DeferredLevelLoadingScreen; import org.embeddedt.modernfix.world.IntegratedWatchdog; import java.lang.management.ManagementFactory; import java.lang.reflect.Field; -import java.sql.Ref; import java.util.*; import java.util.function.Supplier; @@ -51,9 +48,6 @@ public class ModernFixClient { public ModernFixClient() { // clear reserve as it's not needed MemoryReserve.release(); - if(ModernFixMixinPlugin.instance.isOptionEnabled("perf.faster_singleplayer_load.ClientEvents")) { - MinecraftForge.EVENT_BUS.register(new LoadEvents()); - } if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.branding.F3Screen")) { Optional mfContainer = ModList.get().getModContainerById("modernfix"); if(mfContainer.isPresent()) @@ -93,7 +87,6 @@ public class ModernFixClient { if(event.phase == TickEvent.Phase.END && recipesUpdated && tagsUpdated - && !(Minecraft.getInstance().screen instanceof DeferredLevelLoadingScreen) && worldLoadStartTime != -1 && Minecraft.getInstance().player != null && numRenderTicks++ >= 10) { diff --git a/src/main/java/org/embeddedt/modernfix/agent/Agent.java b/src/main/java/org/embeddedt/modernfix/agent/Agent.java deleted file mode 100644 index 5cf5298d..00000000 --- a/src/main/java/org/embeddedt/modernfix/agent/Agent.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.embeddedt.modernfix.agent; - -import com.google.common.collect.ImmutableMap; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.tree.*; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.IllegalClassFormatException; -import java.lang.instrument.Instrumentation; -import java.security.ProtectionDomain; -import java.util.function.Function; - -public class Agent { - public static void agentmain(String args, Instrumentation instrumentation) { - instrumentation.addTransformer(new EarlyTransformer()); - } - - private static class EarlyTransformer implements ClassFileTransformer { - - private static final ImmutableMap> TRANSFORMERS = ImmutableMap.>builder() - .put("net/minecraftforge/fml/loading/moddiscovery/Scanner", EarlyTransformer::transformScanner) - .build(); - - private static ClassNode transformScanner(ClassNode input) { - for(MethodNode method : input.methods) { - if(method.name.equals("fileVisitor")) { - for(int i = 0; i < method.instructions.size(); i++) { - AbstractInsnNode ainsn = method.instructions.get(i); - if(ainsn.getOpcode() == Opcodes.INVOKEVIRTUAL) { - MethodInsnNode minsn = (MethodInsnNode)ainsn; - if(minsn.name.equals("accept") && minsn.owner.equals("org/objectweb/asm/ClassReader")) { - method.instructions.set(minsn.getPrevious(), new LdcInsnNode(ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES)); - return input; - } - } - } - } - } - return input; - } - - @Override - public byte[] transform(ClassLoader classLoader, String s, Class aClass, ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException { - Function func = TRANSFORMERS.get(s); - if(func != null) { - ClassReader reader = new ClassReader(bytes); - ClassNode node = new ClassNode(Opcodes.ASM9); - reader.accept(node, 0); - node = func.apply(node); - ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - node.accept(writer); - return writer.toByteArray(); - } else - return bytes; - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index 7afb9339..d5d339b3 100644 --- a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -59,7 +59,6 @@ public class ModernFixEarlyConfig { /* Keep this off if JEI/REI isn't installed to prevent breaking vanilla gameplay */ this.addMixinRule("perf.blast_search_trees", FMLLoader.getLoadingModList().getModFileById("jei") != null || FMLLoader.getLoadingModList().getModFileById("roughlyenoughitems") != null); this.addMixinRule("safety", true); - this.addMixinRule("launch.transformer_cache", false); this.addMixinRule("launch.class_search_cache", true); boolean isDevEnv = !FMLLoader.isProduction() && FMLLoader.getLoadingModList().getModFileById("modernfix").getFile().getProvider() instanceof ExplodedDirectoryLocator; this.addMixinRule("devenv", isDevEnv); diff --git a/src/main/java/org/embeddedt/modernfix/load/LoadEvents.java b/src/main/java/org/embeddedt/modernfix/load/LoadEvents.java deleted file mode 100644 index 7c4484e4..00000000 --- a/src/main/java/org/embeddedt/modernfix/load/LoadEvents.java +++ /dev/null @@ -1,113 +0,0 @@ -package org.embeddedt.modernfix.load; - -import it.unimi.dsi.fastutil.longs.LongIterator; -import net.minecraft.Util; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screens.LevelLoadingScreen; -import net.minecraft.client.gui.screens.ProgressScreen; -import net.minecraft.client.server.IntegratedServer; -import net.minecraft.network.chat.Component; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.TicketType; -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.util.Unit; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.ForcedChunksSavedData; -import net.minecraftforge.client.event.ScreenEvent; -import net.minecraftforge.common.world.ForgeChunkManager; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.event.server.ServerAboutToStartEvent; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.server.ServerLifecycleHooks; -import org.embeddedt.modernfix.core.ModernFixMixinPlugin; -import org.embeddedt.modernfix.screen.DeferredLevelLoadingScreen; - -import java.util.concurrent.locks.LockSupport; -import java.util.function.BooleanSupplier; - -/** - * Handles deferring the world load screen. - *

- * TODO: The vanilla check that at least 441 chunks have been loaded does not check whether they are spawn chunks - * or chunks loaded by the player. Consequently it is possible for loading to finish before every spawn chunk has - * been loaded. However the chunk system has at least been warmed up by this point so the remaining chunks load - * reasonably quickly. - */ -public class LoadEvents { - private boolean hasFirstPlayerJoined = false; - - @SubscribeEvent - public void serverWillStart(ServerAboutToStartEvent event) { - hasFirstPlayerJoined = false; - } - - @SubscribeEvent(priority = EventPriority.LOWEST) - public void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) { - if(!hasFirstPlayerJoined && ModernFixMixinPlugin.instance.isOptionEnabled("perf.faster_singleplayer_load.ClientEvents")) { - hasFirstPlayerJoined = true; - MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); - if(server instanceof IntegratedServer) { - handleInitialChunkLoad(); - } - } - } - - @SubscribeEvent(priority = EventPriority.LOWEST) - public void onWorldShow(ScreenEvent.Opening event) { - if(ServerLifecycleHooks.getCurrentServer() instanceof IntegratedServer) { - if(event.getNewScreen() == null && Minecraft.getInstance().level != null && integratedWorldLoadListener != null) { - /* this means the world is about to be displayed, check if 441 initialized */ - ServerChunkCache provider = ServerLifecycleHooks.getCurrentServer().overworld().getChunkSource(); - BooleanSupplier worldLoadDone = () -> provider.getTickingGenerated() >= 441; - if(!worldLoadDone.getAsBoolean()) { - DeferredLevelLoadingScreen newScreen = new DeferredLevelLoadingScreen(Minecraft.getInstance().progressListener.get(), worldLoadDone); - event.setNewScreen(newScreen); - } - } else if(event.getNewScreen() instanceof LevelLoadingScreen && Minecraft.getInstance().level == null && ModernFixMixinPlugin.instance.isOptionEnabled("perf.faster_singleplayer_load.ClientEvents")) { - ProgressScreen loadscreen = new ProgressScreen(false); - loadscreen.progressStartNoAbort(Component.translatable("connect.joining")); - event.setNewScreen(loadscreen); - } - } - } - - public static ChunkProgressListener integratedWorldLoadListener; - - private void handleInitialChunkLoad() { - MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); - ServerLevel overworld = server.overworld(); - ServerChunkCache provider = overworld.getChunkSource(); - provider.getLightEngine().setTaskPerBatch(500); - provider.addRegionTicket(TicketType.START, new ChunkPos(overworld.getSharedSpawnPos()), 11, Unit.INSTANCE); - while(provider.getTickingGenerated() < 441) { - server.runAllTasks(); - Thread.yield(); - LockSupport.parkNanos("waiting for world load", 100000L); - server.nextTickTime = Util.getMillis() + 10; - } - for(ServerLevel serverworld1 : server.getAllLevels()) { - ForcedChunksSavedData forcedchunkssavedata = serverworld1.getDataStorage().get(ForcedChunksSavedData::load, "chunks"); - if (forcedchunkssavedata != null) { - LongIterator longiterator = forcedchunkssavedata.getChunks().iterator(); - - while(longiterator.hasNext()) { - long i = longiterator.nextLong(); - ChunkPos chunkpos = new ChunkPos(i); - serverworld1.getChunkSource().updateChunkForced(chunkpos, true); - } - - ForgeChunkManager.reinstatePersistentChunks(serverworld1, forcedchunkssavedata); - } - } - server.runAllTasks(); - server.nextTickTime = Util.getMillis() + 10; - provider.getLightEngine().setTaskPerBatch(5); - if(integratedWorldLoadListener != null) { - integratedWorldLoadListener.stop(); - integratedWorldLoadListener = null; - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_singleplayer_load/MinecraftServerMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_singleplayer_load/MinecraftServerMixin.java deleted file mode 100644 index ad0b11a0..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_singleplayer_load/MinecraftServerMixin.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.faster_singleplayer_load; - -import net.minecraft.Util; -import net.minecraft.client.server.IntegratedServer; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.progress.ChunkProgressListener; -import org.embeddedt.modernfix.ModernFixClient; -import org.embeddedt.modernfix.load.LoadEvents; -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; - -@Mixin(MinecraftServer.class) -public abstract class MinecraftServerMixin { - @Shadow protected long nextTickTime; - - @Shadow public abstract ServerLevel overworld(); - - @Shadow protected abstract void updateMobSpawningFlags(); - - /** - * @author embeddedt - * @reason defer the 441 chunk load until *after* join game packets are sent to the client, in order to allow - * mods that process advancements, etc. to work on that at the same time - */ - @Inject(method = "prepareLevels", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;getChunkSource()Lnet/minecraft/server/level/ServerChunkCache;", ordinal = 0), cancellable = true) - private void skipInitialChunkLoad(ChunkProgressListener arg, CallbackInfo ci) { - if(((Object)this) instanceof IntegratedServer) { - ci.cancel(); - LoadEvents.integratedWorldLoadListener = arg; - this.nextTickTime = Util.getMillis(); - this.overworld().getChunkSource().getLightEngine().setTaskPerBatch(5); - this.updateMobSpawningFlags(); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/flatten_model_predicates/AndConditionMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/flatten_model_predicates/AndConditionMixin.java deleted file mode 100644 index 94283f0a..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/flatten_model_predicates/AndConditionMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.flatten_model_predicates; - -import com.google.common.collect.Streams; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.client.renderer.block.model.multipart.AndCondition; -import net.minecraft.client.renderer.block.model.multipart.Condition; -import net.minecraft.world.level.block.state.StateDefinition; -import org.embeddedt.modernfix.predicate.StatePropertyPredicateHelper; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; - -import java.util.function.Predicate; -import java.util.stream.Collectors; - -@Mixin(AndCondition.class) -public class AndConditionMixin { - @Shadow @Final private Iterable conditions; - - /** - * @author JellySquid - * @reason Flatten predicates - */ - @Overwrite - public Predicate getPredicate(StateDefinition stateManager) { - return StatePropertyPredicateHelper.allMatch(Streams.stream(this.conditions).map((multipartModelSelector) -> { - return multipartModelSelector.getPredicate(stateManager); - }).collect(Collectors.toList())); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/flatten_model_predicates/OrConditionMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/flatten_model_predicates/OrConditionMixin.java deleted file mode 100644 index f336a997..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/flatten_model_predicates/OrConditionMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.flatten_model_predicates; - -import com.google.common.collect.Streams; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.client.renderer.block.model.multipart.Condition; -import net.minecraft.client.renderer.block.model.multipart.OrCondition; -import net.minecraft.world.level.block.state.StateDefinition; -import org.embeddedt.modernfix.predicate.StatePropertyPredicateHelper; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; - -import java.util.function.Predicate; -import java.util.stream.Collectors; - -@Mixin(OrCondition.class) -public class OrConditionMixin { - @Shadow @Final private Iterable conditions; - - /** - * @author JellySquid - * @reason Flatten predicates - */ - @Overwrite - public Predicate getPredicate(StateDefinition stateManager) { - return StatePropertyPredicateHelper.anyMatch(Streams.stream(this.conditions).map((multipartModelSelector) -> { - return multipartModelSelector.getPredicate(stateManager); - }).collect(Collectors.toList())); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/flatten_model_predicates/PropertyValueConditionMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/flatten_model_predicates/PropertyValueConditionMixin.java deleted file mode 100644 index 80c8991d..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/flatten_model_predicates/PropertyValueConditionMixin.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.flatten_model_predicates; - -import com.google.common.base.Splitter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.client.renderer.block.model.multipart.KeyValueCondition; -import net.minecraft.world.level.block.state.properties.Property; -import net.minecraft.world.level.block.state.StateDefinition; -import org.embeddedt.modernfix.predicate.single.SingleMatchAny; -import org.embeddedt.modernfix.predicate.single.SingleMatchOne; -import org.spongepowered.asm.mixin.Final; -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.Predicate; -import java.util.stream.Collectors; - -@Mixin(KeyValueCondition.class) -public class PropertyValueConditionMixin { - @Shadow @Final private String key; - - @Shadow @Final private String value; - - @Shadow @Final private static Splitter PIPE_SPLITTER; - - /** - * @author JellySquid - * @reason De-duplication - */ - @Overwrite - public Predicate getPredicate(StateDefinition stateManager) { - Property property = stateManager.getProperty(this.key); - - if (property == null) { - throw new RuntimeException(String.format("Unknown property '%s' on '%s'", this.key, stateManager.getOwner().toString())); - } - - String valueString = this.value; - boolean negate = !valueString.isEmpty() && valueString.charAt(0) == '!'; - - if (negate) { - valueString = valueString.substring(1); - } - - List split = PIPE_SPLITTER.splitToList(valueString); - - if (split.isEmpty()) { - throw new RuntimeException(String.format("Empty value '%s' for property '%s' on '%s'", this.value, this.key, stateManager.getOwner().toString())); - } - - Predicate predicate; - - if (split.size() == 1) { - predicate = new SingleMatchOne(property, this.getPropertyValue(stateManager, property, valueString)); - } else { - predicate = SingleMatchAny.create(property, split.stream() - .map(str -> this.getPropertyValue(stateManager, property, str)) - .collect(Collectors.toList())); - } - - return negate ? predicate.negate() : predicate; - } - - private Object getPropertyValue(StateDefinition stateFactory, Property property, String valueString) { - Object value = property.getValue(valueString) - .orElse(null); - - if (value == null) { - throw new RuntimeException(String.format("Unknown value '%s' for property '%s' on '%s' in '%s'", - valueString, this.key, stateFactory.getOwner().toString(), this.value)); - } - - return value; - } -} diff --git a/src/main/java/org/embeddedt/modernfix/predicate/AllPredicate.java b/src/main/java/org/embeddedt/modernfix/predicate/AllPredicate.java deleted file mode 100644 index e741e58a..00000000 --- a/src/main/java/org/embeddedt/modernfix/predicate/AllPredicate.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.embeddedt.modernfix.predicate; - -import java.util.function.Predicate; - -public class AllPredicate implements Predicate { - private final Predicate[] predicates; - - public AllPredicate(Predicate[] predicates) { - this.predicates = predicates; - } - - @Override - public boolean test(T t) { - for (Predicate predicate : this.predicates) { - if (!predicate.test(t)) { - return false; - } - } - - return true; - } -} diff --git a/src/main/java/org/embeddedt/modernfix/predicate/AnyPredicate.java b/src/main/java/org/embeddedt/modernfix/predicate/AnyPredicate.java deleted file mode 100644 index 7c04f5fb..00000000 --- a/src/main/java/org/embeddedt/modernfix/predicate/AnyPredicate.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.embeddedt.modernfix.predicate; - -import java.util.function.Predicate; - -public class AnyPredicate implements Predicate { - private final Predicate[] predicates; - - public AnyPredicate(Predicate[] predicates) { - this.predicates = predicates; - } - - @Override - public boolean test(T t) { - for (Predicate predicate : this.predicates) { - if (predicate.test(t)) { - return true; - } - } - - return false; - } -} diff --git a/src/main/java/org/embeddedt/modernfix/predicate/CachedModelPredicate.java b/src/main/java/org/embeddedt/modernfix/predicate/CachedModelPredicate.java deleted file mode 100644 index 8c5a4566..00000000 --- a/src/main/java/org/embeddedt/modernfix/predicate/CachedModelPredicate.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.embeddedt.modernfix.predicate; - -/** - * Calculates the - */ -public class CachedModelPredicate { -} diff --git a/src/main/java/org/embeddedt/modernfix/predicate/StatePropertyPredicateHelper.java b/src/main/java/org/embeddedt/modernfix/predicate/StatePropertyPredicateHelper.java deleted file mode 100644 index 8125e307..00000000 --- a/src/main/java/org/embeddedt/modernfix/predicate/StatePropertyPredicateHelper.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.embeddedt.modernfix.predicate; - -import net.minecraft.world.level.block.state.BlockState; -import org.embeddedt.modernfix.predicate.all.AllMatchOneBoolean; -import org.embeddedt.modernfix.predicate.all.AllMatchOneObject; -import org.embeddedt.modernfix.predicate.any.AllMatchAnyObject; -import org.embeddedt.modernfix.predicate.single.SingleMatchAny; -import org.embeddedt.modernfix.predicate.single.SingleMatchOne; - -import java.util.List; -import java.util.function.Predicate; - -public class StatePropertyPredicateHelper { - @SuppressWarnings("unchecked") - public static Predicate allMatch(List> predicates) { - if (SingleMatchOne.areOfType(predicates)) { - if (SingleMatchOne.valuesMatchType(predicates, Boolean.class)) { - return new AllMatchOneBoolean(predicates); - } - - return new AllMatchOneObject(predicates); - } else if (SingleMatchAny.areOfType(predicates)) { - return new AllMatchAnyObject(predicates); - } - - return new AllPredicate<>(predicates.toArray(new Predicate[0])); - } - - @SuppressWarnings("unchecked") - public static Predicate anyMatch(List> predicates) { - return new AnyPredicate<>(predicates.toArray(new Predicate[0])); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/predicate/all/AllMatchOneBoolean.java b/src/main/java/org/embeddedt/modernfix/predicate/all/AllMatchOneBoolean.java deleted file mode 100644 index 06984eb1..00000000 --- a/src/main/java/org/embeddedt/modernfix/predicate/all/AllMatchOneBoolean.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.embeddedt.modernfix.predicate.all; - -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.Property; -import org.embeddedt.modernfix.predicate.single.SingleMatchOne; - -import java.util.List; -import java.util.function.Predicate; - -public class AllMatchOneBoolean implements Predicate { - private final Property[] properties; - private final boolean[] values; - - public AllMatchOneBoolean(List> list) { - int size = list.size(); - - this.properties = new Property[size]; - this.values = new boolean[size]; - - for (int i = 0; i < size; i++) { - SingleMatchOne predicate = (SingleMatchOne) list.get(i); - - this.properties[i] = predicate.property; - this.values[i] = (boolean) predicate.value; - } - } - - public static boolean canReplace(List> list) { - return list.stream() - .allMatch(p -> { - return p instanceof SingleMatchOne && ((SingleMatchOne) p).value instanceof Boolean; - }); - } - - @Override - public boolean test(BlockState blockState) { - for (int i = 0; i < this.properties.length; i++) { - Boolean value = (Boolean) blockState.getValue(this.properties[i]); - - if (value != this.values[i]) { - return false; - } - } - - return true; - } -} diff --git a/src/main/java/org/embeddedt/modernfix/predicate/all/AllMatchOneObject.java b/src/main/java/org/embeddedt/modernfix/predicate/all/AllMatchOneObject.java deleted file mode 100644 index 5a90591b..00000000 --- a/src/main/java/org/embeddedt/modernfix/predicate/all/AllMatchOneObject.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.embeddedt.modernfix.predicate.all; - -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.Property; -import org.embeddedt.modernfix.predicate.single.SingleMatchOne; - -import java.util.List; -import java.util.function.Predicate; - -public class AllMatchOneObject implements Predicate { - private final Property[] properties; - private final Object[] values; - - public AllMatchOneObject(List> list) { - int size = list.size(); - - this.properties = new Property[size]; - this.values = new Object[size]; - - for (int i = 0; i < size; i++) { - SingleMatchOne predicate = (SingleMatchOne) list.get(i); - - this.properties[i] = predicate.property; - this.values[i] = predicate.value; - } - } - - @Override - public boolean test(BlockState blockState) { - for (int i = 0; i < this.properties.length; i++) { - if (blockState.getValue(this.properties[i]) != this.values[i]) { - return false; - } - } - - return true; - } -} diff --git a/src/main/java/org/embeddedt/modernfix/predicate/any/AllMatchAnyObject.java b/src/main/java/org/embeddedt/modernfix/predicate/any/AllMatchAnyObject.java deleted file mode 100644 index f9585376..00000000 --- a/src/main/java/org/embeddedt/modernfix/predicate/any/AllMatchAnyObject.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.embeddedt.modernfix.predicate.any; - -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.Property; -import org.apache.commons.lang3.ArrayUtils; -import org.embeddedt.modernfix.predicate.single.SingleMatchAny; - -import java.util.List; -import java.util.function.Predicate; - -public class AllMatchAnyObject implements Predicate { - private final Property[] properties; - private final Object[][] values; - - public AllMatchAnyObject(List> list) { - int size = list.size(); - - this.properties = new Property[size]; - this.values = new Object[size][]; - - for (int i = 0; i < size; i++) { - SingleMatchAny predicate = (SingleMatchAny) list.get(i); - - this.properties[i] = predicate.property; - this.values[i] = predicate.values; - } - } - - @Override - public boolean test(BlockState blockState) { - for (int i = 0; i < this.properties.length; i++) { - if (!ArrayUtils.contains(this.values[i], blockState.getValue(this.properties[i]))) { - return false; - } - } - - return true; - } -} diff --git a/src/main/java/org/embeddedt/modernfix/predicate/single/SingleMatchAny.java b/src/main/java/org/embeddedt/modernfix/predicate/single/SingleMatchAny.java deleted file mode 100644 index 1c7906e9..00000000 --- a/src/main/java/org/embeddedt/modernfix/predicate/single/SingleMatchAny.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.embeddedt.modernfix.predicate.single; - -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.Property; -import org.apache.commons.lang3.ArrayUtils; - -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.function.Predicate; - -public class SingleMatchAny implements Predicate { - public static final ObjectOpenHashSet PREDICATES = new ObjectOpenHashSet<>(); - - public final Property property; - public final Object[] values; - - private SingleMatchAny(Property property, List values) { - this.property = property; - this.values = values.toArray(); - } - - public static SingleMatchAny create(Property property, List values) { - return PREDICATES.addOrGet(new SingleMatchAny(property, values)); - } - - public static boolean areOfType(List> predicates) { - return predicates.stream() - .allMatch(p -> { - return p instanceof SingleMatchAny; - }); - } - - public static boolean valuesMatchType(List> predicates, Class type) { - return predicates.stream() - .allMatch(p -> { - return p instanceof SingleMatchAny && - Arrays.stream(((SingleMatchAny) p).values).allMatch(t -> type.isInstance(p)); - }); - } - - @Override - public boolean test(BlockState blockState) { - return ArrayUtils.contains(this.values, blockState.getValue(this.property)); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - SingleMatchAny that = (SingleMatchAny) o; - return Objects.equals(property, that.property) && - Arrays.equals(values, that.values); - } - - @Override - public int hashCode() { - int result = Objects.hash(property); - result = 31 * result + Arrays.hashCode(values); - return result; - } -} diff --git a/src/main/java/org/embeddedt/modernfix/predicate/single/SingleMatchOne.java b/src/main/java/org/embeddedt/modernfix/predicate/single/SingleMatchOne.java deleted file mode 100644 index e44e0515..00000000 --- a/src/main/java/org/embeddedt/modernfix/predicate/single/SingleMatchOne.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.embeddedt.modernfix.predicate.single; - -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.Property; - -import java.util.List; -import java.util.function.Predicate; - -public class SingleMatchOne implements Predicate { - public final Property property; - public final Object value; - - public SingleMatchOne(Property property, Object value) { - this.property = property; - this.value = value; - } - - public static boolean areOfType(List> predicates) { - return predicates.stream() - .allMatch(p -> { - return p instanceof SingleMatchOne; - }); - } - - public static boolean valuesMatchType(List> predicates, Class type) { - return predicates.stream() - .allMatch(p -> { - return p instanceof SingleMatchOne && type.isInstance(((SingleMatchOne) p).value); - }); - } - - @Override - public boolean test(BlockState blockState) { - return blockState.getValue(this.property) == this.value; - } -} diff --git a/src/main/java/org/embeddedt/modernfix/registry/DeferredRegisterBaker.java b/src/main/java/org/embeddedt/modernfix/registry/DeferredRegisterBaker.java deleted file mode 100644 index be78ace2..00000000 --- a/src/main/java/org/embeddedt/modernfix/registry/DeferredRegisterBaker.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.embeddedt.modernfix.registry; - -import com.google.common.base.Stopwatch; -import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.fml.ModWorkManager; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.util.AsyncStopwatch; -import org.embeddedt.modernfix.util.CachedSupplier; -import org.embeddedt.modernfix.util.OrderedParallelModDispatcher; - -import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.function.Supplier; - -public class DeferredRegisterBaker { - private static final HashMap>>> supplierMap = new HashMap<>(); - public static Supplier cacheForComputationLater(ResourceLocation registry, String modid, Supplier supplier) { - synchronized (supplierMap) { - HashMap>> registrySupplierMap = supplierMap.computeIfAbsent(registry, reg -> new HashMap<>()); - List> modSupplierList = registrySupplierMap.computeIfAbsent(modid, id -> new ArrayList<>()); - CachedSupplier cacher = new CachedSupplier<>(supplier); - modSupplierList.add(cacher); - return cacher; - } - } - - public static void bakeSuppliers(ResourceLocation registry) { - synchronized (supplierMap) { - Set modErrors = Collections.synchronizedSet(new HashSet<>()); - HashMap>> registrySupplierMap = supplierMap.get(registry); - if(registrySupplierMap == null) - return; - ModernFix.LOGGER.info("Caching suppliers for " + registry); - Stopwatch realtimeStopwatch = Stopwatch.createStarted(); - AsyncStopwatch cpuStopwatch = new AsyncStopwatch(); - OrderedParallelModDispatcher.dispatchBlocking(ModWorkManager.parallelExecutor(), modId -> { - List> suppliersToCompute = registrySupplierMap.get(modId); - if (suppliersToCompute == null || suppliersToCompute.size() == 0) { - return; - } - cpuStopwatch.startMeasuringAsync(); - for (CachedSupplier supplier : suppliersToCompute) { - try { - supplier.compute(); - } catch(RuntimeException e) { - ModernFix.LOGGER.debug("Exception encountered while caching supplier", e); - modErrors.add(modId); - } - } - cpuStopwatch.stopMeasuringAsync(); - }); - realtimeStopwatch.stop(); - if(modErrors.size() > 0) - ModernFix.LOGGER.warn("The following mods had errors while caching " + registry + " suppliers (this is likely safe): [" + String.join(", ", modErrors) + "]"); - ModernFix.LOGGER.info("CPU time spent constructing " + registry + " suppliers: " + cpuStopwatch.getCpuTime()/1000f + " seconds"); - ModernFix.LOGGER.info("Real time spent constructing " + registry + " suppliers: " + realtimeStopwatch.elapsed(TimeUnit.MILLISECONDS)/1000f + " seconds"); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/screen/DeferredLevelLoadingScreen.java b/src/main/java/org/embeddedt/modernfix/screen/DeferredLevelLoadingScreen.java deleted file mode 100644 index cd49687a..00000000 --- a/src/main/java/org/embeddedt/modernfix/screen/DeferredLevelLoadingScreen.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.embeddedt.modernfix.screen; - -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.gui.screens.LevelLoadingScreen; -import net.minecraft.server.level.progress.StoringChunkProgressListener; - -import java.util.function.BooleanSupplier; - -public class DeferredLevelLoadingScreen extends LevelLoadingScreen { - private final BooleanSupplier worldLoadFinished; - public DeferredLevelLoadingScreen(StoringChunkProgressListener arg, BooleanSupplier worldLoadFinished) { - super(arg); - this.worldLoadFinished = worldLoadFinished; - } - - @Override - public void tick() { - super.tick(); - if(this.worldLoadFinished.getAsBoolean()) - this.onClose(); - } - - @Override - public void renderBackground(PoseStack matrixStack, int vOffset) { - renderDirtBackground(vOffset); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/util/AsyncStopwatch.java b/src/main/java/org/embeddedt/modernfix/util/AsyncStopwatch.java deleted file mode 100644 index a45db852..00000000 --- a/src/main/java/org/embeddedt/modernfix/util/AsyncStopwatch.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.embeddedt.modernfix.util; - -import com.google.common.base.Stopwatch; -import org.embeddedt.modernfix.ModernFix; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; - -public class AsyncStopwatch { - private final AtomicLong cpuTimeMs = new AtomicLong(0); - private final ThreadLocal threadStopwatch = ThreadLocal.withInitial(Stopwatch::createUnstarted); - - public void startMeasuringAsync() { - threadStopwatch.get().start(); - } - - public void stopMeasuringAsync() { - Stopwatch watch = threadStopwatch.get(); - watch.stop(); - long elapsed = watch.elapsed(TimeUnit.MILLISECONDS); - cpuTimeMs.addAndGet(elapsed); - watch.reset(); - } - - public void ensureStoppedAsync() { - Stopwatch watch = threadStopwatch.get(); - if(watch.isRunning()) - stopMeasuringAsync(); - } - - public long getCpuTime() { - return cpuTimeMs.get(); - } - - public static void measureAndLogSerialRunningTime(String label, Runnable runnable) { - ModernFix.LOGGER.info(label + "..."); - Stopwatch stopwatch = Stopwatch.createStarted(); - try { - runnable.run(); - ModernFix.LOGGER.info(label + " took " + stopwatch.elapsed(TimeUnit.MILLISECONDS)/1000f + " seconds"); - } finally { - stopwatch.stop(); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/util/CachedSupplier.java b/src/main/java/org/embeddedt/modernfix/util/CachedSupplier.java deleted file mode 100644 index 50b2303d..00000000 --- a/src/main/java/org/embeddedt/modernfix/util/CachedSupplier.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.embeddedt.modernfix.util; - -import java.util.function.Supplier; - -/** - * An implementation of Supplier that allows separating the time at which the value is computed from when it is - * retrieved. - */ -public class CachedSupplier implements Supplier { - private T value = null; - - private boolean hasBeenComputed; - private final Supplier delegate; - - public CachedSupplier(Supplier delegate) { - this.delegate = delegate; - } - - public synchronized void compute() { - this.value = this.delegate.get(); - this.hasBeenComputed = true; - } - - @Override - public synchronized T get() { - if(this.hasBeenComputed) { - this.hasBeenComputed = false; - return this.value; - } else { - return this.delegate.get(); - } - } -} diff --git a/src/main/java/org/embeddedt/modernfix/util/OrderedParallelModDispatcher.java b/src/main/java/org/embeddedt/modernfix/util/OrderedParallelModDispatcher.java deleted file mode 100644 index 9c53ac86..00000000 --- a/src/main/java/org/embeddedt/modernfix/util/OrderedParallelModDispatcher.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.embeddedt.modernfix.util; - -import com.google.common.base.Preconditions; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.loading.moddiscovery.ModInfo; -import net.minecraftforge.fml.util.ObfuscationReflectionHelper; -import net.minecraftforge.forgespi.language.IModInfo; -import org.apache.logging.log4j.Marker; -import org.apache.logging.log4j.MarkerManager; -import org.embeddedt.modernfix.ModernFix; - -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.concurrent.Semaphore; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -/** - * Iterates over all mods in the game, parallelizing where possible while preserving dependency ordering. - * - * Can also be given a list of mods to skip. - */ -public class OrderedParallelModDispatcher { - private static final Marker DISPATCHER = MarkerManager.getMarker("OrderedParallelModDispatcher"); - public static void dispatchBlocking(Executor executor, Consumer task, Collection modIDsToFilter) { - Set finishedMods = Collections.synchronizedSet(new HashSet<>(modIDsToFilter)); - HashMap> submittedFutures = new HashMap<>(); - Semaphore jobWaitingSemaphore = new Semaphore(0); - ArrayList remainingModList = new ArrayList<>(ModList.get().getMods()); - while(remainingModList.size() > 0) { - remainingModList.removeIf(modInfo -> { - if(finishedMods.contains(modInfo.getModId())) - return true; - List missingDependencies = modInfo.getDependencies().stream() - .filter(IModInfo.ModVersion::isMandatory) - .map(IModInfo.ModVersion::getModId) - .filter(modId -> !finishedMods.contains(modId)) - .collect(Collectors.toList()); - if(missingDependencies.size() > 0) { - ModernFix.LOGGER.debug(DISPATCHER, "Cannot process " + modInfo.getModId() + ", as it is waiting on mods: [" + String.join(", ", missingDependencies) + "]"); - return false; - } - Optional modContainerOpt = ModList.get().getModContainerById(modInfo.getModId()); - if(!modContainerOpt.isPresent()) - throw new IllegalStateException("Can't find mod container"); - ModContainer container = modContainerOpt.get(); - ModernFix.LOGGER.debug(DISPATCHER, "Submitting job for " + modInfo.getModId()); - submittedFutures.put(modInfo.getModId(), CompletableFuture.runAsync(() -> { - ModLoadingContext.get().setActiveContainer(container); - try { - task.accept(modInfo.getModId()); - } catch(RuntimeException e) { - e.printStackTrace(); - } - /* - * We cannot rely on the main thread to correctly mark us as done, as it might start running - * before the future is marked as complete. So we add the mod to the finished set ourselves. - */ - finishedMods.add(modInfo.getModId()); - jobWaitingSemaphore.release(); - //ModLoadingContext.get().setActiveContainer(null, null); - }, executor)); - return true; - }); - Preconditions.checkState(submittedFutures.size() > 0, "The semaphore will block forever!"); - ModernFix.LOGGER.debug(DISPATCHER, "Waiting for one of [" + String.join(", ", submittedFutures.keySet()) + "] to finish..."); - try { - jobWaitingSemaphore.acquire(); - } catch(InterruptedException e) { - throw new RuntimeException("Unexpected interruption", e); - } - submittedFutures.entrySet().removeIf(entry -> { - if(entry.getValue().isDone()) { - ModernFix.LOGGER.debug(DISPATCHER, "Job finished for " + entry.getKey()); - return true; - } - return false; - }); - } - submittedFutures.values().forEach(CompletableFuture::join); - } - - public static void dispatchBlocking(Executor executor, Consumer task) { - dispatchBlocking(executor, task, Collections.emptyList()); - } -} diff --git a/src/main/resources/modernfix.mixins.json b/src/main/resources/modernfix.mixins.json index dd387d7f..a820332f 100644 --- a/src/main/resources/modernfix.mixins.json +++ b/src/main/resources/modernfix.mixins.json @@ -64,9 +64,6 @@ "perf.thread_priorities.IntegratedServerMixin", "safety.BlockColorsMixin", "safety.ItemColorsMixin", - "perf.flatten_model_predicates.AndConditionMixin", - "perf.flatten_model_predicates.OrConditionMixin", - "perf.flatten_model_predicates.PropertyValueConditionMixin", "perf.blast_search_trees.MinecraftMixin", "perf.blast_search_trees.IngredientFilterInvoker", "perf.cache_model_materials.VanillaModelMixin", @@ -74,7 +71,6 @@ "perf.cache_model_materials.MultipartMixin", "perf.faster_texture_stitching.StitcherMixin", "perf.skip_first_datapack_reload.CreateWorldScreenMixin", - "perf.faster_singleplayer_load.MinecraftServerMixin", "devenv.MinecraftMixin", "devenv.NarratorMixin" ],