Add back DI leaderboard retrieval via bindable pathway

This commit is contained in:
Dean Herbert 2022-09-13 17:49:53 +09:00
parent 70e6b595f1
commit 6d167070f8
6 changed files with 86 additions and 29 deletions

View File

@ -5,9 +5,12 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Leaderboards;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
@ -15,31 +18,36 @@
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestSceneSoloGameplayLeaderboard : OsuTestScene
public class TestSceneSoloGameplayLeaderboard : OsuTestScene, ILeaderboardScoreSource
{
[Cached]
private readonly ScoreProcessor scoreProcessor = new ScoreProcessor(new OsuRuleset());
private SoloGameplayLeaderboard leaderboard = null!;
private readonly BindableList<ScoreInfo> scores = new BindableList<ScoreInfo>();
[SetUp]
public void SetUp() => Schedule(() =>
[SetUpSteps]
public void SetUpSteps()
{
var trackingUser = new APIUser
{
Username = "local user",
Id = 2,
};
AddStep("clear scores", () => scores.Clear());
Child = leaderboard = new SoloGameplayLeaderboard(trackingUser)
AddStep("create component", () =>
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Expanded = { Value = true },
};
var trackingUser = new APIUser
{
Username = "local user",
Id = 2,
};
leaderboard.ShowScores(createSampleScores());
});
Child = new SoloGameplayLeaderboard(trackingUser)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Expanded = { Value = true },
};
});
AddStep("add scores", () => scores.AddRange(createSampleScores()));
}
[Test]
public void TestLocalUser()
@ -49,6 +57,8 @@ public void TestLocalUser()
AddSliderStep("combo", 0, 1000, 0, v => scoreProcessor.Combo.Value = v);
}
IBindableList<ScoreInfo> ILeaderboardScoreSource.Scores => scores;
private static List<ScoreInfo> createSampleScores()
{
return new[]

View File

@ -0,0 +1,15 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Scoring;
namespace osu.Game.Online.Leaderboards
{
[Cached]
public interface ILeaderboardScoreSource
{
IBindableList<ScoreInfo> Scores { get; }
}
}

View File

@ -39,7 +39,9 @@ public abstract class Leaderboard<TScope, TScoreInfo> : CompositeDrawable
/// <summary>
/// The currently displayed scores.
/// </summary>
public IEnumerable<TScoreInfo> Scores => scores;
public IBindableList<TScoreInfo> Scores => scores;
private readonly BindableList<TScoreInfo> scores = new BindableList<TScoreInfo>();
/// <summary>
/// Whether the current scope should refetch in response to changes in API connectivity state.
@ -68,8 +70,6 @@ public abstract class Leaderboard<TScope, TScoreInfo> : CompositeDrawable
private readonly IBindable<APIState> apiState = new Bindable<APIState>();
private ICollection<TScoreInfo> scores;
private TScope scope;
public TScope Scope
@ -169,7 +169,7 @@ protected void SetErrorState(LeaderboardState state)
throw new InvalidOperationException($"State {state} cannot be set by a leaderboard implementation.");
}
Debug.Assert(scores?.Any() != true);
Debug.Assert(scores.Any() != true);
setState(state);
}
@ -181,7 +181,10 @@ protected void SetErrorState(LeaderboardState state)
/// <param name="userScore">The user top score, if any.</param>
protected void SetScores(IEnumerable<TScoreInfo> scores, TScoreInfo userScore = default)
{
this.scores = scores?.ToList();
this.scores.Clear();
if (scores != null)
this.scores.AddRange(scores);
userScoreContainer.Score.Value = userScore;
if (userScore == null)
@ -247,7 +250,7 @@ private void updateScoresDrawables()
.Expire();
scoreFlowContainer = null;
if (scores?.Any() != true)
if (scores.Any() != true)
{
setState(LeaderboardState.NoScores);
return;

View File

@ -4,6 +4,8 @@
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Online.Leaderboards;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Users;
@ -14,6 +16,8 @@ public class SoloGameplayLeaderboard : GameplayLeaderboard
{
private readonly IUser trackingUser;
private readonly IBindableList<ScoreInfo> scores = new BindableList<ScoreInfo>();
[Resolved]
private ScoreProcessor scoreProcessor { get; set; } = null!;
@ -22,7 +26,16 @@ public SoloGameplayLeaderboard(IUser trackingUser)
this.trackingUser = trackingUser;
}
public void ShowScores(IEnumerable<IScoreInfo> scores)
[BackgroundDependencyLoader(true)]
private void load(ILeaderboardScoreSource? scoreSource)
{
if (scoreSource != null)
scores.BindTo(scoreSource.Scores);
scores.BindCollectionChanged((_, __) => Scheduler.AddOnce(showScores, scores), true);
}
private void showScores(IEnumerable<IScoreInfo> scores)
{
Clear();

View File

@ -23,7 +23,7 @@
namespace osu.Game.Screens.Select.Leaderboards
{
public class BeatmapLeaderboard : Leaderboard<BeatmapLeaderboardScope, ScoreInfo>
public class BeatmapLeaderboard : Leaderboard<BeatmapLeaderboardScope, ScoreInfo>, ILeaderboardScoreSource
{
public Action<ScoreInfo> ScoreSelected;
@ -152,7 +152,8 @@ protected override APIRequest FetchScores(CancellationToken cancellationToken)
{
SetScores(
scoreManager.OrderByTotalScore(r.Scores.Select(s => s.ToScoreInfo(rulesets, fetchBeatmapInfo))),
r.UserScore?.CreateScoreInfo(rulesets, fetchBeatmapInfo));
r.UserScore?.CreateScoreInfo(rulesets, fetchBeatmapInfo)
);
});
return req;

View File

@ -6,10 +6,12 @@
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Framework.Screens;
using osu.Game.Graphics;
using osu.Game.Online.Leaderboards;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets.Mods;
@ -22,7 +24,7 @@
namespace osu.Game.Screens.Select
{
public class PlaySongSelect : SongSelect
public class PlaySongSelect : SongSelect, ILeaderboardScoreSource
{
private OsuScreen playerLoader;
@ -37,14 +39,25 @@ public class PlaySongSelect : SongSelect
private void load(OsuColour colours)
{
BeatmapOptions.AddButton(@"Edit", @"beatmap", FontAwesome.Solid.PencilAlt, colours.Yellow, () => Edit());
((PlayBeatmapDetailArea)BeatmapDetails).Leaderboard.ScoreSelected += PresentScore;
}
protected void PresentScore(ScoreInfo score) =>
FinaliseSelection(score.BeatmapInfo, score.Ruleset, () => this.Push(new SoloResultsScreen(score, false)));
protected override BeatmapDetailArea CreateBeatmapDetailArea() => new PlayBeatmapDetailArea();
protected override BeatmapDetailArea CreateBeatmapDetailArea()
{
var playBeatmapDetailArea = new PlayBeatmapDetailArea
{
Leaderboard =
{
ScoreSelected = PresentScore
}
};
Scores.BindTo(playBeatmapDetailArea.Leaderboard.Scores);
return playBeatmapDetailArea;
}
protected override bool OnKeyDown(KeyDownEvent e)
{
@ -121,5 +134,7 @@ public override void OnResuming(ScreenTransitionEvent e)
playerLoader = null;
}
}
IBindableList<ScoreInfo> ILeaderboardScoreSource.Scores { get; } = new BindableList<ScoreInfo>();
}
}