1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-28 02:02:53 +08:00

Change Duck() to be IDisposable and prevent overlapping usages

This commit is contained in:
Jamie Taylor 2024-07-04 14:23:35 +09:00
parent d29d114133
commit d948193757
No known key found for this signature in database
GPG Key ID: 2ACFA8B6370B8C8C
4 changed files with 49 additions and 31 deletions

View File

@ -1,8 +1,8 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -24,6 +24,8 @@ namespace osu.Game.Collections
protected override string PopInSampleName => @"UI/overlay-big-pop-in";
protected override string PopOutSampleName => @"UI/overlay-big-pop-out";
private IDisposable? audioDucker;
[Resolved]
private MusicController? musicController { get; set; }
@ -40,7 +42,7 @@ namespace osu.Game.Collections
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, AudioManager audio)
private void load(OsuColour colours)
{
Children = new Drawable[]
{
@ -115,9 +117,15 @@ namespace osu.Game.Collections
};
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
audioDucker?.Dispose();
}
protected override void PopIn()
{
musicController?.Duck(100, 1f);
audioDucker = musicController?.Duck(100, 1f, unduckDuration: 100);
this.FadeIn(enter_duration, Easing.OutQuint);
this.ScaleTo(0.9f).Then().ScaleTo(1f, enter_duration, Easing.OutQuint);
@ -127,7 +135,7 @@ namespace osu.Game.Collections
{
base.PopOut();
musicController?.Unduck(100);
audioDucker?.Dispose();
this.FadeOut(exit_duration, Easing.OutQuint);
this.ScaleTo(0.9f, exit_duration);

View File

@ -47,9 +47,6 @@ namespace osu.Game.Overlays.Dialog
private partial class DangerousConfirmContainer : HoldToConfirmContainer
{
[Resolved]
private MusicController musicController { get; set; }
public DangerousConfirmContainer()
: base(isDangerousAction: true)
{
@ -73,15 +70,8 @@ namespace osu.Game.Overlays.Dialog
Progress.BindValueChanged(progressChanged);
}
protected override void AbortConfirm()
{
musicController?.Unduck();
base.AbortConfirm();
}
protected override void Confirm()
{
musicController?.Duck(100, 1f);
confirmSample?.Play();
base.Confirm();
}

View File

@ -3,6 +3,7 @@
#nullable disable
using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Overlays.Dialog;
@ -29,6 +30,8 @@ namespace osu.Game.Overlays
public override bool IsPresent => Scheduler.HasPendingTasks
|| dialogContainer.Children.Count > 0;
private IDisposable? audioDucker;
public DialogOverlay()
{
AutoSizeAxes = Axes.Y;
@ -45,6 +48,12 @@ namespace osu.Game.Overlays
Origin = Anchor.Centre;
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
audioDucker?.Dispose();
}
public void Push(PopupDialog dialog)
{
if (dialog == CurrentDialog || dialog.State.Value == Visibility.Hidden) return;
@ -95,13 +104,13 @@ namespace osu.Game.Overlays
protected override void PopIn()
{
musicController.Duck(100, 1f);
audioDucker = musicController.Duck(100, 1f, unduckDuration: 100);
}
protected override void PopOut()
{
base.PopOut();
musicController.Unduck(100);
audioDucker?.Dispose();
// PopOut gets called initially, but we only want to hide dialog when we have been loaded and are present.
if (IsLoaded && CurrentDialog?.State.Value == Visibility.Visible)

View File

@ -67,6 +67,7 @@ namespace osu.Game.Overlays
private AudioFilter audioDuckFilter;
private readonly BindableDouble audioDuckVolume = new BindableDouble(1);
private bool audioDuckActive;
[BackgroundDependencyLoader]
private void load(AudioManager audio)
@ -262,8 +263,15 @@ namespace osu.Game.Overlays
/// <param name="duckVolumeTo">Level to drop volume to (1.0 = 100%).</param>
/// <param name="duckCutoffTo">Cutoff frequency to drop `AudioFilter` to. Use `null` to skip filter effect.</param>
/// <param name="easing">Easing for the ducking transition.</param>
public void Duck(int duration = 0, float duckVolumeTo = 0.25f, int? duckCutoffTo = 300, Easing easing = Easing.OutCubic)
/// <param name="unduckDuration">Duration of the unducking transition, in ms.</param>
/// <param name="unduckEasing">Easing for the unducking transition.</param>
public IDisposable Duck(int duration = 0, float duckVolumeTo = 0.25f, int? duckCutoffTo = 300, Easing easing = Easing.OutCubic, int unduckDuration = 500, Easing unduckEasing = Easing.InCubic)
{
if (audioDuckActive)
throw new InvalidOperationException("Cannot perform Duck() while another Duck() is in progress.");
audioDuckActive = true;
Schedule(() =>
{
if (duckCutoffTo.IsNotNull())
@ -271,20 +279,8 @@ namespace osu.Game.Overlays
this.TransformBindableTo(audioDuckVolume, duckVolumeTo, duration, easing);
});
}
/// <summary>
/// Restores the volume to full and stops filtering the currently playing track after having used <see cref="Duck"/>.
/// </summary>
/// <param name="duration">Duration of the unducking transition, in ms.</param>
/// <param name="easing">Easing for the unducking transition.</param>
public void Unduck(int duration = 500, Easing easing = Easing.InCubic)
{
Schedule(() =>
{
audioDuckFilter?.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF, duration, easing);
this.TransformBindableTo(audioDuckVolume, 1, duration, easing);
});
return new InvokeOnDisposal(() => unduck(unduckDuration, unduckEasing));
}
/// <summary>
@ -299,8 +295,23 @@ namespace osu.Game.Overlays
/// <param name="duckEasing">Easing for the ducking transition.</param>
public void TimedDuck(int delay, int unduckDuration = 500, Easing unduckEasing = Easing.InCubic, float duckVolumeTo = 0.25f, int? duckCutoffTo = 300, int duckDuration = 0, Easing duckEasing = Easing.OutCubic)
{
if (audioDuckActive) return;
Duck(duckDuration, duckVolumeTo, duckCutoffTo, duckEasing);
Scheduler.AddDelayed(() => Unduck(unduckDuration, unduckEasing), delay);
Scheduler.AddDelayed(() => unduck(unduckDuration, unduckEasing), delay);
}
private void unduck(int duration, Easing easing)
{
if (!audioDuckActive) return;
audioDuckActive = false;
Schedule(() =>
{
audioDuckFilter?.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF, duration, easing);
this.TransformBindableTo(audioDuckVolume, 1, duration, easing);
});
}
private bool next()