Tidy up clock logic in all SongProgress classes

This commit is contained in:
Dean Herbert 2023-01-18 16:29:42 +09:00
parent 5ead85f461
commit 42e9b2b48c
6 changed files with 29 additions and 33 deletions

View File

@ -38,7 +38,8 @@ namespace osu.Game.Tests.Visual.Gameplay
}
});
Dependencies.CacheAs<IGameplayClock>(frameStabilityContainer);
Dependencies.CacheAs<IGameplayClock>(gameplayClockContainer);
Dependencies.CacheAs<IFrameStableClock>(frameStabilityContainer);
}
[SetUpSteps]

View File

@ -6,11 +6,9 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Timing;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.UI;
namespace osu.Game.Screens.Play.HUD
{
@ -26,13 +24,6 @@ namespace osu.Game.Screens.Play.HUD
[SettingSource("Show difficulty graph", "Whether a graph displaying difficulty throughout the beatmap should be shown")]
public Bindable<bool> ShowGraph { get; } = new BindableBool(true);
[Resolved]
private DrawableRuleset? drawableRuleset { get; set; }
// Even though `FrameStabilityContainer` caches as a `GameplayClock`, we need to check it directly via `drawableRuleset`
// as this calculator is not contained within the `FrameStabilityContainer` and won't see the dependency.
private IClock referenceClock => drawableRuleset?.FrameStableClock ?? GameplayClock;
[Resolved]
private Player? player { get; set; }
@ -116,12 +107,12 @@ namespace osu.Game.Screens.Play.HUD
protected override void UpdateProgress(double progress, bool isIntro)
{
bar.ReferenceTime = GameplayClock.CurrentTime;
bar.TrackTime = GameplayClock.CurrentTime;
if (isIntro)
bar.CurrentTime = 0;
else
bar.CurrentTime = referenceClock.CurrentTime;
bar.CurrentTime = FrameStableClock.CurrentTime;
}
}
}

View File

@ -64,21 +64,21 @@ namespace osu.Game.Screens.Play.HUD
set => CurrentNumber.Value = value;
}
public double ReferenceTime
public double TrackTime
{
private get => currentReference.Value;
set => currentReference.Value = value;
private get => currentTrackTime.Value;
set => currentTrackTime.Value = value;
}
private double length => EndTime - StartTime;
private readonly BindableNumber<double> currentReference;
private readonly BindableNumber<double> currentTrackTime;
public bool Interactive { get; set; }
public ArgonSongProgressBar(float barHeight)
{
currentReference = new BindableDouble();
currentTrackTime = new BindableDouble();
setupAlternateValue();
StartTime = 0;
@ -124,9 +124,9 @@ namespace osu.Game.Screens.Play.HUD
private void setupAlternateValue()
{
CurrentNumber.MaxValueChanged += v => currentReference.MaxValue = v;
CurrentNumber.MinValueChanged += v => currentReference.MinValue = v;
CurrentNumber.PrecisionChanged += v => currentReference.Precision = v;
CurrentNumber.MaxValueChanged += v => currentTrackTime.MaxValue = v;
CurrentNumber.MinValueChanged += v => currentTrackTime.MinValue = v;
CurrentNumber.PrecisionChanged += v => currentTrackTime.Precision = v;
}
private float normalizedReference
@ -136,7 +136,7 @@ namespace osu.Game.Screens.Play.HUD
if (EndTime - StartTime == 0)
return 1;
return (float)((ReferenceTime - StartTime) / length);
return (float)((TrackTime - StartTime) / length);
}
}
@ -183,12 +183,12 @@ namespace osu.Game.Screens.Play.HUD
playfieldBar.Length = (float)Interpolation.Lerp(playfieldBar.Length, NormalizedValue, Math.Clamp(Time.Elapsed / 40, 0, 1));
catchupBar.Length = (float)Interpolation.Lerp(catchupBar.Length, normalizedReference, Math.Clamp(Time.Elapsed / 40, 0, 1));
if (ReferenceTime < CurrentTime)
if (TrackTime < CurrentTime)
ChangeChildDepth(catchupBar, playfieldBar.Depth - 0.1f);
else
ChangeChildDepth(catchupBar, catchupBaseDepth);
float timeDelta = (float)(Math.Abs(CurrentTime - ReferenceTime));
float timeDelta = (float)(Math.Abs(CurrentTime - TrackTime));
catchupBar.Alpha = MathHelper.Clamp(timeDelta, 0, alpha_threshold) / alpha_threshold;
}

View File

@ -15,14 +15,12 @@ namespace osu.Game.Screens.Play.HUD.ClicksPerSecond
[Resolved]
private IGameplayClock gameplayClock { get; set; } = null!;
[Resolved(canBeNull: true)]
private DrawableRuleset? drawableRuleset { get; set; }
[Resolved]
private IFrameStableClock? frameStableClock { get; set; }
public int Value { get; private set; }
// Even though `FrameStabilityContainer` caches as a `GameplayClock`, we need to check it directly via `drawableRuleset`
// as this calculator is not contained within the `FrameStabilityContainer` and won't see the dependency.
private IGameplayClock clock => drawableRuleset?.FrameStableClock ?? gameplayClock;
private IGameplayClock clock => frameStableClock ?? gameplayClock;
public ClicksPerSecondCalculator()
{

View File

@ -36,7 +36,15 @@ namespace osu.Game.Screens.Play.HUD
[Resolved]
protected IGameplayClock GameplayClock { get; private set; } = null!;
private IClock? referenceClock;
[Resolved]
private IFrameStableClock? frameStableClock { get; set; }
/// <summary>
/// The reference clock is used to accurately tell the current playfield's time (including catch-up lag).
/// However, if none is available (i.e. used in tests), we fall back to the gameplay clock.
/// </summary>
protected IClock FrameStableClock => frameStableClock ?? GameplayClock;
private IEnumerable<HitObject>? objects;
public IEnumerable<HitObject> Objects
@ -74,7 +82,6 @@ namespace osu.Game.Screens.Play.HUD
((IBindable<bool>)Interactive).BindTo(drawableRuleset.HasReplayLoaded);
Objects = drawableRuleset.Objects;
referenceClock = drawableRuleset.FrameStableClock;
}
}
@ -89,9 +96,7 @@ namespace osu.Game.Screens.Play.HUD
if (objects == null)
return;
// The reference clock is used to accurately tell the playfield's time. This is obtained from the drawable ruleset.
// However, if no drawable ruleset is available (i.e. used in tests), we fall back to the gameplay clock.
double currentTime = referenceClock?.CurrentTime ?? GameplayClock.CurrentTime;
double currentTime = FrameStableClock.CurrentTime;
bool isInIntro = currentTime < FirstHitTime;

View File

@ -225,6 +225,7 @@ namespace osu.Game.Screens.Play
DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, gameplayMods);
dependencies.CacheAs(DrawableRuleset);
dependencies.CacheAs(DrawableRuleset.FrameStableClock);
ScoreProcessor = ruleset.CreateScoreProcessor();
ScoreProcessor.Mods.Value = gameplayMods;