From 071e158a297139bff0812b567cf6f6064e98839e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 25 May 2022 22:20:10 +0200 Subject: [PATCH] Expose available mod state outwardly as a bindable --- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 38 ++++++++++++++-------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index d8355a4dea..4bad34d94f 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -34,6 +34,15 @@ namespace osu.Game.Overlays.Mods [Cached] public Bindable> SelectedMods { get; private set; } = new Bindable>(Array.Empty()); + /// + /// Contains a dictionary with the current of all mods applicable for the current ruleset. + /// + /// + /// Contrary to and , the instances + /// inside the objects are owned solely by this instance. + /// + public Bindable>> AvailableMods { get; } = new Bindable>>(new Dictionary>()); + private Func isValidMod = m => true; /// @@ -79,9 +88,9 @@ namespace osu.Game.Overlays.Mods yield return new DeselectAllModsButton(this); } - private readonly Bindable>> availableMods = new Bindable>>(); - private readonly Dictionary> localAvailableMods = new Dictionary>(); - private IEnumerable allLocalAvailableMods => localAvailableMods.SelectMany(pair => pair.Value); + private readonly Bindable>> globalAvailableMods = new Bindable>>(); + + private IEnumerable allAvailableMods => AvailableMods.Value.SelectMany(pair => pair.Value); private readonly BindableBool customisationVisible = new BindableBool(); @@ -204,13 +213,13 @@ namespace osu.Game.Overlays.Mods }) }; - availableMods.BindTo(game.AvailableMods); + globalAvailableMods.BindTo(game.AvailableMods); } protected override void LoadComplete() { // this is called before base call so that the mod state is populated early, and the transition in `PopIn()` can play out properly. - availableMods.BindValueChanged(_ => createLocalMods(), true); + globalAvailableMods.BindValueChanged(_ => createLocalMods(), true); base.LoadComplete(); @@ -275,9 +284,9 @@ namespace osu.Game.Overlays.Mods private void createLocalMods() { - localAvailableMods.Clear(); + var newLocalAvailableMods = new Dictionary>(); - foreach (var (modType, mods) in availableMods.Value) + foreach (var (modType, mods) in globalAvailableMods.Value) { var modStates = mods.SelectMany(ModUtils.FlattenMod) .Select(mod => new ModState(mod.DeepClone())) @@ -286,18 +295,19 @@ namespace osu.Game.Overlays.Mods foreach (var modState in modStates) modState.Active.BindValueChanged(_ => updateFromInternalSelection()); - localAvailableMods[modType] = modStates; + newLocalAvailableMods[modType] = modStates; } + AvailableMods.Value = newLocalAvailableMods; filterMods(); foreach (var column in columnFlow.Columns) - column.AvailableMods = localAvailableMods.GetValueOrDefault(column.ModType, Array.Empty()); + column.AvailableMods = AvailableMods.Value.GetValueOrDefault(column.ModType, Array.Empty()); } private void filterMods() { - foreach (var modState in allLocalAvailableMods) + foreach (var modState in allAvailableMods) modState.Filtered.Value = !modState.Mod.HasImplementation || !IsValidMod.Invoke(modState.Mod); } @@ -378,7 +388,7 @@ namespace osu.Game.Overlays.Mods var newSelection = new List(); - foreach (var modState in allLocalAvailableMods) + foreach (var modState in allAvailableMods) { var matchingSelectedMod = SelectedMods.Value.SingleOrDefault(selected => selected.GetType() == modState.Mod.GetType()); @@ -405,9 +415,9 @@ namespace osu.Game.Overlays.Mods if (externalSelectionUpdateInProgress) return; - var candidateSelection = allLocalAvailableMods.Where(modState => modState.Active.Value) - .Select(modState => modState.Mod) - .ToArray(); + var candidateSelection = allAvailableMods.Where(modState => modState.Active.Value) + .Select(modState => modState.Mod) + .ToArray(); SelectedMods.Value = ComputeNewModsFromSelection(SelectedMods.Value, candidateSelection); }