mirror of
https://github.com/ppy/osu.git
synced 2025-01-28 00:02:56 +08:00
Split countdown start into separate method
This commit is contained in:
parent
40eca0fbe2
commit
ea9de0199d
@ -315,57 +315,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
switch (request)
|
switch (request)
|
||||||
{
|
{
|
||||||
case StartMatchCountdownRequest matchCountdownRequest:
|
case StartMatchCountdownRequest matchCountdownRequest:
|
||||||
Debug.Assert(ThreadSafety.IsUpdateThread);
|
startCountdown(new MatchStartCountdown { TimeRemaining = matchCountdownRequest.Duration }, StartMatch);
|
||||||
|
|
||||||
countdownStopSource?.Cancel();
|
|
||||||
|
|
||||||
// Note that this will leak CTSs, however this is a test method and we haven't noticed foregoing disposal of non-linked CTSs to be detrimental.
|
|
||||||
// If necessary, this can be moved into the final schedule below, and the class-level fields be nulled out accordingly.
|
|
||||||
var stopSource = countdownStopSource = new CancellationTokenSource();
|
|
||||||
var skipSource = countdownSkipSource = new CancellationTokenSource();
|
|
||||||
var countdown = new MatchStartCountdown { TimeRemaining = matchCountdownRequest.Duration };
|
|
||||||
|
|
||||||
Task lastCountdownTask = countdownTask;
|
|
||||||
countdownTask = start();
|
|
||||||
|
|
||||||
async Task start()
|
|
||||||
{
|
|
||||||
await lastCountdownTask;
|
|
||||||
|
|
||||||
Schedule(() =>
|
|
||||||
{
|
|
||||||
if (stopSource.IsCancellationRequested)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Room.Countdown = countdown;
|
|
||||||
MatchEvent(new CountdownChangedEvent { Countdown = countdown });
|
|
||||||
});
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (var cancellationSource = CancellationTokenSource.CreateLinkedTokenSource(stopSource.Token, skipSource.Token))
|
|
||||||
await Task.Delay(matchCountdownRequest.Duration, cancellationSource.Token).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (OperationCanceledException)
|
|
||||||
{
|
|
||||||
// Clients need to be notified of cancellations in the following code.
|
|
||||||
}
|
|
||||||
|
|
||||||
Schedule(() =>
|
|
||||||
{
|
|
||||||
if (Room.Countdown != countdown)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Room.Countdown = null;
|
|
||||||
MatchEvent(new CountdownChangedEvent { Countdown = null });
|
|
||||||
|
|
||||||
if (stopSource.IsCancellationRequested)
|
|
||||||
return;
|
|
||||||
|
|
||||||
StartMatch().WaitSafely();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StopCountdownRequest _:
|
case StopCountdownRequest _:
|
||||||
@ -393,6 +343,60 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startCountdown(MultiplayerCountdown countdown, Func<Task> continuation)
|
||||||
|
{
|
||||||
|
Debug.Assert(Room != null);
|
||||||
|
Debug.Assert(ThreadSafety.IsUpdateThread);
|
||||||
|
|
||||||
|
countdownStopSource?.Cancel();
|
||||||
|
|
||||||
|
// Note that this will leak CTSs, however this is a test method and we haven't noticed foregoing disposal of non-linked CTSs to be detrimental.
|
||||||
|
// If necessary, this can be moved into the final schedule below, and the class-level fields be nulled out accordingly.
|
||||||
|
var stopSource = countdownStopSource = new CancellationTokenSource();
|
||||||
|
var skipSource = countdownSkipSource = new CancellationTokenSource();
|
||||||
|
|
||||||
|
Task lastCountdownTask = countdownTask;
|
||||||
|
countdownTask = start();
|
||||||
|
|
||||||
|
async Task start()
|
||||||
|
{
|
||||||
|
await lastCountdownTask;
|
||||||
|
|
||||||
|
Schedule(() =>
|
||||||
|
{
|
||||||
|
if (stopSource.IsCancellationRequested)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Room.Countdown = countdown;
|
||||||
|
MatchEvent(new CountdownChangedEvent { Countdown = countdown });
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var cancellationSource = CancellationTokenSource.CreateLinkedTokenSource(stopSource.Token, skipSource.Token))
|
||||||
|
await Task.Delay(countdown.TimeRemaining, cancellationSource.Token).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
// Clients need to be notified of cancellations in the following code.
|
||||||
|
}
|
||||||
|
|
||||||
|
Schedule(() =>
|
||||||
|
{
|
||||||
|
if (Room.Countdown != countdown)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Room.Countdown = null;
|
||||||
|
MatchEvent(new CountdownChangedEvent { Countdown = null });
|
||||||
|
|
||||||
|
if (stopSource.IsCancellationRequested)
|
||||||
|
return;
|
||||||
|
|
||||||
|
continuation().WaitSafely();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override Task StartMatch()
|
public override Task StartMatch()
|
||||||
{
|
{
|
||||||
Debug.Assert(Room != null);
|
Debug.Assert(Room != null);
|
||||||
|
Loading…
Reference in New Issue
Block a user