diff options
Diffstat (limited to 'runtime-frontend/widgets/src/main/java/me')
24 files changed, 4018 insertions, 0 deletions
diff --git a/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/tooltip/MissingStacksTooltip.java b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/tooltip/MissingStacksTooltip.java new file mode 100644 index 000000000..696384d03 --- /dev/null +++ b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/tooltip/MissingStacksTooltip.java @@ -0,0 +1,106 @@ +/* + * 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.tooltip; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.math.Matrix4f; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.SimpleDisplayRenderer; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.entry.EntryStack; +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.util.Mth; +import net.minecraft.world.inventory.tooltip.TooltipComponent; + +import java.util.List; + +public class MissingStacksTooltip implements ClientTooltipComponent, TooltipComponent { + private static final int MAX_WIDTH = 200; + private final List<EntryIngredient> stacks; + + public MissingStacksTooltip(List<EntryIngredient> stacks) { + this.stacks = SimpleDisplayRenderer.simplify(stacks); + } + + @Override + public int getHeight() { + int entrySize = 18; + int w = Math.max(1, MAX_WIDTH / entrySize); + int height = Math.min(6, Mth.ceil(stacks.size() / (float) w)) * entrySize + 2; + height += 12; + return height; + } + + @Override + public int getWidth(Font font) { + int entrySize = 18; + int w = Math.max(1, MAX_WIDTH / entrySize); + int size = stacks.size(); + int width = Math.min(size, w) * entrySize; + width = Math.max(width, font.width(new TranslatableComponent("text.rei.missing"))); + return width; + } + + @Override + public void renderImage(Font font, int x, int y, PoseStack poses, ItemRenderer renderer, int z) { + int entrySize = 18; + int w = Math.max(1, MAX_WIDTH / entrySize); + int i = 0; + poses.pushPose(); + poses.translate(0, 0, z + 50); + for (EntryIngredient entry : stacks) { + int x1 = x + (i % w) * entrySize; + int y1 = y + 13 + (i / w) * entrySize; + i++; + if (i / w > 5) { + MultiBufferSource.BufferSource source = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder()); + Component text = new TextComponent("+" + (stacks.size() - w * 6 + 1)).withStyle(ChatFormatting.GRAY); + font.drawInBatch(text, x1 + entrySize / 2 - font.width(text) / 2, y1 + entrySize / 2 - 1, -1, true, poses.last().pose(), source, false, 0, 15728880); + source.endBatch(); + break; + } else { + EntryStack<?> stack; + if (entry.isEmpty()) stack = EntryStack.empty(); + else if (entry.size() == 1) stack = entry.get(0); + else stack = entry.get(Mth.floor((System.currentTimeMillis() / 1000 % (double) entry.size()))); + stack.render(poses, new Rectangle(x1, y1, entrySize, entrySize), -1000, -1000, 0); + } + } + poses.popPose(); + } + + @Override + public void renderText(Font font, int x, int y, Matrix4f pose, MultiBufferSource.BufferSource buffers) { + font.drawInBatch(new TranslatableComponent("text.rei.missing").withStyle(ChatFormatting.GRAY), + x, y + 2, -1, true, pose, buffers, false, 0, 15728880); + } +} diff --git a/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/tooltip/MissingStacksTooltipProviderImpl.java b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/tooltip/MissingStacksTooltipProviderImpl.java new file mode 100644 index 000000000..66e027634 --- /dev/null +++ b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/tooltip/MissingStacksTooltipProviderImpl.java @@ -0,0 +1,37 @@ +/* + * 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.tooltip; + +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.impl.client.provider.MissingStacksTooltipProvider; +import net.minecraft.world.inventory.tooltip.TooltipComponent; + +import java.util.List; + +public class MissingStacksTooltipProviderImpl implements MissingStacksTooltipProvider { + @Override + public TooltipComponent provide(List<EntryIngredient> stacks) { + return new MissingStacksTooltip(stacks); + } +} diff --git a/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ArrowWidget.java b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ArrowWidget.java new file mode 100644 index 000000000..8afb30220 --- /dev/null +++ b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ArrowWidget.java @@ -0,0 +1,98 @@ +/* + * 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.basewidgets; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.clothconfig2.api.animator.NumberAnimator; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.REIRuntime; +import me.shedaniel.rei.api.client.config.ConfigObject; +import me.shedaniel.rei.api.client.gui.widgets.Arrow; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.util.Mth; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +final class ArrowWidget extends Arrow { + private Rectangle bounds; + private double animationDuration = -1; + private final NumberAnimator<Float> darkBackgroundAlpha = ValueAnimator.ofFloat() + .withConvention(() -> ConfigObject.getInstance().isUsingDarkTheme() ? 1.0F : 0.0F, ValueAnimator.typicalTransitionTime()) + .asFloat(); + + public ArrowWidget(Rectangle bounds) { + this.bounds = new Rectangle(Objects.requireNonNull(bounds)); + } + + @Override + public double getAnimationDuration() { + return animationDuration; + } + + @Override + public void setAnimationDuration(double animationDurationMS) { + this.animationDuration = animationDurationMS; + if (this.animationDuration <= 0) + this.animationDuration = -1; + } + + @Override + public Rectangle getBounds() { + return bounds; + } + + @Override + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + this.darkBackgroundAlpha.update(delta); + renderBackground(matrices, false, 1.0F); + if (darkBackgroundAlpha.value() > 0.0F) { + renderBackground(matrices, true, this.darkBackgroundAlpha.value()); + } + } + + public void renderBackground(PoseStack matrices, boolean dark, float alpha) { + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, alpha); + RenderSystem.setShaderTexture(0, REIRuntime.getInstance().getDefaultDisplayTexture(dark)); + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(770, 771, 1, 0); + RenderSystem.blendFunc(770, 771); + if (getAnimationDuration() > 0) { + int width = Mth.ceil((System.currentTimeMillis() / (animationDuration / 24) % 24d)); + blit(matrices, getX() + width, getY(), 106 + width, 91, 24 - width, 17); + blit(matrices, getX(), getY(), 82, 91, width, 17); + } else { + blit(matrices, getX(), getY(), 106, 91, 24, 17); + } + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + } + + @Override + public List<? extends GuiEventListener> children() { + return Collections.emptyList(); + } +} diff --git a/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BatchedSlotsImpl.java b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BatchedSlotsImpl.java new file mode 100644 index 000000000..dc1b2e4dc --- /dev/null +++ b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BatchedSlotsImpl.java @@ -0,0 +1,350 @@ +/* + * 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.basewidgets; + +import com.google.common.collect.AbstractIterator; +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.math.Point; +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.client.gui.widgets.BatchedSlots; +import me.shedaniel.rei.api.client.gui.widgets.Slot; +import me.shedaniel.rei.api.client.gui.widgets.Tooltip; +import me.shedaniel.rei.api.client.gui.widgets.TooltipContext; +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.gui.components.events.GuiEventListener; +import net.minecraft.client.renderer.MultiBufferSource; +import org.apache.commons.lang3.mutable.MutableInt; +import org.apache.commons.lang3.mutable.MutableLong; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +final class BatchedSlotsImpl extends BatchedSlots implements ForwardingList<Slot> { + private final boolean fastEntryRendering = ConfigObject.getInstance().doesFastEntryRendering(); + private final Int2ObjectMap<List<Object>> grouping = new Int2ObjectOpenHashMap<>(); + private final List<Slot> toRender = new ArrayList<>(); + private final List<Slot> delegateList = new DelegatedSlotList(); + private int size; + public boolean debug; + public MutableInt debugSize = new MutableInt(); + public MutableLong debugTime = new MutableLong(); + + @Override + public boolean isBatched() { + return fastEntryRendering; + } + + @Override + public List<Slot> delegate() { + return delegateList; + } + + @Override + public void addAllUnbatched(Collection<? extends Slot> slots) { + this.toRender.addAll(slots); + this.size += slots.size(); + } + + @Override + public void addDebugger(MutableInt size, MutableLong time) { + this.debug = true; + this.debugSize = size; + this.debugTime = time; + } + + @Override + public void addUnbatched(Slot slot) { + this.toRender.add(slot); + this.size++; + } + + @Override + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + if (this.debug) { + render(false, null, null, matrices, mouseX, mouseY, delta); + } else { + render(true, debugSize, debugTime, 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<Object> entries : grouping.values()) { + Object[] extraData = new Object[entries.size() / 2]; + for (int i = 0; i < extraData.length; i++) { + extraData[i] = entries.get(i * 2 + 1); + } + renderBatched(debugTime, size, time, matrices, mouseX, mouseY, delta, groupingAsList(entries), extraData); + } + } + if (!toRender.isEmpty()) { + renderSlow(debugTime, size, time, matrices, mouseX, mouseY, delta, toRender); + } + } + + public List<Slot> groupingsAsList() { + return CollectionUtils.concatUnmodifiable((Iterable<List<Slot>>) () -> new AbstractIterator<>() { + final Iterator<List<Object>> groups = grouping.values().iterator(); + + @Nullable + @Override + protected List<Slot> computeNext() { + if (groups.hasNext()) { + return groupingAsList(groups.next()); + } + return endOfData(); + } + }); + } + + public List<Slot> groupingAsList(List<Object> entries) { + return new AbstractList<>() { + @Override + public Slot get(int index) { + return (Slot) entries.get(index * 2); + } + + @Override + public Iterator<Slot> iterator() { + return new AbstractIterator<>() { + public int i = 0; + + @Override + protected Slot computeNext() { + if (i >= entries.size()) { + return endOfData(); + } + Slot widget = (Slot) entries.get(i); + i += 2; + return widget; + } + }; + } + + @Override + public int size() { + return entries.size() / 2; + } + }; + } + + public static void renderEntries(boolean debugTime, MutableInt size, MutableLong time, boolean fastEntryRendering, PoseStack matrices, int mouseX, int mouseY, float delta, Collection<? extends Slot> entries) { + if (fastEntryRendering) { + Slot firstWidget = Iterables.getFirst(entries, null); + if (firstWidget == null) return; + EntryRenderer<?> renderer = firstWidget.getCurrentEntry().getRenderer(); + if (renderer instanceof BatchedEntryRenderer) { + BatchedEntryRenderer<?, Object> firstRenderer = (BatchedEntryRenderer<?, Object>) renderer; + Object[] extraData = new Object[entries.size()]; + int i = 0; + for (Slot entry : entries) { + EntryStack<?> currentEntry = entry.getCurrentEntry(); + extraData[i++] = ((BatchedEntryRenderer<Object, Object>) currentEntry.getRenderer()).getExtraData(currentEntry.cast()); + } + renderBatched(debugTime, size, time, matrices, mouseX, mouseY, delta, entries, extraData); + return; + } + } + renderSlow(debugTime, size, time, matrices, mouseX, mouseY, delta, entries); + } + + private static void renderBatched(boolean debugTime, MutableInt size, MutableLong time, PoseStack matrices, int mouseX, int mouseY, float delta, Iterable<? extends Slot> entries, Object[] extraData) { + Slot firstWidget = Iterables.getFirst(entries, null); + if (firstWidget == null) return; + @SuppressWarnings("rawtypes") + EntryStack first = firstWidget.getCurrentEntry(); + EntryRenderer<?> renderer = first.getRenderer(); + BatchedEntryRenderer<?, Object> firstRenderer = (BatchedEntryRenderer<?, Object>) renderer; + matrices = firstRenderer.batchModifyMatrices(matrices); + long l = debugTime ? System.nanoTime() : 0; + MultiBufferSource.BufferSource immediate = Minecraft.getInstance().renderBuffers().bufferSource(); + int i = 0; + for (Slot entry : entries) { + try { + entry.drawBackground(matrices, mouseX, mouseY, delta); + } catch (Throwable throwable) { + CrashReport report = CrashReportUtils.essential(throwable, "Rendering entry background"); + CrashReportUtils.renderer(report, entry); + CrashReportUtils.catchReport(report); + return; + } + } + firstRenderer.startBatch(first, extraData[0], matrices, delta); + for (Slot entry : entries) { + try { + @SuppressWarnings("rawtypes") + EntryStack currentEntry = entry.getCurrentEntry(); + currentEntry.setZ(100); + firstRenderer.renderBase(currentEntry, extraData[i++], matrices, immediate, entry.getInnerBounds(), mouseX, mouseY, delta); + if (debugTime && !currentEntry.isEmpty()) size.increment(); + } catch (Throwable throwable) { + CrashReport report = CrashReportUtils.essential(throwable, "Rendering entry base"); + CrashReportUtils.renderer(report, entry); + CrashReportUtils.catchReport(report); + return; + } + } + immediate.endBatch(); + firstRenderer.afterBase(first, extraData[0], matrices, delta); + i = 0; + for (Slot entry : entries) { + try { + @SuppressWarnings("rawtypes") + EntryStack currentEntry = entry.getCurrentEntry(); + firstRenderer.renderOverlay(currentEntry, extraData[i++], matrices, immediate, entry.getInnerBounds(), mouseX, mouseY, delta); + } catch (Throwable throwable) { + CrashReport report = CrashReportUtils.essential(throwable, "Rendering entry base"); + CrashReportUtils.renderer(report, entry); + CrashReportUtils.catchReport(report); + return; + } + } + immediate.endBatch(); + for (Slot entry : entries) { + try { + if (entry.containsMouse(mouseX, mouseY)) { + Tooltip tooltip = entry.getCurrentTooltip(TooltipContext.of(new Point(mouseX, mouseY))); + if (tooltip != null) { + tooltip.queue(); + } + + if (entry.isHighlightEnabled()) { + entry.drawHighlighted(matrices, mouseX, mouseY, delta); + } + } + + entry.drawExtra(matrices, mouseX, mouseY, delta); + } catch (Throwable throwable) { + CrashReport report = CrashReportUtils.essential(throwable, "Rendering entry extra"); + CrashReportUtils.renderer(report, entry); + CrashReportUtils.catchReport(report); + return; + } + } + if (debugTime) time.add(System.nanoTime() - l); + firstRenderer.endBatch(first, extraData[0], matrices, delta); + } + + public static void renderSlow(boolean debugTime, MutableInt size, MutableLong time, PoseStack matrices, int mouseX, int mouseY, float delta, Iterable<? extends Slot> entries) { + for (Slot entry : entries) { + if (entry.getCurrentEntry().isEmpty()) + continue; + try { + if (debugTime) { + size.increment(); + long l = System.nanoTime(); + entry.render(matrices, mouseX, mouseY, delta); + time.add(System.nanoTime() - l); + } else entry.render(matrices, mouseX, mouseY, delta); + } catch (Throwable throwable) { + CrashReport report = CrashReportUtils.essential(throwable, "Rendering entry"); + CrashReportUtils.renderer(report, entry); + CrashReportUtils.catchReport(report); + return; + } + } + } + + @Override + public List<? extends GuiEventListener> children() { + return null; + } + + private class DelegatedSlotList extends AbstractList<Slot> { + private final List<Slot> unmodifiable = CollectionUtils.concatUnmodifiable(toRender, + groupingsAsList()); + + @Override + public void add(int index, Slot element) { + add(element); + } + + @Override + public int size() { + return size; + } + + @Override + public boolean add(Slot widget) { + if (fastEntryRendering) { + EntryStack<?> currentEntry = widget.getCurrentEntry(); + try { + EntryRenderer<?> renderer = currentEntry.getRenderer(); + if (renderer instanceof BatchedEntryRenderer) { + BatchedEntryRenderer<Object, Object> batchedRenderer = (BatchedEntryRenderer<Object, Object>) renderer; + EntryStack<Object> cast = currentEntry.cast(); + if (batchedRenderer.isBatched(cast)) { + Object extraData = batchedRenderer.getExtraData(cast); + int hash = batchedRenderer.getBatchIdentifier(cast, widget.getBounds(), extraData) + ^ widget.getCurrentEntry().getType().hashCode(); + List<Object> entries = grouping.get(hash); + if (entries == null) { + grouping.put(hash, entries = new ArrayList<>()); + } + entries.add(widget); + entries.add(extraData); + size++; + return true; + } + } + } catch (Throwable throwable) { + CrashReport report = CrashReportUtils.essential(throwable, "Adding entry"); + CrashReportUtils.renderer(report, currentEntry); + CrashReportUtils.catchReport(report); + return false; + } + } + + addUnbatched(widget); + return true; + } + + @Override + public Slot get(int index) { + return unmodifiable.get(index); + } + + @Override + public boolean addAll(Collection<? extends Slot> widgets) { + if (fastEntryRendering) { + for (Slot widget : widgets) { + add(widget); + } + } else { + addAllUnbatched(widgets); + } + + return true; + } + } +} diff --git a/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BurningFireWidget.java b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BurningFireWidget.java new file mode 100644 index 000000000..4140de261 --- /dev/null +++ b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BurningFireWidg |
