2023-06-21 13:28:15 -04: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 ;
}
}
}
}