1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 18:42:56 +08:00

Merge branch 'catch-hr-fixes' into sorcerer-diffcalc-changes

This commit is contained in:
smoogipoo 2019-03-20 12:15:01 +09:00
commit 8210128979
34 changed files with 219 additions and 134 deletions

View File

@ -20,6 +20,13 @@ namespace osu.Game.Rulesets.Catch.Mods
public void ApplyToHitObject(HitObject hitObject) public void ApplyToHitObject(HitObject hitObject)
{ {
if (hitObject is JuiceStream stream)
{
lastPosition = stream.EndX;
lastStartTime = stream.EndTime;
return;
}
if (!(hitObject is Fruit)) if (!(hitObject is Fruit))
return; return;
@ -70,7 +77,7 @@ namespace osu.Game.Rulesets.Catch.Mods
private void applyRandomOffset(ref float position, double maxOffset) private void applyRandomOffset(ref float position, double maxOffset)
{ {
bool right = RNG.NextBool(); bool right = RNG.NextBool();
float rand = Math.Min(20, (float)RNG.NextDouble(0, maxOffset)) / CatchPlayfield.BASE_WIDTH; float rand = Math.Min(20, (float)RNG.NextDouble(0, Math.Max(0, maxOffset))) / CatchPlayfield.BASE_WIDTH;
if (right) if (right)
{ {

View File

@ -354,9 +354,9 @@ namespace osu.Game.Rulesets.Osu.Tests
judgementResults = new List<JudgementResult>(); judgementResults = new List<JudgementResult>();
}); });
AddUntilStep(() => Beatmap.Value.Track.CurrentTime == 0, "Beatmap at 0"); AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0);
AddUntilStep(() => currentPlayer.IsCurrentScreen(), "Wait until player is loaded"); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen());
AddUntilStep(() => allJudgedFired, "Wait for all judged"); AddUntilStep("Wait for all judged", () => allJudgedFired);
} }
private class ScoreAccessibleReplayPlayer : ReplayPlayer private class ScoreAccessibleReplayPlayer : ReplayPlayer

View File

@ -242,6 +242,61 @@ namespace osu.Game.Tests.Beatmaps.IO
} }
} }
[Test]
public void TestImportWithDuplicateBeatmapIDs()
{
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportWithDuplicateBeatmapID"))
{
try
{
var osu = loadOsu(host);
var metadata = new BeatmapMetadata
{
Artist = "SomeArtist",
AuthorString = "SomeAuthor"
};
var difficulty = new BeatmapDifficulty();
var toImport = new BeatmapSetInfo
{
OnlineBeatmapSetID = 1,
Metadata = metadata,
Beatmaps = new List<BeatmapInfo>
{
new BeatmapInfo
{
OnlineBeatmapID = 2,
Metadata = metadata,
BaseDifficulty = difficulty
},
new BeatmapInfo
{
OnlineBeatmapID = 2,
Metadata = metadata,
Status = BeatmapSetOnlineStatus.Loved,
BaseDifficulty = difficulty
}
}
};
var manager = osu.Dependencies.Get<BeatmapManager>();
var imported = manager.Import(toImport);
Assert.NotNull(imported);
Assert.AreEqual(null, imported.Beatmaps[0].OnlineBeatmapID);
Assert.AreEqual(null, imported.Beatmaps[1].OnlineBeatmapID);
}
finally
{
host.Exit();
}
}
}
[Test] [Test]
[NonParallelizable] [NonParallelizable]
[Ignore("Binding IPC on Appveyor isn't working (port in use). Need to figure out why")] [Ignore("Binding IPC on Appveyor isn't working (port in use). Need to figure out why")]

View File

@ -27,8 +27,8 @@ namespace osu.Game.Tests.Visual
protected override void AddCheckSteps(Func<Player> player) protected override void AddCheckSteps(Func<Player> player)
{ {
base.AddCheckSteps(player); base.AddCheckSteps(player);
AddUntilStep(() => ((ScoreAccessiblePlayer)player()).ScoreProcessor.TotalScore.Value > 0, "score above zero"); AddUntilStep("score above zero", () => ((ScoreAccessiblePlayer)player()).ScoreProcessor.TotalScore.Value > 0);
AddUntilStep(() => ((ScoreAccessiblePlayer)player()).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0), "key counter counted keys"); AddUntilStep("key counter counted keys", () => ((ScoreAccessiblePlayer)player()).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0));
} }
private class ScoreAccessiblePlayer : Player private class ScoreAccessiblePlayer : Player

View File

