瀏覽代碼

Convert KeyboardShortcut into a struct

ManlyMarco 5 年之前
父節點
當前提交
091b2fa788
共有 2 個文件被更改,包括 47 次插入20 次删除
  1. 18 17
      BepInEx/Configuration/KeyboardShortcut.cs
  2. 29 3
      BepInExTests/Configuration/ConfigFileTests.cs

+ 18 - 17
BepInEx/Configuration/KeyboardShortcut.cs

@@ -17,7 +17,7 @@ namespace BepInEx.Configuration
 	/// 
 	/// How to use: Use <see cref="IsDown"/> in this class instead of <see cref="Input.GetKeyDown(KeyCode)"/> in the Update loop.
 	/// </summary>
-	public class KeyboardShortcut
+	public struct KeyboardShortcut
 	{
 		static KeyboardShortcut()
 		{
@@ -25,12 +25,17 @@ namespace BepInEx.Configuration
 				typeof(KeyboardShortcut),
 				new TypeConverter
 				{
-					ConvertToString = (o, type) => (o as KeyboardShortcut)?.Serialize() ?? "",
+					ConvertToString = (o, type) => ((KeyboardShortcut)o).Serialize(),
 					ConvertToObject = (s, type) => Deserialize(s)
 				});
 		}
 
 		/// <summary>
+		/// Shortcut that never triggers.
+		/// </summary>
+		public static readonly KeyboardShortcut Empty = new KeyboardShortcut();
+
+		/// <summary>
 		/// All KeyCode values that can be used in a keyboard shortcut.
 		/// </summary>
 		public static readonly IEnumerable<KeyCode> AllKeyCodes = (KeyCode[])Enum.GetValues(typeof(KeyCode));
@@ -55,15 +60,6 @@ namespace BepInEx.Configuration
 			_allKeysLookup = new HashSet<KeyCode>(_allKeys);
 		}
 
-		/// <summary>
-		/// Create a new empty shortcut.
-		/// </summary>
-		public KeyboardShortcut()
-		{
-			_allKeys = SanitizeKeys();
-			_allKeysLookup = new HashSet<KeyCode>(_allKeys);
-		}
-
 		private static KeyCode[] SanitizeKeys(params KeyCode[] keys)
 		{
 			if (keys.Length == 0 || keys[0] == KeyCode.None)
@@ -76,12 +72,12 @@ namespace BepInEx.Configuration
 		/// Main key of the key combination. It has to be pressed / let go last for the combination to be triggered.
 		/// If the combination is empty, <see cref="KeyCode.None"/> is returned.
 		/// </summary>
-		public KeyCode MainKey => _allKeys.Length > 0 ? _allKeys[0] : KeyCode.None;
+		public KeyCode MainKey => _allKeys != null && _allKeys.Length > 0 ? _allKeys[0] : KeyCode.None;
 
 		/// <summary>
 		/// Modifiers of the key combination, if any.
 		/// </summary>
-		public IEnumerable<KeyCode> Modifiers => _allKeys.Skip(1);
+		public IEnumerable<KeyCode> Modifiers => _allKeys?.Skip(1) ?? Enumerable.Empty<KeyCode>();
 
 		/// <summary>
 		/// Attempt to deserialize key combination from the string.
@@ -97,7 +93,7 @@ namespace BepInEx.Configuration
 			catch (SystemException ex)
 			{
 				Logger.Log(LogLevel.Error, "Failed to read keybind from settings: " + ex.Message);
-				return new KeyboardShortcut();
+				return Empty;
 			}
 		}
 
@@ -106,6 +102,7 @@ namespace BepInEx.Configuration
 		/// </summary>
 		public string Serialize()
 		{
+			if (_allKeys == null) return string.Empty;
 			return string.Join(" + ", _allKeys.Select(x => x.ToString()).ToArray());
 		}
 
@@ -144,11 +141,13 @@ namespace BepInEx.Configuration
 
 		private bool ModifierKeyTest()
 		{
+			var lookup = _allKeysLookup;
+			var mainKey = MainKey;
 			return AllKeyCodes.All(c =>
 			{
-				if (_allKeysLookup.Contains(c))
+				if (lookup.Contains(c))
 				{
-					if (_allKeys[0] == c)
+					if (mainKey == c)
 						return true;
 					return Input.GetKey(c);
 				}
@@ -167,12 +166,14 @@ namespace BepInEx.Configuration
 		/// <inheritdoc />
 		public override bool Equals(object obj)
 		{
-			return obj is KeyboardShortcut shortcut && _allKeys.SequenceEqual(shortcut._allKeys);
+			return obj is KeyboardShortcut shortcut && MainKey == shortcut.MainKey && Modifiers.SequenceEqual(shortcut.Modifiers);
 		}
 
 		/// <inheritdoc />
 		public override int GetHashCode()
 		{
+			if (_allKeys == null || _allKeys.Length == 0) return 0;
+
 			var hc = _allKeys.Length;
 			for (var i = 0; i < _allKeys.Length; i++)
 				hc = unchecked(hc * 31 + (int)_allKeys[i]);

+ 29 - 3
BepInExTests/Configuration/ConfigFileTests.cs

@@ -232,7 +232,7 @@ namespace BepInEx.Configuration.Tests
 		}
 
 		[TestMethod]
-		public void KeyShortcutTest()
+		public void KeyboardShortcutTest()
 		{
 			var shortcut = new KeyboardShortcut(KeyCode.H, KeyCode.O, KeyCode.R, KeyCode.S, KeyCode.E, KeyCode.Y);
 			var s = shortcut.Serialize();
@@ -247,7 +247,33 @@ namespace BepInEx.Configuration.Tests
 			c.Reload();
 			Assert.AreEqual(shortcut, w.Value);
 		}
-		
+
+		[TestMethod]
+		public void KeyboardShortcutTest2()
+		{
+			Assert.AreEqual(KeyboardShortcut.Empty, new KeyboardShortcut());
+
+			var c = MakeConfig();
+
+			var w = c.GetSetting("Cat", "Key", KeyboardShortcut.Empty, new ConfigDescription("Test"));
+
+			Assert.AreEqual("", w.ConfigEntry.GetSerializedValue());
+
+			w.ConfigEntry.SetSerializedValue(w.ConfigEntry.GetSerializedValue());
+			Assert.AreEqual(KeyboardShortcut.Empty, w.Value);
+
+			var testShortcut = new KeyboardShortcut(KeyCode.A, KeyCode.B, KeyCode.C);
+			w.Value = testShortcut;
+
+			w.ConfigEntry.SetSerializedValue(w.ConfigEntry.GetSerializedValue());
+			Assert.AreEqual(testShortcut, w.Value);
+
+			c.Save();
+			c.Reload();
+
+			Assert.AreEqual(testShortcut, w.Value);
+		}
+
 		[TestMethod]
 		public void StringEscapeChars()
 		{
@@ -274,7 +300,7 @@ namespace BepInEx.Configuration.Tests
 			var c = MakeConfig();
 
 			var unescaped = @"D:\test\p ath";
-			foreach (string testVal in new[]{ unescaped , @"D:\\test\\p ath" })
+			foreach (string testVal in new[] { unescaped, @"D:\\test\\p ath" })
 			{
 				File.WriteAllText(c.ConfigFilePath, $"[Cat]\n# Test\nKey={testVal}\n");
 				c.Reload();