You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
3.0 KiB

  1. using System;
  2. using System.Collections.Specialized;
  3. using System.ComponentModel;
  4. using System.IO;
  5. using IPA.Logging;
  6. using Newtonsoft.Json;
  7. using Newtonsoft.Json.Linq;
  8. namespace IPA.Config.ConfigProviders
  9. {
  10. internal class JsonConfigProvider : IConfigProvider
  11. {
  12. private JObject jsonObj;
  13. // TODO: create a wrapper that allows empty object creation
  14. public dynamic Dynamic => jsonObj;
  15. public bool HasChanged { get; private set; }
  16. public DateTime LastModified => File.GetLastWriteTime(Filename + ".json");
  17. private string _filename;
  18. public string Filename
  19. {
  20. get => _filename;
  21. set
  22. {
  23. if (_filename != null)
  24. throw new InvalidOperationException("Can only assign to Filename once");
  25. _filename = value;
  26. }
  27. }
  28. public void Load()
  29. {
  30. Logger.config.Debug($"Loading file {Filename}.json");
  31. var fileInfo = new FileInfo(Filename + ".json");
  32. if (fileInfo.Exists)
  33. {
  34. var json = fileInfo.OpenText().ReadToEnd();
  35. try
  36. {
  37. jsonObj = JObject.Parse(json);
  38. }
  39. catch (Exception e)
  40. {
  41. Logger.config.Error($"Error parsing JSON in file {Filename}.json; resetting to empty JSON");
  42. Logger.config.Error(e);
  43. jsonObj = new JObject();
  44. File.WriteAllText(fileInfo.FullName, JsonConvert.SerializeObject(jsonObj, Formatting.Indented));
  45. }
  46. }
  47. else
  48. {
  49. jsonObj = new JObject();
  50. }
  51. SetupListeners();
  52. }
  53. private void SetupListeners()
  54. {
  55. jsonObj.PropertyChanged += JsonObj_PropertyChanged;
  56. jsonObj.ListChanged += JsonObj_ListChanged;
  57. jsonObj.CollectionChanged += JsonObj_CollectionChanged;
  58. }
  59. private void JsonObj_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
  60. {
  61. HasChanged = true;
  62. }
  63. private void JsonObj_ListChanged(object sender, ListChangedEventArgs e)
  64. {
  65. HasChanged = true;
  66. }
  67. private void JsonObj_PropertyChanged(object sender, PropertyChangedEventArgs e)
  68. {
  69. HasChanged = true;
  70. }
  71. public T Parse<T>()
  72. {
  73. return jsonObj.ToObject<T>();
  74. }
  75. public void Save()
  76. {
  77. Logger.config.Debug($"Saving file {Filename}.json");
  78. var fileInfo = new FileInfo(Filename + ".json");
  79. File.WriteAllText(fileInfo.FullName, JsonConvert.SerializeObject(jsonObj, Formatting.Indented));
  80. HasChanged = false;
  81. }
  82. public void Store<T>(T obj)
  83. {
  84. jsonObj = JObject.FromObject(obj);
  85. SetupListeners();
  86. HasChanged = true;
  87. }
  88. }
  89. }