@ -98,7 +98,7 @@ namespace osu.Game.Tests.Visual
{ {
setupUserSettings(); setupUserSettings();
AddStep("Start player loader", () => songSelect.Push(playerLoader = new DimAccessiblePlayerLoader(player = new DimAccessiblePlayer()))); AddStep("Start player loader", () => songSelect.Push(playerLoader = new DimAccessiblePlayerLoader(player = new DimAccessiblePlayer())));
AddUntilStep(() => playerLoader?.IsLoaded ?? false, "Wait for Player Loader to load"); AddUntilStep("Wait for Player Loader to load", () => playerLoader?.IsLoaded ?? false);
AddAssert("Background retained from song select", () => songSelect.IsBackgroundCurrent()); AddAssert("Background retained from song select", () => songSelect.IsBackgroundCurrent());
AddStep("Trigger background preview", () => AddStep("Trigger background preview", () =>
{ {
@ -220,7 +220,7 @@ namespace osu.Game.Tests.Visual
AddAssert("Screen is undimmed", () => songSelect.IsBackgroundUndimmed()); AddAssert("Screen is undimmed", () => songSelect.IsBackgroundUndimmed());
} }
private void waitForDim() => AddWaitStep(5, "Wait for dim"); private void waitForDim() => AddWaitStep("Wait for dim", 5);
private void createFakeStoryboard() => AddStep("Create storyboard", () => private void createFakeStoryboard() => AddStep("Create storyboard", () =>
{ {
@ -249,14 +249,14 @@ namespace osu.Game.Tests.Visual
Ready = true, Ready = true,
})); }));
}); });
AddUntilStep(() => playerLoader.IsLoaded, "Wait for Player Loader to load"); AddUntilStep("Wait for Player Loader to load", () => playerLoader.IsLoaded);
AddStep("Move mouse to center of screen", () => InputManager.MoveMouseTo(playerLoader.ScreenPos)); AddStep("Move mouse to center of screen", () => InputManager.MoveMouseTo(playerLoader.ScreenPos));
AddUntilStep(() => player.IsLoaded, "Wait for player to load"); AddUntilStep("Wait for player to load", () => player.IsLoaded);
} }
private void setupUserSettings() private void setupUserSettings()
{ {
AddUntilStep(() => songSelect.Carousel.SelectedBeatmap != null, "Song select has selection"); AddUntilStep("Song select has selection", () => songSelect.Carousel.SelectedBeatmap != null);
AddStep("Set default user settings", () => AddStep("Set default user settings", () =>
{ {
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { new OsuModNoFail() }); Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { new OsuModNoFail() });

View File

@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual
carousel.BeatmapSetsChanged = () => changed = true; carousel.BeatmapSetsChanged = () => changed = true;
carousel.BeatmapSets = beatmapSets; carousel.BeatmapSets = beatmapSets;
}); });
AddUntilStep(() => changed, "Wait for load"); AddUntilStep("Wait for load", () => changed);
} }
private void ensureRandomFetchSuccess() => private void ensureRandomFetchSuccess() =>
@ -214,7 +214,7 @@ namespace osu.Game.Tests.Visual
checkSelected(3, 2); checkSelected(3, 2);
AddStep("Un-filter (debounce)", () => carousel.Filter(new FilterCriteria())); AddStep("Un-filter (debounce)", () => carousel.Filter(new FilterCriteria()));
AddUntilStep(() => !carousel.PendingFilterTask, "Wait for debounce"); AddUntilStep("Wait for debounce", () => !carousel.PendingFilterTask);
checkVisibleItemCount(diff: false, count: set_count); checkVisibleItemCount(diff: false, count: set_count);
checkVisibleItemCount(diff: true, count: 3); checkVisibleItemCount(diff: true, count: 3);
@ -327,13 +327,13 @@ namespace osu.Game.Tests.Visual
AddStep("Remove first", () => carousel.RemoveBeatmapSet(carousel.BeatmapSets.First())); AddStep("Remove first", () => carousel.RemoveBeatmapSet(carousel.BeatmapSets.First()));
checkSelected(1); checkSelected(1);
AddUntilStep(() => AddUntilStep("Remove all", () =>
{ {
if (!carousel.BeatmapSets.Any()) return true; if (!carousel.BeatmapSets.Any()) return true;
carousel.RemoveBeatmapSet(carousel.BeatmapSets.Last()); carousel.RemoveBeatmapSet(carousel.BeatmapSets.Last());
return false; return false;
}, "Remove all"); });
checkNoSelection(); checkNoSelection();
} }

View File

@ -56,11 +56,11 @@ namespace osu.Game.Tests.Visual
// select part is redundant, but wait for load isn't // select part is redundant, but wait for load isn't
selectBeatmap(Beatmap.Value.Beatmap); selectBeatmap(Beatmap.Value.Beatmap);
AddWaitStep(3); AddWaitStep("wait for select", 3);
AddStep("hide", () => { infoWedge.State = Visibility.Hidden; }); AddStep("hide", () => { infoWedge.State = Visibility.Hidden; });
AddWaitStep(3); AddWaitStep("wait for hide", 3);
AddStep("show", () => { infoWedge.State = Visibility.Visible; }); AddStep("show", () => { infoWedge.State = Visibility.Visible; });
@ -135,7 +135,7 @@ namespace osu.Game.Tests.Visual
infoWedge.Beatmap = Beatmap.Value = b == null ? Beatmap.Default : new TestWorkingBeatmap(b); infoWedge.Beatmap = Beatmap.Value = b == null ? Beatmap.Default : new TestWorkingBeatmap(b);
}); });
AddUntilStep(() => infoWedge.Info != infoBefore, "wait for async load"); AddUntilStep("wait for async load", () => infoWedge.Info != infoBefore);
} }
private IBeatmap createTestBeatmap(RulesetInfo ruleset) private IBeatmap createTestBeatmap(RulesetInfo ruleset)

View File

@ -90,7 +90,7 @@ namespace osu.Game.Tests.Visual
AddStep("set second channel", () => channelTabControl.Current.Value = channelTabControl.Items.Skip(1).First()); AddStep("set second channel", () => channelTabControl.Current.Value = channelTabControl.Items.Skip(1).First());
AddAssert("selector tab is inactive", () => !channelTabControl.ChannelSelectorActive.Value); AddAssert("selector tab is inactive", () => !channelTabControl.ChannelSelectorActive.Value);
AddUntilStep(() => AddUntilStep("remove all channels", () =>
{ {
var first = channelTabControl.Items.First(); var first = channelTabControl.Items.First();
if (first.Name == "+") if (first.Name == "+")
@ -98,7 +98,7 @@ namespace osu.Game.Tests.Visual
channelTabControl.RemoveChannel(first); channelTabControl.RemoveChannel(first);
return false; return false;
}, "remove all channels"); });
AddAssert("selector tab is active", () => channelTabControl.ChannelSelectorActive.Value); AddAssert("selector tab is active", () => channelTabControl.ChannelSelectorActive.Value);
} }

