1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-06 09:07:25 +08:00

Merge branch 'master' into fix-long-spinner-performance

This commit is contained in:
Dan Balasescu 2020-03-23 12:39:59 +09:00 committed by GitHub
commit c281ccd590
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 443 additions and 189 deletions

View File

@ -4,48 +4,43 @@
using System;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Skinning;
using osu.Game.Tests.Visual;
using osuTK;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestSceneHitCircleArea : ManualInputManagerTestScene
public class TestSceneHitCircleArea : OsuManualInputManagerTestScene
{
private HitCircle hitCircle;
private DrawableHitCircle drawableHitCircle;
private DrawableHitCircle.HitReceptor hitAreaReceptor => drawableHitCircle.HitArea;
[SetUp]
public new void SetUp()
public void SetUp() => Schedule(() =>
{
base.SetUp();
Schedule(() =>
hitCircle = new HitCircle
{
hitCircle = new HitCircle
{
Position = new Vector2(100, 100),
StartTime = Time.Current + 500
};
Position = new Vector2(100, 100),
StartTime = Time.Current + 500
};
hitCircle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
hitCircle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
Child = new SkinProvidingContainer(new DefaultSkin())
Child = new SkinProvidingContainer(new DefaultSkin())
{
RelativeSizeAxes = Axes.Both,
Child = drawableHitCircle = new DrawableHitCircle(hitCircle)
{
RelativeSizeAxes = Axes.Both,
Child = drawableHitCircle = new DrawableHitCircle(hitCircle)
{
Size = new Vector2(100)
}
};
});
}
Size = new Vector2(100)
}
};
});
[Test]
public void TestCircleHitCentre()

View File

