1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 18:23:04 +08:00

Merge pull request #18708 from smoogipoo/multi-song-select-operation

Block multiplayer operations until beatmap selection completes
This commit is contained in:
Bartłomiej Dach 2022-06-18 12:42:04 +02:00 committed by GitHub
commit cbc218200a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 22 deletions

View File

@ -1,11 +1,11 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable disable
using System;
using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Screens;
using osu.Game.Beatmaps;
using osu.Game.Graphics.UserInterface;
@ -20,11 +20,16 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
public class MultiplayerMatchSongSelect : OnlinePlaySongSelect
{
[Resolved]
private MultiplayerClient client { get; set; }
private MultiplayerClient client { get; set; } = null!;
[Resolved]
private OngoingOperationTracker operationTracker { get; set; } = null!;
private readonly IBindable<bool> operationInProgress = new Bindable<bool>();
private readonly long? itemToEdit;
private LoadingLayer loadingLayer;
private LoadingLayer loadingLayer = null!;
private IDisposable? selectionOperation;
/// <summary>
/// Construct a new instance of multiplayer song select.
@ -33,7 +38,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
/// <param name="itemToEdit">The item to be edited. May be null, in which case a new item will be added to the playlist.</param>
/// <param name="beatmap">An optional initial beatmap selection to perform.</param>
/// <param name="ruleset">An optional initial ruleset selection to perform.</param>
public MultiplayerMatchSongSelect(Room room, long? itemToEdit = null, WorkingBeatmap beatmap = null, RulesetInfo ruleset = null)
public MultiplayerMatchSongSelect(Room room, long? itemToEdit = null, WorkingBeatmap? beatmap = null, RulesetInfo? ruleset = null)
: base(room)
{
this.itemToEdit = itemToEdit;
@ -54,13 +59,32 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
AddInternal(loadingLayer = new LoadingLayer(true));
}
protected override void SelectItem(PlaylistItem item)
protected override void LoadComplete()
{
base.LoadComplete();
operationInProgress.BindTo(operationTracker.InProgress);
operationInProgress.BindValueChanged(_ => updateLoadingLayer(), true);
}
private void updateLoadingLayer()
{
if (operationInProgress.Value)
loadingLayer.Show();
else
loadingLayer.Hide();
}
protected override bool SelectItem(PlaylistItem item)
{
if (operationInProgress.Value)
return false;
// If the client is already in a room, update via the client.
// Otherwise, update the playlist directly in preparation for it to be submitted to the API on match creation.
if (client.Room != null)
{
loadingLayer.Show();
selectionOperation = operationTracker.BeginOperation();
var multiplayerItem = new MultiplayerPlaylistItem
{
@ -74,18 +98,25 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
Task task = itemToEdit != null ? client.EditPlaylistItem(multiplayerItem) : client.AddPlaylistItem(multiplayerItem);
task.FireAndForget(onSuccess: () => Schedule(() =>
task.FireAndForget(onSuccess: () =>
{
loadingLayer.Hide();
selectionOperation.Dispose();
Schedule(() =>
{
// If an error or server side trigger occurred this screen may have already exited by external means.
if (this.IsCurrentScreen())
this.Exit();
}), onError: _ => Schedule(() =>
});
}, onError: _ =>
{
selectionOperation.Dispose();
Schedule(() =>
{
loadingLayer.Hide();
Carousel.AllowSelection = true;
}));
});
});
}
else
{
@ -93,6 +124,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
Playlist.Add(item);
this.Exit();
}
return true;
}
protected override BeatmapDetailArea CreateBeatmapDetailArea() => new PlayBeatmapDetailArea();

View File

@ -118,8 +118,6 @@ namespace osu.Game.Screens.OnlinePlay
protected sealed override bool OnStart()
{
itemSelected = true;
var item = new PlaylistItem(Beatmap.Value.BeatmapInfo)
{
RulesetID = Ruleset.Value.OnlineID,
@ -127,15 +125,21 @@ namespace osu.Game.Screens.OnlinePlay
AllowedMods = FreeMods.Value.Select(m => new APIMod(m)).ToArray()
};
SelectItem(item);
if (SelectItem(item))
{
itemSelected = true;
return true;
}
return false;
}
/// <summary>
/// Invoked when the user has requested a selection of a beatmap.
/// </summary>
/// <param name="item">The resultant <see cref="PlaylistItem"/>. This item has not yet been added to the <see cref="Room"/>'s.</param>
protected abstract void SelectItem(PlaylistItem item);
/// <returns><c>true</c> if a selection occurred.</returns>
protected abstract bool SelectItem(PlaylistItem item);
public override bool OnBackButton()
{

View File

@ -24,7 +24,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
CreateNewItem = createNewItem
};
protected override void SelectItem(PlaylistItem item)
protected override bool SelectItem(PlaylistItem item)
{
switch (Playlist.Count)
{
@ -39,6 +39,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
}
this.Exit();
return true;
}
private void createNewItem()