1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-14 00:13:10 +08:00

Merge pull request #20389 from peppy/fix-gameplay-leaderboard-layout

Fix gameplay leaderboard sometimes not showing up
This commit is contained in:
Dan Balasescu 2022-09-22 20:51:54 +09:00 committed by GitHub
commit 445e026a32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 14 deletions

View File

@ -6,7 +6,9 @@
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions.PolygonExtensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
@ -18,37 +20,52 @@ namespace osu.Game.Tests.Visual.Gameplay
[TestFixture] [TestFixture]
public class TestSceneGameplayLeaderboard : OsuTestScene public class TestSceneGameplayLeaderboard : OsuTestScene
{ {
private readonly TestGameplayLeaderboard leaderboard; private TestGameplayLeaderboard leaderboard;
private readonly BindableDouble playerScore = new BindableDouble(); private readonly BindableDouble playerScore = new BindableDouble();
public TestSceneGameplayLeaderboard() public TestSceneGameplayLeaderboard()
{ {
Add(leaderboard = new TestGameplayLeaderboard AddStep("toggle expanded", () =>
{ {
Anchor = Anchor.Centre, if (leaderboard != null)
Origin = Anchor.Centre, leaderboard.Expanded.Value = !leaderboard.Expanded.Value;
Scale = new Vector2(2),
}); });
AddSliderStep("set player score", 50, 5000000, 1222333, v => playerScore.Value = v);
} }
[SetUpSteps] [Test]
public void SetUpSteps() public void TestLayoutWithManyScores()
{ {
AddStep("reset leaderboard", () => createLeaderboard();
AddStep("add many scores in one go", () =>
{ {
leaderboard.Clear(); for (int i = 0; i < 32; i++)
playerScore.Value = 1222333; createRandomScore(new APIUser { Username = $"Player {i + 1}" });
// Add player at end to force an animation down the whole list.
playerScore.Value = 0;
createLeaderboardScore(playerScore, new APIUser { Username = "You", Id = 3 }, true);
}); });
AddStep("add local player", () => createLeaderboardScore(playerScore, new APIUser { Username = "You", Id = 3 }, true)); // Gameplay leaderboard has custom scroll logic, which when coupled with LayoutDuration
AddStep("toggle expanded", () => leaderboard.Expanded.Value = !leaderboard.Expanded.Value); // has caused layout to not work in the past.
AddSliderStep("set player score", 50, 5000000, 1222333, v => playerScore.Value = v);
AddUntilStep("wait for fill flow layout",
() => leaderboard.ChildrenOfType<FillFlowContainer<GameplayLeaderboardScore>>().First().ScreenSpaceDrawQuad.Intersects(leaderboard.ScreenSpaceDrawQuad));
AddUntilStep("wait for some scores not masked away",
() => leaderboard.ChildrenOfType<GameplayLeaderboardScore>().Any(s => leaderboard.ScreenSpaceDrawQuad.Contains(s.ScreenSpaceDrawQuad.Centre)));
} }
[Test] [Test]
public void TestPlayerScore() public void TestPlayerScore()
{ {
createLeaderboard();
addLocalPlayer();
var player2Score = new BindableDouble(1234567); var player2Score = new BindableDouble(1234567);
var player3Score = new BindableDouble(1111111); var player3Score = new BindableDouble(1111111);
@ -73,6 +90,9 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test] [Test]
public void TestRandomScores() public void TestRandomScores()
{ {
createLeaderboard();
addLocalPlayer();
int playerNumber = 1; int playerNumber = 1;
AddRepeatStep("add player with random score", () => createRandomScore(new APIUser { Username = $"Player {playerNumber++}" }), 10); AddRepeatStep("add player with random score", () => createRandomScore(new APIUser { Username = $"Player {playerNumber++}" }), 10);
} }
@ -80,6 +100,9 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test] [Test]
public void TestExistingUsers() public void TestExistingUsers()
{ {
createLeaderboard();
addLocalPlayer();
AddStep("add peppy", () => createRandomScore(new APIUser { Username = "peppy", Id = 2 })); AddStep("add peppy", () => createRandomScore(new APIUser { Username = "peppy", Id = 2 }));
AddStep("add smoogipoo", () => createRandomScore(new APIUser { Username = "smoogipoo", Id = 1040328 })); AddStep("add smoogipoo", () => createRandomScore(new APIUser { Username = "smoogipoo", Id = 1040328 }));
AddStep("add flyte", () => createRandomScore(new APIUser { Username = "flyte", Id = 3103765 })); AddStep("add flyte", () => createRandomScore(new APIUser { Username = "flyte", Id = 3103765 }));
@ -89,6 +112,9 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test] [Test]
public void TestMaxHeight() public void TestMaxHeight()
{ {
createLeaderboard();
addLocalPlayer();
int playerNumber = 1; int playerNumber = 1;
AddRepeatStep("add 3 other players", () => createRandomScore(new APIUser { Username = $"Player {playerNumber++}" }), 3); AddRepeatStep("add 3 other players", () => createRandomScore(new APIUser { Username = $"Player {playerNumber++}" }), 3);
checkHeight(4); checkHeight(4);
@ -103,6 +129,28 @@ namespace osu.Game.Tests.Visual.Gameplay
=> AddAssert($"leaderboard height is {panelCount} panels high", () => leaderboard.DrawHeight == (GameplayLeaderboardScore.PANEL_HEIGHT + leaderboard.Spacing) * panelCount); => AddAssert($"leaderboard height is {panelCount} panels high", () => leaderboard.DrawHeight == (GameplayLeaderboardScore.PANEL_HEIGHT + leaderboard.Spacing) * panelCount);
} }
private void addLocalPlayer()
{
AddStep("add local player", () =>
{
playerScore.Value = 1222333;
createLeaderboardScore(playerScore, new APIUser { Username = "You", Id = 3 }, true);
});
}
private void createLeaderboard()
{
AddStep("create leaderboard", () =>
{
Child = leaderboard = new TestGameplayLeaderboard
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(2),
};
});
}
private void createRandomScore(APIUser user) => createLeaderboardScore(new BindableDouble(RNG.Next(0, 5_000_000)), user); private void createRandomScore(APIUser user) => createLeaderboardScore(new BindableDouble(RNG.Next(0, 5_000_000)), user);
private void createLeaderboardScore(BindableDouble score, APIUser user, bool isTracked = false) private void createLeaderboardScore(BindableDouble score, APIUser user, bool isTracked = false)

View File

@ -96,6 +96,14 @@ namespace osu.Game.Screens.Play.HUD
int displayCount = Math.Min(Flow.Count, maxPanels); int displayCount = Math.Min(Flow.Count, maxPanels);
Height = displayCount * (GameplayLeaderboardScore.PANEL_HEIGHT + Flow.Spacing.Y); Height = displayCount * (GameplayLeaderboardScore.PANEL_HEIGHT + Flow.Spacing.Y);
// Add extra margin space to flow equal to height of leaderboard.
// This ensures the content is always on screen, but also accounts for the fact that scroll operations
// without animation were actually forcing the local score to a location it can't usually reside at.
//
// Basically, the local score was in the scroll extension region (due to always trying to scroll the
// local player to the middle of the display, but there being no other content below the local player
// to scroll up by).
Flow.Margin = new MarginPadding { Bottom = Height };
requiresScroll = displayCount != Flow.Count; requiresScroll = displayCount != Flow.Count;
return drawable; return drawable;
@ -118,7 +126,7 @@ namespace osu.Game.Screens.Play.HUD
if (requiresScroll && trackedScore != null) if (requiresScroll && trackedScore != null)
{ {
float scrollTarget = scroll.GetChildPosInContent(trackedScore) + trackedScore.DrawHeight / 2 - scroll.DrawHeight / 2; float scrollTarget = scroll.GetChildPosInContent(trackedScore) + trackedScore.DrawHeight / 2 - scroll.DrawHeight / 2;
scroll.ScrollTo(scrollTarget, false); scroll.ScrollTo(scrollTarget);
} }
const float panel_height = GameplayLeaderboardScore.PANEL_HEIGHT; const float panel_height = GameplayLeaderboardScore.PANEL_HEIGHT;