/* * Decompiled with CFR 0.152. * * Could not load the following classes: * com.google.common.collect.Queues * org.apache.commons.lang3.mutable.MutableBoolean * org.jspecify.annotations.Nullable */ package net.minecraft.client.gui.components.toasts; import com.google.common.collect.Queues; import java.util.ArrayList; import java.util.BitSet; import java.util.Deque; import java.util.HashSet; import java.util.List; import java.util.Set; import net.minecraft.client.Minecraft; import net.minecraft.client.Options; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.toasts.NowPlayingToast; import net.minecraft.client.gui.components.toasts.Toast; import net.minecraft.client.gui.screens.PauseScreen; import net.minecraft.client.resources.sounds.SimpleSoundInstance; import net.minecraft.sounds.SoundEvent; import net.minecraft.util.Mth; import net.minecraft.util.Util; import org.apache.commons.lang3.mutable.MutableBoolean; import org.jspecify.annotations.Nullable; public class ToastManager { private static final int SLOT_COUNT = 5; private static final int ALL_SLOTS_OCCUPIED = -1; private final Minecraft minecraft; private final List> visibleToasts = new ArrayList(); private final BitSet occupiedSlots = new BitSet(5); private final Deque queued = Queues.newArrayDeque(); private final Set playedToastSounds = new HashSet(); private @Nullable ToastInstance nowPlayingToast; public ToastManager(Minecraft minecraft, Options options) { this.minecraft = minecraft; if (options.showNowPlayingToast().get().booleanValue()) { this.createNowPlayingToast(); } } public void update() { MutableBoolean visibilityChangeSoundPlayed = new MutableBoolean(false); this.visibleToasts.removeIf(toast -> { Toast.Visibility previousVisibility = toast.visibility; toast.update(); if (toast.visibility != previousVisibility && visibilityChangeSoundPlayed.isFalse()) { visibilityChangeSoundPlayed.setTrue(); toast.visibility.playSound(this.minecraft.getSoundManager()); } if (toast.hasFinishedRendering()) { this.occupiedSlots.clear(toast.firstSlotIndex, toast.firstSlotIndex + toast.occupiedSlotCount); return true; } return false; }); if (!this.queued.isEmpty() && this.freeSlotCount() > 0) { this.queued.removeIf(toast -> { int occcupiedSlotCount = toast.occcupiedSlotCount(); int firstSlotIndex = this.findFreeSlotsIndex(occcupiedSlotCount); if (firstSlotIndex == -1) { return false; } this.visibleToasts.add(new ToastInstance(this, toast, firstSlotIndex, occcupiedSlotCount)); this.occupiedSlots.set(firstSlotIndex, firstSlotIndex + occcupiedSlotCount); SoundEvent toastSound = toast.getSoundEvent(); if (toastSound != null && this.playedToastSounds.add(toastSound)) { this.minecraft.getSoundManager().play(SimpleSoundInstance.forUI(toastSound, 1.0f, 1.0f)); } return true; }); } this.playedToastSounds.clear(); if (this.nowPlayingToast != null) { this.nowPlayingToast.update(); } } public void render(GuiGraphics graphics) { if (this.minecraft.options.hideGui) { return; } int screenWidth = graphics.guiWidth(); if (!this.visibleToasts.isEmpty()) { graphics.nextStratum(); } for (ToastInstance toast : this.visibleToasts) { toast.render(graphics, screenWidth); } if (this.minecraft.options.showNowPlayingToast().get().booleanValue() && this.nowPlayingToast != null && (this.minecraft.screen == null || !(this.minecraft.screen instanceof PauseScreen))) { this.nowPlayingToast.render(graphics, screenWidth); } } private int findFreeSlotsIndex(int requiredCount) { if (this.freeSlotCount() >= requiredCount) { int consecutiveFreeSlotCount = 0; for (int i = 0; i < 5; ++i) { if (this.occupiedSlots.get(i)) { consecutiveFreeSlotCount = 0; continue; } if (++consecutiveFreeSlotCount != requiredCount) continue; return i + 1 - consecutiveFreeSlotCount; } } return -1; } private int freeSlotCount() { return 5 - this.occupiedSlots.cardinality(); } public @Nullable T getToast(Class clazz, Object token) { for (ToastInstance instance : this.visibleToasts) { if (!clazz.isAssignableFrom(instance.getToast().getClass()) || !instance.getToast().getToken().equals(token)) continue; return (T)instance.getToast(); } for (Toast toast : this.queued) { if (!clazz.isAssignableFrom(toast.getClass()) || !toast.getToken().equals(token)) continue; return (T)toast; } return null; } public void clear() { this.occupiedSlots.clear(); this.visibleToasts.clear(); this.queued.clear(); } public void addToast(Toast toast) { this.queued.add(toast); } public void showNowPlayingToast() { if (this.nowPlayingToast != null) { this.nowPlayingToast.resetToast(); this.nowPlayingToast.getToast().showToast(this.minecraft.options); } } public void hideNowPlayingToast() { if (this.nowPlayingToast != null) { this.nowPlayingToast.getToast().setWantedVisibility(Toast.Visibility.HIDE); } } public void createNowPlayingToast() { this.nowPlayingToast = new ToastInstance(this, (Toast)new NowPlayingToast(), 0, 0); } public void removeNowPlayingToast() { this.nowPlayingToast = null; } public Minecraft getMinecraft() { return this.minecraft; } public double getNotificationDisplayTimeMultiplier() { return this.minecraft.options.notificationDisplayTime().get(); } private class ToastInstance { private static final long SLIDE_ANIMATION_DURATION_MS = 600L; private final T toast; private final int firstSlotIndex; private final int occupiedSlotCount; private long animationStartTime; private long becameFullyVisibleAt; private Toast.Visibility visibility; private long fullyVisibleFor; private float visiblePortion; protected boolean hasFinishedRendering; final /* synthetic */ ToastManager this$0; /* * WARNING - Possible parameter corruption */ private ToastInstance(T toast, int firstSlotIndex, int occupiedSlotCount) { this.this$0 = (ToastManager)n; this.toast = toast; this.firstSlotIndex = firstSlotIndex; this.occupiedSlotCount = occupiedSlotCount; this.resetToast(); } public T getToast() { return this.toast; } public void resetToast() { this.animationStartTime = -1L; this.becameFullyVisibleAt = -1L; this.visibility = Toast.Visibility.HIDE; this.fullyVisibleFor = 0L; this.visiblePortion = 0.0f; this.hasFinishedRendering = false; } public boolean hasFinishedRendering() { return this.hasFinishedRendering; } private void calculateVisiblePortion(long now) { float animationProgress = Mth.clamp((float)(now - this.animationStartTime) / 600.0f, 0.0f, 1.0f); animationProgress *= animationProgress; this.visiblePortion = this.visibility == Toast.Visibility.HIDE ? 1.0f - animationProgress : animationProgress; } public void update() { long now = Util.getMillis(); if (this.animationStartTime == -1L) { this.animationStartTime = now; this.visibility = Toast.Visibility.SHOW; } if (this.visibility == Toast.Visibility.SHOW && now - this.animationStartTime <= 600L) { this.becameFullyVisibleAt = now; } this.fullyVisibleFor = now - this.becameFullyVisibleAt; this.calculateVisiblePortion(now); this.toast.update(this.this$0, this.fullyVisibleFor); Toast.Visibility wantedVisibility = this.toast.getWantedVisibility(); if (wantedVisibility != this.visibility) { this.animationStartTime = now - (long)((int)((1.0f - this.visiblePortion) * 600.0f)); this.visibility = wantedVisibility; } boolean wasAlreadyFinishedRendering = this.hasFinishedRendering; boolean bl = this.hasFinishedRendering = this.visibility == Toast.Visibility.HIDE && now - this.animationStartTime > 600L; if (this.hasFinishedRendering && !wasAlreadyFinishedRendering) { this.toast.onFinishedRendering(); } } public void render(GuiGraphics graphics, int screenWidth) { if (this.hasFinishedRendering) { return; } graphics.pose().pushMatrix(); graphics.pose().translate(this.toast.xPos(screenWidth, this.visiblePortion), this.toast.yPos(this.firstSlotIndex)); this.toast.render(graphics, this.this$0.minecraft.font, this.fullyVisibleFor); graphics.pose().popMatrix(); } } }