diff --git a/source/VersionHandlerImpl/src/ProjectSettings.cs b/source/VersionHandlerImpl/src/ProjectSettings.cs index a2c0001a..6edb9f31 100644 --- a/source/VersionHandlerImpl/src/ProjectSettings.cs +++ b/source/VersionHandlerImpl/src/ProjectSettings.cs @@ -51,6 +51,12 @@ public enum SettingsLocation { /// This is a UnityEditor.EditorPrefs compatible interface. /// public interface ISettings { + + /// + /// Determine whether setting are out of sync and needs to be persisted or not + /// + bool IsModified { get; set; } + /// /// Set an int property. /// @@ -131,6 +137,13 @@ public interface ISettings { /// Default implementation of system wide settings. /// internal class EditorSettings : ISettings { + + /// + /// Determine whether setting are out of sync and needs to be persisted or not + /// Always false as editor settings are always persisted by Unity + /// + public bool IsModified { get { return false; } set { } } + /// /// Set a int property. /// @@ -224,6 +237,12 @@ public IEnumerable Keys { /// In-memory settings storage. /// internal class InMemorySettings : ISettings { + + /// + /// Determine whether setting are out of sync and needs to be persisted or not + /// + public bool IsModified { get; set; } + /// /// In-memory storage for settings. /// @@ -234,8 +253,15 @@ internal class InMemorySettings : ISettings { /// /// Name of the value. /// Value to set. - private void Set(string name, T value) { - settings[name] = value.ToString(); + private void Set(string name, T value) + { + string stringValue = value.ToString(); + + if (!settings.ContainsKey(name) || settings[name] != stringValue) { + IsModified = true; + } + + settings[name] = stringValue; } /// @@ -333,6 +359,7 @@ public bool HasKey(string name) { /// Name of the value to delete. public void DeleteKey(string name) { settings.Remove(name); + IsModified = true; } /// @@ -347,6 +374,16 @@ public void DeleteKey(string name) { /// either application or project level settings based upon the UseProjectSettings flag. /// public class ProjectSettings : ISettings { + + /// + /// Determine whether setting are out of sync and needs to be persisted or not + /// + public bool IsModified + { + get { return systemSettings.IsModified || projectSettings.IsModified; } + set { systemSettings.IsModified = projectSettings.IsModified = value; } + } + /// /// Whether to load settings from and save settings to disk. /// Exposed for testing. @@ -798,6 +835,9 @@ private static bool Load() { })) { return false; } + + // Project settings were just loaded so there shouldn't be any stale values + projectSettings.IsModified = false; return true; } } @@ -807,7 +847,7 @@ private static bool Load() { /// private static void Save() { lock (classLock) { - if (projectSettings == null || !persistenceEnabled) { + if (projectSettings == null || !persistenceEnabled || !projectSettings.IsModified) { return; } Directory.CreateDirectory(Path.GetDirectoryName(PROJECT_SETTINGS_FILE)); @@ -817,9 +857,10 @@ private static void Save() { PROJECT_SETTINGS_FILE), LogLevel.Error); return; } + string tmpFile = Path.GetTempFileName(); try { using (var writer = - XmlWriter.Create(PROJECT_SETTINGS_FILE, + XmlWriter.Create(tmpFile, new XmlWriterSettings { Encoding = new UTF8Encoding(false), Indent = true, @@ -839,6 +880,8 @@ private static void Save() { } writer.WriteEndElement(); } + + File.Copy(tmpFile, PROJECT_SETTINGS_FILE, true); } catch (Exception exception) { if (exception is IOException || exception is UnauthorizedAccessException) { logger.Log(String.Format("Unable to write to '{0}' ({1}, " + @@ -848,6 +891,10 @@ private static void Save() { } throw exception; } + finally + { + File.Delete(tmpFile); + } } } }