mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 04:13:00 +08:00
Merge branch 'master' into update-framework
This commit is contained in:
commit
51840121b9
@ -104,7 +104,7 @@ namespace osu.Game.Beatmaps
|
||||
string cacheFilePath = storage.GetFullPath(cache_database_name);
|
||||
string compressedCacheFilePath = $"{cacheFilePath}.bz2";
|
||||
|
||||
cacheDownloadRequest = new FileWebRequest(compressedCacheFilePath, $"https://assets.ppy.sh/client-resources/{cache_database_name}.bz2");
|
||||
cacheDownloadRequest = new FileWebRequest(compressedCacheFilePath, $"https://assets.ppy.sh/client-resources/{cache_database_name}.bz2?{DateTimeOffset.UtcNow:yyyyMMdd}");
|
||||
|
||||
cacheDownloadRequest.Failed += ex =>
|
||||
{
|
||||
|
@ -95,6 +95,16 @@ namespace osu.Game.Screens.Play
|
||||
localGameplayClock = new LocalGameplayClock(userOffsetClock);
|
||||
|
||||
GameplayClock.IsPaused.BindTo(IsPaused);
|
||||
|
||||
IsPaused.BindValueChanged(onPauseChanged);
|
||||
}
|
||||
|
||||
private void onPauseChanged(ValueChangedEvent<bool> isPaused)
|
||||
{
|
||||
if (isPaused.NewValue)
|
||||
this.TransformBindableTo(pauseFreqAdjust, 0, 200, Easing.Out).OnComplete(_ => adjustableClock.Stop());
|
||||
else
|
||||
this.TransformBindableTo(pauseFreqAdjust, 1, 200, Easing.In);
|
||||
}
|
||||
|
||||
private double totalOffset => userOffsetClock.Offset + platformOffsetClock.Offset;
|
||||
@ -154,13 +164,16 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
public void Start()
|
||||
{
|
||||
// Seeking the decoupled clock to its current time ensures that its source clock will be seeked to the same time
|
||||
// This accounts for the audio clock source potentially taking time to enter a completely stopped state
|
||||
Seek(GameplayClock.CurrentTime);
|
||||
adjustableClock.Start();
|
||||
IsPaused.Value = false;
|
||||
if (!adjustableClock.IsRunning)
|
||||
{
|
||||
// Seeking the decoupled clock to its current time ensures that its source clock will be seeked to the same time
|
||||
// This accounts for the audio clock source potentially taking time to enter a completely stopped state
|
||||
Seek(GameplayClock.CurrentTime);
|
||||
|
||||
this.TransformBindableTo(pauseFreqAdjust, 1, 200, Easing.In);
|
||||
adjustableClock.Start();
|
||||
}
|
||||
|
||||
IsPaused.Value = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -199,8 +212,6 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
this.TransformBindableTo(pauseFreqAdjust, 0, 200, Easing.Out).OnComplete(_ => adjustableClock.Stop());
|
||||
|
||||
IsPaused.Value = true;
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
@ -71,8 +72,9 @@ namespace osu.Game.Screens.Play
|
||||
}
|
||||
|
||||
private bool readyForPush =>
|
||||
!playerConsumed
|
||||
// don't push unless the player is completely loaded
|
||||
player?.LoadState == LoadState.Ready
|
||||
&& player?.LoadState == LoadState.Ready
|
||||
// don't push if the user is hovering one of the panes, unless they are idle.
|
||||
&& (IsHovered || idleTracker.IsIdle.Value)
|
||||
// don't push if the user is dragging a slider or otherwise.
|
||||
@ -84,6 +86,11 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
private Player player;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the curent player instance has been consumed via <see cref="consumePlayer"/>.
|
||||
/// </summary>
|
||||
private bool playerConsumed;
|
||||
|
||||
private LogoTrackingContainer content;
|
||||
|
||||
private bool hideOverlays;
|
||||
@ -179,7 +186,10 @@ namespace osu.Game.Screens.Play
|
||||
contentIn();
|
||||
|
||||
MetadataInfo.Delay(750).FadeIn(500);
|
||||
this.Delay(1800).Schedule(pushWhenLoaded);
|
||||
|
||||
// after an initial delay, start the debounced load check.
|
||||
// this will continue to execute even after resuming back on restart.
|
||||
Scheduler.Add(new ScheduledDelegate(pushWhenLoaded, 1800, 0));
|
||||
|
||||
showMuteWarningIfNeeded();
|
||||
}
|
||||
@ -188,17 +198,18 @@ namespace osu.Game.Screens.Play
|
||||
{
|
||||
base.OnResuming(last);
|
||||
|
||||
contentIn();
|
||||
// prepare for a retry.
|
||||
player = null;
|
||||
playerConsumed = false;
|
||||
cancelLoad();
|
||||
|
||||
this.Delay(400).Schedule(pushWhenLoaded);
|
||||
contentIn();
|
||||
}
|
||||
|
||||
public override void OnSuspending(IScreen next)
|
||||
{
|
||||
base.OnSuspending(next);
|
||||
|
||||
cancelLoad();
|
||||
|
||||
BackgroundBrightnessReduction = false;
|
||||
|
||||
// we're moving to player, so a period of silence is upcoming.
|
||||
@ -274,6 +285,14 @@ namespace osu.Game.Screens.Play
|
||||
}
|
||||
}
|
||||
|
||||
private Player consumePlayer()
|
||||
{
|
||||
Debug.Assert(!playerConsumed);
|
||||
|
||||
playerConsumed = true;
|
||||
return player;
|
||||
}
|
||||
|
||||
private void prepareNewPlayer()
|
||||
{
|
||||
if (!this.IsCurrentScreen())
|
||||
@ -315,64 +334,62 @@ namespace osu.Game.Screens.Play
|
||||
{
|
||||
if (!this.IsCurrentScreen()) return;
|
||||
|
||||
try
|
||||
if (!readyForPush)
|
||||
{
|
||||
if (!readyForPush)
|
||||
// as the pushDebounce below has a delay, we need to keep checking and cancel a future debounce
|
||||
// if we become unready for push during the delay.
|
||||
cancelLoad();
|
||||
return;
|
||||
}
|
||||
|
||||
// if a push has already been scheduled, no further action is required.
|
||||
// this value is reset via cancelLoad() to allow a second usage of the same PlayerLoader screen.
|
||||
if (scheduledPushPlayer != null)
|
||||
return;
|
||||
|
||||
scheduledPushPlayer = Scheduler.AddDelayed(() =>
|
||||
{
|
||||
// ensure that once we have reached this "point of no return", readyForPush will be false for all future checks (until a new player instance is prepared).
|
||||
var consumedPlayer = consumePlayer();
|
||||
|
||||
contentOut();
|
||||
|
||||
TransformSequence<PlayerLoader> pushSequence = this.Delay(250);
|
||||
|
||||
// only show if the warning was created (i.e. the beatmap needs it)
|
||||
// and this is not a restart of the map (the warning expires after first load).
|
||||
if (epilepsyWarning?.IsAlive == true)
|
||||
{
|
||||
// as the pushDebounce below has a delay, we need to keep checking and cancel a future debounce
|
||||
// if we become unready for push during the delay.
|
||||
cancelLoad();
|
||||
return;
|
||||
const double epilepsy_display_length = 3000;
|
||||
|
||||
pushSequence
|
||||
.Schedule(() => epilepsyWarning.State.Value = Visibility.Visible)
|
||||
.TransformBindableTo(volumeAdjustment, 0.25, EpilepsyWarning.FADE_DURATION, Easing.OutQuint)
|
||||
.Delay(epilepsy_display_length)
|
||||
.Schedule(() =>
|
||||
{
|
||||
epilepsyWarning.Hide();
|
||||
epilepsyWarning.Expire();
|
||||
})
|
||||
.Delay(EpilepsyWarning.FADE_DURATION);
|
||||
}
|
||||
|
||||
if (scheduledPushPlayer != null)
|
||||
return;
|
||||
|
||||
scheduledPushPlayer = Scheduler.AddDelayed(() =>
|
||||
pushSequence.Schedule(() =>
|
||||
{
|
||||
contentOut();
|
||||
if (!this.IsCurrentScreen()) return;
|
||||
|
||||
TransformSequence<PlayerLoader> pushSequence = this.Delay(250);
|
||||
LoadTask = null;
|
||||
|
||||
// only show if the warning was created (i.e. the beatmap needs it)
|
||||
// and this is not a restart of the map (the warning expires after first load).
|
||||
if (epilepsyWarning?.IsAlive == true)
|
||||
{
|
||||
const double epilepsy_display_length = 3000;
|
||||
// By default, we want to load the player and never be returned to.
|
||||
// Note that this may change if the player we load requested a re-run.
|
||||
ValidForResume = false;
|
||||
|
||||
pushSequence
|
||||
.Schedule(() => epilepsyWarning.State.Value = Visibility.Visible)
|
||||
.TransformBindableTo(volumeAdjustment, 0.25, EpilepsyWarning.FADE_DURATION, Easing.OutQuint)
|
||||
.Delay(epilepsy_display_length)
|
||||
.Schedule(() =>
|
||||
{
|
||||
epilepsyWarning.Hide();
|
||||
epilepsyWarning.Expire();
|
||||
})
|
||||
.Delay(EpilepsyWarning.FADE_DURATION);
|
||||
}
|
||||
|
||||
pushSequence.Schedule(() =>
|
||||
{
|
||||
if (!this.IsCurrentScreen()) return;
|
||||
|
||||
LoadTask = null;
|
||||
|
||||
// By default, we want to load the player and never be returned to.
|
||||
// Note that this may change if the player we load requested a re-run.
|
||||
ValidForResume = false;
|
||||
|
||||
if (player.LoadedBeatmapSuccessfully)
|
||||
this.Push(player);
|
||||
else
|
||||
this.Exit();
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Schedule(pushWhenLoaded);
|
||||
}
|
||||
if (consumedPlayer.LoadedBeatmapSuccessfully)
|
||||
this.Push(consumedPlayer);
|
||||
else
|
||||
this.Exit();
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
|
||||
private void cancelLoad()
|
||||
@ -390,7 +407,7 @@ namespace osu.Game.Screens.Play
|
||||
if (isDisposing)
|
||||
{
|
||||
// if the player never got pushed, we should explicitly dispose it.
|
||||
DisposalTask = LoadTask?.ContinueWith(_ => player.Dispose());
|
||||
DisposalTask = LoadTask?.ContinueWith(_ => player?.Dispose());
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user