From fe119da044a3290df438908da7d82a7ecfe879b4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 30 Nov 2021 19:52:36 +0900 Subject: [PATCH] Add fetching of beatmap and user data when playlist panels come on screen --- .../Online/Multiplayer/MultiplayerClient.cs | 34 +++++++++-------- .../OnlinePlay/DrawableRoomPlaylistItem.cs | 37 ++++++++++++++----- 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/osu.Game/Online/Multiplayer/MultiplayerClient.cs b/osu.Game/Online/Multiplayer/MultiplayerClient.cs index 4b44d5724f..78bf2c4db3 100644 --- a/osu.Game/Online/Multiplayer/MultiplayerClient.cs +++ b/osu.Game/Online/Multiplayer/MultiplayerClient.cs @@ -444,10 +444,18 @@ namespace osu.Game.Online.Multiplayer return Task.CompletedTask; } - Task IMultiplayerClient.SettingsChanged(MultiplayerRoomSettings newSettings) + async Task IMultiplayerClient.SettingsChanged(MultiplayerRoomSettings newSettings) { + Debug.Assert(APIRoom != null); + Debug.Assert(Room != null); + + // ensure the new selected item is populated immediately. + var playlistItem = APIRoom.Playlist.SingleOrDefault(p => p.ID == newSettings.PlaylistItemId); + + if (playlistItem != null) + await PopulateBeatmap(playlistItem).ConfigureAwait(false); + Scheduler.Add(() => updateLocalRoomSettings(newSettings)); - return Task.CompletedTask; } Task IMultiplayerClient.UserStateChanged(int userId, MultiplayerUserState state) @@ -700,7 +708,7 @@ namespace osu.Game.Online.Multiplayer CurrentMatchPlayingItem.Value = APIRoom.Playlist.SingleOrDefault(p => p.ID == settings.PlaylistItemId); } - private async Task createPlaylistItem(MultiplayerPlaylistItem item, bool populateImmediately) + private async Task createPlaylistItem(MultiplayerPlaylistItem item, bool populateBeatmapImmediately) { var ruleset = Rulesets.GetRuleset(item.RulesetID); var rulesetInstance = ruleset.CreateInstance(); @@ -708,6 +716,7 @@ namespace osu.Game.Online.Multiplayer var playlistItem = new PlaylistItem { ID = item.ID, + BeatmapID = item.BeatmapID, OwnerID = item.OwnerID, Ruleset = { Value = ruleset }, Expired = item.Expired @@ -716,23 +725,18 @@ namespace osu.Game.Online.Multiplayer playlistItem.RequiredMods.AddRange(item.RequiredMods.Select(m => m.ToMod(rulesetInstance))); playlistItem.AllowedMods.AddRange(item.AllowedMods.Select(m => m.ToMod(rulesetInstance))); - if (populateImmediately) - { - await populateFromOnline(item, playlistItem).ConfigureAwait(false); - } - else - { - // to avoid blocking other operations (like the initial room join), schedule online population to happen in the background. - // ReSharper disable once AsyncVoidLambda - Schedule(async () => await populateFromOnline(item, playlistItem).ConfigureAwait(false)); - } + if (populateBeatmapImmediately) + await PopulateBeatmap(playlistItem).ConfigureAwait(false); return playlistItem; } - private async Task populateFromOnline(MultiplayerPlaylistItem item, PlaylistItem playlistItem) + public async Task PopulateBeatmap(PlaylistItem item) { - playlistItem.Beatmap.Value = await GetAPIBeatmap(item.BeatmapID).ConfigureAwait(false); + if (item.Beatmap.Value != null) + return; + + item.Beatmap.Value = await GetAPIBeatmap(item.BeatmapID).ConfigureAwait(false); } /// diff --git a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs index 79a624b884..737c331d2f 100644 --- a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs +++ b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs @@ -16,6 +16,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Framework.Localisation; +using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Database; @@ -24,6 +25,7 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online; using osu.Game.Online.Chat; +using osu.Game.Online.Multiplayer; using osu.Game.Online.Rooms; using osu.Game.Overlays.BeatmapSet; using osu.Game.Rulesets; @@ -67,6 +69,13 @@ namespace osu.Game.Screens.OnlinePlay [Resolved] private UserLookupCache userLookupCache { get; set; } + [Resolved] + private MultiplayerClient multiplayerClient { get; set; } + + private PanelBackground panelBackground; + + private readonly DelayedLoadWrapper onScreenLoader = new DelayedLoadWrapper(Empty); + private readonly bool allowEdit; private readonly bool allowSelection; private readonly bool showItemOwner; @@ -131,11 +140,27 @@ namespace osu.Game.Screens.OnlinePlay valid.BindValueChanged(_ => Scheduler.AddOnce(refresh)); requiredMods.CollectionChanged += (_, __) => Scheduler.AddOnce(refresh); + onScreenLoader.DelayedLoadStarted += _ => + { + Task.Run(async () => + { + try + { + var user = await userLookupCache.GetUserAsync(Item.OwnerID).ConfigureAwait(false); + Schedule(() => ownerAvatar.User = user); + + await multiplayerClient.PopulateBeatmap(Item).ConfigureAwait(false); + } + catch (Exception e) + { + Logger.Log($"Error while populating playlist item {e}"); + } + }); + }; + refresh(); } - private PanelBackground panelBackground; - private void refresh() { if (!valid.Value) @@ -144,13 +169,6 @@ namespace osu.Game.Screens.OnlinePlay maskingContainer.BorderColour = colours.Red; } - if (showItemOwner) - { - ownerAvatar.Show(); - userLookupCache.GetUserAsync(Item.OwnerID) - .ContinueWith(u => Schedule(() => ownerAvatar.User = u.Result), TaskContinuationOptions.OnlyOnRanToCompletion); - } - if (Item.Beatmap.Value != null) difficultyIconContainer.Child = new DifficultyIcon(Item.Beatmap.Value, ruleset.Value, requiredMods, performBackgroundDifficultyLookup: false) { Size = new Vector2(ICON_HEIGHT) }; else @@ -203,6 +221,7 @@ namespace osu.Game.Screens.OnlinePlay Alpha = 0, AlwaysPresent = true }, + onScreenLoader, panelBackground = new PanelBackground { RelativeSizeAxes = Axes.Both,