diff options
| author | shedaniel <daniel@shedaniel.me> | 2022-02-09 20:17:34 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2022-02-09 20:17:34 +0800 |
| commit | caa850ff55576c8aef92c28ab5dcf87a319f6e3a (patch) | |
| tree | 4fbb17d0d7ee6c3d523ff5839288315e483accea /runtime | |
| parent | 48ef9ff7f4b1be74006837b51a683d5e8b9bdc52 (diff) | |
| download | RoughlyEnoughItems-caa850ff55576c8aef92c28ab5dcf87a319f6e3a.tar.gz RoughlyEnoughItems-caa850ff55576c8aef92c28ab5dcf87a319f6e3a.tar.bz2 RoughlyEnoughItems-caa850ff55576c8aef92c28ab5dcf87a319f6e3a.zip | |
Migrate to Cloth Config's ValueAnimator, and add option to cache entry renders
Diffstat (limited to 'runtime')
26 files changed, 314 insertions, 90 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java index 9351303cb..d5a6ddf94 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java @@ -43,6 +43,7 @@ import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry; import me.shedaniel.rei.api.common.registry.ReloadStage; import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl; import me.shedaniel.rei.impl.client.gui.hints.HintProvider; +import me.shedaniel.rei.impl.client.gui.widget.CachedEntryListRender; import me.shedaniel.rei.impl.client.gui.widget.search.OverlaySearchField; import me.shedaniel.rei.impl.client.search.argument.Argument; import net.fabricmc.api.EnvType; @@ -240,6 +241,7 @@ public class REIRuntimeImpl implements REIRuntime { Argument.SEARCH_CACHE.clear(); getOverlay().ifPresent(ScreenOverlay::queueReloadOverlay); lastDisplayScreen.clear(); + CachedEntryListRender.refresh(); } @Override 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 4fe37ff72..e79aecaa8 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 @@ -255,6 +255,15 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { } @Override + public boolean doesCacheEntryRendering() { + return advanced.miscellaneous.cachingFastEntryRendering; + } + + public void setDoesCacheEntryRendering(boolean doesCacheEntryRendering) { + advanced.miscellaneous.cachingFastEntryRendering = doesCacheEntryRendering; + } + + @Override public boolean doDebugRenderTimeRequired() { return advanced.layout.debugRenderTimeRequired; } @@ -622,6 +631,8 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { @Comment("Declares whether arrows in containers should be clickable.") private boolean clickableRecipeArrows = true; private boolean registerRecipesInAnotherThread = true; private boolean newFastEntryRendering = true; + @ConfigEntry.Gui.PrefixText + private boolean cachingFastEntryRendering = false; } public static class Filtering { 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 2ea8b127a..5fcd5790e 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 @@ -30,8 +30,7 @@ import com.mojang.blaze3d.vertex.*; import com.mojang.math.Matrix4f; import me.shedaniel.clothconfig2.ClothConfigInitializer; import me.shedaniel.clothconfig2.api.ScissorsHandler; -import me.shedaniel.clothconfig2.api.ScrollingContainer; -import me.shedaniel.clothconfig2.gui.widget.DynamicNewSmoothScrollingEntryListWidget; +import me.shedaniel.clothconfig2.api.scroll.ScrollingContainer; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.math.impl.PointHelper; @@ -80,7 +79,7 @@ public class FilteringScreen extends Screen { } @Override - public int getScrollBarX() { + public int getScrollBarX(int maxX) { return width - 7; } }; @@ -130,7 +129,7 @@ public class FilteringScreen extends Screen { for (int i = 0; i < entryStacks.size(); i++) { EntryStack<?> stack = entryStacks.get(i); EntryListEntry entry = entries.get(i); - entry.getBounds().y = (int) (entry.backupY - scrolling.scrollAmount); + entry.getBounds().y = entry.backupY - scrolling.scrollAmountInt(); if (entry.isSelected() && !entry.isFiltered()) { filteringEntry.configFiltered.add(stack); filteringEntry.edited = true; @@ -145,7 +144,7 @@ public class FilteringScreen extends Screen { for (int i = 0; i < entryStacks.size(); i++) { EntryStack<?> stack = entryStacks.get(i); EntryListEntry entry = entries.get(i); - entry.getBounds().y = (int) (entry.backupY - scrolling.scrollAmount); + entry.getBounds().y = entry.backupY - scrolling.scrollAmountInt(); if (entry.isSelected() && filteringEntry.configFiltered.remove(stack)) { filteringEntry.edited = true; entry.dirty = true; @@ -219,14 +218,14 @@ public class FilteringScreen extends Screen { ScissorsHandler.INSTANCE.scissor(bounds); for (EntryListEntry entry : entries) entry.clearStacks(); - int skip = Math.max(0, Mth.floor(scrolling.scrollAmount / (float) entrySize())); + int skip = Math.max(0, Mth.floor(scrolling.scrollAmount() / (float) entrySize())); int nextIndex = skip * innerBounds.width / entrySize(); int i = nextIndex; BatchedEntryRendererManager manager = new BatchedEntryRendererManager(); for (; i < entryStacks.size(); i++) { EntryStack<?> stack = entryStacks.get(i); EntryListEntry entry = entries.get(nextIndex); - entry.getBounds().y = (int) (entry.backupY - scrolling.scrollAmount); + entry.getBounds().y = entry.backupY - scrolling.scrollAmountInt(); if (entry.getBounds().y > bounds.getMaxY()) break; entry.entry(stack); @@ -281,13 +280,13 @@ public class FilteringScreen extends Screen { Point p = secondPoint; if (p == null) { p = PointHelper.ofMouse(); - p.translate(0, (int) scrolling.scrollAmount); + p.translate(0, scrolling.scrollAmountInt()); } int left = Math.min(p.x, selectionPoint.x); int top = Math.min(p.y, selectionPoint.y); int right = Math.max(p.x, selectionPoint.x); int bottom = Math.max(p.y, selectionPoint.y); - selectionCache = new Rectangle(left, (int) (top - scrolling.scrollAmount), right - left, bottom - top); + selectionCache = new Rectangle(left, top - scrolling.scrollAmountInt(), right - left, bottom - top); return; } selectionCache = new Rectangle(0, 0, 0, 0); @@ -301,13 +300,6 @@ public class FilteringScreen extends Screen { } private void updatePosition(float delta) { - if (ConfigObject.getInstance().doesSnapToRows() && scrolling.scrollTarget >= 0 && scrolling.scrollTarget <= scrolling.getMaxScroll()) { - double nearestRow = Math.round(scrolling.scrollTarget / (double) entrySize()) * (double) entrySize(); - if (!DynamicNewSmoothScrollingEntryListWidget.Precision.almostEquals(scrolling.scrollTarget, nearestRow, DynamicNewSmoothScrollingEntryListWidget.Precision.FLOAT_EPSILON)) - scrolling.scrollTarget += (nearestRow - scrolling.scrollTarget) * Math.min(delta / 2.0, 1.0); - else - scrolling.scrollTarget = nearestRow; - } scrolling.updatePosition(delta); } @@ -377,7 +369,7 @@ public class FilteringScreen extends Screen { return true; } if (int_1 == 0) { - this.selectionPoint = new Point(double_1, double_2 + scrolling.scrollAmount); + this.selectionPoint = new Point(double_1, double_2 + scrolling.scrollAmount()); this.secondPoint = null; return true; } @@ -388,7 +380,7 @@ public class FilteringScreen extends Screen { @Override public boolean mouseReleased(double mouseX, double mouseY, int button) { if (selectionPoint != null && button == 0 && secondPoint == null) { - this.secondPoint = new Point(mouseX, mouseY + scrolling.scrollAmount); + this.secondPoint = new Point(mouseX, mouseY + scrolling.scrollAmount()); if (secondPoint.equals(selectionPoint)) { secondPoint.translate(1, 1); } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java index ff1fa2a2d..067e8d32e 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java @@ -442,6 +442,11 @@ public class ScreenOverlayImpl extends ScreenOverlay { config::setEntryListWidgetScrolled ), new SeparatorMenuEntry(), + ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.caching_entry_rendering"), + config::doesCacheEntryRendering, + config::setDoesCacheEntryRendering + ), + new SeparatorMenuEntry(), ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.side_search_field"), () -> config.getSearchFieldLocation() != SearchFieldLocation.CENTER, bool -> config.setSearchFieldLocation(bool ? SearchFieldLocation.BOTTOM_SIDE : SearchFieldLocation.CENTER) diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java index 1e204dbb2..df2d8d452 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java @@ -24,13 +24,13 @@ package me.shedaniel.rei.impl.client.gui.dragging; import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.clothconfig2.api.animator.NumberAnimator; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.math.FloatingRectangle; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.math.impl.PointHelper; import me.shedaniel.rei.RoughlyEnoughItemsCoreClient; -import me.shedaniel.rei.api.client.gui.animator.NumberAnimator; -import me.shedaniel.rei.api.client.gui.animator.ValueAnimator; import me.shedaniel.rei.api.client.gui.drag.*; import me.shedaniel.rei.api.client.gui.widgets.Widget; import me.shedaniel.rei.impl.client.gui.widget.LateRenderable; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/Menu.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/Menu.java index 15afb1a4b..490a22d2a 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/Menu.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/Menu.java @@ -29,7 +29,7 @@ import com.google.common.collect.Sets; import com.mojang.blaze3d.vertex.PoseStack; import me.shedaniel.clothconfig2.ClothConfigInitializer; import me.shedaniel.clothconfig2.api.ScissorsHandler; -import me.shedaniel.clothconfig2.api.ScrollingContainer; +import me.shedaniel.clothconfig2.api.scroll.ScrollingContainer; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.RoughlyEnoughItemsCore; @@ -244,7 +244,7 @@ public class Menu extends WidgetWithBounds implements LateRenderable { fill(matrices, innerBounds.x, innerBounds.y, innerBounds.getMaxX(), innerBounds.getMaxY(), -16777216); boolean contains = innerBounds.contains(mouseX, mouseY); MenuEntry focused = getFocused() instanceof MenuEntry menuEntry ? menuEntry : null; - int currentY = (int) (innerBounds.y - scrolling.scrollAmount); + int currentY = innerBounds.y - scrolling.scrollAmountInt(); for (MenuEntry child : children()) { boolean containsMouse = contains && mouseY >= currentY && mouseY < currentY + child.getEntryHeight(); if (containsMouse) { @@ -252,7 +252,7 @@ public class Menu extends WidgetWithBounds implements LateRenderable { } currentY += child.getEntryHeight(); } - currentY = (int) (innerBounds.y - scrolling.scrollAmount); + currentY = innerBounds.y - scrolling.scrollAmountInt(); ScissorsHandler.INSTANCE.scissor(scrolling.getScissorBounds()); for (MenuEntry child : children()) { boolean rendering = currentY + child.getEntryHeight() >= innerBounds.y && currentY <= innerBounds.getMaxY(); 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 27919c5d1..d6029865f 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 @@ -79,7 +79,7 @@ public class EntryStackSubsetsMenuEntry extends AbstractMenuEntry { REIRuntime.getInstance().queueTooltip(stack.getTooltip(new Point(mouseX, mouseY))); if (RoughlyEnoughItemsCoreClient.isLeftMousePressed && !clickedLast) { clickedLast = true; - if (!getParent().scrolling.draggingScrollBar) { + if (getParent().scrolling.getScissorBounds().contains(mouseX, mouseY)) { minecraft.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F)); List<EntryStackProvider<?>> filteredStacks = ConfigObject.getInstance().getFilteredStackProviders(); if (isFiltered()) { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java index f986f5e61..1102abca8 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java @@ -27,7 +27,7 @@ import com.google.common.collect.Lists; import com.mojang.blaze3d.vertex.PoseStack; import me.shedaniel.clothconfig2.ClothConfigInitializer; import me.shedaniel.clothconfig2.api.ScissorsHandler; -import me.shedaniel.clothconfig2.api.ScrollingContainer; +import me.shedaniel.clothconfig2.api.scroll.ScrollingContainer; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.math.impl.PointHelper; @@ -109,7 +109,6 @@ public class CompositeDisplayViewingScreen extends AbstractDisplayViewingScreen super.init(); boolean isCompactTabs = ConfigObject.getInstance().isUsingCompactTabs(); int tabSize = isCompactTabs ? 24 : 28; - scrolling.draggingScrollBar = false; this.children().clear(); this.widgets.clear(); this.buttonList.clear(); @@ -357,7 +356,7 @@ public class CompositeDisplayViewingScreen extends AbstractDisplayViewingScreen matrices.pushPose(); ScissorsHandler.INSTANCE.scissor(scrolling.getBounds()); for (Button button : buttonList) { - button.getBounds().y = scrollListBounds.y + 1 + yOffset - (int) scrolling.scrollAmount; + button.getBounds().y = scrollListBounds.y + 1 + yOffset - scrolling.scrollAmountInt(); if (button.getBounds().getMaxY() > scrollListBounds.getMinY() && button.getBounds().getMinY() < scrollListBounds.getMaxY()) { button.render(matrices, mouseX, mouseY, delta); } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java index e90637e2e..b5457e2ed 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java @@ -30,13 +30,13 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.math.Matrix4f; import me.shedaniel.clothconfig2.api.ModifierKeyCode; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.math.Color; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.math.impl.PointHelper; import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigObject; -import me.shedaniel.rei.api.client.gui.animator.ValueAnimator; import me.shedaniel.rei.api.client.gui.widgets.Button; import me.shedaniel.rei.api.client.gui.widgets.Panel; import me.shedaniel.rei.api.client.gui.widgets.Widget; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/UncertainDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/UncertainDisplayViewingScreen.java index 7a363f315..e9c71f7cd 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/UncertainDisplayViewingScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/UncertainDisplayViewingScreen.java @@ -30,6 +30,8 @@ import com.mojang.math.Matrix4f; import dev.architectury.platform.Platform; import it.unimi.dsi.fastutil.booleans.BooleanConsumer; import me.shedaniel.clothconfig2.api.ScissorsHandler; +import me.shedaniel.clothconfig2.api.animator.NumberAnimator; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.clothconfig2.gui.widget.DynamicNewSmoothScrollingEntryListWidget; import me.shedaniel.clothconfig2.impl.EasingMethod; import me.shedaniel.math.Point; @@ -40,8 +42,6 @@ import me.shedaniel.rei.api.client.ClientHelper; import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigManager; import me.shedaniel.rei.api.client.config.ConfigObject; -import me.shedaniel.rei.api.client.gui.animator.NumberAnimator; -import me.shedaniel.rei.api.client.gui.animator.ValueAnimator; import me.shedaniel.rei.api.client.gui.config.DisplayScreenType; import me.shedaniel.rei.api.client.gui.widgets.Button; import me.shedaniel.rei.api.client.gui.widgets.Widget; 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 4693b12c9..ff472a9be 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 @@ -212,7 +212,7 @@ public class BatchedEntryRendererManager { firstRenderer.endBatch(first, extraData[0], matrices, delta); } - private static <T extends EntryWidget> void renderSlow(boolean debugTime, MutableInt size, MutableLong time, PoseStack matrices, int mouseX, int mouseY, float delta, Iterable<T> entries) { + public static <T extends EntryWidget> void renderSlow(boolean debugTime, MutableInt size, MutableLong time, PoseStack matrices, int mouseX, int mouseY, float delta, Iterable<T> entries) { for (T entry : entries) { if (entry.getCurrentEntry().isEmpty()) continue; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/CachedEntryListRender.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/CachedEntryListRender.java new file mode 100644 index 000000000..65447b81b --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/CachedEntryListRender.java @@ -0,0 +1,176 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.impl.client.gui.widget; + +import com.mojang.blaze3d.pipeline.TextureTarget; +import com.mojang.blaze3d.platform.Lighting; +import com.mojang.blaze3d.platform.NativeImage; +import com.mojang.blaze3d.platform.Window; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Matrix4f; +import dev.architectury.registry.ReloadListenerRegistry; +import it.unimi.dsi.fastutil.longs.Long2LongMap; +import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.RoughlyEnoughItemsCore; +import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer; +import me.shedaniel.rei.api.client.registry.entry.EntryRegistry; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; +import me.shedaniel.rei.api.common.util.EntryStacks; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.PackType; +import net.minecraft.util.Unit; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class CachedEntryListRender { + public static final int RESOLUTION = 64; + public static DynamicTexture cachedTexture; + public static ResourceLocation cachedTextureLocation; + public static Long2LongMap hash = new Long2LongOpenHashMap(); + + public static class Sprite { + public final float u0; + public final float u1; + public final float v0; + public final float v1; + + public Sprite(float u0, float u1, float v0, float v1) { + this.u0 = u0; + this.u1 = u1; + this.v0 = v0; + this.v1 = v1; + } + } + + static { + ReloadListenerRegistry.register(PackType.CLIENT_RESOURCES, (barrier, resourceManager, preparationProfiler, reloadProfiler, preparationExecutor, reloadExecutor) -> { + return barrier.wait(Unit.INSTANCE).thenRunAsync(CachedEntryListRender::refresh, reloadExecutor); + }); + } + + public static void refresh() { + RoughlyEnoughItemsCore.LOGGER.info("Refreshing cached entry list texture..."); + if (cachedTextureLocation != null) { + Minecraft.getInstance().getTextureManager().release(cachedTextureLocation); + cachedTextureLocation = null; + } + if (cachedTexture != null) { + cachedTexture.close(); + cachedTexture = null; + } + hash = new Long2LongOpenHashMap(); + } + + @Nullable + public static Sprite get(EntryStack<?> stack) { + if (stack.getType() == VanillaEntryTypes.ITEM) { + if (stack.getNullable(EntryStack.Settings.RENDERER) != null) { + return null; + } + + if (cachedTexture == null) { + prepare(); + } + + long hashExact = EntryStacks.hashExact(stack); + + long hashOrDefault = hash.getOrDefault(hashExact, -1L); + if (hashOrDefault != -1L) { + // unpack + int x = (int) (hashOrDefault >> 32); + int y = (int) (hashOrDefault & 0xFFFFFFFFL); + float width = cachedTexture.getPixels().getWidth(); + float height = cachedTexture.getPixels().getWidth(); + return new Sprite(x * RESOLUTION / width, (x + 1) * RESOLUTION / width, y * RESOLUTION / height, (y + 1) * RESOLUTION / height); + } + } + + return null; + } + + private static void prepare() { + int side = 4; + List<EntryStack<?>> list = EntryRegistry.getInstance().getPreFilteredList(); + while (side * side < list.size()) { + side++; + } + + int width = side * RESOLUTION; + int height = side * RESOLUTION; + + RoughlyEnoughItemsCore.LOGGER.info("Preparing cached texture with size %sx%s for %sx%s entries", width, height, side, side); + + hash = new Long2LongOpenHashMap(list.size() + 10); + Minecraft minecraft = Minecraft.getInstance(); + Window window = minecraft.getWindow(); + TextureTarget target = new TextureTarget(width, height, true, false); + target.bindWrite(true); + Matrix4f projectionMatrix = Matrix4f.orthographic(0.0F, width, 0.0F, height, 1000.0F, 3000.0F); + RenderSystem.setProjectionMatrix(projectionMatrix); + PoseStack modelViewStack = RenderSystem.getModelViewStack(); + modelViewStack.pushPose(); + modelViewStack.setIdentity(); + modelViewStack.translate(0.0D, 0.0D, -2000.0D); + RenderSystem.applyModelViewMatrix(); + + Lighting.setupFor3DItems(); + PoseStack matrices = new PoseStack(); + Rectangle bounds = new Rectangle(); + + int index = 0; + for (EntryStack<?> stack : list) { + int x = index % side; + int y = index / side; + bounds.setBounds(x * RESOLUTION, y * RESOLUTION, RESOLUTION, RESOLUTION); + ((EntryRenderer<Object>) stack.getDefinition().getRenderer()).render((EntryStack<Object>) stack, matrices, bounds, -1, -1, 0); + hash.put(EntryStacks.hashExact(stack), pack(x, y)); + index++; + } + + NativeImage nativeImage = new NativeImage(width, height, false); + RenderSystem.bindTexture(target.getColorTextureId()); + nativeImage.downloadTexture(0, false); + nativeImage.flipY(); + + cachedTexture = new DynamicTexture(nativeImage); + cachedTextureLocation = minecraft.getTextureManager().register("rei_cached_entries", cachedTexture); + + target.destroyBuffers(); + Minecraft.getInstance().levelRenderer.graphicsChanged(); + Minecraft.getInstance().getMainRenderTarget().bindWrite(true); + + modelViewStack.popPose(); + RenderSystem.applyModelViewMatrix(); + } + + private static long pack(int x, int y) { + return ((long) x << 32) | (y & 0xFFFF |
