Add assets
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using Cainos.LucidEditor;
|
||||
|
||||
namespace Cainos.LucidEditor
|
||||
{
|
||||
internal static class InspectorPropertyUtil
|
||||
{
|
||||
public static IEnumerable<InspectorProperty> CreateProperties(SerializedObject serializedObject)
|
||||
{
|
||||
var list = new List<InspectorProperty>();
|
||||
SerializedProperty iterator = serializedObject.GetIterator();
|
||||
|
||||
iterator.NextVisible(true);
|
||||
while (iterator.NextVisible(false))
|
||||
{
|
||||
InspectorField ip = new InspectorField(iterator.Copy(), iterator.GetAttributes<Attribute>(true));
|
||||
list.Add(ip);
|
||||
}
|
||||
|
||||
list.AddRange(CreateEditableProperties(serializedObject, serializedObject.targetObject));
|
||||
list.AddRange(CreateButtonsAndNonSerializedProperties(serializedObject, serializedObject.targetObject));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static IEnumerable<InspectorProperty> CreateChildProperties(InspectorField property)
|
||||
{
|
||||
var list = new List<InspectorProperty>();
|
||||
|
||||
if (property.serializedProperty.hasVisibleChildren &&
|
||||
(property.serializedProperty.propertyType == SerializedPropertyType.Generic || property.serializedProperty.propertyType == SerializedPropertyType.ManagedReference) &&
|
||||
!property.serializedProperty.isArray &&
|
||||
!TypeUtil.HasCustomDrawerType(TypeUtil.GetType(property.serializedProperty.type)))
|
||||
{
|
||||
var iterator = property.serializedProperty.Copy();
|
||||
|
||||
iterator.NextVisible(true);
|
||||
int depth = iterator.depth;
|
||||
list.Add(new InspectorField(iterator.Copy(), iterator.GetAttributes<Attribute>(true)));
|
||||
|
||||
while (iterator.NextVisible(false))
|
||||
{
|
||||
if (iterator.depth != depth) break;
|
||||
list.Add(new InspectorField(iterator.Copy(), iterator.GetAttributes<Attribute>(true)));
|
||||
}
|
||||
|
||||
object obj = property.serializedProperty.GetValue<object>();
|
||||
list.AddRange(CreateButtonsAndNonSerializedProperties(property.serializedProperty.serializedObject, obj));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static IEnumerable<InspectorProperty> CreateButtonsAndNonSerializedProperties(SerializedObject serializedObject, object targetObject)
|
||||
{
|
||||
var list = new List<InspectorProperty>();
|
||||
|
||||
foreach (MemberInfo memberInfo in ReflectionUtil.GetAllMembers(targetObject.GetType(), (BindingFlags)(-1), inherit: true))
|
||||
{
|
||||
//field
|
||||
if (memberInfo is FieldInfo fieldInfo)
|
||||
{
|
||||
if (fieldInfo.IsPublic || fieldInfo.GetCustomAttribute<SerializeField>() == null)
|
||||
{
|
||||
ShowInInspectorAttribute showInInspector = fieldInfo.GetCustomAttribute<ShowInInspectorAttribute>();
|
||||
if (showInInspector != null)
|
||||
{
|
||||
list.Add(new NonSerializedInspectorProperty(serializedObject, targetObject, fieldInfo.Name, fieldInfo.GetCustomAttributes().ToArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
//property
|
||||
//modified: property is now handled in CreateEditableProperties to support editing
|
||||
//else if (memberInfo is PropertyInfo propertyInfo)
|
||||
//{
|
||||
// MethodInfo getterInfo = propertyInfo.GetGetMethod();
|
||||
// if (getterInfo != null)
|
||||
// {
|
||||
// if (getterInfo.IsPublic || propertyInfo.GetCustomAttribute<SerializeField>() == null)
|
||||
// {
|
||||
// ShowInInspectorAttribute showInInspector = propertyInfo.GetCustomAttribute<ShowInInspectorAttribute>();
|
||||
// if (showInInspector != null)
|
||||
// {
|
||||
// list.Add(new NonSerializedInspectorProperty(serializedObject, targetObject, propertyInfo.Name, propertyInfo.GetCustomAttributes().ToArray()));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
//method
|
||||
else if (memberInfo is MethodInfo methodInfo)
|
||||
{
|
||||
ShowInInspectorAttribute showInInspector = methodInfo.GetCustomAttribute<ShowInInspectorAttribute>();
|
||||
if (showInInspector != null)
|
||||
{
|
||||
list.Add(new NonSerializedInspectorProperty(serializedObject, targetObject, methodInfo.Name, methodInfo.GetCustomAttributes().ToArray()));
|
||||
}
|
||||
|
||||
ButtonAttribute buttonAttribute = methodInfo.GetCustomAttribute<ButtonAttribute>();
|
||||
if (buttonAttribute != null)
|
||||
{
|
||||
InspectorButton ib;
|
||||
if (string.IsNullOrEmpty(buttonAttribute.label))
|
||||
{
|
||||
ib = new InspectorButton(serializedObject, serializedObject.targetObject, methodInfo, buttonAttribute.size);
|
||||
}
|
||||
else
|
||||
{
|
||||
ib = new InspectorButton(serializedObject, serializedObject.targetObject, methodInfo, buttonAttribute.label, buttonAttribute.size);
|
||||
}
|
||||
list.Add(ib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
//draw editable property
|
||||
public static IEnumerable<InspectorProperty> CreateEditableProperties(SerializedObject serializedObject, object targetObject)
|
||||
{
|
||||
var list = new List<InspectorProperty>();
|
||||
|
||||
foreach (MemberInfo memberInfo in ReflectionUtil.GetAllMembers(targetObject.GetType(), (BindingFlags)(-1), inherit: true))
|
||||
{
|
||||
if (memberInfo is PropertyInfo propertyInfo)
|
||||
{
|
||||
MethodInfo getterInfo = propertyInfo.GetGetMethod();
|
||||
if (getterInfo != null)
|
||||
{
|
||||
ShowInInspectorAttribute showInInspector = propertyInfo.GetCustomAttribute<ShowInInspectorAttribute>();
|
||||
if (showInInspector != null)
|
||||
{
|
||||
list.Add(new EditableInspectorProperty(serializedObject, targetObject, propertyInfo.Name, propertyInfo.GetCustomAttributes().ToArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static IEnumerable<InspectorProperty> GroupProperties(IEnumerable<InspectorProperty> properties)
|
||||
{
|
||||
List<List<InspectorProperty>> groupList = new List<List<InspectorProperty>>();
|
||||
|
||||
List<InspectorProperty> propertyList = new List<InspectorProperty>(properties);
|
||||
List<InspectorProperty> usedProperties = new List<InspectorProperty>();
|
||||
|
||||
Dictionary<InspectorProperty, List<PropertyGroupAttribute>> paDictionary = new Dictionary<InspectorProperty, List<PropertyGroupAttribute>>();
|
||||
foreach (InspectorProperty property in propertyList)
|
||||
{
|
||||
paDictionary.Add(property, new List<PropertyGroupAttribute>());
|
||||
paDictionary[property].AddRange(
|
||||
property.attributes
|
||||
.Where(x => x is PropertyGroupAttribute)
|
||||
.Select(x => (PropertyGroupAttribute)x)
|
||||
);
|
||||
}
|
||||
|
||||
int depth = 0;
|
||||
while (propertyList.Count > 0)
|
||||
{
|
||||
groupList.Add(new List<InspectorProperty>());
|
||||
|
||||
foreach (InspectorProperty property in propertyList)
|
||||
{
|
||||
PropertyGroupAttribute attribute = paDictionary[property].FirstOrDefault(x => x.groupDepth == depth);
|
||||
|
||||
if (attribute != null)
|
||||
{
|
||||
string[] hierarchy = attribute.path.Split('/');
|
||||
string currentPath = string.Empty;
|
||||
InspectorPropertyGroup group = null;
|
||||
|
||||
for (int i = 0; i < hierarchy.Length; i++)
|
||||
{
|
||||
currentPath += hierarchy[i];
|
||||
|
||||
InspectorPropertyGroup newGroup = groupList[i]
|
||||
.Where(x => x is InspectorPropertyGroup)
|
||||
.Select(x => (InspectorPropertyGroup)x)
|
||||
.FirstOrDefault(x => x.path.Split('/')[i] == hierarchy[i]);
|
||||
|
||||
if (newGroup == null)
|
||||
{
|
||||
newGroup = new InspectorPropertyGroup(currentPath, property.serializedObject, attribute);
|
||||
groupList[i].Add(newGroup);
|
||||
group?.Add(newGroup);
|
||||
}
|
||||
|
||||
group = newGroup;
|
||||
currentPath += '/';
|
||||
}
|
||||
|
||||
paDictionary[property].RemoveAll(x => x.groupDepth == depth);
|
||||
if (paDictionary[property].Count == 0)
|
||||
{
|
||||
group.Add(property);
|
||||
usedProperties.Add(property);
|
||||
}
|
||||
}
|
||||
else if (paDictionary[property].Count == 0)
|
||||
{
|
||||
groupList[0].Add(property);
|
||||
usedProperties.Add(property);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (InspectorProperty property in usedProperties)
|
||||
{
|
||||
propertyList.Remove(property);
|
||||
}
|
||||
usedProperties.Clear();
|
||||
depth++;
|
||||
}
|
||||
|
||||
return groupList.Count > 0 ? groupList[0] : new List<InspectorProperty>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb96b6984d4004d9c855f20b38e1b75c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using Cainos.LucidEditor;
|
||||
|
||||
namespace Cainos.LucidEditor
|
||||
{
|
||||
internal static class ProcessorUtil
|
||||
{
|
||||
private static Type[] cacheAttributeProcessorTypes;
|
||||
private static Type[] cacheGroupProcessorTypes;
|
||||
|
||||
public static PropertyProcessor CreateAttributeProcessor(InspectorProperty property, Attribute attribute)
|
||||
{
|
||||
if (cacheAttributeProcessorTypes == null)
|
||||
{
|
||||
cacheAttributeProcessorTypes = Assembly.GetAssembly(typeof(PropertyProcessor))
|
||||
.GetTypes()
|
||||
.Where(x => x.IsSubclassOf(typeof(PropertyProcessor)) && !x.IsAbstract)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
foreach (Type t in cacheAttributeProcessorTypes)
|
||||
{
|
||||
if (t.IsDefined(typeof(CustomAttributeProcessorAttribute), false))
|
||||
{
|
||||
CustomAttributeProcessorAttribute a = t.GetCustomAttributes(typeof(CustomAttributeProcessorAttribute), false)[0] as CustomAttributeProcessorAttribute;
|
||||
if (a.type == attribute.GetType())
|
||||
{
|
||||
PropertyProcessor processor = (PropertyProcessor)Activator.CreateInstance(t);
|
||||
processor._attribute = attribute;
|
||||
processor._inspectorProperty = property;
|
||||
return processor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PropertyGroupProcessor CreateGroupProcessor(InspectorPropertyGroup group, SerializedObject serializedObject, PropertyGroupAttribute attribute)
|
||||
{
|
||||
if (attribute == null) return null;
|
||||
|
||||
if (cacheGroupProcessorTypes == null)
|
||||
{
|
||||
cacheGroupProcessorTypes = Assembly.GetAssembly(typeof(PropertyGroupProcessor))
|
||||
.GetTypes()
|
||||
.Where(x => x.IsSubclassOf(typeof(PropertyGroupProcessor)) && !x.IsAbstract)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
foreach (Type t in cacheGroupProcessorTypes)
|
||||
{
|
||||
if (t.IsDefined(typeof(CustomGroupProcessorAttribute), false))
|
||||
{
|
||||
CustomGroupProcessorAttribute a = t.GetCustomAttributes(typeof(CustomGroupProcessorAttribute), false)[0] as CustomGroupProcessorAttribute;
|
||||
|
||||
if (a.type == attribute.GetType())
|
||||
{
|
||||
PropertyGroupProcessor processor = (PropertyGroupProcessor)Activator.CreateInstance(t);
|
||||
processor._attribute = attribute;
|
||||
processor._group = group;
|
||||
processor.serializedObject = serializedObject;
|
||||
|
||||
return processor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 739804b6bf10a4611bfb1a74b476cb8f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,273 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace Cainos.LucidEditor
|
||||
{
|
||||
internal static class ReflectionUtil
|
||||
{
|
||||
private static Dictionary<(Type, string, BindingFlags, bool), FieldInfo> cacheFieldInfo = new Dictionary<(Type, string, BindingFlags, bool), FieldInfo>();
|
||||
private static Dictionary<(Type, string, BindingFlags, bool), PropertyInfo> cachePropertyInfo = new Dictionary<(Type, string, BindingFlags, bool), PropertyInfo>();
|
||||
private static Dictionary<(Type, BindingFlags, bool), MemberInfo[]> cacheAllMembers = new Dictionary<(Type, BindingFlags, bool), MemberInfo[]>();
|
||||
// private static Dictionary<(object, BindingFlags), MethodInfo[]> cacheAllMethods = new Dictionary<(object, BindingFlags), MethodInfo[]>();
|
||||
|
||||
private static Dictionary<(object, string), Func<object>> cacheGetFieldValue = new Dictionary<(object, string), Func<object>>();
|
||||
private static Dictionary<(object, string), Func<object>> cacheGetPropertyValue = new Dictionary<(object, string), Func<object>>();
|
||||
private static Dictionary<(object, string), Func<object>> cacheGetMethodValue = new Dictionary<(object, string), Func<object>>();
|
||||
|
||||
public static object GetFieldValue(object target, Type type, string name, BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
|
||||
{
|
||||
if (cacheGetFieldValue.ContainsKey((target, name)))
|
||||
{
|
||||
if (cacheGetFieldValue[(target, name)] == null) return null;
|
||||
else return cacheGetFieldValue[(target, name)].Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
FieldInfo info = type.GetField(name, bindingAttr);
|
||||
if (info == null)
|
||||
{
|
||||
cacheGetFieldValue.Add((target, name), null);
|
||||
return null;
|
||||
}
|
||||
|
||||
var lambda = Expression.Lambda<Func<object>>(
|
||||
Expression.Convert(Expression.Field(info.IsStatic ? null : Expression.Constant(target), info), typeof(object))
|
||||
);
|
||||
|
||||
cacheGetFieldValue.Add((target, name), lambda.Compile());
|
||||
|
||||
return cacheGetFieldValue[(target, name)].Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public static object GetPropertyValue(object target, Type type, string name, BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
|
||||
{
|
||||
if (cacheGetPropertyValue.ContainsKey((target, name)))
|
||||
{
|
||||
if (cacheGetPropertyValue[(target, name)] == null) return null;
|
||||
else return cacheGetPropertyValue[(target, name)].Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
PropertyInfo info = type.GetProperty(name, bindingAttr);
|
||||
if (info == null)
|
||||
{
|
||||
cacheGetPropertyValue.Add((target, name), null);
|
||||
return null;
|
||||
}
|
||||
|
||||
var lambda = Expression.Lambda<Func<object>>(
|
||||
Expression.Convert(Expression.Property(info.GetGetMethod(true).IsStatic ? null : Expression.Constant(target), info), typeof(object))
|
||||
);
|
||||
|
||||
cacheGetPropertyValue.Add((target, name), lambda.Compile());
|
||||
|
||||
return cacheGetPropertyValue[(target, name)].Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public static object GetMethodValue(object target, Type type, string name, BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
|
||||
{
|
||||
if (cacheGetMethodValue.ContainsKey((target, name)))
|
||||
{
|
||||
if (cacheGetMethodValue[(target, name)] == null) return null;
|
||||
else return cacheGetMethodValue[(target, name)].Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
MethodInfo info = type.GetMethod(name, bindingAttr);
|
||||
if (info == null)
|
||||
{
|
||||
cacheGetMethodValue.Add((target, name), null);
|
||||
return null;
|
||||
}
|
||||
|
||||
var lambda = Expression.Lambda<Func<object>>(
|
||||
Expression.Convert(Expression.Call(info.IsStatic ? null : Expression.Constant(target), info), typeof(object))
|
||||
);
|
||||
|
||||
cacheGetMethodValue.Add((target, name), lambda.Compile());
|
||||
|
||||
return cacheGetMethodValue[(target, name)].Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public static FieldInfo GetField(Type type, string name, BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static, bool inherit = false)
|
||||
{
|
||||
FieldInfo info;
|
||||
if (cacheFieldInfo.ContainsKey((type, name, bindingAttr, inherit)))
|
||||
{
|
||||
info = cacheFieldInfo[(type, name, bindingAttr, inherit)];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inherit)
|
||||
{
|
||||
info = GetAllFieldsIncludingInherited(type, bindingAttr).FirstOrDefault(x => x.Name == name);
|
||||
}
|
||||
else
|
||||
{
|
||||
info = type.GetField(name, bindingAttr);
|
||||
}
|
||||
cacheFieldInfo.Add((type, name, bindingAttr, inherit), info);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
private static IEnumerable<FieldInfo> GetAllFieldsIncludingInherited(Type type, BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
|
||||
{
|
||||
if (type == null) return Enumerable.Empty<FieldInfo>();
|
||||
return type.GetFields(bindingAttr).Concat(GetAllFieldsIncludingInherited(type.BaseType));
|
||||
}
|
||||
|
||||
public static PropertyInfo GetProperty(Type type, string name, BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static, bool inherit = false)
|
||||
{
|
||||
PropertyInfo info;
|
||||
if (cachePropertyInfo.ContainsKey((type, name, bindingAttr, inherit)))
|
||||
{
|
||||
info = cachePropertyInfo[(type, name, bindingAttr, inherit)];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inherit)
|
||||
{
|
||||
info = GetAllPropertiesIncludingInherited(type, bindingAttr).FirstOrDefault(x => x.Name == name);
|
||||
}
|
||||
else
|
||||
{
|
||||
info = type.GetProperty(name, bindingAttr);
|
||||
}
|
||||
cachePropertyInfo.Add((type, name, bindingAttr, inherit), info);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
private static IEnumerable<PropertyInfo> GetAllPropertiesIncludingInherited(Type type, BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
|
||||
{
|
||||
if (type == null) return Enumerable.Empty<PropertyInfo>();
|
||||
return type.GetProperties(bindingAttr).Concat(GetAllPropertiesIncludingInherited(type.BaseType));
|
||||
}
|
||||
|
||||
public static object GetValue(object target, string name, BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static, bool allowProperty = true, bool allowMethod = true)
|
||||
{
|
||||
if (target == null) return null;
|
||||
Type type = target.GetType();
|
||||
object result = null;
|
||||
|
||||
while (type != null)
|
||||
{
|
||||
result = GetFieldValue(target, type, name, bindingAttr);
|
||||
if (result != null) return result;
|
||||
|
||||
if (allowProperty)
|
||||
{
|
||||
result = GetPropertyValue(target, type, name, bindingAttr);
|
||||
if (result != null) return result;
|
||||
}
|
||||
|
||||
if (allowMethod)
|
||||
{
|
||||
result = GetMethodValue(target, type, name, bindingAttr);
|
||||
if (result != null) return result;
|
||||
}
|
||||
|
||||
type = type.BaseType;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static object GetValue(object target, string name, int index)
|
||||
{
|
||||
IEnumerable enumerable = ReflectionUtil.GetValue(target, name, allowMethod: false) as IEnumerable;
|
||||
if (enumerable == null) return null;
|
||||
IEnumerator enm = enumerable.GetEnumerator();
|
||||
|
||||
for (int i = 0; i <= index; i++)
|
||||
{
|
||||
if (!enm.MoveNext()) return null;
|
||||
}
|
||||
return enm.Current;
|
||||
}
|
||||
|
||||
public static bool GetValueBool(object target, string name)
|
||||
{
|
||||
if (GetValue(target, name) is bool cond)
|
||||
{
|
||||
return cond;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static MemberInfo[] GetAllMembers(Type type, BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static, bool inherit = false)
|
||||
{
|
||||
if (cacheAllMembers.ContainsKey((type, bindingAttr, inherit)))
|
||||
{
|
||||
return cacheAllMembers[(type, bindingAttr, inherit)];
|
||||
}
|
||||
else
|
||||
{
|
||||
MemberInfo[] memberInfos;
|
||||
if (inherit)
|
||||
{
|
||||
memberInfos = GetAllMembersIncludingInherited(type, bindingAttr).ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
memberInfos = type.GetMembers(bindingAttr);
|
||||
}
|
||||
cacheAllMembers.Add((type, bindingAttr, inherit), memberInfos);
|
||||
return memberInfos;
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<MemberInfo> GetAllMembersIncludingInherited(Type type, BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
|
||||
{
|
||||
if (type == null) return Enumerable.Empty<MemberInfo>();
|
||||
return type.GetMembers(bindingAttr).Concat(GetAllMembersIncludingInherited(type.BaseType));
|
||||
}
|
||||
|
||||
// public static MethodInfo[] GetAllMethods(object target, BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
|
||||
// {
|
||||
// if (cacheAllMethods.ContainsKey((target, bindingAttr)))
|
||||
// {
|
||||
// return cacheAllMethods[(target, bindingAttr)];
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// MethodInfo[] methodInfos = target.GetType().GetMethods(bindingAttr);
|
||||
// cacheAllMethods.Add((target, bindingAttr), methodInfos);
|
||||
// return methodInfos;
|
||||
// }
|
||||
// }
|
||||
|
||||
public static object Invoke(object target, string name, params object[] parameters)
|
||||
{
|
||||
if (target == null) return false;
|
||||
Type type = target.GetType();
|
||||
BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
|
||||
|
||||
while (type != null)
|
||||
{
|
||||
MethodInfo m = type.GetMethod(name, bindingAttr);
|
||||
if (m != null) return m.Invoke(m.IsStatic ? null : target, parameters);
|
||||
|
||||
type = type.BaseType;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool InvokeBool(object target, string name, params object[] parameters)
|
||||
{
|
||||
if (Invoke(target, name, parameters) is bool cond)
|
||||
{
|
||||
return cond;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb81ea54915e94ee3b2089488dc6106d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
125
Assets/Cainos/Third Party/Lucid Editor/Editor/Utils/TypeUtil.cs
Normal file
125
Assets/Cainos/Third Party/Lucid Editor/Editor/Utils/TypeUtil.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Cainos.LucidEditor
|
||||
{
|
||||
internal static class TypeUtil
|
||||
{
|
||||
private static List<Type> cacheCustomDrawerTypes;
|
||||
public static bool HasCustomDrawerType(Type type)
|
||||
{
|
||||
if (cacheCustomDrawerTypes == null)
|
||||
{
|
||||
cacheCustomDrawerTypes = new List<Type>();
|
||||
foreach (var drawer in TypeCache.GetTypesDerivedFrom<GUIDrawer>())
|
||||
{
|
||||
foreach (CustomPropertyDrawer customAttribute in drawer.GetCustomAttributes(typeof(CustomPropertyDrawer), true))
|
||||
{
|
||||
var field = customAttribute.GetType().GetField("m_Type", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var useForChildren = customAttribute.GetType().GetField("m_UseForChildren", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var t = (Type)field.GetValue(customAttribute);
|
||||
|
||||
if (!cacheCustomDrawerTypes.Contains(t)) cacheCustomDrawerTypes.Add(t);
|
||||
if ((bool)useForChildren.GetValue(customAttribute))
|
||||
{
|
||||
foreach (var d in Assembly.GetAssembly(t).GetTypes().Where(x => x.IsSubclassOf(t)))
|
||||
{
|
||||
if (!cacheCustomDrawerTypes.Contains(d)) cacheCustomDrawerTypes.Add(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cacheCustomDrawerTypes.Contains(type);
|
||||
}
|
||||
|
||||
private static List<Type> cacheTypes;
|
||||
public static Type GetType(string name)
|
||||
{
|
||||
foreach (Type type in GetAllTypes())
|
||||
{
|
||||
if (type.Name == name) return type;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IReadOnlyList<Type> GetAllTypes()
|
||||
{
|
||||
if (cacheTypes == null)
|
||||
{
|
||||
cacheTypes = new List<Type>();
|
||||
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
cacheTypes.AddRange(assembly.GetTypes());
|
||||
}
|
||||
}
|
||||
|
||||
return cacheTypes;
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> GetBaseClassesAndInterfaces(Type type, bool includeSelf = false)
|
||||
{
|
||||
List<Type> allTypes = new List<Type>();
|
||||
|
||||
if (includeSelf) allTypes.Add(type);
|
||||
|
||||
if (type.BaseType == typeof(object))
|
||||
{
|
||||
allTypes.AddRange(type.GetInterfaces());
|
||||
}
|
||||
else
|
||||
{
|
||||
allTypes.AddRange(
|
||||
Enumerable.Repeat(type.BaseType, 1)
|
||||
.Concat(type.GetInterfaces())
|
||||
.Concat(GetBaseClassesAndInterfaces(type.BaseType))
|
||||
.Distinct());
|
||||
}
|
||||
|
||||
return allTypes;
|
||||
}
|
||||
}
|
||||
|
||||
internal static class GenericTypeConverter<T>
|
||||
{
|
||||
private readonly static IDictionary<Type, object> funcs = new Dictionary<Type, object>();
|
||||
|
||||
// static GenericTypeConverter()
|
||||
// {
|
||||
// funcs.Add(typeof(int), new Func<int, int>(o => o));
|
||||
// funcs.Add(typeof(float), new Func<float, float>(o => o));
|
||||
// funcs.Add(typeof(double), new Func<double, double>(o => o));
|
||||
// funcs.Add(typeof(long), new Func<long, long>(o => o));
|
||||
// funcs.Add(typeof(bool), new Func<bool, bool>(o => o));
|
||||
// funcs.Add(typeof(string), new Func<string, string>(o => o));
|
||||
// funcs.Add(typeof(Enum), new Func<Enum, Enum>(o => o));
|
||||
// funcs.Add(typeof(Vector2Int), new Func<Vector2Int, Vector2Int>(o => o));
|
||||
// funcs.Add(typeof(Vector2), new Func<Vector2, Vector2>(o => o));
|
||||
// funcs.Add(typeof(Vector3Int), new Func<Vector3Int, Vector3Int>(o => o));
|
||||
// funcs.Add(typeof(Vector3), new Func<Vector3, Vector3>(o => o));
|
||||
// funcs.Add(typeof(Vector4), new Func<Vector4, Vector4>(o => o));
|
||||
// funcs.Add(typeof(RectInt), new Func<RectInt, RectInt>(o => o));
|
||||
// funcs.Add(typeof(Rect), new Func<Rect, Rect>(o => o));
|
||||
// funcs.Add(typeof(BoundsInt), new Func<BoundsInt, BoundsInt>(o => o));
|
||||
// funcs.Add(typeof(Bounds), new Func<Bounds, Bounds>(o => o));
|
||||
// funcs.Add(typeof(UnityEngine.Object), new Func<UnityEngine.Object, UnityEngine.Object>(o => o));
|
||||
// }
|
||||
|
||||
public static T Convert<TArgument>(TArgument t1)
|
||||
{
|
||||
Type argType = typeof(TArgument);
|
||||
if (!funcs.ContainsKey(argType))
|
||||
{
|
||||
funcs.Add(argType, new Func<T, T>(o => o));
|
||||
}
|
||||
|
||||
var f = funcs[argType] as Func<TArgument, T>;
|
||||
return f(t1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 995cb61483290490a88699758f50592e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user