From 7c04bf5c53442b3fe2d0adf05928c674a378923c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 17 Apr 2022 22:12:06 +0200 Subject: [PATCH] Refactor mod reference management to meet test expectations --- osu.Game/Overlays/Mods/ModColumn.cs | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModColumn.cs b/osu.Game/Overlays/Mods/ModColumn.cs index c839305746..c2273abf53 100644 --- a/osu.Game/Overlays/Mods/ModColumn.cs +++ b/osu.Game/Overlays/Mods/ModColumn.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +#nullable enable + using System; using System.Collections.Generic; using System.Linq; @@ -10,6 +12,7 @@ using Humanizer; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; @@ -25,8 +28,6 @@ using osuTK; using osuTK.Graphics; using osuTK.Input; -#nullable enable - namespace osu.Game.Overlays.Mods { public class ModColumn : CompositeDrawable @@ -256,7 +257,9 @@ namespace osu.Game.Overlays.Mods private void updateMods() { - var newMods = ModUtils.FlattenMods(availableMods.Value.GetValueOrDefault(ModType) ?? Array.Empty()).ToList(); + var newMods = ModUtils.FlattenMods(availableMods.Value.GetValueOrDefault(ModType) ?? Array.Empty()) + .Select(m => m.DeepClone()) + .ToList(); if (newMods.SequenceEqual(panelFlow.Children.Select(p => p.Mod))) return; @@ -280,9 +283,16 @@ namespace osu.Game.Overlays.Mods panel.Active.BindValueChanged(_ => { updateToggleAllState(); - SelectedMods.Value = panel.Active.Value - ? SelectedMods.Value.Append(panel.Mod).ToArray() - : SelectedMods.Value.Except(new[] { panel.Mod }).ToArray(); + + var newSelectedMods = SelectedMods.Value; + + var matchingModInstance = SelectedMods.Value.SingleOrDefault(selected => selected.GetType() == panel.Mod.GetType()); + if (matchingModInstance != null && (matchingModInstance != panel.Mod || !panel.Active.Value)) + newSelectedMods = newSelectedMods.Except(matchingModInstance.Yield()).ToArray(); + if (panel.Active.Value) + newSelectedMods = newSelectedMods.Append(panel.Mod).ToArray(); + + SelectedMods.Value = newSelectedMods.ToArray(); }); } }, (cancellationTokenSource = new CancellationTokenSource()).Token); @@ -296,7 +306,12 @@ namespace osu.Game.Overlays.Mods private void updateActiveState() { foreach (var panel in panelFlow) - panel.Active.Value = SelectedMods.Value.Any(selected => selected.GetType() == panel.Mod.GetType()); + { + var matchingSelectedMod = SelectedMods.Value.SingleOrDefault(selected => selected.GetType() == panel.Mod.GetType()); + panel.Active.Value = matchingSelectedMod != null; + if (matchingSelectedMod != null) + panel.Mod.CopyFrom(matchingSelectedMod); + } } #region Bulk select / deselect