diff options
15 files changed, 130 insertions, 39 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/category/CategoryRegistry.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/category/CategoryRegistry.java index 35817b419..6e83dfac2 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/category/CategoryRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/category/CategoryRegistry.java @@ -109,6 +109,8 @@ public interface CategoryRegistry extends Reloadable<REIClientPlugin>, Iterable< <T extends Display> CategoryConfiguration<T> get(CategoryIdentifier<T> category); + <T extends Display> Optional<CategoryConfiguration<T>> tryGet(CategoryIdentifier<T> category); + <T extends Display> void configure(CategoryIdentifier<T> category, Consumer<CategoryConfiguration<T>> action); int size(); 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 be9c107ef..2ecb40967 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 @@ -34,6 +34,7 @@ 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.Nullable; import java.util.*; import java.util.function.Function; @@ -82,14 +83,31 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> { * * @param display the display */ - void add(Display display); + default void add(Display display) { + add(display, null); + } + + /** + * Registers a display with an origin attached. + * + * @param display the display + */ + void add(Display display, @Nullable Object origin); /** * Registers a display by the object provided, to be filled during {@link #tryFillDisplay(Object)}. * * @param object the object to be filled */ - void add(Object object); + default void add(Object object) { + if (object instanceof Display) { + add((Display) object, null); + } else { + for (Display display : tryFillDisplay(object)) { + add(display, object); + } + } + } /** * Returns an unmodifiable map of displays visible to the player @@ -271,4 +289,7 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> { * @return the collection of displays */ <T> Collection<Display> tryFillDisplay(T value); + + @Nullable + Object getDisplayOrigin(Display display); } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/plugins/PluginView.java b/api/src/main/java/me/shedaniel/rei/api/common/plugins/PluginView.java index 101f62b0d..ddd74a367 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/plugins/PluginView.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/plugins/PluginView.java @@ -31,7 +31,6 @@ import net.fabricmc.api.Environment; import org.jetbrains.annotations.ApiStatus; @ApiStatus.Internal -@FunctionalInterface public interface PluginView<P extends REIPlugin<?>> { @Environment(EnvType.CLIENT) static PluginView<REIClientPlugin> getClientInstance() { @@ -54,9 +53,26 @@ public interface PluginView<P extends REIPlugin<?>> { void registerPlugin(REIPluginProvider<? extends P> plugin); default PluginView<P> then(PluginView<? super P> view) { - return plugin -> { - registerPlugin(plugin); - view.registerPlugin(plugin); + return new PluginView<P>() { + @Override + public void registerPlugin(REIPluginProvider<? extends P> plugin) { + PluginView.this.registerPlugin(plugin); + view.registerPlugin(plugin); + } + + @Override + public void pre() { + PluginView.this.pre(); + } + + @Override + public void post() { + PluginView.this.post(); + } }; } + + void pre(); + + void post(); } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuTransferException.java b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuTransferException.java index 5fff31cb7..0016e0866 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuTransferException.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuTransferException.java @@ -28,16 +28,30 @@ import net.minecraft.network.chat.TranslatableComponent; public class MenuTransferException extends Exception { private final Component component; + private final boolean applicable; - public MenuTransferException(Component component) { + private MenuTransferException(Component component, boolean applicable) { this.component = component; + this.applicable = applicable; + } + + public MenuTransferException(Component component) { + this(component, true); } public MenuTransferException(String message) { this(new TranslatableComponent(message)); } + public static MenuTransferException createNotApplicable() { + return new MenuTransferException(null, false); + } + public Component getError() { return component; } + + public boolean isApplicable() { + return applicable; + } } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java b/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java index 3f4054cbc..97934437d 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java @@ -138,6 +138,14 @@ public class CollectionUtils { return l; } + public static <T, R> List<R> flatMap(T[] list, Function<T, Collection<R>> function) { + List<R> l = new ArrayList<>(); + for (T t : list) { + l.addAll(function.apply(t)); + } + return l; + } + public static <T> IntList mapToInt(Collection<T> list, ToIntFunction<T> function) { IntList l = new IntArrayList(list.size() + 1); for (T t : list) { diff --git a/api/src/main/java/me/shedaniel/rei/impl/Internals.java b/api/src/main/java/me/shedaniel/rei/impl/Internals.java index a5912535e..cbbc257ea 100644 --- a/api/src/main/java/me/shedaniel/rei/impl/Internals.java +++ b/api/src/main/java/me/shedaniel/rei/impl/Internals.java @@ -33,6 +33,7 @@ import me.shedaniel.rei.api.common.entry.type.EntryType; import me.shedaniel.rei.api.common.plugins.PluginManager; import me.shedaniel.rei.api.common.plugins.REIPlugin; import me.shedaniel.rei.api.common.plugins.REIServerPlugin; +import me.shedaniel.rei.api.common.transfer.info.MenuInfoRegistry; import net.minecraft.nbt.Tag; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Unit; @@ -51,6 +52,7 @@ public final class Internals { private static Supplier<PluginManager<REIServerPlugin>> serverPluginManager = Internals::throwNotSetup; private static Supplier<NbtHasherProvider> nbtHasherProvider = Internals::throwNotSetup; private static Function<String, CategoryIdentifier<?>> categoryIdentifier = (object) -> throwNotSetup(); + private static Supplier<MenuInfoRegistry> stubMenuInfoRegistry = Internals::throwNotSetup; private static <T> T throwNotSetup() { throw new AssertionError("REI Internals have not been initialized!"); diff --git a/forge/src/main/java/me/shedaniel/rei/forge/PluginDetectorImpl.java b/forge/src/main/java/me/shedaniel/rei/forge/PluginDetectorImpl.java index 8ee7a0a99..98d16516c 100644 --- a/forge/src/main/java/me/shedaniel/rei/forge/PluginDetectorImpl.java +++ b/forge/src/main/java/me/shedaniel/rei/forge/PluginDetectorImpl.java @@ -31,6 +31,7 @@ import me.shedaniel.rei.api.common.plugins.REIPluginProvider; import me.shedaniel.rei.api.common.plugins.REIServerPlugin; import me.shedaniel.rei.impl.ClientInternals; import me.shedaniel.rei.jeicompat.JEIPluginDetector; +import me.shedaniel.rei.jeicompat.JEITransferHandlerPlugin; import me.shedaniel.rei.plugin.client.DefaultClientPlugin; import me.shedaniel.rei.plugin.client.runtime.DefaultClientRuntimePlugin; import me.shedaniel.rei.plugin.common.DefaultPlugin; @@ -71,6 +72,7 @@ public class PluginDetectorImpl { public static void detectServerPlugins() { PluginView.getServerInstance().registerPlugin(wrapPlugin(Collections.singletonList("roughlyenoughitems"), new DefaultPlugin())); PluginView.getServerInstance().registerPlugin(wrapPlugin(Collections.singletonList("roughlyenoughitems"), new DefaultRuntimePlugin())); + PluginView.getServerInstance().registerPlugin(wrapPlugin(Collections.singletonList("roughlyenoughitems"), new JEITransferHandlerPlugin())); RoughlyEnoughItemsForge.<REIPlugin, REIServerPlugin>scanAnnotation(REIPlugin.class, REIServerPlugin.class::isAssignableFrom, (modId, plugin) -> { ((PluginView<REIServerPlugin>) PluginManager.getServerInstance()).registerPlugin(wrapPlugin(modId, plugin.get())); }); diff --git a/forge/src/main/java/me/shedaniel/rei/impl/client/gui/forge/ScreenOverlayImplImpl.java b/forge/src/main/java/me/shedaniel/rei/impl/client/gui/forge/ScreenOverlayImplImpl.java index 1b27ecf80..90b0e8857 100644 --- a/forge/src/main/java/me/shedaniel/rei/impl/client/gui/forge/ScreenOverlayImplImpl.java +++ b/forge/src/main/java/me/shedaniel/rei/impl/client/gui/forge/ScreenOverlayImplImpl.java @@ -26,11 +26,16 @@ package me.shedaniel.rei.impl.client.gui.forge; import com.mojang.blaze3d.vertex.PoseStack; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.CollectionUtils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.FormattedText; +import net.minecraft.network.chat.Style; import net.minecraft.world.item.ItemStack; import net.minecraftforge.fmlclient.gui.GuiUtils; +import java.util.List; + public class ScreenOverlayImplImpl { public static void renderTooltipInner(Screen screen, PoseStack matrices, Tooltip tooltip, int mouseX, int mouseY) { matrices.pushPose(); @@ -38,7 +43,8 @@ public class ScreenOverlayImplImpl { EntryStack<?> stack = tooltip.getContextStack(); ItemStack itemStack = stack.getValue() instanceof ItemStack ? stack.castValue() : ItemStack.EMPTY; GuiUtils.preItemToolTip(itemStack); - GuiUtils.drawHoveringText(matrices, tooltip.getText(), mouseX, mouseY, screen.width, screen.height, screen.width, Minecraft.getInstance().font); + List<FormattedText> texts = CollectionUtils.flatMap(tooltip.getText(), component -> Minecraft.getInstance().font.getSplitter().splitLines(component, 100000, Style.EMPTY)); + GuiUtils.drawHoveringText(matrices, texts, mouseX, mouseY, screen.width, screen.height, screen.width, Minecraft.getInstance().font); GuiUtils.postItemToolTip(); matrices.popPose(); } diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java index d6f6ac5a1..6bab2c9d8 100644 --- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java +++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java @@ -123,8 +123,14 @@ public class RoughlyEnoughItemsCore { } try { for (PluginManager<? extends REIPlugin<?>> instance : PluginManager.getActiveInstances()) { + instance.view().pre(); + } + for (PluginManager<? extends REIPlugin<?>> instance : PluginManager.getActiveInstances()) { instance.startReload(stage); } + for (PluginManager<? extends REIPlugin<?>> instance : PluginManager.getActiveInstances()) { + instance.view().post(); + } } catch (Throwable throwable) { throwable.printStackTrace(); } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java index b6dc4028d..b8525b6dc 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java @@ -511,7 +511,7 @@ public class ScreenOverlayImpl extends ScreenOverlay { }; Set<CategoryIdentifier<?>> categories = ScreenRegistry.getInstance().handleClickArea((Class<Screen>) screen.getClass(), context); if (categories != null && !categories.isEmpty()) { - Component collect = CollectionUtils.mapAndJoinToComponent(categories, identifier -> CategoryRegistry.getInstance().get(identifier).getCategory().getTitle(), new ImmutableTextComponent(", ")); + Component collect = CollectionUtils.mapAndJoinToComponent(categories, identifier -> CategoryRegistry.getInstance().tryGet(identifier).map(config -> config.getCategory().getTitle()).orElse(new ImmutableTextComponent(identifier.toString())), new ImmutableTextComponent(", ")); Tooltip.create(new TranslatableComponent("text.rei.view_recipes_for", collect)).queue(); } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java index 6cc34b3b1..8df053102 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java @@ -177,7 +177,7 @@ public final class InternalWidgets { } } if (Minecraft.getInstance().options.advancedItemTooltips && displaySupplier.get().getDisplayLocation().isPresent()) { - str.add(new TranslatableComponent("text.rei.recipe_id", new TextComponent(displaySupplier.get().getDisplayLocation().get().toString()).withStyle(ChatFormatting.GRAY)).withStyle(ChatFormatting.GRAY)); + str.add(new TranslatableComponent("text.rei.recipe_id", "", new TextComponent(displaySupplier.get().getDisplayLocation().get().toString()).withStyle(ChatFormatting.GRAY)).withStyle(ChatFormatting.GRAY)); } return str.toArray(new Component[0]); }); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/category/CategoryRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/category/CategoryRegistryImpl.java index 1e03b2ce7..ad1aaa431 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/category/CategoryRegistryImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/category/CategoryRegistryImpl.java @@ -75,6 +75,11 @@ public class CategoryRegistryImpl implements CategoryRegistry { } @Override + public <T extends Display> Optional<CategoryConfiguration<T>> tryGet(CategoryIdentifier<T> category) { + return Optional.ofNullable((CategoryConfiguration<T>) this.categories.get(category)); + } + + @Override public <T extends Display> void configure(CategoryIdentifier<T> category, Consumer<CategoryConfiguration<T>> action) { if (this.categories.containsKey(category)) { action.accept(get(category)); 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 4d57df4e6..e638f14fd 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 @@ -37,6 +37,7 @@ import me.shedaniel.rei.api.common.display.Display; import me.shedaniel.rei.impl.common.registry.RecipeManagerContextImpl; import net.minecraft.world.item.crafting.Recipe; import org.apache.commons.lang3.mutable.MutableInt; +import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -44,6 +45,7 @@ import java.util.function.Function; import java.util.function.Predicate; public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugin> implements DisplayRegistry { + private final WeakHashMap<Display, Object> displaysBase = new WeakHashMap<>(); private final Map<CategoryIdentifier<?>, List<Display>> displays = new ConcurrentHashMap<>(); private final Map<CategoryIdentifier<?>, List<DynamicDisplayGenerator<?>>> displayGenerators = new ConcurrentHashMap<>(); private final List<DynamicDisplayGenerator<?>> globalDisplayGenerators = new ArrayList<>(); @@ -66,25 +68,17 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi } @Override - public void add(Display display) { + public void add(Display display, @Nullable Object origin) { displays.computeIfAbsent(display.getCategoryIdentifier(), location -> new ArrayList<>()) .add(display); displayCount.increment(); - } - - @Override - public void add(Object object) { - for (Display display : tryFillDisplay(object)) { - add(display); + if (origin != null) { + synchronized (displaysBase) { + displaysBase.put(display, origin); + } } } - public void registerDisplay(int index, Display display) { - displays.computeIfAbsent(display.getCategoryIdentifier(), location -> new ArrayList<>()) - .add(index, display); - displayCount.increment(); - } - @Override public Map<CategoryIdentifier<?>, List<Display>> getAll() { return Collections.unmodifiableMap(displays); @@ -166,10 +160,7 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi List<Recipe<?>> allSortedRecipes = getAllSortedRecipes(); for (int i = allSortedRecipes.size() - 1; i >= 0; i--) { Recipe<?> recipe = allSortedRecipes.get(i); - Collection<Display> displays = tryFillDisplay(recipe); - for (Display display : displays) { - registerDisplay(0, display); - } + add(recipe); } } } @@ -206,6 +197,12 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi return null; } + @Override + @Nullable + public Object getDisplayOrigin(Display display) { + return displaysBase.get(display); + } + private static record DisplayFiller<D extends Display>( Predicate<Object> predicate, 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 48e818d32..82bc8f518 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 @@ -150,6 +150,24 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager< } @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); + } + + @Override + public void post() { + 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, "post-register", plugins, REIPlugin::postRegister); + } + + @Override public void startReload(ReloadStage stage) { try { reloading = true; @@ -170,19 +188,11 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager< RoughlyEnoughItemsCore.LOGGER.info("Reloading Plugin Manager [%s] stage [%s], registered %d plugins: %s", pluginClass.getSimpleName(), stage.toString(), plugins.size(), CollectionUtils.mapAndJoinToString(plugins, REIPlugin::getPluginProviderName, ", ")); Collections.reverse(plugins); - if (stage == ReloadStage.START) { - pluginSection(sectionData, "pre-register", plugins, REIPlugin::preRegister); - } - 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)); } - if (stage == ReloadStage.END) { - pluginSection(sectionData, "post-register", plugins, REIPlugin::postRegister); - } - for (Reloadable<P> reloadable : reloadables) { Class<?> reloadableClass = reloadable.getClass(); try (SectionClosable endReload = section(sectionData, "end-reload-" + MoreObjects.firstNonNull(reloadableClass.getSimpleName(), reloadableClass.getName()))) { diff --git a/runtime/src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java b/runtime/src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java index 2efe420a9..14f50a0d7 100644 --- a/runtime/src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java +++ b/runtime/src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java @@ -32,7 +32,6 @@ import me.shedaniel.rei.api.client.ClientHelper; import me.shedaniel.rei.api.client.registry.transfer.TransferHandler; import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.display.Display; -import me.shedaniel.rei.api.common.display.SimpleGridMenuDisplay; import me.shedaniel.rei.api.common.transfer.RecipeFinder; import me.shedaniel.rei.api.common.transfer.info.MenuInfo; import me.shedaniel.rei.api.common.transfer.info.MenuInfoContext; @@ -56,8 +55,7 @@ import java.util.List; public class DefaultCategoryHandler implements TransferHandler { @Override public Result handle(Context context) { - if (!(context.getDisplay() instanceof SimpleGridMenuDisplay display)) - return Result.createNotApplicable(); + Display display = context.getDisplay(); AbstractContainerScreen<?> containerScreen = context.getContainerScreen(); if (containerScreen == null) { return Result.createNotApplicable(); @@ -71,7 +69,11 @@ public class DefaultCategoryHandler implements TransferHandler { try { menuInfo.validate(menuInfoContext); } catch (MenuTransferException e) { - return Result.createFailed(e.getError()); + if (e.isApplicable()) { + return Result.createFailed(e.getError()); + } else { + return Result.createNotApplicable(); + } } List<List<ItemStack>> input = menuInfo.getInputs(menuInfoContext); IntList intList = hasItems(menu, menuInfo, display, input); |
