private void InitReflectionData(SyncList <SearchResult> results) { if (!useReflection) { return; } var types = ( from assembly in AppDomain.CurrentDomain.GetAssemblies() from type in assembly.GetTypes() where AssemblyIsAllowed(assembly) where !type.Name.StartsWith("<>") // Anonymous types where !typeof(Node).IsAssignableFrom(type) // Custom nodes select type ).ToList(); foreach (var type in types) { var typePath = type.FullName.Replace('.', '/').Replace('+', '/'); // Ignore attribute types if (typeof(Attribute).IsAssignableFrom(type)) { continue; } // Allow variable node if type is not a static class if (!type.IsAbstract || !type.IsSealed) { results.Add(new SearchResult(typePath, () => { return(CreateDynamicNode(type)); }, null, new List <Type>() { type }) ); } var members = from member in type.GetMembers() where member.MemberType == MemberTypes.Field || member.MemberType == MemberTypes.Property || member.MemberType == MemberTypes.Method select member; foreach (var member in members) { // Ignore obselete members if (member.GetCustomAttributes(true) .Any(t => t.GetType() == typeof(ObsoleteAttribute))) { continue; } if (member is MethodInfo) { var method = (MethodInfo)member; // Ignore special methods if (method.IsSpecialName) { continue; } } // Build the suffix string suffix; switch (member.MemberType) { case MemberTypes.Method: suffix = "()"; break; case MemberTypes.Field: case MemberTypes.Property: // Ignore enum fields and properties if (type.IsEnum) { continue; } suffix = ""; break; default: suffix = "?"; break; } var memberPath = string.Format("{0}.{1}{2}", typePath, member.Name, suffix); var result = new SearchResult(memberPath, () => { return(CreateDynamicNode(type, member)); }); PrepareDynamicContext(result, type, member); results.Add(result); } } }
private bool DrawNodeResults (GraphEditor editor, string newSearchStr, bool keysUsed) { if (searchStr != newSearchStr || justOpened) { justOpened = false; if (searchJob != null) { searchJob.IsRunning = false; } // Define variables for capture var contextType = this.contextWantsType; var contextIsInput = this.contextWantsInput; var newResults = new SyncList <SearchResult>(); results = newResults; // Perform search searchJob = new Job((job) => { var scores = new List <int>(); int timeout = 0; int n = 0; while (job.IsRunning) { // Check if the search items have changed (and restart // the search if so) if (n > policy.SearchItems.Count) { scores.Clear(); newResults.Clear(); n = 0; } // Get the next item, if available if (n == policy.SearchItems.Count) { if (timeout > 0) { break; } timeout++; Thread.Sleep(1000); continue; } timeout = 0; var item = policy.SearchItems[n++]; if (contextType != null) { if (!item.MatchesContext(contextIsInput, contextType)) { continue; } } // Score the item and insert it var score = FuzzySearch(newSearchStr, item.Label); if (score == int.MinValue) { continue; } int i = 0; for (; i < scores.Count; ++i) { if (score > scores[i] || (score == scores[i] && item.Label.Length < newResults[i].Label.Length) ) { scores.Insert(i, score); newResults.Insert(i, item); break; } } if (i == scores.Count) { scores.Add(score); newResults.Add(item); } } }).Start(); } searchStr = newSearchStr; // Update the count if (Event.current.type != EventType.Repaint && Event.current.type != EventType.ExecuteCommand) { resultCount = results == null ? 0 : results.Count; } selected = Mathf.Clamp(selected, 0, resultCount - 1); if (keysUsed) { if (selected > Mathf.FloorToInt(scrollPos) + 11) { scrollPos = selected - 11; } else if (selected < scrollPos) { scrollPos = selected; } } scrollPos = Mathf.Clamp(scrollPos, 0, Mathf.Max(0, resultCount - 12)); XGUI.ResetToStyle(null); XGUI.BeginHorizontal(); XGUI.BeginVertical(); // Show results int index = Mathf.Clamp((int)scrollPos, 0, resultCount); bool hoveringOnResult = false; for (int i = index; i < Mathf.Min(index + 12, resultCount); ++i) { var result = results[i]; XGUI.ResetToStyle(GUI.skin.label); if (i == selected) { XGUI.Normal.background = GetHighlightTex(); } XGUI.BeginHorizontal(); XGUI.ResetToStyle(GUI.skin.label); if (i == selected) { XGUI.Normal.textColor = Color.white; } XGUI.RichText = true; XGUI.Alignment = TextAnchor.MiddleLeft; var score = "" + FuzzySearch(searchStr, result.Label); var highlight = FuzzyHighlight(searchStr, result.Label); XGUI.Label(score, XGUI.Width(30)); XGUI.Label(highlight, XGUI.ExpandWidth(true)); XGUI.EndHorizontal(); var lastRect = GUILayoutUtility.GetLastRect(); if (lastRect.Contains(Event.current.mousePosition)) { if (Event.current.type == EventType.MouseMove) { selected = i; Event.current.Use(); } hoveringOnResult = selected == i; } } // No results if (resultCount == 0) { XGUI.ResetToStyle(GUI.skin.label); XGUI.Alignment = TextAnchor.LowerCenter; XGUI.Enabled = false; XGUI.FontStyle = FontStyle.Italic; XGUI.Label("No results", XGUI.MaxHeight(30)); } XGUI.EndVertical(); scrollPos = GUILayout.VerticalScrollbar (scrollPos, Mathf.Min(resultCount, 12), 0, Mathf.Max(resultCount, 12), GUILayout.ExpandHeight(true)); XGUI.EndHorizontal(); switch (Event.current.type) { case EventType.ScrollWheel: scrollPos += Event.current.delta.y; Event.current.Use(); break; // Detect key events in the search field case EventType.Used: switch (Event.current.keyCode) { case KeyCode.KeypadEnter: case KeyCode.Return: SelectResult(editor, selected); Close(); break; } break; } return(hoveringOnResult); }