2025-11-24 22:52:51 +03:00

313 lines
11 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.joml.Matrix3x2f
* org.joml.Matrix3x2fc
* org.jspecify.annotations.Nullable
*/
package net.minecraft.client.gui.render.state;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import net.minecraft.SharedConstants;
import net.minecraft.client.gui.navigation.ScreenRectangle;
import net.minecraft.client.gui.render.TextureSetup;
import net.minecraft.client.gui.render.state.BlitRenderState;
import net.minecraft.client.gui.render.state.ColoredRectangleRenderState;
import net.minecraft.client.gui.render.state.GuiElementRenderState;
import net.minecraft.client.gui.render.state.GuiItemRenderState;
import net.minecraft.client.gui.render.state.GuiTextRenderState;
import net.minecraft.client.gui.render.state.ScreenArea;
import net.minecraft.client.gui.render.state.pip.PictureInPictureRenderState;
import net.minecraft.client.renderer.RenderPipelines;
import org.joml.Matrix3x2f;
import org.joml.Matrix3x2fc;
import org.jspecify.annotations.Nullable;
public class GuiRenderState {
private static final int DEBUG_RECTANGLE_COLOR = 0x774444FF;
private final List<Node> strata = new ArrayList<Node>();
private int firstStratumAfterBlur = Integer.MAX_VALUE;
private Node current;
private final Set<Object> itemModelIdentities = new HashSet<Object>();
private @Nullable ScreenRectangle lastElementBounds;
public GuiRenderState() {
this.nextStratum();
}
public void nextStratum() {
this.current = new Node(null);
this.strata.add(this.current);
}
public void blurBeforeThisStratum() {
if (this.firstStratumAfterBlur != Integer.MAX_VALUE) {
throw new IllegalStateException("Can only blur once per frame");
}
this.firstStratumAfterBlur = this.strata.size() - 1;
}
public void up() {
if (this.current.up == null) {
this.current.up = new Node(this.current);
}
this.current = this.current.up;
}
public void submitItem(GuiItemRenderState itemState) {
if (!this.findAppropriateNode(itemState)) {
return;
}
this.itemModelIdentities.add(itemState.itemStackRenderState().getModelIdentity());
this.current.submitItem(itemState);
this.sumbitDebugRectangleIfEnabled(itemState.bounds());
}
public void submitText(GuiTextRenderState textState) {
if (!this.findAppropriateNode(textState)) {
return;
}
this.current.submitText(textState);
this.sumbitDebugRectangleIfEnabled(textState.bounds());
}
public void submitPicturesInPictureState(PictureInPictureRenderState picturesInPictureState) {
if (!this.findAppropriateNode(picturesInPictureState)) {
return;
}
this.current.submitPicturesInPictureState(picturesInPictureState);
this.sumbitDebugRectangleIfEnabled(picturesInPictureState.bounds());
}
public void submitGuiElement(GuiElementRenderState blitState) {
if (!this.findAppropriateNode(blitState)) {
return;
}
this.current.submitGuiElement(blitState);
this.sumbitDebugRectangleIfEnabled(blitState.bounds());
}
private void sumbitDebugRectangleIfEnabled(@Nullable ScreenRectangle bounds) {
if (!SharedConstants.DEBUG_RENDER_UI_LAYERING_RECTANGLES || bounds == null) {
return;
}
this.up();
this.current.submitGuiElement(new ColoredRectangleRenderState(RenderPipelines.GUI, TextureSetup.noTexture(), (Matrix3x2fc)new Matrix3x2f(), 0, 0, 10000, 10000, 0x774444FF, 0x774444FF, bounds));
}
private boolean findAppropriateNode(ScreenArea screenArea) {
ScreenRectangle bounds = screenArea.bounds();
if (bounds == null) {
return false;
}
if (this.lastElementBounds != null && this.lastElementBounds.encompasses(bounds)) {
this.up();
} else {
this.navigateToAboveHighestElementWithIntersectingBounds(bounds);
}
this.lastElementBounds = bounds;
return true;
}
private void navigateToAboveHighestElementWithIntersectingBounds(ScreenRectangle bounds) {
Node node = this.strata.getLast();
while (node.up != null) {
node = node.up;
}
boolean found = false;
while (!found) {
boolean bl = found = this.hasIntersection(bounds, node.elementStates) || this.hasIntersection(bounds, node.itemStates) || this.hasIntersection(bounds, node.textStates) || this.hasIntersection(bounds, node.picturesInPictureStates);
if (node.parent == null) break;
if (found) continue;
node = node.parent;
}
this.current = node;
if (found) {
this.up();
}
}
private boolean hasIntersection(ScreenRectangle bounds, @Nullable List<? extends ScreenArea> states) {
if (states != null) {
for (ScreenArea screenArea : states) {
ScreenRectangle existingBounds = screenArea.bounds();
if (existingBounds == null || !existingBounds.intersects(bounds)) continue;
return true;
}
}
return false;
}
public void submitBlitToCurrentLayer(BlitRenderState blitState) {
this.current.submitGuiElement(blitState);
}
public void submitGlyphToCurrentLayer(GuiElementRenderState glyphState) {
this.current.submitGlyph(glyphState);
}
public Set<Object> getItemModelIdentities() {
return this.itemModelIdentities;
}
public void forEachElement(Consumer<GuiElementRenderState> consumer, TraverseRange range) {
this.traverse((Node node) -> {
if (node.elementStates == null && node.glyphStates == null) {
return;
}
if (node.elementStates != null) {
for (GuiElementRenderState elementState : node.elementStates) {
consumer.accept(elementState);
}
}
if (node.glyphStates != null) {
for (GuiElementRenderState glyphState : node.glyphStates) {
consumer.accept(glyphState);
}
}
}, range);
}
public void forEachItem(Consumer<GuiItemRenderState> consumer) {
Node currentBackup = this.current;
this.traverse((Node node) -> {
if (node.itemStates != null) {
this.current = node;
for (GuiItemRenderState itemState : node.itemStates) {
consumer.accept(itemState);
}
}
}, TraverseRange.ALL);
this.current = currentBackup;
}
public void forEachText(Consumer<GuiTextRenderState> consumer) {
Node currentBackup = this.current;
this.traverse((Node node) -> {
if (node.textStates != null) {
for (GuiTextRenderState textState : node.textStates) {
this.current = node;
consumer.accept(textState);
}
}
}, TraverseRange.ALL);
this.current = currentBackup;
}
public void forEachPictureInPicture(Consumer<PictureInPictureRenderState> consumer) {
Node currentBackup = this.current;
this.traverse((Node node) -> {
if (node.picturesInPictureStates != null) {
this.current = node;
for (PictureInPictureRenderState pictureInPictureState : node.picturesInPictureStates) {
consumer.accept(pictureInPictureState);
}
}
}, TraverseRange.ALL);
this.current = currentBackup;
}
public void sortElements(Comparator<GuiElementRenderState> comparator) {
this.traverse((Node node) -> {
if (node.elementStates != null) {
if (SharedConstants.DEBUG_SHUFFLE_UI_RENDERING_ORDER) {
Collections.shuffle(node.elementStates);
}
node.elementStates.sort(comparator);
}
}, TraverseRange.ALL);
}
private void traverse(Consumer<Node> consumer, TraverseRange range) {
int startIndex = 0;
int endIndex = this.strata.size();
if (range == TraverseRange.BEFORE_BLUR) {
endIndex = Math.min(this.firstStratumAfterBlur, this.strata.size());
} else if (range == TraverseRange.AFTER_BLUR) {
startIndex = this.firstStratumAfterBlur;
}
for (int i = startIndex; i < endIndex; ++i) {
Node stratum = this.strata.get(i);
this.traverse(stratum, consumer);
}
}
private void traverse(Node node, Consumer<Node> consumer) {
consumer.accept(node);
if (node.up != null) {
this.traverse(node.up, consumer);
}
}
public void reset() {
this.itemModelIdentities.clear();
this.strata.clear();
this.firstStratumAfterBlur = Integer.MAX_VALUE;
this.nextStratum();
}
private static class Node {
public final @Nullable Node parent;
public @Nullable Node up;
public @Nullable List<GuiElementRenderState> elementStates;
public @Nullable List<GuiElementRenderState> glyphStates;
public @Nullable List<GuiItemRenderState> itemStates;
public @Nullable List<GuiTextRenderState> textStates;
public @Nullable List<PictureInPictureRenderState> picturesInPictureStates;
private Node(@Nullable Node parent) {
this.parent = parent;
}
public void submitItem(GuiItemRenderState itemState) {
if (this.itemStates == null) {
this.itemStates = new ArrayList<GuiItemRenderState>();
}
this.itemStates.add(itemState);
}
public void submitText(GuiTextRenderState textState) {
if (this.textStates == null) {
this.textStates = new ArrayList<GuiTextRenderState>();
}
this.textStates.add(textState);
}
public void submitPicturesInPictureState(PictureInPictureRenderState picturesInPictureState) {
if (this.picturesInPictureStates == null) {
this.picturesInPictureStates = new ArrayList<PictureInPictureRenderState>();
}
this.picturesInPictureStates.add(picturesInPictureState);
}
public void submitGuiElement(GuiElementRenderState blitState) {
if (this.elementStates == null) {
this.elementStates = new ArrayList<GuiElementRenderState>();
}
this.elementStates.add(blitState);
}
public void submitGlyph(GuiElementRenderState glyphState) {
if (this.glyphStates == null) {
this.glyphStates = new ArrayList<GuiElementRenderState>();
}
this.glyphStates.add(glyphState);
}
}
public static enum TraverseRange {
ALL,
BEFORE_BLUR,
AFTER_BLUR;
}
}