Skip to content

Commit

Permalink
Preload song select instances in multiplayer / playlists
Browse files Browse the repository at this point in the history
Off the back of some very old feedback:
https://www.reddit.com/r/osugame/comments/1dga6m5/comment/l8ot8qy/

Maybe resolves some of ppy#21952, too
(definitely not all of it, state is still lost even with this).

Mirrors the setup `MainMenu` does. It's not really possible to just keep
one instance around since `ScreenStack` protests when trying to push an
already-loaded screen.
  • Loading branch information
bdach committed Aug 21, 2024
1 parent 4ee5a12 commit ed45efb
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Screens;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
Expand Down Expand Up @@ -277,11 +276,7 @@ private void load(OverlayColourProvider colourProvider, OsuColour colours)
RelativeSizeAxes = Axes.X,
Height = 40,
Text = "Select beatmap",
Action = () =>
{
if (matchSubScreen.IsCurrentScreen())
matchSubScreen.Push(new MultiplayerMatchSongSelect(matchSubScreen.Room));
}
Action = () => matchSubScreen.OpenSongSelection()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ public partial class MultiplayerMatchSongSelect : OnlinePlaySongSelect
private OngoingOperationTracker operationTracker { get; set; } = null!;

private readonly IBindable<bool> operationInProgress = new Bindable<bool>();
private readonly PlaylistItem? itemToEdit;

private LoadingLayer loadingLayer = null!;
private IDisposable? selectionOperation;
Expand All @@ -34,11 +33,9 @@ public partial class MultiplayerMatchSongSelect : OnlinePlaySongSelect
/// Construct a new instance of multiplayer song select.
/// </summary>
/// <param name="room">The room.</param>
/// <param name="itemToEdit">The item to be edited. May be null, in which case a new item will be added to the playlist.</param>
public MultiplayerMatchSongSelect(Room room, PlaylistItem? itemToEdit = null)
: base(room, itemToEdit)
public MultiplayerMatchSongSelect(Room room)
: base(room)
{
this.itemToEdit = itemToEdit;
}

[BackgroundDependencyLoader]
Expand Down Expand Up @@ -79,15 +76,15 @@ protected override bool SelectItem(PlaylistItem item)

var multiplayerItem = new MultiplayerPlaylistItem
{
ID = itemToEdit?.ID ?? 0,
ID = PlaylistItem?.ID ?? 0,
BeatmapID = item.Beatmap.OnlineID,
BeatmapChecksum = item.Beatmap.MD5Hash,
RulesetID = item.RulesetID,
RequiredMods = item.RequiredMods.ToArray(),
AllowedMods = item.AllowedMods.ToArray()
};

Task task = itemToEdit != null ? client.EditPlaylistItem(multiplayerItem) : client.AddPlaylistItem(multiplayerItem);
Task task = PlaylistItem != null ? client.EditPlaylistItem(multiplayerItem) : client.AddPlaylistItem(multiplayerItem);

task.FireAndForget(onSuccess: () =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
Expand Down Expand Up @@ -51,6 +52,7 @@ public partial class MultiplayerMatchSubScreen : RoomSubScreen, IHandlePresentBe
private OsuGame game { get; set; }

private AddItemButton addItemButton;
private MultiplayerMatchSongSelect songSelect;

public MultiplayerMatchSubScreen(Room room)
: base(room)
Expand All @@ -59,6 +61,28 @@ public MultiplayerMatchSubScreen(Room room)
Activity.Value = new UserActivity.InLobby(room);
}

[BackgroundDependencyLoader]
private void load()
{
preloadSongSelect();
}

private void preloadSongSelect()
{
LoadComponentAsync(songSelect = new MultiplayerMatchSongSelect(Room));
}

private MultiplayerMatchSongSelect consumeSongSelect([CanBeNull] PlaylistItem initialItem = null)
{
var s = songSelect;
Debug.Assert(s != null);

songSelect = null;

s.PlaylistItem = initialItem;
return s;
}

protected override void LoadComplete()
{
base.LoadComplete();
Expand Down Expand Up @@ -225,7 +249,7 @@ internal void OpenSongSelection(PlaylistItem itemToEdit = null)
if (!this.IsCurrentScreen())
return;

this.Push(new MultiplayerMatchSongSelect(Room, itemToEdit));
this.Push(consumeSongSelect(itemToEdit));
}

protected override Drawable CreateFooter() => new MultiplayerMatchFooter();
Expand All @@ -244,6 +268,12 @@ protected override void UpdateMods()
Mods.Value = client.LocalUser.Mods.Select(m => m.ToMod(rulesetInstance)).Concat(SelectedItem.Value.RequiredMods.Select(m => m.ToMod(rulesetInstance))).ToList();
}

