|
|
|
|
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<TObject, TValue> : IPropertyAccessor where TObject : class
|
|
|
|
|
{
|
|
|
|
|
private readonly Func<TObject, TValue> getter;
|
|
|
|
|
|
|
|
|
|
public PropertyWrapper( MethodInfo getterMethod )
|
|
|
|
|
{
|
|
|
|
|
getter = (Func<TObject, TValue>) Delegate.CreateDelegate( typeof( Func<TObject, TValue> ), 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|