mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-16 00:07:52 +08:00
Added Search page and AutoCompleter
This commit is contained in:
@ -1,69 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityExplorer.Core;
|
||||
|
||||
namespace UnityExplorer.Core.CSharp
|
||||
{
|
||||
public struct Suggestion
|
||||
{
|
||||
public enum Contexts
|
||||
{
|
||||
Namespace,
|
||||
Keyword,
|
||||
Other
|
||||
}
|
||||
|
||||
// ~~~~ Instance ~~~~
|
||||
|
||||
public readonly string Prefix;
|
||||
public readonly string Addition;
|
||||
public readonly Contexts Context;
|
||||
|
||||
public string Full => Prefix + Addition;
|
||||
|
||||
public Color TextColor => GetTextColor();
|
||||
|
||||
public Suggestion(string addition, string prefix, Contexts type)
|
||||
{
|
||||
Addition = addition;
|
||||
Prefix = prefix;
|
||||
Context = type;
|
||||
}
|
||||
|
||||
private Color GetTextColor()
|
||||
{
|
||||
switch (Context)
|
||||
{
|
||||
case Contexts.Namespace: return Color.grey;
|
||||
case Contexts.Keyword: return keywordColor;
|
||||
default: return Color.white;
|
||||
}
|
||||
}
|
||||
|
||||
// ~~~~ Static ~~~~
|
||||
|
||||
public static HashSet<string> Namespaces => m_namespaces ?? GetNamespaces();
|
||||
private static HashSet<string> m_namespaces;
|
||||
|
||||
public static HashSet<string> Keywords => throw new NotImplementedException("TODO!"); // m_keywords ?? (m_keywords = new HashSet<string>(CSLexerHighlighter.validKeywordMatcher.Keywords));
|
||||
//private static HashSet<string> m_keywords;
|
||||
|
||||
private static readonly Color keywordColor = new Color(80f / 255f, 150f / 255f, 215f / 255f);
|
||||
|
||||
private static HashSet<string> GetNamespaces()
|
||||
{
|
||||
HashSet<string> set = new HashSet<string>(
|
||||
AppDomain.CurrentDomain.GetAssemblies()
|
||||
.SelectMany(GetTypes)
|
||||
.Where(x => x.IsPublic && !string.IsNullOrEmpty(x.Namespace))
|
||||
.Select(x => x.Namespace));
|
||||
|
||||
return m_namespaces = set;
|
||||
|
||||
IEnumerable<Type> GetTypes(Assembly asm) => asm.TryGetTypes();
|
||||
}
|
||||
}
|
||||
}
|
@ -120,7 +120,7 @@ namespace UnityExplorer
|
||||
}
|
||||
|
||||
// cache for GetBaseTypes
|
||||
internal static readonly Dictionary<string, Type[]> s_cachedTypeInheritance = new Dictionary<string, Type[]>();
|
||||
internal static readonly Dictionary<string, Type[]> s_cachedBaseTypes = new Dictionary<string, Type[]>();
|
||||
|
||||
/// <summary>
|
||||
/// Get all base types of the provided Type, including itself.
|
||||
@ -137,7 +137,7 @@ namespace UnityExplorer
|
||||
|
||||
var name = type.AssemblyQualifiedName;
|
||||
|
||||
if (s_cachedTypeInheritance.TryGetValue(name, out Type[] ret))
|
||||
if (s_cachedBaseTypes.TryGetValue(name, out Type[] ret))
|
||||
return ret;
|
||||
|
||||
List<Type> list = new List<Type>();
|
||||
@ -150,11 +150,52 @@ namespace UnityExplorer
|
||||
|
||||
ret = list.ToArray();
|
||||
|
||||
s_cachedTypeInheritance.Add(name, ret);
|
||||
s_cachedBaseTypes.Add(name, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// cache for GetImplementationsOf
|
||||
internal static readonly Dictionary<Type, HashSet<Type>> s_cachedTypeInheritance = new Dictionary<Type, HashSet<Type>>();
|
||||
internal static int s_lastAssemblyCount;
|
||||
|
||||
/// <summary>
|
||||
/// Get all non-abstract implementations of the provided type (include itself, if not abstract) in the current AppDomain.
|
||||
/// </summary>
|
||||
/// <param name="baseType">The base type, which can optionally be abstract / interface.</param>
|
||||
/// <returns>All implementations of the type in the current AppDomain.</returns>
|
||||
public static HashSet<Type> GetImplementationsOf(this Type baseType, bool allowAbstract)
|
||||
{
|
||||
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
|
||||
if (!s_cachedTypeInheritance.ContainsKey(baseType) || assemblies.Length != s_lastAssemblyCount)
|
||||
{
|
||||
if (assemblies.Length != s_lastAssemblyCount)
|
||||
{
|
||||
s_cachedTypeInheritance.Clear();
|
||||
s_lastAssemblyCount = assemblies.Length;
|
||||
}
|
||||
|
||||
var set = new HashSet<Type>();
|
||||
|
||||
if (!baseType.IsAbstract && !baseType.IsInterface)
|
||||
set.Add(baseType);
|
||||
|
||||
foreach (var asm in assemblies)
|
||||
{
|
||||
foreach (var t in asm.TryGetTypes().Where(t => allowAbstract || (!t.IsAbstract && !t.IsInterface)))
|
||||
{
|
||||
if (baseType.IsAssignableFrom(t) && !set.Contains(t))
|
||||
set.Add(t);
|
||||
}
|
||||
}
|
||||
|
||||
s_cachedTypeInheritance.Add(baseType, set);
|
||||
}
|
||||
|
||||
return s_cachedTypeInheritance[baseType];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Safely get all valid Types inside an Assembly.
|
||||
/// </summary>
|
||||
|
@ -5,7 +5,7 @@ using System.Text;
|
||||
|
||||
namespace UnityExplorer.Core.Search
|
||||
{
|
||||
internal enum ChildFilter
|
||||
public enum ChildFilter
|
||||
{
|
||||
Any,
|
||||
RootObject,
|
||||
|
@ -5,11 +5,11 @@ using System.Text;
|
||||
|
||||
namespace UnityExplorer.Core.Search
|
||||
{
|
||||
internal enum SceneFilter
|
||||
public enum SceneFilter
|
||||
{
|
||||
Any,
|
||||
Asset,
|
||||
ActivelyLoaded,
|
||||
DontDestroyOnLoad,
|
||||
Explicit,
|
||||
HideAndDontSave,
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ using System.Text;
|
||||
|
||||
namespace UnityExplorer.Core.Search
|
||||
{
|
||||
internal enum SearchContext
|
||||
public enum SearchContext
|
||||
{
|
||||
UnityObject,
|
||||
GameObject,
|
||||
|
@ -4,15 +4,16 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityExplorer.Core.Runtime;
|
||||
|
||||
namespace UnityExplorer.Core.Search
|
||||
{
|
||||
public static class SearchProvider
|
||||
{
|
||||
internal static object[] StaticClassSearch(string input)
|
||||
internal static List<object> StaticClassSearch(string input)
|
||||
{
|
||||
var list = new List<Type>();
|
||||
var list = new List<object>();
|
||||
|
||||
var nameFilter = "";
|
||||
if (!string.IsNullOrEmpty(input))
|
||||
@ -29,7 +30,7 @@ namespace UnityExplorer.Core.Search
|
||||
}
|
||||
}
|
||||
|
||||
return list.ToArray();
|
||||
return list;
|
||||
}
|
||||
|
||||
internal static string[] s_instanceNames = new string[]
|
||||
@ -46,7 +47,7 @@ namespace UnityExplorer.Core.Search
|
||||
"<instance>k__BackingField",
|
||||
};
|
||||
|
||||
internal static object[] SingletonSearch(string input)
|
||||
internal static List<object> SingletonSearch(string input)
|
||||
{
|
||||
var instances = new List<object>();
|
||||
|
||||
@ -72,12 +73,31 @@ namespace UnityExplorer.Core.Search
|
||||
}
|
||||
}
|
||||
|
||||
return instances.ToArray();
|
||||
return instances;
|
||||
}
|
||||
|
||||
internal static object[] UnityObjectSearch(string input, string customTypeInput, SearchContext context,
|
||||
ChildFilter childFilter, SceneFilter sceneFilter, string sceneName = null)
|
||||
private static bool Filter(Scene scene, SceneFilter filter)
|
||||
{
|
||||
switch (filter)
|
||||
{
|
||||
case SceneFilter.Any:
|
||||
return true;
|
||||
case SceneFilter.DontDestroyOnLoad:
|
||||
return scene == SceneHandler.DontDestroyScene;
|
||||
case SceneFilter.HideAndDontSave:
|
||||
return scene == SceneHandler.AssetScene;
|
||||
case SceneFilter.ActivelyLoaded:
|
||||
return scene != SceneHandler.DontDestroyScene && scene != SceneHandler.AssetScene;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal static List<object> UnityObjectSearch(string input, string customTypeInput, SearchContext context,
|
||||
ChildFilter childFilter, SceneFilter sceneFilter)
|
||||
{
|
||||
var results = new List<object>();
|
||||
|
||||
Type searchType = null;
|
||||
switch (context)
|
||||
{
|
||||
@ -91,13 +111,15 @@ namespace UnityExplorer.Core.Search
|
||||
if (string.IsNullOrEmpty(customTypeInput))
|
||||
{
|
||||
ExplorerCore.LogWarning("Custom Type input must not be empty!");
|
||||
return null;
|
||||
return results;
|
||||
}
|
||||
if (ReflectionUtility.GetTypeByName(customTypeInput) is Type customType)
|
||||
{
|
||||
if (typeof(UnityEngine.Object).IsAssignableFrom(customType))
|
||||
searchType = customType;
|
||||
else
|
||||
ExplorerCore.LogWarning($"Custom type '{customType.FullName}' is not assignable from UnityEngine.Object!");
|
||||
}
|
||||
else
|
||||
ExplorerCore.LogWarning($"Could not find a type by the name '{customTypeInput}'!");
|
||||
break;
|
||||
@ -106,11 +128,11 @@ namespace UnityExplorer.Core.Search
|
||||
searchType = typeof(UnityEngine.Object); break;
|
||||
}
|
||||
|
||||
|
||||
if (searchType == null)
|
||||
return null;
|
||||
return results;
|
||||
|
||||
var allObjects = RuntimeProvider.Instance.FindObjectsOfTypeAll(searchType);
|
||||
var results = new List<object>();
|
||||
|
||||
// perform filter comparers
|
||||
|
||||
@ -121,20 +143,11 @@ namespace UnityExplorer.Core.Search
|
||||
bool canGetGameObject = (sceneFilter != SceneFilter.Any || childFilter != ChildFilter.Any)
|
||||
&& (context == SearchContext.GameObject || typeof(Component).IsAssignableFrom(searchType));
|
||||
|
||||
string sceneFilterString = null;
|
||||
if (!canGetGameObject)
|
||||
{
|
||||
if (context != SearchContext.UnityObject && (sceneFilter != SceneFilter.Any || childFilter != ChildFilter.Any))
|
||||
ExplorerCore.LogWarning($"Type '{searchType}' cannot have Scene or Child filters applied to it");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sceneFilter == SceneFilter.DontDestroyOnLoad)
|
||||
sceneFilterString = "DontDestroyOnLoad";
|
||||
else if (sceneFilter == SceneFilter.Explicit)
|
||||
//sceneFilterString = SearchPage.Instance.m_sceneDropdown.options[SearchPage.Instance.m_sceneDropdown.value].text;
|
||||
sceneFilterString = sceneName;
|
||||
}
|
||||
|
||||
foreach (var obj in allObjects)
|
||||
{
|
||||
@ -157,12 +170,9 @@ namespace UnityExplorer.Core.Search
|
||||
switch (context)
|
||||
{
|
||||
case SearchContext.GameObject:
|
||||
if (go.scene.name != sceneFilterString)
|
||||
continue;
|
||||
break;
|
||||
case SearchContext.Custom:
|
||||
case SearchContext.Component:
|
||||
if (go.scene.name != sceneFilterString)
|
||||
if (!Filter(go.scene, sceneFilter))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
@ -184,7 +194,7 @@ namespace UnityExplorer.Core.Search
|
||||
results.Add(obj);
|
||||
}
|
||||
|
||||
return results.ToArray();
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user