ToastManager.java

net.minecraft.client.gui.components.toasts.ToastManager

信息

  • 全限定名:net.minecraft.client.gui.components.toasts.ToastManager
  • 类型:public class
  • 包:net.minecraft.client.gui.components.toasts
  • 源码路径:src/main/java/net/minecraft/client/gui/components/toasts/ToastManager.java
  • 起始行号:L27
  • 职责:

    TODO

字段/常量

  • SLOT_COUNT

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L28
    • 说明:

      TODO

  • ALL_SLOTS_OCCUPIED

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L29
    • 说明:

      TODO

  • minecraft

    • 类型: Minecraft
    • 修饰符: private final
    • 源码定位: L30
    • 说明:

      TODO

  • visibleToasts

    • 类型: List<ToastManager.ToastInstance<?>>
    • 修饰符: private final
    • 源码定位: L31
    • 说明:

      TODO

  • occupiedSlots

    • 类型: BitSet
    • 修饰符: private final
    • 源码定位: L32
    • 说明:

      TODO

  • queued

    • 类型: Deque<Toast>
    • 修饰符: private final
    • 源码定位: L33
    • 说明:

      TODO

  • playedToastSounds

    • 类型: Set<SoundEvent>
    • 修饰符: private final
    • 源码定位: L34
    • 说明:

      TODO

  • nowPlayingToast

    • 类型: ToastManager.ToastInstance<NowPlayingToast>
    • 修饰符: private
    • 源码定位: L35
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.gui.components.toasts.ToastManager.ToastInstance
    • 类型: class
    • 修饰符: private
    • 源码定位: L195
    • 说明:

      TODO

构造器

public ToastManager(Minecraft minecraft, Options options) @ L37

  • 构造器名:ToastManager
  • 源码定位:L37
  • 修饰符:public

参数:

  • minecraft: Minecraft
  • options: Options

说明:

TODO

方法

下面的方法块按源码顺序生成。

public void update() @ L42

  • 方法名:update
  • 源码定位:L42
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void extractRenderState(GuiGraphicsExtractor graphics) @ L84

  • 方法名:extractRenderState
  • 源码定位:L84
  • 返回类型:void
  • 修饰符:public

参数:

  • graphics: GuiGraphicsExtractor

说明:

TODO

private int findFreeSlotsIndex(int requiredCount) @ L103

  • 方法名:findFreeSlotsIndex
  • 源码定位:L103
  • 返回类型:int
  • 修饰符:private

参数:

  • requiredCount: int

说明:

TODO

private int freeSlotCount() @ L119

  • 方法名:freeSlotCount
  • 源码定位:L119
  • 返回类型:int
  • 修饰符:private

参数:

说明:

TODO

public <T extends Toast> T getToast(Class<?extends T> clazz, Object token) @ L123

  • 方法名:getToast
  • 源码定位:L123
  • 返回类型: T
  • 修饰符:public

参数:

  • clazz: Class<?extends T>
  • token: Object

说明:

TODO

public void clear() @ L139

  • 方法名:clear
  • 源码定位:L139
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void addToast(Toast toast) @ L145

  • 方法名:addToast
  • 源码定位:L145
  • 返回类型:void
  • 修饰符:public

参数:

  • toast: Toast

说明:

TODO

public void showNowPlayingToast() @ L149

  • 方法名:showNowPlayingToast
  • 源码定位:L149
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void hideNowPlayingToast() @ L156

  • 方法名:hideNowPlayingToast
  • 源码定位:L156
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public Minecraft getMinecraft() @ L162

  • 方法名:getMinecraft
  • 源码定位:L162
  • 返回类型:Minecraft
  • 修饰符:public

参数:

说明:

TODO

public double getNotificationDisplayTimeMultiplier() @ L166

  • 方法名:getNotificationDisplayTimeMultiplier
  • 源码定位:L166
  • 返回类型:double
  • 修饰符:public

参数:

说明:

TODO

private void initializeMusicToast(MusicToastDisplayState state) @ L170

  • 方法名:initializeMusicToast
  • 源码定位:L170
  • 返回类型:void
  • 修饰符:private

参数:

  • state: MusicToastDisplayState

说明:

TODO

public void setMusicToastDisplayState(MusicToastDisplayState state) @ L178

  • 方法名:setMusicToastDisplayState
  • 源码定位:L178
  • 返回类型:void
  • 修饰符:public

