public static Delegate Create(FieldInfo singletonField, PropertyInfo singletonProperty, Type delegateType, MethodInfo method) { var parameters = method.GetParameters(); bool hasReturnValue = !method.ReturnType.Equals(typeof(void)); var genericMethodName = "Call" + (hasReturnValue?"Func":"Action") + method.GetParameters().Length + (singletonField == null ? "P" : "F"); var genericMethodInfo = typeof(SingletonMethodCall).GetMethod(genericMethodName); if (genericMethodInfo == null) { throw new InvalidOperationException("Couldn't find method needed to dynamically bind: " + genericMethodName); } MethodInfo methodInfo; if (genericMethodInfo.IsGenericMethod) { var genericParameterTypes = new Type[parameters.Length + (hasReturnValue?1:0)]; for (int i = 0; i < parameters.Length; ++i) { genericParameterTypes[i] = parameters[i].ParameterType; } if (hasReturnValue) { genericParameterTypes[parameters.Length] = method.ReturnType; } methodInfo = genericMethodInfo.MakeGenericMethod(genericParameterTypes); } else { methodInfo = genericMethodInfo; } var instance = new SingletonMethodCall() { Field = singletonField, Property = singletonProperty, Method = method, }; return(Delegate.CreateDelegate(delegateType, instance, methodInfo)); }
private static void bindStaticMethods(Type type) { MemberInfo[] members = type.FindMembers( MemberTypes.Field, BindingFlags.Static | BindingFlags.SetField | BindingFlags.Public | BindingFlags.NonPublic, delegate(MemberInfo memberInfo, object lastParameterOfFindMembers) { return(memberInfo.MemberType == MemberTypes.Field && Attribute.IsDefined(memberInfo, typeof(Bind))); }, null); for (int j = 0; j < members.Length; ++j) { FieldInfo delegateFieldToBind = (FieldInfo)members[j]; Type delegateFieldToBindType = delegateFieldToBind.FieldType; Type[] parameterTypes = GetDelegateParameterTypes(delegateFieldToBindType); Type returnType = GetDelegateReturnType(delegateFieldToBindType); bool alreadyHasValue = delegateFieldToBind.GetValue(null) != null; if (!alreadyHasValue) { #if UNITY_EDITOR if (returnType != typeof(void)) { UnityEngine.Debug.LogErrorFormat("{0}.{1} should be assigned to BoundAction.Null by default (to make sure the AOT compiler generates code for the binding)", type.Name, delegateFieldToBind.Name); } else { UnityEngine.Debug.LogErrorFormat("{0}.{1} should be assigned to BoundFunc<{2}>.Null by default (to make sure the AOT compiler generates code for the binding)", type.Name, delegateFieldToBind.Name, returnType.Name); } #endif } //UnityEngine.Debug.LogFormat ("Attempting to bind {0}.{1}", type.Name, delegateFieldToBind.Name); Type singletonType; FieldInfo staticSingletonField; PropertyInfo staticSingletonProperty; MethodInfo methodToCall; bool wasFound = findSingletonMethod( delegateFieldToBind, returnType, parameterTypes, out singletonType, out staticSingletonField, out staticSingletonProperty, out methodToCall); if (!wasFound) { wasFound = findStaticMethod( delegateFieldToBind, returnType, parameterTypes, out methodToCall ); if (!wasFound) { throw new InvalidOperationException(string.Format("Unable to bind {0}.{1}", type.Name, delegateFieldToBind.Name)); } var staticDelegate = Delegate.CreateDelegate(delegateFieldToBindType, null, methodToCall); delegateFieldToBind.SetValue(null, staticDelegate); continue; } var dynamicDelegate = SingletonMethodCall.Create( staticSingletonField, staticSingletonProperty, delegateFieldToBindType, methodToCall); // UnityEngine.Debug.LogFormat ("Binding {0}", delegateFieldToBind.Name); delegateFieldToBind.SetValue(null, dynamicDelegate); } }