View File

@ -159,7 +159,7 @@ namespace osu.Game.Tests.Visual
Scheduler.AddDelayed(() => newLine.Message = new DummyMessage(completeText ?? text), delay); Scheduler.AddDelayed(() => newLine.Message = new DummyMessage(completeText ?? text), delay);
}); });
AddUntilStep(() => textContainer.All(line => line.Message is DummyMessage), $"wait for msg #{echoCounter}"); AddUntilStep($"wait for msg #{echoCounter}", () => textContainer.All(line => line.Message is DummyMessage));
} }
} }

View File

@ -32,9 +32,9 @@ namespace osu.Game.Tests.Visual
var text = holdForMenuButton.Children.OfType<SpriteText>().First(); var text = holdForMenuButton.Children.OfType<SpriteText>().First();
AddStep("Trigger text fade in", () => InputManager.MoveMouseTo(holdForMenuButton)); AddStep("Trigger text fade in", () => InputManager.MoveMouseTo(holdForMenuButton));
AddUntilStep(() => text.IsPresent && !exitAction, "Text visible"); AddUntilStep("Text visible", () => text.IsPresent && !exitAction);
AddStep("Trigger text fade out", () => InputManager.MoveMouseTo(Vector2.One)); AddStep("Trigger text fade out", () => InputManager.MoveMouseTo(Vector2.One));
AddUntilStep(() => !text.IsPresent && !exitAction, "Text is not visible"); AddUntilStep("Text is not visible", () => !text.IsPresent && !exitAction);
AddStep("Trigger exit action", () => AddStep("Trigger exit action", () =>
{ {
@ -47,7 +47,7 @@ namespace osu.Game.Tests.Visual
AddAssert("action not triggered", () => !exitAction); AddAssert("action not triggered", () => !exitAction);
AddStep("Trigger exit action", () => InputManager.PressButton(MouseButton.Left)); AddStep("Trigger exit action", () => InputManager.PressButton(MouseButton.Left));
AddUntilStep(() => exitAction, $"{nameof(holdForMenuButton.Action)} was triggered"); AddUntilStep($"{nameof(holdForMenuButton.Action)} was triggered", () => exitAction);
} }
} }
} }

View File

@ -49,7 +49,7 @@ namespace osu.Game.Tests.Visual
AddStep("start confirming", () => overlay.Begin()); AddStep("start confirming", () => overlay.Begin());
AddUntilStep(() => fired, "wait until confirmed"); AddUntilStep("wait until confirmed", () => fired);
} }
private class TestHoldToConfirmOverlay : ExitConfirmOverlay private class TestHoldToConfirmOverlay : ExitConfirmOverlay

View File

@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual
{ {
AddStep("move mouse to top left", () => InputManager.MoveMouseTo(box1.ScreenSpaceDrawQuad.Centre)); AddStep("move mouse to top left", () => InputManager.MoveMouseTo(box1.ScreenSpaceDrawQuad.Centre));
AddUntilStep(() => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle, "Wait for all idle"); AddUntilStep("Wait for all idle", () => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle);
AddStep("nudge mouse", () => InputManager.MoveMouseTo(box1.ScreenSpaceDrawQuad.Centre + new Vector2(1))); AddStep("nudge mouse", () => InputManager.MoveMouseTo(box1.ScreenSpaceDrawQuad.Centre + new Vector2(1)));
@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual
AddAssert("check idle", () => !box3.IsIdle); AddAssert("check idle", () => !box3.IsIdle);
AddAssert("check idle", () => !box4.IsIdle); AddAssert("check idle", () => !box4.IsIdle);
AddUntilStep(() => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle, "Wait for all idle"); AddUntilStep("Wait for all idle", () => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle);
} }
[Test] [Test]
@ -96,13 +96,13 @@ namespace osu.Game.Tests.Visual
AddStep("move mouse", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre)); AddStep("move mouse", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre));
AddAssert("check not idle", () => !box1.IsIdle && !box2.IsIdle && !box3.IsIdle && !box4.IsIdle); AddAssert("check not idle", () => !box1.IsIdle && !box2.IsIdle && !box3.IsIdle && !box4.IsIdle);
AddUntilStep(() => box1.IsIdle, "Wait for idle"); AddUntilStep("Wait for idle", () => box1.IsIdle);
AddAssert("check not idle", () => !box2.IsIdle && !box3.IsIdle && !box4.IsIdle); AddAssert("check not idle", () => !box2.IsIdle && !box3.IsIdle && !box4.IsIdle);
AddUntilStep(() => box2.IsIdle, "Wait for idle"); AddUntilStep("Wait for idle", () => box2.IsIdle);
AddAssert("check not idle", () => !box3.IsIdle && !box4.IsIdle); AddAssert("check not idle", () => !box3.IsIdle && !box4.IsIdle);
AddUntilStep(() => box3.IsIdle, "Wait for idle"); AddUntilStep("Wait for idle", () => box3.IsIdle);
AddUntilStep(() => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle, "Wait for all idle"); AddUntilStep("Wait for all idle", () => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle);
} }
private class IdleTrackingBox : CompositeDrawable private class IdleTrackingBox : CompositeDrawable

