diff options
| author | shedaniel <daniel@shedaniel.me> | 2021-03-28 20:35:46 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2021-03-28 20:35:46 +0800 |
| commit | ebf2bb9dfa1f0e1abca845d7283e6e74ad8b00cd (patch) | |
| tree | cc2e4c4d101aaaf5dcbc9dd5cebb9d7f7b3a7982 | |
| parent | 9d835c7823978e04007414cfe3ebf128e23a6494 (diff) | |
| download | RoughlyEnoughItems-ebf2bb9dfa1f0e1abca845d7283e6e74ad8b00cd.tar.gz RoughlyEnoughItems-ebf2bb9dfa1f0e1abca845d7283e6e74ad8b00cd.tar.bz2 RoughlyEnoughItems-ebf2bb9dfa1f0e1abca845d7283e6e74ad8b00cd.zip | |
Optimise > 1 million entries & Improve Favorites Dragging
Signed-off-by: shedaniel <daniel@shedaniel.me>
25 files changed, 453 insertions, 289 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/renderer/BatchEntryRenderer.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/renderer/BatchEntryRenderer.java index 89f1d0034..ba7e5d150 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/entry/renderer/BatchEntryRenderer.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/renderer/BatchEntryRenderer.java @@ -44,7 +44,7 @@ public interface BatchEntryRenderer<T> extends EntryRenderer<T> { void renderBase(EntryStack<T> entry, PoseStack matrices, MultiBufferSource.BufferSource immediate, Rectangle bounds, int mouseX, int mouseY, float delta); - void renderOverlay(EntryStack<T> entry, PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta); + void renderOverlay(EntryStack<T> entry, PoseStack matrices, MultiBufferSource.BufferSource immediate, Rectangle bounds, int mouseX, int mouseY, float delta); void endBatch(EntryStack<T> entry, PoseStack matrices, float delta); @@ -55,7 +55,8 @@ public interface BatchEntryRenderer<T> extends EntryRenderer<T> { MultiBufferSource.BufferSource immediate = Minecraft.getInstance().renderBuffers().bufferSource(); renderBase(entry, matrices, immediate, bounds, mouseX, mouseY, delta); immediate.endBatch(); - renderOverlay(entry, matrices, bounds, mouseX, mouseY, delta); + renderOverlay(entry, matrices, immediate, bounds, mouseX, mouseY, delta); + immediate.endBatch(); endBatch(entry, matrices, delta); } }
\ No newline at end of file diff --git a/api/src/main/java/me/shedaniel/rei/api/client/view/Views.java b/api/src/main/java/me/shedaniel/rei/api/client/view/Views.java index 7a74f3d8b..86c47e3fc 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/view/Views.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/view/Views.java @@ -47,7 +47,7 @@ public interface Views extends Reloadable<REIClientPlugin> { * @param inventoryItems the materials * @return the list of craftable entries */ - Collection<EntryStack<?>> findCraftableEntriesByItems(Iterable<? extends EntryStack<?>> inventoryItems); + Collection<EntryStack<?>> findCraftableEntriesByMaterials(Iterable<? extends EntryStack<?>> inventoryItems); /** * Returns a map of recipes for an entry diff --git a/api/src/main/java/me/shedaniel/rei/api/common/entry/EntryStack.java b/api/src/main/java/me/shedaniel/rei/api/common/entry/EntryStack.java index cd3defe83..b75624da0 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/entry/EntryStack.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/entry/EntryStack.java @@ -126,8 +126,6 @@ public interface EntryStack<T> extends TextRepresentable, Renderer { @Deprecated int hashCode(); - int hash(ComparisonContext context); - @Deprecated boolean equals(Object o); diff --git a/api/src/main/java/me/shedaniel/rei/api/common/util/EntryStacks.java b/api/src/main/java/me/shedaniel/rei/api/common/util/EntryStacks.java index b7882298b..58cf1ada5 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/util/EntryStacks.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/util/EntryStacks.java @@ -158,7 +158,7 @@ public final class EntryStacks { * @return the hash code of the {@link ComparisonContext#EXACT} context */ public static <T> int hashExact(EntryStack<T> stack) { - return stack.hash(ComparisonContext.EXACT); + return stack.getDefinition().hash(stack, stack.getValue(), ComparisonContext.EXACT); } /** @@ -172,7 +172,7 @@ public final class EntryStacks { * @return the hash code of the {@link ComparisonContext#FUZZY} context */ public static <T> int hashFuzzy(EntryStack<T> stack) { - return stack.hash(ComparisonContext.FUZZY); + return stack.getDefinition().hash(stack, stack.getValue(), ComparisonContext.FUZZY); } public static EntryStack<FluidStack> simplifyAmount(EntryStack<FluidStack> stack) { diff --git a/build.gradle b/build.gradle index bb7ce9244..1aff1a6b3 100755 --- a/build.gradle +++ b/build.gradle @@ -219,11 +219,7 @@ publishing { }*/ allprojects { - repositories { - mavenLocal() - } - architectury { - transformerVersion = "2.1.9999" + transformerVersion = "2.1.38" } } diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/GameModeFavoriteEntry.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/GameModeFavoriteEntry.java index 78bbe9ca6..1e45f89fd 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/GameModeFavoriteEntry.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/GameModeFavoriteEntry.java @@ -104,7 +104,11 @@ public class GameModeFavoriteEntry extends FavoriteEntry { public void render(PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { int color = bounds.contains(mouseX, mouseY) ? 0xFFEEEEEE : 0xFFAAAAAA; if (bounds.width > 4 && bounds.height > 4) { - renderGameModeText(matrices, type, bounds.getCenterX(), bounds.getCenterY(), color); + matrices.pushPose(); + matrices.translate(bounds.getCenterX(), bounds.getCenterY(), 0); + matrices.scale(bounds.getWidth() / 18f, bounds.getHeight() / 18f, 1); + renderGameModeText(matrices, type, 0, 0, color); + matrices.popPose(); } } diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/WeatherFavoriteEntry.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/WeatherFavoriteEntry.java index b288a2f8f..13c66e1b0 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/WeatherFavoriteEntry.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/WeatherFavoriteEntry.java @@ -24,8 +24,6 @@ package me.shedaniel.rei.plugin.client.favorites; import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Vector4f; -import me.shedaniel.clothconfig2.api.ScissorsHandler; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.REIHelper; @@ -37,21 +35,16 @@ import me.shedaniel.rei.api.client.favorites.FavoriteMenuEntry; import me.shedaniel.rei.api.client.gui.AbstractRenderer; import me.shedaniel.rei.api.client.gui.Renderer; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; -import me.shedaniel.rei.api.common.util.Animator; import me.shedaniel.rei.api.common.util.CollectionUtils; -import net.minecraft.Util; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Font; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.resources.language.I18n; import net.minecraft.client.resources.sounds.SimpleSoundInstance; import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvents; -import net.minecraft.world.level.GameType; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; @@ -120,10 +113,14 @@ public class WeatherFavoriteEntry extends FavoriteEntry { public void render(PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { int color = bounds.contains(mouseX, mouseY) ? 0xFFEEEEEE : 0xFFAAAAAA; if (bounds.width > 4 && bounds.height > 4) { - renderWeatherIcon(matrices, weather, bounds.getCenterX(), bounds.getCenterY(), color); + matrices.pushPose(); + matrices.translate(bounds.getCenterX(), bounds.getCenterY(), 0); + matrices.scale(bounds.getWidth() / 18f, bounds.getHeight() / 18f, 1); + renderWeatherIcon(matrices, weather, 0, 0, color); + matrices.popPose(); } } - + private void renderWeatherIcon(PoseStack matrices, Weather type, int centerX, int centerY, int color) { Minecraft.getInstance().getTextureManager().bind(CHEST_GUI_TEXTURE); blit(matrices, centerX - 7, centerY - 7, type.getId() * 14, 14, 14, 14, 256, 256); @@ -196,7 +193,7 @@ public class WeatherFavoriteEntry extends FavoriteEntry { public enum Type implements FavoriteEntryType<WeatherFavoriteEntry> { INSTANCE; - + @Override public WeatherFavoriteEntry read(CompoundTag object) { String stringValue = object.getString(KEY); @@ -208,7 +205,7 @@ public class WeatherFavoriteEntry extends FavoriteEntry { public WeatherFavoriteEntry fromArgs(Object... args) { return new WeatherFavoriteEntry((Weather) args[0]); } - + @Override public CompoundTag save(WeatherFavoriteEntry entry, CompoundTag tag) { tag.putString(KEY, entry.weather == null ? "NOT_SET" : entry.weather.name()); diff --git a/forge/src/main/java/me/shedaniel/rei/forge/PluginDetectorImpl.java b/forge/src/main/java/me/shedaniel/rei/forge/PluginDetectorImpl.java index 4c261c177..437a05e22 100644 --- a/forge/src/main/java/me/shedaniel/rei/forge/PluginDetectorImpl.java +++ b/forge/src/main/java/me/shedaniel/rei/forge/PluginDetectorImpl.java @@ -28,10 +28,10 @@ import me.shedaniel.rei.api.common.plugins.PluginManager; import me.shedaniel.rei.api.common.plugins.PluginView; import me.shedaniel.rei.api.common.plugins.REIPluginProvider; import me.shedaniel.rei.api.common.plugins.REIServerPlugin; -import me.shedaniel.rei.plugin.client.DefaultClientRuntimePlugin; -import me.shedaniel.rei.impl.Internals; +import me.shedaniel.rei.impl.ClientInternals; import me.shedaniel.rei.jeicompat.JEIPluginDetector; import me.shedaniel.rei.plugin.client.DefaultClientPlugin; +import me.shedaniel.rei.plugin.client.DefaultClientRuntimePlugin; import me.shedaniel.rei.plugin.common.DefaultPlugin; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -62,7 +62,7 @@ public class PluginDetectorImpl { RoughlyEnoughItemsForge.<REIPlugin, REIClientPlugin>scanAnnotation(REIPlugin.class, REIClientPlugin.class::isAssignableFrom, (modId, plugin) -> { ((PluginView<REIClientPlugin>) PluginManager.getClientInstance()).registerPlugin(plugin); }); - Internals.attachInstance((Supplier<List<String>>) () -> { + ClientInternals.attachInstance((Supplier<List<String>>) () -> { List<String> modIds = new ArrayList<>(); for (REIPluginProvider<REIClientPlugin> plugin : PluginManager.getClientInstance().getPluginProviders()) { if (plugin instanceof JEIPluginDetector.JEIPluginProvider) { diff --git a/gradle.properties b/gradle.properties index 657fd1fcc..01ce31c61 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ supported_version=1.16.2/3/4/5 minecraft_version=1.16.5 forge_version=36.0.43 fabricloader_version=0.11.1 -cloth_config_version=4.11.17 +cloth_config_version=4.11.18 modmenu_version=1.16.7 fabric_api=0.30.0+1.16 architectury_version=1.9.136 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 6a9feabe9..a111dd7fd 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 @@ -352,8 +352,9 @@ public class ConfigManagerImpl implements ConfigManager { }).setSavingRunnable(() -> { saveConfig(); EntryRegistry.getInstance().refilter(); - if (REIHelperImpl.getSearchField() != null) + if (REIHelperImpl.getSearchField() != null) { ContainerScreenOverlay.getEntryListWidget().updateSearch(REIHelperImpl.getSearchField().getText(), true); + } }).build(); }); Screen configScreen = provider.get(); 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 adabe8d62..0c41f834c 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 @@ -25,6 +25,7 @@ package me.shedaniel.rei.impl.client.config.entries; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.DefaultVertexFormat; @@ -46,6 +47,7 @@ import me.shedaniel.rei.api.client.search.SearchFilter; import me.shedaniel.rei.api.client.search.SearchProvider; import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.impl.client.gui.ContainerScreenOverlay; +import me.shedaniel.rei.impl.client.gui.widget.BatchEntryRendererManager; import me.shedaniel.rei.impl.client.gui.widget.EntryWidget; import me.shedaniel.rei.impl.client.gui.widget.search.OverlaySearchField; import net.minecraft.client.Minecraft; @@ -221,16 +223,18 @@ 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; + BatchEntryRendererManager manager = new BatchEntryRendererManager(); for (; i < entryStacks.size(); i++) { - EntryStack stack = entryStacks.get(i); + EntryStack<?> stack = entryStacks.get(i); EntryListEntry entry = entries.get(nextIndex); entry.getBounds().y = (int) (entry.backupY - scrolling.scrollAmount); if (entry.getBounds().y > bounds.getMaxY()) break; entry.entry(stack); - entry.render(matrices, mouseX, mouseY, delta); + manager.add(entry); nextIndex++; } + manager.render(matrices, mouseX, mouseY, delta); updatePosition(delta); scrolling.renderScrollBar(0xff000000, 1, REIHelper.getInstance().isDarkThemeEnabled() ? 0.8f : 1f); matrices.pushPose(); @@ -243,8 +247,8 @@ public class FilteringScreen extends Screen { matrices.popPose(); ScissorsHandler.INSTANCE.removeLastScissor(); - Tesselator tessellator = Tesselator.getInstance(); - BufferBuilder buffer = tessellator.getBuilder(); + Tesselator tesselator = Tesselator.getInstance(); + BufferBuilder buffer = tesselator.getBuilder(); RenderSystem.enableBlend(); RenderSystem.blendFuncSeparate(770, 771, 0, 1); RenderSystem.disableAlphaTest(); @@ -256,7 +260,7 @@ public class FilteringScreen extends Screen { buffer.vertex(matrix, width, bounds.y + 4, 0.0F).uv(1.0F, 1.0F).color(0, 0, 0, 0).endVertex(); buffer.vertex(matrix, width, bounds.y, 0.0F).uv(1.0F, 0.0F).color(0, 0, 0, 255).endVertex(); buffer.vertex(matrix, 0, bounds.y, 0.0F).uv(0.0F, 0.0F).color(0, 0, 0, 255).endVertex(); - tessellator.end(); + tesselator.end(); RenderSystem.enableTexture(); RenderSystem.shadeModel(7424); RenderSystem.enableAlphaTest(); @@ -314,11 +318,7 @@ public class FilteringScreen extends Screen { public void updateSearch(String searchTerm) { lastFilter = SearchProvider.getInstance().createFilter(searchTerm); Set<EntryStack<?>> list = Sets.newLinkedHashSet(); - EntryRegistry.getInstance().getEntryStacks().forEach(stack -> { - if (matches(stack)) { - list.add(stack.normalize()); - } - }); + EntryRegistry.getInstance().getEntryStacks().parallel().filter(this::matches).map(EntryStack::normalize).forEachOrdered(list::add); entryStacks = Lists.newArrayList(list); updateEntriesPosition(); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ContainerScreenOverlay.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ContainerScreenOverlay.java index ef88474a0..c2c69f1a4 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ContainerScreenOverlay.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ContainerScreenOverlay.java @@ -531,9 +531,11 @@ public class ContainerScreenOverlay extends REIOverlay { if (Minecraft.getInstance().screen instanceof AbstractContainerScreen) { AbstractContainerScreen<?> containerScreen = (AbstractContainerScreen<?>) Minecraft.getInstance().screen; int x = containerScreen.leftPos, y = containerScreen.topPos; - for (Slot slot : containerScreen.getMenu().slots) - if (!slot.hasItem() || !ENTRY_LIST_WIDGET.matches(EntryStacks.of(slot.getItem()))) + for (Slot slot : containerScreen.getMenu().slots) { + if (!slot.hasItem() || !ENTRY_LIST_WIDGET.matches(EntryStacks.of(slot.getItem()))) { fillGradient(matrices, x + slot.x, y + slot.y, x + slot.x + 16, y + slot.y + 16, -601874400, -601874400); + } + } } matrices.popPose(); } @@ -696,7 +698,7 @@ public class ContainerScreenOverlay extends REIOverlay { ConfigManager.getInstance().saveConfig(); FavoritesListWidget favoritesListWidget = ContainerScreenOverlay.getFavoritesListWidget(); if (favoritesListWidget != null) - favoritesListWidget.updateSearch(ContainerScreenOverlay.getEntryListWidget(), REIHelperImpl.getSearchField().getText()); + favoritesListWidget.updateSearch(); return true; } } @@ -757,7 +759,7 @@ public class ContainerScreenOverlay extends REIOverlay { ConfigManager.getInstance().saveConfig(); FavoritesListWidget favoritesListWidget = ContainerScreenOverlay.getFavoritesListWidget(); if (favoritesListWidget != null) - favoritesListWidget.updateSearch(ContainerScreenOverlay.getEntryListWidget(), REIHelper.getInstance().getSearchTextField().getText()); + favoritesListWidget.updateSearch(); return true; } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/EntryStackSubsetsMenuEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/EntryStackSubsetsMenuEntry.java index 74174d60f..a449df7d1 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/EntryStackSubsetsMenuEntry.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/EntryStackSubsetsMenuEntry.java @@ -107,8 +107,9 @@ public class EntryStackSubsetsMenuEntry extends MenuEntry { recalculateFilter(menu); ConfigManager.getInstance().saveConfig(); EntryRegistry.getInstance().refilter(); - if (REIHelperImpl.getSearchField() != null) + if (REIHelperImpl.getSearchField() != null) { ContainerScreenOverlay.getEntryListWidget().updateSearch(REIHelperImpl.getSearchField().getText(), true); + } } } else if (!RoughlyEnoughItemsCore.isLeftMousePressed) clickedLast = false; } else clickedLast = false; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/SubSubsetsMenuEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/SubSubsetsMenuEntry.java index 4a33aa7d6..36c3426b6 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/SubSubsetsMenuEntry.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/SubSubsetsMenuEntry.java @@ -157,8 +157,9 @@ public class SubSubsetsMenuEntry extends MenuEntry { setFiltered(filteredStacks, overlay, this, !(getFilteredRatio() > 0)); ConfigManager.getInstance().saveConfig(); EntryRegistry.getInstance().refilter(); - if (REIHelperImpl.getSearchField() != null) + if (REIHelperImpl.getSearchField() != null) { ContainerScreenOverlay.getEntryListWidget().updateSearch(REIHelperImpl.getSearchField().getText(), true); + } } else { clickedBefore = true; } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchEntryRendererManager.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchEntryRendererManager.java new file mode 100644 index 000000000..6cafecb90 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchEntryRendererManager.java @@ -0,0 +1,143 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020 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; + +import com.google.common.collect.Iterables; +import com.mojang.blaze3d.vertex.PoseStack; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import me.shedaniel.rei.api.client.config.ConfigObject; +import me.shedaniel.rei.api.client.entry.renderer.BatchEntryRenderer; +import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer; +import me.shedaniel.rei.api.common.entry.EntryStack; +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 java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class BatchEntryRendererManager { + private boolean fastEntryRendering = ConfigObject.getInstance().doesFastEntryRendering(); + private Int2ObjectMap<List<EntryWidget>> grouping = new Int2ObjectOpenHashMap<>(); + private List<EntryWidget> toRender = new ArrayList<>(); + + public BatchEntryRendererManager() { + } + + public BatchEntryRendererManager(Collection<? extends EntryWidget> widgets) { + addAll(widgets); + } + + public void addAll(Collection<? extends EntryWidget> widgets) { + if (fastEntryRendering) { + for (EntryWidget widget : widgets) { + add(widget); + } + } else { + toRender.addAll(widgets); + } + } + + public void add(EntryWidget widget) { + if (fastEntryRendering) { + EntryStack<?> currentEntry = widget.getCurrentEntry(); + EntryRenderer<?> renderer = currentEntry.getRenderer(); + if (renderer instanceof BatchEntryRenderer) { + int hash = ((BatchEntryRenderer<Object>) renderer).getBatchId(currentEntry.cast()); + List<EntryWidget> entries = grouping.get(hash); + if (entries == null) { + grouping.put(hash, entries = new ArrayList<>()); + } + entries.add(widget); + return; + } + } + toRender.add(widget); + } + + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + render(false, null, null, matrices, mouseX, mouseY, delta); + } + + public void render(boolean debugTime, MutableInt size, MutableLong time, PoseStack matrices, int mouseX, int mouseY, float delta) { + if (fastEntryRendering) { + for (List<EntryWidget> entries : grouping.values()) { + renderEntries(debugTime, size, time, fastEntryRendering, matrices, mouseX, mouseY, delta, entries); + } + } + if (!toRender.isEmpty()) { + renderEntries(debugTime, size, time, fastEntryRendering, matrices, mouseX, mouseY, delta, toRender); + } + } + + + public static <T extends EntryWidget> void renderEntries(boolean debugTime, MutableInt size, MutableLong time, boolean fastEntryRendering, PoseStack matrices, int mouseX, int mouseY, float delta, Iterable<T> entries) { + T firstWidget = Iterables.getFirst(entries, null); + if (firstWidget == null) return; + @SuppressWarnings("rawtypes") + EntryStack first = firstWidget.getCurrentEntry(); + EntryRenderer<?> renderer = first.getRenderer(); + if (fastEntryRendering && renderer instanceof BatchEntryRenderer) { + BatchEntryRenderer<?> firstRenderer = (BatchEntryRenderer<?>) renderer; + firstRenderer.startBatch(first, matrices, delta); + long l = debugTime ? System.nanoTime() : 0; + MultiBufferSource.BufferSource immediate = Minecraft.getInstance().renderBuffers().bufferSource(); + for (T listEntry : entries) { + @SuppressWarnings("rawtypes") + EntryStack currentEntry = listEntry.getCurrentEntry(); + currentEntry.setZ(100); + listEntry.drawBackground(matrices, mouseX, mouseY, delta); + firstRenderer.renderBase(currentEntry, matrices, immediate, listEntry.getInnerBounds(), mouseX, mouseY, delta); + if (debugTime && !currentEntry.isEmpty()) size.increment(); + } + immediate.endBatch(); + for (T listEntry : entries) { + @SuppressWarnings("rawtypes") + EntryStack currentEntry = listEntry.getCurrentEntry(); + firstRenderer.renderOverlay(currentEntry, matrices, immediate, listEntry.getInnerBounds(), mouseX, mouseY, delta); + if (listEntry.containsMouse(mouseX, mouseY)) { + listEntry.queueTooltip(matrices, mouseX, mouseY, delta); + listEntry.drawHighlighted(matrices, mouseX, mouseY, delta); + } + } + immediate.endBatch(); + if (debugTime) time.add(System.nanoTime() - l); + firstRenderer.endBatch(first, matrices, delta); + } else { + for (T entry : entries) { + if (entry.getCurrentEntry().isEmpty()) + continue; + if (debugTime) { + size.increment(); + long l = System.nanoTime(); + entry.render(matrices, mouseX, mouseY, delta); + t |
