From d2b4ef837faec468cd5d08f8a8df0ab5adc2b73f Mon Sep 17 00:00:00 2001 From: Xandaros Date: Sat, 22 Oct 2022 17:08:16 +0200 Subject: Only use LMB for dragging (#1153) --- .../shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'runtime/src/main/java') diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java index add5f947b..a354ffc96 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java @@ -154,6 +154,9 @@ public class CurrentDraggingStack extends Widget implements LateRenderable, Drag @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (button != 0) { + return false; + } drop(); DraggableComponent hoveredStack = provider.getHovered(this, mouseX, mouseY); if (hoveredStack != null) { @@ -169,7 +172,7 @@ public class CurrentDraggingStack extends Widget implements LateRenderable, Drag @Override public boolean mouseDragged(double mouseX1, double mouseY1, int button, double mouseX2, double mouseY2) { - return entry != null && entry.dragging; + return button == 0 && entry != null && entry.dragging; } private boolean drop() { -- cgit From 651e6f10ced5fc042f72fdbb1750b573c6e0a3f8 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Fri, 28 Oct 2022 20:03:11 +0800 Subject: Add filtering rules to the API (#1169) --- .../rei/RoughlyEnoughItemsCoreClient.java | 4 + .../rei/impl/client/config/ConfigManagerImpl.java | 18 ++- .../rei/impl/client/config/ConfigObjectImpl.java | 2 +- .../config/entries/FilteringAddRuleScreen.java | 23 +-- .../impl/client/config/entries/FilteringEntry.java | 2 +- .../config/entries/FilteringRuleOptionsScreen.java | 6 +- .../config/entries/FilteringRulesScreen.java | 21 +-- .../entry/filtering/AbstractFilteringRule.java | 40 ----- .../client/entry/filtering/FilteringCache.java | 31 ---- .../client/entry/filtering/FilteringCacheImpl.java | 44 ----- .../client/entry/filtering/FilteringContext.java | 47 ------ .../entry/filtering/FilteringContextImpl.java | 53 +++--- .../client/entry/filtering/FilteringResult.java | 93 ----------- .../entry/filtering/FilteringResultImpl.java | 27 +++- .../impl/client/entry/filtering/FilteringRule.java | 86 ---------- .../filtering/rules/BasicFilteringRuleImpl.java | 156 ++++++++++++++++++ .../filtering/rules/BasicFilteringRuleType.java | 63 ++++++++ .../rules/FilteringRuleTypeRegistryImpl.java | 87 ++++++++++ .../entry/filtering/rules/ManualFilteringRule.java | 45 ++---- .../filtering/rules/ManualFilteringRuleType.java | 63 ++++++++ .../entry/filtering/rules/SearchFilteringRule.java | 153 ++---------------- .../filtering/rules/SearchFilteringRuleType.java | 179 +++++++++++++++++++++ .../rei/impl/client/gui/widget/EntryWidget.java | 6 +- .../common/entry/type/PreFilteredEntryList.java | 22 +-- .../runtime/FilteredStacksVisibilityHandler.java | 20 ++- 25 files changed, 695 insertions(+), 596 deletions(-) delete mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/AbstractFilteringRule.java delete mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringCache.java delete mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringCacheImpl.java delete mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContext.java delete mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringResult.java delete mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringRule.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleImpl.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleType.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/FilteringRuleTypeRegistryImpl.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/ManualFilteringRuleType.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRuleType.java (limited to 'runtime/src/main/java') diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java index 0181a0267..ac3753e90 100644 --- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java +++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java @@ -35,6 +35,7 @@ import dev.architectury.networking.NetworkManager; import me.shedaniel.math.Point; import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigObject; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRuleTypeRegistry; import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer; import me.shedaniel.rei.api.client.favorites.FavoriteEntry; import me.shedaniel.rei.api.client.favorites.FavoriteEntryType; @@ -59,6 +60,7 @@ import me.shedaniel.rei.impl.ClientInternals; import me.shedaniel.rei.impl.client.REIRuntimeImpl; import me.shedaniel.rei.impl.client.config.ConfigManagerImpl; import me.shedaniel.rei.impl.client.config.addon.ConfigAddonRegistryImpl; +import me.shedaniel.rei.impl.client.entry.filtering.rules.FilteringRuleTypeRegistryImpl; import me.shedaniel.rei.impl.client.entry.renderer.EntryRendererRegistryImpl; import me.shedaniel.rei.impl.client.favorites.DelegatingFavoriteEntryProviderImpl; import me.shedaniel.rei.impl.client.favorites.FavoriteEntryTypeRegistryImpl; @@ -204,6 +206,7 @@ public class RoughlyEnoughItemsCoreClient { return categories.stream(); } }, "clickAreaHandlerResult"); + ClientInternals.attachInstanceSupplier(new FilteringRuleTypeRegistryImpl(), "filteringRuleTypeRegistry"); ClientInternals.attachInstanceSupplier(new PluginManagerImpl<>( REIClientPlugin.class, view -> view.then(PluginView.getInstance()), @@ -214,6 +217,7 @@ public class RoughlyEnoughItemsCoreClient { new ConfigManagerImpl(), new EntryRegistryImpl(), new CollapsibleEntryRegistryImpl(), + FilteringRuleTypeRegistry.getInstance().basic(), new CategoryRegistryImpl(), new DisplayRegistryImpl(), new ScreenRegistryImpl(), diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java index 2a1e99012..7ca73d683 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java @@ -46,11 +46,13 @@ import me.shedaniel.clothconfig2.gui.AbstractConfigScreen; import me.shedaniel.clothconfig2.gui.GlobalizedClothConfigScreen; import me.shedaniel.clothconfig2.gui.entries.KeyCodeEntry; import me.shedaniel.clothconfig2.gui.entries.TextListEntry; -import me.shedaniel.rei.RoughlyEnoughItemsCore; import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigManager; import me.shedaniel.rei.api.client.config.addon.ConfigAddonRegistry; import me.shedaniel.rei.api.client.config.entry.EntryStackProvider; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRule; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRuleType; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRuleTypeRegistry; import me.shedaniel.rei.api.client.favorites.FavoriteEntry; import me.shedaniel.rei.api.client.gui.config.CheatingMode; import me.shedaniel.rei.api.client.gui.config.DisplayScreenType; @@ -63,8 +65,6 @@ import me.shedaniel.rei.api.common.util.ImmutableTextComponent; import me.shedaniel.rei.impl.client.REIRuntimeImpl; import me.shedaniel.rei.impl.client.config.addon.ConfigAddonRegistryImpl; import me.shedaniel.rei.impl.client.config.entries.*; -import me.shedaniel.rei.impl.client.entry.filtering.FilteringRule; -import me.shedaniel.rei.impl.client.entry.filtering.rules.ManualFilteringRule; import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl; import me.shedaniel.rei.impl.client.gui.credits.CreditsScreen; import me.shedaniel.rei.impl.client.gui.performance.entry.PerformanceEntry; @@ -235,7 +235,7 @@ public class ConfigManagerImpl implements ConfigManager { // FilteringRule builder.registerSerializer(FilteringRule.class, (value, marshaller) -> { try { - return marshaller.serialize(FilteringRule.save(value, new CompoundTag())); + return marshaller.serialize(FilteringRuleType.save(value, new CompoundTag())); } catch (Exception e) { e.printStackTrace(); return JsonNull.INSTANCE; @@ -243,7 +243,7 @@ public class ConfigManagerImpl implements ConfigManager { }); builder.registerDeserializer(Tag.class, FilteringRule.class, (value, marshaller) -> { try { - return FilteringRule.read((CompoundTag) value); + return FilteringRuleType.read((CompoundTag) value); } catch (Exception e) { e.printStackTrace(); return null; @@ -251,7 +251,7 @@ public class ConfigManagerImpl implements ConfigManager { }); builder.registerDeserializer(String.class, FilteringRule.class, (value, marshaller) -> { try { - return FilteringRule.read(TagParser.parseTag(value)); + return FilteringRuleType.read(TagParser.parseTag(value)); } catch (Exception e) { e.printStackTrace(); return null; @@ -293,8 +293,10 @@ public class ConfigManagerImpl implements ConfigManager { @Override public void saveConfig() { - if (getConfig().getFilteringRules().stream().noneMatch(filteringRule -> filteringRule instanceof ManualFilteringRule)) { - getConfig().getFilteringRules().add(new ManualFilteringRule()); + for (FilteringRuleType type : FilteringRuleTypeRegistry.getInstance()) { + if (type.isSingular() && getConfig().getFilteringRules().stream().noneMatch(filteringRule -> filteringRule.getType().equals(type))) { + getConfig().getFilteringRules().add(type.createNew()); + } } AutoConfig.getConfigHolder(ConfigObjectImpl.class).registerLoadListener((configHolder, configObject) -> { object = configObject; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java index 33c6e0490..7fc03b5a5 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java @@ -33,9 +33,9 @@ import me.shedaniel.clothconfig2.api.Modifier; import me.shedaniel.clothconfig2.api.ModifierKeyCode; import me.shedaniel.rei.api.client.config.ConfigObject; import me.shedaniel.rei.api.client.config.entry.EntryStackProvider; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRule; import me.shedaniel.rei.api.client.favorites.FavoriteEntry; import me.shedaniel.rei.api.client.gui.config.*; -import me.shedaniel.rei.impl.client.entry.filtering.FilteringRule; import me.shedaniel.rei.impl.client.gui.widget.favorites.FavoritesEntriesManager; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringAddRuleScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringAddRuleScreen.java index 61f16508f..e1cbe7da6 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringAddRuleScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringAddRuleScreen.java @@ -25,8 +25,9 @@ package me.shedaniel.rei.impl.client.config.entries; import com.mojang.blaze3d.vertex.PoseStack; import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget; -import me.shedaniel.rei.impl.client.entry.filtering.FilteringRule; -import me.shedaniel.rei.impl.client.entry.filtering.rules.ManualFilteringRule; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRule; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRuleType; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRuleTypeRegistry; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.events.GuiEventListener; @@ -42,7 +43,7 @@ import net.minecraft.resources.ResourceLocation; import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.function.BiFunction; +import java.util.function.Function; public class FilteringAddRuleScreen extends Screen { private final FilteringEntry entry; @@ -65,8 +66,8 @@ public class FilteringAddRuleScreen extends Screen { })); } rulesList = addWidget(new RulesList(minecraft, width, height, 30, height, BACKGROUND_LOCATION)); - for (FilteringRule rule : FilteringRule.REGISTRY.values()) { - if (!(rule instanceof ManualFilteringRule)) + for (FilteringRuleType rule : FilteringRuleTypeRegistry.getInstance()) { + if (!rule.isSingular()) rulesList.addItem(new DefaultRuleEntry(parent, entry, rule.createNew(), null)); } rulesList.selectItem(rulesList.children().get(0)); @@ -147,14 +148,14 @@ public class FilteringAddRuleScreen extends Screen { public static class DefaultRuleEntry extends RuleEntry { private final Button addButton; - private final BiFunction screenFunction; + private final Function screenFunction; - public DefaultRuleEntry(Screen parent, FilteringEntry entry, FilteringRule rule, BiFunction screenFunction) { + public DefaultRuleEntry(Screen parent, FilteringEntry entry, FilteringRule rule, Function screenFunction) { super(rule); - this.screenFunction = (screenFunction == null ? rule.createEntryScreen().orElse(null) : screenFunction); + this.screenFunction = (screenFunction == null ? ((FilteringRuleType>) rule.getType()).createEntryScreen(rule) : screenFunction); addButton = new Button(0, 0, 20, 20, Component.nullToEmpty(" + "), button -> { entry.edited = true; - Minecraft.getInstance().setScreen(this.screenFunction.apply(entry, parent)); + Minecraft.getInstance().setScreen(this.screenFunction.apply(parent)); entry.rules.add(0, rule); }); addButton.active = this.screenFunction != null; @@ -164,7 +165,7 @@ public class FilteringAddRuleScreen extends Screen { public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) { Minecraft client = Minecraft.getInstance(); { - Component title = getRule().getTitle(); + Component title = ((FilteringRuleType>) getRule().getType()).getTitle(getRule()); int i = client.font.width(title); if (i > entryWidth - 28) { FormattedText titleTrimmed = FormattedText.composite(client.font.substrByWidth(title, entryWidth - 28 - client.font.width("...")), FormattedText.of("...")); @@ -174,7 +175,7 @@ public class FilteringAddRuleScreen extends Screen { } } { - Component subtitle = getRule().getSubtitle(); + Component subtitle = ((FilteringRuleType>) getRule().getType()).getSubtitle(getRule()); int i = client.font.width(subtitle); if (i > entryWidth - 28) { FormattedText subtitleTrimmed = FormattedText.composite(client.font.substrByWidth(subtitle, entryWidth - 28 - client.font.width("...")), FormattedText.of("...")); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringEntry.java index 403f1e94d..c8d75ed77 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringEntry.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringEntry.java @@ -28,9 +28,9 @@ import com.google.common.collect.Lists; import com.mojang.blaze3d.platform.Window; import com.mojang.blaze3d.vertex.PoseStack; import me.shedaniel.clothconfig2.api.AbstractConfigListEntry; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRule; import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.api.common.util.EntryStacks; -import me.shedaniel.rei.impl.client.entry.filtering.FilteringRule; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.chat.NarratorChatListener; import net.minecraft.client.gui.components.AbstractWidget; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRuleOptionsScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRuleOptionsScreen.java index fac731ecf..0f69cdaa3 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRuleOptionsScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRuleOptionsScreen.java @@ -29,7 +29,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget; import me.shedaniel.math.Rectangle; -import me.shedaniel.rei.impl.client.entry.filtering.FilteringRule; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRule; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.EditBox; @@ -53,14 +53,12 @@ import java.util.function.Function; import java.util.function.Supplier; public abstract class FilteringRuleOptionsScreen> extends Screen { - private final FilteringEntry entry; private RulesList rulesList; Screen parent; public T rule; - public FilteringRuleOptionsScreen(FilteringEntry entry, T rule, Screen screen) { + public FilteringRuleOptionsScreen(T rule, Screen screen) { super(new TranslatableComponent("config.roughlyenoughitems.filteringRulesScreen")); - this.entry = entry; this.rule = rule; this.parent = screen; } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java index 0ed9f7129..2c60930bf 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java @@ -26,7 +26,8 @@ package me.shedaniel.rei.impl.client.config.entries; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget; -import me.shedaniel.rei.impl.client.entry.filtering.FilteringRule; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRule; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRuleType; import me.shedaniel.rei.impl.client.entry.filtering.rules.ManualFilteringRule; import me.shedaniel.rei.impl.client.gui.InternalTextures; import net.minecraft.client.Minecraft; @@ -46,7 +47,7 @@ import net.minecraft.sounds.SoundEvents; import java.util.Arrays; import java.util.List; import java.util.Objects; -import java.util.function.BiFunction; +import java.util.function.Function; public class FilteringRulesScreen extends Screen { private final FilteringEntry entry; @@ -80,7 +81,7 @@ public class FilteringRulesScreen extends Screen { for (int i = entry.rules.size() - 1; i >= 0; i--) { FilteringRule rule = entry.rules.get(i); if (rule instanceof ManualFilteringRule) - rulesList.addItem(new DefaultRuleEntry(rule, entry, (entry, screen) -> { + rulesList.addItem(new DefaultRuleEntry(rule, entry, (screen) -> { entry.filteringScreen.parent = screen; return entry.filteringScreen; })); @@ -180,14 +181,14 @@ public class FilteringRulesScreen extends Screen { public static class DefaultRuleEntry extends RuleEntry { private final Button configureButton; private final Button deleteButton; - private final BiFunction screenFunction; + private final Function screenFunction; - public DefaultRuleEntry(FilteringRule rule, FilteringEntry entry, BiFunction screenFunction) { + public DefaultRuleEntry(FilteringRule rule, FilteringEntry entry, Function screenFunction) { super(rule); - this.screenFunction = (screenFunction == null ? rule.createEntryScreen().orElse(null) : screenFunction); + this.screenFunction = (screenFunction == null ? ((FilteringRuleType>) rule.getType()).createEntryScreen(rule) : screenFunction); configureButton = new Button(0, 0, 20, 20, Component.nullToEmpty(null), button -> { entry.edited = true; - Minecraft.getInstance().setScreen(this.screenFunction.apply(entry, Minecraft.getInstance().screen)); + Minecraft.getInstance().setScreen(this.screenFunction.apply(Minecraft.getInstance().screen)); }) { @Override protected void renderBg(PoseStack matrices, Minecraft client, int mouseX, int mouseY) { @@ -206,14 +207,14 @@ public class FilteringRulesScreen extends Screen { }); } configureButton.active = this.screenFunction != null; - deleteButton.active = !(rule instanceof ManualFilteringRule); + deleteButton.active = !rule.getType().isSingular(); } @Override public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) { Minecraft client = Minecraft.getInstance(); { - Component title = getRule().getTitle(); + Component title = ((FilteringRuleType>) getRule().getType()).getTitle(getRule()); int i = client.font.width(title); if (i > entryWidth - 28) { FormattedText titleTrimmed = FormattedText.composite(client.font.substrByWidth(title, entryWidth - 28 - client.font.width("...")), FormattedText.of("...")); @@ -223,7 +224,7 @@ public class FilteringRulesScreen extends Screen { } } { - Component subtitle = getRule().getSubtitle(); + Component subtitle = ((FilteringRuleType>) getRule().getType()).getSubtitle(getRule()); int i = client.font.width(subtitle); if (i > entryWidth - 28) { FormattedText subtitleTrimmed = FormattedText.composite(client.font.substrByWidth(subtitle, entryWidth - 28 - client.font.width("...")), FormattedText.of("...")); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/AbstractFilteringRule.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/AbstractFilteringRule.java deleted file mode 100644 index 4ab670fbc..000000000 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/AbstractFilteringRule.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is licensed under the MIT License, part of Roughly Enough Items. - * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package me.shedaniel.rei.impl.client.entry.filtering; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; - -@Environment(EnvType.CLIENT) -public abstract class AbstractFilteringRule> implements FilteringRule { - @Override - public boolean equals(Object obj) { - return getClass() == obj.getClass(); - } - - @Override - public int hashCode() { - return getClass().hashCode(); - } -} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringCache.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringCache.java deleted file mode 100644 index 388652210..000000000 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringCache.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is licensed under the MIT License, part of Roughly Enough Items. - * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package me.shedaniel.rei.impl.client.entry.filtering; - -import org.jetbrains.annotations.Nullable; - -public interface FilteringCache { - @Nullable - Object getCache(FilteringRule rule); -} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringCacheImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringCacheImpl.java deleted file mode 100644 index 6befc1b5d..000000000 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringCacheImpl.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is licensed under the MIT License, part of Roughly Enough Items. - * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package me.shedaniel.rei.impl.client.entry.filtering; - -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -public class FilteringCacheImpl implements FilteringCache { - private final Map, Optional> CACHE = new HashMap<>(); - - @Override - @Nullable - public Object getCache(FilteringRule rule) { - return CACHE.getOrDefault(rule, Optional.empty()).orElse(null); - } - - public void setCache(FilteringRule rule, @Nullable Object value) { - CACHE.put(rule, Optional.ofNullable(value)); - } -} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContext.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContext.java deleted file mode 100644 index 59b2ce647..000000000 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContext.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is licensed under the MIT License, part of Roughly Enough Items. - * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package me.shedaniel.rei.impl.client.entry.filtering; - -import me.shedaniel.rei.api.common.entry.EntryStack; -import org.jetbrains.annotations.ApiStatus; - -import java.util.Collection; - -@ApiStatus.Internal -@ApiStatus.Experimental -public interface FilteringContext { - Collection> getStacks(FilteringContextType type); - - default Collection> getShownStacks() { - return getStacks(FilteringContextType.SHOWN); - } - - default Collection> getUnsetStacks() { - return getStacks(FilteringContextType.DEFAULT); - } - - default Collection> getHiddenStacks() { - return getStacks(FilteringContextType.HIDDEN); - } -} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java index e46f8660b..d0e26a9fc 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java @@ -23,19 +23,18 @@ package me.shedaniel.rei.impl.client.entry.filtering; +import com.google.common.collect.Iterators; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import me.shedaniel.rei.api.client.entry.filtering.FilteringContext; import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.api.common.util.CollectionUtils; import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -45,7 +44,6 @@ import java.util.concurrent.TimeoutException; public class FilteringContextImpl implements FilteringContext { private final boolean async; public final Map> stacks; - private final Map>> cachedStacks; public FilteringContextImpl(Collection> allStacks) { this(true, allStacks); @@ -54,40 +52,55 @@ public class FilteringContextImpl implements FilteringContext { public FilteringContextImpl(boolean async, Collection> allStacks) { this.async = async; this.stacks = Maps.newHashMap(); - this.cachedStacks = Maps.newHashMap(); for (FilteringContextType type : FilteringContextType.values()) { this.stacks.computeIfAbsent(type, t -> Sets.newHashSet()); } this.stacks.get(FilteringContextType.DEFAULT).addAll(async ? CollectionUtils.mapParallel(allStacks, HashedEntryStackWrapper::new) : CollectionUtils.map(allStacks, HashedEntryStackWrapper::new)); - fillCache(); } public FilteringContextImpl(Map> stacks) { this.async = false; this.stacks = stacks; - this.cachedStacks = Maps.newHashMap(); for (FilteringContextType type : FilteringContextType.values()) { this.stacks.computeIfAbsent(type, t -> Sets.newHashSet()); } - fillCache(); } - private void fillCache() { - this.cachedStacks.clear(); - for (FilteringContextType type : FilteringContextType.values()) { - this.cachedStacks.put(type, CollectionUtils.map(stacks.get(type), HashedEntryStackWrapper::unwrap)); - } + @Override + public Collection> getHiddenStacks() { + return getPublicFacing(FilteringContextType.HIDDEN); + } + + @Override + public Collection> getShownStacks() { + return getPublicFacing(FilteringContextType.SHOWN); } @Override - public Collection> getStacks(FilteringContextType type) { - return cachedStacks.get(type); + public Collection> getUnsetStacks() { + return getPublicFacing(FilteringContextType.DEFAULT); } - public void handleResult(FilteringResult result) { - Collection hiddenStacks = result.getHiddenStacks(); - Collection shownStacks = result.getShownStacks(); + private Collection> getPublicFacing(FilteringContextType type) { + Set wrappers = this.stacks.get(type); + if (wrappers == null || wrappers.isEmpty()) return List.of(); + return new AbstractSet<>() { + @Override + public Iterator> iterator() { + return Iterators.transform(wrappers.iterator(), HashedEntryStackWrapper::unwrap); + } + + @Override + public int size() { + return wrappers.size(); + } + }; + } + + public void handleResult(FilteringResultImpl result) { + Collection hiddenStacks = result.hiddenStacks; + Collection shownStacks = result.shownStacks; if (async) { List> completableFutures = Lists.newArrayList(); @@ -116,7 +129,5 @@ public class FilteringContextImpl implements FilteringContext { this.stacks.get(FilteringContextType.HIDDEN).addAll(hiddenStacks); this.stacks.get(FilteringContextType.HIDDEN).removeAll(shownStacks); } - - fillCache(); } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringResult.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringResult.java deleted file mode 100644 index 55fb39f01..000000000 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringResult.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is licensed under the MIT License, part of Roughly Enough Items. - * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package me.shedaniel.rei.impl.client.entry.filtering; - -import com.google.common.collect.Lists; -import me.shedaniel.rei.api.common.entry.EntryStack; -import me.shedaniel.rei.api.common.util.CollectionUtils; -import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import org.jetbrains.annotations.ApiStatus; - -import java.util.Collection; -import java.util.List; -import java.util.Set; - -@Environment(EnvType.CLIENT) -@ApiStatus.Internal -@ApiStatus.Experimental -public interface FilteringResult { - static FilteringResult create() { - return create(Lists.newArrayList(), Lists.newArrayList()); - } - - static FilteringResult create(List> hiddenStacks, List> shownStacks) { - return new FilteringResultImpl(hiddenStacks, shownStacks); - } - - Set getHiddenStacks(); - - Set getShownStacks(); - - default FilteringResult hide(EntryStack stack) { - getHiddenStacks().add(new HashedEntryStackWrapper(stack)); - return this; - } - - default FilteringResult hide(Collection> stacks) { - getHiddenStacks().addAll(CollectionUtils.map(stacks, HashedEntryStackWrapper::new)); - return this; - } - - default FilteringResult show(EntryStack stack) { - getShownStacks().add(new HashedEntryStackWrapper(stack)); - return this; - } - - default FilteringResult show(Collection> stacks) { - getShownStacks().addAll(CollectionUtils.map(stacks, HashedEntryStackWrapper::new)); - return this; - } - - default FilteringResult hideW(HashedEntryStackWrapper stack) { - getHiddenStacks().add(stack); - return this; - } - - default FilteringResult hideW(Collection stacks) { - getHiddenStacks().addAll(stacks); - return this; - } - - default FilteringResult showW(HashedEntryStackWrapper stack) { - getShownStacks().add(stack); - return this; - } - - default FilteringResult showW(Collection stacks) { - getShownStacks().addAll(stacks); - return this; - } -} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringResultImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringResultImpl.java index e1fb6ef9c..8f2768079 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringResultImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringResultImpl.java @@ -24,17 +24,20 @@ package me.shedaniel.rei.impl.client.entry.filtering; import com.google.common.collect.Sets; +import me.shedaniel.rei.api.client.entry.filtering.FilteringResult; import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.CollectionUtils; import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import java.util.Collection; import java.util.List; import java.util.Set; @Environment(EnvType.CLIENT) public class FilteringResultImpl implements FilteringResult { - private final Set hiddenStacks, shownStacks; + public final Set hiddenStacks, shownStacks; public FilteringResultImpl(List> hiddenStacks, List> shownStacks) { this.hiddenStacks = Sets.newHashSetWithExpectedSize(hiddenStacks.size()); @@ -44,12 +47,26 @@ public class FilteringResultImpl implements FilteringResult { } @Override - public Set getHiddenStacks() { - return hiddenStacks; + public FilteringResult hide(EntryStack stack) { + this.hiddenStacks.add(new HashedEntryStackWrapper(stack)); + return this; } @Override - public Set getShownStacks() { - return shownStacks; + public FilteringResult hide(Collection> stacks) { + this.hiddenStacks.addAll(CollectionUtils.map(stacks, HashedEntryStackWrapper::new)); + return this; + } + + @Override + public FilteringResult show(EntryStack stack) { + this.shownStacks.add(new HashedEntryStackWrapper(stack)); + return this; + } + + @Override + public FilteringResult show(Collection> stacks) { + this.shownStacks.addAll(CollectionUtils.map(stacks, HashedEntryStackWrapper::new)); + return this; } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringRule.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringRule.java deleted file mode 100644 index e18d2e4ea..000000000 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringRule.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * This file is licensed under the MIT License, part of Roughly Enough Items. - * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package me.shedaniel.rei.impl.client.entry.filtering; - -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import me.shedaniel.rei.impl.client.config.entries.FilteringEntry; -import me.shedaniel.rei.impl.client.entry.filtering.rules.ManualFilteringRule; -import me.shedaniel.rei.impl.client.entry.filtering.rules.SearchFilteringRule; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.Util; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import org.jetbrains.annotations.ApiStatus; - -import java.util.Optional; -import java.util.function.BiFunction; - -@ApiStatus.Internal -@ApiStatus.Experimental -@Environment(EnvType.CLIENT) -public interface FilteringRule> { - BiMap> REGISTRY = Util.make(HashBiMap.create(), registry -> { - registry.put(new ResourceLocation("roughlyenoughitems", "search"), new SearchFilteringRule()); - registry.put(new ResourceLocation("roughlyenoughitems", "manual"), new ManualFilteringRule()); - }); - - static CompoundTag save(FilteringRule rule, CompoundTag tag) { - tag.putString("id", REGISTRY.inverse().get(rule).toString()); - tag.put("rule", rule.save(new CompoundTag())); - return tag; - } - - static FilteringRule read(CompoundTag tag) { - return REGISTRY.get(ResourceLocation.tryParse(tag.getString("id"))).createFromTag(tag.getCompound("rule")); - } - - CompoundTag save(CompoundTag tag); - - T createFromTag(CompoundTag tag); - - FilteringResult processFilteredStacks(FilteringContext context, FilteringCache cache, boolean async); - - @ApiStatus.Internal - default Optional> createEntryScreen() { - return Optional.empty(); - } - - default Component getTitle() { - return Component.nullToEmpty(FilteringRule.REGISTRY.inverse().get(this).toString()); - } - - default Component getSubtitle() { - return Component.nullToEmpty(null); - } - - default Object prepareCache(boolean async) { - return null; - } - - T createNew(); -} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleImpl.java new file mode 100644 index 000000000..a1a8b7558 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleImpl.java @@ -0,0 +1,156 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.impl.client.entry.filtering.rules; + +import com.google.common.collect.Lists; +import com.mojang.datafixers.util.Pair; +import it.unimi.dsi.fastutil.longs.LongOpenHashSet; +import it.unimi.dsi.fastutil.longs.LongSet; +import me.shedaniel.rei.api.client.entry.filtering.*; +import me.shedaniel.rei.api.client.entry.filtering.base.BasicFilteringRule; +import me.shedaniel.rei.api.client.plugins.REIClientPlugin; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.registry.ReloadStage; +import me.shedaniel.rei.api.common.util.CollectionUtils; +import me.shedaniel.rei.api.common.util.EntryStacks; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; + +public enum BasicFilteringRuleImpl implements BasicFilteringRule> { + INSTANCE; + private final List> hidden = new ArrayList<>(), shown = new ArrayList<>(); + + @Override + public FilteringRuleType>> getType() { + return BasicFilteringRuleType.INSTANCE; + } + + @Override + public Pair prepareCache(boolean async) { + return new Pair<>(prepareCacheFor(hidden, async), prepareCacheFor(shown, async)); + } + + @NotNull + private static LongSet prepareCacheFor(List> stacks, boolean async) { + if (async) { + LongSet all = new LongOpenHashSet(); + List> completableFutures = Lists.newArrayList(); + for (Iterable> partitionStacks : CollectionUtils.partition(stacks, 100)) { + completableFutures.add(CompletableFuture.supplyAsync(() -> { + LongSet output = new LongOpenHashSet(); + for (EntryStack stack : partitionStacks) { + if (stack != null && !stack.isEmpty()) { + output.add(EntryStacks.hashExact(stack)); + } + } + return output; + })); + } + try { + CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).get(5, TimeUnit.MINUTES); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + e.printStackTrace(); + } + for (CompletableFuture future : completableFutures) { + LongSet now = future.getNow(null); + if (now != null) { + all.addAll(now); + } + } + return all; + } else { + return stacks.stream().map(EntryStacks::hashExact).collect(Collectors.toCollection(LongOpenHashSet::new)); + } + } + + @Override + public FilteringResult processFilteredStacks(FilteringContext context, FilteringResultFactory resultFactory, Pair cache, boolean async) { + FilteringResult result = resultFactory.create(); + hideList(context.getShownStacks(), result, async, cache.getFirst()); + hideList(context.getUnsetStacks(), result, async, cache.getFirst()); + showList(context.getHiddenStacks(), result, async, cache.getSecond()); + showList(context.getUnsetStacks(), result, async, cache.getSecond()); + return result; + } + + private void hideList(Collection> stacks, FilteringResult result, boolean async, LongSet filteredStacks) { + result.hide((async ? stacks.parallelStream() : stacks.stream()).filter(stack -> filteredStacks.contains(EntryStacks.hashExact(stack))).collect(Collectors.toList())); + } + + private void showList(Collection> stacks, FilteringResult result, boolean async, LongSet filteredStacks) { + result.show((async ? stacks.parallelStream() : stacks.stream()).filter(stack -> filteredStacks.contains(EntryStacks.hashExact(stack))).collect(Collectors.toList())); + } + + @Override + public FilteringResult hide(EntryStack stack) { + hidden.add(stack); + shown.remove(stack); + return this; + } + + @Override + public FilteringResult hide(Collection> stacks) { + hidden.addAll(stacks); + shown.removeAll(stacks); + return this; + } + + @Override + public FilteringResult show(EntryStack stack) { + shown.add(stack); + hidden.remove(stack); + return this; + } + + @Override + public FilteringResult show(Collection> stacks) { + shown.addAll(stacks); + hidden.removeAll(stacks); + return this; + } + + @Override + public ReloadStage getStage() { + return ReloadStage.START; + } + + @Override + public void startReload() { + hidden.clear(); + shown.clear(); + } + + @Override + public void acceptPlugin(REIClientPlugin plugin) { + plugin.registerBasicEntryFiltering(this); + } +} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleType.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleType.java new file mode 100644 index 000000000..8f4e4b74e --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleType.java @@ -0,0 +1,63 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.impl.client.entry.filtering.rules; + +import me.shedaniel.rei.api.client.entry.filtering.FilteringRuleType; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TranslatableComponent; + +public enum BasicFilteringRuleType implements FilteringRuleType { + INSTANCE; + + @Override + public CompoundTag saveTo(BasicFilteringRuleImpl rule, CompoundTag tag) { + return tag; + } + + @Override + public BasicFilteringRuleImpl readFrom(CompoundTag tag) { + return BasicFilteringRuleImpl.INSTANCE; + } + + @Override + public Component getTitle(BasicFilteringRuleImpl rule) { + return new TranslatableComponent("rule.roughlyenoughitems.filtering.basic"); + } + + @Override + public Component getSubtitle(BasicFilteringRuleImpl rule) { + return new TranslatableComponent("rule.roughlyenoughitems.filtering.basic.subtitle"); + } + + @Override + public BasicFilteringRuleImpl createNew() { + return BasicFilteringRuleImpl.INSTANCE; + } + + @Override + public boolean isSingular() { + return true; + } +} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/FilteringRuleTypeRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/FilteringRuleTypeRegistryImpl.java new file mode 100644 index 000000000..93af294c6 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/FilteringRuleTypeRegistryImpl.java @@ -0,0 +1,87 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.impl.client.entry.filtering.rules; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.google.common.collect.Iterators; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRuleType; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRuleTypeRegistry; +import me.shedaniel.rei.api.client.entry.filtering.base.BasicFilteringRule; +import me.shedaniel.rei.impl.common.InternalLogger; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import java.util.AbstractList; +import java.util.Iterator; + +@ApiStatus.Internal +public class FilteringRuleTypeRegistryImpl extends AbstractList> implements FilteringRuleTypeRegistry { + private final BiMap> types = HashBiMap.create(); + + public FilteringRuleTypeRegistryImpl() { + register(new ResourceLocation("roughlyenoughitems", "search"), SearchFilteringRuleType.INSTANCE); + register(new ResourceLocation("roughlyenoughitems", "manual"), ManualFilteringRuleType.INSTANCE); + register(new ResourceLocation("roughlyenoughitems", "basic"), BasicFilteringRuleType.INSTANCE); + } + + @Override + public Iterator> iterator() { + return types.values().iterator(); + } + + @Override + public FilteringRuleType get(int index) { + return Iterators.get(iterator(), index); + } + + @Override + public int size() { + return types.size(); + } + + @Override + @Nullable + public FilteringRuleType get(ResourceLocation id) { + return types.get(id); + } + + @Override + @Nullable + public ResourceLocation getId(FilteringRuleType rule) { + return types.inverse().get(rule); + } + + @Override + public void register(ResourceLocation id, FilteringRuleType rule) { + types.put(id, rule); + InternalLogger.getInstance().debug("Added filtering rule [%s]: %s", id, rule); + } + + @Override + public BasicFilteringRule basic() { + return BasicFilteringRuleImpl.INSTANCE; + } +} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/ManualFilteringRule.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/ManualFilteringRule.java index c65d18cb8..dcc1c9500 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/ManualFilteringRule.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/ManualFilteringRule.java @@ -28,16 +28,10 @@ import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import it.unimi.dsi.fastutil.longs.LongSet; import me.shedaniel.rei.api.client.config.ConfigObject; import me.shedaniel.rei.api.client.config.entry.EntryStackProvider; +import me.shedaniel.rei.api.client.entry.filtering.*; import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.api.common.util.CollectionUtils; import me.shedaniel.rei.api.common.util.EntryStacks; -import me.shedaniel.rei.impl.client.entry.filtering.AbstractFilteringRule; -import me.shedaniel.rei.impl.client.entry.filtering.FilteringCache; -import me.shedaniel.rei.impl.client.entry.filtering.FilteringContext; -import me.shedaniel.rei.impl.client.entry.filtering.FilteringResult; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TranslatableComponent; import java.util.Collection; import java.util.List; @@ -47,19 +41,14 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; -public class ManualFilteringRule extends AbstractFilteringRule { +public class ManualFilteringRule implements FilteringRule { @Override - public CompoundTag save(CompoundTag tag) { - return tag; + public FilteringRuleType> getType() { + return ManualFilteringRuleType.INSTANCE; } @Override - public ManualFilteringRule createFromTag(CompoundTag tag) { - return new ManualFilteringRule(); - } - - @Override - public Object prepareCache(boolean async) { + public LongSet prepareCache(boolean async) { if (async) { LongSet all = new LongOpenHashSet(); List> completableFutures = Lists.newArrayList(); @@ -92,30 +81,14 @@ public class ManualFilteringRule extends AbstractFilteringRule