mirror of
https://github.com/ppy/osu.git
synced 2025-02-15 20:05:29 +08:00
Merge pull request #18126 from bdach/mod-overlay/fix-broken-mod-reference-logic
Fix several issues with new mod select reference replacement logic
This commit is contained in:
commit
2dd9899cd7
@ -6,24 +6,19 @@ using NUnit.Framework;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Overlays.Mods;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Screens.OnlinePlay;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public class TestSceneFreeModSelectScreen : MultiplayerTestScene
|
||||
{
|
||||
private FreeModSelectScreen freeModSelectScreen;
|
||||
|
||||
[Test]
|
||||
public void TestFreeModSelect()
|
||||
{
|
||||
FreeModSelectScreen freeModSelectScreen = null;
|
||||
|
||||
AddStep("create free mod select screen", () => Child = freeModSelectScreen = new FreeModSelectScreen
|
||||
{
|
||||
State = { Value = Visibility.Visible }
|
||||
});
|
||||
AddUntilStep("all column content loaded",
|
||||
() => freeModSelectScreen.ChildrenOfType<ModColumn>().Any()
|
||||
&& freeModSelectScreen.ChildrenOfType<ModColumn>().All(column => column.IsLoaded && column.ItemsLoaded));
|
||||
createFreeModSelect();
|
||||
|
||||
AddUntilStep("all visible mods are playable",
|
||||
() => this.ChildrenOfType<ModPanel>()
|
||||
@ -36,5 +31,26 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
freeModSelectScreen.State.Value = visible ? Visibility.Visible : Visibility.Hidden;
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCustomisationNotAvailable()
|
||||
{
|
||||
createFreeModSelect();
|
||||
|
||||
AddStep("select difficulty adjust", () => freeModSelectScreen.SelectedMods.Value = new[] { new OsuModDifficultyAdjust() });
|
||||
AddWaitStep("wait some", 3);
|
||||
AddAssert("customisation area not expanded", () => this.ChildrenOfType<ModSettingsArea>().Single().Height == 0);
|
||||
}
|
||||
|
||||
private void createFreeModSelect()
|
||||
{
|
||||
AddStep("create free mod select screen", () => Child = freeModSelectScreen = new FreeModSelectScreen
|
||||
{
|
||||
State = { Value = Visibility.Visible }
|
||||
});
|
||||
AddUntilStep("all column content loaded",
|
||||
() => freeModSelectScreen.ChildrenOfType<ModColumn>().Any()
|
||||
&& freeModSelectScreen.ChildrenOfType<ModColumn>().All(column => column.IsLoaded && column.ItemsLoaded));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ namespace osu.Game.Overlays.Mods
|
||||
set
|
||||
{
|
||||
filter = value;
|
||||
updateFilter();
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,9 +292,7 @@ namespace osu.Game.Overlays.Mods
|
||||
{
|
||||
panelFlow.ChildrenEnumerable = loaded;
|
||||
|
||||
updateActiveState();
|
||||
updateToggleAllState();
|
||||
updateFilter();
|
||||
updateState();
|
||||
|
||||
foreach (var panel in panelFlow)
|
||||
{
|
||||
@ -308,10 +306,19 @@ namespace osu.Game.Overlays.Mods
|
||||
});
|
||||
}
|
||||
|
||||
private void updateActiveState()
|
||||
private void updateState()
|
||||
{
|
||||
foreach (var panel in panelFlow)
|
||||
{
|
||||
panel.Active.Value = SelectedMods.Contains(panel.Mod);
|
||||
panel.ApplyFilter(Filter);
|
||||
}
|
||||
|
||||
if (toggleAllCheckbox != null && !SelectionAnimationRunning)
|
||||
{
|
||||
toggleAllCheckbox.Alpha = panelFlow.Any(panel => !panel.Filtered.Value) ? 1 : 0;
|
||||
toggleAllCheckbox.Current.Value = panelFlow.Where(panel => !panel.Filtered.Value).All(panel => panel.Active.Value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -323,14 +330,15 @@ namespace osu.Game.Overlays.Mods
|
||||
|
||||
private void panelStateChanged(ModPanel panel)
|
||||
{
|
||||
updateToggleAllState();
|
||||
if (externalSelectionUpdateInProgress)
|
||||
return;
|
||||
|
||||
var newSelectedMods = panel.Active.Value
|
||||
? SelectedMods.Append(panel.Mod)
|
||||
: SelectedMods.Except(panel.Mod.Yield());
|
||||
|
||||
SelectedMods = newSelectedMods.ToArray();
|
||||
if (!externalSelectionUpdateInProgress)
|
||||
updateState();
|
||||
SelectionChangedByUser?.Invoke();
|
||||
}
|
||||
|
||||
@ -364,7 +372,7 @@ namespace osu.Game.Overlays.Mods
|
||||
}
|
||||
|
||||
SelectedMods = newSelection;
|
||||
updateActiveState();
|
||||
updateState();
|
||||
|
||||
externalSelectionUpdateInProgress = false;
|
||||
}
|
||||
@ -403,15 +411,6 @@ namespace osu.Game.Overlays.Mods
|
||||
}
|
||||
}
|
||||
|
||||
private void updateToggleAllState()
|
||||
{
|
||||
if (toggleAllCheckbox != null && !SelectionAnimationRunning)
|
||||
{
|
||||
toggleAllCheckbox.Alpha = panelFlow.Any(panel => !panel.Filtered.Value) ? 1 : 0;
|
||||
toggleAllCheckbox.Current.Value = panelFlow.Where(panel => !panel.Filtered.Value).All(panel => panel.Active.Value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects all mods.
|
||||
/// </summary>
|
||||
@ -507,18 +506,6 @@ namespace osu.Game.Overlays.Mods
|
||||
|
||||
#endregion
|
||||
|
||||
#region Filtering support
|
||||
|
||||
private void updateFilter()
|
||||
{
|
||||
foreach (var modPanel in panelFlow)
|
||||
modPanel.ApplyFilter(Filter);
|
||||
|
||||
updateToggleAllState();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Keyboard selection support
|
||||
|
||||
protected override bool OnKeyDown(KeyDownEvent e)
|
||||
|
@ -13,6 +13,7 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Layout;
|
||||
using osu.Framework.Lists;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
@ -264,7 +265,9 @@ namespace osu.Game.Overlays.Mods
|
||||
{
|
||||
var candidateSelection = columnFlow.Columns.SelectMany(column => column.SelectedMods).ToArray();
|
||||
|
||||
if (candidateSelection.SequenceEqual(SelectedMods.Value))
|
||||
// the following guard intends to check cases where we've already replaced potentially-external mod references with our own and avoid endless recursion.
|
||||
// TODO: replace custom comparer with System.Collections.Generic.ReferenceEqualityComparer when fully on .NET 6
|
||||
if (candidateSelection.SequenceEqual(SelectedMods.Value, new FuncEqualityComparer<Mod>(ReferenceEquals)))
|
||||
return;
|
||||
|
||||
SelectedMods.Value = ComputeNewModsFromSelection(SelectedMods.Value, candidateSelection);
|
||||
|
Loading…
Reference in New Issue
Block a user