参数:

  • state: MusicToastDisplayState

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
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<ToastManager.ToastInstance<?>> visibleToasts = new ArrayList<>();
    private final BitSet occupiedSlots = new BitSet(5);
    private final Deque<Toast> queued = Queues.newArrayDeque();
    private final Set<SoundEvent> playedToastSounds = new HashSet<>();
    private ToastManager.@Nullable ToastInstance<NowPlayingToast> nowPlayingToast;
 
    public ToastManager(Minecraft minecraft, Options options) {
        this.minecraft = minecraft;
        this.initializeMusicToast(options.musicToast().get());
    }
 
    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;
            } else {
                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;
                } else {
                    this.visibleToasts.add(new ToastManager.ToastInstance<>(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 extractRenderState(GuiGraphicsExtractor graphics) {
        if (!this.minecraft.options.hideGui) {
            int screenWidth = graphics.guiWidth();
            if (!this.visibleToasts.isEmpty()) {
                graphics.nextStratum();
            }
 
            for (ToastManager.ToastInstance<?> toast : this.visibleToasts) {
                toast.extractRenderState(graphics, screenWidth);
            }
 
            if (this.minecraft.options.musicToast().get().renderToast()
                && this.nowPlayingToast != null
                && (this.minecraft.screen == null || !(this.minecraft.screen instanceof PauseScreen))) {
                this.nowPlayingToast.extractRenderState(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;
                } else if (++consecutiveFreeSlotCount == requiredCount) {
                    return i + 1 - consecutiveFreeSlotCount;
                }
            }
        }
 
        return -1;
    }
 
    private int freeSlotCount() {
        return 5 - this.occupiedSlots.cardinality();
    }
 
    public <T extends Toast> @Nullable T getToast(Class<? extends T> clazz, Object token) {
        for (ToastManager.ToastInstance<?> instance : this.visibleToasts) {
            if (clazz.isAssignableFrom(instance.getToast().getClass()) && instance.getToast().getToken().equals(token)) {
                return (T)instance.getToast();
            }
        }
 
        for (Toast toast : this.queued) {
            if (clazz.isAssignableFrom(toast.getClass()) && toast.getToken().equals(token)) {
                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 Minecraft getMinecraft() {
        return this.minecraft;
    }
 
    public double getNotificationDisplayTimeMultiplier() {
        return this.minecraft.options.notificationDisplayTime().get();
    }
 
    private void initializeMusicToast(MusicToastDisplayState state) {
        switch (state) {
            case PAUSE:
            case PAUSE_AND_TOAST:
                this.nowPlayingToast = new ToastManager.ToastInstance<>(new NowPlayingToast(), 0, 0);
        }
    }
 
    public void setMusicToastDisplayState(MusicToastDisplayState state) {
        switch (state) {
            case PAUSE:
                this.nowPlayingToast = new ToastManager.ToastInstance<>(new NowPlayingToast(), 0, 0);
                break;
            case PAUSE_AND_TOAST:
                this.nowPlayingToast = new ToastManager.ToastInstance<>(new NowPlayingToast(), 0, 0);
                if (this.minecraft.options.getFinalSoundSourceVolume(SoundSource.MUSIC) > 0.0F) {
                    this.nowPlayingToast.getToast().showToast(this.minecraft.options);
                }
                break;
            case NEVER:
                this.nowPlayingToast = null;
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    private class ToastInstance<T extends Toast> {
        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;
 
        private ToastInstance(T toast, int firstSlotIndex, int occupiedSlotCount) {
            Objects.requireNonNull(ToastManager.this);
            super();
            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;
            if (this.visibility == Toast.Visibility.HIDE) {
                this.visiblePortion = 1.0F - animationProgress;
            } else {
                this.visiblePortion = 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(ToastManager.this, this.fullyVisibleFor);
            Toast.Visibility wantedVisibility = this.toast.getWantedVisibility();
            if (wantedVisibility != this.visibility) {
                this.animationStartTime = now - (int)((1.0F - this.visiblePortion) * 600.0F);
                this.visibility = wantedVisibility;
            }
 
            boolean wasAlreadyFinishedRendering = this.hasFinishedRendering;
            this.hasFinishedRendering = this.visibility == Toast.Visibility.HIDE && now - this.animationStartTime > 600L;
            if (this.hasFinishedRendering && !wasAlreadyFinishedRendering) {
                this.toast.onFinishedRendering();
            }
        }
 
        public void extractRenderState(GuiGraphicsExtractor graphics, int screenWidth) {
            if (!this.hasFinishedRendering) {
                graphics.pose().pushMatrix();
                graphics.pose().translate(this.toast.xPos(screenWidth, this.visiblePortion), this.toast.yPos(this.firstSlotIndex));
                this.toast.extractRenderState(graphics, ToastManager.this.minecraft.font, this.fullyVisibleFor);
                graphics.pose().popMatrix();
            }
        }
    }
}

引用的其他类