fabric-rendering-v1-16.2.0+bee81f016f.jar
Download file
package net.fabricmc.fabric.impl.client.rendering.hud;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.rendering.v1.hud.HudElement;
import net.fabricmc.fabric.api.client.rendering.v1.hud.VanillaHudElements;
import net.minecraft.class_2960;
import net.minecraft.class_332;
import net.minecraft.class_9779;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.jetbrains.annotations.VisibleForTesting;
@Environment(EnvType.CLIENT)
public class HudElementRegistryImpl {
@VisibleForTesting
static final List<class_2960> VANILLA_ELEMENT_IDS;
@VisibleForTesting
public static final Map<class_2960, RootLayer> ROOT_ELEMENTS;
private static final RootLayer FIRST;
private static final RootLayer LAST;
public static RootLayer getRoot(class_2960 id) {
return (RootLayer)ROOT_ELEMENTS.get(id);
}
public static void addFirst(class_2960 id, HudElement element) {
validateUnique(id);
FIRST.layers().addFirst(HudLayer.ofElement(id, element));
}
public static void addLast(class_2960 id, HudElement element) {
validateUnique(id);
LAST.layers().addLast(HudLayer.ofElement(id, element));
}
public static void attachElementBefore(class_2960 beforeThis, class_2960 id, HudElement element) {
validateUnique(id);
boolean didChange = findLayer(beforeThis, (l, iterator) -> {
iterator.previous();
iterator.add(HudLayer.ofElement(id, element));
iterator.next();
return true;
});
if (!didChange) {
throw new IllegalArgumentException("Layer with identifier " + String.valueOf(beforeThis) + " not found");
}
}
public static void attachElementAfter(class_2960 afterThis, class_2960 id, HudElement element) {
validateUnique(id);
boolean didChange = findLayer(afterThis, (l, iterator) -> {
iterator.add(HudLayer.ofElement(id, element));
return true;
});
if (!didChange) {
throw new IllegalArgumentException("Layer with identifier " + String.valueOf(afterThis) + " not found");
}
}
public static void removeElement(class_2960 identifier) {
boolean didChange = findLayer(identifier, (l, iterator) -> {
class_2960 var10001 = l.id();
Objects.requireNonNull(l);
iterator.set(HudLayer.of(var10001, l::element, true));
return true;
});
if (!didChange) {
throw new IllegalArgumentException("Layer with identifier " + String.valueOf(identifier) + " not found");
}
}
public static void replaceElement(class_2960 identifier, Function<HudElement, HudElement> replacer) {
boolean didChange = findLayer(identifier, (l, iterator) -> {
class_2960 var10001 = l.id();
Objects.requireNonNull(l);
iterator.set(HudLayer.of(var10001, replacer.compose(l::element), l.isRemoved()));
return true;
});
if (!didChange) {
throw new IllegalArgumentException("Layer with identifier " + String.valueOf(identifier) + " not found");
}
}
@VisibleForTesting
static void validateUnique(class_2960 id) {
visitLayers((l, iterator) -> {
if (l.id().equals(id)) {
throw new IllegalArgumentException("Layer with identifier " + String.valueOf(id) + " already exists");
} else {
return false;
}
});
}
@VisibleForTesting
static boolean findLayer(class_2960 identifier, LayerVisitor visitor) {
MutableBoolean found = new MutableBoolean(false);
visitLayers((l, iterator) -> {
if (l.id().equals(identifier)) {
found.setTrue();
return visitor.visit(l, iterator);
} else {
return false;
}
});
return found.booleanValue();
}
@VisibleForTesting
static boolean visitLayers(LayerVisitor visitor) {
boolean modified = false;
for(class_2960 id : VANILLA_ELEMENT_IDS) {
RootLayer rootLayer = (RootLayer)ROOT_ELEMENTS.get(id);
modified |= visitLayers(rootLayer.layers(), visitor);
}
return modified;
}
private static boolean visitLayers(List<HudLayer> layers, LayerVisitor visitor) {
MutableBoolean modified = new MutableBoolean(false);
ListIterator<HudLayer> iterator = layers.listIterator();
while(iterator.hasNext()) {
HudLayer layer = (HudLayer)iterator.next();
if (visitor.visit(layer, iterator)) {
modified.setTrue();
}
}
return modified.booleanValue();
}
static {
VANILLA_ELEMENT_IDS = List.of(VanillaHudElements.MISC_OVERLAYS, VanillaHudElements.CROSSHAIR, VanillaHudElements.SPECTATOR_MENU, VanillaHudElements.HOTBAR, VanillaHudElements.ARMOR_BAR, VanillaHudElements.HEALTH_BAR, VanillaHudElements.FOOD_BAR, VanillaHudElements.AIR_BAR, VanillaHudElements.MOUNT_HEALTH, VanillaHudElements.INFO_BAR, VanillaHudElements.EXPERIENCE_LEVEL, VanillaHudElements.HELD_ITEM_TOOLTIP, VanillaHudElements.SPECTATOR_TOOLTIP, VanillaHudElements.STATUS_EFFECTS, VanillaHudElements.BOSS_BAR, VanillaHudElements.SLEEP, VanillaHudElements.DEMO_TIMER, VanillaHudElements.SCOREBOARD, VanillaHudElements.OVERLAY_MESSAGE, VanillaHudElements.TITLE_AND_SUBTITLE, VanillaHudElements.CHAT, VanillaHudElements.PLAYER_LIST, VanillaHudElements.SUBTITLES);
ROOT_ELEMENTS = (Map)VANILLA_ELEMENT_IDS.stream().map(RootLayer::new).collect(Collectors.toMap(RootLayer::id, Function.identity(), (a, b) -> a, IdentityHashMap::new));
FIRST = (RootLayer)ROOT_ELEMENTS.get(VanillaHudElements.MISC_OVERLAYS);
LAST = (RootLayer)ROOT_ELEMENTS.get(VanillaHudElements.SUBTITLES);
}
@Environment(EnvType.CLIENT)
public static record RootLayer(class_2960 id, List<HudLayer> layers) {
private RootLayer(class_2960 id) {
this(id, new ArrayList());
this.layers().add(HudLayer.ofVanilla(id));
}
public void render(class_332 context, class_9779 tickCounter, HudElement vanillaElement) {
for(HudLayer layer : this.layers) {
if (!layer.isRemoved()) {
layer.element(vanillaElement).render(context, tickCounter);
}
}
}
}
@Environment(EnvType.CLIENT)
@VisibleForTesting
interface LayerVisitor {
boolean visit(HudLayer var1, ListIterator<HudLayer> var2);
}
}
Download file