mirror of
https://github.com/ppy/osu.git
synced 2025-01-15 12:02:55 +08:00
Expose available mod state outwardly as a bindable
This commit is contained in:
parent
f0303d76e8
commit
071e158a29
@ -34,6 +34,15 @@ namespace osu.Game.Overlays.Mods
|
||||
[Cached]
|
||||
public Bindable<IReadOnlyList<Mod>> SelectedMods { get; private set; } = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());
|
||||
|
||||
/// <summary>
|
||||
/// Contains a dictionary with the current <see cref="ModState"/> of all mods applicable for the current ruleset.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Contrary to <see cref="OsuGameBase.AvailableMods"/> and <see cref="globalAvailableMods"/>, the <see cref="Mod"/> instances
|
||||
/// inside the <see cref="ModState"/> objects are owned solely by this <see cref="ModSelectOverlay"/> instance.
|
||||
/// </remarks>
|
||||
public Bindable<Dictionary<ModType, IReadOnlyList<ModState>>> AvailableMods { get; } = new Bindable<Dictionary<ModType, IReadOnlyList<ModState>>>(new Dictionary<ModType, IReadOnlyList<ModState>>());
|
||||
|
||||
private Func<Mod, bool> isValidMod = m => true;
|
||||
|
||||
/// <summary>
|
||||
@ -79,9 +88,9 @@ namespace osu.Game.Overlays.Mods
|
||||
yield return new DeselectAllModsButton(this);
|
||||
}
|
||||
|
||||
private readonly Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> availableMods = new Bindable<Dictionary<ModType, IReadOnlyList<Mod>>>();
|
||||
private readonly Dictionary<ModType, IReadOnlyList<ModState>> localAvailableMods = new Dictionary<ModType, IReadOnlyList<ModState>>();
|
||||
private IEnumerable<ModState> allLocalAvailableMods => localAvailableMods.SelectMany(pair => pair.Value);
|
||||
private readonly Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> globalAvailableMods = new Bindable<Dictionary<ModType, IReadOnlyList<Mod>>>();
|
||||
|
||||
private IEnumerable<ModState> 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<ModType, IReadOnlyList<ModState>>();
|
||||
|
||||
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<ModState>());
|
||||
column.AvailableMods = AvailableMods.Value.GetValueOrDefault(column.ModType, Array.Empty<ModState>());
|
||||
}
|
||||
|
||||
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<Mod>();
|
||||
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user