diff --git a/BizHawk.Client.Common/config/Binding.cs b/BizHawk.Client.Common/config/Binding.cs index e151c3e826..f7c5c0086e 100644 --- a/BizHawk.Client.Common/config/Binding.cs +++ b/BizHawk.Client.Common/config/Binding.cs @@ -18,6 +18,12 @@ namespace BizHawk.Client.Common { public List Bindings { get; private set; } + [Newtonsoft.Json.JsonConstructor] + public BindingCollection(List Bindings) + { + this.Bindings = Bindings; + } + public BindingCollection() { Bindings = new List(); diff --git a/BizHawk.Client.Common/config/Config.cs b/BizHawk.Client.Common/config/Config.cs index 9ffa12ea03..5c414992bb 100644 --- a/BizHawk.Client.Common/config/Config.cs +++ b/BizHawk.Client.Common/config/Config.cs @@ -16,8 +16,7 @@ namespace BizHawk.Client.Common { if (AllTrollers.Count == 0 && AllTrollersAutoFire.Count == 0 && AllTrollersAnalog.Count == 0) { - ControlDefaults cd = new ControlDefaults(); - cd = ConfigService.Load(ControlDefaultPath, cd); + ControlDefaults cd = ConfigService.Load(ControlDefaultPath); AllTrollers = cd.AllTrollers; AllTrollersAutoFire = cd.AllTrollersAutoFire; AllTrollersAnalog = cd.AllTrollersAnalog; diff --git a/BizHawk.Client.Common/config/ConfigService.cs b/BizHawk.Client.Common/config/ConfigService.cs index 12b9528bca..c47445c4a8 100644 --- a/BizHawk.Client.Common/config/ConfigService.cs +++ b/BizHawk.Client.Common/config/ConfigService.cs @@ -2,14 +2,35 @@ using System.IO; using System.Reflection; using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; namespace BizHawk.Client.Common { public static class ConfigService { - public static T Load(string filepath, T currentConfig) where T : new() + static JsonSerializer Serializer; + + static ConfigService() { - T config = new T(); + Serializer = new JsonSerializer + { + MissingMemberHandling = MissingMemberHandling.Ignore, + TypeNameHandling = TypeNameHandling.Auto, + ConstructorHandling = ConstructorHandling.Default, + + // because of the peculiar setup of Binding.cs and PathEntry.cs + ObjectCreationHandling = ObjectCreationHandling.Replace, + + ContractResolver = new DefaultContractResolver + { + DefaultMembersSearchFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic + }, + }; + } + + public static T Load(string filepath) where T : new() + { + T config = default(T); try { @@ -17,14 +38,8 @@ namespace BizHawk.Client.Common if (file.Exists) using (var reader = file.OpenText()) { - var s = new JsonSerializer - { - MissingMemberHandling = MissingMemberHandling.Ignore, - TypeNameHandling = TypeNameHandling.Auto - //SuppressDuplicateMemberException = true - }; var r = new JsonTextReader(reader); - config = (T)s.Deserialize(r, typeof(T)); + config = (T)Serializer.Deserialize(r, typeof(T)); } } catch (Exception ex) @@ -32,28 +47,9 @@ namespace BizHawk.Client.Common throw new InvalidOperationException("Config Error", ex); } - //if (config == null) return new T(); + if (config == null) + return new T(); - //patch up arrays in the config with the minimum number of things - // TODO: do we still need this with the new json.net version? - foreach(var fi in typeof(T).GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)) - if (fi.FieldType.IsArray) - { - Array aold = fi.GetValue(currentConfig) as Array; - Array anew = fi.GetValue(config) as Array; - if (aold.Length == anew.Length) continue; - - //create an array of the right size - Array acreate = Array.CreateInstance(fi.FieldType.GetElementType(), Math.Max(aold.Length,anew.Length)); - - //copy the old values in, (presumably the defaults), and then copy the new ones on top - Array.Copy(aold, acreate, Math.Min(aold.Length,acreate.Length)); - Array.Copy(anew, acreate, Math.Min(anew.Length, acreate.Length)); - - //stash it into the config struct - fi.SetValue(config, acreate); - } - return config; } @@ -62,14 +58,9 @@ namespace BizHawk.Client.Common var file = new FileInfo(filepath); using (var writer = file.CreateText()) { - var s = new JsonSerializer - { - TypeNameHandling = TypeNameHandling.Auto - }; - var w = new JsonTextWriter(writer) { Formatting = Formatting.Indented }; - s.Serialize(w, config); + Serializer.Serialize(w, config); } } } -} \ No newline at end of file +} diff --git a/BizHawk.Client.Common/config/PathEntry.cs b/BizHawk.Client.Common/config/PathEntry.cs index 76abf0be73..4e3b4e127a 100644 --- a/BizHawk.Client.Common/config/PathEntry.cs +++ b/BizHawk.Client.Common/config/PathEntry.cs @@ -39,6 +39,12 @@ namespace BizHawk.Client.Common Paths.AddRange(DefaultValues); } + [Newtonsoft.Json.JsonConstructor] + public PathEntryCollection(List Paths) + { + this.Paths = Paths; + } + public void Add(PathEntry p) { Paths.Add(p); diff --git a/BizHawk.Client.EmuHawk/MainForm.Events.cs b/BizHawk.Client.EmuHawk/MainForm.Events.cs index 87f78aaa9d..a34f132949 100644 --- a/BizHawk.Client.EmuHawk/MainForm.Events.cs +++ b/BizHawk.Client.EmuHawk/MainForm.Events.cs @@ -1076,7 +1076,7 @@ namespace BizHawk.Client.EmuHawk private void LoadConfigMenuItem_Click(object sender, EventArgs e) { - Global.Config = ConfigService.Load(PathManager.DefaultIniPath, Global.Config); + Global.Config = ConfigService.Load(PathManager.DefaultIniPath); Global.Config.ResolveDefaults(); GlobalWin.OSD.AddMessage("Config file loaded"); } diff --git a/BizHawk.Client.EmuHawk/Program.cs b/BizHawk.Client.EmuHawk/Program.cs index 4cafd7bf8a..e6cf8c812a 100644 --- a/BizHawk.Client.EmuHawk/Program.cs +++ b/BizHawk.Client.EmuHawk/Program.cs @@ -65,9 +65,8 @@ namespace BizHawk.Client.EmuHawk Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - string iniPath = System.IO.Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "config.ini"); - Global.Config = ConfigService.Load(iniPath, new Config()); + Global.Config = ConfigService.Load(iniPath); Global.Config.ResolveDefaults(); BizHawk.Common.HawkFile.ArchiveHandlerFactory = new SevenZipSharpArchiveHandler(); diff --git a/BizHawk.Client.EmuHawk/config/ControllerConfig.cs b/BizHawk.Client.EmuHawk/config/ControllerConfig.cs index 7cbe669dff..750be6b0cb 100644 --- a/BizHawk.Client.EmuHawk/config/ControllerConfig.cs +++ b/BizHawk.Client.EmuHawk/config/ControllerConfig.cs @@ -317,8 +317,7 @@ namespace BizHawk.Client.EmuHawk // load panels directly from the default config. // this means that the changes are NOT committed. so "Cancel" works right and you // still have to hit OK at the end. - var cd = new ControlDefaults(); - cd = ConfigService.Load(Config.ControlDefaultPath, cd); + var cd = ConfigService.Load(Config.ControlDefaultPath); LoadPanels(cd); tabControl1.SelectTab(wasTabbedMain); @@ -358,8 +357,7 @@ namespace BizHawk.Client.EmuHawk var result = MessageBox.Show(this, "OK to overwrite defaults for current control scheme?", "Save Defaults", MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { - var cd = new ControlDefaults(); - cd = ConfigService.Load(Config.ControlDefaultPath, cd); + var cd = ConfigService.Load(Config.ControlDefaultPath); cd.AllTrollers[_theDefinition.Name] = new Dictionary(); cd.AllTrollersAutoFire[_theDefinition.Name] = new Dictionary(); cd.AllTrollersAnalog[_theDefinition.Name] = new Dictionary();