diff options
| author | shedaniel <daniel@shedaniel.me> | 2021-10-16 00:37:19 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2021-10-16 00:50:42 +0800 |
| commit | 6e7a641926d8b0ea2d0a1caddbf348fe24b669ce (patch) | |
| tree | 58820c892f893b7a53eeb33448f5936a70469433 | |
| parent | 3a84bfa28bb233b3a6f0a14f2e90956a98512453 (diff) | |
| download | RoughlyEnoughItems-6e7a641926d8b0ea2d0a1caddbf348fe24b669ce.tar.gz RoughlyEnoughItems-6e7a641926d8b0ea2d0a1caddbf348fe24b669ce.tar.bz2 RoughlyEnoughItems-6e7a641926d8b0ea2d0a1caddbf348fe24b669ce.zip | |
Fix JEI recipes duplicating and going to the wrong category, Fix JER's insane resource reload during plugin application, Add DisplayAdditionReason, Safeguard DisplayCategory#setupDisplay
11 files changed, 264 insertions, 65 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayRegistry.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayRegistry.java index 2ecb40967..ad3a2aa18 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayRegistry.java @@ -25,6 +25,8 @@ package me.shedaniel.rei.api.client.registry.display; import com.google.common.base.Predicates; import me.shedaniel.rei.api.client.plugins.REIClientPlugin; +import me.shedaniel.rei.api.client.registry.display.reason.DisplayAdditionReason; +import me.shedaniel.rei.api.client.registry.display.reason.DisplayAdditionReasons; import me.shedaniel.rei.api.client.registry.display.visibility.DisplayVisibilityPredicate; import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.display.Display; @@ -34,9 +36,11 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.RecipeType; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.*; +import java.util.function.BiPredicate; import java.util.function.Function; import java.util.function.Predicate; @@ -100,10 +104,20 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> { * @param object the object to be filled */ default void add(Object object) { + addWithReason(object, DisplayAdditionReason.NONE); + } + + /** + * Registers a display by the object provided, to be filled during {@link #tryFillDisplay(Object)}. + * + * @param object the object to be filled + */ + @ApiStatus.Experimental + default void addWithReason(Object object, DisplayAdditionReason... reasons) { if (object instanceof Display) { add((Display) object, null); } else { - for (Display display : tryFillDisplay(object)) { + for (Display display : tryFillDisplay(object, reasons)) { add(display, object); } } @@ -275,6 +289,21 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> { * Vanilla {@link Recipe} are by default filled, display filters * can be used to automatically generate displaies for vanilla {@link Recipe}. * + * @param typeClass the type of {@code T} + * @param predicate the predicate of {@code T} and reason + * @param filler the filler, taking a {@code T} and returning a {@code D} + * @param <T> the type of object + * @param <D> the type of display + */ + @ApiStatus.Experimental + <T, D extends Display> void registerFiller(Class<T> typeClass, BiPredicate<? extends T, DisplayAdditionReasons> predicate, Function<? extends T, D> filler); + + /** + * Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}. + * <p> + * Vanilla {@link Recipe} are by default filled, display filters + * can be used to automatically generate displaies for vanilla {@link Recipe}. + * * @param predicate the predicate of the object * @param filler the filler, taking an object and returning a {@code D} * @param <D> the type of display @@ -288,7 +317,19 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> { * @param <T> the type of object * @return the collection of displays */ - <T> Collection<Display> tryFillDisplay(T value); + default <T> Collection<Display> tryFillDisplay(T value) { + return tryFillDisplay(value, DisplayAdditionReason.NONE); + } + + /** + * Tries to fill displays from {@code T}. + * + * @param value the object + * @param <T> the type of object + * @return the collection of displays + */ + @ApiStatus.Experimental + <T> Collection<Display> tryFillDisplay(T value, DisplayAdditionReason... reasons); @Nullable Object getDisplayOrigin(Display display); diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/reason/DisplayAdditionReason.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/reason/DisplayAdditionReason.java new file mode 100644 index 000000000..aae5244f2 --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/reason/DisplayAdditionReason.java @@ -0,0 +1,21 @@ +package me.shedaniel.rei.api.client.registry.display.reason; + +import org.jetbrains.annotations.ApiStatus; + +/** + * Reason for adding a display, used for {@link me.shedaniel.rei.api.client.registry.display.DisplayRegistry#tryFillDisplay(Object, DisplayAdditionReason...)} + * Plugins may filter their filler with reasons, this class can be implemented to provide additional context to fillers. + */ +@ApiStatus.Experimental +public interface DisplayAdditionReason { + DisplayAdditionReason[] NONE = new DisplayAdditionReason[0]; + /** + * Denotes that the display is added automatically by REI's RecipeManager, + * fillers which do not wish to be added with this should filter with this. + */ + DisplayAdditionReason RECIPE_MANAGER = simple(); + + static DisplayAdditionReason simple() { + return new DisplayAdditionReason() {}; + } +} diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/reason/DisplayAdditionReasons.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/reason/DisplayAdditionReasons.java new file mode 100644 index 000000000..ed3e43126 --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/reason/DisplayAdditionReasons.java @@ -0,0 +1,68 @@ +package me.shedaniel.rei.api.client.registry.display.reason; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; + +@ApiStatus.Experimental +public interface DisplayAdditionReasons { + @Nullable <T extends DisplayAdditionReason> T get(Class<? extends T> c); + + @Nullable <T extends DisplayAdditionReason> T get(T c); + + <T extends DisplayAdditionReason> boolean has(Class<? extends T> c); + + <T extends DisplayAdditionReason> boolean has(T c); + + @ApiStatus.Internal + class Impl implements DisplayAdditionReasons { + public static final Impl EMPTY = new Impl(DisplayAdditionReason.NONE); + private final DisplayAdditionReason[] reasons; + + public Impl(DisplayAdditionReason[] reasons) { + this.reasons = reasons; + } + + @Override + @Nullable + public <T extends DisplayAdditionReason> T get(Class<? extends T> c) { + for (DisplayAdditionReason reason : reasons) { + if (Objects.equals(reason.getClass(), c)) { + return (T) reason; + } + } + return null; + } + + @Override + public <T extends DisplayAdditionReason> @Nullable T get(T c) { + for (DisplayAdditionReason reason : reasons) { + if (Objects.equals(reason, c)) { + return (T) reason; + } + } + return null; + } + + @Override + public <T extends DisplayAdditionReason> boolean has(Class<? extends T> c) { + for (DisplayAdditionReason reason : reasons) { + if (Objects.equals(reason.getClass(), c)) { + return true; + } + } + return false; + } + + @Override + public <T extends DisplayAdditionReason> boolean has(T c) { + for (DisplayAdditionReason reason : reasons) { + if (Objects.equals(reason, c)) { + return true; + } + } + return false; + } + } +} diff --git a/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java b/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java index 724dc0fed..2599281e8 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java @@ -29,6 +29,7 @@ import me.shedaniel.rei.api.common.entry.comparison.FluidComparatorRegistry; import me.shedaniel.rei.api.common.entry.comparison.ItemComparatorRegistry; import me.shedaniel.rei.api.common.entry.type.EntryTypeRegistry; import me.shedaniel.rei.api.common.fluid.FluidSupportProvider; +import me.shedaniel.rei.api.common.registry.Reloadable; import org.jetbrains.annotations.ApiStatus; import java.util.Collection; @@ -107,4 +108,10 @@ public interface REIPlugin<P extends REIPlugin<?>> extends Comparable<REIPlugin< default Collection<P> provide() { return Collections.singletonList((P) this); } + + @ApiStatus.Internal + @ApiStatus.Experimental + default boolean shouldBeForcefullyDoneOnMainThread(Reloadable<?> reloadable) { + return false; + } } diff --git a/forge/build.gradle b/forge/build.gradle index 1accad167..eca05ac20 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -84,6 +84,8 @@ dependencies { // modRuntime("curse.maven:create-328085:3278516") modRuntime("curse.maven:industrial-foregoing-266515:3446262") modRuntime("curse.maven:titanium-287342:3346366") + modRuntime("curse.maven:extended-crafting-268387:3470453") + modRuntime("curse.maven:cucumber-272335:3349690") } shadowJar { diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml index 1a89466fd..f35aba857 100644 --- a/forge/src/main/resources/META-INF/mods.toml +++ b/forge/src/main/resources/META-INF/mods.toml @@ -8,7 +8,7 @@ license = "MIT" [[mods]] modId = "roughlyenoughitems" version = "${version}" -displayName = "Roughly Enough Items" +displayName = "Roughly Enough Items (REI)" description = ''' To allow players to view items and recipes. ''' diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/AbstractDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/AbstractDisplayViewingScreen.java index 0d69d3fce..48aea3c1a 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/AbstractDisplayViewingScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/AbstractDisplayViewingScreen.java @@ -24,6 +24,7 @@ package me.shedaniel.rei.impl.client.gui.screen; import com.google.common.collect.Lists; +import me.shedaniel.architectury.fluid.FluidStack; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.gui.screen.DisplayScreen; import me.shedaniel.rei.api.client.gui.widgets.Slot; @@ -33,12 +34,20 @@ import me.shedaniel.rei.api.client.registry.display.DisplayCategory; import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.display.Display; import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.entry.type.EntryType; +import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; import me.shedaniel.rei.api.common.util.CollectionUtils; import me.shedaniel.rei.impl.client.ClientHelperImpl; import me.shedaniel.rei.impl.client.gui.widget.EntryWidget; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.chat.NarratorChatListener; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.Tag; +import net.minecraft.tags.TagCollection; +import net.minecraft.tags.TagContainer; +import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -151,4 +160,35 @@ public abstract class AbstractDisplayViewingScreen extends Screen implements Dis } } } + + protected void setupTags(List<Widget> widgets) { + TagContainer tags = Minecraft.getInstance().getConnection().getTags(); + outer: + for (EntryWidget widget : Widgets.<EntryWidget>walk(widgets, EntryWidget.class::isInstance)) { + widget.removeTagMatch = false; + if (widget.getEntries().size() <= 1) continue; + EntryType<?> type = null; + for (EntryStack<?> entry : widget.getEntries()) { + if (type == null) { + type = entry.getType(); + } else if (type != entry.getType()) { + continue outer; + } + } + // TODO: Don't hardcode + TagCollection<?> collection; + List<Object> objects; + if (type == VanillaEntryTypes.ITEM) { + collection = tags.getItems(); + objects = CollectionUtils.map(widget.getEntries(), stack -> stack.<ItemStack>castValue().getItem()); + } else if (type == VanillaEntryTypes.FLUID) { + collection = tags.getFluids(); + objects = CollectionUtils.map(widget.getEntries(), stack -> stack.<FluidStack>castValue().getFluid()); + } else continue; + Map.Entry<ResourceLocation, ? extends Tag<?>> firstOrNull = CollectionUtils.findFirstOrNull(collection.getAllTags().entrySet(), entry -> entry.getValue().getValues().equals(objects)); + if (firstOrNull != null) { + widget.tagMatch = firstOrNull.getKey(); + } + } + } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java index b2b86fb47..5d1d66a98 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java @@ -47,6 +47,7 @@ import me.shedaniel.rei.api.common.display.Display; import me.shedaniel.rei.api.common.entry.EntryIngredient; import me.shedaniel.rei.impl.client.ClientHelperImpl; import me.shedaniel.rei.impl.client.REIRuntimeImpl; +import me.shedaniel.rei.impl.client.gui.widget.EntryWidget; import me.shedaniel.rei.impl.client.gui.widget.InternalWidgets; import me.shedaniel.rei.impl.client.gui.widget.TabWidget; import net.minecraft.client.Minecraft; @@ -61,6 +62,7 @@ import net.minecraft.util.Mth; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Optional; @@ -152,9 +154,22 @@ public class CompositeDisplayViewingScreen extends AbstractDisplayViewingScreen this.widgets.add(Widgets.createSlotBase(scrollListBounds)); Rectangle recipeBounds = new Rectangle(bounds.x + 100 + (guiWidth - 100) / 2 - category.getDisplayWidth(display) / 2, bounds.y + bounds.height / 2 - category.getDisplayHeight() / 2, category.getDisplayWidth(display), category.getDisplayHeight()); - List<Widget> setupDisplay = category.setupDisplay(display, recipeBounds); + List<Widget> setupDisplay; + try { + setupDisplay = category.setupDisplay(display, recipeBounds); + } catch (Throwable throwable) { + throwable.printStackTrace(); + setupDisplay = new ArrayList<>(); + setupDisplay.add(Widgets.createRecipeBase(bounds).color(0xFFBB0000)); + setupDisplay.add(Widgets.createLabel(new Point(bounds.getCenterX(), bounds.getCenterY() - 8), new TextComponent("Failed to initiate setupDisplay"))); + setupDisplay.add(Widgets.createLabel(new Point(bounds.getCenterX(), bounds.getCenterY() + 1), new TextComponent("Check console for error"))); + } + setupTags(setupDisplay); transformIngredientNotice(setupDisplay, ingredientStackToNotice); transformResultNotice(setupDisplay, resultStackToNotice); + for (EntryWidget widget : Widgets.<EntryWidget>walk(widgets, EntryWidget.class::isInstance)) { + widget.removeTagMatch = true; + } this.widgets.addAll(setupDisplay); Optional<ButtonArea> supplier = CategoryRegistry.getInstance().get(category.getCategoryIdentifier()).getPlusButtonArea(); if (supplier.isPresent() && supplier.get().get(recipeBounds) != null) diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java index c190033b2..52e5b3a67 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java @@ -29,7 +29,6 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.math.Matrix4f; -import me.shedaniel.architectury.fluid.FluidStack; import me.shedaniel.clothconfig2.api.ModifierKeyCode; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; @@ -47,9 +46,6 @@ import me.shedaniel.rei.api.client.view.ViewSearchBuilder; import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.display.Display; import me.shedaniel.rei.api.common.entry.EntryIngredient; -import me.shedaniel.rei.api.common.entry.EntryStack; -import me.shedaniel.rei.api.common.entry.type.EntryType; -import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; import me.shedaniel.rei.api.common.util.CollectionUtils; import me.shedaniel.rei.api.common.util.ImmutableTextComponent; import me.shedaniel.rei.impl.client.ClientHelperImpl; @@ -71,18 +67,11 @@ import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvents; -import net.minecraft.tags.Tag; -import net.minecraft.tags.TagCollection; -import net.minecraft.tags.TagContainer; import net.minecraft.util.Mth; -import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; import java.util.function.Supplier; @ApiStatus.Internal @@ -253,7 +242,16 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { final Supplier<Display> displaySupplier = () -> display; int displayWidth = getCurrentCategory().getDisplayWidth(displaySupplier.get()); final Rectangle displayBounds = new Rectangle(getBounds().getCenterX() - displayWidth / 2, getBounds().getCenterY() + 16 - recipeHeight * (getRecipesPerPage() + 1) / 2 - 2 * (getRecipesPerPage() + 1) + recipeHeight * i + 4 * i, displayWidth, recipeHeight); - List<Widget> setupDisplay = getCurrentCategory().setupDisplay(display, displayBounds); + List<Widget> setupDisplay; + try { + setupDisplay = getCurrentCategory().setupDisplay(display, displayBounds); + } catch (Throwable throwable) { + throwable.printStackTrace(); + setupDisplay = new ArrayList<>(); + setupDisplay.add(Widgets.createRecipeBase(bounds).color(0xFFBB0000)); + setupDisplay.add(Widgets.createLabel(new Point(bounds.getCenterX(), bounds.getCenterY() - 8), new TextComponent("Failed to initiate setupDisplay"))); + setupDisplay.add(Widgets.createLabel(new Point(bounds.getCenterX(), bounds.getCenterY() + 1), new TextComponent("Check console for error"))); + } setupTags(setupDisplay); transformIngredientNotice(setupDisplay, ingredientStackToNotice); transformResultNotice(setupDisplay, resultStackToNotice); @@ -299,37 +297,6 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { _children().addAll(preWidgets); } - private void setupTags(List<Widget> widgets) { - TagContainer tags = Minecraft.getInstance().getConnection().getTags(); - outer: - for (EntryWidget widget : Widgets.<EntryWidget>walk(widgets, EntryWidget.class::isInstance)) { - widget.removeTagMatch = false; - if (widget.getEntries().size() <= 1) continue; - EntryType<?> type = null; - for (EntryStack<?> entry : widget.getEntries()) { - if (type == null) { - type = entry.getType(); - } else if (type != entry.getType()) { - continue outer; - } - } - // TODO: Don't hardcode - TagCollection<?> collection; - List<Object> objects; - if (type == VanillaEntryTypes.ITEM) { - collection = tags.getItems(); - objects = CollectionUtils.map(widget.getEntries(), stack -> stack.<ItemStack>castValue().getItem()); - } else if (type == VanillaEntryTypes.FLUID) { - collection = tags.getFluids(); - objects = CollectionUtils.map(widget.getEntries(), stack -> stack.<FluidStack>castValue().getFluid()); - } else continue; - Map.Entry<ResourceLocation, ? extends Tag<?>> firstOrNull = CollectionUtils.findFirstOrNull(collection.getAllTags().entrySet(), entry -> entry.getValue().getValues().equals(objects)); - if (firstOrNull != null) { - widget.tagMatch = firstOrNull.getKey(); - } - } - } - public List<Widget> getWidgets() { return widgets; } 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 e638f14fd..bfc975188 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 @@ -31,6 +31,8 @@ import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; import me.shedaniel.rei.api.client.registry.display.DisplayCategory; import me.shedaniel.rei.api.client.registry.display.DisplayRegistry; import me.shedaniel.rei.api.client.registry.display.DynamicDisplayGenerator; +import me.shedaniel.rei.api.client.registry.display.reason.DisplayAdditionReason; +import me.shedaniel.rei.api.client.registry.display.reason.DisplayAdditionReasons; import me.shedaniel.rei.api.client.registry.display.visibility.DisplayVisibilityPredicate; import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.display.Display; @@ -41,6 +43,7 @@ import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.BiPredicate; import java.util.function.Function; import java.util.function.Predicate; @@ -140,8 +143,13 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi } @Override + public <T, D extends Display> void registerFiller(Class<T> typeClass, BiPredicate<? extends T, DisplayAdditionReasons> predicate, Function<? extends T, D> filler) { + fillers.add(new DisplayFiller<>((o, s) -> typeClass.isInstance(o) && ((BiPredicate<Object, DisplayAdditionReasons>) predicate).test(o, s), (Function<Object, D>) filler)); + } + + @Override public <D extends Display> void registerFiller(Predicate<?> predicate, Function<?, D> filler) { - fillers.add(new DisplayFiller<>((Predicate<Object>) predicate, (Function<Object, D>) filler)); + fillers.add(new DisplayFiller<>((o, s) -> ((Predicate<Object>) predicate).test(o), (Function<Object, D>) filler)); } @Override @@ -160,17 +168,18 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi List<Recipe<?>> allSortedRecipes = getAllSortedRecipes(); for (int i = allSortedRecipes.size() - 1; i >= 0; i--) { Recipe<?> recipe = allSortedRecipes.get(i); - add(recipe); + addWithReason(recipe, DisplayAdditionReason.RECIPE_MANAGER); } } } @Override - public <T> Collection<Display> tryFillDisplay(T value) { + public <T> Collection<Display> tryFillDisplay(T value, DisplayAdditionReason... reason) { if (value instanceof Display) return Collections.singleton((Display) value); List<Display> displays = null; + DisplayAdditionReasons reasons = reason.length == 0 ? DisplayAdditionReasons.Impl.EMPTY : new DisplayAdditionReasons.Impl(reason); for (DisplayFiller<?> filler : fillers) { - Display display = tryFillDisplayGenerics(filler, value); + Display display = tryFillDisplayGenerics(filler, value, reasons); if (display != null) { if (displays == null) displays = Collections.singletonList(display); else { @@ -185,9 +194,9 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi return Collections.emptyList(); } - private <D extends Display> D tryFillDisplayGenerics(DisplayFiller<D> filler, Object value) { + private <D extends Display> D tryFillDisplayGenerics(DisplayFiller<D> filler, Object value, DisplayAdditionReasons reasons) { try { - if (filler.predicate.test(value)) { + if (filler.predicate.test(value, reasons)) { return filler.mappingFunction.apply(value); } } catch (Throwable e) { @@ -204,7 +213,7 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi } private static record DisplayFiller<D extends Display>( - Predicate<Object> predicate, + BiPredicate<Object, DisplayAdditionReasons> predicate, Function<Object, D> mappingFunction ) {} 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 82bc8f518..f3421e76e 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 @@ -23,10 +23,13 @@ package me.shedaniel.rei.impl.common.plugins; -import com.google.common.base.MoreObjects; import com.google.common.base.Stopwatch; import com.google.common.collect.FluentIterable; import com.google.common.collect.Iterables; +import me.shedaniel.architectury.platform.Platform; +import me.shedaniel.architectury.utils.Env; +import me.shedaniel.architectury.utils.EnvExecutor; +import me.shedaniel.architectury.utils.GameInstance; import me.shedaniel.rei.RoughlyEnoughItemsCore; import me.shedaniel.rei.api.common.plugins.PluginManager; import me.shedaniel.rei.api.common.plugins.PluginView; @@ -36,8 +39,11 @@ 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 net.minecraft.Util; +import net.minecraft.client.Minecraft; +import net.minecraft.server.MinecraftServer; import org.apache.commons.lang3.tuple.MutablePair; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; import java.io.Closeable; import java.util.*; @@ -103,7 +109,7 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager< @Override public void registerPlugin(REIPluginProvider<? extends P> plugin) { plugins.add((REIPluginProvider<P>) plugin); - RoughlyEnoughItemsCore.LOGGER.info("Registered plugin provider %s for %s", plugin.getPluginProviderName(), pluginClass.getSimpleName()); + RoughlyEnoughItemsCore.LOGGER.info("Registered plugin provider %s for %s", plugin.getPluginProviderName(), name(pluginClass)); } @Override @@ -139,23 +145,40 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager< return new SectionClosable(sectionData, section); } - private void pluginSection(MutablePair<Stopwatch, String> sectionData, String sectionName, List<P> list, Consumer<P> consumer) { + private void pluginSection(MutablePair<Stopwatch, String> sectionData, String sectionName, List<P> list, @Nullable Reloadable<?> reloadable, Consumer<P> consumer) { for (P plugin : list) { try (SectionClosable section = section(sectionData, sectionName + " for " + plugin.getPluginProviderName())) { - consumer.accept(plugin); + if (reloadable == null || !plugin.shouldBeForcefullyDoneOnMainThread(reloadable)) { + consumer.accept(plugin); + } else if (Platform.getEnvironment() == Env.CLIENT) { + EnvExecutor.runInEnv(Env.CLIENT, () -> () -> queueExecutionClient(() -> consumer.accept(plugin))); + } else { + queueExecution(() -> consumer.accept(plugin)); + } } catch (Throwable throwable) { RoughlyEnoughItemsCore.LOGGER.error(plugin.getPluginProviderName() + " plugin failed to " + sectionName + "!", throwable); } } } + private void queueExecution(Runnable runnable) { + MinecraftServer server = GameInstance.getServer(); + if (server != null) { + server.executeBlocking(runnable); + } + } + + private void queueExecutionClient(Runnable runnable) { + Minecraft.getInstance().executeBlocking(runnable); + } + @Override public void pre() { List<P> plugins = new ArrayList<>(getPlugins().toList()); plugins.sort(Comparator.comparingDouble(P::getPriority).reversed()); Collections.reverse(plugins); MutablePair<Stopwatch, String> sectionData = new MutablePair<>(Stopwatch.createUnstarted(), ""); - pluginSection(sectionData, "pre-register", plugins, REIPlugin::preRegister); + pluginSection(sectionData, "pre-register", plugins, null, REIPlugin::preRegister); } @Override @@ -164,7 +187,13 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager< plugins.sort(Comparator.comparingDouble(P::getPriority).reversed()); Collections.reverse(plugins); MutablePair<Stopwatch, String> sectionData = new MutablePair<>(Stopwatch.createUnstarted(), ""); - pluginSection(sectionData, "post-register", plugins, REIPlugin::postRegister); + pluginSection(sectionData, "post-register", plugins, null, REIPlugin::postRegister); + } + + private static String name(Class<?> clazz) { + String simpleName = clazz.getSimpleName(); + if (simpleName.isEmpty()) return clazz.getName(); + return simpleName; } @Override @@ -176,7 +205,7 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager< for (Reloadable<P> reloadable : reloadables) { Class<?> reloadableClass = reloadable.getClass(); - try (SectionClosable startReload = section(sectionData, "start-reload-" + MoreObjects.firstNonNull(reloadableClass.getSimpleName(), reloadableClass.getName()))) { + try (SectionClosable startReload = section(sectionData, "start-reload-" + name(reloadableClass))) { reloadable.startReload(stage); } catch (Throwable throwable) { throwable.printStackTrace(); @@ -185,17 +214,17 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager< List<P> plugins = new ArrayList<>(getPlugins().toList()); plugins.sort(Comparator.comparingDouble(P::getPriority).reversed()); - RoughlyEnoughItemsCore.LOGGER.info("Reloading Plugin Manager [%s] stage [%s], registered %d plugins: %s", pluginClass.getSimpleName(), stage.toString(), plugins.size(), CollectionUtils.mapAndJoinToString(plugins, REIPlugin::getPluginProviderName, ", ")); + RoughlyEnoughItemsCore.LOGGER.info("Reloading Plugin Manager [%s] stage [%s], registered %d plugins: %s", name(pluginClass), stage.toString(), plugins.size(), CollectionUtils.mapAndJoinToString(plugins, REIPlugin::getPluginProviderName, ", ")); Collections.reverse(plugins); for (Reloadable<P> reloadable : getReloadables()) { Class<?> reloadableClass = reloadable.getClass(); - pluginSection(sectionData, "reloadable-plugin-" + MoreObjects.firstNonNull(reloadableClass.getSimpleName(), reloadableClass.getName()), plugins, plugin -> reloadable.acceptPlugin(plugin, stage)); + pluginSection(sectionData, "re |
