diff options
Diffstat (limited to 'runtime/src/main/java/me')
6 files changed, 184 insertions, 22 deletions
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 29bfeef7b..1fcd50f82 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 @@ -31,6 +31,9 @@ import me.shedaniel.rei.api.client.config.ConfigObject; import me.shedaniel.rei.api.client.entry.renderer.BatchedEntryRenderer; import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer; import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.impl.client.util.CrashReportUtils; +import net.minecraft.CrashReport; +import net.minecraft.ReportedException; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import org.apache.commons.lang3.mutable.MutableInt; @@ -131,31 +134,55 @@ public class BatchedEntryRendererManager { MultiBufferSource.BufferSource immediate = Minecraft.getInstance().renderBuffers().bufferSource(); int i = 0; for (T entry : entries) { - entry.drawBackground(matrices, mouseX, mouseY, delta); + try { + entry.drawBackground(matrices, mouseX, mouseY, delta); + } catch (Throwable throwable) { + CrashReport report = CrashReportUtils.essential(throwable, "Rendering entry background"); + CrashReportUtils.renderer(report, entry); + throw new ReportedException(report); + } } firstRenderer.startBatch(first, extraData[0], matrices, delta); for (T entry : entries) { - @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(); + 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); + throw new ReportedException(report); + } } immediate.endBatch(); firstRenderer.afterBase(first, extraData[0], matrices, delta); i = 0; for (T entry : entries) { - @SuppressWarnings("rawtypes") - EntryStack currentEntry = entry.getCurrentEntry(); - firstRenderer.renderOverlay(currentEntry, extraData[i++], matrices, immediate, entry.getInnerBounds(), mouseX, mouseY, delta); + 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); + throw new ReportedException(report); + } } immediate.endBatch(); for (T entry : entries) { - if (entry.containsMouse(mouseX, mouseY)) { - entry.queueTooltip(matrices, mouseX, mouseY, delta); - entry.drawHighlighted(matrices, mouseX, mouseY, delta); + try { + if (entry.containsMouse(mouseX, mouseY)) { + entry.queueTooltip(matrices, mouseX, mouseY, delta); + 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); + throw new ReportedException(report); } - entry.drawExtra(matrices, mouseX, mouseY, delta); } if (debugTime) time.add(System.nanoTime() - l); firstRenderer.endBatch(first, extraData[0], matrices, delta); @@ -165,12 +192,18 @@ public class BatchedEntryRendererManager { for (T entry : entries) { if (entry.getCurrentEntry().isEmpty()) continue; - 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); + 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); + throw new ReportedException(report); + } } } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java index a26a6fbc2..781db8d0c 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java @@ -43,6 +43,8 @@ import me.shedaniel.rei.api.client.view.ViewSearchBuilder; import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.impl.client.REIRuntimeImpl; import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl; +import net.minecraft.CrashReport; +import net.minecraft.CrashReportCategory; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.resources.language.I18n; @@ -482,4 +484,20 @@ public class EntryWidget extends Slot implements DraggableStackProviderWidget { render(matrices, mouseX, mouseY, delta); getBounds().setBounds(clone); } + + @Override + public void fillCrashReport(CrashReport report, CrashReportCategory category) { + super.fillCrashReport(report, category); + category.setDetail("Notice mark", () -> String.valueOf(getNoticeMark())); + category.setDetail("Interactable", () -> String.valueOf(isInteractable())); + category.setDetail("Interactable favorites", () -> String.valueOf(isInteractableFavorites())); + category.setDetail("Highlight enabled", () -> String.valueOf(isHighlightEnabled())); + category.setDetail("Tooltip enabled", () -> String.valueOf(isTooltipsEnabled())); + category.setDetail("Background enabled", () -> String.valueOf(isBackgroundEnabled())); + category.setDetail("Entries count", () -> String.valueOf(entryStacks.size())); + EntryStack<?> currentEntry = getCurrentEntry(); + + CrashReportCategory entryCategory = report.addCategory("Current Rendering Entry"); + currentEntry.fillCrashReport(report, entryCategory); + } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/util/CrashReportUtils.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/util/CrashReportUtils.java new file mode 100644 index 000000000..c3c66ab13 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/util/CrashReportUtils.java @@ -0,0 +1,57 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021 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.util; + +import me.shedaniel.rei.api.client.gui.Renderer; +import net.minecraft.CrashReport; +import net.minecraft.CrashReportCategory; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.Screen; + +public class CrashReportUtils { + public static CrashReport essential(Throwable throwable, String task) { + CrashReport report = CrashReport.forThrowable(throwable, "Rendering background of entry"); + screen(report, Minecraft.getInstance().screen); + return report; + } + + private static void screen(CrashReport report, Screen screen) { + if (screen != null) { + CrashReportCategory category = report.addCategory("Screen details"); + String screenName = screen.getClass().getCanonicalName(); + category.setDetail("Screen name", () -> screenName); + } + } + + public static void renderer(CrashReport report, Renderer renderer) { + if (renderer != null) { + CrashReportCategory category = report.addCategory("Renderer details"); + try { + renderer.fillCrashReport(report, category); + } catch (Throwable throwable) { + category.setDetailError("Filling Report", throwable); + } + } + } +} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/AbstractEntryStack.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/AbstractEntryStack.java index ae09bcd7e..20194e7a7 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/AbstractEntryStack.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/AbstractEntryStack.java @@ -38,6 +38,8 @@ import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.api.common.util.EntryStacks; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.CrashReport; +import net.minecraft.CrashReportCategory; import net.minecraft.client.Minecraft; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -200,4 +202,19 @@ public abstract class AbstractEntryStack<A> extends AbstractRenderer implements public Component asFormattedText() { return getDefinition().asFormattedText(this, getValue()); } + + @Override + public void fillCrashReport(CrashReport report, CrashReportCategory category) { + super.fillCrashReport(report, category); + category.setDetail("Entry type", () -> String.valueOf(getType().getId())); + category.setDetail("Is empty", () -> String.valueOf(isEmpty())); + category.setDetail("Entry identifier", () -> String.valueOf(getIdentifier())); + + CrashReportCategory rendererCategory = report.addCategory("Entry Renderer"); + try { + getDefinition().fillCrashReport(report, rendererCategory, this); + } catch (Throwable throwable) { + rendererCategory.setDetailError("Filling Report", throwable); + } + } } diff --git a/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/FluidEntryDefinition.java b/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/FluidEntryDefinition.java index 121c49c18..90e1da0bd 100644 --- a/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/FluidEntryDefinition.java +++ b/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/FluidEntryDefinition.java @@ -23,6 +23,7 @@ package me.shedaniel.rei.plugin.client.entry; +import com.google.common.base.Suppliers; import com.google.common.collect.Lists; import com.mojang.blaze3d.vertex.PoseStack; import dev.architectury.fluid.FluidStack; @@ -47,10 +48,14 @@ import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.ChatFormatting; +import net.minecraft.CrashReport; +import net.minecraft.CrashReportCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.language.I18n; import net.minecraft.core.Registry; @@ -69,6 +74,7 @@ import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -174,7 +180,21 @@ public class FluidEntryDefinition implements EntryDefinition<FluidStack>, EntryS return collection == null ? Collections.emptyList() : collection.getMatchingTags(value.getFluid()); } + @Override + public void fillCrashReport(CrashReport report, CrashReportCategory category, EntryStack<FluidStack> entry) { + EntryDefinition.super.fillCrashReport(report, category, entry); + FluidStack stack = entry.getValue(); + category.setDetail("Fluid Type", () -> String.valueOf(Registry.FLUID.getKey(stack.getFluid()))); + category.setDetail("Fluid Amount", () -> String.valueOf(stack.getAmount())); + category.setDetail("Fluid NBT", () -> String.valueOf(stack.getTag())); + } + public static class FluidEntryRenderer extends AbstractEntryRenderer<FluidStack> implements BatchedEntryRenderer<FluidStack, TextureAtlasSprite> { + private static final Supplier<TextureAtlasSprite> MISSING_SPRITE = Suppliers.memoize(() -> { + TextureAtlas atlas = Minecraft.getInstance().getModelManager().getAtlas(TextureAtlas.LOCATION_BLOCKS); + return atlas.getSprite(MissingTextureAtlasSprite.getLocation()); + }); + @Override public TextureAtlasSprite getExtraData(EntryStack<FluidStack> entry) { FluidStack stack = entry.getValue(); @@ -182,6 +202,10 @@ public class FluidEntryDefinition implements EntryDefinition<FluidStack>, EntryS return FluidStackHooks.getStillTexture(stack); } + private TextureAtlasSprite missingTexture() { + return MISSING_SPRITE.get(); + } + @Override public int getBatchIdentifier(EntryStack<FluidStack> entry, Rectangle bounds, TextureAtlasSprite extraData) { return 0; @@ -192,16 +216,17 @@ public class FluidEntryDefinition implements EntryDefinition<FluidStack>, EntryS @Override public void renderBase(EntryStack<FluidStack> entry, TextureAtlasSprite sprite, PoseStack matrices, MultiBufferSource.BufferSource immediate, Rectangle bounds, int mouseX, int mouseY, float delta) { + TextureAtlasSprite s = sprite == null ? missingTexture() : sprite; SpriteRenderer.beginPass() .setup(immediate, RenderType.solid()) - .sprite(sprite) - .color(FluidStackHooks.getColor(entry.getValue())) + .sprite(s) + .color(sprite == null ? 0xFFFFFF : FluidStackHooks.getColor(entry.getValue())) .light(0x00f000f0) .overlay(OverlayTexture.NO_OVERLAY) .alpha(0xff) .normal(matrices.last().normal(), 0, 0, 0) .position(matrices.last().pose(), bounds.x, bounds.getMaxY() - bounds.height * Mth.clamp(entry.get(EntryStack.Settings.FLUID_RENDER_RATIO), 0, 1), bounds.getMaxX(), bounds.getMaxY(), entry.getZ()) - .next(InventoryMenu.BLOCK_ATLAS); + .next(s.atlas().location()); } @Override diff --git a/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java b/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java index cc3a57941..ba5e0c08f 100644 --- a/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java +++ b/runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java @@ -48,6 +48,8 @@ import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; import me.shedaniel.rei.api.common.util.ImmutableTextComponent; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.CrashReport; +import net.minecraft.CrashReportCategory; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.block.model.ItemTransforms; @@ -194,6 +196,16 @@ public class ItemEntryDefinition implements EntryDefinition<ItemStack>, EntrySer return Lists.newArrayList(asFormattedText(entry, value)); } + @Override + public void fillCrashReport(CrashReport report, CrashReportCategory category, EntryStack<ItemStack> entry) { + EntryDefinition.super.fillCrashReport(report, category, entry); + ItemStack stack = entry.getValue(); + category.setDetail("Item Type", () -> String.valueOf(stack.getItem())); + category.setDetail("Item Damage", () -> String.valueOf(stack.getDamageValue())); + category.setDetail("Item NBT", () -> String.valueOf(stack.getTag())); + category.setDetail("Item Foil", () -> String.valueOf(stack.hasFoil())); + } + @Environment(EnvType.CLIENT) public class ItemEntryRenderer extends AbstractEntryRenderer<ItemStack> implements BatchedEntryRenderer<ItemStack, BakedModel> { private static final float SCALE = 20.0F; |
