From 5c23a2cb3058724b531516c7557fee6b7d9cba11 Mon Sep 17 00:00:00 2001 From: Wezwery Date: Sat, 19 Oct 2024 00:30:11 +0300 Subject: [PATCH 01/12] Fixed a bug where custom playlist music order was ignored. Added the ability to filter music by search or by music collection to play. --- osu.Game/Overlays/Music/Playlist.cs | 2 ++ osu.Game/Overlays/Music/PlaylistOverlay.cs | 22 ++++++------- osu.Game/Overlays/MusicController.cs | 38 +++++++++++++--------- osu.Game/Overlays/NowPlayingOverlay.cs | 4 +-- 4 files changed, 38 insertions(+), 28 deletions(-) diff --git a/osu.Game/Overlays/Music/Playlist.cs b/osu.Game/Overlays/Music/Playlist.cs index ab51ca7e1dec..90b7038ff462 100644 --- a/osu.Game/Overlays/Music/Playlist.cs +++ b/osu.Game/Overlays/Music/Playlist.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -49,6 +50,7 @@ public void Filter(FilterCriteria criteria) } public Live? FirstVisibleSet => Items.FirstOrDefault(i => ((PlaylistItem)ItemMap[i]).MatchingFilter); + public IEnumerable>? AllVisibleSets => Items.Where(i => ((PlaylistItem)ItemMap[i]).MatchingFilter); protected override OsuRearrangeableListItem> CreateOsuDrawable(Live item) => new PlaylistItem(item) diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index b49c794aa30b..bf908d0ce5e9 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -26,7 +26,7 @@ public partial class PlaylistOverlay : VisibilityContainer private const float transition_duration = 600; public const float PLAYLIST_HEIGHT = 510; - private readonly BindableList> beatmapSets = new BindableList>(); + public readonly BindableList> BeatmapSets = new BindableList>(); private readonly Bindable beatmap = new Bindable(); @@ -39,7 +39,7 @@ public partial class PlaylistOverlay : VisibilityContainer private IDisposable beatmapSubscription; private FilterControl filter; - private Playlist list; + public Playlist List; [BackgroundDependencyLoader] private void load(OsuColour colours, Bindable beatmap) @@ -66,7 +66,7 @@ private void load(OsuColour colours, Bindable beatmap) Colour = colours.Gray3, RelativeSizeAxes = Axes.Both, }, - list = new Playlist + List = new Playlist { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = 95, Bottom = 10, Right = 10 }, @@ -76,7 +76,7 @@ private void load(OsuColour colours, Bindable beatmap) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - FilterChanged = criteria => list.Filter(criteria), + FilterChanged = criteria => List.Filter(criteria), Padding = new MarginPadding(10), }, }, @@ -85,7 +85,7 @@ private void load(OsuColour colours, Bindable beatmap) filter.Search.OnCommit += (_, _) => { - list.FirstVisibleSet?.PerformRead(set => + List.FirstVisibleSet?.PerformRead(set => { BeatmapInfo toSelect = set.Beatmaps.FirstOrDefault(); @@ -104,25 +104,25 @@ protected override void LoadComplete() beatmapSubscription = realm.RegisterForNotifications(r => r.All().Where(s => !s.DeletePending && !s.Protected), beatmapsChanged); - list.Items.BindTo(beatmapSets); - beatmap.BindValueChanged(working => list.SelectedSet.Value = working.NewValue.BeatmapSetInfo.ToLive(realm), true); + List.Items.BindTo(BeatmapSets); + beatmap.BindValueChanged(working => List.SelectedSet.Value = working.NewValue.BeatmapSetInfo.ToLive(realm), true); } private void beatmapsChanged(IRealmCollection sender, ChangeSet changes) { if (changes == null) { - beatmapSets.Clear(); + BeatmapSets.Clear(); // must use AddRange to avoid RearrangeableList sort overhead per add op. - beatmapSets.AddRange(sender.Select(b => b.ToLive(realm))); + BeatmapSets.AddRange(sender.Select(b => b.ToLive(realm))); return; } foreach (int i in changes.InsertedIndices) - beatmapSets.Insert(i, sender[i].ToLive(realm)); + BeatmapSets.Insert(i, sender[i].ToLive(realm)); foreach (int i in changes.DeletedIndices.OrderDescending()) - beatmapSets.RemoveAt(i); + BeatmapSets.RemoveAt(i); } protected override void PopIn() diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 87920fdf551b..f5ffaf58f821 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -122,6 +122,8 @@ public void ReloadCurrentTrack() private ScheduledDelegate? seekDelegate; + private IEnumerable>? currentPlaylist; + public void SeekTo(double position) { seekDelegate?.Cancel(); @@ -223,9 +225,12 @@ public bool TogglePause() /// /// Invoked when the operation has been performed successfully. /// Whether to include beatmap sets when navigating. - public void PreviousTrack(Action? onSuccess = null, bool allowProtectedTracks = false) => Schedule(() => + /// A playlist to navigate through. Otherwise use the current or list of all beatmap sets. + public void PreviousTrack(Action? onSuccess = null, bool allowProtectedTracks = false, IEnumerable>? playlist = null) => Schedule(() => { - PreviousTrackResult res = prev(allowProtectedTracks); + if (playlist != null && currentPlaylist != playlist) + currentPlaylist = playlist; + PreviousTrackResult res = prev(allowProtectedTracks, currentPlaylist); if (res != PreviousTrackResult.None) onSuccess?.Invoke(res); }); @@ -234,8 +239,9 @@ public void PreviousTrack(Action? onSuccess = null, bool al /// Play the previous track or restart the current track if it's current time below . /// /// Whether to include beatmap sets when navigating. + /// A playlist to navigate through. Otherwise use the current or list of all beatmap sets. /// The that indicate the decided action. - private PreviousTrackResult prev(bool allowProtectedTracks) + private PreviousTrackResult prev(bool allowProtectedTracks, IEnumerable>? playlist = null) { if (beatmap.Disabled || !AllowTrackControl.Value) return PreviousTrackResult.None; @@ -253,11 +259,11 @@ private PreviousTrackResult prev(bool allowProtectedTracks) Live? playableSet; if (Shuffle.Value) - playableSet = getNextRandom(-1, allowProtectedTracks); + playableSet = getNextRandom(-1, allowProtectedTracks, playlist); else { - playableSet = getBeatmapSets().TakeWhile(i => !i.Value.Equals(current?.BeatmapSetInfo)).LastOrDefault(s => !s.Value.Protected || allowProtectedTracks) - ?? getBeatmapSets().LastOrDefault(s => !s.Value.Protected || allowProtectedTracks); + playableSet = (playlist ?? getBeatmapSets()).TakeWhile(i => !i.Value.Equals(current?.BeatmapSetInfo)).LastOrDefault(s => !s.Value.Protected || allowProtectedTracks) + ?? (playlist ?? getBeatmapSets()).LastOrDefault(s => !s.Value.Protected || allowProtectedTracks); } if (playableSet != null) @@ -275,10 +281,12 @@ private PreviousTrackResult prev(bool allowProtectedTracks) /// /// Invoked when the operation has been performed successfully. /// Whether to include beatmap sets when navigating. - /// A of the operation. - public void NextTrack(Action? onSuccess = null, bool allowProtectedTracks = false) => Schedule(() => + /// A playlist to navigate through. Otherwise use the current or list of all beatmap sets. + public void NextTrack(Action? onSuccess = null, bool allowProtectedTracks = false, IEnumerable>? playlist = null) => Schedule(() => { - bool res = next(allowProtectedTracks); + if (playlist != null && currentPlaylist != playlist) + currentPlaylist = playlist; + bool res = next(allowProtectedTracks, currentPlaylist); if (res) onSuccess?.Invoke(); }); @@ -339,7 +347,7 @@ public void DuckMomentarily(double delayUntilRestore, DuckParameters? parameters Scheduler.AddDelayed(() => duckOperation.Dispose(), delayUntilRestore); } - private bool next(bool allowProtectedTracks) + private bool next(bool allowProtectedTracks, IEnumerable>? playlist = null) { if (beatmap.Disabled || !AllowTrackControl.Value) return false; @@ -349,13 +357,13 @@ private bool next(bool allowProtectedTracks) Live? playableSet; if (Shuffle.Value) - playableSet = getNextRandom(1, allowProtectedTracks); + playableSet = getNextRandom(1, allowProtectedTracks, playlist); else { - playableSet = getBeatmapSets().SkipWhile(i => !i.Value.Equals(current?.BeatmapSetInfo)) + playableSet = (playlist ?? getBeatmapSets()).SkipWhile(i => !i.Value.Equals(current?.BeatmapSetInfo)) .Where(i => !i.Value.Protected || allowProtectedTracks) .ElementAtOrDefault(1) - ?? getBeatmapSets().FirstOrDefault(i => !i.Value.Protected || allowProtectedTracks); + ?? (playlist ?? getBeatmapSets()).FirstOrDefault(i => !i.Value.Protected || allowProtectedTracks); } var playableBeatmap = playableSet?.Value.Beatmaps.FirstOrDefault(); @@ -370,13 +378,13 @@ private bool next(bool allowProtectedTracks) return false; } - private Live? getNextRandom(int direction, bool allowProtectedTracks) + private Live? getNextRandom(int direction, bool allowProtectedTracks, IEnumerable>? playlist = null) { try { Live result; - var possibleSets = getBeatmapSets().Where(s => !s.Value.Protected || allowProtectedTracks).ToList(); + var possibleSets = (playlist ?? getBeatmapSets()).Where(s => !s.Value.Protected || allowProtectedTracks).ToList(); if (possibleSets.Count == 0) return null; diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index f4da9a92dcfa..1cb0c552ad97 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -145,7 +145,7 @@ private void load() { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Action = () => musicController.PreviousTrack(), + Action = () => musicController.PreviousTrack(playlist: playlist?.List.AllVisibleSets), Icon = FontAwesome.Solid.StepBackward, }, playButton = new MusicIconButton @@ -161,7 +161,7 @@ private void load() { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Action = () => musicController.NextTrack(), + Action = () => musicController.NextTrack(playlist: playlist?.List.AllVisibleSets), Icon = FontAwesome.Solid.StepForward, }, } From 814d2ed23a37807d53edeb3896060543b7565b7d Mon Sep 17 00:00:00 2001 From: Wezwery Date: Sat, 19 Oct 2024 00:37:42 +0300 Subject: [PATCH 02/12] Return BeatmapSets visibility to private. --- osu.Game/Overlays/Music/PlaylistOverlay.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index bf908d0ce5e9..f53c05d0fed5 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -26,7 +26,7 @@ public partial class PlaylistOverlay : VisibilityContainer private const float transition_duration = 600; public const float PLAYLIST_HEIGHT = 510; - public readonly BindableList> BeatmapSets = new BindableList>(); + private readonly BindableList> beatmapSets = new BindableList>(); private readonly Bindable beatmap = new Bindable(); @@ -104,7 +104,7 @@ protected override void LoadComplete() beatmapSubscription = realm.RegisterForNotifications(r => r.All().Where(s => !s.DeletePending && !s.Protected), beatmapsChanged); - List.Items.BindTo(BeatmapSets); + List.Items.BindTo(beatmapSets); beatmap.BindValueChanged(working => List.SelectedSet.Value = working.NewValue.BeatmapSetInfo.ToLive(realm), true); } @@ -112,17 +112,17 @@ private void beatmapsChanged(IRealmCollection sender, ChangeSet { if (changes == null) { - BeatmapSets.Clear(); + beatmapSets.Clear(); // must use AddRange to avoid RearrangeableList sort overhead per add op. - BeatmapSets.AddRange(sender.Select(b => b.ToLive(realm))); + beatmapSets.AddRange(sender.Select(b => b.ToLive(realm))); return; } foreach (int i in changes.InsertedIndices) - BeatmapSets.Insert(i, sender[i].ToLive(realm)); + beatmapSets.Insert(i, sender[i].ToLive(realm)); foreach (int i in changes.DeletedIndices.OrderDescending()) - BeatmapSets.RemoveAt(i); + beatmapSets.RemoveAt(i); } protected override void PopIn() From 9ee8e4f4ee3ff41edb42ebe400caf9adb6c374aa Mon Sep 17 00:00:00 2001 From: Wezwery Date: Sat, 19 Oct 2024 01:04:10 +0300 Subject: [PATCH 03/12] Removed nullable from IEnumerable> --- osu.Game/Overlays/Music/Playlist.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Music/Playlist.cs b/osu.Game/Overlays/Music/Playlist.cs index 90b7038ff462..d6d7ba955ab2 100644 --- a/osu.Game/Overlays/Music/Playlist.cs +++ b/osu.Game/Overlays/Music/Playlist.cs @@ -50,7 +50,7 @@ public void Filter(FilterCriteria criteria) } public Live? FirstVisibleSet => Items.FirstOrDefault(i => ((PlaylistItem)ItemMap[i]).MatchingFilter); - public IEnumerable>? AllVisibleSets => Items.Where(i => ((PlaylistItem)ItemMap[i]).MatchingFilter); + public IEnumerable> AllVisibleSets => Items.Where(i => ((PlaylistItem)ItemMap[i]).MatchingFilter); protected override OsuRearrangeableListItem> CreateOsuDrawable(Live item) => new PlaylistItem(item) From 854a41275a55b1c22a18b25561e9b329a8fc2e11 Mon Sep 17 00:00:00 2001 From: Wezwery Date: Sat, 19 Oct 2024 14:37:56 +0300 Subject: [PATCH 04/12] Formatting code and change equals methods. --- osu.Game/Overlays/MusicController.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index f5ffaf58f821..dbf6e2d0ced9 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -228,7 +228,7 @@ public bool TogglePause() /// A playlist to navigate through. Otherwise use the current or list of all beatmap sets. public void PreviousTrack(Action? onSuccess = null, bool allowProtectedTracks = false, IEnumerable>? playlist = null) => Schedule(() => { - if (playlist != null && currentPlaylist != playlist) + if (playlist != null && !EqualityComparer>?>.Default.Equals(playlist, currentPlaylist)) currentPlaylist = playlist; PreviousTrackResult res = prev(allowProtectedTracks, currentPlaylist); if (res != PreviousTrackResult.None) @@ -284,7 +284,7 @@ private PreviousTrackResult prev(bool allowProtectedTracks, IEnumerableA playlist to navigate through. Otherwise use the current or list of all beatmap sets. public void NextTrack(Action? onSuccess = null, bool allowProtectedTracks = false, IEnumerable>? playlist = null) => Schedule(() => { - if (playlist != null && currentPlaylist != playlist) + if (playlist != null && !EqualityComparer>?>.Default.Equals(playlist, currentPlaylist)) currentPlaylist = playlist; bool res = next(allowProtectedTracks, currentPlaylist); if (res) @@ -361,8 +361,8 @@ private bool next(bool allowProtectedTracks, IEnumerable>? else { playableSet = (playlist ?? getBeatmapSets()).SkipWhile(i => !i.Value.Equals(current?.BeatmapSetInfo)) - .Where(i => !i.Value.Protected || allowProtectedTracks) - .ElementAtOrDefault(1) + .Where(i => !i.Value.Protected || allowProtectedTracks) + .ElementAtOrDefault(1) ?? (playlist ?? getBeatmapSets()).FirstOrDefault(i => !i.Value.Protected || allowProtectedTracks); } From aa57ca3225cb399031c22b6998e39b4b067deff6 Mon Sep 17 00:00:00 2001 From: Wezwery Date: Mon, 21 Oct 2024 15:28:24 +0300 Subject: [PATCH 05/12] Add Playlist to MusicController. It seems to work. --- osu.Game/Overlays/Music/Playlist.cs | 16 +++++++++ osu.Game/Overlays/Music/PlaylistOverlay.cs | 12 +++---- osu.Game/Overlays/MusicController.cs | 41 ++++++++++------------ osu.Game/Overlays/NowPlayingOverlay.cs | 4 +-- 4 files changed, 42 insertions(+), 31 deletions(-) diff --git a/osu.Game/Overlays/Music/Playlist.cs b/osu.Game/Overlays/Music/Playlist.cs index d6d7ba955ab2..451d6080eab7 100644 --- a/osu.Game/Overlays/Music/Playlist.cs +++ b/osu.Game/Overlays/Music/Playlist.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -22,6 +23,9 @@ public partial class Playlist : OsuRearrangeableListContainer base.Padding; @@ -47,6 +51,18 @@ public void Filter(FilterCriteria criteria) items.SearchTerm = criteria.SearchText; currentCriteria = criteria; + + if (currentCriteria == criteria) + { + musicController.Playlist.Clear(); + musicController.Playlist.AddRange(AllVisibleSets); + } + + items.FilterCompleted += () => + { + musicController.Playlist.Clear(); + musicController.Playlist.AddRange(AllVisibleSets); + }; } public Live? FirstVisibleSet => Items.FirstOrDefault(i => ((PlaylistItem)ItemMap[i]).MatchingFilter); diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index f53c05d0fed5..b49c794aa30b 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -39,7 +39,7 @@ public partial class PlaylistOverlay : VisibilityContainer private IDisposable beatmapSubscription; private FilterControl filter; - public Playlist List; + private Playlist list; [BackgroundDependencyLoader] private void load(OsuColour colours, Bindable beatmap) @@ -66,7 +66,7 @@ private void load(OsuColour colours, Bindable beatmap) Colour = colours.Gray3, RelativeSizeAxes = Axes.Both, }, - List = new Playlist + list = new Playlist { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = 95, Bottom = 10, Right = 10 }, @@ -76,7 +76,7 @@ private void load(OsuColour colours, Bindable beatmap) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - FilterChanged = criteria => List.Filter(criteria), + FilterChanged = criteria => list.Filter(criteria), Padding = new MarginPadding(10), }, }, @@ -85,7 +85,7 @@ private void load(OsuColour colours, Bindable beatmap) filter.Search.OnCommit += (_, _) => { - List.FirstVisibleSet?.PerformRead(set => + list.FirstVisibleSet?.PerformRead(set => { BeatmapInfo toSelect = set.Beatmaps.FirstOrDefault(); @@ -104,8 +104,8 @@ protected override void LoadComplete() beatmapSubscription = realm.RegisterForNotifications(r => r.All().Where(s => !s.DeletePending && !s.Protected), beatmapsChanged); - List.Items.BindTo(beatmapSets); - beatmap.BindValueChanged(working => List.SelectedSet.Value = working.NewValue.BeatmapSetInfo.ToLive(realm), true); + list.Items.BindTo(beatmapSets); + beatmap.BindValueChanged(working => list.SelectedSet.Value = working.NewValue.BeatmapSetInfo.ToLive(realm), true); } private void beatmapsChanged(IRealmCollection sender, ChangeSet changes) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index dbf6e2d0ced9..c8886cdb93dc 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -60,6 +60,8 @@ public partial class MusicController : CompositeDrawable [Resolved] private IBindable> mods { get; set; } = null!; + public BindableList> Playlist { get; private set; } = null!; + public DrawableTrack CurrentTrack { get; private set; } = new DrawableTrack(new TrackVirtual(1000)); [Resolved] @@ -90,6 +92,8 @@ protected override void LoadComplete() { base.LoadComplete(); + Playlist = new BindableList>(getBeatmapSets()); + beatmap.BindValueChanged(b => { if (b.NewValue != null) @@ -122,8 +126,6 @@ public void ReloadCurrentTrack() private ScheduledDelegate? seekDelegate; - private IEnumerable>? currentPlaylist; - public void SeekTo(double position) { seekDelegate?.Cancel(); @@ -225,12 +227,9 @@ public bool TogglePause() /// /// Invoked when the operation has been performed successfully. /// Whether to include beatmap sets when navigating. - /// A playlist to navigate through. Otherwise use the current or list of all beatmap sets. - public void PreviousTrack(Action? onSuccess = null, bool allowProtectedTracks = false, IEnumerable>? playlist = null) => Schedule(() => + public void PreviousTrack(Action? onSuccess = null, bool allowProtectedTracks = false) => Schedule(() => { - if (playlist != null && !EqualityComparer>?>.Default.Equals(playlist, currentPlaylist)) - currentPlaylist = playlist; - PreviousTrackResult res = prev(allowProtectedTracks, currentPlaylist); + PreviousTrackResult res = prev(allowProtectedTracks); if (res != PreviousTrackResult.None) onSuccess?.Invoke(res); }); @@ -239,9 +238,8 @@ public void PreviousTrack(Action? onSuccess = null, bool al /// Play the previous track or restart the current track if it's current time below . /// /// Whether to include beatmap sets when navigating. - /// A playlist to navigate through. Otherwise use the current or list of all beatmap sets. /// The that indicate the decided action. - private PreviousTrackResult prev(bool allowProtectedTracks, IEnumerable>? playlist = null) + private PreviousTrackResult prev(bool allowProtectedTracks) { if (beatmap.Disabled || !AllowTrackControl.Value) return PreviousTrackResult.None; @@ -259,11 +257,11 @@ private PreviousTrackResult prev(bool allowProtectedTracks, IEnumerable? playableSet; if (Shuffle.Value) - playableSet = getNextRandom(-1, allowProtectedTracks, playlist); + playableSet = getNextRandom(-1, allowProtectedTracks); else { - playableSet = (playlist ?? getBeatmapSets()).TakeWhile(i => !i.Value.Equals(current?.BeatmapSetInfo)).LastOrDefault(s => !s.Value.Protected || allowProtectedTracks) - ?? (playlist ?? getBeatmapSets()).LastOrDefault(s => !s.Value.Protected || allowProtectedTracks); + playableSet = Playlist.TakeWhile(i => !i.Value.Equals(current?.BeatmapSetInfo)).LastOrDefault(s => !s.Value.Protected || allowProtectedTracks) + ?? Playlist.LastOrDefault(s => !s.Value.Protected || allowProtectedTracks); } if (playableSet != null) @@ -281,12 +279,9 @@ private PreviousTrackResult prev(bool allowProtectedTracks, IEnumerable /// Invoked when the operation has been performed successfully. /// Whether to include beatmap sets when navigating. - /// A playlist to navigate through. Otherwise use the current or list of all beatmap sets. - public void NextTrack(Action? onSuccess = null, bool allowProtectedTracks = false, IEnumerable>? playlist = null) => Schedule(() => + public void NextTrack(Action? onSuccess = null, bool allowProtectedTracks = false) => Schedule(() => { - if (playlist != null && !EqualityComparer>?>.Default.Equals(playlist, currentPlaylist)) - currentPlaylist = playlist; - bool res = next(allowProtectedTracks, currentPlaylist); + bool res = next(allowProtectedTracks); if (res) onSuccess?.Invoke(); }); @@ -347,7 +342,7 @@ public void DuckMomentarily(double delayUntilRestore, DuckParameters? parameters Scheduler.AddDelayed(() => duckOperation.Dispose(), delayUntilRestore); } - private bool next(bool allowProtectedTracks, IEnumerable>? playlist = null) + private bool next(bool allowProtectedTracks) { if (beatmap.Disabled || !AllowTrackControl.Value) return false; @@ -357,13 +352,13 @@ private bool next(bool allowProtectedTracks, IEnumerable>? Live? playableSet; if (Shuffle.Value) - playableSet = getNextRandom(1, allowProtectedTracks, playlist); + playableSet = getNextRandom(1, allowProtectedTracks); else { - playableSet = (playlist ?? getBeatmapSets()).SkipWhile(i => !i.Value.Equals(current?.BeatmapSetInfo)) + playableSet = Playlist.SkipWhile(i => !i.Value.Equals(current?.BeatmapSetInfo)) .Where(i => !i.Value.Protected || allowProtectedTracks) .ElementAtOrDefault(1) - ?? (playlist ?? getBeatmapSets()).FirstOrDefault(i => !i.Value.Protected || allowProtectedTracks); + ?? Playlist.FirstOrDefault(i => !i.Value.Protected || allowProtectedTracks); } var playableBeatmap = playableSet?.Value.Beatmaps.FirstOrDefault(); @@ -378,13 +373,13 @@ private bool next(bool allowProtectedTracks, IEnumerable>? return false; } - private Live? getNextRandom(int direction, bool allowProtectedTracks, IEnumerable>? playlist = null) + private Live? getNextRandom(int direction, bool allowProtectedTracks) { try { Live result; - var possibleSets = (playlist ?? getBeatmapSets()).Where(s => !s.Value.Protected || allowProtectedTracks).ToList(); + var possibleSets = Playlist.Where(s => !s.Value.Protected || allowProtectedTracks).ToList(); if (possibleSets.Count == 0) return null; diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index 1cb0c552ad97..f4da9a92dcfa 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -145,7 +145,7 @@ private void load() { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Action = () => musicController.PreviousTrack(playlist: playlist?.List.AllVisibleSets), + Action = () => musicController.PreviousTrack(), Icon = FontAwesome.Solid.StepBackward, }, playButton = new MusicIconButton @@ -161,7 +161,7 @@ private void load() { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Action = () => musicController.NextTrack(playlist: playlist?.List.AllVisibleSets), + Action = () => musicController.NextTrack(), Icon = FontAwesome.Solid.StepForward, }, } From 7b989b5801ddb1fbc126e1e46a0f868cc72f900c Mon Sep 17 00:00:00 2001 From: Wezwery Date: Mon, 21 Oct 2024 16:16:14 +0300 Subject: [PATCH 06/12] Code formatting. Calling a method once per frame. --- osu.Game/Overlays/Music/Playlist.cs | 11 +++++------ osu.Game/Overlays/MusicController.cs | 8 ++++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/Music/Playlist.cs b/osu.Game/Overlays/Music/Playlist.cs index 451d6080eab7..1642079d8599 100644 --- a/osu.Game/Overlays/Music/Playlist.cs +++ b/osu.Game/Overlays/Music/Playlist.cs @@ -53,16 +53,15 @@ public void Filter(FilterCriteria criteria) currentCriteria = criteria; if (currentCriteria == criteria) - { - musicController.Playlist.Clear(); - musicController.Playlist.AddRange(AllVisibleSets); - } + updateMusicControllerPlaylist(); - items.FilterCompleted += () => + items.FilterCompleted += () => Scheduler.AddOnce(updateMusicControllerPlaylist); + + void updateMusicControllerPlaylist() { musicController.Playlist.Clear(); musicController.Playlist.AddRange(AllVisibleSets); - }; + } } public Live? FirstVisibleSet => Items.FirstOrDefault(i => ((PlaylistItem)ItemMap[i]).MatchingFilter); diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index c8886cdb93dc..5827aca90766 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -60,7 +60,7 @@ public partial class MusicController : CompositeDrawable [Resolved] private IBindable> mods { get; set; } = null!; - public BindableList> Playlist { get; private set; } = null!; + public readonly BindableList> Playlist = new BindableList>(); public DrawableTrack CurrentTrack { get; private set; } = new DrawableTrack(new TrackVirtual(1000)); @@ -92,7 +92,7 @@ protected override void LoadComplete() { base.LoadComplete(); - Playlist = new BindableList>(getBeatmapSets()); + Playlist.AddRange(getBeatmapSets()); beatmap.BindValueChanged(b => { @@ -356,8 +356,8 @@ private bool next(bool allowProtectedTracks) else { playableSet = Playlist.SkipWhile(i => !i.Value.Equals(current?.BeatmapSetInfo)) - .Where(i => !i.Value.Protected || allowProtectedTracks) - .ElementAtOrDefault(1) + .Where(i => !i.Value.Protected || allowProtectedTracks) + .ElementAtOrDefault(1) ?? Playlist.FirstOrDefault(i => !i.Value.Protected || allowProtectedTracks); } From 191699054e450037fb22ca08e2f944b8f2e927cd Mon Sep 17 00:00:00 2001 From: Wezwery Date: Wed, 23 Oct 2024 21:20:41 +0300 Subject: [PATCH 07/12] Register a realm notification for beatmaps changes. Tests seem to work. --- .../Menus/TestSceneMusicActionHandling.cs | 2 + osu.Game/Overlays/Music/Playlist.cs | 13 +++++-- osu.Game/Overlays/MusicController.cs | 39 ++++++++++++++++++- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs index 32009dc8c240..5dba3b62880f 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs @@ -48,6 +48,8 @@ public void TestMusicNavigationActions() }); }); + AddAssert("empty playlist", () => Game.MusicController.Playlist.Count > 0); + AddStep("bind to track change", () => { trackChangeQueue = new Queue<(IWorkingBeatmap, TrackChangeDirection)>(); diff --git a/osu.Game/Overlays/Music/Playlist.cs b/osu.Game/Overlays/Music/Playlist.cs index 1642079d8599..378f6dc534d8 100644 --- a/osu.Game/Overlays/Music/Playlist.cs +++ b/osu.Game/Overlays/Music/Playlist.cs @@ -55,18 +55,25 @@ public void Filter(FilterCriteria criteria) if (currentCriteria == criteria) updateMusicControllerPlaylist(); - items.FilterCompleted += () => Scheduler.AddOnce(updateMusicControllerPlaylist); + items.FilterCompleted += updateMusicControllerPlaylist; - void updateMusicControllerPlaylist() + void updateMusicControllerPlaylist() => Scheduler.AddOnce(() => { + musicController.PlaylistHookedByOverlay.Value = true; musicController.Playlist.Clear(); musicController.Playlist.AddRange(AllVisibleSets); - } + }); } public Live? FirstVisibleSet => Items.FirstOrDefault(i => ((PlaylistItem)ItemMap[i]).MatchingFilter); public IEnumerable> AllVisibleSets => Items.Where(i => ((PlaylistItem)ItemMap[i]).MatchingFilter); + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + musicController.PlaylistHookedByOverlay.Value = false; + } + protected override OsuRearrangeableListItem> CreateOsuDrawable(Live item) => new PlaylistItem(item) { diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 5827aca90766..ab25fb95e037 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -20,6 +20,7 @@ using osu.Game.Configuration; using osu.Game.Database; using osu.Game.Rulesets.Mods; +using Realms; namespace osu.Game.Overlays { @@ -61,12 +62,15 @@ public partial class MusicController : CompositeDrawable private IBindable> mods { get; set; } = null!; public readonly BindableList> Playlist = new BindableList>(); + public readonly BindableBool PlaylistHookedByOverlay = new BindableBool(false); public DrawableTrack CurrentTrack { get; private set; } = new DrawableTrack(new TrackVirtual(1000)); [Resolved] private RealmAccess realm { get; set; } = null!; + private IDisposable? beatmapSubscription; + private BindableNumber sampleVolume = null!; private readonly BindableDouble audioDuckVolume = new BindableDouble(1); @@ -92,8 +96,16 @@ protected override void LoadComplete() { base.LoadComplete(); - Playlist.AddRange(getBeatmapSets()); + beatmapSubscription = realm.RegisterForNotifications(r => r.All().Where(s => !s.DeletePending && !s.Protected), beatmapsChanged); + PlaylistHookedByOverlay.ValueChanged += b => + { + if (!b.NewValue) + { + Playlist.Clear(); + Playlist.AddRange(getBeatmapSets()); + } + }; beatmap.BindValueChanged(b => { if (b.NewValue != null) @@ -102,6 +114,25 @@ protected override void LoadComplete() mods.BindValueChanged(_ => ResetTrackAdjustments(), true); } + private void beatmapsChanged(IRealmCollection sender, ChangeSet? changes) + { + if (PlaylistHookedByOverlay.Value) return; + + if (changes == null) + { + Playlist.Clear(); + // must use AddRange to avoid RearrangeableList sort overhead per add op. + Playlist.AddRange(sender.Select(b => b.ToLive(realm))); + return; + } + + foreach (int i in changes.InsertedIndices) + Playlist.Insert(i, sender[i].ToLive(realm)); + + foreach (int i in changes.DeletedIndices.OrderDescending()) + Playlist.RemoveAt(i); + } + /// /// Forcefully reload the current 's track from disk. /// @@ -602,6 +633,12 @@ public void ResetTrackAdjustments() mod.ApplyToTrack(modTrackAdjustments); } } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + beatmapSubscription?.Dispose(); + } } public class DuckParameters From a75ad5cd119b5a975f755bce9776bb7179a9c9fd Mon Sep 17 00:00:00 2001 From: Wezwery Date: Wed, 23 Oct 2024 21:37:20 +0300 Subject: [PATCH 08/12] Added empty playlist checks to other tests in TestSceneMusicActionHandling.cs --- osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs index 5dba3b62880f..905bfe24d431 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs @@ -100,6 +100,8 @@ public void TestShuffleBackwards() beatmap.Length = 60_000; })); + AddAssert("empty playlist", () => Game.MusicController.Playlist.Count > 0); + AddStep("bind to track change", () => { trackChangeQueue = new Queue<(IWorkingBeatmap, TrackChangeDirection)>(); @@ -142,6 +144,8 @@ public void TestShuffleForwards() beatmap.Length = 60_000; })); + AddAssert("empty playlist", () => Game.MusicController.Playlist.Count > 0); + AddStep("bind to track change", () => { trackChangeQueue = new Queue<(IWorkingBeatmap, TrackChangeDirection)>(); @@ -177,6 +181,8 @@ public void TestShuffleBackAndForth() beatmap.Length = 60_000; })); + AddAssert("empty playlist", () => Game.MusicController.Playlist.Count > 0); + AddStep("bind to track change", () => { trackChangeQueue = new Queue<(IWorkingBeatmap, TrackChangeDirection)>(); From 42d712b587c234ab9915eb26075911fd9452bbb2 Mon Sep 17 00:00:00 2001 From: Wezwery Date: Thu, 24 Oct 2024 13:35:28 +0300 Subject: [PATCH 09/12] Remove bad code. Add beatmapsets to MusicController.Playlist when Playlist.cs is not loaded. --- osu.Game/Overlays/Music/Playlist.cs | 7 ---- osu.Game/Overlays/Music/PlaylistOverlay.cs | 20 +++++++++-- osu.Game/Overlays/MusicController.cs | 39 ---------------------- osu.Game/Overlays/NowPlayingOverlay.cs | 29 ++++++---------- 4 files changed, 29 insertions(+), 66 deletions(-) diff --git a/osu.Game/Overlays/Music/Playlist.cs b/osu.Game/Overlays/Music/Playlist.cs index 378f6dc534d8..3a82412e4b3a 100644 --- a/osu.Game/Overlays/Music/Playlist.cs +++ b/osu.Game/Overlays/Music/Playlist.cs @@ -59,7 +59,6 @@ public void Filter(FilterCriteria criteria) void updateMusicControllerPlaylist() => Scheduler.AddOnce(() => { - musicController.PlaylistHookedByOverlay.Value = true; musicController.Playlist.Clear(); musicController.Playlist.AddRange(AllVisibleSets); }); @@ -68,12 +67,6 @@ void updateMusicControllerPlaylist() => Scheduler.AddOnce(() => public Live? FirstVisibleSet => Items.FirstOrDefault(i => ((PlaylistItem)ItemMap[i]).MatchingFilter); public IEnumerable> AllVisibleSets => Items.Where(i => ((PlaylistItem)ItemMap[i]).MatchingFilter); - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - musicController.PlaylistHookedByOverlay.Value = false; - } - protected override OsuRearrangeableListItem> CreateOsuDrawable(Live item) => new PlaylistItem(item) { diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index b49c794aa30b..73c18d674c62 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -36,6 +36,9 @@ public partial class PlaylistOverlay : VisibilityContainer [Resolved] private RealmAccess realm { get; set; } + [Resolved] + private MusicController musicController { get; set; } + private IDisposable beatmapSubscription; private FilterControl filter; @@ -46,6 +49,8 @@ private void load(OsuColour colours, Bindable beatmap) { this.beatmap.BindTo(beatmap); + beatmapSubscription = realm.RegisterForNotifications(r => r.All().Where(s => !s.DeletePending && !s.Protected), beatmapsChanged); + Children = new Drawable[] { new Container @@ -102,8 +107,6 @@ protected override void LoadComplete() { base.LoadComplete(); - beatmapSubscription = realm.RegisterForNotifications(r => r.All().Where(s => !s.DeletePending && !s.Protected), beatmapsChanged); - list.Items.BindTo(beatmapSets); beatmap.BindValueChanged(working => list.SelectedSet.Value = working.NewValue.BeatmapSetInfo.ToLive(realm), true); } @@ -115,14 +118,27 @@ private void beatmapsChanged(IRealmCollection sender, ChangeSet beatmapSets.Clear(); // must use AddRange to avoid RearrangeableList sort overhead per add op. beatmapSets.AddRange(sender.Select(b => b.ToLive(realm))); + if (list.IsLoaded == false) + { + musicController.Playlist.Clear(); + musicController.Playlist.AddRange(sender.Select(b => b.ToLive(realm))); + } return; } foreach (int i in changes.InsertedIndices) + { beatmapSets.Insert(i, sender[i].ToLive(realm)); + if (list.IsLoaded == false) + musicController.Playlist.Insert(i, sender[i].ToLive(realm)); + } foreach (int i in changes.DeletedIndices.OrderDescending()) + { beatmapSets.RemoveAt(i); + if (list.IsLoaded == false) + musicController.Playlist.RemoveAt(i); + } } protected override void PopIn() diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index ab25fb95e037..1d52e4ef99b1 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -20,7 +20,6 @@ using osu.Game.Configuration; using osu.Game.Database; using osu.Game.Rulesets.Mods; -using Realms; namespace osu.Game.Overlays { @@ -62,15 +61,12 @@ public partial class MusicController : CompositeDrawable private IBindable> mods { get; set; } = null!; public readonly BindableList> Playlist = new BindableList>(); - public readonly BindableBool PlaylistHookedByOverlay = new BindableBool(false); public DrawableTrack CurrentTrack { get; private set; } = new DrawableTrack(new TrackVirtual(1000)); [Resolved] private RealmAccess realm { get; set; } = null!; - private IDisposable? beatmapSubscription; - private BindableNumber sampleVolume = null!; private readonly BindableDouble audioDuckVolume = new BindableDouble(1); @@ -96,16 +92,6 @@ protected override void LoadComplete() { base.LoadComplete(); - beatmapSubscription = realm.RegisterForNotifications(r => r.All().Where(s => !s.DeletePending && !s.Protected), beatmapsChanged); - - PlaylistHookedByOverlay.ValueChanged += b => - { - if (!b.NewValue) - { - Playlist.Clear(); - Playlist.AddRange(getBeatmapSets()); - } - }; beatmap.BindValueChanged(b => { if (b.NewValue != null) @@ -114,25 +100,6 @@ protected override void LoadComplete() mods.BindValueChanged(_ => ResetTrackAdjustments(), true); } - private void beatmapsChanged(IRealmCollection sender, ChangeSet? changes) - { - if (PlaylistHookedByOverlay.Value) return; - - if (changes == null) - { - Playlist.Clear(); - // must use AddRange to avoid RearrangeableList sort overhead per add op. - Playlist.AddRange(sender.Select(b => b.ToLive(realm))); - return; - } - - foreach (int i in changes.InsertedIndices) - Playlist.Insert(i, sender[i].ToLive(realm)); - - foreach (int i in changes.DeletedIndices.OrderDescending()) - Playlist.RemoveAt(i); - } - /// /// Forcefully reload the current 's track from disk. /// @@ -633,12 +600,6 @@ public void ResetTrackAdjustments() mod.ApplyToTrack(modTrackAdjustments); } } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - beatmapSubscription?.Dispose(); - } } public class DuckParameters diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index f4da9a92dcfa..c50934ef364f 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -203,29 +203,22 @@ private void load() } }, }; - } - private void togglePlaylist() - { - if (playlist == null) + LoadComponentAsync(playlist = new PlaylistOverlay { - LoadComponentAsync(playlist = new PlaylistOverlay - { - RelativeSizeAxes = Axes.Both, - }, _ => - { - playlistContainer.Add(playlist); - - playlist.State.BindValueChanged(s => playlistButton.FadeColour(s.NewValue == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint), true); - - togglePlaylist(); - }); + RelativeSizeAxes = Axes.Both, + }, _ => + { + playlistContainer.Add(playlist); - return; - } + playlist.State.BindValueChanged(s => playlistButton.FadeColour(s.NewValue == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint), true); + }); + } + private void togglePlaylist() + { if (!beatmap.Disabled) - playlist.ToggleVisibility(); + playlist?.ToggleVisibility(); } protected override void LoadComplete() From 0fcd5e7ca376f04a9647d085121043d60049a924 Mon Sep 17 00:00:00 2001 From: Wezwery Date: Thu, 24 Oct 2024 17:06:27 +0300 Subject: [PATCH 10/12] Adding spaces --- osu.Game/Overlays/Music/PlaylistOverlay.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 73c18d674c62..d911a7c78fe8 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -118,11 +118,13 @@ private void beatmapsChanged(IRealmCollection sender, ChangeSet beatmapSets.Clear(); // must use AddRange to avoid RearrangeableList sort overhead per add op. beatmapSets.AddRange(sender.Select(b => b.ToLive(realm))); + if (list.IsLoaded == false) { musicController.Playlist.Clear(); musicController.Playlist.AddRange(sender.Select(b => b.ToLive(realm))); } + return; } From d4aaa86d706b377ee983c5a05831aa43cc55c810 Mon Sep 17 00:00:00 2001 From: Wezwery Date: Fri, 1 Nov 2024 21:09:22 +0200 Subject: [PATCH 11/12] Get all beatmap sets when playlist is empty --- .../Menus/TestSceneMusicActionHandling.cs | 8 ----- osu.Game/Overlays/Music/PlaylistOverlay.cs | 14 ++------- osu.Game/Overlays/MusicController.cs | 17 ++++++----- osu.Game/Overlays/NowPlayingOverlay.cs | 29 ++++++++++++------- 4 files changed, 29 insertions(+), 39 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs index 905bfe24d431..32009dc8c240 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs @@ -48,8 +48,6 @@ public void TestMusicNavigationActions() }); }); - AddAssert("empty playlist", () => Game.MusicController.Playlist.Count > 0); - AddStep("bind to track change", () => { trackChangeQueue = new Queue<(IWorkingBeatmap, TrackChangeDirection)>(); @@ -100,8 +98,6 @@ public void TestShuffleBackwards() beatmap.Length = 60_000; })); - AddAssert("empty playlist", () => Game.MusicController.Playlist.Count > 0); - AddStep("bind to track change", () => { trackChangeQueue = new Queue<(IWorkingBeatmap, TrackChangeDirection)>(); @@ -144,8 +140,6 @@ public void TestShuffleForwards() beatmap.Length = 60_000; })); - AddAssert("empty playlist", () => Game.MusicController.Playlist.Count > 0); - AddStep("bind to track change", () => { trackChangeQueue = new Queue<(IWorkingBeatmap, TrackChangeDirection)>(); @@ -181,8 +175,6 @@ public void TestShuffleBackAndForth() beatmap.Length = 60_000; })); - AddAssert("empty playlist", () => Game.MusicController.Playlist.Count > 0); - AddStep("bind to track change", () => { trackChangeQueue = new Queue<(IWorkingBeatmap, TrackChangeDirection)>(); diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index d911a7c78fe8..9018dac6bea1 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -49,8 +49,6 @@ private void load(OsuColour colours, Bindable beatmap) { this.beatmap.BindTo(beatmap); - beatmapSubscription = realm.RegisterForNotifications(r => r.All().Where(s => !s.DeletePending && !s.Protected), beatmapsChanged); - Children = new Drawable[] { new Container @@ -107,6 +105,8 @@ protected override void LoadComplete() { base.LoadComplete(); + beatmapSubscription = realm.RegisterForNotifications(r => r.All().Where(s => !s.DeletePending && !s.Protected), beatmapsChanged); + list.Items.BindTo(beatmapSets); beatmap.BindValueChanged(working => list.SelectedSet.Value = working.NewValue.BeatmapSetInfo.ToLive(realm), true); } @@ -119,27 +119,17 @@ private void beatmapsChanged(IRealmCollection sender, ChangeSet // must use AddRange to avoid RearrangeableList sort overhead per add op. beatmapSets.AddRange(sender.Select(b => b.ToLive(realm))); - if (list.IsLoaded == false) - { - musicController.Playlist.Clear(); - musicController.Playlist.AddRange(sender.Select(b => b.ToLive(realm))); - } - return; } foreach (int i in changes.InsertedIndices) { beatmapSets.Insert(i, sender[i].ToLive(realm)); - if (list.IsLoaded == false) - musicController.Playlist.Insert(i, sender[i].ToLive(realm)); } foreach (int i in changes.DeletedIndices.OrderDescending()) { beatmapSets.RemoveAt(i); - if (list.IsLoaded == false) - musicController.Playlist.RemoveAt(i); } } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 1d52e4ef99b1..62428565b948 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -258,8 +258,8 @@ private PreviousTrackResult prev(bool allowProtectedTracks) playableSet = getNextRandom(-1, allowProtectedTracks); else { - playableSet = Playlist.TakeWhile(i => !i.Value.Equals(current?.BeatmapSetInfo)).LastOrDefault(s => !s.Value.Protected || allowProtectedTracks) - ?? Playlist.LastOrDefault(s => !s.Value.Protected || allowProtectedTracks); + playableSet = getBeatmapSets().TakeWhile(i => !i.Value.Equals(current?.BeatmapSetInfo)).LastOrDefault(s => !s.Value.Protected || allowProtectedTracks) + ?? getBeatmapSets().LastOrDefault(s => !s.Value.Protected || allowProtectedTracks); } if (playableSet != null) @@ -353,10 +353,10 @@ private bool next(bool allowProtectedTracks) playableSet = getNextRandom(1, allowProtectedTracks); else { - playableSet = Playlist.SkipWhile(i => !i.Value.Equals(current?.BeatmapSetInfo)) + playableSet = getBeatmapSets().SkipWhile(i => !i.Value.Equals(current?.BeatmapSetInfo)) .Where(i => !i.Value.Protected || allowProtectedTracks) .ElementAtOrDefault(1) - ?? Playlist.FirstOrDefault(i => !i.Value.Protected || allowProtectedTracks); + ?? getBeatmapSets().FirstOrDefault(i => !i.Value.Protected || allowProtectedTracks); } var playableBeatmap = playableSet?.Value.Beatmaps.FirstOrDefault(); @@ -377,7 +377,7 @@ private bool next(bool allowProtectedTracks) { Live result; - var possibleSets = Playlist.Where(s => !s.Value.Protected || allowProtectedTracks).ToList(); + var possibleSets = getBeatmapSets().Where(s => !s.Value.Protected || allowProtectedTracks).ToList(); if (possibleSets.Count == 0) return null; @@ -460,9 +460,10 @@ private void restartTrack() private TrackChangeDirection? queuedDirection; - private IEnumerable> getBeatmapSets() => realm.Realm.All().Where(s => !s.DeletePending) - .AsEnumerable() - .Select(s => new RealmLive(s, realm)); + private IEnumerable> getBeatmapSets() => Playlist.IsDefault ? realm.Realm.All().Where(s => !s.DeletePending) + .AsEnumerable() + .Select(s => new RealmLive(s, realm)) + : Playlist.Where(s => !s.Value.DeletePending); private void changeBeatmap(WorkingBeatmap newWorking) { diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index c50934ef364f..f4da9a92dcfa 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -203,22 +203,29 @@ private void load() } }, }; - - LoadComponentAsync(playlist = new PlaylistOverlay - { - RelativeSizeAxes = Axes.Both, - }, _ => - { - playlistContainer.Add(playlist); - - playlist.State.BindValueChanged(s => playlistButton.FadeColour(s.NewValue == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint), true); - }); } private void togglePlaylist() { + if (playlist == null) + { + LoadComponentAsync(playlist = new PlaylistOverlay + { + RelativeSizeAxes = Axes.Both, + }, _ => + { + playlistContainer.Add(playlist); + + playlist.State.BindValueChanged(s => playlistButton.FadeColour(s.NewValue == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint), true); + + togglePlaylist(); + }); + + return; + } + if (!beatmap.Disabled) - playlist?.ToggleVisibility(); + playlist.ToggleVisibility(); } protected override void LoadComplete() From bd467a62c9ed0ee0428d75d0fb38a23497d66f4a Mon Sep 17 00:00:00 2001 From: Wezwery Date: Fri, 1 Nov 2024 22:08:48 +0200 Subject: [PATCH 12/12] Code Quality fix --- osu.Game/Overlays/Music/PlaylistOverlay.cs | 3 --- osu.Game/Overlays/MusicController.cs | 17 +++++++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 9018dac6bea1..eb1f2ff05a8c 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -36,9 +36,6 @@ public partial class PlaylistOverlay : VisibilityContainer [Resolved] private RealmAccess realm { get; set; } - [Resolved] - private MusicController musicController { get; set; } - private IDisposable beatmapSubscription; private FilterControl filter; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 62428565b948..e8d3942ab3bb 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -354,8 +354,8 @@ private bool next(bool allowProtectedTracks) else { playableSet = getBeatmapSets().SkipWhile(i => !i.Value.Equals(current?.BeatmapSetInfo)) - .Where(i => !i.Value.Protected || allowProtectedTracks) - .ElementAtOrDefault(1) + .Where(i => !i.Value.Protected || allowProtectedTracks) + .ElementAtOrDefault(1) ?? getBeatmapSets().FirstOrDefault(i => !i.Value.Protected || allowProtectedTracks); } @@ -460,10 +460,15 @@ private void restartTrack() private TrackChangeDirection? queuedDirection; - private IEnumerable> getBeatmapSets() => Playlist.IsDefault ? realm.Realm.All().Where(s => !s.DeletePending) - .AsEnumerable() - .Select(s => new RealmLive(s, realm)) - : Playlist.Where(s => !s.Value.DeletePending); + private IEnumerable> getBeatmapSets() + { + return Playlist.IsDefault + ? realm.Realm.All() + .Where(s => !s.DeletePending) + .AsEnumerable() + .Select(s => new RealmLive(s, realm)) + : Playlist.Where(s => !s.Value.DeletePending); + } private void changeBeatmap(WorkingBeatmap newWorking) {