formatting

This commit is contained in:
max 2022-12-28 14:03:46 +01:00
parent a0fa2c9b36
commit 0d04c50612
7 changed files with 72 additions and 62 deletions

View File

@ -1,5 +1,6 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using System;
using System.Collections.Generic;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
@ -13,14 +14,12 @@ public class SerializeReferenceButtonAttributeDrawer : PropertyDrawer
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{ {
EditorGUI.BeginProperty(position, label, property); EditorGUI.BeginProperty(position, label, property);
var labelPosition = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight); Rect labelPosition = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(labelPosition, label); EditorGUI.LabelField(labelPosition, label);
var typeRestrictions = SerializedReferenceUIDefaultTypeRestrictions.GetAllBuiltInTypeRestrictions(fieldInfo); IEnumerable<Func<Type, bool>> typeRestrictions = SerializedReferenceUIDefaultTypeRestrictions.GetAllBuiltInTypeRestrictions(fieldInfo);
property.DrawSelectionButtonForManagedReference(position, typeRestrictions); property.DrawSelectionButtonForManagedReference(position, typeRestrictions);
EditorGUI.PropertyField(position, property, GUIContent.none, true); EditorGUI.PropertyField(position, property, GUIContent.none, true);

View File

@ -1,5 +1,6 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using System;
using System.Collections.Generic;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
@ -15,7 +16,7 @@ public class SerializeReferenceMenuAttributeDrawer : PropertyDrawer
{ {
EditorGUI.BeginProperty(position, label, property); EditorGUI.BeginProperty(position, label, property);
var typeRestrictions = SerializedReferenceUIDefaultTypeRestrictions.GetAllBuiltInTypeRestrictions(fieldInfo); IEnumerable<Func<Type, bool>> typeRestrictions = SerializedReferenceUIDefaultTypeRestrictions.GetAllBuiltInTypeRestrictions(fieldInfo);
property.ShowContextMenuForManagedReferenceOnMouseMiddleButton(position, typeRestrictions); property.ShowContextMenuForManagedReferenceOnMouseMiddleButton(position, typeRestrictions);
EditorGUI.PropertyField(position, property, true); EditorGUI.PropertyField(position, property, true);
@ -23,4 +24,3 @@ public class SerializeReferenceMenuAttributeDrawer : PropertyDrawer
} }
} }
#endif #endif

View File

