Simplify implementation of CheckCompatibleSet

This commit is contained in:
smoogipoo
2021-02-02 18:18:57 +09:00
parent 8232d9d2fe
commit d0655c21c6

View File

@ -4,7 +4,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Extensions.TypeExtensions;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
#nullable enable #nullable enable
@ -29,7 +28,7 @@ namespace osu.Game.Utils
{ {
// Prevent multiple-enumeration. // Prevent multiple-enumeration.
var combinationList = combination as ICollection<Mod> ?? combination.ToArray(); var combinationList = combination as ICollection<Mod> ?? combination.ToArray();
return CheckCompatibleSet(combinationList) && CheckAllowed(combinationList, allowedTypes); return CheckCompatibleSet(combinationList, out _) && CheckAllowed(combinationList, allowedTypes);
} }
/// <summary> /// <summary>
@ -38,32 +37,31 @@ namespace osu.Game.Utils
/// <param name="combination">The <see cref="Mod"/> combination to check.</param> /// <param name="combination">The <see cref="Mod"/> combination to check.</param>
/// <returns>Whether all <see cref="Mod"/>s in the combination are compatible with each-other.</returns> /// <returns>Whether all <see cref="Mod"/>s in the combination are compatible with each-other.</returns>
public static bool CheckCompatibleSet(IEnumerable<Mod> combination) public static bool CheckCompatibleSet(IEnumerable<Mod> combination)
=> CheckCompatibleSet(combination, out _);
/// <summary>
/// Checks that all <see cref="Mod"/>s in a combination are compatible with each-other.
/// </summary>
/// <param name="combination">The <see cref="Mod"/> combination to check.</param>
/// <param name="invalidMods">Any invalid mods in the set.</param>
/// <returns>Whether all <see cref="Mod"/>s in the combination are compatible with each-other.</returns>
public static bool CheckCompatibleSet(IEnumerable<Mod> combination, out List<Mod>? invalidMods)
{ {
var incompatibleTypes = new HashSet<Type>(); invalidMods = null;
var incomingTypes = new HashSet<Type>();
foreach (var mod in combination.SelectMany(FlattenMod)) foreach (var mod in combination)
{ {
// Add the new mod incompatibilities, checking whether any match the existing mod types. foreach (var type in mod.IncompatibleMods)
foreach (var t in mod.IncompatibleMods)
{ {
if (incomingTypes.Contains(t)) foreach (var invalid in combination.Where(m => type.IsInstanceOfType(m)))
return false; {
invalidMods ??= new List<Mod>();
incompatibleTypes.Add(t); invalidMods.Add(invalid);
} }
// Add the new mod types, checking whether any match the incompatible types.
foreach (var t in mod.GetType().EnumerateBaseTypes())
{
if (incompatibleTypes.Contains(t))
return false;
incomingTypes.Add(t);
} }
} }
return true; return invalidMods == null;
} }
/// <summary> /// <summary>