diff --git a/osu.Game.Tests/WaveformTestBeatmap.cs b/osu.Game.Tests/WaveformTestBeatmap.cs index 9c85fa0c9c..ab7bf7fb73 100644 --- a/osu.Game.Tests/WaveformTestBeatmap.cs +++ b/osu.Game.Tests/WaveformTestBeatmap.cs @@ -59,6 +59,13 @@ namespace osu.Game.Tests protected override Track GetBeatmapTrack() => trackStore.Get(firstAudioFile); + public override bool TryTransferTrack(WorkingBeatmap target) + { + // Our track comes from a local track store that's disposed on finalizer, + // therefore it's unsafe to transfer it to another working beatmap. + return false; + } + private string firstAudioFile { get diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index bb64ec796c..09072ec897 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -126,11 +126,19 @@ namespace osu.Game.Beatmaps } /// - /// Transfer a valid audio track into this working beatmap. Used as an optimisation to avoid reload / track swap - /// across difficulties in the same beatmap set. + /// Attempts to transfer the audio track to a target working beatmap, if valid for transferring. + /// Used as an optimisation to avoid reload / track swap across difficulties in the same beatmap set. /// - /// The track to transfer. - public void TransferTrack([NotNull] Track track) => this.track = track ?? throw new ArgumentNullException(nameof(track)); + /// The target working beatmap to transfer this track to. + /// Whether the track has been transferred to the . + public virtual bool TryTransferTrack([NotNull] WorkingBeatmap target) + { + if (BeatmapInfo?.AudioEquals(target.BeatmapInfo) != true || Track.IsDummyDevice) + return false; + + target.track = Track; + return true; + } /// /// Get the loaded audio track instance. must have first been called. diff --git a/osu.Game/Graphics/UserInterface/ShearedButton.cs b/osu.Game/Graphics/UserInterface/ShearedButton.cs index dea44e6d99..66c6eedd0c 100644 --- a/osu.Game/Graphics/UserInterface/ShearedButton.cs +++ b/osu.Game/Graphics/UserInterface/ShearedButton.cs @@ -5,6 +5,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Framework.Localisation; @@ -68,6 +69,7 @@ namespace osu.Game.Graphics.UserInterface private Colour4? lighterColour; private Colour4? textColour; + private readonly Container backgroundLayer; private readonly Box flashLayer; /// @@ -85,24 +87,35 @@ namespace osu.Game.Graphics.UserInterface Height = 50; Padding = new MarginPadding { Horizontal = shear * 50 }; - Content.CornerRadius = 7; + const float corner_radius = 7; + + Content.CornerRadius = corner_radius; Content.Shear = new Vector2(shear, 0); Content.Masking = true; - Content.BorderThickness = 2; Content.Anchor = Content.Origin = Anchor.Centre; Children = new Drawable[] { - background = new Box + backgroundLayer = new Container { - RelativeSizeAxes = Axes.Both - }, - text = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.TorusAlternate.With(size: 17), - Shear = new Vector2(-shear, 0) + RelativeSizeAxes = Axes.Both, + CornerRadius = corner_radius, + Masking = true, + BorderThickness = 2, + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + text = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.TorusAlternate.With(size: 17), + Shear = new Vector2(-shear, 0) + }, + } }, flashLayer = new Box { @@ -186,7 +199,7 @@ namespace osu.Game.Graphics.UserInterface } background.FadeColour(colourDark, 150, Easing.OutQuint); - Content.TransformTo(nameof(BorderColour), ColourInfo.GradientVertical(colourDark, colourLight), 150, Easing.OutQuint); + backgroundLayer.TransformTo(nameof(BorderColour), ColourInfo.GradientVertical(colourDark, colourLight), 150, Easing.OutQuint); if (!Enabled.Value) colourText = colourText.Opacity(0.6f); diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 65b06eb864..aa09ff6b97 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -267,7 +267,7 @@ namespace osu.Game.Overlays TrackChangeDirection direction = TrackChangeDirection.None; - bool audioEquals = newWorking?.BeatmapInfo?.AudioEquals(current?.BeatmapInfo) ?? false; + bool audioEquals = newWorking?.BeatmapInfo?.AudioEquals(current?.BeatmapInfo) == true; if (current != null) { @@ -290,15 +290,8 @@ namespace osu.Game.Overlays current = newWorking; - if (!audioEquals || CurrentTrack.IsDummyDevice) - { + if (lastWorking == null || !lastWorking.TryTransferTrack(current)) changeTrack(); - } - else - { - // transfer still valid track to new working beatmap - current.TransferTrack(lastWorking.Track); - } TrackChanged?.Invoke(current, direction); diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index f2d280417e..1582bdfca4 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -373,6 +373,13 @@ namespace osu.Game.Tests.Visual protected override Track GetBeatmapTrack() => track; + public override bool TryTransferTrack(WorkingBeatmap target) + { + // Our track comes from a local track store that's disposed on finalizer, + // therefore it's unsafe to transfer it to another working beatmap. + return false; + } + public class TrackVirtualStore : AudioCollectionManager, ITrackStore { private readonly IFrameBasedClock referenceClock;