@ -1,5 +1,4 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -12,7 +11,7 @@ public static class ManagedReferenceUtility
/// Creates instance of passed type and assigns it to managed reference /// Creates instance of passed type and assigns it to managed reference
public static object AssignNewInstanceOfTypeToManagedReference(this SerializedProperty serializedProperty, Type type) public static object AssignNewInstanceOfTypeToManagedReference(this SerializedProperty serializedProperty, Type type)
{ {
var instance = Activator.CreateInstance(type); object instance = Activator.CreateInstance(type);
serializedProperty.serializedObject.Update(); serializedProperty.serializedObject.Update();
serializedProperty.managedReferenceValue = instance; serializedProperty.managedReferenceValue = instance;
@ -32,34 +31,44 @@ public static class ManagedReferenceUtility
/// Collects appropriate types based on managed reference field type and filters. Filters all derive /// Collects appropriate types based on managed reference field type and filters. Filters all derive
public static IEnumerable<Type> GetAppropriateTypesForAssigningToManagedReference(this SerializedProperty property, List<Func<Type, bool>> filters = null) public static IEnumerable<Type> GetAppropriateTypesForAssigningToManagedReference(this SerializedProperty property, List<Func<Type, bool>> filters = null)
{ {
var fieldType = property.GetManagedReferenceFieldType(); Type fieldType = property.GetManagedReferenceFieldType();
return GetAppropriateTypesForAssigningToManagedReference(fieldType, filters); return GetAppropriateTypesForAssigningToManagedReference(fieldType, filters);
} }
/// Filters derived types of field typ parameter and finds ones whose are compatible with managed reference and filters. /// Filters derived types of field typ parameter and finds ones whose are compatible with managed reference and filters.
public static IEnumerable<Type> GetAppropriateTypesForAssigningToManagedReference(Type fieldType, List<Func<Type, bool>> filters = null) public static IEnumerable<Type> GetAppropriateTypesForAssigningToManagedReference(Type fieldType, List<Func<Type, bool>> filters = null)
{ {
var appropriateTypes = new List<Type>(); List<Type> appropriateTypes = new List<Type>();
// Get and filter all appropriate types // Get and filter all appropriate types
var derivedTypes = TypeCache.GetTypesDerivedFrom(fieldType); TypeCache.TypeCollection derivedTypes = TypeCache.GetTypesDerivedFrom(fieldType);
foreach (var type in derivedTypes) foreach (Type type in derivedTypes)
{ {
// Skips unity engine Objects (because they are not serialized by SerializeReference) // Skips unity engine Objects (because they are not serialized by SerializeReference)
if (type.IsSubclassOf(typeof(Object))) if (type.IsSubclassOf(typeof(Object)))
{
continue; continue;
}
// Skip abstract classes because they should not be instantiated // Skip abstract classes because they should not be instantiated
if (type.IsAbstract) if (type.IsAbstract)
{
continue; continue;
// Skip generic classes because they can not be instantiated }
// Skip generic classes because they can not be instantiated
if (type.ContainsGenericParameters) if (type.ContainsGenericParameters)
{
continue; continue;
}
// Skip types that has no public empty constructors (activator can not create them) // Skip types that has no public empty constructors (activator can not create them)
if (type.IsClass && type.GetConstructor(Type.EmptyTypes) == null) // Structs still can be created (strangely) if (type.IsClass && type.GetConstructor(Type.EmptyTypes) == null) // Structs still can be created (strangely)
{
continue; continue;
}
// Filter types by provided filters if there is ones // Filter types by provided filters if there is ones
if (filters != null && filters.All(f => f == null || f.Invoke(type)) == false) if (filters != null && filters.All(f => f == null || f.Invoke(type)) == false)
{
continue; continue;
}
appropriateTypes.Add(type); appropriateTypes.Add(type);
} }
@ -70,9 +79,11 @@ public static class ManagedReferenceUtility
/// Gets real type of managed reference /// Gets real type of managed reference
public static Type GetManagedReferenceFieldType(this SerializedProperty property) public static Type GetManagedReferenceFieldType(this SerializedProperty property)
{ {
var realPropertyType = GetRealTypeFromTypename(property.managedReferenceFieldTypename); Type realPropertyType = GetRealTypeFromTypename(property.managedReferenceFieldTypename);
if (realPropertyType != null) if (realPropertyType != null)
{
return realPropertyType; return realPropertyType;
}
Debug.LogError($"Can not get field type of managed reference : {property.managedReferenceFieldTypename}"); Debug.LogError($"Can not get field type of managed reference : {property.managedReferenceFieldTypename}");
return null; return null;
@ -81,8 +92,9 @@ public static class ManagedReferenceUtility
/// Gets real type of managed reference's field typeName /// Gets real type of managed reference's field typeName
public static Type GetRealTypeFromTypename(string stringType) public static Type GetRealTypeFromTypename(string stringType)
{ {
var names = GetSplitNamesFromTypename(stringType); (string AssemblyName, string ClassName) = GetSplitNamesFromTypename(stringType);
var realType = Type.GetType($"{names.ClassName}, {names.AssemblyName}"); Type realType = Type.GetType($"{ClassName}, {AssemblyName}");
return realType; return realType;
} }
@ -90,11 +102,14 @@ public static class ManagedReferenceUtility
public static (string AssemblyName, string ClassName) GetSplitNamesFromTypename(string typename) public static (string AssemblyName, string ClassName) GetSplitNamesFromTypename(string typename)
{ {
if (string.IsNullOrEmpty(typename)) if (string.IsNullOrEmpty(typename))
{
return ("",""); return ("","");
}
string[] typeSplitString = typename.Split(char.Parse(" "));
string typeClassName = typeSplitString[1];
string typeAssemblyName = typeSplitString[0];
var typeSplitString = typename.Split(char.Parse(" "));
var typeClassName = typeSplitString[1];
var typeAssemblyName = typeSplitString[0];
return (typeAssemblyName, typeClassName); return (typeAssemblyName, typeClassName);
} }
} }

View File

@ -1,5 +1,4 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -17,7 +16,7 @@ public static class SerializeReferenceGenericSelectionMenu
/// And it will be performed on each Appropriate type found by TypeCache. /// And it will be performed on each Appropriate type found by TypeCache.
public static void ShowContextMenuForManagedReference(this SerializedProperty property, Rect position, IEnumerable<Func<Type,bool>> filters = null) public static void ShowContextMenuForManagedReference(this SerializedProperty property, Rect position, IEnumerable<Func<Type,bool>> filters = null)
{ {
var context = new GenericMenu(); GenericMenu context = new GenericMenu();
FillContextMenu(filters, context, property); FillContextMenu(filters, context, property);
context.DropDown(position); context.DropDown(position);
} }
@ -31,38 +30,40 @@ public static class SerializeReferenceGenericSelectionMenu
/// And it will be performed on each Appropriate type found by TypeCache. /// And it will be performed on each Appropriate type found by TypeCache.
public static void ShowContextMenuForManagedReference(this SerializedProperty property, IEnumerable<Func<Type, bool>> filters = null) public static void ShowContextMenuForManagedReference(this SerializedProperty property, IEnumerable<Func<Type, bool>> filters = null)
{ {
var context = new GenericMenu(); GenericMenu context = new GenericMenu();
FillContextMenu(filters, context, property); FillContextMenu(filters, context, property);
context.ShowAsContext(); context.ShowAsContext();
} }
private static void FillContextMenu(IEnumerable<Func<Type, bool>> enumerableFilters, GenericMenu contextMenu, SerializedProperty property) private static void FillContextMenu(IEnumerable<Func<Type, bool>> enumerableFilters, GenericMenu contextMenu, SerializedProperty property)
{ {
var filters = enumerableFilters.ToList();// Prevents possible multiple enumerations List<Func<Type, bool>> filters = enumerableFilters.ToList();// Prevents possible multiple enumerations
// Adds "Make Null" menu command // Adds "Make Null" menu command
contextMenu.AddItem(new GUIContent("Null"), false, property.SetManagedReferenceToNull); contextMenu.AddItem(new GUIContent("Null"), false, property.SetManagedReferenceToNull);
// Collects appropriate types // Collects appropriate types
var appropriateTypes = property.GetAppropriateTypesForAssigningToManagedReference(filters); IEnumerable<Type> appropriateTypes = property.GetAppropriateTypesForAssigningToManagedReference(filters);
// Adds appropriate types to menu // Adds appropriate types to menu
foreach (var appropriateType in appropriateTypes) foreach (Type appropriateType in appropriateTypes)
{
AddItemToContextMenu(appropriateType, contextMenu, property); AddItemToContextMenu(appropriateType, contextMenu, property);
}
} }
private static void AddItemToContextMenu(Type type, GenericMenu genericMenuContext, SerializedProperty property) private static void AddItemToContextMenu(Type type, GenericMenu genericMenuContext, SerializedProperty property)
{ {
var assemblyName = type.Assembly.ToString().Split('(', ',')[0]; string assemblyName = type.Assembly.ToString().Split('(', ',')[0];
var entryName = type + " ( " + assemblyName + " )"; string entryName = type + " ( " + assemblyName + " )";
genericMenuContext.AddItem(new GUIContent(entryName), false, AssignNewInstanceCommand, new GenericMenuParameterForAssignInstanceCommand(type, property)); genericMenuContext.AddItem(new GUIContent(entryName), false, AssignNewInstanceCommand, new GenericMenuParameterForAssignInstanceCommand(type, property));
} }
private static void AssignNewInstanceCommand(object objectGenericMenuParameter ) private static void AssignNewInstanceCommand(object objectGenericMenuParameter )
{ {
var parameter = (GenericMenuParameterForAssignInstanceCommand) objectGenericMenuParameter; GenericMenuParameterForAssignInstanceCommand parameter = (GenericMenuParameterForAssignInstanceCommand) objectGenericMenuParameter;
var type = parameter.Type; Type type = parameter.Type;
var property = parameter.Property; SerializedProperty property = parameter.Property;
property.AssignNewInstanceOfTypeToManagedReference(type); property.AssignNewInstanceOfTypeToManagedReference(type);
} }
@ -78,5 +79,4 @@ public static class SerializeReferenceGenericSelectionMenu
public readonly Type Type; public readonly Type Type;
} }
} }
#endif #endif

View File

@ -1,5 +1,4 @@
#if UNITY_EDITOR #if UNITY_EDITOR
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEditor; using UnityEditor;
@ -7,15 +6,15 @@ using UnityEngine;
public static class SerializeReferenceInspectorMiddleMouseMenu public static class SerializeReferenceInspectorMiddleMouseMenu
{ {
public static void ShowContextMenuForManagedReferenceOnMouseMiddleButton(this SerializedProperty property, public static void ShowContextMenuForManagedReferenceOnMouseMiddleButton(this SerializedProperty property, Rect position, IEnumerable<Func<Type, bool>> filters = null)
Rect position, IEnumerable<Func<Type, bool>> filters = null)
{ {
var e = Event.current; Event e = Event.current;
if (e.type != EventType.MouseDown || !position.Contains(e.mousePosition) || e.button != 2) if (e.type != EventType.MouseDown || !position.Contains(e.mousePosition) || e.button != 2)
{
return; return;
}
property.ShowContextMenuForManagedReference(filters); property.ShowContextMenuForManagedReference(filters);
} }
} }
#endif #endif

View File

@ -6,10 +6,10 @@ public static class SerializedReferenceUIDefaultTypeRestrictions
{ {
public static IEnumerable<Func<Type, bool>> GetAllBuiltInTypeRestrictions(FieldInfo fieldInfo) public static IEnumerable<Func<Type, bool>> GetAllBuiltInTypeRestrictions(FieldInfo fieldInfo)
{ {
var result = new List<Func<Type, bool>>(); List<Func<Type, bool>> result = new List<Func<Type, bool>>();
var attributeObjects = fieldInfo.GetCustomAttributes(false); object[] attributeObjects = fieldInfo.GetCustomAttributes(false);
foreach (var attributeObject in attributeObjects) foreach (object attributeObject in attributeObjects)
{ {
switch (attributeObject) switch (attributeObject)
{ {

View File

@ -1,13 +1,10 @@
 using System; using System;
using System.Linq; using System.Linq;
public static class SerializeReferenceTypeRestrictionFilters public static class SerializeReferenceTypeRestrictionFilters
{ {
public static Func<Type, bool> TypeIsNotSubclassOrEqualOrHasInterface(Type[] types) => type => public static Func<Type, bool> TypeIsNotSubclassOrEqualOrHasInterface(Type[] types) => type => TypeIsSubclassOrEqualOrHasInterface(types).Invoke(type) == false;
TypeIsSubclassOrEqualOrHasInterface(types).Invoke(type) == false; public static Func<Type, bool> TypeIsSubclassOrEqualOrHasInterface(Type[] types) => type => types.Any(e => e.IsInterface ? TypeHasInterface(type, e) : TypeIsSubclassOrEqual(type, e));
public static Func<Type, bool> TypeIsSubclassOrEqualOrHasInterface(Type[] types) => type =>
types.Any(e => e.IsInterface ? TypeHasInterface(type, e) : TypeIsSubclassOrEqual(type, e));
public static bool TypeIsSubclassOrEqual(Type type, Type comparator) => type.IsSubclassOf(comparator) || type == comparator; public static bool TypeIsSubclassOrEqual(Type type, Type comparator) => type.IsSubclassOf(comparator) || type == comparator;
public static bool TypeHasInterface(this Type type, Type comparator) => type.GetInterface(comparator.ToString()) != null; public static bool TypeHasInterface(this Type type, Type comparator) => type.GetInterface(comparator.ToString()) != null;