public override void OnResuming(ScreenTransitionEvent e)
{
base.OnResuming(e);
preloadSongSelect();
}

[Resolved(canBeNull: true)]
private IDialogOverlay dialogOverlay { get; set; }

Expand Down
23 changes: 16 additions & 7 deletions osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ public abstract partial class OnlinePlaySongSelect : SongSelect, IOnlinePlaySubS
[Resolved(typeof(Room), nameof(Room.Playlist))]
protected BindableList<PlaylistItem> Playlist { get; private set; } = null!;

/// <summary>
/// An optional initial <see cref="PlaylistItem"/> to use for the initial beatmap/ruleset/mods.
/// If <see langword="null"/>, the last <see cref="PlaylistItem"/> in the room will be used.
/// </summary>
public PlaylistItem? PlaylistItem { get; set; }

[Resolved]
private RulesetStore rulesets { get; set; } = null!;

Expand All @@ -46,21 +52,19 @@ public abstract partial class OnlinePlaySongSelect : SongSelect, IOnlinePlaySubS
protected readonly Bindable<IReadOnlyList<Mod>> FreeMods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());

private readonly Room room;
private readonly PlaylistItem? initialItem;
private readonly FreeModSelectOverlay freeModSelectOverlay;

private PlaylistItem? initialItem => PlaylistItem ?? room.Playlist.LastOrDefault();

private IDisposable? freeModSelectOverlayRegistration;

/// <summary>
/// Creates a new <see cref="OnlinePlaySongSelect"/>.
/// </summary>
/// <param name="room">The room.</param>
/// <param name="initialItem">An optional initial <see cref="PlaylistItem"/> to use for the initial beatmap/ruleset/mods.
/// If <c>null</c>, the last <see cref="PlaylistItem"/> in the room will be used.</param>
protected OnlinePlaySongSelect(Room room, PlaylistItem? initialItem = null)
protected OnlinePlaySongSelect(Room room)
{
this.room = room;
this.initialItem = initialItem ?? room.Playlist.LastOrDefault();

Padding = new MarginPadding { Horizontal = HORIZONTAL_OVERFLOW_PADDING };

Expand All @@ -82,6 +86,13 @@ protected override void LoadComplete()
{
base.LoadComplete();

freeModSelectOverlayRegistration = OverlayManager?.RegisterBlockingOverlay(freeModSelectOverlay);
}

public override void OnEntering(ScreenTransitionEvent e)
{
base.OnEntering(e);

if (initialItem != null)
{
// Prefer using a local databased beatmap lookup since OnlineId may be -1 for an invalid beatmap selection.
Expand Down Expand Up @@ -115,8 +126,6 @@ protected override void LoadComplete()

Mods.BindValueChanged(onModsChanged);
Ruleset.BindValueChanged(onRulesetChanged);

freeModSelectOverlayRegistration = OverlayManager?.RegisterBlockingOverlay(freeModSelectOverlay);
}

private void onModsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods)
Expand Down
26 changes: 25 additions & 1 deletion osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public partial class PlaylistsRoomSubScreen : RoomSubScreen

private MatchLeaderboard leaderboard;
private SelectionPollingComponent selectionPollingComponent;
private PlaylistsSongSelect songSelect;

private FillFlowContainer progressSection;

Expand All @@ -52,6 +53,22 @@ private void load([CanBeNull] IdleTracker idleTracker)
isIdle.BindTo(idleTracker.IsIdle);

AddInternal(selectionPollingComponent = new SelectionPollingComponent(Room));
preloadSongSelect();
}

private void preloadSongSelect()
{
if (songSelect == null)
LoadComponentAsync(songSelect = new PlaylistsSongSelect(Room));
}

private PlaylistsSongSelect consumeSongSelect()
{
var s = songSelect;
Debug.Assert(s != null);

songSelect = null;
return s;
}

protected override void LoadComplete()
Expand Down Expand Up @@ -234,7 +251,7 @@ protected override void LoadComplete()
EditPlaylist = () =>
{
if (this.IsCurrentScreen())
this.Push(new PlaylistsSongSelect(Room));
this.Push(consumeSongSelect());
},
};

Expand All @@ -248,5 +265,12 @@ private void updatePollingRate()
{
Exited = () => leaderboard.RefetchScores()
});

public override void OnResuming(ScreenTransitionEvent e)
{
base.OnResuming(e);

preloadSongSelect();
}
}
}

0 comments on commit ed45efb

Please sign in to comment.