diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs
index 7139b804b0..3e3bb4dbc5 100644
--- a/osu.Game/Screens/Select/BeatmapCarousel.cs
+++ b/osu.Game/Screens/Select/BeatmapCarousel.cs
@@ -49,6 +49,11 @@ namespace osu.Game.Screens.Select
///
public BeatmapSetInfo SelectedBeatmapSet => selectedBeatmapSet?.BeatmapSet;
+ ///
+ /// A function to optionally decide on a recommended difficulty from a beatmap set.
+ ///
+ public Func, BeatmapInfo> GetRecommendedBeatmap;
+
private CarouselBeatmapSet selectedBeatmapSet;
///
@@ -120,8 +125,6 @@ namespace osu.Game.Screens.Select
private CarouselRoot root;
- public DifficultyRecommender DifficultyRecommender;
-
public BeatmapCarousel()
{
root = new CarouselRoot(this);
@@ -586,12 +589,10 @@ namespace osu.Game.Screens.Select
b.Metadata = beatmapSet.Metadata;
}
- BeatmapInfo recommender(IEnumerable beatmaps)
+ var set = new CarouselBeatmapSet(beatmapSet)
{
- return DifficultyRecommender?.GetRecommendedBeatmap(beatmaps);
- }
-
- var set = new CarouselBeatmapSet(beatmapSet, recommender);
+ GetRecommendedBeatmap = beatmaps => GetRecommendedBeatmap?.Invoke(beatmaps)
+ };
foreach (var c in set.Beatmaps)
{
diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
index 99ded4c58e..92ccfde14b 100644
--- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
+++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
@@ -12,13 +12,13 @@ namespace osu.Game.Screens.Select.Carousel
{
public class CarouselBeatmapSet : CarouselGroupEagerSelect
{
- private readonly Func, BeatmapInfo> getRecommendedBeatmap;
-
public IEnumerable Beatmaps => InternalChildren.OfType();
public BeatmapSetInfo BeatmapSet;
- public CarouselBeatmapSet(BeatmapSetInfo beatmapSet, Func, BeatmapInfo> getRecommendedBeatmap)
+ public Func, BeatmapInfo> GetRecommendedBeatmap;
+
+ public CarouselBeatmapSet(BeatmapSetInfo beatmapSet)
{
BeatmapSet = beatmapSet ?? throw new ArgumentNullException(nameof(beatmapSet));
@@ -26,8 +26,6 @@ namespace osu.Game.Screens.Select.Carousel
.Where(b => !b.Hidden)
.Select(b => new CarouselBeatmap(b))
.ForEach(AddChild);
-
- this.getRecommendedBeatmap = getRecommendedBeatmap;
}
protected override DrawableCarouselItem CreateDrawableRepresentation() => new DrawableCarouselBeatmapSet(this);
@@ -36,9 +34,8 @@ namespace osu.Game.Screens.Select.Carousel
{
if (LastSelected == null)
{
- var recommendedBeatmapInfo = getRecommendedBeatmap(Children.OfType().Where(b => !b.Filtered.Value).Select(b => b.Beatmap));
- if (recommendedBeatmapInfo != null)
- return Children.OfType().First(b => b.Beatmap == recommendedBeatmapInfo);
+ if (GetRecommendedBeatmap?.Invoke(Children.OfType().Where(b => !b.Filtered.Value).Select(b => b.Beatmap)) is BeatmapInfo recommended)
+ return Children.OfType().First(b => b.Beatmap == recommended);
}
return base.GetNextToSelect();
diff --git a/osu.Game/Screens/Select/DifficultyRecommender.cs b/osu.Game/Screens/Select/DifficultyRecommender.cs
index fb67d63818..47838ebd6d 100644
--- a/osu.Game/Screens/Select/DifficultyRecommender.cs
+++ b/osu.Game/Screens/Select/DifficultyRecommender.cs
@@ -33,10 +33,33 @@ namespace osu.Game.Screens.Select
[BackgroundDependencyLoader]
private void load()
{
- updateRecommended();
+ calculateRecommendedDifficulties();
}
- private void updateRecommended()
+ ///
+ /// Find the recommended difficulty from a selection of available difficulties for the current local user.
+ ///
+ ///
+ /// This requires the user to be online for now.
+ ///
+ /// A collection of beatmaps to select a difficulty from.
+ /// The recommended difficulty, or null if a recommendation could not be provided.
+ public BeatmapInfo GetRecommendedBeatmap(IEnumerable beatmaps)
+ {
+ if (!recommendedStarDifficulty.ContainsKey(ruleset.Value))
+ {
+ calculateRecommendedDifficulties();
+ return null;
+ }
+
+ return beatmaps.OrderBy(b =>
+ {
+ var difference = b.StarDifficulty - recommendedStarDifficulty[ruleset.Value];
+ return difference >= 0 ? difference * 2 : difference * -1; // prefer easier over harder
+ }).FirstOrDefault();
+ }
+
+ private void calculateRecommendedDifficulties()
{
if (pendingAPIRequests > 0)
return;
@@ -60,20 +83,5 @@ namespace osu.Game.Screens.Select
api.Queue(req);
});
}
-
- public BeatmapInfo GetRecommendedBeatmap(IEnumerable beatmaps)
- {
- if (!recommendedStarDifficulty.ContainsKey(ruleset.Value))
- {
- updateRecommended();
- return null;
- }
-
- return beatmaps.OrderBy(b =>
- {
- var difference = b.StarDifficulty - recommendedStarDifficulty[ruleset.Value];
- return difference >= 0 ? difference * 2 : difference * -1; // prefer easier over harder
- }).FirstOrDefault();
- }
}
}
diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs
index 9897515615..f164056ede 100644
--- a/osu.Game/Screens/Select/SongSelect.cs
+++ b/osu.Game/Screens/Select/SongSelect.cs
@@ -80,7 +80,8 @@ namespace osu.Game.Screens.Select
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value);
protected BeatmapCarousel Carousel { get; private set; }
- private DifficultyRecommender difficultyRecommender;
+
+ private DifficultyRecommender recommender;
private BeatmapInfoWedge beatmapInfoWedge;
private DialogOverlay dialogOverlay;
@@ -108,10 +109,9 @@ namespace osu.Game.Screens.Select
// initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter).
transferRulesetValue();
- AddInternal(difficultyRecommender = new DifficultyRecommender());
-
AddRangeInternal(new Drawable[]
{
+ recommender = new DifficultyRecommender(),
new ResetScrollContainer(() => Carousel.ScrollToSelected())
{
RelativeSizeAxes = Axes.Y,
@@ -159,7 +159,7 @@ namespace osu.Game.Screens.Select
RelativeSizeAxes = Axes.Both,
SelectionChanged = updateSelectedBeatmap,
BeatmapSetsChanged = carouselBeatmapsLoaded,
- DifficultyRecommender = difficultyRecommender,
+ GetRecommendedBeatmap = recommender.GetRecommendedBeatmap,
},
}
},