1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-13 20:33:35 +08:00

Attempt to improve safety of pushing matchmaking screens (#37452)

Due to the push of the relevant screens being delayed it's possible that
the room goes away between the scheduling of the push and the actual
execution of the push.

This maybe closes https://github.com/ppy/osu/issues/37374 but my hopes
are not high.

Includes some extra cleanups I noticed along the way.
This commit is contained in:
Bartłomiej Dach
2026-04-21 12:11:35 +02:00
committed by GitHub
Unverified
parent 9a2846539f
commit 1eee6dc870
3 changed files with 23 additions and 5 deletions
@@ -71,6 +71,22 @@ namespace osu.Game.Tests.Visual.Matchmaking
AddStep("change state to in room", () => queueScreen!.SetState(ScreenQueue.MatchmakingScreenState.InRoom));
}
[Test]
public void TestDelayedRoomScreenPushDoesNotRunIfRoomIsLeftPrematurely()
{
AddStep("change state to in room then immediately leave room", () =>
{
queueScreen!.SetState(ScreenQueue.MatchmakingScreenState.InRoom);
MultiplayerClient.LeaveRoom();
});
// the queue screen waits 2 seconds between transitioning to `InRoom` state and actually pushing the relevant screen.
// if the room goes to `null` in that time, things die very hard.
// therefore the wait here is to check that things don't die very hard.
// if they do the test will throw an exception and fail.
AddWaitStep("wait a little bit", 10);
}
private static double generateCount(double x, double mean, double stdDev, double amplitude)
{
return amplitude * Math.Exp(-Math.Pow(x - mean, 2) / (2 * Math.Pow(stdDev, 2))) + Random.Shared.Next(300);
@@ -27,8 +27,6 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
///
/// Includes support for deferring to background.
/// </summary>
/// <remarks>
/// This is initialised and cached in the <see cref="ScreenQueue"/> but can be used throughout the system via DI.</remarks>
public partial class QueueController : Component
{
public readonly Bindable<ScreenQueue.MatchmakingScreenState> CurrentState = new Bindable<ScreenQueue.MatchmakingScreenState>();
@@ -90,6 +90,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
private SampleChannel? waitingLoopChannel;
private ScheduledDelegate? startLoopPlaybackDelegate;
private DrawableSample waitingLoop = null!;
private ScheduledDelegate? pushScreenDelegate;
private int? userRating;
@@ -390,14 +391,14 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
if (e.NewValue == null)
{
client.MatchmakingLeaveLobby();
client.MatchmakingLeaveLobby().FireAndForget();
return;
}
client.MatchmakingJoinLobbyWithParams(new MatchmakingJoinLobbyRequest
{
PoolId = e.NewValue.Id
});
}).FireAndForget();
}
public override void OnEntering(ScreenTransitionEvent e)
@@ -465,6 +466,9 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
startLoopPlaybackDelegate?.Cancel();
stopWaitingLoopPlayback();
pushScreenDelegate?.Cancel();
pushScreenDelegate = null;
switch (newState)
{
case MatchmakingScreenState.Idle:
@@ -599,7 +603,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
using (BeginDelayedSequence(2000))
{
Schedule(() =>
pushScreenDelegate = Schedule(() =>
{
switch (poolType)
{