Add async JEI loading
This commit is contained in:
parent
21d559ab94
commit
41da489c85
21
build.gradle
21
build.gradle
|
|
@ -121,14 +121,16 @@ repositories {
|
|||
includeGroup "curse.maven"
|
||||
}
|
||||
}
|
||||
|
||||
// Put repositories for dependencies here
|
||||
// ForgeGradle automatically adds the Forge maven and Maven Central for you
|
||||
|
||||
// If you have mod jar dependencies in ./libs, you can declare them as a repository like so:
|
||||
// flatDir {
|
||||
// dir 'libs'
|
||||
// }
|
||||
maven {
|
||||
// location of the maven that hosts JEI files
|
||||
name = "Progwml6 maven"
|
||||
url = "https://dvs1.progwml6.com/files/maven/"
|
||||
}
|
||||
maven {
|
||||
// location of a maven mirror for JEI files, as a fallback
|
||||
name = "ModMaven"
|
||||
url = "https://modmaven.dev"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
@ -148,6 +150,9 @@ dependencies {
|
|||
runtimeOnly fg.deobf("mekanism:Mekanism:${mekanism_version}")// core
|
||||
runtimeOnly fg.deobf("mekanism:Mekanism:${mekanism_version}:generators")// Mekanism: Generators
|
||||
runtimeOnly fg.deobf("mekanism:Mekanism:${mekanism_version}:tools")// Mekanism: Tools
|
||||
|
||||
compileOnly fg.deobf("mezz.jei:jei-${minecraft_version}:${jei_version}")
|
||||
runtimeOnly fg.deobf("mezz.jei:jei-${minecraft_version}:${jei_version}")
|
||||
}
|
||||
|
||||
// Example for how to get properties into the manifest for reading at runtime.
|
||||
|
|
|
|||
|
|
@ -4,4 +4,5 @@ minecraft_version=1.16.5
|
|||
forge_version=36.2.39
|
||||
lazydfu_version=3249059
|
||||
mekanism_version=1.16.5-10.1.2.457
|
||||
parchment_version=2022.03.06
|
||||
parchment_version=2022.03.06
|
||||
jei_version=7.7.1.153
|
||||
|
|
@ -28,6 +28,7 @@ public class ModernFixConfig {
|
|||
this.addMixinRule("perf.trim_model_caches", true);
|
||||
this.addMixinRule("bugfix.concurrency", true);
|
||||
this.addMixinRule("bugfix.edge_chunk_not_saved", true);
|
||||
this.addMixinRule("perf.async_jei", true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
package org.embeddedt.modernfix.jei.async;
|
||||
|
||||
public interface IAsyncJeiStarter {
|
||||
static void checkForLoadInterruption() {
|
||||
if(Thread.currentThread().isInterrupted())
|
||||
throw new JEILoadingInterruptedException();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package org.embeddedt.modernfix.jei.async;
|
||||
|
||||
public class JEILoadingInterruptedException extends RuntimeException {
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.async_jei;
|
||||
|
||||
import mezz.jei.api.IModPlugin;
|
||||
import mezz.jei.api.helpers.IModIdHelper;
|
||||
import mezz.jei.config.*;
|
||||
import mezz.jei.config.sorting.RecipeCategorySortingConfig;
|
||||
import mezz.jei.events.EventBusHelper;
|
||||
import mezz.jei.events.PlayerJoinedWorldEvent;
|
||||
import mezz.jei.gui.textures.Textures;
|
||||
import mezz.jei.ingredients.IIngredientSorter;
|
||||
import mezz.jei.startup.ClientLifecycleHandler;
|
||||
import mezz.jei.startup.JeiStarter;
|
||||
import mezz.jei.startup.NetworkHandler;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.jei.async.JEILoadingInterruptedException;
|
||||
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 org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(ClientLifecycleHandler.class)
|
||||
public class ClientLifecycleHandlerMixin {
|
||||
@Shadow @Final private JeiStarter starter;
|
||||
@Shadow @Final private List<IModPlugin> plugins;
|
||||
@Shadow @Final private Textures textures;
|
||||
@Shadow @Final private IClientConfig clientConfig;
|
||||
@Shadow @Final private IEditModeConfig editModeConfig;
|
||||
@Shadow @Final private IngredientFilterConfig ingredientFilterConfig;
|
||||
@Shadow @Final private WorldConfig worldConfig;
|
||||
@Shadow @Final private BookmarkConfig bookmarkConfig;
|
||||
@Shadow @Final private IModIdHelper modIdHelper;
|
||||
@Shadow @Final private RecipeCategorySortingConfig recipeCategorySortingConfig;
|
||||
@Shadow @Final private IIngredientSorter ingredientSorter;
|
||||
private volatile Thread reloadThread = null;
|
||||
@Inject(method = "setupJEI", at = @At(value = "INVOKE", target = "Lmezz/jei/startup/ClientLifecycleHandler;startJEI()V"), cancellable = true, remap = false)
|
||||
private void startAsync(CallbackInfo ci) {
|
||||
ci.cancel();
|
||||
startJEIAsync(() -> Minecraft.getInstance().execute(() -> EventBusHelper.post(new PlayerJoinedWorldEvent())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @author embeddedt
|
||||
* @reason force JEI starts to be asynchronous
|
||||
*/
|
||||
@Overwrite(remap = false)
|
||||
public void startJEI() {
|
||||
startJEIAsync(() -> {});
|
||||
}
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void setupCancellationHandler(NetworkHandler networkHandler, Textures textures, CallbackInfo ci) {
|
||||
EventBusHelper.addListener(this, ClientPlayerNetworkEvent.LoggedOutEvent.class, event -> cancelPreviousStart());
|
||||
}
|
||||
|
||||
private void cancelPreviousStart() {
|
||||
Thread currentReloadThread = reloadThread;
|
||||
if(currentReloadThread != null) {
|
||||
currentReloadThread.interrupt();
|
||||
Minecraft.getInstance().managedBlock(currentReloadThread::isAlive);
|
||||
reloadThread = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void startJEIAsync(Runnable whenFinishedCb) {
|
||||
cancelPreviousStart();
|
||||
Thread newThread = new Thread(() -> {
|
||||
try {
|
||||
starter.start(
|
||||
plugins,
|
||||
textures,
|
||||
clientConfig,
|
||||
editModeConfig,
|
||||
ingredientFilterConfig,
|
||||
worldConfig,
|
||||
bookmarkConfig,
|
||||
modIdHelper,
|
||||
recipeCategorySortingConfig,
|
||||
ingredientSorter);
|
||||
} catch(JEILoadingInterruptedException e) {
|
||||
ModernFix.LOGGER.warn("JEI loading interrupted prematurely (this is normal)");
|
||||
}
|
||||
whenFinishedCb.run();
|
||||
reloadThread = null;
|
||||
}, "JEI Reload Thread");
|
||||
newThread.setPriority(Thread.MIN_PRIORITY);
|
||||
reloadThread = newThread;
|
||||
newThread.start();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.async_jei;
|
||||
|
||||
import mezz.jei.api.ingredients.IIngredientType;
|
||||
import mezz.jei.api.runtime.IIngredientManager;
|
||||
import mezz.jei.gui.ingredients.IIngredientListElement;
|
||||
import mezz.jei.ingredients.IngredientListElementFactory;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import org.embeddedt.modernfix.jei.async.IAsyncJeiStarter;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(IngredientListElementFactory.class)
|
||||
public class IngredientListElementFactoryMixin {
|
||||
@Inject(method = "addToBaseList", at = @At(value = "INVOKE", target = "Lmezz/jei/ingredients/IngredientOrderTracker;getOrderIndex(Ljava/lang/Object;Lmezz/jei/api/ingredients/IIngredientHelper;)I"), remap = false)
|
||||
private static void checkForInterrupt(NonNullList<IIngredientListElement<?>> baseList, IIngredientManager ingredientManager, IIngredientType ingredientType, CallbackInfo ci) {
|
||||
IAsyncJeiStarter.checkForLoadInterruption();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.async_jei;
|
||||
|
||||
import mezz.jei.api.IModPlugin;
|
||||
import mezz.jei.api.helpers.IModIdHelper;
|
||||
import mezz.jei.config.*;
|
||||
import mezz.jei.config.sorting.RecipeCategorySortingConfig;
|
||||
import mezz.jei.gui.textures.Textures;
|
||||
import mezz.jei.ingredients.IIngredientSorter;
|
||||
import mezz.jei.load.PluginCaller;
|
||||
import mezz.jei.startup.JeiStarter;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.embeddedt.modernfix.jei.async.IAsyncJeiStarter;
|
||||
import org.embeddedt.modernfix.jei.async.JEILoadingInterruptedException;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
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 org.spongepowered.asm.mixin.injection.callback.CancellationException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Mixin(JeiStarter.class)
|
||||
public class JeiStarterMixin {
|
||||
@Shadow private boolean started;
|
||||
|
||||
@Inject(method = "start", at = @At(value = "INVOKE", target = "Lmezz/jei/util/ErrorUtil;checkNotEmpty(Ljava/util/Collection;Ljava/lang/String;)V", ordinal = 0, shift = At.Shift.AFTER), remap = false)
|
||||
private void setStartedFlag(List<IModPlugin> plugins, Textures textures, IClientConfig clientConfig, IEditModeConfig editModeConfig, IIngredientFilterConfig ingredientFilterConfig, IWorldConfig worldConfig, BookmarkConfig bookmarkConfig, IModIdHelper modIdHelper, RecipeCategorySortingConfig recipeCategorySortingConfig, IIngredientSorter ingredientSorter, CallbackInfo ci) {
|
||||
/* We need to set this ASAP so the reload system will restart the async load if needed */
|
||||
started = true;
|
||||
}
|
||||
|
||||
@Redirect(method = "start", at = @At(value = "INVOKE", target = "Lmezz/jei/load/PluginCaller;callOnPlugins(Ljava/lang/String;Ljava/util/List;Ljava/util/function/Consumer;)V"), remap = false)
|
||||
private void callOnPluginsViaMainThread(String title, List<IModPlugin> plugins, Consumer<IModPlugin> func) {
|
||||
PluginCaller.callOnPlugins(title, plugins, plugin -> {
|
||||
try {
|
||||
Minecraft.getInstance().executeBlocking(() -> func.accept(plugin));
|
||||
} catch(CancellationException | CompletionException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.async_jei;
|
||||
|
||||
import mezz.jei.api.IModPlugin;
|
||||
import mezz.jei.load.PluginCaller;
|
||||
import org.embeddedt.modernfix.jei.async.IAsyncJeiStarter;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
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.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Mixin(PluginCaller.class)
|
||||
public class PluginCallerMixin {
|
||||
@Inject(method = "callOnPlugins", at = @At(value = "INVOKE", target = "Ljava/util/Iterator;hasNext()Z"), remap = false)
|
||||
private static void checkForInterrupt(String title, List<IModPlugin> plugins, Consumer<IModPlugin> func, CallbackInfo ci) {
|
||||
IAsyncJeiStarter.checkForLoadInterruption();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.async_jei;
|
||||
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import mezz.jei.recipes.RecipeManagerInternal;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.embeddedt.modernfix.jei.async.IAsyncJeiStarter;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(RecipeManagerInternal.class)
|
||||
public class RecipeManagerInternalMixin {
|
||||
@Inject(method = "addRecipes", at = @At(value = "INVOKE", target = "Lmezz/jei/recipes/RecipeManagerInternal;addRecipeTyped(Ljava/lang/Object;Lnet/minecraft/util/ResourceLocation;)V"), remap = false)
|
||||
private void checkForInterrupt(ImmutableListMultimap<ResourceLocation, Object> recipes, CallbackInfo ci) {
|
||||
IAsyncJeiStarter.checkForLoadInterruption();
|
||||
}
|
||||
}
|
||||
|
|
@ -56,3 +56,10 @@ mandatory = true
|
|||
versionRange = "[1.16.5,1.17)"
|
||||
ordering = "NONE"
|
||||
side = "BOTH"
|
||||
[[dependencies.modernfix]]
|
||||
modId = "jei"
|
||||
mandatory = false
|
||||
# This version range declares a minimum of the current minecraft version up to but not including the next major version
|
||||
versionRange = "[7.7.1.153,)"
|
||||
ordering = "BEFORE"
|
||||
side = "CLIENT"
|
||||
|
|
|
|||
|
|
@ -22,7 +22,12 @@
|
|||
"perf.skip_first_datapack_reload.MinecraftMixin",
|
||||
"bugfix.concurrency.RenderTypeMixin",
|
||||
"perf.parallelize_model_loading.ModelBakeryMixin",
|
||||
"perf.trim_model_caches.ModelManagerMixin"
|
||||
"perf.trim_model_caches.ModelManagerMixin",
|
||||
"perf.async_jei.IngredientListElementFactoryMixin",
|
||||
"perf.async_jei.ClientLifecycleHandlerMixin",
|
||||
"perf.async_jei.JeiStarterMixin",
|
||||
"perf.async_jei.PluginCallerMixin",
|
||||
"perf.async_jei.RecipeManagerInternalMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user