123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- using System;
- using UnityEngine;
- namespace UnityEditor.SettingsManagement
- {
- [Flags]
- 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);
- }
- }
- }
|