diff --git a/BizHawk.Common/Colors.cs b/BizHawk.Common/Colors.cs
index 424e7af9f2..1d6802561b 100644
--- a/BizHawk.Common/Colors.cs
+++ b/BizHawk.Common/Colors.cs
@@ -1,22 +1,12 @@
-#nullable disable
-
-namespace BizHawk.Common
+namespace BizHawk.Common
{
public static class Colors
{
- public static int ARGB(byte red, byte green, byte blue)
- {
- return (int)((uint)((red << 0x10) | (green << 8) | blue | (0xFF << 0x18)));
- }
+ /// This is just Color.FromArgb(alpha, red, green, blue).ToArgb() with extra steps.
+ public static int ARGB(byte red, byte green, byte blue, byte alpha = 0xFF) => unchecked((int) ((uint) (alpha << 24) | (uint) (red << 16) | (uint) (green << 8) | blue));
- public static int ARGB(byte red, byte green, byte blue, byte alpha)
- {
- return (int)((uint)((red << 0x10) | (green << 8) | blue | (alpha << 0x18)));
- }
-
- public static int Luminosity(byte lum)
- {
- return (int)((uint)((lum << 0x10) | (lum << 8) | lum | (0xFF << 0x18)));
- }
+#if false
+ public static int Luminosity(byte lum) => ARGB(lum, lum, lum);
+#endif
}
}
diff --git a/BizHawk.Common/CustomCollections.cs b/BizHawk.Common/CustomCollections.cs
index e65253fc41..9a6eae030a 100644
--- a/BizHawk.Common/CustomCollections.cs
+++ b/BizHawk.Common/CustomCollections.cs
@@ -1,107 +1,58 @@
-#nullable disable
-
-using System;
+using System;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.Serialization;
namespace BizHawk.Common
{
- ///
- /// A dictionary that creates new values on the fly as necessary so that any key you need will be defined.
- ///
- /// dictionary keys
- /// dictionary values
+ /// Wrapper over WorkingDictionary<, List<>>.
[Serializable]
- public class WorkingDictionary : Dictionary where V : new()
+ public class Bag : IEnumerable where TKey : notnull
{
- public new V this[K key]
+ private readonly WorkingDictionary> dictionary = new WorkingDictionary>();
+
+ public IList Keys => dictionary.Keys.ToList();
+
+ public List this[TKey key]
{
- get
- {
- V temp;
- if (!TryGetValue(key, out temp))
- {
- temp = this[key] = new V();
- }
-
- return temp;
- }
-
- set
- {
- base[key] = value;
- }
+#pragma warning disable CS8603 // the only call to the index setter of `dictionary` is this index setter, which only takes non-null `List`s
+ get => dictionary[key];
+#pragma warning restore CS8603
+ set => dictionary[key] = value;
}
- public WorkingDictionary() { }
+ public void Add(TKey key, IEnumerable val) => this[key].AddRange(val);
- protected WorkingDictionary(SerializationInfo info, StreamingContext context) : base(info, context) { }
+ public void Add(TKey key, TValue val) => this[key].Add(val);
+
+ public bool ContainsKey(TKey key) => dictionary.ContainsKey(key);
+
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+
+ public IEnumerator GetEnumerator() => dictionary.Values.SelectMany(lv => lv).GetEnumerator();
+
+ public IEnumerator>> GetKVPEnumerator() => dictionary.GetEnumerator();
}
- ///
- /// a Dictionary-of-lists with key K and values List<V>
- ///
+ /// A dictionary whose index getter creates an entry if the requested key isn't part of the collection, making it always safe to use the returned value. The new entry's value will be the result of the default constructor of .
[Serializable]
- public class Bag : BagBase>, List> { }
-
- ///
- /// base class for Bag and SortedBag
- ///
- /// dictionary keys
- /// list values
- /// dictionary type
- /// list type
- [Serializable]
- public class BagBase : IEnumerable
- where D : IDictionary, new()
- where L : IList, IEnumerable, new()
+ public class WorkingDictionary : Dictionary
+ where TKey : notnull
+ where TValue : new()
{
- readonly D dictionary = new D();
- public void Add(K key, V val)
+ public WorkingDictionary() {}
+
+ protected WorkingDictionary(SerializationInfo info, StreamingContext context) : base(info, context) {}
+
+ [property: MaybeNull]
+ public new TValue this[TKey key]
{
- this[key].Add(val);
- }
-
- public void Add(K key, L val)
- {
- foreach (var v in val)
- this[key].Add(v);
- }
-
- public bool ContainsKey(K key) { return dictionary.ContainsKey(key); }
-
- IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
- public IEnumerator GetEnumerator()
- {
- return dictionary.Values.SelectMany(lv => lv).GetEnumerator();
- }
-
- public IEnumerable KeyValuePairEnumerator { get { return dictionary; } }
-
- ///
- /// Gets the list of keys contained herein
- ///
- public IList Keys { get { return new List(dictionary.Keys); } }
-
- public L this[K key]
- {
- get
- {
- L slot;
- if (!dictionary.TryGetValue(key, out slot))
- {
- dictionary[key] = slot = new L();
- }
-
- return slot;
- }
-
- set
- {
- dictionary[key] = value;
- }
+ get => TryGetValue(key, out var temp)
+ ? temp
+ : (base[key] = new TValue());
+ set => base[key] = value;
}
}
}
diff --git a/BizHawk.Common/DescribableEnumConverter.cs b/BizHawk.Common/DescribableEnumConverter.cs
index 3eb428ac7c..551be0ade3 100644
--- a/BizHawk.Common/DescribableEnumConverter.cs
+++ b/BizHawk.Common/DescribableEnumConverter.cs
@@ -1,74 +1,61 @@
-#nullable disable
-
-using System;
-using System.Collections.Generic;
+using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
+using System.Linq;
using System.Reflection;
namespace BizHawk.Common
{
public class DescribableEnumConverter : EnumConverter
{
- private Type enumType;
+ private readonly Type enumType;
public DescribableEnumConverter(Type type) : base(type)
{
enumType = type;
}
- public override bool CanConvertTo(ITypeDescriptorContext context, Type destType)
+ public override bool CanConvertFrom(ITypeDescriptorContext context, Type srcType) => srcType == typeof(string);
+
+ public override bool CanConvertTo(ITypeDescriptorContext context, Type destType) => destType == typeof(string);
+
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
- return destType == typeof(string);
+ var valueStr = value?.ToString() ?? throw new ArgumentException($"got null {nameof(value)}");
+ return Enum.Parse(
+ enumType,
+ enumType.GetFields(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault(fi => valueStr.Equals((fi.GetCustomAttribute(typeof(DisplayAttribute)) as DisplayAttribute)?.Name))?.Name
+ ?? valueStr
+ );
}
- public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture,
- object value, Type destType)
+ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destType)
{
- var fi = enumType.GetField(Enum.GetName(enumType, value));
- var attr = (DisplayAttribute)fi.GetCustomAttribute(typeof(DisplayAttribute));
- if (attr != null)
- return attr.Name;
- else
- return value.ToString();
- }
-
- public override bool CanConvertFrom(ITypeDescriptorContext context, Type srcType)
- {
- return srcType == typeof(string);
- }
-
- public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture,
- object value)
- {
- foreach (var fi in enumType.GetFields(BindingFlags.Public | BindingFlags.Static))
+ var fieldName = Enum.GetName(enumType, value ?? throw new ArgumentException($"got null {nameof(value)}"));
+ if (fieldName != null)
{
- var attr = (DisplayAttribute)fi.GetCustomAttribute(typeof(DisplayAttribute));
- if (attr != null && attr.Name.Equals(value))
- return Enum.Parse(enumType, fi.Name);
+ var fieldInfo = enumType.GetField(fieldName);
+ if (fieldInfo != null)
+ {
+ var found = fieldInfo.GetCustomAttribute(typeof(DisplayAttribute));
+ if (found is DisplayAttribute da) return da.Name;
+ }
}
- return Enum.Parse(enumType, (string)value);
+#pragma warning disable CS8603 // value can't be null here, it would've thrown already
+ return value.ToString();
+#pragma warning restore CS8603
}
- public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
- {
- return true;
- }
+ public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) => new StandardValuesCollection(
+ enumType.GetFields(BindingFlags.Public | BindingFlags.Static)
+ .Select(fi => fi.GetValue(null))
+ .ToList()
+ );
- public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
- {
- return true;
- }
+ public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) => true;
- public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
- {
- var ret = new List