View File

@ -25,30 +25,30 @@ namespace osu.Game.Tests.Visual
bool logoVisible = false; bool logoVisible = false;
AddStep("almost instant display", () => Child = loader = new TestLoader(250)); AddStep("almost instant display", () => Child = loader = new TestLoader(250));
AddUntilStep(() => AddUntilStep("loaded", () =>
{ {
logoVisible = loader.Logo?.Alpha > 0; logoVisible = loader.Logo?.Alpha > 0;
return loader.Logo != null && loader.ScreenLoaded; return loader.Logo != null && loader.ScreenLoaded;
}, "loaded"); });
AddAssert("logo not visible", () => !logoVisible); AddAssert("logo not visible", () => !logoVisible);
AddStep("short load", () => Child = loader = new TestLoader(800)); AddStep("short load", () => Child = loader = new TestLoader(800));
AddUntilStep(() => AddUntilStep("loaded", () =>
{ {
logoVisible = loader.Logo?.Alpha > 0; logoVisible = loader.Logo?.Alpha > 0;
return loader.Logo != null && loader.ScreenLoaded; return loader.Logo != null && loader.ScreenLoaded;
}, "loaded"); });
AddAssert("logo visible", () => logoVisible); AddAssert("logo visible", () => logoVisible);
AddUntilStep(() => loader.Logo?.Alpha == 0, "logo gone"); AddUntilStep("logo gone", () => loader.Logo?.Alpha == 0);
AddStep("longer load", () => Child = loader = new TestLoader(1400)); AddStep("longer load", () => Child = loader = new TestLoader(1400));
AddUntilStep(() => AddUntilStep("loaded", () =>
{ {
logoVisible = loader.Logo?.Alpha > 0; logoVisible = loader.Logo?.Alpha > 0;
return loader.Logo != null && loader.ScreenLoaded; return loader.Logo != null && loader.ScreenLoaded;
}, "loaded"); });
AddAssert("logo visible", () => logoVisible); AddAssert("logo visible", () => logoVisible);
AddUntilStep(() => loader.Logo?.Alpha == 0, "logo gone"); AddUntilStep("logo gone", () => loader.Logo?.Alpha == 0);
} }
private class TestLoader : Loader private class TestLoader : Loader

View File

@ -111,7 +111,7 @@ namespace osu.Game.Tests.Visual
settings.ApplyButton.Action.Invoke(); settings.ApplyButton.Action.Invoke();
}); });
AddUntilStep(() => !settings.ErrorText.IsPresent, "error not displayed"); AddUntilStep("error not displayed", () => !settings.ErrorText.IsPresent);
} }
private class TestRoomSettings : MatchSettingsOverlay private class TestRoomSettings : MatchSettingsOverlay

View File

@ -208,22 +208,22 @@ namespace osu.Game.Tests.Visual
{ {
checkLabelColor(Color4.White); checkLabelColor(Color4.White);
selectNext(mod); selectNext(mod);
AddWaitStep(1, "wait for changing colour"); AddWaitStep("wait for changing colour", 1);
checkLabelColor(colour); checkLabelColor(colour);
selectPrevious(mod); selectPrevious(mod);
AddWaitStep(1, "wait for changing colour"); AddWaitStep("wait for changing colour", 1);
checkLabelColor(Color4.White); checkLabelColor(Color4.White);
} }
private void testRankedText(Mod mod) private void testRankedText(Mod mod)
{ {
AddWaitStep(1, "wait for fade"); AddWaitStep("wait for fade", 1);
AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0); AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0);
selectNext(mod); selectNext(mod);
AddWaitStep(1, "wait for fade"); AddWaitStep("wait for fade", 1);
AddAssert("check for unranked", () => modSelect.UnrankedLabel.Alpha != 0); AddAssert("check for unranked", () => modSelect.UnrankedLabel.Alpha != 0);
selectPrevious(mod); selectPrevious(mod);
AddWaitStep(1, "wait for fade"); AddWaitStep("wait for fade", 1);
AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0); AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0);
} }

View File

@ -60,7 +60,7 @@ namespace osu.Game.Tests.Visual
setState(Visibility.Hidden); setState(Visibility.Hidden);
AddRepeatStep(@"add many simple", sendManyNotifications, 3); AddRepeatStep(@"add many simple", sendManyNotifications, 3);
AddWaitStep(5); AddWaitStep("wait some", 5);
checkProgressingCount(0); checkProgressingCount(0);
@ -70,7 +70,7 @@ namespace osu.Game.Tests.Visual
AddAssert("Displayed count is 33", () => manager.UnreadCount.Value == 33); AddAssert("Displayed count is 33", () => manager.UnreadCount.Value == 33);
AddWaitStep(10); AddWaitStep("wait some", 10);
checkProgressingCount(0); checkProgressingCount(0);

View File

