Rasagar/Library/PackageCache/com.unity.settings-manager/Editor/UserSettings.cs

142 lines
5.9 KiB
C#
Raw Normal View History

2024-08-26 13:07:20 -07:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
namespace UnityEditor.SettingsManagement
{
/// <summary>
/// A collection of utilities for working with settings.
/// </summary>
static class UserSettings
{
internal const string packageName = "com.unity.settings-manager";
internal static string GetSettingsString(IEnumerable<Assembly> assemblies, params SettingsScope[] scopes)
{
var settings = FindUserSettings(assemblies, SettingVisibility.All);
if (scopes != null && scopes.Length > 0)
settings = settings.Where(x => scopes.Contains(x.scope));
var sb = new System.Text.StringBuilder();
Type t = null;
foreach (var pref in settings.OrderBy(x => x.type.ToString()))
{
if (pref.type != t)
{
if (t != null)
sb.AppendLine();
t = pref.type;
sb.AppendLine(pref.type.ToString());
}
var val = pref.GetValue();
sb.AppendLine(string.Format("{0,-4}{1,-24}{2,-64}{3}", "", pref.scope, pref.key, val != null ? val.ToString() : "null"));
}
return sb.ToString();
}
/// <summary>
/// Collect all registered UserSetting and HiddenSetting attributes.
/// </summary>
/// <returns></returns>
public static IEnumerable<IUserSetting> FindUserSettings(IEnumerable<Assembly> assemblies, SettingVisibility visibility, BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
{
var loadedTypes = assemblies.SelectMany(x => x.GetTypes());
var loadedFields = loadedTypes.SelectMany(x => x.GetFields(flags));
var settings = new List<IUserSetting>();
if ((visibility & (SettingVisibility.Visible | SettingVisibility.Unlisted)) > 0)
{
var attributes = loadedFields.Where(prop => Attribute.IsDefined(prop, typeof(UserSettingAttribute)));
foreach (var field in attributes)
{
var userSetting = (UserSettingAttribute)Attribute.GetCustomAttribute(field, typeof(UserSettingAttribute));
if (!field.IsStatic || !typeof(IUserSetting).IsAssignableFrom(field.FieldType))
{
Debug.LogError("[UserSetting] is only valid on static fields of a type implementing `interface IUserSetting`. \"" + field.Name + "\" (" + field.FieldType + ")\n" + field.DeclaringType);
continue;
}
bool visible = userSetting.visibleInSettingsProvider;
if (visible && (visibility & SettingVisibility.Visible) == SettingVisibility.Visible)
settings.Add((IUserSetting)field.GetValue(null));
else if (!visible && (visibility & SettingVisibility.Hidden) == SettingVisibility.Hidden)
settings.Add((IUserSetting)field.GetValue(null));
}
}
if ((visibility & SettingVisibility.Unlisted) == SettingVisibility.Unlisted)
{
var settingsKeys = loadedFields.Where(y => Attribute.IsDefined(y, typeof(SettingsKeyAttribute)));
foreach (var field in settingsKeys)
{
if (field.IsStatic)
{
settings.Add((IUserSetting)field.GetValue(null));
}
else
{
var settingAttribute = (SettingsKeyAttribute)Attribute.GetCustomAttribute(field, typeof(SettingsKeyAttribute));
var pref = CreateGenericPref(settingAttribute.key, settingAttribute.scope, field);
if (pref != null)
settings.Add(pref);
else
Debug.LogWarning("Failed adding [SettingsKey] " + field.FieldType + "\"" + settingAttribute.key + "\" in " + field.DeclaringType);
}
}
}
if ((visibility & SettingVisibility.Unregistered) == SettingVisibility.Unregistered)
{
var unregisterd = loadedFields.Where(y => typeof(IUserSetting).IsAssignableFrom(y.FieldType)
&& !Attribute.IsDefined(y, typeof(SettingsKeyAttribute))
&& !Attribute.IsDefined(y, typeof(UserSettingAttribute)));
foreach (var field in unregisterd)
{
if (field.IsStatic)
{
settings.Add((IUserSetting)field.GetValue(null));
}
else
{
#if PB_DEBUG
Log.Warning("Found unregistered instance field: "
+ field.FieldType
+ " "
+ field.Name
+ " in " + field.DeclaringType);
#endif
}
}
}
return settings;
}
static IUserSetting CreateGenericPref(string key, SettingsScope scope, FieldInfo field)
{
try
{
var type = field.FieldType;
if (typeof(IUserSetting).IsAssignableFrom(type) && type.IsGenericType)
type = type.GetGenericArguments().FirstOrDefault();
var genericPrefClass = typeof(UserSetting<>).MakeGenericType(type);
var defaultValue = type.IsValueType ? Activator.CreateInstance(type) : null;
return (IUserSetting)Activator.CreateInstance(genericPrefClass, new object[] { key, defaultValue, scope });
}
catch
{
return null;
}
}
}
}