1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-14 20:13:22 +08:00

Fix multiple issues with timekeeping

- Using realtime (`DateTimeOffset.Now`) meant that values would be
  changing in the same frame, causing misfirings or incorrect displays
- No debounce on sample playback meant that scheduling edge cases could
  potentially cause samples to be played more than once.
This commit is contained in:
Dean Herbert 2022-04-05 11:49:57 +09:00
parent 3708f2b744
commit 174dc1641c

View File

@ -48,7 +48,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
}
private MultiplayerCountdown countdown;
private DateTimeOffset countdownChangeTime;
private double countdownChangeTime;
private ScheduledDelegate countdownUpdateDelegate;
private void onRoomUpdated() => Scheduler.AddOnce(() =>
@ -56,7 +56,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
if (countdown != room?.Countdown)
{
countdown = room?.Countdown;
countdownChangeTime = DateTimeOffset.Now;
countdownChangeTime = Time.Current;
}
scheduleNextCountdownUpdate();
@ -86,13 +86,27 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
int secondsRemaining = countdownTimeRemaining.Seconds;
if (secondsRemaining < 10) countdownTickSample?.Play();
if (secondsRemaining <= 3) countdownTickFinalSample?.Play();
playTickSound(secondsRemaining);
scheduleNextCountdownUpdate();
if (secondsRemaining > 0)
scheduleNextCountdownUpdate();
}
}
private double? lastTickSampleTime;
private void playTickSound(int secondsRemaining)
{
// Simplified debounce. Ticks should only be played roughly once per second regardless of how often this function is called.
if (Time.Current - lastTickSampleTime < 500)
return;
lastTickSampleTime = Time.Current;
if (secondsRemaining < 10) countdownTickSample?.Play();
if (secondsRemaining <= 3) countdownTickFinalSample?.Play();
}
private void updateButtonText()
{
if (room == null)
@ -146,13 +160,13 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
{
get
{
TimeSpan timeElapsed = DateTimeOffset.Now - countdownChangeTime;
double timeElapsed = Time.Current - countdownChangeTime;
TimeSpan remaining;
if (timeElapsed > countdown.TimeRemaining)
if (timeElapsed > countdown.TimeRemaining.TotalMilliseconds)
remaining = TimeSpan.Zero;
else
remaining = countdown.TimeRemaining - timeElapsed;
remaining = countdown.TimeRemaining - TimeSpan.FromMilliseconds(timeElapsed);
return remaining;
}