@ -112,10 +112,10 @@ namespace osu.Game.Tests.Visual
createSongSelect(); createSongSelect();
AddAssert("dummy selected", () => songSelect.CurrentBeatmap == defaultBeatmap); AddAssert("dummy selected", () => songSelect.CurrentBeatmap == defaultBeatmap);
AddUntilStep(() => songSelect.CurrentBeatmapDetailsBeatmap == defaultBeatmap, "dummy shown on wedge"); AddUntilStep("dummy shown on wedge", () => songSelect.CurrentBeatmapDetailsBeatmap == defaultBeatmap);
addManyTestMaps(); addManyTestMaps();
AddWaitStep(3); AddWaitStep("wait for select", 3);
AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap);
} }
@ -125,7 +125,7 @@ namespace osu.Game.Tests.Visual
{ {
createSongSelect(); createSongSelect();
addManyTestMaps(); addManyTestMaps();
AddWaitStep(3); AddWaitStep("wait for add", 3);
AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap);
@ -142,7 +142,7 @@ namespace osu.Game.Tests.Visual
createSongSelect(); createSongSelect();
changeRuleset(2); changeRuleset(2);
importForRuleset(0); importForRuleset(0);
AddUntilStep(() => songSelect.Carousel.SelectedBeatmap == null, "no selection"); AddUntilStep("no selection", () => songSelect.Carousel.SelectedBeatmap == null);
} }
[Test] [Test]
@ -152,13 +152,13 @@ namespace osu.Game.Tests.Visual
changeRuleset(2); changeRuleset(2);
importForRuleset(2); importForRuleset(2);
importForRuleset(1); importForRuleset(1);
AddUntilStep(() => songSelect.Carousel.SelectedBeatmap.RulesetID == 2, "has selection"); AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap.RulesetID == 2);
changeRuleset(1); changeRuleset(1);
AddUntilStep(() => songSelect.Carousel.SelectedBeatmap.RulesetID == 1, "has selection"); AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap.RulesetID == 1);
changeRuleset(0); changeRuleset(0);
AddUntilStep(() => songSelect.Carousel.SelectedBeatmap == null, "no selection"); AddUntilStep("no selection", () => songSelect.Carousel.SelectedBeatmap == null);
} }
[Test] [Test]
@ -196,7 +196,7 @@ namespace osu.Game.Tests.Visual
{ {
createSongSelect(); createSongSelect();
addManyTestMaps(); addManyTestMaps();
AddUntilStep(() => songSelect.Carousel.SelectedBeatmap != null, "has selection"); AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap != null);
bool startRequested = false; bool startRequested = false;
@ -225,7 +225,7 @@ namespace osu.Game.Tests.Visual
private void createSongSelect() private void createSongSelect()
{ {
AddStep("create song select", () => LoadScreen(songSelect = new TestSongSelect())); AddStep("create song select", () => LoadScreen(songSelect = new TestSongSelect()));
AddUntilStep(() => songSelect.IsCurrentScreen(), "wait for present"); AddUntilStep("wait for present", () => songSelect.IsCurrentScreen());
} }
private void addManyTestMaps() private void addManyTestMaps()

View File

@ -37,15 +37,15 @@ namespace osu.Game.Tests.Visual
AllowResults = false, AllowResults = false,
}))); })));
AddUntilStep(() => loader.IsCurrentScreen(), "wait for current"); AddUntilStep("wait for current", () => loader.IsCurrentScreen());
AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre)); AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre));
AddUntilStep(() => !loader.IsCurrentScreen(), "wait for no longer current"); AddUntilStep("wait for no longer current", () => !loader.IsCurrentScreen());
AddStep("exit loader", () => loader.Exit()); AddStep("exit loader", () => loader.Exit());
AddUntilStep(() => !loader.IsAlive, "wait for no longer alive"); AddUntilStep("wait for no longer alive", () => !loader.IsAlive);
AddStep("load slow dummy beatmap", () => AddStep("load slow dummy beatmap", () =>
{ {
@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual
Scheduler.AddDelayed(() => slow.Ready = true, 5000); Scheduler.AddDelayed(() => slow.Ready = true, 5000);
}); });
AddUntilStep(() => !loader.IsCurrentScreen(), "wait for no longer current"); AddUntilStep("wait for no longer current", () => !loader.IsCurrentScreen());
} }
protected class SlowLoadPlayer : Player protected class SlowLoadPlayer : Player

View File

@ -24,8 +24,8 @@ namespace osu.Game.Tests.Visual
protected override void AddCheckSteps(Func<Player> player) protected override void AddCheckSteps(Func<Player> player)
{ {
base.AddCheckSteps(player); base.AddCheckSteps(player);
AddUntilStep(() => ((ScoreAccessibleReplayPlayer)player()).ScoreProcessor.TotalScore.Value > 0, "score above zero"); AddUntilStep("score above zero", () => ((ScoreAccessibleReplayPlayer)player()).ScoreProcessor.TotalScore.Value > 0);
AddUntilStep(() => ((ScoreAccessibleReplayPlayer)player()).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0), "key counter counted keys"); AddUntilStep("key counter counted keys", () => ((ScoreAccessibleReplayPlayer)player()).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0));
} }
private class ScoreAccessibleReplayPlayer : ReplayPlayer private class ScoreAccessibleReplayPlayer : ReplayPlayer

View File

