module-inspector/Runtime/Utilities/ReflectionUtility.cs

231 lines
7.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
namespace Module.Inspector.Utilities
{
internal static class ReflectionUtility
{
#if UNITY_EDITOR
public static T GetValue<T>(object obj, string name)
{
return GetValue<T>(obj, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
}
public static T GetValue<T>(object obj, string name, BindingFlags flags)
{
FieldInfo field = obj.GetType().GetField(name, flags);
return field != null ? (T)field.GetValue(obj) : default;
}
public static T GetValue<T>(object obj, FieldInfo field)
{
return field != null ? (T)field.GetValue(obj) : default;
}
public static T[] GetArrayValue<T>(object obj, string name)
{
return GetArrayValue<T>(obj, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
}
public static T[] GetArrayValue<T>(object obj, string name, BindingFlags flags)
{
FieldInfo field = obj.GetType().GetField(name, flags);
return field != null ? (T[])field.GetValue(obj) : default;
}
public static void SetValue<T>(object obj, string name, T value)
{
SetValue(obj, name, value, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
}
public static void SetValue<T>(object obj, string name, T value, BindingFlags flags)
{
FieldInfo field = obj.GetType().GetField(name, flags);
if (field != null)
field.SetValue(obj, value);
}
public static void SetValue<T>(object obj, T value, FieldInfo field)
{
field.SetValue(obj, value);
}
public static void SetValue<T>(object obj, string name, T[] value)
{
SetValue(obj, name, value, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
}
public static void SetValue<T>(object obj, string name, T[] value, BindingFlags flags)
{
FieldInfo field = obj.GetType().GetField(name, flags);
if (field != null)
field.SetValue(obj, value);
}
public static FieldInfo[] GetFields<T>(BindingFlags flags)
{
return typeof(T).GetFields(flags);
}
public static FieldInfo[] GetFields(Type type, BindingFlags flags)
{
return type.GetFields(flags);
}
public static FieldInfo[] GetFields(Type type, BindingFlags flags, string[] ignoreFields)
{
var fields = new List<FieldInfo>(GetFields(type, flags));
for (int i = fields.Count - 1; i >= 0; i--)
{
FieldInfo fi = fields[i];
for (var j = 0; j < ignoreFields.Length; j++)
{
if (!fi.Name.Equals(ignoreFields[j]))
continue;
fields.RemoveAt(i);
break;
}
}
return fields.ToArray();
}
public static bool HasField<T>(object obj, string name)
{
return HasField<T>(obj, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
}
public static bool HasField<T>(object obj, string name, BindingFlags flags)
{
FieldInfo field = obj.GetType().GetField(name, flags);
return field != null && field.FieldType.IsAssignableFrom(typeof(T));
}
public static T GetPropertyValue<T>(object obj, string name)
{
return GetPropertyValue<T>(obj, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
}
public static T GetPropertyValue<T>(object obj, string name, BindingFlags flags)
{
PropertyInfo pi = obj.GetType().GetProperty(name, flags);
return pi != null ? (T)pi.GetValue(obj, null) : default(T);
}
public static void SetPropertyValue<T>(object obj, string name, T value)
{
SetPropertyValue<T>(obj, name, value, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
}
public static void SetPropertyValue<T>(object obj, string name, T value, BindingFlags flags)
{
PropertyInfo pi = obj.GetType().GetProperty(name, flags);
if (pi != null)
pi.SetValue(obj, value, null);
}
public static bool HasAttribute(FieldInfo field, System.Type attributeType)
{
// WSU: Needs the explicit conversion
var objs = (object[])field.GetCustomAttributes(attributeType, true);
return objs.Length != 0;
}
public static bool HasAttributeTitle(FieldInfo field)
{
return HasAttribute(field, typeof(HeaderAttribute));
}
public static T GetAttribute<T>(FieldInfo field)
{
// WSU: Needs the explicit conversion
var objs = (object[])field.GetCustomAttributes(typeof(T), true);
if (objs.Length != 0)
return (T)objs[0];
return default;
}
public static string GetAttributeTitle(FieldInfo field)
{
// WSU: Needs the explicit conversion
var objs = (object[])field.GetCustomAttributes(typeof(HeaderAttribute), true);
if (objs.Length == 0)
return "Unknown";
Type type = objs[0].GetType();
return (string)type.GetFields()[0].GetValue(objs[0]);
}
public static Type[] GetTypesWith(System.Type type)
{
Type[] types = type.Assembly.GetTypes();
var arr = new List<Type>();
for (var i = 0; i < types.Length; i++)
{
Type t = types[i];
if (t == type || type.IsAssignableFrom(t))
arr.Add(t);
}
return arr.ToArray();
}
public static Type GetAnyTypeWithName(string typeName)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (var i = 0; i < assemblies.Length; i++)
{
Type type = assemblies[i].GetType(typeName);
if (type != null)
return type;
}
return null;
}
public static object Create(Type type)
{
return Activator.CreateInstance(type);
}
public static void CopyFields(object source, object destination)
{
// Get fields
FieldInfo[] sourceFields = GetFields(source.GetType(), BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
FieldInfo[] destinationFields = GetFields(destination.GetType(), BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
// Start setting fields (if of same type)
for (var i = 0; i < sourceFields.Length; i++)
{
FieldInfo fiSource = sourceFields[i];
for (var j = 0; j < destinationFields.Length; j++)
{
FieldInfo fiDestination = destinationFields[j];
if (fiSource.Name.Equals(fiDestination.Name) && fiSource.FieldType == fiDestination.FieldType)
{
fiDestination.SetValue(destination, fiSource.GetValue(source));
break;
}
}
}
}
#endif
}
}