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:
parent
d29d114133
commit
d948193757
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user