/************************************************************************************************************************/ private static List <MemberInfo> GetSortedMembers(Type type, BindingFlags bindings) { // Get the cache for the specified bindings. Dictionary <Type, List <MemberInfo> > memberCache; if (!MemberCache.TryGetValue(bindings, out memberCache)) { memberCache = new Dictionary <Type, List <MemberInfo> >(); MemberCache.Add(bindings, memberCache); } // If the members for the specified type aren't cached for those bindings, gather and sort them. List <MemberInfo> members; if (!memberCache.TryGetValue(type, out members)) { var properties = type.GetProperties(bindings); var methods = type.GetMethods(bindings); // When gathering static members, also include instance constructors. var constructors = ((bindings & BindingFlags.Static) == BindingFlags.Static) ? type.GetConstructors((bindings & ~BindingFlags.Static) | BindingFlags.Instance) : null; var capacity = properties.Length + methods.Length; if (constructors != null) { capacity += constructors.Length; } members = new List <MemberInfo>(capacity); members.AddRange(properties); if (constructors != null) { members.AddRange(constructors); } members.AddRange(methods); // If the bindings include static, add static members from each base type. if ((bindings & BindingFlags.Static) == BindingFlags.Static && type.BaseType != null) { members.AddRange(GetSortedMembers(type.BaseType, bindings & ~BindingFlags.Instance)); } UltEventUtils.StableInsertionSort(members, CompareMembers); memberCache.Add(type, members); } return(members); }
/************************************************************************************************************************/ private static void PopulateMenuForComponents(string prefix, GameObject[] gameObjects) { var firstGameObject = gameObjects[0]; var components = firstGameObject.GetComponents <Component>(); for (int i = 0; i < components.Length; i++) { var component = components[i]; var targets = new Object[gameObjects.Length]; targets[0] = component; Type type; var typeIndex = GetComponentTypeIndex(component, components, out type); int minTypeCount; Component unused; GetComponent(firstGameObject, type, typeIndex, out minTypeCount, out unused); var j = 1; for (; j < gameObjects.Length; j++) { int typeCount; Component targetComponent; GetComponent(gameObjects[j], type, typeIndex, out typeCount, out targetComponent); if (typeCount <= typeIndex) { goto NextComponent; } targets[j] = targetComponent; if (minTypeCount > typeCount) { minTypeCount = typeCount; } } var name = type.GetNameCS(BoolPref.ShowFullTypeNames) + " ->/"; if (minTypeCount > 1) { name = UltEventUtils.GetPlacementName(typeIndex) + " " + name; } PopulateMenuForObject(prefix + name, targets); } NextComponent :; }
/************************************************************************************************************************/ private static void DoMethodNameSuggestionGUI(ref Rect area, Type declaringType, string methodName) { if (declaringType == null || string.IsNullOrEmpty(methodName)) { return; } var lastDot = methodName.LastIndexOf('.'); if (lastDot >= 0) { lastDot++; if (lastDot >= methodName.Length) { return; } methodName = methodName.Substring(lastDot); } var methods = declaringType.GetMethods(UltEventUtils.AnyAccessBindings); if (methods.Length == 0) { return; } area.width -= SuggestionButtonWidth + Padding; var buttonArea = new Rect( area.x + area.width + Padding, area.y, SuggestionButtonWidth, area.height); if (GUI.Button(buttonArea, MethodNameSuggestionLabel)) { var cachedState = new DrawerState(); cachedState.CopyFrom(DrawerState.Current); EditorApplication.delayCall += () => { DrawerState.Current.CopyFrom(cachedState); var bestMethod = methods[0]; var bestDistance = UltEventUtils.CalculateLevenshteinDistance(methodName, bestMethod.Name); var i = 1; for (; i < methods.Length; i++) { var method = methods[i]; var distance = UltEventUtils.CalculateLevenshteinDistance(methodName, method.Name); if (bestDistance > distance) { bestDistance = distance; bestMethod = method; } } SetMethod(bestMethod); DrawerState.Current.Clear(); InternalEditorUtility.RepaintAllViews(); }; } }