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(object obj, string name) { return GetValue(obj, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); } public static T GetValue(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(object obj, FieldInfo field) { return field != null ? (T)field.GetValue(obj) : default; } public static T[] GetArrayValue(object obj, string name) { return GetArrayValue(obj, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); } public static T[] GetArrayValue(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(object obj, string name, T value) { SetValue(obj, name, value, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); } public static void SetValue(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(object obj, T value, FieldInfo field) { field.SetValue(obj, value); } public static void SetValue(object obj, string name, T[] value) { SetValue(obj, name, value, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); } public static void SetValue(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(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(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(object obj, string name) { return HasField(obj, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); } public static bool HasField(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(object obj, string name) { return GetPropertyValue(obj, name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); } public static T GetPropertyValue(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(object obj, string name, T value) { SetPropertyValue(obj, name, value, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); } public static void SetPropertyValue(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(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(); 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 } }