@ -23,7 +23,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestSceneOsuDistanceSnapGrid : ManualInputManagerTestScene
public class TestSceneOsuDistanceSnapGrid : OsuManualInputManagerTestScene
{
private const double beat_length = 100;
private static readonly Vector2 grid_position = new Vector2(512, 384);

View File

@ -12,7 +12,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestSceneResumeOverlay : ManualInputManagerTestScene
public class TestSceneResumeOverlay : OsuManualInputManagerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{

View File

@ -37,7 +37,7 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Background
{
[TestFixture]
public class TestSceneUserDimBackgrounds : ManualInputManagerTestScene
public class TestSceneUserDimBackgrounds : OsuManualInputManagerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -278,6 +278,7 @@ namespace osu.Game.Tests.Visual.Background
private void setupUserSettings()
{
AddUntilStep("Song select is current", () => songSelect.IsCurrentScreen());
AddUntilStep("Song select has selection", () => songSelect.Carousel?.SelectedBeatmap != null);
AddStep("Set default user settings", () =>
{

View File

@ -12,7 +12,7 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Components
{
[TestFixture]
public class TestSceneIdleTracker : ManualInputManagerTestScene
public class TestSceneIdleTracker : OsuManualInputManagerTestScene
{
private IdleTrackingBox box1;
private IdleTrackingBox box2;

View File

@ -16,7 +16,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.Editor
{
public class TestSceneBeatDivisorControl : ManualInputManagerTestScene
public class TestSceneBeatDivisorControl : OsuManualInputManagerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(BindableBeatDivisor) };
private BeatDivisorControl beatDivisorControl;

View File

@ -17,7 +17,7 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Editor
{
public class TestSceneZoomableScrollContainer : ManualInputManagerTestScene
public class TestSceneZoomableScrollContainer : OsuManualInputManagerTestScene
{
private ZoomableScrollContainer scrollContainer;
private Drawable innerBox;

View File

@ -18,7 +18,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.Gameplay
{
[Description("player pause/fail screens")]
public class TestSceneGameplayMenuOverlay : ManualInputManagerTestScene
public class TestSceneGameplayMenuOverlay : OsuManualInputManagerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(FailOverlay), typeof(PauseOverlay) };

View File

@ -15,7 +15,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestSceneHUDOverlay : ManualInputManagerTestScene
public class TestSceneHUDOverlay : OsuManualInputManagerTestScene
{
private HUDOverlay hudOverlay;

View File

@ -13,7 +13,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.Gameplay
{
[Description("'Hold to Quit' UI element")]
public class TestSceneHoldForMenuButton : ManualInputManagerTestScene
public class TestSceneHoldForMenuButton : OsuManualInputManagerTestScene
{
private bool exitAction;

View File

@ -13,7 +13,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public class TestSceneKeyCounter : ManualInputManagerTestScene
public class TestSceneKeyCounter : OsuManualInputManagerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{

View File

@ -29,7 +29,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestScenePlayerLoader : ManualInputManagerTestScene
public class TestScenePlayerLoader : OsuManualInputManagerTestScene
{
private TestPlayerLoader loader;
private TestPlayerLoaderContainer container;

View File

@ -14,7 +14,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public class TestSceneSkipOverlay : ManualInputManagerTestScene
public class TestSceneSkipOverlay : OsuManualInputManagerTestScene
{
private SkipOverlay skip;
private int requestCount;

View File

@ -20,7 +20,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.Multiplayer
{
public class TestSceneDrawableRoomPlaylist : ManualInputManagerTestScene
public class TestSceneDrawableRoomPlaylist : OsuManualInputManagerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{

View File

@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual.Navigation
/// <summary>
/// A scene which tests full game flow.
/// </summary>
public abstract class OsuGameTestScene : ManualInputManagerTestScene
public abstract class OsuGameTestScene : OsuManualInputManagerTestScene
{
private GameHost host;

View File

@ -22,7 +22,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.Online
{
public class TestSceneChatOverlay : ManualInputManagerTestScene
public class TestSceneChatOverlay : OsuManualInputManagerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{

View File

@ -227,6 +227,34 @@ namespace osu.Game.Tests.Visual.SongSelect
waitForSelection(set_count);
}
[Test]
public void TestSelectionEnteringFromEmptyRuleset()
{
var sets = new List<BeatmapSetInfo>();
AddStep("Create beatmaps for taiko only", () =>
{
sets.Clear();
var rulesetBeatmapSet = createTestBeatmapSet(1);
var taikoRuleset = rulesets.AvailableRulesets.ElementAt(1);
rulesetBeatmapSet.Beatmaps.ForEach(b =>
{
b.Ruleset = taikoRuleset;
b.RulesetID = 1;
});
sets.Add(rulesetBeatmapSet);
});
loadBeatmaps(sets, () => new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(0) });
AddStep("Set non-empty mode filter", () =>
carousel.Filter(new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(1) }, false));
AddAssert("Something is selected", () => carousel.SelectedBeatmap != null);
}
/// <summary>
/// Test sorting
/// </summary>
@ -399,27 +427,32 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("filter to ruleset 0", () =>
carousel.Filter(new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(0) }, false));
AddStep("select filtered map skipping filtered", () => carousel.SelectBeatmap(testMixed.Beatmaps[1], false));
AddAssert("unfiltered beatmap not selected", () => carousel.SelectedBeatmap == null);
AddAssert("unfiltered beatmap not selected", () => carousel.SelectedBeatmap.RulesetID == 0);
AddStep("remove mixed set", () =>
{
carousel.RemoveBeatmapSet(testMixed);
testMixed = null;
});
var testSingle = createTestBeatmapSet(set_count + 2);
testSingle.Beatmaps.ForEach(b =>
BeatmapSetInfo testSingle = null;
AddStep("add single ruleset beatmapset", () =>
{
b.Ruleset = rulesets.AvailableRulesets.ElementAt(1);
b.RulesetID = b.Ruleset.ID ?? 1;
testSingle = createTestBeatmapSet(set_count + 2);
testSingle.Beatmaps.ForEach(b =>
{
b.Ruleset = rulesets.AvailableRulesets.ElementAt(1);
b.RulesetID = b.Ruleset.ID ?? 1;
});
carousel.UpdateBeatmapSet(testSingle);
});
AddStep("add single ruleset beatmapset", () => carousel.UpdateBeatmapSet(testSingle));
AddStep("select filtered map skipping filtered", () => carousel.SelectBeatmap(testSingle.Beatmaps[0], false));
checkNoSelection();
AddStep("remove single ruleset set", () => carousel.RemoveBeatmapSet(testSingle));
}
[Test]
public void TestCarouselRootIsRandom()
public void TestCarouselRemembersSelection()
{
List<BeatmapSetInfo> manySets = new List<BeatmapSetInfo>();
@ -429,12 +462,74 @@ namespace osu.Game.Tests.Visual.SongSelect
loadBeatmaps(manySets);
advanceSelection(direction: 1, diff: false);
checkNonmatchingFilter();
checkNonmatchingFilter();
checkNonmatchingFilter();
checkNonmatchingFilter();
checkNonmatchingFilter();
AddAssert("Selection was random", () => eagerSelectedIDs.Count > 1);
for (int i = 0; i < 5; i++)
{
AddStep("Toggle non-matching filter", () =>
{
carousel.Filter(new FilterCriteria { SearchText = Guid.NewGuid().ToString() }, false);
});
AddStep("Restore no filter", () =>
{
carousel.Filter(new FilterCriteria(), false);
eagerSelectedIDs.Add(carousel.SelectedBeatmapSet.ID);
});
}
// always returns to same selection as long as it's available.
AddAssert("Selection was remembered", () => eagerSelectedIDs.Count == 1);
}
[Test]
public void TestRandomFallbackOnNonMatchingPrevious()
{
List<BeatmapSetInfo> manySets = new List<BeatmapSetInfo>();
AddStep("populate maps", () =>
{
for (int i = 0; i < 10; i++)
{
var set = createTestBeatmapSet(i);
foreach (var b in set.Beatmaps)
{
// all taiko except for first
int ruleset = i > 0 ? 1 : 0;
b.Ruleset = rulesets.GetRuleset(ruleset);
b.RulesetID = ruleset;
}
manySets.Add(set);
}
});
loadBeatmaps(manySets);
for (int i = 0; i < 10; i++)
{
AddStep("Reset filter", () => carousel.Filter(new FilterCriteria(), false));
AddStep("select first beatmap", () => carousel.SelectBeatmap(manySets.First().Beatmaps.First()));
AddStep("Toggle non-matching filter", () =>
{
carousel.Filter(new FilterCriteria { SearchText = Guid.NewGuid().ToString() }, false);
});
AddAssert("selection lost", () => carousel.SelectedBeatmap == null);
AddStep("Restore different ruleset filter", () =>
{
carousel.Filter(new FilterCriteria { Ruleset = rulesets.GetRuleset(1) }, false);
eagerSelectedIDs.Add(carousel.SelectedBeatmapSet.ID);
});
AddAssert("selection changed", () => carousel.SelectedBeatmap != manySets.First().Beatmaps.First());
}
AddAssert("Selection was random", () => eagerSelectedIDs.Count > 2);
}
[Test]
@ -484,7 +579,7 @@ namespace osu.Game.Tests.Visual.SongSelect
checkVisibleItemCount(true, 15);
}
private void loadBeatmaps(List<BeatmapSetInfo> beatmapSets = null)
private void loadBeatmaps(List<BeatmapSetInfo> beatmapSets = null, Func<FilterCriteria> initialCriteria = null)
{
createCarousel();
@ -499,7 +594,7 @@ namespace osu.Game.Tests.Visual.SongSelect
bool changed = false;
AddStep($"Load {(beatmapSets.Count > 0 ? beatmapSets.Count.ToString() : "some")} beatmaps", () =>
{
carousel.Filter(new FilterCriteria());
carousel.Filter(initialCriteria?.Invoke() ?? new FilterCriteria());
carousel.BeatmapSetsChanged = () => changed = true;
carousel.BeatmapSets = beatmapSets;
});
@ -593,16 +688,6 @@ namespace osu.Game.Tests.Visual.SongSelect
AddAssert("Selection is visible", selectedBeatmapVisible);
}
private void checkNonmatchingFilter()
{
AddStep("Toggle non-matching filter", () =>
{
carousel.Filter(new FilterCriteria { SearchText = "Dingo" }, false);
carousel.Filter(new FilterCriteria(), false);
eagerSelectedIDs.Add(carousel.SelectedBeatmapSet.ID);
});
}
private BeatmapSetInfo createTestBeatmapSet(int id)
{
return new BeatmapSetInfo

View File

@ -15,7 +15,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.UserInterface
{
public class TestSceneCommentEditor : ManualInputManagerTestScene
public class TestSceneCommentEditor : OsuManualInputManagerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{

View File

@ -17,7 +17,7 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.UserInterface
{
[TestFixture]
public class TestSceneCursors : ManualInputManagerTestScene
public class TestSceneCursors : OsuManualInputManagerTestScene
{
private readonly MenuCursorContainer menuCursorContainer;
private readonly CustomCursorBox[] cursorBoxes = new CustomCursorBox[6];

View File

@ -27,7 +27,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.UserInterface
{
public class TestSceneDeleteLocalScore : ManualInputManagerTestScene
public class TestSceneDeleteLocalScore : OsuManualInputManagerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{

View File

@ -12,7 +12,7 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.UserInterface
{
[TestFixture]
public class TestSceneOsuHoverContainer : ManualInputManagerTestScene
public class TestSceneOsuHoverContainer : OsuManualInputManagerTestScene
{
private OsuHoverTestContainer hoverContainer;
private Box colourContainer;

View File

@ -12,7 +12,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.UserInterface
{
public class TestSceneStatefulMenuItem : ManualInputManagerTestScene
public class TestSceneStatefulMenuItem : OsuManualInputManagerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{

View File

@ -9,7 +9,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.UserInterface
{
public class TestSceneSwitchButton : ManualInputManagerTestScene
public class TestSceneSwitchButton : OsuManualInputManagerTestScene
{
private SwitchButton switchButton;

View File

@ -1,16 +1,147 @@
// 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 System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Tournament.Models;
using osu.Game.Users;
namespace osu.Game.Tournament.Tests
{
[TestFixture]
public abstract class LadderTestScene : TournamentTestScene
{
[Cached]
protected LadderInfo Ladder { get; private set; } = new LadderInfo();
[Resolved]
protected LadderInfo Ladder { get; private set; }
private RulesetStore rulesetStore { get; set; }
[BackgroundDependencyLoader]
private void load()
{
if (Ladder.Ruleset.Value == null)
Ladder.Ruleset.Value = rulesetStore.AvailableRulesets.First();
Ruleset.BindTo(Ladder.Ruleset);
}
protected override void LoadComplete()
{
base.LoadComplete();
TournamentMatch match = CreateSampleMatch();
Ladder.Rounds.Add(match.Round.Value);
Ladder.Matches.Add(match);
Ladder.Teams.Add(match.Team1.Value);
Ladder.Teams.Add(match.Team2.Value);
Ladder.CurrentMatch.Value = match;
}
public static TournamentMatch CreateSampleMatch() => new TournamentMatch
{
Team1 =
{
Value = new TournamentTeam
{
FlagName = { Value = "JP" },
FullName = { Value = "Japan" },
LastYearPlacing = { Value = 10 },
Seed = { Value = "Low" },
SeedingResults =
{
new SeedingResult
{
Mod = { Value = "NM" },
Seed = { Value = 10 },
Beatmaps =
{
new SeedingBeatmap
{
BeatmapInfo = CreateSampleBeatmapInfo(),
Score = 12345672,
Seed = { Value = 24 },
},
new SeedingBeatmap
{
BeatmapInfo = CreateSampleBeatmapInfo(),
Score = 1234567,
Seed = { Value = 12 },
},
new SeedingBeatmap
{
BeatmapInfo = CreateSampleBeatmapInfo(),
Score = 1234567,
Seed = { Value = 16 },
}
}
},
new SeedingResult
{
Mod = { Value = "DT" },
Seed = { Value = 5 },
Beatmaps =
{
new SeedingBeatmap
{
BeatmapInfo = CreateSampleBeatmapInfo(),
Score = 234567,
Seed = { Value = 3 },
},
new SeedingBeatmap
{
BeatmapInfo = CreateSampleBeatmapInfo(),
Score = 234567,
Seed = { Value = 6 },
},
new SeedingBeatmap
{
BeatmapInfo = CreateSampleBeatmapInfo(),
Score = 234567,
Seed = { Value = 12 },
}
}
}
},
Players =
{
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 12 } } },
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 16 } } },
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 20 } } },
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 24 } } },
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 30 } } },
}
}
},
Team2 =
{
Value = new TournamentTeam
{
FlagName = { Value = "US" },
FullName = { Value = "United States" },
Players =
{
new User { Username = "Hello" },
new User { Username = "Hello" },
new User { Username = "Hello" },
new User { Username = "Hello" },
new User { Username = "Hello" },
}
}
},
Round =
{
Value = new TournamentRound { Name = { Value = "Quarterfinals" } }
}
};
public static BeatmapInfo CreateSampleBeatmapInfo() =>
new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist", ID = RNG.Next(0, 1000000) } };
}
}

View File

@ -1,24 +1,140 @@
// 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 System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Tournament.Components;
using osu.Game.Tournament.Models;
using osu.Game.Tournament.Screens.MapPool;
namespace osu.Game.Tournament.Tests.Screens
{
public class TestSceneMapPoolScreen : LadderTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(MapPoolScreen)
};
private MapPoolScreen screen;
[BackgroundDependencyLoader]
private void load()
{
Add(new MapPoolScreen { Width = 0.7f });
Add(screen = new MapPoolScreen { Width = 0.7f });
}
[Test]
public void TestFewMaps()
{
AddStep("load few maps", () =>
{
Ladder.CurrentMatch.Value.Round.Value.Beatmaps.Clear();
for (int i = 0; i < 8; i++)
addBeatmap();
});
AddStep("reset match", () =>
{
Ladder.CurrentMatch.Value = new TournamentMatch();
Ladder.CurrentMatch.Value = Ladder.Matches.First();
});
assertTwoWide();
}
[Test]
public void TestJustEnoughMaps()
{
AddStep("load just enough maps", () =>
{
Ladder.CurrentMatch.Value.Round.Value.Beatmaps.Clear();
for (int i = 0; i < 18; i++)
addBeatmap();
});
AddStep("reset match", () =>
{
Ladder.CurrentMatch.Value = new TournamentMatch();
Ladder.CurrentMatch.Value = Ladder.Matches.First();
});
assertTwoWide();
}
[Test]
public void TestManyMaps()
{
AddStep("load many maps", () =>
{
Ladder.CurrentMatch.Value.Round.Value.Beatmaps.Clear();
for (int i = 0; i < 19; i++)
addBeatmap();
});
AddStep("reset match", () =>
{
Ladder.CurrentMatch.Value = new TournamentMatch();
Ladder.CurrentMatch.Value = Ladder.Matches.First();
});
assertThreeWide();
}
[Test]
public void TestJustEnoughMods()
{
AddStep("load many maps", () =>
{
Ladder.CurrentMatch.Value.Round.Value.Beatmaps.Clear();
for (int i = 0; i < 11; i++)
addBeatmap(i > 4 ? $"M{i}" : "NM");
});
AddStep("reset match", () =>
{
Ladder.CurrentMatch.Value = new TournamentMatch();
Ladder.CurrentMatch.Value = Ladder.Matches.First();
});
assertTwoWide();
}
private void assertTwoWide() =>
AddAssert("ensure layout width is 2", () => screen.ChildrenOfType<FillFlowContainer<FillFlowContainer<TournamentBeatmapPanel>>>().First().Padding.Left > 0);
private void assertThreeWide() =>
AddAssert("ensure layout width is 3", () => screen.ChildrenOfType<FillFlowContainer<FillFlowContainer<TournamentBeatmapPanel>>>().First().Padding.Left == 0);
[Test]
public void TestManyMods()
{
AddStep("load many maps", () =>
{
Ladder.CurrentMatch.Value.Round.Value.Beatmaps.Clear();
for (int i = 0; i < 12; i++)
addBeatmap(i > 4 ? $"M{i}" : "NM");
});
AddStep("reset match", () =>
{
Ladder.CurrentMatch.Value = new TournamentMatch();
Ladder.CurrentMatch.Value = Ladder.Matches.First();
});
assertThreeWide();
}
private void addBeatmap(string mods = "nm")
{
Ladder.CurrentMatch.Value.Round.Value.Beatmaps.Add(new RoundBeatmap
{
BeatmapInfo = CreateSampleBeatmapInfo(),
Mods = mods
});
}
}
}

View File

@ -14,7 +14,7 @@ namespace osu.Game.Tournament.Tests.Screens
public TestSceneSeedingEditorScreen()
{
var match = TestSceneSeedingScreen.CreateSampleSeededMatch();
var match = CreateSampleMatch();
Add(new SeedingEditorScreen(match.Team1.Value)
{

View File

@ -3,10 +3,8 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Tournament.Models;
using osu.Game.Tournament.Screens.TeamIntro;
using osu.Game.Users;
namespace osu.Game.Tournament.Tests.Screens
{
@ -18,110 +16,11 @@ namespace osu.Game.Tournament.Tests.Screens
[BackgroundDependencyLoader]
private void load()
{
ladder.CurrentMatch.Value = CreateSampleSeededMatch();
Add(new SeedingScreen
{
FillMode = FillMode.Fit,
FillAspectRatio = 16 / 9f
});
}
public static TournamentMatch CreateSampleSeededMatch() => new TournamentMatch
{
Team1 =
{
Value = new TournamentTeam
{
FlagName = { Value = "JP" },
FullName = { Value = "Japan" },
LastYearPlacing = { Value = 10 },
Seed = { Value = "Low" },
SeedingResults =
{
new SeedingResult
{
Mod = { Value = "NM" },
Seed = { Value = 10 },
Beatmaps =
{
new SeedingBeatmap
{
BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist" } },
Score = 12345672,
Seed = { Value = 24 },
},
new SeedingBeatmap
{
BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist" } },
Score = 1234567,
Seed = { Value = 12 },
},
new SeedingBeatmap
{
BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist" } },
Score = 1234567,
Seed = { Value = 16 },
}
}
},
new SeedingResult
{
Mod = { Value = "DT" },
Seed = { Value = 5 },
Beatmaps =
{
new SeedingBeatmap
{
BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist" } },
Score = 234567,
Seed = { Value = 3 },
},
new SeedingBeatmap
{
BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist" } },
Score = 234567,
Seed = { Value = 6 },
},
new SeedingBeatmap
{
BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist" } },
Score = 234567,
Seed = { Value = 12 },
}
}
}
},
Players =
{
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 12 } } },
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 16 } } },
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 20 } } },
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 24 } } },
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 30 } } },
}
}
},
Team2 =
{
Value = new TournamentTeam
{
FlagName = { Value = "US" },
FullName = { Value = "United States" },
Players =
{
new User { Username = "Hello" },
new User { Username = "Hello" },
new User { Username = "Hello" },
new User { Username = "Hello" },
new User { Username = "Hello" },
}
}
},
Round =
{
Value = new TournamentRound { Name = { Value = "Quarterfinals" } }
}
};
}
}

View File

@ -50,11 +50,11 @@ namespace osu.Game.Tournament.Screens.MapPool
new MatchHeader(),
mapFlows = new FillFlowContainer<FillFlowContainer<TournamentBeatmapPanel>>
{
Y = 140,
Y = 160,
Spacing = new Vector2(10, 10),
Padding = new MarginPadding(25),
Direction = FillDirection.Vertical,
RelativeSizeAxes = Axes.Both,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
},
new ControlPanel
{
@ -95,6 +95,7 @@ namespace osu.Game.Tournament.Screens.MapPool
Text = "Reset",
Action = reset
},
new ControlPanel.Spacer(),
}
}
};
@ -211,11 +212,15 @@ namespace osu.Game.Tournament.Screens.MapPool
{
mapFlows.Clear();
int totalRows = 0;
if (match.NewValue.Round.Value != null)
{
FillFlowContainer<TournamentBeatmapPanel> currentFlow = null;
string currentMod = null;
int flowCount = 0;
foreach (var b in match.NewValue.Round.Value.Beatmaps)
{
if (currentFlow == null || currentMod != b.Mods)
@ -229,6 +234,15 @@ namespace osu.Game.Tournament.Screens.MapPool
});
currentMod = b.Mods;
totalRows++;
flowCount = 0;
}
if (++flowCount > 2)
{
totalRows++;
flowCount = 1;
}
currentFlow.Add(new TournamentBeatmapPanel(b.BeatmapInfo, b.Mods)
@ -239,6 +253,12 @@ namespace osu.Game.Tournament.Screens.MapPool
});
}
}
mapFlows.Padding = new MarginPadding(5)
{
// remove horizontal padding to increase flow width to 3 panels
Horizontal = totalRows > 9 ? 0 : 100
};
}
}
}

View File

@ -333,8 +333,7 @@ namespace osu.Game.Screens.Select
else
set = visibleSets.ElementAt(RNG.Next(visibleSets.Count));
var visibleBeatmaps = set.Beatmaps.Where(s => !s.Filtered.Value).ToList();
select(visibleBeatmaps[RNG.Next(visibleBeatmaps.Count)]);
select(set);
return true;
}
@ -751,13 +750,17 @@ namespace osu.Game.Screens.Select
public CarouselRoot(BeatmapCarousel carousel)
{
// root should always remain selected. if not, PerformSelection will not be called.
State.Value = CarouselItemState.Selected;
State.ValueChanged += state => State.Value = CarouselItemState.Selected;
this.carousel = carousel;
}
protected override void PerformSelection()
{
if (LastSelected == null)
carousel.SelectNextRandom();
if (LastSelected == null || LastSelected.Filtered.Value)
carousel?.SelectNextRandom();
else
base.PerformSelection();
}

View File

@ -104,7 +104,8 @@ namespace osu.Game.Screens.Select.Carousel
private void updateSelected(CarouselItem newSelection)
{
LastSelected = newSelection;
if (newSelection != null)
LastSelected = newSelection;
updateSelectedIndex();
}

View File

@ -150,6 +150,7 @@ namespace osu.Game.Screens.Select
},
Child = Carousel = new BeatmapCarousel
{
AllowSelection = false, // delay any selection until our bindables are ready to make a good choice.
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
RelativeSizeAxes = Axes.Both,
@ -655,6 +656,8 @@ namespace osu.Game.Screens.Select
{
bindBindables();
Carousel.AllowSelection = true;
// If a selection was already obtained, do not attempt to update the selected beatmap.
if (Carousel.SelectedBeatmapSet != null)
return;

View File

@ -14,7 +14,7 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual
{
public abstract class ManualInputManagerTestScene : OsuTestScene
public abstract class OsuManualInputManagerTestScene : OsuTestScene
{
protected override Container<Drawable> Content => content;
private readonly Container content;
@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual
private readonly TriangleButton buttonTest;
private readonly TriangleButton buttonLocal;
protected ManualInputManagerTestScene()
protected OsuManualInputManagerTestScene()
{
base.Content.AddRange(new Drawable[]
{

View File

@ -11,7 +11,7 @@ namespace osu.Game.Tests.Visual
/// <summary>
/// A test case which can be used to test a screen (that relies on OnEntering being called to execute startup instructions).
/// </summary>
public abstract class ScreenTestScene : ManualInputManagerTestScene
public abstract class ScreenTestScene : OsuManualInputManagerTestScene
{
protected readonly OsuScreenStack Stack;

View File

@ -8,7 +8,7 @@ using osu.Game.Rulesets.Edit;
namespace osu.Game.Tests.Visual
{
public abstract class SelectionBlueprintTestScene : ManualInputManagerTestScene
public abstract class SelectionBlueprintTestScene : OsuManualInputManagerTestScene
{
protected override Container<Drawable> Content => content ?? base.Content;
private readonly Container content;