public IUseDrawer GetAttributeThatDefinesDrawer([NotNull] LinkedMemberInfo memberInfo, Type drawerType) { var attributes = memberInfo.GetAttributes(false, true); for (int n = 0, count = attributes.Length; n < count; n++) { var useDrawer = attributes[n] as IUseDrawer; if (useDrawer != null && useDrawer.GetDrawerType(memberInfo.Type, GetClassDrawerType(memberInfo.Type)) == drawerType) { return(useDrawer); } } attributes = memberInfo.Type.GetCustomAttributes(false); PluginAttributeConverterProvider.ConvertAll(ref attributes); for (int n = 0, count = attributes.Length; n < count; n++) { var useDrawer = attributes[n] as IUseDrawer; if (useDrawer != null && useDrawer.GetDrawerType(memberInfo.Type, GetClassDrawerType(memberInfo.Type)) == drawerType) { return(useDrawer); } } return(null); }
public static TAttribute[] GetAttributes <TAttribute>([NotNull] Type classType) where TAttribute : Attribute { List <TAttribute> list = null; object[] attributes; if (AttributesByClass.TryGetValue(classType, out attributes)) { for (int n = attributes.Length - 1; n >= 0; n--) { var cast = attributes[n] as TAttribute; if (cast != null) { if (list == null) { list = new List <TAttribute>(0); } list.Add(cast); } } } else { #if CSHARP_7_3_OR_NEWER foreach (var attributeType in PluginAttributeConverterProvider.GetAttributeTypeAndEachAlias(typeof(TAttribute))) { var attribute = classType.GetCustomAttribute(attributeType, InheritMemberAttributes); if (attribute != null) { TAttribute cast; if (PluginAttributeConverterProvider.TryConvert(attribute, out cast)) { if (list == null) { list = new List <TAttribute>(0); } list.Add(cast); } } } #else attributes = classType.GetCustomAttributes(typeof(TAttribute), InheritClassAttributes); PluginAttributeConverterProvider.ConvertAll(ref attributes); for (int n = attributes.Length - 1; n >= 0; n--) { var cast = attributes[n] as TAttribute; if (cast != null) { if (list == null) { list = new List <TAttribute>(0); } list.Add(cast); } } #endif } return(list == null ? ArrayPool <TAttribute> .ZeroSizeArray : list.ToArray()); }
public static object[] GetAttributes([NotNull] MemberInfo member, [NotNull] Type attributeType) { object[] attributes; if (AttributesByMember.TryGetValue(member, out attributes)) { return(attributes); } attributes = member.GetCustomAttributes(attributeType, InheritMemberAttributes); PluginAttributeConverterProvider.ConvertAll(ref attributes); return(attributes); }
public static object[] GetAttributes([NotNull] Type classType) { object[] attributes; if (AttributesByClass.TryGetValue(classType, out attributes)) { return(attributes); } attributes = classType.GetCustomAttributes(InheritClassAttributes); PluginAttributeConverterProvider.ConvertAll(ref attributes); #if THREAD_SAFE AttributesByClass[classType] = attributes; #else AttributesByClass.Add(classType, attributes); #endif return(attributes); }
public static void GetAttributes(Type classType, [NotNull] Type attributeType, [NotNull] List <object> addToList) { object[] attributes; if (AttributesByClass.TryGetValue(classType, out attributes)) { for (int n = attributes.Length - 1; n >= 0; n--) { if (attributeType.IsAssignableFrom(attributes[n].GetType())) { addToList.Add(attributes[n]); } } } else { attributes = classType.GetCustomAttributes(attributeType, InheritClassAttributes); PluginAttributeConverterProvider.ConvertAll(ref attributes); addToList.AddRange(attributes); } }
public static TAttribute GetAttribute <TAttribute>([NotNull] MemberInfo member) where TAttribute : Attribute { object[] attributes; if (AttributesByMember.TryGetValue(member, out attributes)) { for (int n = attributes.Length - 1; n >= 0; n--) { var cast = attributes[n] as TAttribute; if (cast != null) { return(cast); } } return(null); } #if CSHARP_7_3_OR_NEWER foreach (var attributeType in PluginAttributeConverterProvider.GetAttributeTypeAndEachAlias(typeof(TAttribute))) { var attribute = member.GetCustomAttribute(attributeType, InheritMemberAttributes); if (attribute != null) { TAttribute result; if (PluginAttributeConverterProvider.TryConvert(attribute, out result)) { return(result); } } } #else attributes = member.GetCustomAttributes(typeof(TAttribute), InheritMemberAttributes); if (attributes.Length > 0) { return(attributes[0] as TAttribute); } #endif return(null); }
public static void GetAttributes([NotNull] MemberInfo member, [NotNull] Type attributeType, [NotNull] List <object> addToList) { object[] attributes; if (AttributesByMember.TryGetValue(member, out attributes)) { for (int n = attributes.Length - 1; n >= 0; n--) { if (attributeType.IsAssignableFrom(attributes[n].GetType())) { addToList.Add(attributes[n]); } } } else { foreach (var type in PluginAttributeConverterProvider.GetAttributeTypeAndEachAlias(attributeType)) { attributes = member.GetCustomAttributes(type, InheritMemberAttributes); PluginAttributeConverterProvider.ConvertAll(ref attributes); addToList.AddRange(attributes); } } }
public static void GetAttributes <TAttribute>([NotNull] Type classType, [NotNull] List <TAttribute> addToList) where TAttribute : Attribute { object[] attributes; if (AttributesByClass.TryGetValue(classType, out attributes)) { for (int n = attributes.Length - 1; n >= 0; n--) { var cast = attributes[n] as TAttribute; if (cast != null) { addToList.Add(cast); } } } else { attributes = classType.GetCustomAttributes(typeof(TAttribute), InheritClassAttributes); PluginAttributeConverterProvider.ConvertAll(ref attributes); for (int n = attributes.Length - 1; n >= 0; n--) { addToList.Add(attributes[n] as TAttribute); } } }
public static TAttribute[] GetAttributes <TAttribute>([NotNull] MemberInfo member) where TAttribute : Attribute { object[] attributes; List <TAttribute> list = null; if (AttributesByMember.TryGetValue(member, out attributes)) { for (int n = attributes.Length - 1; n >= 0; n--) { var cast = attributes[n] as TAttribute; if (cast != null) { if (list == null) { list = new List <TAttribute>(0); } list.Add(cast); } } return(list == null ? ArrayPool <TAttribute> .ZeroSizeArray : list.ToArray()); } else { attributes = member.GetCustomAttributes(typeof(TAttribute), InheritMemberAttributes); PluginAttributeConverterProvider.ConvertAll(ref attributes); for (int n = attributes.Length - 1; n >= 0; n--) { if (list == null) { list = new List <TAttribute>(0); } list.Add(attributes[n] as TAttribute); } } return(list == null ? ArrayPool <TAttribute> .ZeroSizeArray : list.ToArray()); }
private void BuildDictionariesForInheritedTypes(DrawerProviderData drawerProviderData, Type[] drawerTypes, bool isFallback) { var fields = drawerProviderData.fields; var assetDrawers = drawerProviderData.assets; var components = drawerProviderData.components; var decoratorDrawers = drawerProviderData.decoratorDrawers; var propertyDrawersByAttributeType = drawerProviderData.propertyDrawersByAttributeType; for (int n = drawerTypes.Length - 1; n >= 0; n--) { var drawerType = drawerTypes[n]; var attributes = (DrawerForBaseAttribute[])drawerType.GetCustomAttributes(typeof(DrawerForBaseAttribute), false); for (int a = attributes.Length - 1; a >= 0; a--) { var attribute = attributes[a]; if (attribute.isFallback != isFallback) { continue; } if (!attribute.TargetExtendingTypes) { continue; } var type = attribute.Target; // if has no target type or target type is a value type // then there are no inhertied types that need to be added // for these drawers if (type == null || type.IsValueType) { continue; } #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_NONFALLBACK_DRAWER if (!isFallback) { Debug.Log(StringUtils.ToStringSansNamespace(type) + " inherited types handled by " + StringUtils.ToStringSansNamespace(drawerType)); } #endif var fieldAttribute = attribute as DrawerForFieldAttribute; if (fieldAttribute != null) { Type[] subjectTypes; if (type == Types.Enum) { subjectTypes = TypeExtensions.EnumTypesIncludingInvisible; } else if (type.IsInterface) { subjectTypes = type.GetImplementingTypes(true); } else { subjectTypes = type.GetExtendingTypes(true); } for (int t = subjectTypes.Length - 1; t >= 0; t--) { var subjectType = subjectTypes[t]; if (!fields.ContainsKey(subjectType)) { #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_ENUM_FIELDS if (drawerType == typeof(EnumDrawer)) { Debug.Log(subjectType.FullName + " handled by " + drawerType.Name + " because it's a base type of " + type.FullName); } #endif #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_DELEGATE_FIELDS if (drawerType == typeof(DelegateDrawer)) { Debug.Log(subjectType.FullName + " handled by " + drawerType.Name + " because it's a base type of " + type.FullName); } #endif #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_UNITY_OBJECT_FIELDS if (drawerType == typeof(ObjectReferenceDrawer)) { Debug.Log(subjectType.FullName + " handled by " + drawerType.Name + " because it's a base type of " + type.FullName); } #endif #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_FIELDS if (drawerType != typeof(EnumDrawer) && drawerType != typeof(DelegateDrawer) && drawerType != typeof(ObjectReferenceDrawer)) { Debug.Log(StringUtils.ToStringSansNamespace(subjectType) + " handled by " + StringUtils.ToStringSansNamespace(drawerType) + " because it's a base type of " + StringUtils.ToStringSansNamespace(type)); } #endif fields.Add(subjectType, drawerType); } } continue; } var decoratorDrawerAttribute = attribute as DrawerForDecoratorAttribute; if (decoratorDrawerAttribute != null) { var attributeTypes = PluginAttributeConverterProvider.GetAttributeTypeAndEachAlias(type); while (attributeTypes.MoveNext()) { var attributeType = attributeTypes.Current; var subjectTypes = attributeType.GetExtendingNonUnityObjectClassTypes(false); for (int t = subjectTypes.Length - 1; t >= 0; t--) { var subjectType = subjectTypes[t]; if (!decoratorDrawers.ContainsKey(subjectType)) { #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_DECORATOR_DRAWERS Debug.Log(subjectType.FullName + " handled by " + drawerType.Name + " because it's a base type of " + attributeType.FullName); #endif decoratorDrawers.Add(subjectType, drawerType); } } } continue; } var propertyDrawerAttribute = attribute as DrawerForAttributeAttribute; if (propertyDrawerAttribute != null) { var attributeTypes = PluginAttributeConverterProvider.GetAttributeTypeAndEachAlias(type); while (attributeTypes.MoveNext()) { var attributeType = attributeTypes.Current; var subjectTypes = attributeType.GetExtendingNonUnityObjectClassTypes(false); for (int t = subjectTypes.Length - 1; t >= 0; t--) { var subjectType = subjectTypes[t]; Dictionary <Type, Type> drawerTypesByFieldType; if (!propertyDrawersByAttributeType.TryGetValue(subjectType, out drawerTypesByFieldType)) { drawerTypesByFieldType = new Dictionary <Type, Type>(1); propertyDrawersByAttributeType.Add(subjectType, drawerTypesByFieldType); } var fieldType = propertyDrawerAttribute.valueType; if (!drawerTypesByFieldType.ContainsKey(fieldType)) { drawerTypesByFieldType.Add(fieldType, drawerType); #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_PROPERTY_DRAWERS Debug.Log(subjectType.Name + " handled by " + drawerType.Name + " with field type " + fieldType.Name + " because it's a base type of " + attributeType.FullName); #endif #if DEV_MODE && PI_ASSERTATIONS Debug.Assert(drawerTypesByFieldType[fieldType] == drawerType); #endif } #if DEV_MODE && PI_ASSERTATIONS Debug.Assert(propertyDrawersByAttributeType.ContainsKey(subjectType)); Debug.Assert(drawerTypesByFieldType.ContainsKey(fieldType)); #endif } } continue; } var componentAttribute = attribute as DrawerForComponentAttribute; if (componentAttribute != null) { var subjectTypes = type.IsInterface ? type.GetImplementingComponentTypes(true) : type.GetExtendingComponentTypes(true); for (int t = subjectTypes.Length - 1; t >= 0; t--) { var subjectType = subjectTypes[t]; if (subjectType.IsAbstract) { #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_COMPONENTS Debug.Log("Skipping component " + subjectType + " because it's abstract..."); #endif continue; } #if DEV_MODE && PI_ASSERTATIONS Debug.Assert(subjectType.IsComponent(), "DrawerForComponent attribute subject has to be Component type: " + StringUtils.ToString(type)); #endif if (!components.ContainsKey(subjectType)) { components.Add(subjectType, drawerType); } } continue; } var assetAttribute = attribute as DrawerForAssetAttribute; if (assetAttribute != null) { var subjectTypes = type.IsInterface ? type.GetImplementingUnityObjectTypes(true) : type.GetExtendingUnityObjectTypes(true); for (int t = subjectTypes.Length - 1; t >= 0; t--) { var subjectType = subjectTypes[t]; if (subjectType.IsAbstract) { #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_ASSETS Debug.Log("Skipping inherited asset type " + subjectType + " because it's abstract..."); #endif continue; } if (subjectType.IsComponent()) { #if DEV_MODE && PI_ASSERTATIONS Debug.Assert(!type.IsInterface, "DrawerForAsset attribute subject can not be Component type: " + StringUtils.ToString(type)); #endif continue; } if (!assetDrawers.ContainsKey(subjectType)) { #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_ASSETS Debug.Log(StringUtils.ToStringSansNamespace(subjectType) + " handled by " + StringUtils.ToStringSansNamespace(drawerType)); #endif assetDrawers.Add(subjectType, drawerType); } } } } } }
private void BuildDictionariesForExactTypes(DrawerProviderData drawersFor, Type[] drawerTypes, bool isFallback) { var fields = drawersFor.fields; var assetDrawers = drawersFor.assets; var components = drawersFor.components; var decoratorDrawers = drawersFor.decoratorDrawers; var propertyDrawersByAttributeType = drawersFor.propertyDrawersByAttributeType; var assetsByExtension = drawersFor.assetsByExtension; for (int n = drawerTypes.Length - 1; n >= 0; n--) { var drawerType = drawerTypes[n]; #if DEV_MODE && PI_ASSERTATIONS Debug.Assert(!drawerType.IsAbstract); #endif var attributes = (DrawerForBaseAttribute[])drawerType.GetCustomAttributes(typeof(DrawerForBaseAttribute), false); for (int a = attributes.Length - 1; a >= 0; a--) { var attribute = attributes[a]; #if DEV_MODE && PI_ASSERTATIONS attribute.AssertDataIsValid(drawerType); #endif if (attribute.isFallback != isFallback) { continue; } var type = attribute.Target; if (type != null) { #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_NONFALLBACK_DRAWER if (!isFallback) { Debug.Log(StringUtils.ToStringSansNamespace(type) + " handled by " + StringUtils.ToStringSansNamespace(drawerType)); } #endif var fieldAttribute = attribute as DrawerForFieldAttribute; if (fieldAttribute != null) { if (!fields.ContainsKey(type)) { #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_FIELDS Debug.Log(StringUtils.ToStringSansNamespace(type) + " handled by " + StringUtils.ToStringSansNamespace(drawerType)); #endif fields.Add(type, drawerType); } continue; } var assetAttribute = attribute as DrawerForAssetAttribute; if (assetAttribute != null) { if (!assetDrawers.ContainsKey(type)) { #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_ASSETS Debug.Log(StringUtils.ToStringSansNamespace(type) + " handled by " + StringUtils.ToStringSansNamespace(drawerType)); #endif assetDrawers.Add(type, drawerType); } continue; } var componentAttribute = attribute as DrawerForComponentAttribute; if (componentAttribute != null) { if (!components.ContainsKey(type)) { #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_COMPONENTS Debug.Log(StringUtils.ToStringSansNamespace(type) + " handled by " + StringUtils.ToStringSansNamespace(drawerType)); #endif components.Add(type, drawerType); } continue; } var decoratorDrawerAttribute = attribute as DrawerForDecoratorAttribute; if (decoratorDrawerAttribute != null) { var attributeTypes = PluginAttributeConverterProvider.GetAttributeTypeAndEachAlias(type); while (attributeTypes.MoveNext()) { var attributeType = attributeTypes.Current; if (!decoratorDrawers.ContainsKey(attributeType)) { #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_DECORATOR_DRAWERS Debug.Log(attributeType.FullName + " handled by " + drawerType.Name); #endif decoratorDrawers.Add(attributeType, drawerType); } } continue; } var propertyDrawerAttribute = attribute as DrawerForAttributeAttribute; if (propertyDrawerAttribute != null) { var attributeTypes = PluginAttributeConverterProvider.GetAttributeTypeAndEachAlias(type); while (attributeTypes.MoveNext()) { var attributeType = attributeTypes.Current; Dictionary <Type, Type> drawerTypesByFieldType; if (!propertyDrawersByAttributeType.TryGetValue(attributeType, out drawerTypesByFieldType)) { drawerTypesByFieldType = new Dictionary <Type, Type>(1); propertyDrawersByAttributeType.Add(attributeType, drawerTypesByFieldType); } var fieldType = propertyDrawerAttribute.valueType; if (!drawerTypesByFieldType.ContainsKey(fieldType)) { drawerTypesByFieldType.Add(fieldType, drawerType); #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_PROPERTY_DRAWERS Debug.Log(attributeType.FullName + " handled by " + drawerType.Name + " with field type " + fieldType.Name); #endif #if DEV_MODE && PI_ASSERTATIONS Debug.Assert(drawerTypesByFieldType[fieldType] == drawerType); #endif } #if DEV_MODE && PI_ASSERTATIONS Debug.Assert(propertyDrawersByAttributeType.ContainsKey(attributeType)); Debug.Assert(drawerTypesByFieldType.ContainsKey(fieldType)); #endif } continue; } var gameObjectDrawerAttribute = attribute as DrawerForGameObjectAttribute; if (gameObjectDrawerAttribute != null) { if (gameObjectDrawerAttribute.requireComponentOnGameObject == null) { if (drawersFor.gameObject == null || !gameObjectDrawerAttribute.isFallback) { drawersFor.gameObject = drawerType; } // Handle choosing between GameObjectDrawer and CategorizedGameObjectDrawer based on user preferences else if (drawerType == typeof(GameObjectDrawer)) { if (!InspectorUtility.Preferences.EnableCategorizedComponents && drawersFor.gameObject == typeof(CategorizedGameObjectDrawer)) { drawersFor.gameObject = drawerType; } } else if (drawerType == typeof(CategorizedGameObjectDrawer)) { if (InspectorUtility.Preferences.EnableCategorizedComponents && drawersFor.gameObject == typeof(GameObjectDrawer)) { drawersFor.gameObject = drawerType; } } } else { drawersFor.gameObjectByComponent[gameObjectDrawerAttribute.requireComponentOnGameObject] = drawerType; } } #if DEV_MODE else { Debug.LogError("Unrecognized DrawerForBaseAttribute type: " + attribute.GetType().Name); } #endif } else { var extensionAttribute = attribute as DrawerByExtensionAttribute; if (extensionAttribute != null) { var extension = extensionAttribute.fileExtension; #if DEV_MODE && PI_ASSERTATIONS Debug.Assert(!string.IsNullOrEmpty(extension), "fileExtension was null or empty on DrawerByExtension attribute of " + StringUtils.TypeToString(drawerType)); #endif if (!assetsByExtension.ContainsKey(extension)) { #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_ASSETS Debug.Log("Asset extension \"" + extension + "\" handled by " + StringUtils.ToStringSansNamespace(drawerType)); #endif assetsByExtension.Add(extension, drawerType); } #if DEV_MODE && PI_ASSERTATIONS Debug.Assert(assetsByExtension.ContainsKey(extension)); #endif } #if DEV_MODE else { Debug.LogWarning("Ignoring Attribute " + attribute.GetType().Name + " because it had a null Type"); } #endif } } } }