using System; using System.Reflection; using System.Text; using UnityEngine; namespace AssetUsageDetectorNamespace { // Delegate to get the value of a variable (either field or property) public delegate object VariableGetVal( object obj ); // Custom struct to hold a variable, its important properties and its getter function public struct VariableGetterHolder { public readonly MemberInfo variable; public readonly bool isSerializable; private readonly VariableGetVal getter; public string Name { get { return variable.Name; } } public bool IsProperty { get { return variable is PropertyInfo; } } public VariableGetterHolder( FieldInfo fieldInfo, VariableGetVal getter, bool isSerializable ) { this.variable = fieldInfo; this.isSerializable = isSerializable; this.getter = getter; } public VariableGetterHolder( PropertyInfo propertyInfo, VariableGetVal getter, bool isSerializable ) { this.variable = propertyInfo; this.isSerializable = isSerializable; this.getter = getter; } public object Get( object obj ) { try { return getter( obj ); } catch( Exception e ) { StringBuilder sb = Utilities.stringBuilder; sb.Length = 0; sb.Append( "Error while getting the value of (" ).Append( IsProperty ? ( (PropertyInfo) variable ).PropertyType : ( (FieldInfo) variable ).FieldType ).Append( ") " ) .Append( variable.DeclaringType ).Append( "." ).Append( Name ).Append( ": " ).Append( e ); Debug.LogError( sb.ToString() ); return null; } } } // Credit: http://stackoverflow.com/questions/724143/how-do-i-create-a-delegate-for-a-net-property public interface IPropertyAccessor { object GetValue( object source ); } // A wrapper class for properties to get their values more efficiently public class PropertyWrapper : IPropertyAccessor where TObject : class { private readonly Func getter; public PropertyWrapper( MethodInfo getterMethod ) { getter = (Func) Delegate.CreateDelegate( typeof( Func ), getterMethod ); } public object GetValue( object obj ) { try { return getter( (TObject) obj ); } catch { // Property getters may return various kinds of exceptions if their backing fields are not initialized (yet) return null; } } } }