/// <summary>Save current settings if there is any differences</summary> public void Save() { // Null check, or clean state if (_loadedSettingsData != null) { var differences = _loadedSettingsData.Difference(this); // Don't waste the time to save if nothing has changed if (differences.Count == 0) { return; } #if DEBUG // Only log the differences in debug mode only foreach (var diff in differences) { TvCore.LogDebug($"[Settings] {diff}"); } #endif } // Lock the file for writing _fileLock.EnterWriteLock(); try { // Convert to JSON, because var settingsData = JsonConvert.SerializeObject(this); File.WriteAllText(_filePath, settingsData); // Save the new state, using JSON for cloning _loadedSettingsData = JsonConvert.DeserializeObject <Settings>(settingsData); } catch (Exception e) { TvCore.LogError($"[Settings] ERROR Writing settings file {_filePath}, {e.Message}"); } finally { // ALWAYS exit the write lock! _fileLock.ExitWriteLock(); } }
/// <summary>Load the saved settings from the disk</summary> public void Load() { TvCore.LogDebug($"[Settings] Reading settings file {_filePath}"); // Lock the file for reading _fileLock.EnterReadLock(); try { if (!File.Exists(_filePath)) { // There is nothing to load return; } var fileContents = File.ReadAllText(_filePath); _loadedSettingsData = JsonConvert.DeserializeObject <Settings>(fileContents); var settingsType = _loadedSettingsData.GetType(); // Copy the values from the newly loaded state to this instance foreach (var setting in settingsType.GetProperties()) { var currentProperty = GetType().GetProperty(setting.Name); currentProperty?.SetValue(this, setting.GetValue(_loadedSettingsData)); } } catch (Exception e) { TvCore.LogError($"[Settings] ERROR Reading settings file {_filePath}, {e.Message}"); } finally { // ALWAYS release the read lock! _fileLock.ExitReadLock(); } }
/// <summary>Invoke the provided method if the caller isn't on the control's thread</summary> /// <param name="control">The control to invoke against</param> /// <param name="action">The method you want to invoke on the provided control's thread</param> public static void InvokeIfRequired(this Control control, MethodInvoker action) { if (control.Disposing) { return; } if (control.InvokeRequired) { try { control.Invoke(action); } catch (ObjectDisposedException ex) { TvCore.LogError($"[.NET] ObjectDisposedException({ex.Message})"); } } else { action(); } }