Move ready-up operation logic again to client

To salvage ready up button tests.
This commit is contained in:
Bartłomiej Dach 2020-12-29 09:09:47 +01:00
parent db52255bbe
commit e9b0652359
5 changed files with 61 additions and 27 deletions

View File

@ -34,6 +34,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Cached] [Cached]
private OngoingOperationTracker ongoingOperationTracker = new OngoingOperationTracker(); private OngoingOperationTracker ongoingOperationTracker = new OngoingOperationTracker();
private IDisposable toggleReadyOperation;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
{ {
@ -61,6 +63,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
Beatmap = { Value = beatmap }, Beatmap = { Value = beatmap },
Ruleset = { Value = beatmap.Ruleset } Ruleset = { Value = beatmap.Ruleset }
} }
},
OnToggleReady = async () =>
{
toggleReadyOperation = ongoingOperationTracker.BeginOperation();
bool gameplayStarted = await Client.ToggleReady();
if (!gameplayStarted)
toggleReadyOperation.Dispose();
} }
}; };
}); });
@ -168,15 +178,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
private void verifyGameplayStartFlow() private void verifyGameplayStartFlow()
{ {
IDisposable gameplayStartOperation = null;
AddStep("hook up tracker", () => button.OnReady = () => gameplayStartOperation = ongoingOperationTracker.BeginOperation());
addClickButtonStep(); addClickButtonStep();
AddAssert("user waiting for load", () => Client.Room?.Users[0].State == MultiplayerUserState.WaitingForLoad); AddAssert("user waiting for load", () => Client.Room?.Users[0].State == MultiplayerUserState.WaitingForLoad);
AddAssert("ready button disabled", () => !button.ChildrenOfType<OsuButton>().Single().Enabled.Value); AddAssert("ready button disabled", () => !button.ChildrenOfType<OsuButton>().Single().Enabled.Value);
AddStep("transitioned to gameplay", () => gameplayStartOperation.Dispose()); AddStep("transitioned to gameplay", () => toggleReadyOperation.Dispose());
AddAssert("ready button enabled", () => button.ChildrenOfType<OsuButton>().Single().Enabled.Value); AddAssert("ready button enabled", () => button.ChildrenOfType<OsuButton>().Single().Enabled.Value);
} }
} }

View File

@ -183,6 +183,39 @@ namespace osu.Game.Online.Multiplayer
}); });
} }
/// <summary>
/// Toggles the <see cref="LocalUser"/>'s ready state.
/// </summary>
/// <returns><c>true</c> if this toggle triggered a gameplay start; <c>false</c> otherwise.</returns>
/// <exception cref="InvalidOperationException">If a toggle of ready state is not valid at this time.</exception>
public async Task<bool> ToggleReady()
{
var localUser = LocalUser;
if (localUser == null)
return false;
switch (localUser.State)
{
case MultiplayerUserState.Idle:
await ChangeState(MultiplayerUserState.Ready);
return false;
case MultiplayerUserState.Ready:
if (Room?.Host?.Equals(localUser) == true)
{
await StartMatch();
return true;
}
await ChangeState(MultiplayerUserState.Idle);
return false;
default:
throw new InvalidOperationException($"Cannot toggle ready when in {localUser.State}");
}
}
public abstract Task TransferHost(int userId); public abstract Task TransferHost(int userId);
public abstract Task ChangeSettings(MultiplayerRoomSettings settings); public abstract Task ChangeSettings(MultiplayerRoomSettings settings);

View File

@ -20,9 +20,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
public readonly Bindable<PlaylistItem> SelectedItem = new Bindable<PlaylistItem>(); public readonly Bindable<PlaylistItem> SelectedItem = new Bindable<PlaylistItem>();
public Action OnReady public Action OnToggleReady
{ {
set => readyButton.OnReady = value; set => readyButton.OnToggleReady = value;
} }
private readonly Drawable background; private readonly Drawable background;

View File

@ -23,7 +23,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
{ {
public Bindable<PlaylistItem> SelectedItem => button.SelectedItem; public Bindable<PlaylistItem> SelectedItem => button.SelectedItem;
public Action OnReady public Action OnToggleReady
{ {
set => button.Action = value; set => button.Action = value;
} }

View File

@ -162,7 +162,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
new MultiplayerMatchFooter new MultiplayerMatchFooter
{ {
SelectedItem = { BindTarget = SelectedItem }, SelectedItem = { BindTarget = SelectedItem },
OnReady = onReady OnToggleReady = onToggleReady
} }
} }
}, },
@ -209,27 +209,22 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
private void onPlaylistChanged(object sender, NotifyCollectionChangedEventArgs e) => SelectedItem.Value = Playlist.FirstOrDefault(); private void onPlaylistChanged(object sender, NotifyCollectionChangedEventArgs e) => SelectedItem.Value = Playlist.FirstOrDefault();
private void onReady() private void onToggleReady()
{ {
var localUser = client.LocalUser; Debug.Assert(gameplayStartOperation == null);
gameplayStartOperation = ongoingOperationTracker.BeginOperation();
if (localUser == null) client.ToggleReady()
return; .ContinueWith(t =>
{
// if gameplay was started, the button will be unblocked on load requested.
if (t.Result) return;
if (localUser.State == MultiplayerUserState.Idle) // gameplay was not started; unblock button.
client.ChangeState(MultiplayerUserState.Ready).CatchUnobservedExceptions(true); gameplayStartOperation?.Dispose();
else gameplayStartOperation = null;
{ })
if (client.Room?.Host?.Equals(localUser) == true) .CatchUnobservedExceptions();
{
Debug.Assert(gameplayStartOperation == null);
gameplayStartOperation = ongoingOperationTracker.BeginOperation();
client.StartMatch().CatchUnobservedExceptions(true);
}
else
client.ChangeState(MultiplayerUserState.Idle).CatchUnobservedExceptions(true);
}
} }
private void onLoadRequested() private void onLoadRequested()