UserSettings.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using UnityEngine;
  6. namespace UnityEditor.SettingsManagement
  7. {
  8. /// <summary>
  9. /// A collection of utilities for working with settings.
  10. /// </summary>
  11. static class UserSettings
  12. {
  13. internal const string packageName = "com.unity.settings-manager";
  14. internal static string GetSettingsString(IEnumerable<Assembly> assemblies, params SettingsScope[] scopes)
  15. {
  16. var settings = FindUserSettings(assemblies, SettingVisibility.All);
  17. if (scopes != null && scopes.Length > 0)
  18. settings = settings.Where(x => scopes.Contains(x.scope));
  19. var sb = new System.Text.StringBuilder();
  20. Type t = null;
  21. foreach (var pref in settings.OrderBy(x => x.type.ToString()))
  22. {
  23. if (pref.type != t)
  24. {
  25. if (t != null)
  26. sb.AppendLine();
  27. t = pref.type;
  28. sb.AppendLine(pref.type.ToString());
  29. }
  30. var val = pref.GetValue();
  31. sb.AppendLine(string.Format("{0,-4}{1,-24}{2,-64}{3}", "", pref.scope, pref.key, val != null ? val.ToString() : "null"));
  32. }
  33. return sb.ToString();
  34. }
  35. /// <summary>
  36. /// Collect all registered UserSetting and HiddenSetting attributes.
  37. /// </summary>
  38. /// <returns></returns>
  39. public static IEnumerable<IUserSetting> FindUserSettings(IEnumerable<Assembly> assemblies, SettingVisibility visibility, BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
  40. {
  41. var loadedTypes = assemblies.SelectMany(x => x.GetTypes());
  42. var loadedFields = loadedTypes.SelectMany(x => x.GetFields(flags));
  43. var settings = new List<IUserSetting>();
  44. if ((visibility & (SettingVisibility.Visible | SettingVisibility.Unlisted)) > 0)
  45. {
  46. var attributes = loadedFields.Where(prop => Attribute.IsDefined(prop, typeof(UserSettingAttribute)));
  47. foreach (var field in attributes)
  48. {
  49. var userSetting = (UserSettingAttribute)Attribute.GetCustomAttribute(field, typeof(UserSettingAttribute));
  50. if (!field.IsStatic || !typeof(IUserSetting).IsAssignableFrom(field.FieldType))
  51. {
  52. Debug.LogError("[UserSetting] is only valid on static fields of a type implementing `interface IUserSetting`. \"" + field.Name + "\" (" + field.FieldType + ")\n" + field.DeclaringType);
  53. continue;
  54. }
  55. bool visible = userSetting.visibleInSettingsProvider;
  56. if (visible && (visibility & SettingVisibility.Visible) == SettingVisibility.Visible)
  57. settings.Add((IUserSetting)field.GetValue(null));
  58. else if (!visible && (visibility & SettingVisibility.Hidden) == SettingVisibility.Hidden)
  59. settings.Add((IUserSetting)field.GetValue(null));
  60. }
  61. }
  62. if ((visibility & SettingVisibility.Unlisted) == SettingVisibility.Unlisted)
  63. {
  64. var settingsKeys = loadedFields.Where(y => Attribute.IsDefined(y, typeof(SettingsKeyAttribute)));
  65. foreach (var field in settingsKeys)
  66. {
  67. if (field.IsStatic)
  68. {
  69. settings.Add((IUserSetting)field.GetValue(null));
  70. }
  71. else
  72. {
  73. var settingAttribute = (SettingsKeyAttribute)Attribute.GetCustomAttribute(field, typeof(SettingsKeyAttribute));
  74. var pref = CreateGenericPref(settingAttribute.key, settingAttribute.scope, field);
  75. if (pref != null)
  76. settings.Add(pref);
  77. else
  78. Debug.LogWarning("Failed adding [SettingsKey] " + field.FieldType + "\"" + settingAttribute.key + "\" in " + field.DeclaringType);
  79. }
  80. }
  81. }
  82. if ((visibility & SettingVisibility.Unregistered) == SettingVisibility.Unregistered)
  83. {
  84. var unregisterd = loadedFields.Where(y => typeof(IUserSetting).IsAssignableFrom(y.FieldType)
  85. && !Attribute.IsDefined(y, typeof(SettingsKeyAttribute))
  86. && !Attribute.IsDefined(y, typeof(UserSettingAttribute)));
  87. foreach (var field in unregisterd)
  88. {
  89. if (field.IsStatic)
  90. {
  91. settings.Add((IUserSetting)field.GetValue(null));
  92. }
  93. else
  94. {
  95. #if PB_DEBUG
  96. Log.Warning("Found unregistered instance field: "
  97. + field.FieldType
  98. + " "
  99. + field.Name
  100. + " in " + field.DeclaringType);
  101. #endif
  102. }
  103. }
  104. }
  105. return settings;
  106. }
  107. static IUserSetting CreateGenericPref(string key, SettingsScope scope, FieldInfo field)
  108. {
  109. try
  110. {
  111. var type = field.FieldType;
  112. if (typeof(IUserSetting).IsAssignableFrom(type) && type.IsGenericType)
  113. type = type.GetGenericArguments().FirstOrDefault();
  114. var genericPrefClass = typeof(UserSetting<>).MakeGenericType(type);
  115. var defaultValue = type.IsValueType ? Activator.CreateInstance(type) : null;
  116. return (IUserSetting)Activator.CreateInstance(genericPrefClass, new object[] { key, defaultValue, scope });
  117. }
  118. catch
  119. {
  120. return null;
  121. }
  122. }
  123. }
  124. }