| using System; | |
| using UnityEngine; | |
| namespace UnityEditor.SettingsManagement | |
| { | |
| [] | |
| enum SettingVisibility | |
| { | |
| None = 0 << 0, | |
| /// <value> | |
| /// Matches any static field implementing IUserSetting and tagged with [UserSettingAttribute(visibleInSettingsProvider = true)]. | |
| /// </value> | |
| /// <summary> | |
| /// These fields are automatically scraped by the SettingsProvider and displayed. | |
| /// </summary> | |
| Visible = 1 << 0, | |
| /// <value> | |
| /// Matches any static field implementing IUserSetting and tagged with [UserSettingAttribute(visibleInSettingsProvider = false)]. | |
| /// </value> | |
| /// <summary> | |
| /// These fields will be reset by the "Reset All" menu in SettingsProvider, but are not shown in the interface. | |
| /// Typically these fields require some conditional formatting or data handling, and are shown in the | |
| /// SettingsProvider UI with a [UserSettingBlockAttribute]. | |
| /// </summary> | |
| Hidden = 1 << 1, | |
| /// <value> | |
| /// A static or instance field tagged with [SettingsKeyAttribute]. | |
| /// </value> | |
| /// <summary> | |
| /// Unlisted settings are not shown in the SettingsProvider, but are reset to default values by the "Reset All" | |
| /// context menu. | |
| /// </summary> | |
| Unlisted = 1 << 2, | |
| /// <value> | |
| /// A static field implementing IUserSetting that is not marked with any setting attribute. | |
| /// </value> | |
| /// <summary> | |
| /// Unregistered IUserSetting fields are not affected by the SettingsProvider. | |
| /// </summary> | |
| Unregistered = 1 << 3, | |
| All = Visible | Hidden | Unlisted | Unregistered | |
| } | |
| /// <summary> | |
| /// Types implementing IUserSetting are eligible for use with <see cref="UserSettingAttribute"/>, which enables | |
| /// fields to automatically populate the <see cref="UserSettingsProvider"/> interface. | |
| /// </summary> | |
| public interface IUserSetting | |
| { | |
| /// <value> | |
| /// The key for this value. | |
| /// </value> | |
| string key { get; } | |
| /// <value> | |
| /// The type of the stored value. | |
| /// </value> | |
| Type type { get; } | |
| /// <value> | |
| /// At which scope this setting is saved. | |
| /// </value> | |
| SettingsScope scope { get; } | |
| /// <summary> | |
| /// The name of the <see cref="ISettingsRepository"/> that this setting should be associated with. If null, the | |
| /// first repository matching the <see cref="scope"/> will be used. | |
| /// </summary> | |
| string settingsRepositoryName { get; } | |
| /// <value> | |
| /// The <see cref="Settings"/> instance that this setting should be saved and loaded from. | |
| /// </value> | |
| Settings settings { get; } | |
| /// <summary> | |
| /// Get the stored value. | |
| /// If you are implementing IUserSetting it is recommended that you cache this value. | |
| /// </summary> | |
| /// <returns> | |
| /// The stored value. | |
| /// </returns> | |
| object GetValue(); | |
| /// <summary> | |
| /// Get the default value for this setting. | |
| /// </summary> | |
| /// <returns> | |
| /// The default value for this setting. | |
| /// </returns> | |
| object GetDefaultValue(); | |
| /// <summary> | |
| /// Set the value for this setting. | |
| /// </summary> | |
| /// <param name="value">The new value.</param> | |
| /// <param name="saveProjectSettingsImmediately"> | |
| /// True to immediately serialize the ISettingsRepository that is backing this value, or false to postpone. | |
| /// If not serializing immediately, be sure to call <see cref="Settings.Save"/>. | |
| /// </param> | |
| void SetValue(object value, bool saveProjectSettingsImmediately = false); | |
| /// <summary> | |
| /// When the inspected type is a reference value, it is possible to change properties without affecting the | |
| /// backing setting. ApplyModifiedProperties provides a method to force serialize these changes. | |
| /// </summary> | |
| void ApplyModifiedProperties(); | |
| /// <summary> | |
| /// Set the current value back to the default. | |
| /// </summary> | |
| /// <param name="saveProjectSettingsImmediately">True to immediately re-serialize project settings.</param> | |
| void Reset(bool saveProjectSettingsImmediately = false); | |
| /// <summary> | |
| /// Delete the saved setting. Does not clear the current value. | |
| /// </summary> | |
| /// <see cref="Reset"/> | |
| /// <param name="saveProjectSettingsImmediately">True to immediately re-serialize project settings.</param> | |
| void Delete(bool saveProjectSettingsImmediately = false); | |
| } | |
| /// <summary> | |
| /// A generic implementation of IUserSetting to be used with a <see cref="Settings"/> instance. This default | |
| /// implementation assumes the <see cref="Settings"/> instance contains two <see cref="ISettingsRepository"/>, one | |
| /// for <see cref="SettingsScope.Project"/> and one for <see cref="SettingsScope.User"/>. | |
| /// </summary> | |
| /// <typeparam name="T"></typeparam> | |
| /// <inheritdoc /> | |
| public class UserSetting<T> : IUserSetting | |
| { | |
| bool m_Initialized; | |
| string m_Key; | |
| string m_Repository; | |
| T m_Value; | |
| T m_DefaultValue; | |
| SettingsScope m_Scope; | |
| Settings m_Settings; | |
| UserSetting() {} | |
| /// <summary> | |
| /// Constructor for UserSetting{T} type. | |
| /// </summary> | |
| /// <param name="settings">The <see cref="Settings"/> instance that this setting should be saved and loaded from.</param> | |
| /// <param name="key">The key for this value.</param> | |
| /// <param name="value">The default value for this key.</param> | |
| /// <param name="scope">The scope at which to save this setting.</param> | |
| public UserSetting(Settings settings, string key, T value, SettingsScope scope = SettingsScope.Project) | |
| { | |
| m_Key = key; | |
| m_Repository = null; | |
| m_Value = value; | |
| m_Scope = scope; | |
| m_Initialized = false; | |
| m_Settings = settings; | |
| } | |
| /// <summary> | |
| /// Constructor for UserSetting{T} type. | |
| /// </summary> | |
| /// <param name="settings">The <see cref="Settings"/> instance that this setting should be saved and loaded from.</param> | |
| /// <param name="repository">The <see cref="ISettingsRepository"/> name that this setting should be saved and loaded from. Pass null to save to first available instance.</param> | |
| /// <param name="key">The key for this value.</param> | |
| /// <param name="value">The default value for this key.</param> | |
| /// <param name="scope">The scope at which to save this setting.</param> | |
| public UserSetting(Settings settings, string repository, string key, T value, SettingsScope scope = SettingsScope.Project) | |
| { | |
| m_Key = key; | |
| m_Repository = repository; | |
| m_Value = value; | |
| m_Scope = scope; | |
| m_Initialized = false; | |
| m_Settings = settings; | |
| } | |
| /// <value> | |
| /// The key for this value. | |
| /// </value> | |
| /// <inheritdoc /> | |
| public string key | |
| { | |
| get { return m_Key; } | |
| } | |
| /// <value> | |
| /// The name of the repository that this setting is saved in. | |
| /// </value> | |
| /// <inheritdoc /> | |
| public string settingsRepositoryName | |
| { | |
| get { return m_Repository; } | |
| } | |
| /// <value> | |
| /// The type that this setting represents ({T}). | |
| /// </value> | |
| /// <inheritdoc /> | |
| public Type type | |
| { | |
| get { return typeof(T); } | |
| } | |
| /// <summary> | |
| /// Get a copy of the default value. | |
| /// </summary> | |
| /// <returns> | |
| /// The default value. | |
| /// </returns> | |
| /// <inheritdoc /> | |
| public object GetDefaultValue() | |
| { | |
| return defaultValue; | |
| } | |
| /// <summary> | |
| /// Get the currently stored value. | |
| /// </summary> | |
| /// <returns> | |
| /// The value that is currently set. | |
| /// </returns> | |
| /// <inheritdoc /> | |
| public object GetValue() | |
| { | |
| return value; | |
| } | |
| /// <summary> | |
| /// The scope affects which <see cref="ISettingsRepository"/> the <see cref="settings"/> instance will save | |
| /// it's data to. | |
| /// </summary> | |
| /// <value> | |
| /// The scope at which to save this key and value. | |
| /// </value> | |
| /// <inheritdoc /> | |
| public SettingsScope scope | |
| { | |
| get { return m_Scope; } | |
| } | |
| /// <value> | |
| /// The <see cref="Settings"/> instance that this setting will be read from and saved to. | |
| /// </value> | |
| /// <inheritdoc /> | |
| public Settings settings | |
| { | |
| get { return m_Settings; } | |
| } | |
| /// <summary> | |
| /// Set the value for this setting. | |
| /// </summary> | |
| /// <param name="value">The new value.</param> | |
| /// <param name="saveProjectSettingsImmediately"> | |
| /// True to immediately serialize the ISettingsRepository that is backing this value, or false to postpone. | |
| /// If not serializing immediately, be sure to call <see cref="Settings.Save"/>. | |
| /// </param> | |
| /// <inheritdoc /> | |
| public void SetValue(object value, bool saveProjectSettingsImmediately = false) | |
| { | |
| // we do want to allow null values | |
| if (value != null && !(value is T)) | |
| throw new ArgumentException("Value must be of type " + typeof(T) + "\n" + key + " expecting value of type " + type + ", received " + value.GetType()); | |
| SetValue((T)value, saveProjectSettingsImmediately); | |
| } | |
| /// <summary> | |
| /// Set the value for this setting. | |
| /// </summary> | |
| /// <param name="value">The new value.</param> | |
| /// <param name="saveProjectSettingsImmediately"> | |
| /// True to immediately serialize the ISettingsRepository that is backing this value, or false to postpone. | |
| /// If not serializing immediately, be sure to call <see cref="Settings.Save"/>. | |
| /// </param> | |
| public void SetValue(T value, bool saveProjectSettingsImmediately = false) | |
| { | |
| Init(); | |
| m_Value = value; | |
| settings.Set<T>(key, m_Value, m_Scope); | |
| if (saveProjectSettingsImmediately) | |
| settings.Save(); | |
| } | |
| /// <summary> | |
| /// Delete the saved setting. Does not clear the current value. | |
| /// </summary> | |
| /// <see cref="M:UnityEditor.SettingsManagement.UserSetting`1.Reset(System.Boolean)" /> | |
| /// <param name="saveProjectSettingsImmediately">True to immediately re-serialize project settings.</param> | |
| /// <inheritdoc cref="IUserSetting.Delete"/> | |
| public void Delete(bool saveProjectSettingsImmediately = false) | |
| { | |
| settings.DeleteKey<T>(key, scope); | |
| // Don't Init() because that will set the key again. We just want to reset the m_Value with default and | |
| // pretend that this field hasn't been initialised yet. | |
| m_Value = ValueWrapper<T>.DeepCopy(m_DefaultValue); | |
| m_Initialized = false; | |
| } | |
| /// <summary> | |
| /// When the inspected type is a reference value, it is possible to change properties without affecting the | |
| /// backing setting. ApplyModifiedProperties provides a method to force serialize these changes. | |
| /// </summary> | |
| /// <inheritdoc cref="IUserSetting.ApplyModifiedProperties"/> | |
| public void ApplyModifiedProperties() | |
| { | |
| settings.Set<T>(key, m_Value, m_Scope); | |
| settings.Save(); | |
| } | |
| /// <summary> | |
| /// Set the current value back to the default. | |
| /// </summary> | |
| /// <param name="saveProjectSettingsImmediately">True to immediately re-serialize project settings.</param> | |
| /// <inheritdoc cref="IUserSetting.Reset"/> | |
| public void Reset(bool saveProjectSettingsImmediately = false) | |
| { | |
| SetValue(defaultValue, saveProjectSettingsImmediately); | |
| } | |
| void Init() | |
| { | |
| if (!m_Initialized) | |
| { | |
| if (m_Scope == SettingsScope.Project && settings == null) | |
| throw new Exception("UserSetting \"" + m_Key + "\" is attempting to access SettingsScope.Project setting with no Settings instance!"); | |
| m_Initialized = true; | |
| // DeepCopy uses EditorJsonUtility which is not permitted during construction | |
| m_DefaultValue = ValueWrapper<T>.DeepCopy(m_Value); | |
| if (settings.ContainsKey<T>(m_Key, m_Scope)) | |
| m_Value = settings.Get<T>(m_Key, m_Scope); | |
| else | |
| settings.Set<T>(m_Key, m_Value, m_Scope); | |
| } | |
| } | |
| /// <value> | |
| /// The default value for this setting. | |
| /// </value> | |
| public T defaultValue | |
| { | |
| get | |
| { | |
| Init(); | |
| return ValueWrapper<T>.DeepCopy(m_DefaultValue); | |
| } | |
| } | |
| /// <value> | |
| /// The currently stored value. | |
| /// </value> | |
| public T value | |
| { | |
| get | |
| { | |
| Init(); | |
| return m_Value; | |
| } | |
| set { SetValue(value); } | |
| } | |
| /// <summary> | |
| /// Implicit cast to backing type. | |
| /// </summary> | |
| /// <param name="pref">The UserSetting{T} to cast to {T}.</param> | |
| /// <returns> | |
| /// The currently stored <see cref="value"/>. | |
| /// </returns> | |
| public static implicit operator T(UserSetting<T> pref) | |
| { | |
| return pref.value; | |
| } | |
| /// <summary> | |
| /// Get a summary of this setting. | |
| /// </summary> | |
| /// <returns>A string summary of this setting.</returns> | |
| public override string ToString() | |
| { | |
| return string.Format("{0} setting. Key: {1} Value: {2}", scope, key, value); | |
| } | |
| } | |
| } | |