1 #region Copyright & License Information 2 /* 3 * Copyright 2007-2020 The OpenRA Developers (see AUTHORS) 4 * This file is part of OpenRA, which is free software. It is made 5 * available to you under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, either version 3 of 7 * the License, or (at your option) any later version. For more 8 * information, see COPYING. 9 */ 10 #endregion 11 12 using System; 13 using System.Collections.Generic; 14 using OpenRA.FileSystem; 15 16 namespace OpenRA 17 { 18 public sealed class HotkeyManager 19 { 20 readonly Dictionary<string, Hotkey> settings; 21 readonly Dictionary<string, HotkeyDefinition> definitions = new Dictionary<string, HotkeyDefinition>(); 22 readonly Dictionary<string, Hotkey> keys = new Dictionary<string, Hotkey>(); 23 HotkeyManager(IReadOnlyFileSystem fileSystem, Dictionary<string, Hotkey> settings, Manifest manifest)24 public HotkeyManager(IReadOnlyFileSystem fileSystem, Dictionary<string, Hotkey> settings, Manifest manifest) 25 { 26 this.settings = settings; 27 28 var keyDefinitions = MiniYaml.Load(fileSystem, manifest.Hotkeys, null); 29 foreach (var kd in keyDefinitions) 30 { 31 var definition = new HotkeyDefinition(kd.Key, kd.Value); 32 definitions[kd.Key] = definition; 33 keys[kd.Key] = definition.Default; 34 } 35 36 foreach (var kv in settings) 37 { 38 if (definitions.ContainsKey(kv.Key)) 39 keys[kv.Key] = kv.Value; 40 } 41 42 foreach (var hd in definitions) 43 hd.Value.HasDuplicates = GetFirstDuplicate(hd.Value.Name, this[hd.Value.Name].GetValue(), hd.Value) != null; 44 } 45 GetHotkeyReference(string name)46 internal Func<Hotkey> GetHotkeyReference(string name) 47 { 48 // Is this a mod-defined hotkey? 49 if (keys.ContainsKey(name)) 50 return () => keys[name]; 51 52 // Try and parse as a hardcoded definition 53 Hotkey key; 54 if (!Hotkey.TryParse(name, out key)) 55 key = Hotkey.Invalid; 56 57 return () => key; 58 } 59 Set(string name, Hotkey value)60 public void Set(string name, Hotkey value) 61 { 62 HotkeyDefinition definition; 63 if (!definitions.TryGetValue(name, out definition)) 64 return; 65 66 keys[name] = value; 67 if (value != definition.Default) 68 settings[name] = value; 69 else 70 settings.Remove(name); 71 72 var hadDuplicates = definition.HasDuplicates; 73 definition.HasDuplicates = GetFirstDuplicate(definition.Name, this[definition.Name].GetValue(), definition) != null; 74 75 if (hadDuplicates || definition.HasDuplicates) 76 { 77 foreach (var hd in definitions) 78 { 79 if (hd.Value == definition) 80 continue; 81 82 hd.Value.HasDuplicates = GetFirstDuplicate(hd.Value.Name, this[hd.Value.Name].GetValue(), hd.Value) != null; 83 } 84 } 85 } 86 GetFirstDuplicate(string name, Hotkey value, HotkeyDefinition definition)87 public HotkeyDefinition GetFirstDuplicate(string name, Hotkey value, HotkeyDefinition definition) 88 { 89 foreach (var kv in keys) 90 { 91 if (kv.Key == name) 92 continue; 93 94 if (kv.Value == value && definitions[kv.Key].Types.Overlaps(definition.Types)) 95 return definitions[kv.Key]; 96 } 97 98 return null; 99 } 100 101 public HotkeyReference this[string name] 102 { 103 get 104 { 105 return new HotkeyReference(GetHotkeyReference(name)); 106 } 107 } 108 109 public IEnumerable<HotkeyDefinition> Definitions { get { return definitions.Values; } } 110 } 111 } 112