diff options
| author | shedaniel <daniel@shedaniel.me> | 2023-03-16 23:01:27 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2023-03-16 23:01:27 +0800 |
| commit | 1e384a7f0906bc7526ff9596965d76b5bc8fc599 (patch) | |
| tree | 341e6d811207d416e772f620eef5343c6ddcc0e9 | |
| parent | c871bc0a460b8b22ea49d12cc12f9775d67ccd8e (diff) | |
| parent | 8e0aafdf9e16688117bd57e14824d664eb816fa0 (diff) | |
| download | RoughlyEnoughItems-1e384a7f0906bc7526ff9596965d76b5bc8fc599.tar.gz RoughlyEnoughItems-1e384a7f0906bc7526ff9596965d76b5bc8fc599.tar.bz2 RoughlyEnoughItems-1e384a7f0906bc7526ff9596965d76b5bc8fc599.zip | |
Merge remote-tracking branch 'origin/10.x-1.19.3' into 11.x-1.19.4
8 files changed, 246 insertions, 27 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringScreen.java index 3c9837db0..477fb0d00 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringScreen.java @@ -232,7 +232,7 @@ public class FilteringScreen extends Screen { int skip = Math.max(0, Mth.floor(scrolling.scrollAmount() / (float) entrySize())); int nextIndex = skip * innerBounds.width / entrySize(); int i = nextIndex; - BatchedEntryRendererManager manager = new BatchedEntryRendererManager(); + BatchedEntryRendererManager<FilteringListEntry> manager = new BatchedEntryRendererManager<>(); for (; i < entryStacks.size(); i++) { EntryStack<?> stack = entryStacks.get(i); FilteringListEntry entry = entries.get(nextIndex); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRuleType.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRuleType.java index a78917fef..9ffb425d8 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRuleType.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRuleType.java @@ -146,7 +146,7 @@ public enum SearchFilteringRuleType implements FilteringRuleType<SearchFiltering @Override public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) { - BatchedEntryRendererManager manager = new BatchedEntryRendererManager(); + BatchedEntryRendererManager<EntryWidget> manager = new BatchedEntryRendererManager<>(); int entrySize = entrySize(); int width = entryWidth / entrySize; int i = 0; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java index 11fff3ddf..78775c525 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java @@ -25,6 +25,7 @@ package me.shedaniel.rei.impl.client.gui.widget; import com.google.common.collect.AbstractIterator; import com.google.common.collect.Iterables; +import com.google.common.collect.Iterators; import com.mojang.blaze3d.vertex.PoseStack; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; @@ -32,26 +33,29 @@ import me.shedaniel.rei.api.client.config.ConfigObject; import me.shedaniel.rei.api.client.entry.renderer.BatchedEntryRenderer; import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer; import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.CollectionUtils; import me.shedaniel.rei.impl.client.util.CrashReportUtils; import net.minecraft.CrashReport; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.mutable.MutableLong; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import java.util.List; -public class BatchedEntryRendererManager { - private boolean fastEntryRendering = ConfigObject.getInstance().doesFastEntryRendering(); - private Int2ObjectMap<List<Object>> grouping = new Int2ObjectOpenHashMap<>(); - private List<EntryWidget> toRender = new ArrayList<>(); +public class BatchedEntryRendererManager<T extends EntryWidget> implements Iterable<T> { + private final boolean fastEntryRendering = ConfigObject.getInstance().doesFastEntryRendering(); + private final Int2ObjectMap<List<Object>> grouping = new Int2ObjectOpenHashMap<>(); + private final List<T> toRender = new ArrayList<>(); public BatchedEntryRendererManager() { } - public BatchedEntryRendererManager(Collection<? extends EntryWidget> widgets) { + public BatchedEntryRendererManager(Collection<? extends T> widgets) { addAll(widgets); } @@ -59,9 +63,9 @@ public class BatchedEntryRendererManager { return fastEntryRendering; } - public void addAll(Collection<? extends EntryWidget> widgets) { + public void addAll(Collection<? extends T> widgets) { if (fastEntryRendering) { - for (EntryWidget widget : widgets) { + for (T widget : widgets) { add(widget); } } else { @@ -69,7 +73,7 @@ public class BatchedEntryRendererManager { } } - public void add(EntryWidget widget) { + public void add(T widget) { if (fastEntryRendering) { EntryStack<?> currentEntry = widget.getCurrentEntry(); try { @@ -101,11 +105,11 @@ public class BatchedEntryRendererManager { addSlow(widget); } - public void addAllSlow(Collection<? extends EntryWidget> widgets) { + public void addAllSlow(Collection<? extends T> widgets) { toRender.addAll(widgets); } - public void addSlow(EntryWidget widget) { + public void addSlow(T widget) { toRender.add(widget); } @@ -120,15 +124,15 @@ public class BatchedEntryRendererManager { for (int i = 0; i < extraData.length; i++) { extraData[i] = entries.get(i * 2 + 1); } - renderBatched(debugTime, size, time, matrices, mouseX, mouseY, delta, () -> new AbstractIterator<>() { + renderBatched(debugTime, size, time, matrices, mouseX, mouseY, delta, () -> new AbstractIterator<T>() { public int i = 0; @Override - protected EntryWidget computeNext() { + protected T computeNext() { if (i >= entries.size()) { return endOfData(); } - EntryWidget widget = (EntryWidget) entries.get(i); + T widget = (T) entries.get(i); i += 2; return widget; } @@ -252,4 +256,24 @@ public class BatchedEntryRendererManager { } } } + + @NotNull + @Override + public Iterator<T> iterator() { + return Iterators.concat(toRender.iterator(), Iterators.concat( + CollectionUtils.<List<Object>, Iterator<T>>map(grouping.values(), entries -> new AbstractIterator<>() { + public int i = 0; + + @Override + protected T computeNext() { + if (i >= entries.size()) { + return endOfData(); + } + T widget = (T) entries.get(i); + i += 2; + return widget; + } + }).iterator() + )); + } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/CollapsedEntriesBorderRenderer.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/CollapsedEntriesBorderRenderer.java new file mode 100644 index 000000000..18e8d7e90 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/CollapsedEntriesBorderRenderer.java @@ -0,0 +1,171 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022, 2023 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.gui.widget.entrylist; + +import com.mojang.blaze3d.vertex.PoseStack; +import it.unimi.dsi.fastutil.longs.*; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.impl.common.entry.type.collapsed.CollapsedStack; +import net.minecraft.client.gui.GuiComponent; + +import static me.shedaniel.rei.impl.client.gui.widget.entrylist.EntryListWidget.entrySize; + +public class CollapsedEntriesBorderRenderer extends GuiComponent { + private static final int TOP = 0b00; + private static final int BOTTOM = 0b01; + private static final int LEFT = 0b10; + private static final int RIGHT = 0b11; + private static final int TOP_O = 0b100; + private static final int BOTTOM_O = 0b101; + private static final int LEFT_O = 0b110; + private static final int RIGHT_O = 0b111; + + public void render(PoseStack matrices, Iterable<EntryListStackEntry> entries, Object2IntMap<CollapsedStack> collapsedStackIndicesGlobal) { + if (collapsedStackIndicesGlobal.isEmpty()) return; + LongSet edgeSet = new LongOpenHashSet(); + int entrySize = entrySize(); + // bit 0-1: direction + // bit 2 occupied: has edge + // bit 3-14: collapsed stack index + // bit 15-30: y + // bit 31-46: x + for (EntryListStackEntry entry : entries) { + if (entry.getCollapsedStack() != null && entry.getCollapsedStack().isExpanded()) { + Rectangle entryBounds = entry.getBounds(); + int collapsedStackIndices = collapsedStackIndicesGlobal.getInt(entry.getCollapsedStack()); + long base = getPackedLong(entryBounds.getCenterX() + 100, entryBounds.getCenterY() + 100, collapsedStackIndices, 0, false); + if (!edgeSet.add(base | TOP)) edgeSet.add(base | TOP_O); + if (!edgeSet.add(base | BOTTOM)) edgeSet.add(base | BOTTOM_O); + if (!edgeSet.add(base | LEFT)) edgeSet.add(base | LEFT_O); + if (!edgeSet.add(base | RIGHT)) edgeSet.add(base | RIGHT_O); + // to left (base - ((long) entrySize << 31)) | RIGHT) + long nL = withDirD(shiftLongX(base, -entrySize), RIGHT, false); + if (edgeSet.contains(nL)) { + edgeSet.add(occupiedLong(nL)); + edgeSet.add(base | LEFT_O); + } + // to right + nL = withDirD(shiftLongX(base, entrySize), LEFT, false); + if (edgeSet.contains(nL)) { + edgeSet.add(occupiedLong(nL)); + edgeSet.add(base | RIGHT_O); + } + // to top + nL = withDirD(shiftLongY(base, -entrySize), BOTTOM, false); + if (edgeSet.contains(nL)) { + edgeSet.add(occupiedLong(nL)); + edgeSet.add(base | TOP_O); + } + // to bottom + nL = withDirD(shiftLongY(base, entrySize), TOP, false); + if (edgeSet.contains(nL)) { + edgeSet.add(occupiedLong(nL)); + edgeSet.add(base | BOTTOM_O); + } + } + } + + LongIterator iterator = edgeSet.iterator(); + LongList toRemove = new LongArrayList(); + while (iterator.hasNext()) { + long l = iterator.nextLong(); + if ((l & 0b100) != 0) { + toRemove.add(l); + toRemove.add(l & ~0b100); + } + } + edgeSet.removeAll(toRemove); + + matrices.pushPose(); + matrices.translate(-100, -100, 0); + + iterator = edgeSet.iterator(); + while (iterator.hasNext()) { + long l = iterator.nextLong(); + int x = (int) (l >> 31); + int y = (int) ((l >> 15) & 0xFFFF); + int collapsedStackIndices = (int) ((l >> 3) & 0b111111111111); + int x1 = x - entrySize / 2; + int y1 = y - entrySize / 2; + int x2 = x1 + entrySize; + int y2 = y1 + entrySize; + int direction = (int) (l & RIGHT); + switch (direction) { + case 0 -> { // top + int fStart = edgeSet.contains(shiftLongX(l, -entrySize)) || edgeSet.contains(withDirD(l, LEFT, false)) ? 0 : 1; + int fEnd = edgeSet.contains(shiftLongX(l, entrySize)) || edgeSet.contains(withDirD(l, RIGHT, false)) ? 0 : 1; + if (fStart == 1 && edgeSet.contains(getPackedLong(x - entrySize, y - entrySize, collapsedStackIndices, RIGHT, false))) fStart = -1; + if (fEnd == 1 && edgeSet.contains(getPackedLong(x + entrySize, y - entrySize, collapsedStackIndices, LEFT, false))) fEnd = -1; + fillGradient(matrices, x1 + fStart, y1, x2 - fEnd, y1 + 1, 0x67FFFFFF, 0x67FFFFFF); + } + case 1 -> { // bottom + int fStart = edgeSet.contains(shiftLongX(l, -entrySize)) || edgeSet.contains(withDirD(l, LEFT, false)) ? 0 : 1; + int fEnd = edgeSet.contains(shiftLongX(l, entrySize)) || edgeSet.contains(withDirD(l, RIGHT, false)) ? 0 : 1; + if (fStart == 1 && edgeSet.contains(getPackedLong(x - entrySize, y + entrySize, collapsedStackIndices, RIGHT, false))) fStart = -1; + if (fEnd == 1 && edgeSet.contains(getPackedLong(x + entrySize, y + entrySize, collapsedStackIndices, LEFT, false))) fEnd = -1; + fillGradient(matrices, x1 + fStart, y2 - 1, x2 - fEnd, y2, 0x67FFFFFF, 0x67FFFFFF); + } + case 2 -> { // left + int fStart = edgeSet.contains(shiftLongY(l, -entrySize)) ? 0 : 1; + int fEnd = edgeSet.contains(shiftLongY(l, entrySize)) ? 0 : 1; + if (fStart == 1 && edgeSet.contains(getPackedLong(x - entrySize, y - entrySize, collapsedStackIndices, BOTTOM, false))) fStart = 0; + if (fEnd == 1 && edgeSet.contains(getPackedLong(x - entrySize, y + entrySize, collapsedStackIndices, TOP, false))) fEnd = 0; + fillGradient(matrices, x1, y1 + fStart, x1 + 1, y2 - fEnd, 0x67FFFFFF, 0x67FFFFFF); + } + case 3 -> { // right + int fStart = edgeSet.contains(shiftLongY(l, -entrySize)) ? 0 : 1; + int fEnd = edgeSet.contains(shiftLongY(l, entrySize)) ? 0 : 1; + if (fStart == 1 && edgeSet.contains(getPackedLong(x + entrySize, y - entrySize, collapsedStackIndices, BOTTOM, false))) fStart = 0; + if (fEnd == 1 && edgeSet.contains(getPackedLong(x + entrySize, y + entrySize, collapsedStackIndices, TOP, false))) fEnd = 0; + fillGradient(matrices, x2 - 1, y1 + fStart, x2, y2 - fEnd, 0x67FFFFFF, 0x67FFFFFF); + } + } + } + + matrices.popPose(); + } + + private static long getPackedLong(int x, int y, int collapsedStackIndices, int direction, boolean occupied) { + long l = ((long) x << 31) | ((long) y << 15) | ((long) collapsedStackIndices << 3) | direction; + if (occupied) l |= 0b100; + return l; + } + + private static long shiftLongX(long l, int dX) { + return l + ((long) dX << 31); + } + + private static long shiftLongY(long l, int dX) { + return l + ((long) dX << 15); + } + + private static long withDirD(long l, int dir, boolean occupied) { + return (l & ~RIGHT_O) | dir | (occupied ? 0b100 : 0); + } + + private static long occupiedLong(long l) { + return l | 0b100; + } +} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListStackEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListStackEntry.java index 8f8662bc7..729dbb834 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListStackEntry.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListStackEntry.java @@ -110,8 +110,15 @@ public class EntryListStackEntry extends DisplayedEntryWidget { if (collapsedStack != null) { int entrySize = entrySize(); - fillGradient(matrices, bounds.getCenterX() - entrySize / 2, bounds.getCenterY() - entrySize / 2, - bounds.getCenterX() + entrySize / 2 + 1, bounds.getCenterY() + entrySize / 2 + 1, 0x34FFFFFF, 0x34FFFFFF); + int x1 = bounds.getCenterX() - entrySize / 2; + int y1 = bounds.getCenterY() - entrySize / 2; + int x2 = x1 + entrySize; + int y2 = y1 + entrySize; + if (collapsedStack.isExpanded()) { + fillGradient(matrices, x1, y1, x2, y2, 0x34FFFFFF, 0x34FFFFFF); + } else { + fillGradient(matrices, x1, y1, x2, y2, 0x53FFFFFF, 0x53FFFFFF); + } } super.drawBackground(matrices, mouseX, mouseY, delta); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/PaginatedEntryListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/PaginatedEntryListWidget.java index 6954c895d..258140201 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/PaginatedEntryListWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/PaginatedEntryListWidget.java @@ -27,6 +27,8 @@ import com.google.common.collect.Lists; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.config.ConfigObject; @@ -51,16 +53,14 @@ import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; import net.minecraft.util.Mth; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Random; +import java.util.*; import java.util.stream.Stream; public class PaginatedEntryListWidget extends CollapsingEntryListWidget { private Button leftButton, rightButton, changelogButton; private List<Widget> additionalWidgets; private List</*EntryStack<?> | EntryIngredient*/ Object> stacks = new ArrayList<>(); + private Object2IntMap<CollapsedStack> collapsedStackIndices = new Object2IntOpenHashMap<>(); protected List<EntryListStackEntry> entries = Collections.emptyList(); private int page; @@ -94,7 +94,7 @@ public class PaginatedEntryListWidget extends CollapsingEntryListWidget { } } - BatchedEntryRendererManager manager = new BatchedEntryRendererManager(); + BatchedEntryRendererManager<EntryListStackEntry> manager = new BatchedEntryRendererManager<>(); if (manager.isFastEntryRendering()) { for (EntryListStackEntry entry : entries) { CollapsedStack collapsedStack = entry.getCollapsedStack(); @@ -109,6 +109,8 @@ public class PaginatedEntryListWidget extends CollapsingEntryListWidget { } manager.render(debugger.debugTime, debugger.size, debugger.time, matrices, mouseX, mouseY, delta); + new CollapsedEntriesBorderRenderer().render(matrices, entries, collapsedStackIndices); + for (Widget widget : additionalWidgets) { widget.render(matrices, mouseX, mouseY, delta); } @@ -137,6 +139,7 @@ public class PaginatedEntryListWidget extends CollapsingEntryListWidget { int skip = Math.max(0, page * entries.size()); List</*EntryStack<?> | List<EntryStack<?>>*/ Object> subList = stacks.stream().skip(skip).limit(Math.max(0, entries.size() - Math.max(0, -page * entries.size()))).toList(); Int2ObjectMap<CollapsedStack> indexedCollapsedStack = getCollapsedStackIndexed(); + Set<CollapsedStack> collapsedStacks = new LinkedHashSet<>(); for (int i = 0; i < subList.size(); i++) { /*EntryStack<?> | List<EntryStack<?>>*/ Object stack = subList.get(i); @@ -152,11 +155,17 @@ public class PaginatedEntryListWidget extends CollapsingEntryListWidget { CollapsedStack collapsedStack = indexedCollapsedStack.get(i + skip); if (collapsedStack != null && collapsedStack.getIngredient().size() > 1) { entry.collapsed(collapsedStack); + collapsedStacks.add(collapsedStack); } else { entry.collapsed(null); } } this.entries = entries; + this.collapsedStackIndices = new Object2IntOpenHashMap<>(); + int index = 0; + for (CollapsedStack stack : collapsedStacks) { + collapsedStackIndices.put(stack, index++); + } } @Override diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/ScrolledEntryListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/ScrolledEntryListWidget.java index ac057a33c..9dc466cf9 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/ScrolledEntryListWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/ScrolledEntryListWidget.java @@ -27,6 +27,8 @@ import com.google.common.base.Predicates; import com.google.common.collect.Lists; import com.mojang.blaze3d.vertex.PoseStack; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import me.shedaniel.clothconfig2.ClothConfigInitializer; import me.shedaniel.clothconfig2.api.ScissorsHandler; import me.shedaniel.clothconfig2.api.scroll.ScrollingContainer; @@ -39,9 +41,7 @@ import me.shedaniel.rei.impl.common.entry.type.collapsed.CollapsedStack; import net.minecraft.client.gui.screens.Screen; import net.minecraft.util.Mth; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; import java.util.stream.Stream; public class ScrolledEntryListWidget extends CollapsingEntryListWidget { @@ -68,8 +68,11 @@ public class ScrolledEntryListWidget extends CollapsingEntryListWidget { int skip = Math.max(0, Mth.floor(scrolling.scrollAmount() / (float) entrySize)); int nextIndex = skip * innerBounds.width / entrySize; this.blockedCount = 0; - BatchedEntryRendererManager helper = new BatchedEntryRendererManager(); + BatchedEntryRendererManager<EntryListStackEntry> helper = new BatchedEntryRendererManager<>(); Int2ObjectMap<CollapsedStack> indexedCollapsedStack = getCollapsedStackIndexed(); + int collapsedStacksIndex = 0; + Object2IntMap<CollapsedStack> collapsedStackIndices = new Object2IntOpenHashMap<>(); + collapsedStackIndices.defaultReturnValue(-1); int i = nextIndex; for (int cont = nextIndex; cont < entries.size(); cont++) { @@ -100,6 +103,9 @@ public class ScrolledEntryListWidget extends CollapsingEntryListWidget { CollapsedStack collapsedStack = indexedCollapsedStack.get(i - 1); if (collapsedStack != null && collapsedStack.getIngredient().size() > 1) { entry.collapsed(collapsedStack); + if (!collapsedStackIndices.containsKey(collapsedStack)) { + collapsedStackIndices.put(collapsedStack, collapsedStacksIndex++); + } } else { entry.collapsed(null); } @@ -109,6 +115,8 @@ public class ScrolledEntryListWidget extends CollapsingEntryListWidget { } helper.render(debugger.debugTime, debugger.size, debugger.time, matrices, mouseX, mouseY, delta); + + new CollapsedEntriesBorderRenderer().render(matrices, helper, collapsedStackIndices); scrolling.updatePosition(delta); ScissorsHandler.INSTANCE.removeLastScissor(); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/EntryStacksRegionWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/EntryStacksRegionWidget.java index 4041741d8..de91f10b5 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/EntryStacksRegionWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/EntryStacksRegionWidget.java @@ -126,7 +126,7 @@ public class EntryStacksRegionWidget<T extends RegionEntry<T>> extends WidgetWit Stream<RegionEntryWidget<T>> entryStream = this.entriesList.stream() .filter(entry -> entry.getBounds().getMaxY() >= this.bounds.getY() && entry.getBounds().y <= this.bounds.getMaxY()); - new BatchedEntryRendererManager(entryStream.collect(Collectors.toList())) + new BatchedEntryRendererManager<>(entryStream.collect(Collectors.toList())) .render(poses, mouseX, mouseY, delta); updatePosition(delta); |
