diff options
| author | shedaniel <daniel@shedaniel.me> | 2022-12-09 02:08:47 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2022-12-09 02:08:47 +0800 |
| commit | dc6351d3b4893c316854f7a9fc6f8d95320046ee (patch) | |
| tree | a74dc043393b9f228473766cb7ce126cf080c206 | |
| parent | 00029913ffe72ee1b6cdff64ffe1fd9e56ac15a1 (diff) | |
| parent | 2caa595aa94d46ddaefc5ecdb79f7ec834f7eae8 (diff) | |
| download | RoughlyEnoughItems-dc6351d3b4893c316854f7a9fc6f8d95320046ee.tar.gz RoughlyEnoughItems-dc6351d3b4893c316854f7a9fc6f8d95320046ee.tar.bz2 RoughlyEnoughItems-dc6351d3b4893c316854f7a9fc6f8d95320046ee.zip | |
Merge remote-tracking branch 'origin/9.x-1.19' into feature/1.19.3
# Conflicts:
# runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java
32 files changed, 1168 insertions, 540 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringContext.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringContext.java index d46709af9..8cf2179e0 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringContext.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringContext.java @@ -23,6 +23,7 @@ package me.shedaniel.rei.api.client.entry.filtering; +import it.unimi.dsi.fastutil.longs.LongCollection; import me.shedaniel.rei.api.common.entry.EntryStack; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -53,4 +54,28 @@ public interface FilteringContext { * @return the list of stacks that are previously marked as hidden from other filtering rules. */ Collection<EntryStack<?>> getHiddenStacks(); + + /** + * Returns the list of hashes that are previously marked as <b>shown</b> from other filtering rules. + * + * @return the list of hashes that are previously marked as shown from other filtering rules. + */ + @ApiStatus.Experimental + LongCollection getShownExactHashes(); + + /** + * Returns the list of hashes that are previously marked as <b>hidden</b> from other filtering rules. + * + * @return the list of hashes that are previously marked as hidden from other filtering rules. + */ + @ApiStatus.Experimental + LongCollection getUnsetExactHashes(); + + /** + * Returns the list of hashes that are previously marked as <b>hidden</b> from other filtering rules. + * + * @return the list of hashes that are previously marked as hidden from other filtering rules. + */ + @ApiStatus.Experimental + LongCollection getHiddenExactHashes(); } diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRule.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRule.java index 1f3cb5b50..a133de686 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRule.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRule.java @@ -23,9 +23,15 @@ package me.shedaniel.rei.api.client.entry.filtering; +import it.unimi.dsi.fastutil.longs.LongCollection; +import me.shedaniel.rei.api.client.registry.entry.EntryRegistry; +import me.shedaniel.rei.api.common.entry.EntryStack; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; /** * A filtering rule type that is used to filter the entries on the entry panel, @@ -63,4 +69,20 @@ public interface FilteringRule<Cache> { * @return the result of the processing */ FilteringResult processFilteredStacks(FilteringContext context, FilteringResultFactory resultFactory, Cache cache, boolean async); + + /** + * Returns whether the entry registry is in its reloading phase. + * Registration after the reloading phase will be slow and may not be reflected immediately. + * + * @return whether the entry registry is in its reloading phase + */ + @ApiStatus.NonExtendable + default boolean isReloading() { + return EntryRegistry.getInstance().isReloading(); + } + + @ApiStatus.NonExtendable + default void markDirty(Collection<EntryStack<?>> stacks, @Nullable LongCollection hashes) { + EntryRegistry.getInstance().markFilteringRuleDirty(this, stacks, hashes); + } }
\ No newline at end of file diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/base/BasicFilteringRule.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/base/BasicFilteringRule.java index 26b2986c2..4800a430e 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/base/BasicFilteringRule.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/base/BasicFilteringRule.java @@ -26,11 +26,15 @@ package me.shedaniel.rei.api.client.entry.filtering.base; import me.shedaniel.rei.api.client.entry.filtering.FilteringResult; import me.shedaniel.rei.api.client.entry.filtering.FilteringRule; import me.shedaniel.rei.api.client.plugins.REIClientPlugin; +import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.api.common.registry.Reloadable; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import org.jetbrains.annotations.ApiStatus; +import java.util.Collection; +import java.util.function.Supplier; + /** * The basic filtering rule that can be used to filter entries, * without registering a new filtering rule type, for external @@ -41,4 +45,12 @@ import org.jetbrains.annotations.ApiStatus; @ApiStatus.Experimental @Environment(EnvType.CLIENT) public interface BasicFilteringRule<Cache> extends Reloadable<REIClientPlugin>, FilteringRule<Cache>, FilteringResult { + MarkDirty hide(Supplier<Collection<EntryStack<?>>> provider); + + MarkDirty show(Supplier<Collection<EntryStack<?>>> provider); + + @ApiStatus.NonExtendable + interface MarkDirty { + void markDirty(); + } } 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 d2deaac32..7cfbc27ed 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 @@ -23,6 +23,8 @@ package me.shedaniel.rei.api.client.registry.entry; +import it.unimi.dsi.fastutil.longs.LongCollection; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRule; import me.shedaniel.rei.api.client.plugins.REIClientPlugin; import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.api.common.plugins.PluginManager; @@ -209,4 +211,7 @@ public interface EntryRegistry extends Reloadable<REIClientPlugin> { * @return whether the registry is in its reloading phase */ boolean isReloading(); + + @ApiStatus.Experimental + <Cache> void markFilteringRuleDirty(FilteringRule<Cache> cacheFilteringRule, Collection<EntryStack<?>> stacks, @Nullable LongCollection hashes); } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuInfo.java b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuInfo.java index 9769d073e..08165839f 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuInfo.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuInfo.java @@ -189,7 +189,7 @@ public interface MenuInfo<T extends AbstractContainerMenu, D extends Display> { if (widget instanceof Slot && ((Slot) widget).getNoticeMark() == Slot.INPUT) { if (missingIndices.contains(i++)) { matrices.pushPose(); - matrices.translate(0, 0, 400); + matrices.translate(0, 0, 50); Rectangle innerBounds = ((Slot) widget).getInnerBounds(); GuiComponent.fill(matrices, innerBounds.x, innerBounds.y, innerBounds.getMaxX(), innerBounds.getMaxY(), 0x40ff0000); matrices.popPose(); diff --git a/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java b/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java index 67894fb27..3b625d888 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java @@ -241,6 +241,33 @@ public class CollectionUtils { return Stream.of(list).max(comparator); } + public static <T, R> Optional<R> mapAndMin(Collection<T> list, Function<T, R> function, Comparator<R> comparator) { + if (list.isEmpty()) { + return Optional.empty(); + } + return list.stream().min(Comparator.comparing(function, comparator)).map(function); + } + + public static <T, R> Optional<R> mapAndMin(T[] list, Function<T, R> function, Comparator<R> comparator) { + if (list.length <= 0) + return Optional.empty(); + return Stream.of(list).min(Comparator.comparing(function, comparator)).map(function); + } + + public static <T> Optional<T> min(Collection<T> list, Comparator<T> comparator) { + if (list.isEmpty()) { + return Optional.empty(); + } + return list.stream().min(comparator); + } + + public static <T> Optional<T> min(T[] list, Comparator<T> comparator) { + if (list.length <= 0) { + return Optional.empty(); + } + return Stream.of(list).min(comparator); + } + public static String joinToString(Iterable<CharSequence> list, CharSequence separator) { return String.join(separator, list); } diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java index 01e4fc1fd..16558a54e 100644 --- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java +++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java @@ -24,6 +24,8 @@ package me.shedaniel.rei; import com.google.common.collect.Lists; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.serialization.DataResult; import dev.architectury.event.Event; import dev.architectury.event.EventFactory; @@ -88,6 +90,7 @@ import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.components.ImageButton; +import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.CraftingScreen; @@ -385,23 +388,64 @@ public class RoughlyEnoughItemsCoreClient { ClientScreenInputEvent.CHAR_TYPED_PRE.register((minecraftClient, screen, character, keyCode) -> { if (shouldReturn(screen) || screen instanceof DisplayScreen) return EventResult.pass(); - if (screen.getFocused() != null && screen.getFocused() instanceof EditBox || (screen.getFocused() instanceof RecipeBookComponent && ((RecipeBookComponent) screen.getFocused()).searchBox != null && ((RecipeBookComponent) screen.getFocused()).searchBox.isFocused())) - if (!REIRuntimeImpl.getSearchField().isFocused()) - return EventResult.pass(); + if (!REIRuntimeImpl.getSearchField().isFocused()) { + GuiEventListener focused = screen.getFocused(); + if (focused != null) { + if (focused instanceof EditBox editBox && editBox.isFocused()) return EventResult.pass(); + if (focused instanceof RecipeBookComponent book && book.searchBox != null && book.searchBox.isFocused()) return EventResult.pass(); + } + } resetFocused(screen); if (getOverlay().charTyped(character, keyCode) && resetFocused(screen)) return EventResult.interruptFalse(); return EventResult.pass(); }); - ClientGuiEvent.RENDER_POST.register((screen, matrices, mouseX, mouseY, delta) -> { + int[] rendered = {0}; + ClientGuiEvent.RENDER_PRE.register((screen, matrices, mouseX, mouseY, delta) -> { + if (shouldReturn(screen)) + return EventResult.pass(); + rendered[0] = 0; + return EventResult.pass(); + }); + ClientGuiEvent.RENDER_CONTAINER_BACKGROUND.register((screen, matrices, mouseX, mouseY, delta) -> { if (shouldReturn(screen)) return; + rendered[0] = 1; resetFocused(screen); if (!(screen instanceof DisplayScreen)) { getOverlay().render(matrices, mouseX, mouseY, delta); } + resetFocused(screen); + }); + ClientGuiEvent.RENDER_CONTAINER_FOREGROUND.register((screen, matrices, mouseX, mouseY, delta) -> { + if (shouldReturn(screen)) + return; + rendered[0] = 2; + resetFocused(screen); + PoseStack poseStack = RenderSystem.getModelViewStack(); + poseStack.pushPose(); + poseStack.translate(-screen.leftPos, -screen.topPos, 0.0); + RenderSystem.applyModelViewMatrix(); ((ScreenOverlayImpl) getOverlay()).lateRender(matrices, mouseX, mouseY, delta); + poseStack.popPose(); + RenderSystem.applyModelViewMatrix(); + resetFocused(screen); + }); + ClientGuiEvent.RENDER_POST.register((screen, matrices, mouseX, mouseY, delta) -> { + if (shouldReturn(screen) || rendered[0] == 2) + return; + if (screen instanceof AbstractContainerScreen) { + InternalLogger.getInstance().warn("Screen " + screen.getClass().getName() + " did not render background and foreground! This might cause rendering issues!"); + } + resetFocused(screen); + if (rendered[0] == 0 && !(screen instanceof DisplayScreen)) { + getOverlay().render(matrices, mouseX, mouseY, delta); + } + rendered[0] = 1; + if (rendered[0] == 1) { + ((ScreenOverlayImpl) getOverlay()).lateRender(matrices, mouseX, mouseY, delta); + } resetFocused(screen); }); ClientScreenInputEvent.MOUSE_DRAGGED_PRE.register((minecraftClient, screen, mouseX1, mouseY1, button, mouseX2, mouseY2) -> { @@ -422,9 +466,13 @@ public class RoughlyEnoughItemsCoreClient { return EventResult.interruptFalse(); } } - if (screen.getFocused() != null && screen.getFocused() instanceof EditBox || (screen.getFocused() instanceof RecipeBookComponent && ((RecipeBookComponent) screen.getFocused()).searchBox != null && ((RecipeBookComponent) screen.getFocused()).searchBox.isFocused())) - if (!REIRuntimeImpl.getSearchField().isFocused()) - return EventResult.pass(); + if (!REIRuntimeImpl.getSearchField().isFocused()) { + GuiEventListener focused = screen.getFocused(); + if (focused != null) { + if (focused instanceof EditBox editBox && editBox.isFocused()) return EventResult.pass(); + if (focused instanceof RecipeBookComponent book && book.searchBox != null && book.searchBox.isFocused()) return EventResult.pass(); + } + } resetFocused(screen); if (getOverlay().keyPressed(i, i1, i2) && resetFocused(screen)) @@ -434,9 +482,13 @@ public class RoughlyEnoughItemsCoreClient { ClientScreenInputEvent.KEY_RELEASED_PRE.register((minecraftClient, screen, i, i1, i2) -> { if (shouldReturn(screen) || screen instanceof DisplayScreen) return EventResult.pass(); - if (screen.getFocused() != null && screen.getFocused() instanceof EditBox || (screen.getFocused() instanceof RecipeBookComponent && ((RecipeBookComponent) screen.getFocused()).searchBox != null && ((RecipeBookComponent) screen.getFocused()).searchBox.isFocused())) - if (!REIRuntimeImpl.getSearchField().isFocused()) - return EventResult.pass(); + if (!REIRuntimeImpl.getSearchField().isFocused()) { + GuiEventListener focused = screen.getFocused(); + if (focused != null) { + if (focused instanceof EditBox editBox && editBox.isFocused()) return EventResult.pass(); + if (focused instanceof RecipeBookComponent book && book.searchBox != null && book.searchBox.isFocused()) return EventResult.pass(); + } + } resetFocused(screen); if (getOverlay().keyReleased(i, i1, i2) && resetFocused(screen)) 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 d59ece66c..a18d7aeab 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 @@ -684,7 +684,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { @Comment("Declares how the scrollbar in composite screen should act.") private boolean compositeScrollBarPermanent = false; private boolean toastDisplayedOnCopyIdentifier = true; @Comment("Declares whether REI should use compact tabs for categories.") private boolean useCompactTabs = true; - @Comment("Declares whether REI should use compact tab buttons for categories.") @ConfigEntry.Gui.Excluded private boolean useCompactTabButtons = false; + @Comment("Declares whether REI should use compact tab buttons for categories.") private boolean useCompactTabButtons = false; } public static class Search { 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 14636c4c2..803802ea8 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 @@ -23,13 +23,23 @@ package me.shedaniel.rei.impl.client.config.entries; +import com.google.common.base.Suppliers; 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.api.client.entry.filtering.FilteringRule; import me.shedaniel.rei.api.client.entry.filtering.FilteringRuleType; +import me.shedaniel.rei.api.client.gui.widgets.Widgets; +import me.shedaniel.rei.api.client.registry.entry.EntryRegistry; +import me.shedaniel.rei.api.common.util.CollectionUtils; +import me.shedaniel.rei.impl.client.entry.filtering.FilteringContextType; import me.shedaniel.rei.impl.client.entry.filtering.rules.ManualFilteringRule; +import me.shedaniel.rei.impl.client.entry.filtering.rules.SearchFilteringRuleType; import me.shedaniel.rei.impl.client.gui.InternalTextures; +import me.shedaniel.rei.impl.client.gui.widget.EntryWidget; +import me.shedaniel.rei.impl.common.entry.type.FilteringLogic; +import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.events.GuiEventListener; @@ -42,11 +52,11 @@ import net.minecraft.network.chat.FormattedText; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvents; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; +import java.util.*; +import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; +import java.util.stream.Collectors; public class FilteringRulesScreen extends Screen { private final FilteringEntry entry; @@ -184,7 +194,7 @@ public class FilteringRulesScreen extends Screen { public DefaultRuleEntry(FilteringRule<?> rule, FilteringEntry entry, Function<Screen, Screen> screenFunction) { super(rule); - this.screenFunction = (screenFunction == null ? ((FilteringRuleType<FilteringRule<?>>) rule.getType()).createEntryScreen(rule) : screenFunction); + this.screenFunction = Objects.requireNonNullElseGet(screenFunction == null ? ((FilteringRuleType<FilteringRule<?>>) rule.getType()).createEntryScreen(rule) : screenFunction, () -> placeholderScreen(rule)); configureButton = new Button(0, 0, 20, 20, Component.nullToEmpty(null), button -> { entry.edited = true; Minecraft.getInstance().setScreen(this.screenFunction.apply(Minecraft.getInstance().screen)); @@ -250,4 +260,36 @@ public class FilteringRulesScreen extends Screen { return Arrays.asList(configureButton, deleteButton); } } + + private static <Cache> Function<Screen, Screen> placeholderScreen(FilteringRule<Cache> r) { + class PlaceholderScreen extends FilteringRuleOptionsScreen<FilteringRule<Cache>> { + public PlaceholderScreen(Screen parent) { + super(r, parent); + } + + @Override + public void addEntries(Consumer<RuleEntry> entryConsumer) { + addEmpty(entryConsumer, 10); + Function<Boolean, Component> function = bool -> { + return Component.translatable("rule.roughlyenoughitems.filtering.search.show." + bool); + }; + Map<FilteringContextType, Set<HashedEntryStackWrapper>> stacks = FilteringLogic.hidden(FilteringLogic.getRules(), false, false, EntryRegistry.getInstance().getEntryStacks().collect(Collectors.toList())); + + entryConsumer.accept(new SubRulesEntry(rule, () -> function.apply(true), + Collections.singletonList(new SearchFilteringRuleType.EntryStacksRuleEntry(rule, + Suppliers.ofInstance(CollectionUtils.map(stacks.get(FilteringContextType.SHOWN), + stack -> (EntryWidget) Widgets.createSlot(new Rectangle(0, 0, 18, 18)).disableBackground().entry(stack.unwrap().normalize()))))))); + addEmpty(entryConsumer, 10); + entryConsumer.accept(new SubRulesEntry(rule, () -> function.apply(false), + Collections.singletonList(new SearchFilteringRuleType.EntryStacksRuleEntry(rule, + Suppliers.ofInstance(CollectionUtils.map(stacks.get(FilteringContextType.HIDDEN), + stack -> (EntryWidget) Widgets.createSlot(new Rectangle(0, 0, 18, 18)).disableBackground().entry(stack.unwrap().normalize()))))))); + } + + @Override + public void save() { + } + } + return PlaceholderScreen::new; + } } 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 d0e26a9fc..697bcde63 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 @@ -27,6 +27,7 @@ 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 it.unimi.dsi.fastutil.longs.*; 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; @@ -69,20 +70,35 @@ public class FilteringContextImpl implements FilteringContext { @Override public Collection<EntryStack<?>> getHiddenStacks() { - return getPublicFacing(FilteringContextType.HIDDEN); + return getStacksFacing(FilteringContextType.HIDDEN); } @Override public Collection<EntryStack<?>> getShownStacks() { - return getPublicFacing(FilteringContextType.SHOWN); + return getStacksFacing(FilteringContextType.SHOWN); } @Override public Collection<EntryStack<?>> getUnsetStacks() { - return getPublicFacing(FilteringContextType.DEFAULT); + return getStacksFacing(FilteringContextType.DEFAULT); } - private Collection<EntryStack<?>> getPublicFacing(FilteringContextType type) { + @Override + public LongCollection getHiddenExactHashes() { + return getHashesFacing(FilteringContextType.HIDDEN); + } + + @Override + public LongCollection getShownExactHashes() { + return getHashesFacing(FilteringContextType.SHOWN); + } + + @Override + public LongCollection getUnsetExactHashes() { + return getHashesFacing(FilteringContextType.DEFAULT); + } + + private Collection<EntryStack<?>> getStacksFacing(FilteringContextType type) { Set<HashedEntryStackWrapper> wrappers = this.stacks.get(type); if (wrappers == null || wrappers.isEmpty()) return List.of(); return new AbstractSet<>() { @@ -98,6 +114,33 @@ public class FilteringContextImpl implements FilteringContext { }; } + private Long |
