diff --git a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs index 37d262abe5..53d82c385d 100644 --- a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs +++ b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs @@ -69,8 +69,8 @@ namespace osu.Game.Beatmaps /// /// The to get the difficulty of. /// An optional which stops updating the star difficulty for the given . - /// A bindable that is updated to contain the star difficulty when it becomes available. - public IBindable GetBindableDifficulty([NotNull] BeatmapInfo beatmapInfo, CancellationToken cancellationToken = default) + /// A bindable that is updated to contain the star difficulty when it becomes available. Will be null while in an initial calculating state (but not during updates to ruleset and mods if a stale value is already propagated). + public IBindable GetBindableDifficulty([NotNull] BeatmapInfo beatmapInfo, CancellationToken cancellationToken = default) { var bindable = createBindable(beatmapInfo, currentRuleset.Value, currentMods.Value, cancellationToken); @@ -90,9 +90,9 @@ namespace osu.Game.Beatmaps /// The to get the difficulty with. If null, the 's ruleset is used. /// The s to get the difficulty with. If null, no mods will be assumed. /// An optional which stops updating the star difficulty for the given . - /// A bindable that is updated to contain the star difficulty when it becomes available. - public IBindable GetBindableDifficulty([NotNull] BeatmapInfo beatmapInfo, [CanBeNull] RulesetInfo rulesetInfo, [CanBeNull] IEnumerable mods, - CancellationToken cancellationToken = default) + /// A bindable that is updated to contain the star difficulty when it becomes available. Will be null while in an initial calculating state. + public IBindable GetBindableDifficulty([NotNull] BeatmapInfo beatmapInfo, [CanBeNull] RulesetInfo rulesetInfo, [CanBeNull] IEnumerable mods, + CancellationToken cancellationToken = default) => createBindable(beatmapInfo, rulesetInfo, mods, cancellationToken); /// @@ -313,7 +313,7 @@ namespace osu.Game.Beatmaps } } - private class BindableStarDifficulty : Bindable + private class BindableStarDifficulty : Bindable { public readonly BeatmapInfo Beatmap; public readonly CancellationToken CancellationToken; diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 96e18f120a..c62b803d1a 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -151,7 +151,7 @@ namespace osu.Game.Beatmaps.Drawables this.mods = mods; } - private IBindable localStarDifficulty; + private IBindable localStarDifficulty; [BackgroundDependencyLoader] private void load() @@ -160,7 +160,11 @@ namespace osu.Game.Beatmaps.Drawables localStarDifficulty = ruleset != null ? difficultyCache.GetBindableDifficulty(beatmap, ruleset, mods, difficultyCancellation.Token) : difficultyCache.GetBindableDifficulty(beatmap, difficultyCancellation.Token); - localStarDifficulty.BindValueChanged(difficulty => StarDifficulty.Value = difficulty.NewValue); + localStarDifficulty.BindValueChanged(d => + { + if (d.NewValue is StarDifficulty diff) + StarDifficulty.Value = diff; + }); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index a6beb19876..96ec9644b5 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -137,7 +137,7 @@ namespace osu.Game.Scoring ScoringMode.BindValueChanged(onScoringModeChanged, true); } - private IBindable difficultyBindable; + private IBindable difficultyBindable; private CancellationTokenSource difficultyCancellationSource; private void onScoringModeChanged(ValueChangedEvent mode) @@ -168,7 +168,11 @@ namespace osu.Game.Scoring // We can compute the max combo locally after the async beatmap difficulty computation. difficultyBindable = difficulties().GetBindableDifficulty(score.Beatmap, score.Ruleset, score.Mods, (difficultyCancellationSource = new CancellationTokenSource()).Token); - difficultyBindable.BindValueChanged(d => updateScore(d.NewValue.MaxCombo), true); + difficultyBindable.BindValueChanged(d => + { + if (d.NewValue is StarDifficulty diff) + updateScore(diff.MaxCombo); + }, true); return; } diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 36cc19cce3..4069dc82ed 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -47,7 +47,7 @@ namespace osu.Game.Screens.Select [Resolved] private BeatmapDifficultyCache difficultyCache { get; set; } - private IBindable beatmapDifficulty; + private IBindable beatmapDifficulty; protected BufferedWedgeInfo Info; @@ -135,7 +135,7 @@ namespace osu.Game.Screens.Select return; } - LoadComponentAsync(loadingInfo = new BufferedWedgeInfo(beatmap, ruleset.Value, mods.Value, beatmapDifficulty.Value) + LoadComponentAsync(loadingInfo = new BufferedWedgeInfo(beatmap, ruleset.Value, mods.Value, beatmapDifficulty.Value ?? new StarDifficulty()) { Shear = -Shear, Depth = Info?.Depth + 1 ?? 0 diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index e66469ff8d..633ef9297e 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -63,7 +63,7 @@ namespace osu.Game.Screens.Select.Carousel [Resolved(CanBeNull = true)] private ManageCollectionsDialog manageCollectionsDialog { get; set; } - private IBindable starDifficultyBindable; + private IBindable starDifficultyBindable; private CancellationTokenSource starDifficultyCancellationSource; public DrawableCarouselBeatmap(CarouselBeatmap panel) @@ -217,7 +217,10 @@ namespace osu.Game.Screens.Select.Carousel { // We've potentially cancelled the computation above so a new bindable is required. starDifficultyBindable = difficultyCache.GetBindableDifficulty(beatmap, (starDifficultyCancellationSource = new CancellationTokenSource()).Token); - starDifficultyBindable.BindValueChanged(d => starCounter.Current = (float)d.NewValue.Stars, true); + starDifficultyBindable.BindValueChanged(d => + { + starCounter.Current = (float)(d.NewValue?.Stars ?? 0); + }, true); } base.ApplyState();