aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2021-03-28 20:35:46 +0800
committershedaniel <daniel@shedaniel.me>2021-03-28 20:35:46 +0800
commitebf2bb9dfa1f0e1abca845d7283e6e74ad8b00cd (patch)
treecc2e4c4d101aaaf5dcbc9dd5cebb9d7f7b3a7982
parent9d835c7823978e04007414cfe3ebf128e23a6494 (diff)
downloadRoughlyEnoughItems-ebf2bb9dfa1f0e1abca845d7283e6e74ad8b00cd.tar.gz
RoughlyEnoughItems-ebf2bb9dfa1f0e1abca845d7283e6e74ad8b00cd.tar.bz2
RoughlyEnoughItems-ebf2bb9dfa1f0e1abca845d7283e6e74ad8b00cd.zip
Optimise > 1 million entries & Improve Favorites Dragging
Signed-off-by: shedaniel <daniel@shedaniel.me>
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/client/entry/renderer/BatchEntryRenderer.java5
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/client/view/Views.java2
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/common/entry/EntryStack.java2
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/common/util/EntryStacks.java4
-rwxr-xr-xbuild.gradle6
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/GameModeFavoriteEntry.java6
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/WeatherFavoriteEntry.java19
-rw-r--r--forge/src/main/java/me/shedaniel/rei/forge/PluginDetectorImpl.java6
-rw-r--r--gradle.properties2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java3
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringScreen.java20
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ContainerScreenOverlay.java10
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/EntryStackSubsetsMenuEntry.java3
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/SubSubsetsMenuEntry.java3
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchEntryRendererManager.java143
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java232
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java4
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java74
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java141
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/SearchProviderImpl.java14
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/view/ViewsImpl.java11
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/AbstractEntryStack.java8
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java4
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/plugin/test/REITestPlugin.java18
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