diff options
| author | shedaniel <daniel@shedaniel.me> | 2021-11-21 17:21:28 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2021-11-21 19:07:09 +0800 |
| commit | 92778560fb4e9b0f37446bb4858b0dcad23bdde6 (patch) | |
| tree | 1ee8d2420c4bf9b44882c48a385930cf1c41b472 | |
| parent | 30eb93c91f00c6cf8a3809ff72fa9bedaaebbc92 (diff) | |
| download | RoughlyEnoughItems-92778560fb4e9b0f37446bb4858b0dcad23bdde6.tar.gz RoughlyEnoughItems-92778560fb4e9b0f37446bb4858b0dcad23bdde6.tar.bz2 RoughlyEnoughItems-92778560fb4e9b0f37446bb4858b0dcad23bdde6.zip | |
Add wildcard matching
8 files changed, 153 insertions, 15 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/common/entry/EntryStack.java b/api/src/main/java/me/shedaniel/rei/api/common/entry/EntryStack.java index 74529de5c..da37a0432 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/entry/EntryStack.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/entry/EntryStack.java @@ -52,6 +52,7 @@ import java.util.function.Function; /** * @see me.shedaniel.rei.api.common.util.EntryStacks */ +@ApiStatus.NonExtendable public interface EntryStack<T> extends TextRepresentable, Renderer { static EntryStack<Unit> empty() { return Internals.getEntryStackProvider().empty(); @@ -122,14 +123,54 @@ public interface EntryStack<T> extends TextRepresentable, Renderer { boolean isEmpty(); + /** + * Returns a copy of this stack. + * The copied stack will retain the same settings applied, with a copied value. + * + * @return a copy for an entry + */ EntryStack<T> copy(); + /** + * Returns a copy of this stack. + * The copied stack will retain the value object, with no settings applied. + * + * @return a copy for an entry + */ default EntryStack<T> rewrap() { return copy(); } + /** + * Returns a copy of this stack. + * The copied stack will have no settings applied. + * <p> + * The new value should be functionally equivalent to the original value, + * but should have a normalized state. + * <p> + * For example, an {@link net.minecraft.world.item.ItemStack} should have its + * amount removed, but its tags kept. + * + * @return a copy for an entry + */ EntryStack<T> normalize(); + /** + * Returns a copy of this stack. + * The copied stack will have no settings applied. + * <p> + * The new value should be the bare minimum to match the original value. + * <p> + * For example, an {@link net.minecraft.world.item.ItemStack} should have its + * amount and tags removed. + * + * @return a copy for an entry + * @since 6.2 + */ + default EntryStack<T> wildcard() { + return normalize(); + } + Collection<ResourceLocation> getTagsFor(); @Deprecated diff --git a/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryDefinition.java b/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryDefinition.java index 81e2a93dd..343a3491c 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryDefinition.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryDefinition.java @@ -46,22 +46,92 @@ import java.util.Collection; * @see EntryTypeRegistry */ public interface EntryDefinition<T> { + /** + * Returns the type of the entry. + * + * @return the type of the entry + */ Class<T> getValueType(); + /** + * Returns the type of this definition. The type is also used for comparing the type of two definitions, + * as the definition does not guarantee object and reference equality. + * + * @return the type of this definition + */ EntryType<T> getType(); + /** + * Returns the renderer for this entry, this is used to render the entry, and provide tooltip. + * External plugins can extend this method using {@link me.shedaniel.rei.api.client.entry.renderer.EntryRendererRegistry} + * to provide custom renderers. + * + * @return the renderer for this entry + */ @Environment(EnvType.CLIENT) EntryRenderer<T> getRenderer(); + /** + * Returns the identifier for an entry, used in identifier search argument type, + * and appending the mod name to the tooltip. + * + * @param entry the entry + * @param value the value of the entry + * @return the identifier for an entry + */ @Nullable ResourceLocation getIdentifier(EntryStack<T> entry, T value); + /** + * Returns whether the entry is empty, empty entries are not displayed, + * and are considered invalid. + * Empty entries will be treated equally to {@link EntryStack#empty()}. + * + * @param entry the entry + * @param value the value of the entry + * @return whether the entry is empty + */ boolean isEmpty(EntryStack<T> entry, T value); + /** + * Returns a copy for an entry. + * + * @param entry the entry + * @param value the value of the entry + * @return a copy for an entry + */ T copy(EntryStack<T> entry, T value); + /** + * Returns a normalized copy for an entry. + * The returned stack should be functionally equivalent to the original stack, + * but should have a normalized state. + * <p> + * For example, an {@link net.minecraft.world.item.ItemStack} should have its + * amount removed, but its tags kept. + * + * @param entry the entry + * @param value the value of the entry + * @return a normalized copy for an entry + */ T normalize(EntryStack<T> entry, T value); + /** + * Returns a wildcard copy for an entry. + * The returned stack should be the bare minimum to match the original stack. + * <p> + * For example, an {@link net.minecraft.world.item.ItemStack} should have its + * amount and tags removed. + * + * @param entry the entry + * @param value the value of the entry + * @return a wildcard copy for an entry + * @since 6.2 + */ + default T wildcard(EntryStack<T> entry, T value) { + return normalize(entry, value); + } + long hash(EntryStack<T> entry, T value, ComparisonContext context); boolean equals(T o1, T o2, ComparisonContext context); diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/crafting/DefaultCraftingDisplay.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/crafting/DefaultCraftingDisplay.java index f37712c05..7138394e2 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/crafting/DefaultCraftingDisplay.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/crafting/DefaultCraftingDisplay.java @@ -25,7 +25,7 @@ package me.shedaniel.rei.plugin.common.displays.crafting; import dev.architectury.injectables.annotations.ExpectPlatform; import dev.architectury.injectables.annotations.PlatformOnly; -import me.shedaniel.architectury.platform.Platform; +import dev.architectury.platform.Platform; import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.display.SimpleGridMenuDisplay; import me.shedaniel.rei.api.common.display.basic.BasicDisplay; 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 a76cce52f..e56c68fc5 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 @@ -58,6 +58,7 @@ import org.jetbrains.annotations.ApiStatus; import java.util.*; import java.util.function.Consumer; import java.util.stream.Collectors; +import java.util.stream.Stream; @ApiStatus.Internal public class ViewsImpl implements Views { @@ -69,8 +70,14 @@ public class ViewsImpl implements Views { Stopwatch stopwatch = Stopwatch.createStarted(); Set<CategoryIdentifier<?>> categories = builder.getCategories(); - List<EntryStack<?>> recipesFor = builder.getRecipesFor(); - List<EntryStack<?>> usagesFor = builder.getUsagesFor(); + List<EntryStack<?>> recipesForStacks = builder.getRecipesFor(); + List<EntryStack<?>> usagesForStacks = builder.getUsagesFor(); + recipesForStacks = Stream.concat(recipesForStacks.stream(), recipesForStacks.stream().map(EntryStack::wildcard)) + .distinct() + .collect(Collectors.toList()); + usagesForStacks = Stream.concat(usagesForStacks.stream(), usagesForStacks.stream().map(EntryStack::wildcard)) + .distinct() + .collect(Collectors.toList()); DisplayRegistry displayRegistry = DisplayRegistry.getInstance(); Map<DisplayCategory<?>, List<Display>> result = Maps.newLinkedHashMap(); @@ -94,12 +101,12 @@ public class ViewsImpl implements Views { } for (Display display : allRecipesFromCategory) { if (!displayRegistry.isDisplayVisible(display)) continue; - if (!recipesFor.isEmpty()) { + if (!recipesForStacks.isEmpty()) { back: for (List<? extends EntryStack<?>> results : display.getOutputEntries()) { for (EntryStack<?> otherEntry : results) { - for (EntryStack<?> stack : recipesFor) { - if (EntryStacks.equalsFuzzy(otherEntry, stack)) { + for (EntryStack<?> recipesFor : recipesForStacks) { + if (EntryStacks.equalsFuzzy(otherEntry, recipesFor)) { set.add(display); break back; } @@ -107,12 +114,12 @@ public class ViewsImpl implements Views { } } } - if (!usagesFor.isEmpty()) { + if (!usagesForStacks.isEmpty()) { back: for (List<? extends EntryStack<?>> input : display.getInputEntries()) { for (EntryStack<?> otherEntry : input) { - for (EntryStack<?> stack : usagesFor) { - if (EntryStacks.equalsFuzzy(otherEntry, stack)) { + for (EntryStack<?> usagesFor : usagesForStacks) { + if (EntryStacks.equalsFuzzy(otherEntry, usagesFor)) { set.add(display); break back; } @@ -121,8 +128,8 @@ public class ViewsImpl implements Views { } } } - for (EntryStack<?> stack : usagesFor) { - if (isStackWorkStationOfCategory(categoryConfiguration, stack)) { + for (EntryStack<?> usagesFor : usagesForStacks) { + if (isStackWorkStationOfCategory(categoryConfiguration, usagesFor)) { set.addAll(CollectionUtils.filterToSet(allRecipesFromCategory, displayRegistry::isDisplayVisible)); break; } @@ -229,7 +236,7 @@ public class ViewsImpl implements Views { } String message = String.format("Built Recipe View in %s for %d categories, %d recipes for, %d usages for and %d live recipe generators.", - stopwatch.stop(), categories.size(), recipesFor.size(), usagesFor.size(), generatorsCount); + stopwatch.stop(), categories.size(), recipesForStacks.size(), usagesForStacks.size(), generatorsCount); if (ConfigObject.getInstance().doDebugSearchTimeRequired()) { RoughlyEnoughItemsCore.LOGGER.info(message); } else { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/AbstractEntryStack.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/AbstractEntryStack.java index 3e304f41e..1d3486971 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/AbstractEntryStack.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/AbstractEntryStack.java @@ -146,6 +146,11 @@ public abstract class AbstractEntryStack<A> implements EntryStack<A>, Renderer { return wrap(getDefinition().normalize(this, getValue()), false); } + @Override + public EntryStack<A> wildcard() { + return wrap(getDefinition().wildcard(this, getValue()), false); + } + protected EntryStack<A> wrap(A value, boolean copySettings) { TypedEntryStack<A> stack = new TypedEntryStack<>(getDefinition(), value); if (copySettings) { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/types/BuiltinEntryDefinition.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/types/BuiltinEntryDefinition.java index 582590f3b..0cfb65533 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/types/BuiltinEntryDefinition.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/types/BuiltinEntryDefinition.java @@ -101,6 +101,11 @@ public class BuiltinEntryDefinition<T> implements EntryDefinition<T>, EntrySeria } @Override + public T wildcard(EntryStack<T> entry, T value) { + return value; + } + + @Override public long hash(EntryStack<T> entry, T value, ComparisonContext context) { return empty ? 0 : Objects.hash(value.getClass().getName(), value); } diff --git a/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/FluidEntryDefinition.java b/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/FluidEntryDefinition.java index 6ddaba0ba..afb0f3613 100644 --- a/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/FluidEntryDefinition.java +++ b/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/FluidEntryDefinition.java @@ -130,9 +130,14 @@ public class FluidEntryDefinition implements EntryDefinition<FluidStack>, EntryS public FluidStack normalize(EntryStack<FluidStack> entry, FluidStack value) { Fluid fluid = value.getFluid(); if (fluid instanceof FlowingFluid flowingFluid) fluid = flowingFluid.getSource(); - FluidStack copy = FluidStack.create(fluid, value.getAmount(), value.getTag()); - copy.setAmount(FluidStack.bucketAmount()); - return copy; + return FluidStack.create(fluid, FluidStack.bucketAmount(), value.getTag()); + } + + @Override + public FluidStack wildcard(EntryStack<FluidStack> entry, FluidStack value) { + Fluid fluid = value.getFluid(); + if (fluid instanceof FlowingFluid) fluid = ((FlowingFluid) fluid).getSource(); + return FluidStack.create(fluid, FluidStack.bucketAmount()); } @Override diff --git a/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java b/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java index 647d2c7dc..9b34f65d8 100644 --- a/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java +++ b/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java @@ -129,6 +129,11 @@ public class ItemEntryDefinition implements EntryDefinition<ItemStack>, EntrySer } @Override + public ItemStack wildcard(EntryStack<ItemStack> entry, ItemStack value) { + return new ItemStack(value.getItem(), 1); + } + + @Override public long hash(EntryStack<ItemStack> entry, ItemStack value, ComparisonContext context) { int code = 1; code = 31 * code + System.identityHashCode(value.getItem()); |
