using System;
using UnityEngine;
namespace UnityEditor.SettingsManagement
{
[Flags]
enum SettingVisibility
{
None = 0 << 0,
///
/// Matches any static field implementing IUserSetting and tagged with [UserSettingAttribute(visibleInSettingsProvider = true)].
/// These fields are automatically scraped by the SettingsProvider and displayed.
///
Visible = 1 << 0,
///
/// Matches any static field implementing IUserSetting and tagged with [UserSettingAttribute(visibleInSettingsProvider = false)].
/// 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].
///
Hidden = 1 << 1,
///
/// A static or instance field tagged with [SettingsKeyAttribute].
/// Unlisted settings are not shown in the SettingsProvider, but are reset to default values by the "Reset All"
/// context menu.
///
Unlisted = 1 << 2,
///
/// A static field implementing IUserSetting that is not marked with any setting attribute.
/// Unregistered IUserSetting fields are not affected by the SettingsProvider.
///
Unregistered = 1 << 3,
All = Visible | Hidden | Unlisted | Unregistered
}
///
/// An interface that represents a user setting.
/// Types implementing IUserSetting are eligible for use with , which enables
/// fields to automatically populate the interface.
///
public interface IUserSetting
{
///
/// Implement this property to get the key for this value.
///
/// The key used to identify the settings entry. This is used along with the to uniquely identify the value.
string key { get; }
///
/// Implement this property to get the type of the stored value.
///
/// The type of value. This is used along with the to uniquely identify the value.
Type type { get; }
///
/// Implement this property to get the location in the UI where this setting will appear.
///
///
/// Indicates whether this is a setting
/// or a preference.
///
SettingsScope scope { get; }
///
/// Implement this property to get the name of the that this setting should be associated with.
/// If null, the first repository matching the is used.
///
/// The bare filename of this repository.
string settingsRepositoryName { get; }
///
/// Implement this property to get the instance to save and load this setting from.
///
/// A reference to instance.
Settings settings { get; }
///
/// Implement this method to return the stored settings value.
/// If you are implementing IUserSetting, you should cache this value.
///
///
/// The stored value.
///
object GetValue();
///
/// Implement this method to return the the default value for this setting.
///
///
/// The default value for this setting.
///
object GetDefaultValue();
///
/// Implement this method to set the value for this setting.
///
/// The new value.
///
/// True to immediately serialize the that is backing this value; or false to postpone.
/// If not serializing immediately, be sure to call .
///
void SetValue(object value, bool saveProjectSettingsImmediately = false);
///
/// Implement this method to explicitly update the that is backing this value.
/// 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.
///
void ApplyModifiedProperties();
///
/// Implement this method to set the current value back to the default.
///
/// True to immediately re-serialize project settings. By default, no values are updated.
void Reset(bool saveProjectSettingsImmediately = false);
///
/// Implement this method to delete the saved setting. This does not clear the current value.
///
///
/// True to immediately re-serialize project settings. By default, no values are updated.
void Delete(bool saveProjectSettingsImmediately = false);
}
///
/// A generic implementation of to use with a instance. This default
/// implementation assumes that the instance contains two interfaces:
/// - Project settings ()
/// - User preferences ()
///
/// Type of value.
public class UserSetting : IUserSetting
{
bool m_Initialized;
string m_Key;
string m_Repository;
T m_Value;
T m_DefaultValue;
SettingsScope m_Scope;
Settings m_Settings;
UserSetting() { }
///
/// Initializes and returns an instance of the UserSetting<T> type.
///
/// The instance to save and load this setting from.
/// The key for this value.
/// The default value for this key.
/// The scope for this setting. By default, the scope is the project.
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;
}
///
/// Initializes and returns an instance of the UserSetting<T> type using the specified repository.
///
/// The instance to save and load this setting from.
/// The name to save and load this setting from. Specify null to save to the first available instance.
/// The key for this value.
/// The default value for this key.
/// The scope for this setting. By default, the scope is the project.
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;
}
///
/// Gets the key for this value.
///
///
public string key
{
get { return m_Key; }
}
///
/// Gets the name of the repository that this setting is saved in.
///
///
public string settingsRepositoryName
{
get { return m_Repository; }
}
///
/// Gets the type that this setting represents (<T>).
///
///
public Type type
{
get { return typeof(T); }
}
///
/// Returns a copy of the default value.
///
///
/// The default value.
///
///
public object GetDefaultValue()
{
return defaultValue;
}
///
/// Returns the currently stored value.
///
///
/// The value that is currently set.
///
///
public object GetValue()
{
return value;
}
///
/// Gets the scope () where the instance saves
/// its data.
///
///
public SettingsScope scope
{
get { return m_Scope; }
}
///
/// Gets the instance to read from and save to.
///
///
public Settings settings
{
get { return m_Settings; }
}
///
/// Sets the value for this setting from the specified object.
///
/// The new value to set.
///
/// Set this value to true if you want to immediately serialize the
/// that is backing this value. By default, this is false.
///
/// **Note**: If not serializing immediately, you need to call .
///
///
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);
}
///
public void SetValue(T value, bool saveProjectSettingsImmediately = false)
{
Init();
m_Value = value;
settings.Set(key, m_Value, m_Scope);
if (saveProjectSettingsImmediately)
settings.Save();
}
///
/// Deletes the saved setting but doesn't clear the current value.
///
///
/// Set this value to true if you want to immediately serialize the
/// that is backing this value. By default, this is false.
///
/// **Note**: If not serializing immediately, you need to call .
///
///
///
public void Delete(bool saveProjectSettingsImmediately = false)
{
settings.DeleteKey(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.DeepCopy(m_DefaultValue);
m_Initialized = false;
}
///
/// Forces Unity to serialize the changed properties to the that is backing this value.
/// When the inspected type is a reference value, it is possible to change properties without affecting the
/// backing setting.
///
///
public void ApplyModifiedProperties()
{
settings.Set(key, m_Value, m_Scope);
settings.Save();
}
///
/// Sets the current value back to the default.
///
///
/// Set this value to true if you want to immediately serialize the
/// that is backing this value. By default, this is false.
///
/// **Note**: If not serializing immediately, you need to call .
///
///
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.DeepCopy(m_Value);
if (settings.ContainsKey(m_Key, m_Scope))
m_Value = settings.Get(m_Key, m_Scope);
else
settings.Set(m_Key, m_Value, m_Scope);
}
}
///
/// Gets the default value for this setting.
///
public T defaultValue
{
get
{
Init();
return ValueWrapper.DeepCopy(m_DefaultValue);
}
}
///
/// Gets or sets the currently stored value.
///
public T value
{
get
{
Init();
return m_Value;
}
set { SetValue(value); }
}
///
/// Implicit casts this setting to the backing type `T`.
///
/// The UserSetting<T> to cast to `T`.
///
/// The currently stored .
///
public static implicit operator T(UserSetting pref)
{
return pref.value;
}
///
/// Returns a string representation of this setting.
///
/// A string summary of this setting of format "[scope] setting. Key: [key] Value: [value]".
public override string ToString()
{
return string.Format("{0} setting. Key: {1} Value: {2}", scope, key, value);
}
}
}