From 16d4544ff9b4ca72fcd0899c9cd56a1a92f91246 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 1 Apr 2022 17:06:37 +0900 Subject: [PATCH] Prevent reloads when playlist item order changes --- osu.Game/Online/Rooms/PlaylistItem.cs | 6 ++++-- .../Match/Playlist/MultiplayerPlaylist.cs | 20 +++++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/Rooms/PlaylistItem.cs b/osu.Game/Online/Rooms/PlaylistItem.cs index f696362cbb..a56851cfe6 100644 --- a/osu.Game/Online/Rooms/PlaylistItem.cs +++ b/osu.Game/Online/Rooms/PlaylistItem.cs @@ -11,6 +11,7 @@ using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Utils; namespace osu.Game.Online.Rooms { @@ -101,13 +102,13 @@ namespace osu.Game.Online.Rooms #endregion - public PlaylistItem With(IBeatmapInfo beatmap) => new PlaylistItem(beatmap) + public PlaylistItem With(Optional beatmap = default, Optional playlistOrder = default) => new PlaylistItem(beatmap.GetOr(Beatmap)) { ID = ID, OwnerID = OwnerID, RulesetID = RulesetID, Expired = Expired, - PlaylistOrder = PlaylistOrder, + PlaylistOrder = playlistOrder.GetOr(PlaylistOrder), PlayedAt = PlayedAt, AllowedMods = AllowedMods, RequiredMods = RequiredMods, @@ -119,6 +120,7 @@ namespace osu.Game.Online.Rooms && Beatmap.OnlineID == other.Beatmap.OnlineID && RulesetID == other.RulesetID && Expired == other.Expired + && PlaylistOrder == other.PlaylistOrder && AllowedMods.SequenceEqual(other.AllowedMods) && RequiredMods.SequenceEqual(other.RequiredMods); } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylist.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylist.cs index 879a21e7c1..41f548a630 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylist.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylist.cs @@ -117,8 +117,24 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist { base.PlaylistItemChanged(item); - removeItemFromLists(item.ID); - addItemToLists(item); + var newApiItem = Playlist.SingleOrDefault(i => i.ID == item.ID); + var existingApiItemInQueue = queueList.Items.SingleOrDefault(i => i.ID == item.ID); + + // Test if the only change between the two playlist items is the order. + if (newApiItem != null && existingApiItemInQueue != null && existingApiItemInQueue.With(playlistOrder: newApiItem.PlaylistOrder).Equals(newApiItem)) + { + // Set the new playlist order directly without refreshing the DrawablePlaylistItem. + existingApiItemInQueue.PlaylistOrder = newApiItem.PlaylistOrder; + + // The following isn't really required, but is here for safety and explicitness. + // MultiplayerQueueList internally binds to changes in Playlist to invalidate its own layout, which is mutated on every playlist operation. + queueList.Invalidate(); + } + else + { + removeItemFromLists(item.ID); + addItemToLists(item); + } } private void addItemToLists(MultiplayerPlaylistItem item)