2020-06-15 21:45:18 +08:00
|
|
|
// 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.
|
|
|
|
|
2022-06-17 15:37:17 +08:00
|
|
|
#nullable disable
|
|
|
|
|
2020-11-12 03:20:29 +08:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
2022-05-28 19:59:10 +08:00
|
|
|
using System.Threading;
|
2020-06-15 21:45:18 +08:00
|
|
|
using NUnit.Framework;
|
2020-06-18 21:21:30 +08:00
|
|
|
using osu.Framework.Graphics;
|
|
|
|
using osu.Framework.Graphics.Containers;
|
2022-02-03 17:00:40 +08:00
|
|
|
using osu.Framework.Graphics.Shapes;
|
|
|
|
using osu.Game.Beatmaps;
|
|
|
|
using osu.Game.Graphics;
|
|
|
|
using osu.Game.Graphics.Sprites;
|
|
|
|
using osu.Game.Rulesets;
|
|
|
|
using osu.Game.Rulesets.Difficulty;
|
|
|
|
using osu.Game.Rulesets.Mods;
|
2022-05-28 19:59:10 +08:00
|
|
|
using osu.Game.Rulesets.Objects;
|
2020-06-15 21:45:18 +08:00
|
|
|
using osu.Game.Scoring;
|
|
|
|
using osu.Game.Screens.Ranking.Statistics;
|
2020-11-12 03:20:29 +08:00
|
|
|
using osu.Game.Rulesets.Osu.Objects;
|
|
|
|
using osu.Game.Rulesets.Scoring;
|
2022-02-03 17:00:40 +08:00
|
|
|
using osu.Game.Rulesets.UI;
|
2021-12-13 15:34:48 +08:00
|
|
|
using osu.Game.Tests.Resources;
|
2020-11-12 03:20:29 +08:00
|
|
|
using osuTK;
|
2020-06-15 21:45:18 +08:00
|
|
|
|
|
|
|
namespace osu.Game.Tests.Visual.Ranking
|
|
|
|
{
|
2020-06-16 15:08:41 +08:00
|
|
|
public partial class TestSceneStatisticsPanel : OsuTestScene
|
2020-06-15 21:45:18 +08:00
|
|
|
{
|
|
|
|
[Test]
|
2020-11-12 03:20:29 +08:00
|
|
|
public void TestScoreWithTimeStatistics()
|
2020-06-15 21:45:18 +08:00
|
|
|
{
|
2021-12-13 15:34:48 +08:00
|
|
|
var score = TestResources.CreateTestScoreInfo();
|
|
|
|
score.HitEvents = TestSceneHitEventTimingDistributionGraph.CreateDistributedHitEvents();
|
2020-06-16 16:49:37 +08:00
|
|
|
|
|
|
|
loadPanel(score);
|
2020-06-15 21:45:18 +08:00
|
|
|
}
|
|
|
|
|
2020-11-12 03:20:29 +08:00
|
|
|
[Test]
|
|
|
|
public void TestScoreWithPositionStatistics()
|
|
|
|
{
|
2021-12-13 15:34:48 +08:00
|
|
|
var score = TestResources.CreateTestScoreInfo();
|
|
|
|
score.HitEvents = createPositionDistributedHitEvents();
|
2020-11-12 03:20:29 +08:00
|
|
|
|
|
|
|
loadPanel(score);
|
|
|
|
}
|
|
|
|
|
2020-06-18 21:21:30 +08:00
|
|
|
[Test]
|
|
|
|
public void TestScoreWithoutStatistics()
|
|
|
|
{
|
2021-12-13 15:37:20 +08:00
|
|
|
loadPanel(TestResources.CreateTestScoreInfo());
|
2020-06-18 21:21:30 +08:00
|
|
|
}
|
|
|
|
|
2022-02-03 17:00:40 +08:00
|
|
|
[Test]
|
|
|
|
public void TestScoreInRulesetWhereAllStatsRequireHitEvents()
|
|
|
|
{
|
|
|
|
loadPanel(TestResources.CreateTestScoreInfo(new TestRulesetAllStatsRequireHitEvents().RulesetInfo));
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestScoreInRulesetWhereNoStatsRequireHitEvents()
|
|
|
|
{
|
|
|
|
loadPanel(TestResources.CreateTestScoreInfo(new TestRulesetNoStatsRequireHitEvents().RulesetInfo));
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestScoreInMixedRuleset()
|
|
|
|
{
|
|
|
|
loadPanel(TestResources.CreateTestScoreInfo(new TestRulesetMixed().RulesetInfo));
|
|
|
|
}
|
|
|
|
|
2020-06-19 21:47:55 +08:00
|
|
|
[Test]
|
|
|
|
public void TestNullScore()
|
|
|
|
{
|
|
|
|
loadPanel(null);
|
|
|
|
}
|
|
|
|
|
2020-06-15 21:45:18 +08:00
|
|
|
private void loadPanel(ScoreInfo score) => AddStep("load panel", () =>
|
|
|
|
{
|
2020-06-18 21:21:30 +08:00
|
|
|
Child = new StatisticsPanel
|
|
|
|
{
|
|
|
|
RelativeSizeAxes = Axes.Both,
|
|
|
|
State = { Value = Visibility.Visible },
|
|
|
|
Score = { Value = score }
|
|
|
|
};
|
2020-06-15 21:45:18 +08:00
|
|
|
});
|
2020-11-12 03:20:29 +08:00
|
|
|
|
2020-11-12 05:41:25 +08:00
|
|
|
private static List<HitEvent> createPositionDistributedHitEvents()
|
2020-11-12 03:20:29 +08:00
|
|
|
{
|
|
|
|
var hitEvents = new List<HitEvent>();
|
|
|
|
// Use constant seed for reproducibility
|
|
|
|
var random = new Random(0);
|
|
|
|
|
|
|
|
for (int i = 0; i < 500; i++)
|
|
|
|
{
|
2020-11-12 05:40:52 +08:00
|
|
|
double angle = random.NextDouble() * 2 * Math.PI;
|
|
|
|
double radius = random.NextDouble() * 0.5f * OsuHitObject.OBJECT_RADIUS;
|
2020-11-12 03:20:29 +08:00
|
|
|
|
2020-11-12 05:40:52 +08:00
|
|
|
var position = new Vector2((float)(radius * Math.Cos(angle)), (float)(radius * Math.Sin(angle)));
|
2020-11-12 03:20:29 +08:00
|
|
|
|
|
|
|
hitEvents.Add(new HitEvent(0, HitResult.Perfect, new HitCircle(), new HitCircle(), position));
|
|
|
|
}
|
|
|
|
|
|
|
|
return hitEvents;
|
|
|
|
}
|
2022-02-03 17:00:40 +08:00
|
|
|
|
|
|
|
private class TestRuleset : Ruleset
|
|
|
|
{
|
|
|
|
public override IEnumerable<Mod> GetModsFor(ModType type)
|
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
|
|
|
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null)
|
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
2022-05-28 19:59:10 +08:00
|
|
|
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TestBeatmapConverter(beatmap);
|
2022-02-03 17:00:40 +08:00
|
|
|
|
|
|
|
public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap)
|
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
|
|
|
public override string Description => string.Empty;
|
|
|
|
|
|
|
|
public override string ShortName => string.Empty;
|
|
|
|
|
|
|
|
protected static Drawable CreatePlaceholderStatistic(string message) => new Container
|
|
|
|
{
|
|
|
|
RelativeSizeAxes = Axes.X,
|
|
|
|
Masking = true,
|
|
|
|
CornerRadius = 20,
|
|
|
|
Height = 250,
|
|
|
|
Children = new Drawable[]
|
|
|
|
{
|
|
|
|
new Box
|
|
|
|
{
|
|
|
|
RelativeSizeAxes = Axes.Both,
|
|
|
|
Colour = OsuColour.Gray(0.5f),
|
|
|
|
Alpha = 0.5f
|
|
|
|
},
|
|
|
|
new OsuSpriteText
|
|
|
|
{
|
|
|
|
Origin = Anchor.CentreLeft,
|
|
|
|
Anchor = Anchor.CentreLeft,
|
|
|
|
Text = message,
|
|
|
|
Margin = new MarginPadding { Left = 20 }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2022-05-28 19:59:10 +08:00
|
|
|
|
|
|
|
private class TestBeatmapConverter : IBeatmapConverter
|
|
|
|
{
|
|
|
|
#pragma warning disable CS0067 // The event is never used
|
|
|
|
public event Action<HitObject, IEnumerable<HitObject>> ObjectConverted;
|
|
|
|
#pragma warning restore CS0067
|
|
|
|
|
|
|
|
public IBeatmap Beatmap { get; }
|
|
|
|
|
|
|
|
public TestBeatmapConverter(IBeatmap beatmap)
|
|
|
|
{
|
|
|
|
Beatmap = beatmap;
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool CanConvert() => true;
|
|
|
|
|
|
|
|
public IBeatmap Convert(CancellationToken cancellationToken = default) => Beatmap.Clone();
|
|
|
|
}
|
2022-02-03 17:00:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
private class TestRulesetAllStatsRequireHitEvents : TestRuleset
|
|
|
|
{
|
|
|
|
public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap)
|
|
|
|
{
|
|
|
|
return new[]
|
|
|
|
{
|
|
|
|
new StatisticRow
|
|
|
|
{
|
|
|
|
Columns = new[]
|
|
|
|
{
|
|
|
|
new StatisticItem("Statistic Requiring Hit Events 1",
|
|
|
|
() => CreatePlaceholderStatistic("Placeholder statistic. Requires hit events"), true)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
new StatisticRow
|
|
|
|
{
|
|
|
|
Columns = new[]
|
|
|
|
{
|
|
|
|
new StatisticItem("Statistic Requiring Hit Events 2",
|
|
|
|
() => CreatePlaceholderStatistic("Placeholder statistic. Requires hit events"), true)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class TestRulesetNoStatsRequireHitEvents : TestRuleset
|
|
|
|
{
|
|
|
|
public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap)
|
|
|
|
{
|
|
|
|
return new[]
|
|
|
|
{
|
|
|
|
new StatisticRow
|
|
|
|
{
|
|
|
|
Columns = new[]
|
|
|
|
{
|
|
|
|
new StatisticItem("Statistic Not Requiring Hit Events 1",
|
|
|
|
() => CreatePlaceholderStatistic("Placeholder statistic. Does not require hit events"))
|
|
|
|
}
|
|
|
|
},
|
|
|
|
new StatisticRow
|
|
|
|
{
|
|
|
|
Columns = new[]
|
|
|
|
{
|
|
|
|
new StatisticItem("Statistic Not Requiring Hit Events 2",
|
|
|
|
() => CreatePlaceholderStatistic("Placeholder statistic. Does not require hit events"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class TestRulesetMixed : TestRuleset
|
|
|
|
{
|
|
|
|
public override StatisticRow[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap)
|
|
|
|
{
|
|
|
|
return new[]
|
|
|
|
{
|
|
|
|
new StatisticRow
|
|
|
|
{
|
|
|
|
Columns = new[]
|
|
|
|
{
|
|
|
|
new StatisticItem("Statistic Requiring Hit Events",
|
|
|
|
() => CreatePlaceholderStatistic("Placeholder statistic. Requires hit events"), true)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
new StatisticRow
|
|
|
|
{
|
|
|
|
Columns = new[]
|
|
|
|
{
|
|
|
|
new StatisticItem("Statistic Not Requiring Hit Events",
|
|
|
|
() => CreatePlaceholderStatistic("Placeholder statistic. Does not require hit events"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
2020-06-15 21:45:18 +08:00
|
|
|
}
|
|
|
|
}
|