@ -74,7 +74,7 @@ namespace osu.Game.Tests.Visual
} }
private void pushNext() => AddStep(@"push next screen", () => ((TestScreen)screenStack.CurrentScreen).PushNext()); private void pushNext() => AddStep(@"push next screen", () => ((TestScreen)screenStack.CurrentScreen).PushNext());
private void waitForCurrent() => AddUntilStep(() => screenStack.CurrentScreen.IsCurrentScreen(), "current screen"); private void waitForCurrent() => AddUntilStep("current screen", () => screenStack.CurrentScreen.IsCurrentScreen());
private abstract class TestScreen : OsuScreen private abstract class TestScreen : OsuScreen
{ {

View File

@ -46,23 +46,23 @@ namespace osu.Game.Tests.Visual
Origin = Anchor.TopLeft, Origin = Anchor.TopLeft,
}); });
AddWaitStep(5); AddWaitStep("wait some", 5);
AddAssert("ensure not created", () => graph.CreationCount == 0); AddAssert("ensure not created", () => graph.CreationCount == 0);
AddStep("display values", displayNewValues); AddStep("display values", displayNewValues);
AddWaitStep(5); AddWaitStep("wait some", 5);
AddUntilStep(() => graph.CreationCount == 1, "wait for creation count"); AddUntilStep("wait for creation count", () => graph.CreationCount == 1);
AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking); AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking);
AddWaitStep(5); AddWaitStep("wait some", 5);
AddUntilStep(() => graph.CreationCount == 1, "wait for creation count"); AddUntilStep("wait for creation count", () => graph.CreationCount == 1);
AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking); AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking);
AddWaitStep(5); AddWaitStep("wait some", 5);
AddUntilStep(() => graph.CreationCount == 1, "wait for creation count"); AddUntilStep("wait for creation count", () => graph.CreationCount == 1);
AddRepeatStep("New Values", displayNewValues, 5); AddRepeatStep("New Values", displayNewValues, 5);
AddWaitStep(5); AddWaitStep("wait some", 5);
AddAssert("ensure debounced", () => graph.CreationCount == 2); AddAssert("ensure debounced", () => graph.CreationCount == 2);
} }

View File

