diff options
| author | shedaniel <daniel@shedaniel.me> | 2024-09-04 16:20:39 +0900 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2024-09-06 18:20:41 +0900 |
| commit | a31f7254d76add6c34f134713c131463602f8cef (patch) | |
| tree | 0631d373694572a8a745d0e6241585a71b8640be /runtime/src | |
| parent | 3cf87de5b6fea02eb26b747761f8f85ad0b65f51 (diff) | |
| download | RoughlyEnoughItems-a31f7254d76add6c34f134713c131463602f8cef.tar.gz RoughlyEnoughItems-a31f7254d76add6c34f134713c131463602f8cef.tar.bz2 RoughlyEnoughItems-a31f7254d76add6c34f134713c131463602f8cef.zip | |
New plugin reload setup
1. Plugin reloads will now interrupt existing reloading tasks if a new plugin reload has been requested
2. Plugin reloads will be automatically interrupted when the player leaves the level / the level is removed
3. More logging in DisplayRegistryImpl showing the stats of displays
4. Failure in filling recipes will now not stop the caching of display lookup
5. Slightly improve performance of checking display visibility on display lookup
Diffstat (limited to 'runtime/src')
11 files changed, 534 insertions, 196 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java index 732ca00cd..3f99fa7cb 100644 --- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java +++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java @@ -29,13 +29,10 @@ import dev.architectury.platform.Platform; import dev.architectury.registry.ReloadListenerRegistry; import dev.architectury.utils.Env; import dev.architectury.utils.EnvExecutor; -import me.shedaniel.cloth.clothconfig.shadowed.blue.endless.jankson.annotation.Nullable; import me.shedaniel.rei.api.common.entry.type.EntryType; -import me.shedaniel.rei.api.common.plugins.PluginManager; import me.shedaniel.rei.api.common.plugins.PluginView; import me.shedaniel.rei.api.common.plugins.REIPlugin; import me.shedaniel.rei.api.common.plugins.REIServerPlugin; -import me.shedaniel.rei.api.common.registry.ReloadStage; import me.shedaniel.rei.impl.Internals; import me.shedaniel.rei.impl.common.InternalLogger; import me.shedaniel.rei.impl.common.category.CategoryIdentifierImpl; @@ -53,6 +50,8 @@ import me.shedaniel.rei.impl.common.logging.*; import me.shedaniel.rei.impl.common.logging.performance.PerformanceLogger; import me.shedaniel.rei.impl.common.logging.performance.PerformanceLoggerImpl; import me.shedaniel.rei.impl.common.plugins.PluginManagerImpl; +import me.shedaniel.rei.impl.common.plugins.ReloadInterruptionContext; +import me.shedaniel.rei.impl.common.plugins.ReloadManagerImpl; import me.shedaniel.rei.impl.common.registry.RecipeManagerContextImpl; import me.shedaniel.rei.impl.common.transfer.MenuInfoRegistryImpl; import me.shedaniel.rei.impl.common.transfer.SlotAccessorRegistryImpl; @@ -135,7 +134,7 @@ public class RoughlyEnoughItemsCore { UnaryOperator.identity(), new EntryTypeRegistryImpl(), new EntrySettingsAdapterRegistryImpl(), - new RecipeManagerContextImpl<>(RecipeManagerContextImpl.supplier()), + new RecipeManagerContextImpl<>(), new ItemComparatorRegistryImpl(), new FluidComparatorRegistryImpl(), new DisplaySerializerRegistryImpl(), @@ -147,28 +146,6 @@ public class RoughlyEnoughItemsCore { new SlotAccessorRegistryImpl()), "serverPluginManager"); } - public static void _reloadPlugins(@Nullable ReloadStage stage) { - if (stage == null) { - for (ReloadStage reloadStage : ReloadStage.values()) { - _reloadPlugins(reloadStage); - } - return; - } - try { - for (PluginManager<? extends REIPlugin<?>> instance : PluginManager.getActiveInstances()) { - instance.view().pre(stage); - } - for (PluginManager<? extends REIPlugin<?>> instance : PluginManager.getActiveInstances()) { - instance.startReload(stage); - } - for (PluginManager<? extends REIPlugin<?>> instance : PluginManager.getActiveInstances()) { - instance.view().post(stage); - } - } catch (Throwable throwable) { - throwable.printStackTrace(); - } - } - public void onInitialize() { PluginDetector detector = getPluginDetector(); detector.detectCommonPlugins(); @@ -179,8 +156,7 @@ public class RoughlyEnoughItemsCore { MutableLong lastReload = new MutableLong(-1); ReloadListenerRegistry.register(PackType.SERVER_DATA, (preparationBarrier, resourceManager, profilerFiller, profilerFiller2, executor, executor2) -> { return preparationBarrier.wait(Unit.INSTANCE).thenRunAsync(() -> { - PERFORMANCE_LOGGER.clear(); - RoughlyEnoughItemsCore._reloadPlugins(null); + ReloadManagerImpl.reloadPlugins(null, ReloadInterruptionContext.ofNever()); }, executor2); }); } diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java index 96a697253..271d785e5 100644 --- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java +++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java @@ -24,13 +24,12 @@ package me.shedaniel.rei; import com.google.common.collect.Lists; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.serialization.DataResult; import dev.architectury.event.Event; import dev.architectury.event.EventFactory; import dev.architectury.event.EventResult; import dev.architectury.event.events.client.ClientGuiEvent; +import dev.architectury.event.events.client.ClientPlayerEvent; import dev.architectury.event.events.client.ClientRecipeUpdateEvent; import dev.architectury.event.events.client.ClientScreenInputEvent; import dev.architectury.networking.NetworkManager; @@ -67,7 +66,6 @@ import me.shedaniel.rei.impl.client.entry.filtering.rules.FilteringRuleTypeRegis import me.shedaniel.rei.impl.client.entry.renderer.EntryRendererRegistryImpl; import me.shedaniel.rei.impl.client.favorites.DelegatingFavoriteEntryProviderImpl; import me.shedaniel.rei.impl.client.favorites.FavoriteEntryTypeRegistryImpl; -import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl; import me.shedaniel.rei.impl.client.gui.modules.entries.SubMenuEntry; import me.shedaniel.rei.impl.client.gui.modules.entries.ToggleMenuEntry; import me.shedaniel.rei.impl.client.gui.widget.InternalWidgets; @@ -89,6 +87,8 @@ import me.shedaniel.rei.impl.common.entry.type.EntryRegistryImpl; import me.shedaniel.rei.impl.common.entry.type.collapsed.CollapsibleEntryRegistryImpl; import me.shedaniel.rei.impl.common.entry.type.types.EmptyEntryDefinition; import me.shedaniel.rei.impl.common.plugins.PluginManagerImpl; +import me.shedaniel.rei.impl.common.plugins.ReloadManagerImpl; +import me.shedaniel.rei.impl.common.util.InstanceHelper; import me.shedaniel.rei.impl.common.util.IssuesDetector; import me.shedaniel.rei.plugin.test.REITestPlugin; import net.fabricmc.api.EnvType; @@ -121,7 +121,6 @@ import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.List; -import java.util.concurrent.*; import java.util.function.BiFunction; import java.util.function.BooleanSupplier; import java.util.function.Function; @@ -133,15 +132,6 @@ public class RoughlyEnoughItemsCoreClient { public static final Event<ClientRecipeUpdateEvent> PRE_UPDATE_RECIPES = EventFactory.createLoop(); public static final Event<Runnable> POST_UPDATE_TAGS = EventFactory.createLoop(); public static boolean isLeftMousePressed = false; - private static final ExecutorService RELOAD_PLUGINS = Executors.newSingleThreadScheduledExecutor(task -> { - Thread thread = new Thread(task, "REI-ReloadPlugins"); - thread.setDaemon(true); - thread.setUncaughtExceptionHandler(($, exception) -> { - InternalLogger.getInstance().throwException(exception); - }); - return thread; - }); - private static final List<Future<?>> RELOAD_TASKS = new CopyOnWriteArrayList<>(); public static void attachClientInternals() { InternalWidgets.attach(); @@ -317,24 +307,25 @@ public class RoughlyEnoughItemsCoreClient { private void registerEvents() { Minecraft client = Minecraft.getInstance(); final ResourceLocation recipeButtonTex = new ResourceLocation("textures/gui/recipe_button.png"); - MutableLong startReload = new MutableLong(-1); MutableLong endReload = new MutableLong(-1); PRE_UPDATE_RECIPES.register(recipeManager -> { - RoughlyEnoughItemsCore.PERFORMANCE_LOGGER.clear(); - reloadPlugins(startReload, ReloadStage.START); + reloadPlugins(null, ReloadStage.START); }); ClientRecipeUpdateEvent.EVENT.register(recipeManager -> { reloadPlugins(endReload, ReloadStage.END); }); + ClientPlayerEvent.CLIENT_PLAYER_QUIT.register(player -> { + InternalLogger.getInstance().debug("Player quit, clearing reload tasks!"); + endReload.setValue(-1); + ReloadManagerImpl.terminateReloadTasks(); + }); ClientGuiEvent.INIT_PRE.register((screen, access) -> { List<ReloadStage> stages = ((PluginManagerImpl<REIPlugin<?>>) PluginManager.getInstance()).getObservedStages(); if (Minecraft.getInstance().level != null && Minecraft.getInstance().player != null && stages.contains(ReloadStage.START) && !stages.contains(ReloadStage.END) && !PluginManager.areAnyReloading() && screen instanceof AbstractContainerScreen) { - for (Future<?> task : RELOAD_TASKS) { - if (!task.isDone()) { - return EventResult.pass(); - } + if (ReloadManagerImpl.countRunningReloadTasks() > 0) { + return EventResult.pass(); } InternalLogger.getInstance().error("Detected missing stage: END! This is possibly due to issues during client recipe reload! REI will force a reload of the recipes now!"); @@ -473,27 +464,12 @@ public class RoughlyEnoughItemsCoreClient { public static void reloadPlugins(MutableLong lastReload, @Nullable ReloadStage start) { if (Minecraft.getInstance().level == null) return; if (lastReload != null) { - if (lastReload.getValue() > 0 && System.currentTimeMillis() - lastReload.getValue() <= 5000) { + if (lastReload.getValue() > 0 && System.currentTimeMillis() - lastReload.getValue() <= 1000) { InternalLogger.getInstance().warn("Suppressing Reload Plugins of stage " + start); return; } lastReload.setValue(System.currentTimeMillis()); } - InternalLogger.getInstance().debug("Starting Reload Plugins of stage " + start, new Throwable()); - if (ConfigObject.getInstance().doesRegisterRecipesInAnotherThread()) { - Future<?>[] futures = new Future<?>[1]; - CompletableFuture<Void> future = CompletableFuture.runAsync(() -> RoughlyEnoughItemsCore._reloadPlugins(start), RELOAD_PLUGINS) - .whenComplete((unused, throwable) -> { - // Remove the future from the list of futures - if (futures[0] != null) { - RELOAD_TASKS.remove(futures[0]); - futures[0] = null; - } - }); - futures[0] = future; - RELOAD_TASKS.add(future); - } else { - RoughlyEnoughItemsCore._reloadPlugins(start); - } + ReloadManagerImpl.reloadPlugins(start, () -> InstanceHelper.connectionFromClient() == null); } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java index 30340bfba..b9596c200 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java @@ -24,7 +24,6 @@ package me.shedaniel.rei.impl.client.gui.config.options; import me.shedaniel.clothconfig2.api.ModifierKeyCode; -import me.shedaniel.rei.RoughlyEnoughItemsCore; import me.shedaniel.rei.RoughlyEnoughItemsCoreClient; import me.shedaniel.rei.api.client.config.entry.EntryStackProvider; import me.shedaniel.rei.api.client.gui.config.*; @@ -248,7 +247,6 @@ public interface AllREIConfigOptions { .enabledDisabled(); CompositeOption<Object> RELOAD_PLUGINS = make("reset.reload_plugins", i -> null, (i, v) -> new Object()) .reload((access, option, onClose) -> { - RoughlyEnoughItemsCore.PERFORMANCE_LOGGER.clear(); RoughlyEnoughItemsCoreClient.reloadPlugins(null, null); while (!PluginManager.areAnyReloading()) { try { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCache.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCache.java index b65aba97c..9c725efc4 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCache.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCache.java @@ -34,6 +34,10 @@ import java.util.List; import java.util.Set; public interface DisplayCache { + int cachedSize(); + + int notCachedSize(); + boolean doesCache(); boolean isCached(Display display); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCacheImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCacheImpl.java index 80a73f82e..4c995c9b0 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCacheImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayCacheImpl.java @@ -54,6 +54,16 @@ public class DisplayCacheImpl implements DisplayCache { } @Override + public int cachedSize() { + return this.displaysCached.size(); + } + + @Override + public int notCachedSize() { + return this.displaysNotCached.size(); + } + + @Override public boolean doesCache() { return this.cache; } @@ -66,7 +76,7 @@ public class DisplayCacheImpl implements DisplayCache { @Override public void add(Display display) { if (this.cache) { - if (!preprocessed) { + if (!this.preprocessed) { this.displaysNotCached.add(display); } else { this.process(display); @@ -80,7 +90,7 @@ public class DisplayCacheImpl implements DisplayCache { @Override public boolean remove(Display display) { if (this.cache) { - if (!preprocessed) { + if (!this.preprocessed) { return this.displaysNotCached.remove(display); } else { boolean removed = this.displaysCached.remove(display); @@ -106,7 +116,7 @@ public class DisplayCacheImpl implements DisplayCache { @Override public void endReload() { if (this.cache) { - if (preprocessed) { + if (this.preprocessed) { InternalLogger.getInstance().error("DisplayCache#endReload called after preprocessed!"); } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java index d0d36130c..7ec01a9f2 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java @@ -23,7 +23,9 @@ package me.shedaniel.rei.impl.client.registry.display; -import com.google.common.base.Preconditions; +import com.google.common.base.Stopwatch; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; import dev.architectury.event.EventResult; import me.shedaniel.rei.api.client.plugins.REIClientPlugin; import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; @@ -36,6 +38,7 @@ import me.shedaniel.rei.api.client.registry.display.visibility.DisplayVisibility import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.display.Display; import me.shedaniel.rei.api.common.plugins.PluginManager; +import me.shedaniel.rei.api.common.registry.ReloadStage; import me.shedaniel.rei.impl.common.InternalLogger; import me.shedaniel.rei.impl.common.registry.RecipeManagerContextImpl; import net.minecraft.world.item.crafting.Recipe; @@ -55,10 +58,6 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi private long lastAddWarning = -1; private DisplaysHolder displaysHolder = new DisplaysHolderImpl(false); - public DisplayRegistryImpl() { - super(RecipeManagerContextImpl.supplier()); - } - @Override public void acceptPlugin(REIClientPlugin plugin) { plugin.registerDisplays(this); @@ -122,7 +121,11 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi @Override public boolean isDisplayVisible(Display display) { DisplayCategory<Display> category = (DisplayCategory<Display>) CategoryRegistry.getInstance().get(display.getCategoryIdentifier()).getCategory(); - Preconditions.checkNotNull(category, "Failed to resolve category: " + display.getCategoryIdentifier()); + return isDisplayVisible(category, display); + } + + public boolean isDisplayVisible(DisplayCategory<?> category, Display display) { + if (category == null) throw new NullPointerException("Failed to resolve category: " + display.getCategoryIdentifier()); for (DisplayVisibilityPredicate predicate : visibilityPredicates) { try { EventResult result = predicate.handleDisplay(category, display); @@ -187,13 +190,8 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi @Override public void endReload() { - if (!fillers.isEmpty()) { - List<Recipe<?>> allSortedRecipes = getAllSortedRecipes(); - for (int i = allSortedRecipes.size() - 1; i >= 0; i--) { - Recipe<?> recipe = allSortedRecipes.get(i); - addWithReason(recipe, DisplayAdditionReason.RECIPE_MANAGER); - } - } + InternalLogger.getInstance().debug("Found preliminary %d displays", displaySize()); + fillSortedRecipes(); for (CategoryIdentifier<?> identifier : getAll().keySet()) { if (CategoryRegistry.getInstance().tryGet(identifier).isEmpty()) { @@ -201,21 +199,59 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi } } - List<Display> failedDisplays = new ArrayList<>(); + removeFailedDisplays(); + this.displaysHolder.endReload(); + InternalLogger.getInstance().debug("%d displays registration have completed", displaySize()); + } + + private void fillSortedRecipes() { + Stopwatch stopwatch = Stopwatch.createStarted(); + int lastSize = displaySize(); + if (!fillers.isEmpty()) { + List<Recipe<?>> allSortedRecipes = getAllSortedRecipes(); + for (int i = allSortedRecipes.size() - 1; i >= 0; i--) { + Recipe<?> recipe = allSortedRecipes.get(i); + try { + addWithReason(recipe, DisplayAdditionReason.RECIPE_MANAGER); + } catch (Throwable e) { + InternalLogger.getInstance().error("Failed to fill display for recipe: %s [%s]", recipe, recipe.getId(), e); + } + } + } + InternalLogger.getInstance().debug("Filled %d displays from recipe manager in %s", displaySize() - lastSize, stopwatch.stop()); + } + + private void removeFailedDisplays() { + Multimap<CategoryIdentifier<?>, Display> failedDisplays = Multimaps.newListMultimap(new HashMap<>(), ArrayList::new); for (List<Display> displays : getAll().values()) { for (Display display : displays) { if (!DisplayValidator.validate(display)) { - failedDisplays.add(display); + failedDisplays.put(display.getCategoryIdentifier(), display); } } } - for (Display display : failedDisplays) { - this.displaysHolder.remove(display); - } - - this.displaysHolder.endReload(); - InternalLogger.getInstance().debug("Registered %d displays", displaySize()); + InternalLogger.getInstance().debug("Removing %d failed displays" + (!failedDisplays.isEmpty() ? ":" : ""), failedDisplays.size()); + failedDisplays.asMap().entrySet().stream() + .sorted(Comparator.comparing(entry -> entry.getKey().toString())) + .forEach(entry -> { + InternalLogger.getInstance().debug("- %s: %d failed display" + (entry.getValue().size() == 1 ? "" : "s"), entry.getKey(), entry.getValue().size()); + for (Display display : entry.getValue()) { + this.displaysHolder.remove(display); + } + }); + } + + @Override + public void postStage(ReloadStage stage) { + if (stage != ReloadStage.END) return; + InternalLogger.getInstance().debug("Registered displays report (%d displays, %d cached / %d not cached)" + (displaySize() > 0 ? ":" : ""), + displaySize(), displaysHolder().cache().cachedSize(), displaysHolder().cache().notCachedSize()); + getAll().entrySet().stream() + .sorted(Comparator.comparing(entry -> entry.getKey().toString())) + .forEach(entry -> { + InternalLogger.getInstance().debug("- %s: %d display" + (entry.getValue().size() == 1 ? "" : "s"), entry.getKey(), entry.getValue().size()); + }); } public DisplaysHolder displaysHolder() { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/view/ViewsImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/view/ViewsImpl.java index 2d2e6fada..0047638aa 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/view/ViewsImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/view/ViewsImpl.java @@ -111,7 +111,7 @@ public class ViewsImpl implements Views { forCategories(processingVisibilityHandlers, filteringCategories, displayRegistry, result, (configuration, categoryId, displays, set) -> { if (categories.contains(categoryId)) { // If the category is in the search, add all displays for (Display display : displays) { - if (!processingVisibilityHandlers || displayRegistry.isDisplayVisible(display)) { + if (!processingVisibilityHandlers || ((DisplayRegistryImpl) displayRegistry).isDisplayVisible(configuration.getCategory(), display)) { set.add(display); } } @@ -121,7 +121,7 @@ public class ViewsImpl implements Views { return; } for (Display display : displays) { - if (processingVisibilityHandlers && !displayRegistry.isDisplayVisible(display)) continue; + if (processingVisibilityHandlers && !((DisplayRegistryImpl) displayRegistry).isDisplayVisible(configuration.getCategory(), display)) continue; if (!recipesForStacks.isEmpty()) { if (isRecipesFor(displaysHolder, recipesForStacks, display)) { set.add(display); @@ -171,7 +171,7 @@ public class ViewsImpl implements Views { forCategories(processingVisibilityHandlers, filteringCategories, displayRegistry, result, (configuration, categoryId, displays, set) -> { if (categories.contains(categoryId)) return; for (Display display : displays) { - if (processingVisibilityHandlers && !displayRegistry.isDisplayVisible(display)) continue; + if (processingVisibilityHandlers && !((DisplayRegistryImpl) displayRegistry).isDisplayVisible(configuration.getCategory(), display)) continue; if (!recipesForStacksWildcard.isEmpty()) { if (isRecipesFor(displaysHolder, recipesForStacksWildcard, display)) { set.add(display); @@ -193,7 +193,7 @@ public class ViewsImpl implements Views { if (isStackWorkStationOfCategory(configuration, usagesFor)) { categories.add(categoryId); if (processingVisibilityHandlers) { - set.addAll(CollectionUtils.filterToSet(displays, displayRegistry::isDisplayVisible)); + set.addAll(CollectionUtils.filterToSet(displays, display -> ((DisplayRegistryImpl) displayRegistry).isDisplayVisible(configuration.getCategory(), display))); } else { set.addAll(displays); } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/plugins/PluginManagerImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/plugins/PluginManagerImpl.java index d5140f2c8..b0d7abb52 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/common/plugins/PluginManagerImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/plugins/PluginManagerImpl.java @@ -38,12 +38,11 @@ import me.shedaniel.rei.api.common.plugins.REIPlugin; import me.shedaniel.rei.api.common.plugins.REIPluginProvider; import me.shedaniel.rei.api.common.registry.ReloadStage; import me.shedaniel.rei.api.common.registry.Reloadable; -import me.shedaniel.rei.api.common.util.CollectionUtils; import me.shedaniel.rei.impl.common.InternalLogger; import me.shedaniel.rei.impl.common.logging.performance.PerformanceLogger; import net.minecraft.client.Minecraft; import net.minecraft.server.MinecraftServer; -import org.apache.commons.lang3.tuple.MutablePair; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; @@ -52,7 +51,6 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import java.util.function.UnaryOperator; -import java.util.stream.Stream; @ApiStatus.Internal public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager<P>, PluginView<P> { @@ -62,7 +60,7 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager< private final UnaryOperator<PluginView<P>> view; @Nullable private ReloadStage reloading = null; - private List<ReloadStage> observedStages = new ArrayList<>(); + private final List<ReloadStage> observedStages = new ArrayList<>(); private final List<REIPluginProvider<P>> plugins = new ArrayList<>(); private final Stopwatch reloadStopwatch = Stopwatch.createUnstarted(); private boolean forcedMainThread; @@ -127,15 +125,7 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager< return FluentIterable.concat(Iterables.transform(plugins, REIPluginProvider::provide)); } - private static class PluginWrapper<P extends REIPlugin<?>> { - private final P plugin; - private final REIPluginProvider<P> provider; - - public PluginWrapper(P plugin, REIPluginProvider<P> provider) { - this.plugin = plugin; - this.provider = provider; - } - + private record PluginWrapper<P extends REIPlugin<?>>(P plugin, REIPluginProvider<P> provider) { public double getPriority() { return plugin.getPriority(); } @@ -143,7 +133,7 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager< public String getPluginProviderName() { String providerName = provider.getPluginProviderName(); - if (provider.provide().size() >= 1) { + if (!provider.provide().isEmpty()) { String pluginName = plugin.getPluginProviderName(); if (!providerName.equals(pluginName)) { @@ -158,32 +148,36 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager< @SuppressWarnings("RedundantTypeArguments") public FluentIterable<PluginWrapper<P>> getPluginWrapped() { return FluentIterable.<PluginWrapper<P>>concat(Iterables.<REIPluginProvider<P>, Iterable<PluginWrapper<P>>>transform(plugins, input -> Iterables.<P, PluginWrapper<P>>transform(input.provide(), - plugin -> new PluginWrapper(plugin, input)))); + plugin -> new PluginWrapper<>(plugin, input)))); } private class SectionClosable implements Closeable { - private ReloadStage stage; - private MutablePair<Stopwatch, String> sectionData; + private final PluginReloadContext context; + private final String section; + private final Stopwatch stopwatch; - public SectionClosable(ReloadStage stage, String section) { - this.stage = stage; - this.sectionData = new MutablePair<>(Stopwatch.createUnstarted(), ""); - sectionData.setRight(section); - InternalLogger.getInstance().trace("[" + name(pluginClass) + " " + stage + "] Reloading Section: \"%s\"", section); - sectionData.getLeft().reset().start(); + public SectionClosable(PluginReloadContext context, String section) { + this.context = context; + this.section = section; + this.stopwatch = Stopwatch.createStarted(); + InternalLogger.getInstance().trace("[" + name(pluginClass) + " " + context.stage() + "] Reloading Section: \"%s\"", section); } @Override public void close() { - sectionData.getLeft().stop(); - String section = sectionData.getRight(); - InternalLogger.getInstance().trace("[" + name(pluginClass) + " " + stage + "] Reloading Section: \"%s\" done in %s", section, sectionData.getLeft().toString()); - sectionData.getLeft().reset(); + this.stopwatch.stop(); + InternalLogger.getInstance().trace("[" + name(pluginClass) + " " + context.stage() + "] Reloading Section: \"%s\" done in %s", this.section, this.stopwatch); + this.stopwatch.reset(); + try { + context.interruptionContext().checkInterrupted(); + } catch (InterruptedException exception) { + ExceptionUtils.rethrow(exception); + } } } - private SectionClosable section(ReloadStage stage, String section) { - return new SectionClosable(stage, section); + private SectionClosable section(PluginReloadContext context, String section) { + return new SectionClosable(context, section); } @FunctionalInterface @@ -191,9 +185,9 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager< void accept(boolean respectMainThread, Runnable task); } - private void pluginSection(ReloadStage stage, String sectionName, List<PluginWrapper<P>> list, @Nullable Reloadable<?> reloadable, BiConsumer<PluginWrapper<P>, SectionPluginSink> consumer) { + private void pluginSection(PluginReloadContext context, String sectionName, List<PluginWrapper<P>> list, @Nullable Reloadable<?> reloadable, BiConsumer<PluginWrapper<P>, SectionPluginSink> consumer) throws InterruptedException { for (PluginWrapper<P> wrapper : list) { - try (SectionClosable section = section(stage, sectionName + wrapper.getPluginProviderName() + "/")) { + try (SectionClosable section = section(context, sectionName + wrapper.getPluginProviderName() + "/")) { consumer.accept(wrapper, (respectMainThread, runnable) -> { if (!respectMainThread || reloadable == null || !wrapper.plugin.shouldBeForcefullyDoneOnMainThread(reloadable)) { runnable.run(); @@ -213,6 +207,7 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager< } }); } catch (Throwable throwable) { + if (throwable instanceof InterruptedException) throw (InterruptedException) throwable; InternalLogger.getInstance().error(wrapper.getPluginProviderName() + " plugin failed to " + sectionName + "!", throwable); } } @@ -230,13 +225,15 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager< } @Override - public void pre(ReloadStage stage) { - this.reloading = stage; + public void pre(PluginReloadContext context0) throws InterruptedException { + this.reloading = context0.stage(); + PluginReloadContext context = PluginReloadContext.of(context0.stage(), context0.interruptionContext().withJob(() -> this.reloading = null)); + List<PluginWrapper<P>> plugins = new ArrayList<>(getPluginWrapped().toList()); plugins.sort(Comparator.comparingDouble(PluginWrapper<P>::getPriority).reversed()); Collections.reverse(plugins); InternalLogger.getInstance().debug("========================================"); - InternalLogger.getInstance().debug(name(pluginClass) + " starting pre-reload for " + stage + "."); + InternalLogger.getInstance().debug(name(pluginClass) + " starting pre-reload for " + context.stage() + "."); InternalLogger.getInstance().debug("Reloadables (%d):".formatted(reloadables.size())); for (Reloadable<P> reloadable : reloadables) { InternalLogger.getInstance().debug(" - " + name(reloadable.getClass())); @@ -250,47 +247,51 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager< this.forceMainThreadStopwatch.reset |
