diff options
| author | shedaniel <daniel@shedaniel.me> | 2021-03-16 21:09:24 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2021-03-16 21:09:24 +0800 |
| commit | f5c23d37adb57c4428a8a58e4cc892a6b2e83c30 (patch) | |
| tree | e76cf50adb579adbc337de3fdbc3b63b00686469 | |
| parent | d60fd316cc872c8e2d6500f071598ebf79364d4a (diff) | |
| download | RoughlyEnoughItems-f5c23d37adb57c4428a8a58e4cc892a6b2e83c30.tar.gz RoughlyEnoughItems-f5c23d37adb57c4428a8a58e4cc892a6b2e83c30.tar.bz2 RoughlyEnoughItems-f5c23d37adb57c4428a8a58e4cc892a6b2e83c30.zip | |
Implement IIngredientFilter, IRecipeManagerPlugin and IGuiIngredientGroup#set, fix IDrawableBuilder with padding
Signed-off-by: shedaniel <daniel@shedaniel.me>
5 files changed, 124 insertions, 66 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/ButtonAreaSupplier.java b/api/src/main/java/me/shedaniel/rei/api/ButtonAreaSupplier.java index 65116400e..323b8d810 100644 --- a/api/src/main/java/me/shedaniel/rei/api/ButtonAreaSupplier.java +++ b/api/src/main/java/me/shedaniel/rei/api/ButtonAreaSupplier.java @@ -31,7 +31,7 @@ import me.shedaniel.math.Rectangle; @FunctionalInterface public interface ButtonAreaSupplier { static ButtonAreaSupplier defaultArea() { - return bounds -> new Rectangle(bounds.getMaxX() - 16, bounds.getMaxY() - 16, 10, 10); + return bounds -> new Rectangle(bounds.getMaxX() + 2, bounds.getMaxY() - 16, 10, 10); } /** diff --git a/api/src/main/java/me/shedaniel/rei/api/registry/display/DisplayRegistry.java b/api/src/main/java/me/shedaniel/rei/api/registry/display/DisplayRegistry.java index 9451eac96..4b970ebd5 100644 --- a/api/src/main/java/me/shedaniel/rei/api/registry/display/DisplayRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/registry/display/DisplayRegistry.java @@ -31,9 +31,8 @@ import me.shedaniel.rei.api.registry.Reloadable; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.Container; -import net.minecraft.world.item.crafting.Recipe; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; @@ -82,6 +81,13 @@ public interface DisplayRegistry extends RecipeManagerContext, Reloadable { } /** + * Registers a global category-less display generator + * + * @param generator the generator to register + */ + <A extends Display> void registerGlobalDisplayGenerator(LiveDisplayGenerator<A> generator); + + /** * Registers a display generator * * @param categoryId the identifier of the category @@ -94,15 +100,22 @@ public interface DisplayRegistry extends RecipeManagerContext, Reloadable { * * @return an unmodifiable map of display generators */ - Map<ResourceLocation, List<LiveDisplayGenerator<?>>> getAllDisplayGenerators(); + Map<ResourceLocation, List<LiveDisplayGenerator<?>>> getCategoryDisplayGenerators(); + + /** + * Returns an unmodifiable list of category-less display generators + * + * @return an unmodifiable list of category-less display generators + */ + List<LiveDisplayGenerator<?>> getGlobalDisplayGenerators(); /** * Returns the list of display generators for a category * * @return the list of display generators */ - default List<LiveDisplayGenerator<?>> getDisplayGenerators(ResourceLocation categoryId) { - return getAllDisplayGenerators().getOrDefault(categoryId, Collections.emptyList()); + default List<LiveDisplayGenerator<?>> getCategoryDisplayGenerators(ResourceLocation categoryId) { + return getCategoryDisplayGenerators().getOrDefault(categoryId, Collections.emptyList()); } /** @@ -137,9 +150,11 @@ public interface DisplayRegistry extends RecipeManagerContext, Reloadable { */ List<DisplayVisibilityPredicate> getVisibilityPredicates(); - default <A extends Container, T extends Recipe<A>, D extends Display> void registerRecipes(Class<T> recipeClass, Function<T, D> mappingFunction) { - registerRecipes(recipe -> recipeClass.isAssignableFrom(recipe.getClass()), mappingFunction); + default <T, D extends Display> void registerFiller(Class<T> typeClass, Function<T, D> mappingFunction) { + registerFiller(typeClass, typeClass::isInstance, mappingFunction); } - <A extends Container, T extends Recipe<A>, D extends Display> void registerRecipes(Predicate<? extends T> recipeFilter, Function<T, D> mappingFunction); + <T, D extends Display> void registerFiller(Class<T> typeClass, Predicate<? extends T> predicate, Function<T, D> mappingFunction); + + @Nullable <T> Display tryFillDisplay(T value); } diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java index 289ba480b..e41230c5d 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java @@ -236,7 +236,7 @@ public class DefaultPlugin implements REIPlugin, BuiltinPlugin { new DefaultPathingCategory(), new DefaultInformationCategory() ); - + registry.removePlusButton(FUEL); registry.removePlusButton(COMPOSTING); registry.removePlusButton(BEACON); @@ -245,7 +245,7 @@ public class DefaultPlugin implements REIPlugin, BuiltinPlugin { registry.removePlusButton(STRIPPING); registry.removePlusButton(TILLING); registry.removePlusButton(PATHING); - + registry.addWorkstations(CRAFTING, EntryStacks.of(Items.CRAFTING_TABLE)); registry.addWorkstations(SMELTING, EntryStacks.of(Items.FURNACE)); registry.addWorkstations(SMOKING, EntryStacks.of(Items.SMOKER)); @@ -294,14 +294,14 @@ public class DefaultPlugin implements REIPlugin, BuiltinPlugin { @Override public void registerDisplays(DisplayRegistry registry) { - registry.registerRecipes( ShapelessRecipe.class, DefaultShapelessDisplay::new); - registry.registerRecipes( ShapedRecipe.class, DefaultShapedDisplay::new); - registry.registerRecipes( SmeltingRecipe.class, DefaultSmeltingDisplay::new); - registry.registerRecipes( SmokingRecipe.class, DefaultSmokingDisplay::new); - registry.registerRecipes( BlastingRecipe.class, DefaultBlastingDisplay::new); - registry.registerRecipes( CampfireCookingRecipe.class, DefaultCampfireDisplay::new); - registry.registerRecipes( StonecutterRecipe.class, DefaultStoneCuttingDisplay::new); - registry.registerRecipes( UpgradeRecipe.class, DefaultSmithingDisplay::new); + registry.registerFiller(ShapelessRecipe.class, DefaultShapelessDisplay::new); + registry.registerFiller(ShapedRecipe.class, DefaultShapedDisplay::new); + registry.registerFiller(SmeltingRecipe.class, DefaultSmeltingDisplay::new); + registry.registerFiller(SmokingRecipe.class, DefaultSmokingDisplay::new); + registry.registerFiller(BlastingRecipe.class, DefaultBlastingDisplay::new); + registry.registerFiller(CampfireCookingRecipe.class, DefaultCampfireDisplay::new); + registry.registerFiller(StonecutterRecipe.class, DefaultStoneCuttingDisplay::new); + registry.registerFiller(UpgradeRecipe.class, DefaultSmithingDisplay::new); for (Map.Entry<Item, Integer> entry : AbstractFurnaceBlockEntity.getFuel().entrySet()) { registry.registerDisplay(new DefaultFuelDisplay(EntryIngredients.of(entry.getKey()), entry.getValue())); } @@ -421,7 +421,7 @@ public class DefaultPlugin implements REIPlugin, BuiltinPlugin { return AbstractContainerScreen.class; } }); - + registry.registerContainerClickArea(new Rectangle(88, 32, 28, 23), CraftingScreen.class, CRAFTING); registry.registerContainerClickArea(new Rectangle(137, 29, 10, 13), InventoryScreen.class, CRAFTING); registry.registerContainerClickArea(new Rectangle(97, 16, 14, 30), BrewingStandScreen.class, BREWING); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/registry/DisplayRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/registry/DisplayRegistryImpl.java index 421eeb527..5246d38f2 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/registry/DisplayRegistryImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/registry/DisplayRegistryImpl.java @@ -32,10 +32,10 @@ import me.shedaniel.rei.api.registry.display.Display; import me.shedaniel.rei.api.registry.display.DisplayCategory; import me.shedaniel.rei.api.registry.display.DisplayRegistry; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.Container; import net.minecraft.world.InteractionResult; 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; @@ -45,8 +45,9 @@ import java.util.function.Predicate; public class DisplayRegistryImpl extends RecipeManagerContextImpl implements DisplayRegistry { private final Map<ResourceLocation, List<Display>> displays = new ConcurrentHashMap<>(); private final Map<ResourceLocation, List<LiveDisplayGenerator<?>>> displayGenerators = new ConcurrentHashMap<>(); + private final List<LiveDisplayGenerator<?>> globalDisplayGenerators = new ArrayList<>(); private final List<DisplayVisibilityPredicate> visibilityPredicates = new ArrayList<>(); - private final List<RecipeFiller<?, ?, ?>> fillers = new ArrayList<>(); + private final List<DisplayFiller<?, ?>> fillers = new ArrayList<>(); private final MutableInt displayCount = new MutableInt(0); @Override @@ -78,17 +79,27 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl implements Dis } @Override + public <A extends Display> void registerGlobalDisplayGenerator(LiveDisplayGenerator<A> generator) { + globalDisplayGenerators.add(generator); + } + + @Override public <A extends Display> void registerDisplayGenerator(ResourceLocation categoryId, LiveDisplayGenerator<A> generator) { displayGenerators.computeIfAbsent(categoryId, location -> new ArrayList<>()) .add(generator); } @Override - public Map<ResourceLocation, List<LiveDisplayGenerator<?>>> getAllDisplayGenerators() { + public Map<ResourceLocation, List<LiveDisplayGenerator<?>>> getCategoryDisplayGenerators() { return Collections.unmodifiableMap(displayGenerators); } @Override + public List<LiveDisplayGenerator<?>> getGlobalDisplayGenerators() { + return Collections.unmodifiableList(globalDisplayGenerators); + } + + @Override public void registerVisibilityPredicate(DisplayVisibilityPredicate predicate) { visibilityPredicates.add(predicate); visibilityPredicates.sort(Comparator.reverseOrder()); @@ -117,8 +128,8 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl implements Dis } @Override - public <A extends Container, T extends Recipe<A>, D extends Display> void registerRecipes(Predicate<? extends T> recipeFilter, Function<T, D> mappingFunction) { - fillers.add(new RecipeFiller<>((Predicate<T>) recipeFilter, mappingFunction)); + public <T, D extends Display> void registerFiller(Class<T> typeClass, Predicate<? extends T> predicate, Function<T, D> mappingFunction) { + fillers.add(new DisplayFiller<>(typeClass, (Predicate<T>) predicate, mappingFunction)); } @Override @@ -137,33 +148,47 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl implements Dis List<Recipe<?>> allSortedRecipes = getAllSortedRecipes(); for (int i = allSortedRecipes.size() - 1; i >= 0; i--) { Recipe<?> recipe = allSortedRecipes.get(i); - for (RecipeFiller<?, ?, ?> filler : fillers) { - try { - handleRecipe(filler, recipe); - } catch (Throwable e) { - RoughlyEnoughItemsCore.LOGGER.error("Failed to fill recipes!", e); - } + Display display = tryFillDisplay(recipe); + if (display != null) { + registerDisplay(0, display); } } } - this.fillers.clear(); } - private <A extends Container, T extends Recipe<A>, D extends Display> void handleRecipe(RecipeFiller<A, T, D> filler, Recipe<?> recipe) { - if (filler.recipeFilter.test((T) recipe)) { - registerDisplay(0, filler.mappingFunction.apply((T) recipe)); + @Override + @Nullable + public <T> Display tryFillDisplay(T value) { + if (value instanceof Display) return (Display) value; + for (DisplayFiller<?, ?> filler : fillers) { + Display display = tryFillDisplayGenerics(filler, value); + if (display != null) return display; } + return null; } - private static class RecipeFiller<A extends Container, T extends Recipe<A>, D extends Display> { - private final Predicate<T> recipeFilter; + private <T, D extends Display> D tryFillDisplayGenerics(DisplayFiller<T, D> filler, Object value) { + try { + if (filler.typeClass.isInstance(value) && filler.predicate.test((T) value)) { + return filler.mappingFunction.apply((T) value); + } + } catch (Throwable e) { + RoughlyEnoughItemsCore.LOGGER.error("Failed to fill displays!", e); + } + + return null; + } + + private static class DisplayFiller<T, D extends Display> { + private final Class<T> typeClass; + private final Predicate<T> predicate; private final Function<T, D> mappingFunction; - public RecipeFiller(Predicate<T> recipeFilter, Function<T, D> mappingFunction) { - this.recipeFilter = recipeFilter; + public DisplayFiller(Class<T> typeClass, Predicate<T> predicate, Function<T, D> mappingFunction) { + this.typeClass = typeClass; + this.predicate = predicate; this.mappingFunction = mappingFunction; } - } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/view/ViewsImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/view/ViewsImpl.java index ad573abb9..55319da56 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/view/ViewsImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/view/ViewsImpl.java @@ -44,6 +44,7 @@ import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.ApiStatus; import java.util.*; +import java.util.function.Consumer; import java.util.stream.Collectors; @ApiStatus.Internal @@ -115,37 +116,13 @@ public class ViewsImpl implements Views { int generatorsCount = 0; - for (Map.Entry<ResourceLocation, List<LiveDisplayGenerator<?>>> entry : DisplayRegistry.getInstance().getAllDisplayGenerators().entrySet()) { + for (Map.Entry<ResourceLocation, List<LiveDisplayGenerator<?>>> entry : DisplayRegistry.getInstance().getCategoryDisplayGenerators().entrySet()) { ResourceLocation categoryId = entry.getKey(); Set<Display> set = new LinkedHashSet<>(); generatorsCount += entry.getValue().size(); for (LiveDisplayGenerator<Display> generator : (List<LiveDisplayGenerator<Display>>) (List) entry.getValue()) { - for (EntryStack<?> stack : recipesFor) { - Optional<List<Display>> recipeForDisplays = generator.getRecipeFor(stack); - if (recipeForDisplays.isPresent()) { - for (Display display : recipeForDisplays.get()) { - if (isDisplayVisible(display)) - set.add(display); - } - } - } - for (EntryStack<?> stack : usagesFor) { - Optional<List<Display>> usageForDisplays = generator.getUsageFor(stack); - if (usageForDisplays.isPresent()) { - for (Display display : usageForDisplays.get()) { - if (isDisplayVisible(display)) - set.add(display); - } - } - } - Optional<List<Display>> displaysGenerated = generator.generate(builder); - if (displaysGenerated.isPresent()) { - for (Display display : displaysGenerated.get()) { - if (isDisplayVisible(display)) - set.add(display); - } - } + generateLiveDisplays(generator, builder, set::add); } if (!set.isEmpty()) { @@ -153,6 +130,14 @@ 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) DisplayRegistry.getInstance().getGlobalDisplayGenerators()) { + generatorsCount++; + generateLiveDisplays(generator, builder, displayConsumer); + } + 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().toString(), categories.size(), recipesFor.size(), usagesFor.size(), generatorsCount); if (ConfigObject.getInstance().doDebugSearchTimeRequired()) { @@ -163,6 +148,39 @@ public class ViewsImpl implements Views { return result; } + private <T extends Display> void generateLiveDisplays(LiveDisplayGenerator<T> generator, ViewSearchBuilder builder, Consumer<T> displayConsumer) { + for (EntryStack<?> stack : builder.getRecipesFor()) { + Optional<List<T>> recipeForDisplays = generator.getRecipeFor(stack); + if (recipeForDisplays.isPresent()) { + for (T display : recipeForDisplays.get()) { + if (isDisplayVisible(display)) { + displayConsumer.accept(display); + } + } + } + } + + for (EntryStack<?> stack : builder.getUsagesFor()) { + Optional<List<T>> usageForDisplays = generator.getUsageFor(stack); + if (usageForDisplays.isPresent()) { + for (T display : usageForDisplays.get()) { + if (isDisplayVisible(display)) { + displayConsumer.accept(display); + } + } + } + } + + Optional<List<T>> displaysGenerated = generator.generate(builder); + if (displaysGenerated.isPresent()) { + for (T display : displaysGenerated.get()) { + if (isDisplayVisible(display)) { + displayConsumer.accept(display); + } + } + } + } + @Override public Collection<EntryStack<?>> findCraftableEntriesByItems(Iterable<? extends EntryStack<?>> inventoryItems) { Set<EntryStack<?>> craftables = new HashSet<>(); |
