/// <summary> /// Retrieve the PersistentMethod description for the callback described by the callback /// </summary> /// <param name="callback">The callback object containing the information for the method to be raised</param> /// <returns>Returns the Persistent Method definition for the callback or null if not found</returns> public static PersistentMethod GetPersistentMethodFromCallback(PersistentCallback callback) { //Check that the callback is valid if (!callback.IsValid) { return(null); } //Get the type of the target object Type key = callback.Target.GetType(); //If the type hasn't been processed, get to it if (!objectMethods.ContainsKey(key)) { ProcessObjectType(key); } //Create a hashable list for lookup List <object> hashable = new List <object>(callback.ParameterInfo.Length + 1); hashable.Add(callback.MethodName); //Add the parameter signature to the list foreach (var param in callback.ParameterInfo) { hashable.Add(param.ParameterType); } //Generate the hash key for this entry MethodHash hashKey = HashUtitlity.GetCombinedHash(hashable.ToArray()); //Return the corresponding element if it exists return(objectMethods[key].ContainsKey(hashKey) ? objectMethods[key][hashKey] : null ); }
/// <summary> /// Process the supplied type to establish the usable methods that are contained for it /// </summary> /// <param name="key">The type that is to be processed to identify usable methods</param> private static void ProcessObjectType(Type key) { //Find all the methods that belong to the type with the specified flags List <MethodInfo> baseMethods = new List <MethodInfo>(key.GetMethods(PersistentCallbackUtility.SEARCH_FLAGS)); //Remove any method that is not valid baseMethods.RemoveAll(method => { //If this contains generic parameters, not gonna use it if (method.ContainsGenericParameters) { return(true); } //If this is a property (With a special name) only allow setters if (method.IsSpecialName && !method.Name.StartsWith(SETTER_PROPERTY_PREFIX)) { return(true); } //Check if there is an exclusion attribute if (method.GetFirstCustomAttributeOf <OmitRuntimeEventAttribute>() != null) { return(true); } //Retrieve the parameters of the object ParameterInfo[] parameters = method.GetParameters(); //Check that each of the parameter types has a supported type foreach (ParameterInfo parm in parameters) { if (!GenericSerialisation.CanProcess(parm.ParameterType)) { return(true); } } //If gotten this far, not going to be used return(false); }); //Process each of the stored entries for inclusion in the lookup Dictionary <MethodHash, PersistentMethod> typeLookup = new Dictionary <MethodHash, PersistentMethod>(baseMethods.Count); //Process all of the stored methods foreach (MethodInfo method in baseMethods) { //Get all of the parameters belonging to this method that needs to processed ParameterInfo[] parameters = method.GetParameters(); //Create an array for all of the parameters within this method PersistentParameter[] paramsInfo = new PersistentParameter[parameters.Length]; //Store the type signature for this method Type[] signature = new Type[parameters.Length]; //Store the collection of objects that will be used to create this Methods Hash List <object> hashable = new List <object>(parameters.Length + 1); hashable.Add(method.Name); //Process each of the parameter signature values for (int i = 0; i < parameters.Length; i++) { //Store the type for the entry signature[i] = parameters[i].ParameterType; //Add the type to the hashable list hashable.Add(parameters[i].ParameterType); //Look for a description attribute that is attached to this parameter DescriptionAttribute paramDesc = parameters[i].GetFirstCustomAttributeOf <DescriptionAttribute>(); //Create the information object for this parameter paramsInfo[i] = new PersistentParameter( new GUIContent( ObjectNames.NicifyVariableName(parameters[i].Name), paramDesc != null ? paramDesc.Description : string.Empty ), parameters[i].GetFirstCustomAttributeOf <ParameterAttribute>(), parameters[i].DefaultValue ); } //Look for a description attribute that is attached to this method DescriptionAttribute methodDesc = method.GetFirstCustomAttributeOf <DescriptionAttribute>(); //Create the information object for this method PersistentMethod persistentMethod = new PersistentMethod( new GUIContent( GenerateLabelFromSignature( (method.IsSpecialName ? method.Name.Substring(SETTER_PROPERTY_PREFIX.Length) : method.Name ), signature ), methodDesc != null ? methodDesc.Description : string.Empty ), method.Name, signature, paramsInfo, method.IsSpecialName ); //Get the hash key for this method MethodHash hashKey = HashUtitlity.GetCombinedHash(hashable.ToArray()); //Warn on a key conflict (Ideally, shouldn't happen ever) if (typeLookup.ContainsKey(hashKey)) { Debug.LogWarningFormat("Generated hash key for the method '{0}' (For Type: {1}) is identical to the method '{2}'. This method will overrite the previous", persistentMethod.DisplayLabel.text, key.FullName, typeLookup[hashKey].DisplayLabel.text); } //Add the method to the lookup typeLookup[hashKey] = persistentMethod; } //Stash the values in the general lookup objectMethods[key] = typeLookup; }