Implement facility to process specific JEI plugins on the main thread
This commit is contained in:
parent
da0ee80505
commit
f43d54eafd
|
|
@ -126,11 +126,6 @@ repositories {
|
|||
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 {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import net.minecraftforge.fml.ExtensionPoint;
|
|||
import net.minecraftforge.fml.InterModComms;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
|
||||
|
|
@ -26,16 +27,19 @@ import net.minecraftforge.fml.network.FMLNetworkConstants;
|
|||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.embeddedt.modernfix.core.config.ModernFixConfig;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
// The value here should match an entry in the META-INF/mods.toml file
|
||||
@Mod("modernfix")
|
||||
@Mod(ModernFix.MODID)
|
||||
public class ModernFix {
|
||||
|
||||
// Directly reference a log4j logger.
|
||||
public static final Logger LOGGER = LogManager.getLogger("ModernFix");
|
||||
|
||||
public static final String MODID = "modernfix";
|
||||
|
||||
public static ModernFix INSTANCE;
|
||||
|
||||
// Used to skip computing the blockstate caches twice
|
||||
|
|
@ -48,5 +52,6 @@ public class ModernFix {
|
|||
MinecraftForge.EVENT_BUS.register(this);
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> MinecraftForge.EVENT_BUS.register(new ModernFixClient()));
|
||||
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.DISPLAYTEST, () -> Pair.of(() -> FMLNetworkConstants.IGNORESERVERONLY, (a, b) -> true));
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, ModernFixConfig.COMMON_CONFIG);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package org.embeddedt.modernfix.core;
|
|||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.embeddedt.modernfix.core.config.ModernFixConfig;
|
||||
import org.embeddedt.modernfix.core.config.ModernFixEarlyConfig;
|
||||
import org.embeddedt.modernfix.core.config.Option;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
||||
|
|
@ -16,12 +16,12 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin {
|
|||
private static final String MIXIN_PACKAGE_ROOT = "org.embeddedt.modernfix.mixin.";
|
||||
|
||||
private final Logger logger = LogManager.getLogger("ModernFix");
|
||||
public static ModernFixConfig config = null;
|
||||
public static ModernFixEarlyConfig config = null;
|
||||
|
||||
@Override
|
||||
public void onLoad(String mixinPackage) {
|
||||
try {
|
||||
config = ModernFixConfig.load(new File("./config/modernfix-mixins.properties"));
|
||||
config = ModernFixEarlyConfig.load(new File("./config/modernfix-mixins.properties"));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Could not load configuration file for ModernFix", e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,179 +1,52 @@
|
|||
package org.embeddedt.modernfix.core.config;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Mod.EventBusSubscriber(modid = ModernFix.MODID, bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||
public class ModernFixConfig {
|
||||
private static final Logger LOGGER = LogManager.getLogger("ModernFixConfig");
|
||||
private static final ForgeConfigSpec.Builder COMMON_BUILDER = new ForgeConfigSpec.Builder();
|
||||
public static ForgeConfigSpec COMMON_CONFIG;
|
||||
|
||||
private final Map<String, Option> options = new HashMap<>();
|
||||
public static ForgeConfigSpec.ConfigValue<List<? extends String>> BLACKLIST_ASYNC_JEI_PLUGINS;
|
||||
|
||||
private ModernFixConfig() {
|
||||
// Defines the default rules which can be configured by the user or other mods.
|
||||
// You must manually add a rule for any new mixins not covered by an existing package rule.
|
||||
this.addMixinRule("core", true); // TODO: Don't actually allow the user to disable this
|
||||
this.addMixinRule("feature.measure_time", true);
|
||||
this.addMixinRule("perf.remove_biome_temperature_cache", true);
|
||||
this.addMixinRule("perf.resourcepacks", true);
|
||||
this.addMixinRule("perf.reduce_blockstate_cache_rebuilds", true);
|
||||
this.addMixinRule("perf.boost_worker_count", true);
|
||||
this.addMixinRule("perf.skip_first_datapack_reload", true);
|
||||
this.addMixinRule("perf.parallelize_model_loading", true);
|
||||
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);
|
||||
public static Set<ResourceLocation> jeiPluginBlacklist;
|
||||
|
||||
static {
|
||||
List<? extends String> empty = Collections.emptyList();
|
||||
Predicate<Object> locationValidator = o -> o instanceof String && ((String)o).contains(":");
|
||||
BLACKLIST_ASYNC_JEI_PLUGINS = COMMON_BUILDER
|
||||
.comment("These JEI plugins will be loaded on the main thread")
|
||||
.defineList("blacklist_async_jei_plugins", ImmutableList.of(
|
||||
"jepb:jei_plugin"
|
||||
), locationValidator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a Mixin rule which can be configured by users and other mods.
|
||||
* @throws IllegalStateException If a rule with that name already exists
|
||||
* @param mixin The name of the mixin package which will be controlled by this rule
|
||||
* @param enabled True if the rule will be enabled by default, otherwise false
|
||||
*/
|
||||
private void addMixinRule(String mixin, boolean enabled) {
|
||||
String name = getMixinRuleName(mixin);
|
||||
static {
|
||||
COMMON_CONFIG = COMMON_BUILDER.build();
|
||||
}
|
||||
|
||||
if (this.options.putIfAbsent(name, new Option(name, enabled, false)) != null) {
|
||||
throw new IllegalStateException("Mixin rule already defined: " + mixin);
|
||||
@SubscribeEvent
|
||||
public static void onModConfigEvent(final ModConfig.ModConfigEvent configEvent) {
|
||||
if (configEvent.getConfig().getSpec() == COMMON_CONFIG) {
|
||||
bakeConfig();
|
||||
}
|
||||
}
|
||||
|
||||
private void readProperties(Properties props) {
|
||||
for (Map.Entry<Object, Object> entry : props.entrySet()) {
|
||||
String key = (String) entry.getKey();
|
||||
String value = (String) entry.getValue();
|
||||
|
||||
Option option = this.options.get(key);
|
||||
|
||||
if (option == null) {
|
||||
LOGGER.warn("No configuration key exists with name '{}', ignoring", key);
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean enabled;
|
||||
|
||||
if (value.equalsIgnoreCase("true")) {
|
||||
enabled = true;
|
||||
} else if (value.equalsIgnoreCase("false")) {
|
||||
enabled = false;
|
||||
} else {
|
||||
LOGGER.warn("Invalid value '{}' encountered for configuration key '{}', ignoring", value, key);
|
||||
continue;
|
||||
}
|
||||
|
||||
option.setEnabled(enabled, true);
|
||||
}
|
||||
public static void bakeConfig() {
|
||||
jeiPluginBlacklist = BLACKLIST_ASYNC_JEI_PLUGINS.get().stream().map(ResourceLocation::new).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the effective option for the specified class name. This traverses the package path of the given mixin
|
||||
* and checks each root for configuration rules. If a configuration rule disables a package, all mixins located in
|
||||
* that package and its children will be disabled. The effective option is that of the highest-priority rule, either
|
||||
* a enable rule at the end of the chain or a disable rule at the earliest point in the chain.
|
||||
*
|
||||
* @return Null if no options matched the given mixin name, otherwise the effective option for this Mixin
|
||||
*/
|
||||
public Option getEffectiveOptionForMixin(String mixinClassName) {
|
||||
int lastSplit = 0;
|
||||
int nextSplit;
|
||||
|
||||
Option rule = null;
|
||||
|
||||
while ((nextSplit = mixinClassName.indexOf('.', lastSplit)) != -1) {
|
||||
String key = getMixinRuleName(mixinClassName.substring(0, nextSplit));
|
||||
|
||||
Option candidate = this.options.get(key);
|
||||
|
||||
if (candidate != null) {
|
||||
rule = candidate;
|
||||
|
||||
if (!rule.isEnabled()) {
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
|
||||
lastSplit = nextSplit + 1;
|
||||
}
|
||||
|
||||
return rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configuration file from the specified location. If it does not exist, a new configuration file will be
|
||||
* created. The file on disk will then be updated to include any new options.
|
||||
*/
|
||||
public static ModernFixConfig load(File file) {
|
||||
ModernFixConfig config = new ModernFixConfig();
|
||||
Properties props = new Properties();
|
||||
if(file.exists()) {
|
||||
try (FileInputStream fin = new FileInputStream(file)){
|
||||
props.load(fin);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Could not load config file", e);
|
||||
}
|
||||
config.readProperties(props);
|
||||
}
|
||||
|
||||
try {
|
||||
config.writeConfig(file, props);
|
||||
} catch (IOException e) {
|
||||
LOGGER.warn("Could not write configuration file", e);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
private void writeConfig(File file, Properties props) throws IOException {
|
||||
File dir = file.getParentFile();
|
||||
|
||||
if (!dir.exists()) {
|
||||
if (!dir.mkdirs()) {
|
||||
throw new IOException("Could not create parent directories");
|
||||
}
|
||||
} else if (!dir.isDirectory()) {
|
||||
throw new IOException("The parent file is not a directory");
|
||||
}
|
||||
|
||||
try (Writer writer = new FileWriter(file)) {
|
||||
writer.write("# This is the configuration file for ModernFix.\n");
|
||||
writer.write("#\n");
|
||||
writer.write("# The following options are enabled by default and should only be disabled if there is a.\n");
|
||||
writer.write("# compatibility issue. Add a line mixin.example_name=false without the # sign to disable a rule.\n");
|
||||
List<String> lines = this.options.keySet().stream()
|
||||
.filter(key -> !key.equals("mixin.core"))
|
||||
.sorted()
|
||||
.map(key -> "# " + key + "\n")
|
||||
.collect(Collectors.toList());
|
||||
for(String line : lines) {
|
||||
writer.write(line);
|
||||
}
|
||||
for (Map.Entry<Object, Object> entry : props.entrySet()) {
|
||||
String key = (String) entry.getKey();
|
||||
String value = (String) entry.getValue();
|
||||
writer.write(key + "=" + value + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getMixinRuleName(String name) {
|
||||
return "mixin." + name;
|
||||
}
|
||||
|
||||
public int getOptionCount() {
|
||||
return this.options.size();
|
||||
}
|
||||
|
||||
public int getOptionOverrideCount() {
|
||||
return (int) this.options.values()
|
||||
.stream()
|
||||
.filter(Option::isOverridden)
|
||||
.count();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,177 @@
|
|||
package org.embeddedt.modernfix.core.config;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ModernFixEarlyConfig {
|
||||
private static final Logger LOGGER = LogManager.getLogger("ModernFixConfig");
|
||||
|
||||
private final Map<String, Option> options = new HashMap<>();
|
||||
|
||||
private ModernFixEarlyConfig() {
|
||||
// Defines the default rules which can be configured by the user or other mods.
|
||||
// You must manually add a rule for any new mixins not covered by an existing package rule.
|
||||
this.addMixinRule("core", true); // TODO: Don't actually allow the user to disable this
|
||||
this.addMixinRule("feature.measure_time", true);
|
||||
this.addMixinRule("perf.remove_biome_temperature_cache", true);
|
||||
this.addMixinRule("perf.resourcepacks", true);
|
||||
this.addMixinRule("perf.reduce_blockstate_cache_rebuilds", true);
|
||||
this.addMixinRule("perf.boost_worker_count", true);
|
||||
this.addMixinRule("perf.skip_first_datapack_reload", true);
|
||||
this.addMixinRule("perf.parallelize_model_loading", true);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a Mixin rule which can be configured by users and other mods.
|
||||
* @throws IllegalStateException If a rule with that name already exists
|
||||
* @param mixin The name of the mixin package which will be controlled by this rule
|
||||
* @param enabled True if the rule will be enabled by default, otherwise false
|
||||
*/
|
||||
private void addMixinRule(String mixin, boolean enabled) {
|
||||
String name = getMixinRuleName(mixin);
|
||||
|
||||
if (this.options.putIfAbsent(name, new Option(name, enabled, false)) != null) {
|
||||
throw new IllegalStateException("Mixin rule already defined: " + mixin);
|
||||
}
|
||||
}
|
||||
|
||||
private void readProperties(Properties props) {
|
||||
for (Map.Entry<Object, Object> entry : props.entrySet()) {
|
||||
String key = (String) entry.getKey();
|
||||
String value = (String) entry.getValue();
|
||||
|
||||
Option option = this.options.get(key);
|
||||
|
||||
if (option == null) {
|
||||
LOGGER.warn("No configuration key exists with name '{}', ignoring", key);
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean enabled;
|
||||
|
||||
if (value.equalsIgnoreCase("true")) {
|
||||
enabled = true;
|
||||
} else if (value.equalsIgnoreCase("false")) {
|
||||
enabled = false;
|
||||
} else {
|
||||
LOGGER.warn("Invalid value '{}' encountered for configuration key '{}', ignoring", value, key);
|
||||
continue;
|
||||
}
|
||||
|
||||
option.setEnabled(enabled, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the effective option for the specified class name. This traverses the package path of the given mixin
|
||||
* and checks each root for configuration rules. If a configuration rule disables a package, all mixins located in
|
||||
* that package and its children will be disabled. The effective option is that of the highest-priority rule, either
|
||||
* a enable rule at the end of the chain or a disable rule at the earliest point in the chain.
|
||||
*
|
||||
* @return Null if no options matched the given mixin name, otherwise the effective option for this Mixin
|
||||
*/
|
||||
public Option getEffectiveOptionForMixin(String mixinClassName) {
|
||||
int lastSplit = 0;
|
||||
int nextSplit;
|
||||
|
||||
Option rule = null;
|
||||
|
||||
while ((nextSplit = mixinClassName.indexOf('.', lastSplit)) != -1) {
|
||||
String key = getMixinRuleName(mixinClassName.substring(0, nextSplit));
|
||||
|
||||
Option candidate = this.options.get(key);
|
||||
|
||||
if (candidate != null) {
|
||||
rule = candidate;
|
||||
|
||||
if (!rule.isEnabled()) {
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
|
||||
lastSplit = nextSplit + 1;
|
||||
}
|
||||
|
||||
return rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configuration file from the specified location. If it does not exist, a new configuration file will be
|
||||
* created. The file on disk will then be updated to include any new options.
|
||||
*/
|
||||
public static ModernFixEarlyConfig load(File file) {
|
||||
ModernFixEarlyConfig config = new ModernFixEarlyConfig();
|
||||
Properties props = new Properties();
|
||||
if(file.exists()) {
|
||||
try (FileInputStream fin = new FileInputStream(file)){
|
||||
props.load(fin);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Could not load config file", e);
|
||||
}
|
||||
config.readProperties(props);
|
||||
}
|
||||
|
||||
try {
|
||||
config.writeConfig(file, props);
|
||||
} catch (IOException e) {
|
||||
LOGGER.warn("Could not write configuration file", e);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
private void writeConfig(File file, Properties props) throws IOException {
|
||||
File dir = file.getParentFile();
|
||||
|
||||
if (!dir.exists()) {
|
||||
if (!dir.mkdirs()) {
|
||||
throw new IOException("Could not create parent directories");
|
||||
}
|
||||
} else if (!dir.isDirectory()) {
|
||||
throw new IOException("The parent file is not a directory");
|
||||
}
|
||||
|
||||
try (Writer writer = new FileWriter(file)) {
|
||||
writer.write("# This is the configuration file for ModernFix.\n");
|
||||
writer.write("#\n");
|
||||
writer.write("# The following options are enabled by default and should only be disabled if there is a.\n");
|
||||
writer.write("# compatibility issue. Add a line mixin.example_name=false without the # sign to disable a rule.\n");
|
||||
List<String> lines = this.options.keySet().stream()
|
||||
.filter(key -> !key.equals("mixin.core"))
|
||||
.sorted()
|
||||
.map(key -> "# " + key + "\n")
|
||||
.collect(Collectors.toList());
|
||||
for(String line : lines) {
|
||||
writer.write(line);
|
||||
}
|
||||
for (Map.Entry<Object, Object> entry : props.entrySet()) {
|
||||
String key = (String) entry.getKey();
|
||||
String value = (String) entry.getValue();
|
||||
writer.write(key + "=" + value + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getMixinRuleName(String name) {
|
||||
return "mixin." + name;
|
||||
}
|
||||
|
||||
public int getOptionCount() {
|
||||
return this.options.size();
|
||||
}
|
||||
|
||||
public int getOptionOverrideCount() {
|
||||
return (int) this.options.values()
|
||||
.stream()
|
||||
.filter(Option::isOverridden)
|
||||
.count();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package org.embeddedt.modernfix.mixin.bugfix.concurrency;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.concurrent.ThreadTaskExecutor;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
@Mixin(Minecraft.class)
|
||||
public abstract class MinecraftMixin<R extends Runnable> extends ThreadTaskExecutor<R> {
|
||||
|
||||
protected MinecraftMixin(String p_i50403_1_) {
|
||||
super(p_i50403_1_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void managedBlock(BooleanSupplier pIsDone) {
|
||||
if(!this.isSameThread()) {
|
||||
ModernFix.LOGGER.warn("A mod is calling Minecraft.managedBlock from the wrong thread. This is most likely related to one of our parallelizations.");
|
||||
ModernFix.LOGGER.warn("ModernFix will work around this, however ideally the issue should be patched in the other mod.");
|
||||
ModernFix.LOGGER.warn("Stacktrace", new IllegalThreadStateException());
|
||||
while(!pIsDone.getAsBoolean()) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch(InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
super.managedBlock(pIsDone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -27,17 +27,17 @@ 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;
|
||||
@Shadow(remap = false) @Final private JeiStarter starter;
|
||||
@Shadow(remap = false) @Final private List<IModPlugin> plugins;
|
||||
@Shadow(remap = false) @Final private Textures textures;
|
||||
@Shadow(remap = false) @Final private IClientConfig clientConfig;
|
||||
@Shadow(remap = false) @Final private IEditModeConfig editModeConfig;
|
||||
@Shadow(remap = false) @Final private IngredientFilterConfig ingredientFilterConfig;
|
||||
@Shadow(remap = false) @Final private WorldConfig worldConfig;
|
||||
@Shadow(remap = false) @Final private BookmarkConfig bookmarkConfig;
|
||||
@Shadow(remap = false) @Final private IModIdHelper modIdHelper;
|
||||
@Shadow(remap = false) @Final private RecipeCategorySortingConfig recipeCategorySortingConfig;
|
||||
@Shadow(remap = false) @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) {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import java.util.function.Consumer;
|
|||
|
||||
@Mixin(JeiStarter.class)
|
||||
public class JeiStarterMixin {
|
||||
@Shadow private boolean started;
|
||||
@Shadow(remap = false) 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) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ package org.embeddedt.modernfix.mixin.perf.async_jei;
|
|||
|
||||
import mezz.jei.api.IModPlugin;
|
||||
import mezz.jei.load.PluginCaller;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.core.config.ModernFixConfig;
|
||||
import org.embeddedt.modernfix.jei.async.IAsyncJeiStarter;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
|
@ -10,6 +13,8 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Mixin(PluginCaller.class)
|
||||
|
|
@ -18,4 +23,16 @@ public class PluginCallerMixin {
|
|||
private static void checkForInterrupt(String title, List<IModPlugin> plugins, Consumer<IModPlugin> func, CallbackInfo ci) {
|
||||
IAsyncJeiStarter.checkForLoadInterruption();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked","rawtypes"})
|
||||
@Redirect(method = "callOnPlugins", at = @At(value = "INVOKE", target = "Ljava/util/function/Consumer;accept(Ljava/lang/Object;)V"), remap = false)
|
||||
private static void runOnMainThreadIfNeeded(Consumer instance, Object pluginObj) {
|
||||
IModPlugin plugin = (IModPlugin)pluginObj;
|
||||
if(ModernFixConfig.jeiPluginBlacklist.contains(plugin.getPluginUid())) {
|
||||
ModernFix.LOGGER.warn("Going to main thread for " + plugin.getPluginUid());
|
||||
Minecraft.getInstance().executeBlocking(() -> instance.accept(plugin));
|
||||
} else {
|
||||
instance.accept(plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
"client": [
|
||||
"perf.skip_first_datapack_reload.MinecraftMixin",
|
||||
"bugfix.concurrency.RenderTypeMixin",
|
||||
"bugfix.concurrency.MinecraftMixin",
|
||||
"perf.parallelize_model_loading.ModelBakeryMixin",
|
||||
"perf.trim_model_caches.ModelManagerMixin",
|
||||
"perf.async_jei.IngredientListElementFactoryMixin",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user