You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
11 KiB
C#
274 lines
11 KiB
C#
1 year ago
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace UnityEditor.SettingsManagement
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Settings manages a collection of <see cref="ISettingsRepository"/>.
|
||
|
/// </summary>
|
||
|
public sealed class Settings
|
||
|
{
|
||
|
ISettingsRepository[] m_SettingsRepositories;
|
||
|
|
||
|
/// <value>
|
||
|
/// An event that is raised prior to an `ISettingsRepository` serializing it's current state.
|
||
|
/// </value>
|
||
|
public event Action beforeSettingsSaved;
|
||
|
|
||
|
/// <value>
|
||
|
/// An event that is raised after an `ISettingsRepository` has serialized it's current state.
|
||
|
/// </value>
|
||
|
public event Action afterSettingsSaved;
|
||
|
|
||
|
Settings()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Create a new Settings instance with a <see cref="UserSettingsRepository"/> and <see cref="PackageSettingsRepository"/>.
|
||
|
/// </summary>
|
||
|
/// <param name="package">The package name. Ex, `com.unity.my-package`.</param>
|
||
|
/// <param name="settingsFileName">The name of the settings file. Defaults to "Settings."</param>
|
||
|
public Settings(string package, string settingsFileName = "Settings")
|
||
|
{
|
||
|
m_SettingsRepositories = new ISettingsRepository[]
|
||
|
{
|
||
|
new PackageSettingsRepository(package, settingsFileName),
|
||
|
new UserSettingsRepository()
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Create a new Settings instance with a collection of <see cref="ISettingsRepository"/>.
|
||
|
/// </summary>
|
||
|
public Settings(IEnumerable<ISettingsRepository> repositories)
|
||
|
{
|
||
|
m_SettingsRepositories = repositories.ToArray();
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Find a settings repository that matches the requested scope.
|
||
|
/// </summary>
|
||
|
/// <param name="scope">The scope of the settings repository to match.</param>
|
||
|
/// <returns>
|
||
|
/// An ISettingsRepository instance that is implementing the requested scope. May return null if no
|
||
|
/// matching repository is found.
|
||
|
/// </returns>
|
||
|
public ISettingsRepository GetRepository(SettingsScope scope)
|
||
|
{
|
||
|
foreach (var repo in m_SettingsRepositories)
|
||
|
if (repo.scope == scope)
|
||
|
return repo;
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Find a settings repository that matches the requested scope and name.
|
||
|
/// </summary>
|
||
|
/// <param name="scope">The scope of the settings repository to match.</param>
|
||
|
/// <param name="name">The name of the <see cref="ISettingsRepository"/> to match.</param>
|
||
|
/// <returns>
|
||
|
/// An <see cref="ISettingsRepository"/> instance that is implementing the requested scope, and matches name.
|
||
|
/// May return null if no matching repository is found.
|
||
|
/// </returns>
|
||
|
public ISettingsRepository GetRepository(SettingsScope scope, string name)
|
||
|
{
|
||
|
foreach (var repo in m_SettingsRepositories)
|
||
|
if (repo.scope == scope && string.Equals(repo.name, name))
|
||
|
return repo;
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Serialize the state of all settings repositories.
|
||
|
/// </summary>
|
||
|
public void Save()
|
||
|
{
|
||
|
if (beforeSettingsSaved != null)
|
||
|
beforeSettingsSaved();
|
||
|
|
||
|
foreach (var repo in m_SettingsRepositories)
|
||
|
repo.Save();
|
||
|
|
||
|
if (afterSettingsSaved != null)
|
||
|
afterSettingsSaved();
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Set a value for key of type T.
|
||
|
/// </summary>
|
||
|
/// <param name="key">The settings key.</param>
|
||
|
/// <param name="value">The value to set. Must be serializable.</param>
|
||
|
/// <param name="scope">Which scope this settings should be saved in.</param>
|
||
|
/// <typeparam name="T">Type of value.</typeparam>
|
||
|
public void Set<T>(string key, T value, SettingsScope scope = SettingsScope.Project)
|
||
|
{
|
||
|
bool foundScopeRepository = false;
|
||
|
|
||
|
foreach (var repo in m_SettingsRepositories)
|
||
|
{
|
||
|
if (repo.scope == scope)
|
||
|
{
|
||
|
repo.Set<T>(key, value);
|
||
|
foundScopeRepository = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!foundScopeRepository)
|
||
|
Debug.LogWarning("No repository for scope " + scope + " found!");
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Set a value for key of type T.
|
||
|
/// </summary>
|
||
|
/// <param name="key">The settings key.</param>
|
||
|
/// <param name="value">The value to set. Must be serializable.</param>
|
||
|
/// <param name="repositoryName">The repository name to match.</param>
|
||
|
/// <param name="scope">Which scope this settings should be saved in.</param>
|
||
|
/// <typeparam name="T">Type of value.</typeparam>
|
||
|
public void Set<T>(string key, T value, string repositoryName, SettingsScope scope = SettingsScope.Project)
|
||
|
{
|
||
|
bool foundScopeRepository = false;
|
||
|
|
||
|
foreach (var repo in m_SettingsRepositories)
|
||
|
{
|
||
|
if (repo.scope == scope && string.Equals(repo.name, repositoryName))
|
||
|
{
|
||
|
repo.Set<T>(key, value);
|
||
|
foundScopeRepository = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!foundScopeRepository)
|
||
|
Debug.LogWarning("No repository matching name \"" + repositoryName + "\" and scope " + scope + " found in settings.");
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Get a value with key of type T, or return the fallback value if no matching key is found.
|
||
|
/// </summary>
|
||
|
/// <param name="key">The settings key.</param>
|
||
|
/// <param name="scope">Which scope this settings should be retrieved from.</param>
|
||
|
/// <param name="fallback">If no key with a value of type T is found, this value is returned.</param>
|
||
|
/// <typeparam name="T">Type of value to search for.</typeparam>
|
||
|
public T Get<T>(string key, SettingsScope scope = SettingsScope.Project, T fallback = default(T))
|
||
|
{
|
||
|
foreach (var repo in m_SettingsRepositories)
|
||
|
{
|
||
|
if (repo.scope == scope)
|
||
|
return repo.Get<T>(key, fallback);
|
||
|
}
|
||
|
|
||
|
Debug.LogWarning("No repository for scope " + scope + " found!");
|
||
|
return fallback;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Get a value with key of type T, or return the fallback value if no matching key is found.
|
||
|
/// </summary>
|
||
|
/// <param name="key">The settings key.</param>
|
||
|
/// <param name="repositoryName">The repository name to match.</param>
|
||
|
/// <param name="scope">Which scope this settings should be retrieved from.</param>
|
||
|
/// <param name="fallback">If no key with a value of type T is found, this value is returned.</param>
|
||
|
/// <typeparam name="T">Type of value to search for.</typeparam>
|
||
|
public T Get<T>(string key, string repositoryName, SettingsScope scope = SettingsScope.Project, T fallback = default(T))
|
||
|
{
|
||
|
foreach (var repo in m_SettingsRepositories)
|
||
|
{
|
||
|
if (repo.scope == scope && string.Equals(repo.name, repositoryName))
|
||
|
return repo.Get<T>(key, fallback);
|
||
|
}
|
||
|
|
||
|
Debug.LogWarning("No repository matching name \"" + repositoryName + "\" and scope " + scope + " found in settings.");
|
||
|
return fallback;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Does the repository contain a setting with key and type.
|
||
|
/// </summary>
|
||
|
/// <param name="key">The settings key.</param>
|
||
|
/// <typeparam name="T">The type of value to search for.</typeparam>
|
||
|
/// <param name="scope">Which scope should be searched for matching key.</param>
|
||
|
/// <returns>True if a setting matching both key and type is found, false if no entry is found.</returns>
|
||
|
public bool ContainsKey<T>(string key, SettingsScope scope = SettingsScope.Project)
|
||
|
{
|
||
|
foreach (var repo in m_SettingsRepositories)
|
||
|
{
|
||
|
if (repo.scope == scope)
|
||
|
return repo.ContainsKey<T>(key);
|
||
|
}
|
||
|
|
||
|
Debug.LogWarning("No repository for scope " + scope + " found!");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Does the repository contain a setting with key and type.
|
||
|
/// </summary>
|
||
|
/// <param name="key">The settings key.</param>
|
||
|
/// <param name="repositoryName">The repository name to match.</param>
|
||
|
/// <typeparam name="T">The type of value to search for.</typeparam>
|
||
|
/// <param name="scope">Which scope should be searched for matching key.</param>
|
||
|
/// <returns>True if a setting matching both key and type is found, false if no entry is found.</returns>
|
||
|
public bool ContainsKey<T>(string key, string repositoryName, SettingsScope scope = SettingsScope.Project)
|
||
|
{
|
||
|
foreach (var repo in m_SettingsRepositories)
|
||
|
{
|
||
|
if (repo.scope == scope && string.Equals(repo.name, repositoryName))
|
||
|
return repo.ContainsKey<T>(key);
|
||
|
}
|
||
|
|
||
|
Debug.LogWarning("No repository matching name \"" + repositoryName + "\" and scope " + scope + " found in settings.");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Remove a key value pair from a settings repository.
|
||
|
/// </summary>
|
||
|
/// <param name="key">The key to remove.</param>
|
||
|
/// <param name="scope">Which scope should be searched for matching key.</param>
|
||
|
/// <typeparam name="T">The type that this key is pointing to.</typeparam>
|
||
|
public void DeleteKey<T>(string key, SettingsScope scope = SettingsScope.Project)
|
||
|
{
|
||
|
bool foundScopeRepository = false;
|
||
|
|
||
|
foreach (var repo in m_SettingsRepositories)
|
||
|
{
|
||
|
if (repo.scope == scope)
|
||
|
{
|
||
|
foundScopeRepository = true;
|
||
|
repo.Remove<T>(key);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!foundScopeRepository)
|
||
|
Debug.LogWarning("No repository for scope " + scope + " found!");
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Remove a key value pair from a settings repository.
|
||
|
/// </summary>
|
||
|
/// <param name="key">The key to remove.</param>
|
||
|
/// <param name="repositoryName">The repository name to match.</param>
|
||
|
/// <param name="scope">Which scope should be searched for matching key.</param>
|
||
|
/// <typeparam name="T">The type that this key is pointing to.</typeparam>
|
||
|
public void DeleteKey<T>(string key, string repositoryName, SettingsScope scope = SettingsScope.Project)
|
||
|
{
|
||
|
bool foundScopeRepository = false;
|
||
|
|
||
|
foreach (var repo in m_SettingsRepositories)
|
||
|
{
|
||
|
if (repo.scope == scope && string.Equals(repo.name, repositoryName))
|
||
|
{
|
||
|
foundScopeRepository = true;
|
||
|
repo.Remove<T>(key);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!foundScopeRepository)
|
||
|
Debug.LogWarning("No repository matching name \"" + repositoryName + "\" and scope " + scope + " found in settings.");
|
||
|
}
|
||
|
}
|
||
|
}
|