mirror of
https://github.com/ppy/osu.git
synced 2025-03-06 04:23:21 +08:00
Merge pull request #11017 from peppy/fix-song-select-temporary-selection-loss
Fix current beatmap temporarily becoming empty during ruleset change
This commit is contained in:
commit
1cea39ed55
@ -643,6 +643,55 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
AddAssert("Selected beatmap correct", () => songSelect.Carousel.SelectedBeatmap == filteredBeatmap);
|
AddAssert("Selected beatmap correct", () => songSelect.Carousel.SelectedBeatmap == filteredBeatmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestChangingRulesetOnMultiRulesetBeatmap()
|
||||||
|
{
|
||||||
|
int changeCount = 0;
|
||||||
|
|
||||||
|
AddStep("change convert setting", () => config.Set(OsuSetting.ShowConvertedBeatmaps, false));
|
||||||
|
AddStep("bind beatmap changed", () =>
|
||||||
|
{
|
||||||
|
Beatmap.ValueChanged += onChange;
|
||||||
|
changeCount = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
changeRuleset(0);
|
||||||
|
|
||||||
|
createSongSelect();
|
||||||
|
|
||||||
|
AddStep("import multi-ruleset map", () =>
|
||||||
|
{
|
||||||
|
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.ID != 2).ToArray();
|
||||||
|
manager.Import(createTestBeatmapSet(usableRulesets)).Wait();
|
||||||
|
});
|
||||||
|
|
||||||
|
int previousSetID = 0;
|
||||||
|
|
||||||
|
AddUntilStep("wait for selection", () => !Beatmap.IsDefault);
|
||||||
|
|
||||||
|
AddStep("record set ID", () => previousSetID = Beatmap.Value.BeatmapSetInfo.ID);
|
||||||
|
AddAssert("selection changed once", () => changeCount == 1);
|
||||||
|
|
||||||
|
AddAssert("Check ruleset is osu!", () => Ruleset.Value.ID == 0);
|
||||||
|
|
||||||
|
changeRuleset(3);
|
||||||
|
|
||||||
|
AddUntilStep("Check ruleset changed to mania", () => Ruleset.Value.ID == 3);
|
||||||
|
|
||||||
|
AddUntilStep("selection changed", () => changeCount > 1);
|
||||||
|
|
||||||
|
AddAssert("Selected beatmap still same set", () => Beatmap.Value.BeatmapSetInfo.ID == previousSetID);
|
||||||
|
AddAssert("Selected beatmap is mania", () => Beatmap.Value.BeatmapInfo.Ruleset.ID == 3);
|
||||||
|
|
||||||
|
AddAssert("selection changed only fired twice", () => changeCount == 2);
|
||||||
|
|
||||||
|
AddStep("unbind beatmap changed", () => Beatmap.ValueChanged -= onChange);
|
||||||
|
AddStep("change convert setting", () => config.Set(OsuSetting.ShowConvertedBeatmaps, true));
|
||||||
|
|
||||||
|
// ReSharper disable once AccessToModifiedClosure
|
||||||
|
void onChange(ValueChangedEvent<WorkingBeatmap> valueChangedEvent) => changeCount++;
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestDifficultyIconSelectingForDifferentRuleset()
|
public void TestDifficultyIconSelectingForDifferentRuleset()
|
||||||
{
|
{
|
||||||
|
@ -376,7 +376,7 @@ namespace osu.Game.Screens.Select
|
|||||||
if (selectionChangedDebounce?.Completed == false)
|
if (selectionChangedDebounce?.Completed == false)
|
||||||
{
|
{
|
||||||
selectionChangedDebounce.RunTask();
|
selectionChangedDebounce.RunTask();
|
||||||
selectionChangedDebounce.Cancel(); // cancel the already scheduled task.
|
selectionChangedDebounce?.Cancel(); // cancel the already scheduled task.
|
||||||
selectionChangedDebounce = null;
|
selectionChangedDebounce = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,19 +465,30 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
|
// clear pending task immediately to track any potential nested debounce operation.
|
||||||
|
selectionChangedDebounce = null;
|
||||||
|
|
||||||
Logger.Log($"updating selection with beatmap:{beatmap?.ID.ToString() ?? "null"} ruleset:{ruleset?.ID.ToString() ?? "null"}");
|
Logger.Log($"updating selection with beatmap:{beatmap?.ID.ToString() ?? "null"} ruleset:{ruleset?.ID.ToString() ?? "null"}");
|
||||||
|
|
||||||
if (transferRulesetValue())
|
if (transferRulesetValue())
|
||||||
{
|
{
|
||||||
Mods.Value = Array.Empty<Mod>();
|
Mods.Value = Array.Empty<Mod>();
|
||||||
|
|
||||||
// transferRulesetValue() may trigger a refilter. If the current selection does not match the new ruleset, we want to switch away from it.
|
// transferRulesetValue() may trigger a re-filter. If the current selection does not match the new ruleset, we want to switch away from it.
|
||||||
// The default logic on WorkingBeatmap change is to switch to a matching ruleset (see workingBeatmapChanged()), but we don't want that here.
|
// The default logic on WorkingBeatmap change is to switch to a matching ruleset (see workingBeatmapChanged()), but we don't want that here.
|
||||||
// We perform an early selection attempt and clear out the beatmap selection to avoid a second ruleset change (revert).
|
// We perform an early selection attempt and clear out the beatmap selection to avoid a second ruleset change (revert).
|
||||||
if (beatmap != null && !Carousel.SelectBeatmap(beatmap, false))
|
if (beatmap != null && !Carousel.SelectBeatmap(beatmap, false))
|
||||||
beatmap = null;
|
beatmap = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selectionChangedDebounce != null)
|
||||||
|
{
|
||||||
|
// a new nested operation was started; switch to it for further selection.
|
||||||
|
// this avoids having two separate debounces trigger from the same source.
|
||||||
|
selectionChangedDebounce.RunTask();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// We may be arriving here due to another component changing the bindable Beatmap.
|
// We may be arriving here due to another component changing the bindable Beatmap.
|
||||||
// In these cases, the other component has already loaded the beatmap, so we don't need to do so again.
|
// In these cases, the other component has already loaded the beatmap, so we don't need to do so again.
|
||||||
if (!EqualityComparer<BeatmapInfo>.Default.Equals(beatmap, Beatmap.Value.BeatmapInfo))
|
if (!EqualityComparer<BeatmapInfo>.Default.Equals(beatmap, Beatmap.Value.BeatmapInfo))
|
||||||
|
Loading…
Reference in New Issue
Block a user