@ -36,18 +36,18 @@ namespace osu.Game.Tests.Visual
api.Queue(req); api.Queue(req);
AddStep("load null beatmap", () => beatmapBindable.Value = null); AddStep("load null beatmap", () => beatmapBindable.Value = null);
AddUntilStep(() => backgroundSprite.ChildCount == 1, "wait for cleanup..."); AddUntilStep("wait for cleanup...", () => backgroundSprite.ChildCount == 1);
AddStep("load imported beatmap", () => beatmapBindable.Value = imported.Beatmaps.First()); AddStep("load imported beatmap", () => beatmapBindable.Value = imported.Beatmaps.First());
AddUntilStep(() => backgroundSprite.ChildCount == 1, "wait for cleanup..."); AddUntilStep("wait for cleanup...", () => backgroundSprite.ChildCount == 1);
if (api.IsLoggedIn) if (api.IsLoggedIn)
{ {
AddUntilStep(() => req.Result != null, "wait for api response"); AddUntilStep("wait for api response", () => req.Result != null);
AddStep("load online beatmap", () => beatmapBindable.Value = new BeatmapInfo AddStep("load online beatmap", () => beatmapBindable.Value = new BeatmapInfo
{ {
BeatmapSet = req.Result?.ToBeatmapSet(rulesets) BeatmapSet = req.Result?.ToBeatmapSet(rulesets)
}); });
AddUntilStep(() => backgroundSprite.ChildCount == 1, "wait for cleanup..."); AddUntilStep("wait for cleanup...", () => backgroundSprite.ChildCount == 1);
} }
else else
{ {

View File

@ -108,7 +108,7 @@ namespace osu.Game.Tests.Visual
private void checkSupporterTag(bool isSupporter) private void checkSupporterTag(bool isSupporter)
{ {
AddUntilStep(() => profile.Header.User != null, "wait for load"); AddUntilStep("wait for load", () => profile.Header.User != null);
if (isSupporter) if (isSupporter)
AddAssert("is supporter", () => profile.Header.SupporterTag.Alpha == 1); AddAssert("is supporter", () => profile.Header.SupporterTag.Alpha == 1);
else else

View File

@ -105,11 +105,14 @@ namespace osu.Game.Beatmaps
validateOnlineIds(beatmapSet); validateOnlineIds(beatmapSet);
foreach (BeatmapInfo b in beatmapSet.Beatmaps) foreach (BeatmapInfo b in beatmapSet.Beatmaps)
fetchAndPopulateOnlineValues(b, beatmapSet.Beatmaps); fetchAndPopulateOnlineValues(b);
} }
protected override void PreImport(BeatmapSetInfo beatmapSet) protected override void PreImport(BeatmapSetInfo beatmapSet)
{ {
if (beatmapSet.Beatmaps.Any(b => b.BaseDifficulty == null))
throw new InvalidOperationException($"Cannot import {nameof(BeatmapInfo)} with null {nameof(BeatmapInfo.BaseDifficulty)}.");
// check if a set already exists with the same online id, delete if it does. // check if a set already exists with the same online id, delete if it does.
if (beatmapSet.OnlineBeatmapSetID != null) if (beatmapSet.OnlineBeatmapSetID != null)
{ {
@ -382,7 +385,7 @@ namespace osu.Game.Beatmaps
/// <param name="otherBeatmaps">The other beatmaps contained within this set.</param> /// <param name="otherBeatmaps">The other beatmaps contained within this set.</param>
/// <param name="force">Whether to re-query if the provided beatmap already has populated values.</param> /// <param name="force">Whether to re-query if the provided beatmap already has populated values.</param>
/// <returns>True if population was successful.</returns> /// <returns>True if population was successful.</returns>
private bool fetchAndPopulateOnlineValues(BeatmapInfo beatmap, IEnumerable<BeatmapInfo> otherBeatmaps, bool force = false) private bool fetchAndPopulateOnlineValues(BeatmapInfo beatmap, bool force = false)
{ {
if (api?.State != APIState.Online) if (api?.State != APIState.Online)
return false; return false;
@ -405,13 +408,6 @@ namespace osu.Game.Beatmaps
beatmap.Status = res.Status; beatmap.Status = res.Status;
beatmap.BeatmapSet.Status = res.BeatmapSet.Status; beatmap.BeatmapSet.Status = res.BeatmapSet.Status;
if (otherBeatmaps.Any(b => b.OnlineBeatmapID == res.OnlineBeatmapID))
{
Logger.Log("Another beatmap in the same set already mapped to this ID. We'll skip adding it this time.", LoggingTarget.Database);
return false;
}
beatmap.BeatmapSet.OnlineBeatmapSetID = res.OnlineBeatmapSetID; beatmap.BeatmapSet.OnlineBeatmapSetID = res.OnlineBeatmapSetID;
beatmap.OnlineBeatmapID = res.OnlineBeatmapID; beatmap.OnlineBeatmapID = res.OnlineBeatmapID;

View File

@ -11,6 +11,7 @@ namespace osu.Game.Screens
public class BackgroundScreenStack : ScreenStack public class BackgroundScreenStack : ScreenStack
{ {
public BackgroundScreenStack() public BackgroundScreenStack()
: base(false)
{ {
Scale = new Vector2(1.06f); Scale = new Vector2(1.06f);
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System.Threading;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -26,7 +27,24 @@ namespace osu.Game.Screens.Backgrounds
protected virtual UserDimContainer CreateFadeContainer() => new UserDimContainer { RelativeSizeAxes = Axes.Both }; protected virtual UserDimContainer CreateFadeContainer() => new UserDimContainer { RelativeSizeAxes = Axes.Both };
public virtual WorkingBeatmap Beatmap public BackgroundScreenBeatmap(WorkingBeatmap beatmap = null)
{
Beatmap = beatmap;
InternalChild = fadeContainer = CreateFadeContainer();
fadeContainer.EnableUserDim.BindTo(EnableUserDim);
}
[BackgroundDependencyLoader]
private void load()
{
var background = new BeatmapBackground(beatmap);
LoadComponent(background);
switchBackground(background);
}
private CancellationTokenSource cancellationSource;
public WorkingBeatmap Beatmap
{ {
get => beatmap; get => beatmap;
set set
@ -38,54 +56,52 @@ namespace osu.Game.Screens.Backgrounds
Schedule(() => Schedule(() =>
{ {
LoadComponentAsync(new BeatmapBackground(beatmap), b => Schedule(() => if ((Background as BeatmapBackground)?.Beatmap == beatmap)
{ return;
float newDepth = 0;
if (Background != null)
{
newDepth = Background.Depth + 1;
Background.FinishTransforms();
Background.FadeOut(250);
Background.Expire();
}
b.Depth = newDepth; cancellationSource?.Cancel();
fadeContainer.Add(Background = b); LoadComponentAsync(new BeatmapBackground(beatmap), switchBackground, (cancellationSource = new CancellationTokenSource()).Token);
Background.BlurSigma = BlurTarget;
StoryboardReplacesBackground.BindTo(fadeContainer.StoryboardReplacesBackground);
}));
}); });
} }
} }
public BackgroundScreenBeatmap(WorkingBeatmap beatmap = null) private void switchBackground(BeatmapBackground b)
{ {
Beatmap = beatmap; float newDepth = 0;
InternalChild = fadeContainer = CreateFadeContainer(); if (Background != null)
fadeContainer.EnableUserDim.BindTo(EnableUserDim); {
newDepth = Background.Depth + 1;
Background.FinishTransforms();
Background.FadeOut(250);
Background.Expire();
}
b.Depth = newDepth;
fadeContainer.Add(Background = b);
Background.BlurSigma = BlurTarget;
StoryboardReplacesBackground.BindTo(fadeContainer.StoryboardReplacesBackground);
} }
public override bool Equals(BackgroundScreen other) public override bool Equals(BackgroundScreen other)
{ {
var otherBeatmapBackground = other as BackgroundScreenBeatmap; if (!(other is BackgroundScreenBeatmap otherBeatmapBackground)) return false;
if (otherBeatmapBackground == null) return false;
return base.Equals(other) && beatmap == otherBeatmapBackground.Beatmap; return base.Equals(other) && beatmap == otherBeatmapBackground.Beatmap;
} }
protected class BeatmapBackground : Background protected class BeatmapBackground : Background
{ {
private readonly WorkingBeatmap beatmap; public readonly WorkingBeatmap Beatmap;
public BeatmapBackground(WorkingBeatmap beatmap) public BeatmapBackground(WorkingBeatmap beatmap)
{ {
this.beatmap = beatmap; Beatmap = beatmap;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(TextureStore textures) private void load(TextureStore textures)
{ {
Sprite.Texture = beatmap?.Background ?? textures.Get(@"Backgrounds/bg1"); Sprite.Texture = Beatmap?.Background ?? textures.Get(@"Backgrounds/bg1");
} }
} }
} }

View File

@ -34,7 +34,7 @@ namespace osu.Game.Screens.Backgrounds
currentDisplay = RNG.Next(0, background_count); currentDisplay = RNG.Next(0, background_count);
Next(); display(createBackground());
} }
private void display(Background newBackground) private void display(Background newBackground)
@ -51,19 +51,21 @@ namespace osu.Game.Screens.Backgrounds
public void Next() public void Next()
{ {
nextTask?.Cancel(); nextTask?.Cancel();
nextTask = Scheduler.AddDelayed(() => nextTask = Scheduler.AddDelayed(() => { LoadComponentAsync(createBackground(), display); }, 100);
{ }
Background background;
if (user.Value?.IsSupporter ?? false) private Background createBackground()
background = new SkinnedBackground(skin.Value, backgroundName); {
else Background background;
background = new Background(backgroundName);
background.Depth = currentDisplay; if (user.Value?.IsSupporter ?? false)
background = new SkinnedBackground(skin.Value, backgroundName);
else
background = new Background(backgroundName);
LoadComponentAsync(background, display); background.Depth = currentDisplay;
}, 100);
return background;
} }
private class SkinnedBackground : Background private class SkinnedBackground : Background

View File

@ -14,7 +14,7 @@ namespace osu.Game.Screens
protected Vector2 BlurTarget; protected Vector2 BlurTarget;
public TransformSequence<Background> BlurTo(Vector2 sigma, double duration, Easing easing = Easing.None) public TransformSequence<Background> BlurTo(Vector2 sigma, double duration = 0, Easing easing = Easing.None)
{ {
BlurTarget = sigma; BlurTarget = sigma;
return Background?.BlurTo(BlurTarget, duration, easing); return Background?.BlurTo(BlurTarget, duration, easing);

View File

@ -40,7 +40,9 @@ namespace osu.Game.Screens.Menu
[Resolved] [Resolved]
private GameHost host { get; set; } private GameHost host { get; set; }
protected override BackgroundScreen CreateBackground() => new BackgroundScreenDefault(); private BackgroundScreenDefault background;
protected override BackgroundScreen CreateBackground() => background;
[BackgroundDependencyLoader(true)] [BackgroundDependencyLoader(true)]
private void load(OsuGame game = null) private void load(OsuGame game = null)
@ -89,6 +91,7 @@ namespace osu.Game.Screens.Menu
buttons.OnDirect = game.ToggleDirect; buttons.OnDirect = game.ToggleDirect;
} }
LoadComponentAsync(background = new BackgroundScreenDefault());
preloadSongSelect(); preloadSongSelect();
} }

View File

@ -55,7 +55,7 @@ namespace osu.Game.Screens.Play
/// Called when background elements require updates, usually due to a user changing a setting. /// Called when background elements require updates, usually due to a user changing a setting.
/// </summary> /// </summary>
/// <param name="userChange"></param> /// <param name="userChange"></param>
protected virtual void UpdateBackgroundElements() protected void UpdateBackgroundElements()
{ {
if (!this.IsCurrentScreen()) return; if (!this.IsCurrentScreen()) return;

View File

@ -1,4 +1,4 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -61,7 +61,12 @@ namespace osu.Game.Screens.Select
/// </summary> /// </summary>
protected readonly Container FooterPanels; protected readonly Container FooterPanels;
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(); protected override BackgroundScreen CreateBackground()
{
var background = new BackgroundScreenBeatmap();
background.BlurTo(background_blur);
return background;
}
protected readonly BeatmapCarousel Carousel; protected readonly BeatmapCarousel Carousel;
private readonly BeatmapInfoWedge beatmapInfoWedge; private readonly BeatmapInfoWedge beatmapInfoWedge;

View File

@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual
AddStep(r.Name, () => p = loadPlayerFor(r)); AddStep(r.Name, () => p = loadPlayerFor(r));
AddCheckSteps(() => p); AddCheckSteps(() => p);
AddUntilStep(() => AddUntilStep("no leaked beatmaps", () =>
{ {
p = null; p = null;
@ -65,9 +65,9 @@ namespace osu.Game.Tests.Visual
workingWeakReferences.ForEachAlive(_ => count++); workingWeakReferences.ForEachAlive(_ => count++);
return count == 1; return count == 1;
}, "no leaked beatmaps"); });
AddUntilStep(() => AddUntilStep("no leaked players", () =>
{ {
GC.Collect(); GC.Collect();
GC.WaitForPendingFinalizers(); GC.WaitForPendingFinalizers();
@ -75,14 +75,14 @@ namespace osu.Game.Tests.Visual
playerWeakReferences.ForEachAlive(_ => count++); playerWeakReferences.ForEachAlive(_ => count++);
return count == 1; return count == 1;
}, "no leaked players"); });
} }
} }
} }
protected virtual void AddCheckSteps(Func<Player> player) protected virtual void AddCheckSteps(Func<Player> player)
{ {
AddUntilStep(() => player().IsLoaded, "player loaded"); AddUntilStep("player loaded", () => player().IsLoaded);
} }
protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo); protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo);

View File

@ -16,7 +16,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.128.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.128.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.315.0" /> <PackageReference Include="ppy.osu.Framework" Version="2019.319.0" />
<PackageReference Include="SharpCompress" Version="0.22.0" /> <PackageReference Include="SharpCompress" Version="0.22.0" />
<PackageReference Include="NUnit" Version="3.11.0" /> <PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />

View File

@ -105,8 +105,8 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.128.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.128.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.315.0" /> <PackageReference Include="ppy.osu.Framework" Version="2019.319.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.315.0" /> <PackageReference Include="ppy.osu.Framework.iOS" Version="2019.319.0" />
<PackageReference Include="SharpCompress" Version="0.22.0" /> <PackageReference Include="SharpCompress" Version="0.22.0" />
<PackageReference Include="NUnit" Version="3.11.0" /> <PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />