@@ -72,18 +72,14 @@ public static class Helper {
7272
7373 // Delegate hacks to access the internal methods
7474 private delegate Gradient DoGradientField ( GUIContent guiContent , Rect rect , Gradient gradient ) ;
75- private static readonly DoGradientField doGradientField =
76- GetDelegate < DoGradientField > ( typeof ( EditorGUI ) , "GradientField" ) ;
75+ private static readonly DoGradientField doGradientField = GetDelegate < EditorGUI , DoGradientField > ( "GradientField" ) ;
7776
7877 private delegate Gradient DoLayoutGradientField ( GUIContent guiContent , Gradient gradient , params GUILayoutOption [ ] options ) ;
79- private static readonly DoLayoutGradientField doLayoutGradiantField =
80- GetDelegate < DoLayoutGradientField > ( typeof ( EditorGUILayout ) , "GradientField" ) ;
78+ private static readonly DoLayoutGradientField doLayoutGradiantField = GetDelegate < EditorGUILayout , DoLayoutGradientField > ( "GradientField" ) ;
8179
8280 private static readonly Hashtable storedState = new Hashtable ( ) ;
8381
84- internal static void InitPropertyTypeMapper ( ) {
85- if ( propertyTypeMapper . Count > 0 )
86- return ;
82+ static Helper ( ) {
8783 AddPropertyTypeMap ( "System.String" , PropertyType . String ) ;
8884 AddPropertyTypeMap ( "System.Boolean" , PropertyType . Bool ) ;
8985 AddPropertyTypeMap ( "System.Byte" , PropertyType . Integer ) ;
@@ -537,24 +533,60 @@ internal static GUIStyle GetGUIStyle(string styleName) {
537533 return value == null ? defaultValue : ( T ) value ;
538534 }
539535
540- internal static T GetDelegate < T > ( Type fromType , string methodName ) where T : class {
541- Type t = typeof ( T ) ;
542- if ( ! t . IsSubclassOf ( typeof ( Delegate ) ) )
543- throw new ArgumentException ( string . Format ( "{0} is not delegate." , t . Name ) ) ;
544- MethodInfo invokeMethod = t . GetMethod ( "Invoke" ) ;
536+ internal static TDelegate GetDelegate < TDelegate > ( string fromTypeName , string methodName , object target = null ) where TDelegate : class {
537+ if ( fromTypeName == null )
538+ throw new ArgumentNullException ( "fromTypeName" ) ;
539+ Type fromType = Type . GetType ( fromTypeName , false ) ;
540+ if ( fromType == null ) return null ;
541+ return GetDelegate < TDelegate > ( fromType , methodName , target ) ;
542+ }
543+
544+ internal static TDelegate GetDelegate < TDelegate > ( Type fromType , string methodName , object target = null ) where TDelegate : class {
545+ if ( fromType == null )
546+ throw new ArgumentNullException ( "fromType" ) ;
547+ if ( methodName == null )
548+ throw new ArgumentNullException ( "methodName" ) ;
549+ Type delegateType = typeof ( TDelegate ) ;
550+ MethodInfo method = FindMethod ( fromType , methodName , delegateType ) ;
551+ if ( method == null )
552+ return null ;
553+ if ( method . IsStatic )
554+ return Delegate . CreateDelegate ( delegateType , method , false ) as TDelegate ;
555+ if ( target == null && fromType . IsValueType )
556+ target = Activator . CreateInstance ( fromType ) ;
557+ return Delegate . CreateDelegate ( delegateType , target , method , false ) as TDelegate ;
558+ }
559+
560+ internal static TDelegate GetDelegate < TFrom , TDelegate > ( string methodName , TFrom target = default ( TFrom ) ) where TDelegate : class {
561+ if ( methodName == null )
562+ throw new ArgumentNullException ( "methodName" ) ;
563+ Type delegateType = typeof ( TDelegate ) ;
564+ MethodInfo method = FindMethod ( typeof ( TFrom ) , methodName , delegateType ) ;
565+ if ( method == null )
566+ return null ;
567+ if ( method . IsStatic )
568+ return Delegate . CreateDelegate ( delegateType , method , false ) as TDelegate ;
569+ return Delegate . CreateDelegate ( delegateType , target , method , false ) as TDelegate ;
570+ }
571+
572+ private static MethodInfo FindMethod ( Type fromType , string methodName , Type delegateType ) {
573+ const string NotADelegateMsg = "{0} is not a delegate." ;
574+ const string MissingInvokeMsg =
575+ "Cannot determine what parameters does {0} have, " +
576+ "as no Invoke(...) signature found. " +
577+ "Perhaps this is not a valid delegate." ;
578+ if ( ! delegateType . IsSubclassOf ( typeof ( Delegate ) ) )
579+ throw new ArgumentException ( string . Format ( NotADelegateMsg , delegateType . Name ) ) ;
580+ MethodInfo invokeMethod = delegateType . GetMethod ( "Invoke" ) ;
545581 if ( invokeMethod == null )
546- throw new ArgumentException ( string . Format (
547- "Cannot determine what parameters does {0} have, as no Invoke(...) signature found. Perhaps this is not a valid delegate." ,
548- t . Name
549- ) ) ;
550- MethodInfo method = fromType . GetMethod (
582+ throw new ArgumentException ( string . Format ( MissingInvokeMsg , delegateType . Name ) ) ;
583+ return fromType . GetMethod (
551584 methodName ,
552- BindingFlags . NonPublic | BindingFlags . Public | BindingFlags . Static ,
585+ BindingFlags . NonPublic | BindingFlags . Public | BindingFlags . Static | BindingFlags . Instance ,
553586 null , CallingConventions . Any ,
554587 Array . ConvertAll ( invokeMethod . GetParameters ( ) , p => p . ParameterType ) ,
555588 null
556589 ) ;
557- return method == null ? null : Delegate . CreateDelegate ( t , method ) as T ;
558590 }
559591
560592 [ MenuItem ( "Window/Inspector+" ) ]
0 commit comments