diff options
13 files changed, 131 insertions, 28 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 44f185f4c..6061e28b0 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 @@ -33,6 +33,8 @@ import me.shedaniel.rei.api.common.plugins.PluginManager; import me.shedaniel.rei.api.common.registry.Reloadable; import me.shedaniel.rei.api.common.util.CollectionUtils; import me.shedaniel.rei.api.common.util.Identifiable; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.resources.ResourceLocation; import java.util.List; @@ -41,6 +43,13 @@ import java.util.function.Consumer; import java.util.stream.Stream; import java.util.stream.StreamSupport; +/** + * Registry for registering new categories for displays. + * Relies on {@link CategoryIdentifier}, and is reset per plugin reload. + * + * @see REIClientPlugin#registerCategories(CategoryRegistry) + */ +@Environment(EnvType.CLIENT) public interface CategoryRegistry extends Reloadable<REIClientPlugin>, Iterable<CategoryRegistry.CategoryConfiguration<?>> { /** * @return the instance of {@link CategoryRegistry} 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 07412c76c..14204c920 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 @@ -32,6 +32,7 @@ import me.shedaniel.rei.api.common.plugins.PluginManager; import me.shedaniel.rei.api.common.registry.RecipeManagerContext; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.world.item.crafting.Recipe; import java.util.Collection; import java.util.Collections; @@ -40,6 +41,27 @@ import java.util.Map; import java.util.function.Function; import java.util.function.Predicate; +/** + * Registry for registering displays for categories, this is called right after + * {@link me.shedaniel.rei.api.client.registry.category.CategoryRegistry}. + * + * <p>Each display should have a category associated with it that's registered, + * For any dynamic displays, you may want to look at {@link DynamicDisplayGenerator}. + * + * <p>Plugins may also determine the visibility of the displays dynamically via + * {@link DisplayVisibilityPredicate}, these predicates are preferred comparing to + * removing the displays from the registry. + * + * <p>Displays filler may be used for automatically registering displays from {@link Recipe}, + * these are filled after client recipe manager sync, and are invoked with one cycle. + * Additionally, display filters allow other mods to easily register additional displays + * for your mod. + * + * @see Display + * @see DynamicDisplayGenerator + * @see DisplayVisibilityPredicate + * @see REIClientPlugin#registerDisplays(DisplayRegistry) + */ @Environment(EnvType.CLIENT) public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> { /** @@ -85,7 +107,7 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> { * * @param generator the generator to register */ - <A extends Display> void registerGlobalDisplayGenerator(LiveDisplayGenerator<A> generator); + <A extends Display> void registerGlobalDisplayGenerator(DynamicDisplayGenerator<A> generator); /** * Registers a display generator @@ -93,28 +115,28 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> { * @param categoryId the identifier of the category * @param generator the generator to register */ - <A extends Display> void registerDisplayGenerator(CategoryIdentifier<A> categoryId, LiveDisplayGenerator<A> generator); + <A extends Display> void registerDisplayGenerator(CategoryIdentifier<A> categoryId, DynamicDisplayGenerator<A> generator); /** * Returns an unmodifiable map of display generators * * @return an unmodifiable map of display generators */ - Map<CategoryIdentifier<?>, List<LiveDisplayGenerator<?>>> getCategoryDisplayGenerators(); + Map<CategoryIdentifier<?>, List<DynamicDisplayGenerator<?>>> getCategoryDisplayGenerators(); /** * Returns an unmodifiable list of category-less display generators * * @return an unmodifiable list of category-less display generators */ - List<LiveDisplayGenerator<?>> getGlobalDisplayGenerators(); + List<DynamicDisplayGenerator<?>> getGlobalDisplayGenerators(); /** * Returns the list of display generators for a category * * @return the list of display generators */ - default <D extends Display> List<LiveDisplayGenerator<?>> getCategoryDisplayGenerators(CategoryIdentifier<D> categoryId) { + default <D extends Display> List<DynamicDisplayGenerator<?>> getCategoryDisplayGenerators(CategoryIdentifier<D> categoryId) { return getCategoryDisplayGenerators().getOrDefault(categoryId, Collections.emptyList()); } @@ -153,8 +175,8 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> { /** * Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}. * <p> - * Vanilla {@link net.minecraft.world.item.crafting.Recipe} are by default filled, display filters - * can be used to automatically generate displaies for vanilla {@link net.minecraft.world.item.crafting.Recipe}. + * 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 filler the filler, taking a {@code T} and returning a {@code D} @@ -168,8 +190,8 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> { /** * Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}. * <p> - * Vanilla {@link net.minecraft.world.item.crafting.Recipe} are by default filled, display filters - * can be used to automatically generate displaies for vanilla {@link net.minecraft.world.item.crafting.Recipe}. + * 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} diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/LiveDisplayGenerator.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DynamicDisplayGenerator.java index 04cfe3198..9c088e5e5 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/LiveDisplayGenerator.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DynamicDisplayGenerator.java @@ -24,13 +24,22 @@ package me.shedaniel.rei.api.client.registry.display; 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.EntryStack; import java.util.List; import java.util.Optional; -public interface LiveDisplayGenerator<T extends Display> { +/** + * Interface for generating dynamic displays at runtime. + * Invoked per display view search, so please keep this performant. + * + * @param <T> the type of displays to generate + * @see DisplayRegistry#registerDisplayGenerator(CategoryIdentifier, DynamicDisplayGenerator) + * @see DisplayRegistry#registerGlobalDisplayGenerator(DynamicDisplayGenerator) + */ +public interface DynamicDisplayGenerator<T extends Display> { default Optional<List<T>> getRecipeFor(EntryStack<?> entry) { return Optional.empty(); } diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java index d51449d65..6c439a43c 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java @@ -29,6 +29,9 @@ import me.shedaniel.rei.api.common.plugins.PluginManager; import me.shedaniel.rei.api.common.registry.Reloadable; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.core.NonNullList; +import net.minecraft.core.Registry; +import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; @@ -40,6 +43,21 @@ import java.util.function.LongPredicate; import java.util.function.Predicate; import java.util.stream.Stream; +/** + * Registry for registering {@link EntryStack} for display on the overlay entry list. + * + * <p>The default REI plugin iterates both {@link Registry#ITEM} and {@link Registry#FLUID} + * to register new entries. Other plugins may override this default behaviour, altering + * the entry list. + * + * <p>REI plugins should only add entries during reload, modifications outside the + * reload phase may not be reflected immediately. + * + * <p>While this registry can be used for registering variants of stacks, there may be + * native alternatives such as {@link Item#fillItemCategory(CreativeModeTab, NonNullList)}. + * + * @see REIClientPlugin#registerEntries(EntryRegistry) + */ @Environment(EnvType.CLIENT) public interface EntryRegistry extends Reloadable<REIClientPlugin> { /** diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/TransferHandler.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/TransferHandler.java index ef0559364..3c3ea6462 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/TransferHandler.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/TransferHandler.java @@ -301,5 +301,4 @@ public interface TransferHandler extends Comparable<TransferHandler> { return recipeDisplaySupplier.get(); } } - } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/display/DisplaySerializerRegistry.java b/api/src/main/java/me/shedaniel/rei/api/common/display/DisplaySerializerRegistry.java index e1d62beb7..a3cf6cc08 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/display/DisplaySerializerRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/display/DisplaySerializerRegistry.java @@ -31,8 +31,12 @@ import me.shedaniel.rei.api.common.transfer.info.MenuSerializationContext; import net.minecraft.nbt.CompoundTag; /** - * The display serializer used for display transfers. - * This is mostly a fallback system for {@link me.shedaniel.rei.api.common.transfer.info.MenuInfo#save(MenuSerializationContext, Display)}. + * The display serializer used for display serialization, useful for persistent displays across reloads, + * and server-client communication. + * + * <p>This is mostly a fallback system for {@link me.shedaniel.rei.api.common.transfer.info.MenuInfo#save(MenuSerializationContext, Display)}. + * + * @see REIPlugin#registerDisplaySerializer(DisplaySerializerRegistry) */ public interface DisplaySerializerRegistry extends Reloadable<REIPlugin<?>> { static DisplaySerializerRegistry getInstance() { diff --git a/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/FluidComparatorRegistry.java b/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/FluidComparatorRegistry.java index f8489ef2e..b49a051d1 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/FluidComparatorRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/FluidComparatorRegistry.java @@ -27,6 +27,11 @@ import me.shedaniel.architectury.fluid.FluidStack; import me.shedaniel.rei.api.common.plugins.PluginManager; import net.minecraft.world.level.material.Fluid; +/** + * {@inheritDoc} + * + * @see me.shedaniel.rei.api.common.plugins.REIPlugin#registerFluidComparators(FluidComparatorRegistry) + */ public interface FluidComparatorRegistry extends EntryComparatorRegistry<FluidStack, Fluid> { /** * @return the instance of {@link FluidComparatorRegistry} diff --git a/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ItemComparatorRegistry.java b/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ItemComparatorRegistry.java index 299eab648..fca219167 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ItemComparatorRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ItemComparatorRegistry.java @@ -27,6 +27,11 @@ import me.shedaniel.rei.api.common.plugins.PluginManager; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +/** + * {@inheritDoc} + * + * @see me.shedaniel.rei.api.common.plugins.REIPlugin#registerItemComparators(ItemComparatorRegistry) + */ public interface ItemComparatorRegistry extends EntryComparatorRegistry<ItemStack, Item> { /** * @return the instance of {@link ItemComparatorRegistry} 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 880f2ed1c..555149b8e 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 @@ -41,6 +41,7 @@ import java.util.Collection; * A definition of an {@link EntryType}, an interface to provide information from an object type. * * @param <T> the type of entry + * @see EntryTypeRegistry */ public interface EntryDefinition<T> { Class<T> getValueType(); diff --git a/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryTypeBridge.java b/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryTypeBridge.java index ae7674c23..7f81fc181 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryTypeBridge.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryTypeBridge.java @@ -28,8 +28,14 @@ import net.minecraft.world.InteractionResultHolder; import java.util.stream.Stream; +/** + * A bridge of two different entry types, for comparison and equality checks. + * + * @param <A> the original entry type + * @param <B> the destination entry type + * @see EntryTypeRegistry#registerBridge(EntryType, EntryType, EntryTypeBridge) + */ @FunctionalInterface public interface EntryTypeBridge<A, B> { - InteractionResultHolder<Stream<EntryStack<B>>> bridge(EntryStack<A> object); } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryTypeRegistry.java b/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryTypeRegistry.java index 9b62c3d5f..c376a2b88 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryTypeRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/entry/type/EntryTypeRegistry.java @@ -31,6 +31,21 @@ import org.jetbrains.annotations.Nullable; import java.util.Set; +/** + * Registry for registering alternative entry types. + * + * <p>{@link EntryType} must be declared statically, deferring to the actual + * definition by the identifier of the type. During reload, plugins should + * register {@link EntryDefinition} for their deferred {@link EntryType}, + * these definitions are dynamic. + * + * <p>{@link EntryTypeBridge} may be used to convert and compare between + * different types + * + * @see EntryDefinition + * @see #registerBridge(EntryType, EntryType, EntryTypeBridge) + * @see REIPlugin#registerEntryTypes(EntryTypeRegistry) + */ public interface EntryTypeRegistry extends Reloadable<REIPlugin<?>> { static EntryTypeRegistry getInstance() { return PluginManager.getInstance().get(EntryTypeRegistry.class); @@ -76,16 +91,26 @@ public interface EntryTypeRegistry extends Reloadable<REIPlugin<?>> { @Nullable EntryDefinition<?> get(ResourceLocation id); + /** + * Returns the set of types in their identifier form. + * + * @return the set of types + */ Set<ResourceLocation> keySet(); + /** + * Returns the set of entry definitions. + * + * @return the set of entry definitions + */ Set<EntryDefinition<?>> values(); /** * Register a bridge between two entry types, for example, item to fluid, this is used, to - * approximately match two entry stacks,. + * approximately match two entry stacks. * <p> * For bridging two entry types, only 1 one way bridge is required, two way bridges are discouraged - * for performance issues. + * for performance issues and possible recursion. * * @param original the original entry type * @param destination the destination entry type 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 31f5d4c2d..6459963bc 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 @@ -28,7 +28,7 @@ import me.shedaniel.rei.api.client.plugins.REIClientPlugin; 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.LiveDisplayGenerator; +import me.shedaniel.rei.api.client.registry.display.DynamicDisplayGenerator; 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; @@ -44,8 +44,8 @@ import java.util.function.Predicate; public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugin> implements DisplayRegistry { private final Map<CategoryIdentifier<?>, List<Display>> displays = new ConcurrentHashMap<>(); - private final Map<CategoryIdentifier<?>, List<LiveDisplayGenerator<?>>> displayGenerators = new ConcurrentHashMap<>(); - private final List<LiveDisplayGenerator<?>> globalDisplayGenerators = new ArrayList<>(); + private final Map<CategoryIdentifier<?>, List<DynamicDisplayGenerator<?>>> displayGenerators = new ConcurrentHashMap<>(); + private final List<DynamicDisplayGenerator<?>> globalDisplayGenerators = new ArrayList<>(); private final List<DisplayVisibilityPredicate> visibilityPredicates = new ArrayList<>(); private final List<DisplayFiller<?, ?>> fillers = new ArrayList<>(); private final MutableInt displayCount = new MutableInt(0); @@ -83,23 +83,23 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi } @Override - public <A extends Display> void registerGlobalDisplayGenerator(LiveDisplayGenerator<A> generator) { + public <A extends Display> void registerGlobalDisplayGenerator(DynamicDisplayGenerator<A> generator) { globalDisplayGenerators.add(generator); } @Override - public <A extends Display> void registerDisplayGenerator(CategoryIdentifier<A> categoryId, LiveDisplayGenerator<A> generator) { + public <A extends Display> void registerDisplayGenerator(CategoryIdentifier<A> categoryId, DynamicDisplayGenerator<A> generator) { displayGenerators.computeIfAbsent(categoryId, location -> new ArrayList<>()) .add(generator); } @Override - public Map<CategoryIdentifier<?>, List<LiveDisplayGenerator<?>>> getCategoryDisplayGenerators() { + public Map<CategoryIdentifier<?>, List<DynamicDisplayGenerator<?>>> getCategoryDisplayGenerators() { return Collections.unmodifiableMap(displayGenerators); } @Override - public List<LiveDisplayGenerator<?>> getGlobalDisplayGenerators() { + public List<DynamicDisplayGenerator<?>> getGlobalDisplayGenerators() { return Collections.unmodifiableList(globalDisplayGenerators); } 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 c53c75e1d..3a28e2283 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 @@ -31,7 +31,7 @@ import me.shedaniel.rei.api.client.config.ConfigObject; 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.LiveDisplayGenerator; +import me.shedaniel.rei.api.client.registry.display.DynamicDisplayGenerator; import me.shedaniel.rei.api.client.view.ViewSearchBuilder; import me.shedaniel.rei.api.client.view.Views; import me.shedaniel.rei.api.common.category.CategoryIdentifier; @@ -123,12 +123,12 @@ public class ViewsImpl implements Views { int generatorsCount = 0; - for (Map.Entry<CategoryIdentifier<?>, List<LiveDisplayGenerator<?>>> entry : DisplayRegistry.getInstance().getCategoryDisplayGenerators().entrySet()) { + for (Map.Entry<CategoryIdentifier<?>, List<DynamicDisplayGenerator<?>>> entry : DisplayRegistry.getInstance().getCategoryDisplayGenerators().entrySet()) { CategoryIdentifier<?> categoryId = entry.getKey(); Set<Display> set = new LinkedHashSet<>(); generatorsCount += entry.getValue().size(); - for (LiveDisplayGenerator<Display> generator : (List<LiveDisplayGenerator<Display>>) (List<? extends LiveDisplayGenerator<?>>) entry.getValue()) { + for (DynamicDisplayGenerator<Display> generator : (List<DynamicDisplayGenerator<Display>>) (List<? extends DynamicDisplayGenerator<?>>) entry.getValue()) { generateLiveDisplays(generator, builder, set::add); } @@ -140,7 +140,7 @@ public class ViewsImpl implements Views { Consumer<Display> displayConsumer = display -> { CollectionUtils.getOrPutEmptyList(result, CategoryRegistry.getInstance().get(display.getCategoryIdentifier()).getCategory()).add(display); }; - for (LiveDisplayGenerator<Display> generator : (List<LiveDisplayGenerator<Display>>) (List<? extends LiveDisplayGenerator<?>>) DisplayRegistry.getInstance().getGlobalDisplayGenerators()) { + for (DynamicDisplayGenerator<Display> generator : (List<DynamicDisplayGenerator<Display>>) (List<? extends DynamicDisplayGenerator<?>>) DisplayRegistry.getInstance().getGlobalDisplayGenerators()) { generatorsCount++; generateLiveDisplays(generator, builder, displayConsumer); } @@ -155,7 +155,7 @@ public class ViewsImpl implements Views { return result; } - private <T extends Display> void generateLiveDisplays(LiveDisplayGenerator<T> generator, ViewSearchBuilder builder, Consumer<T> displayConsumer) { + private <T extends Display> void generateLiveDisplays(DynamicDisplayGenerator<T> generator, ViewSearchBuilder builder, Consumer<T> displayConsumer) { for (EntryStack<?> stack : builder.getRecipesFor()) { Optional<List<T>> recipeForDisplays = generator.getRecipeFor(stack); if (recipeForDisplays.isPresent()) { |
