mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-23 17:02:36 +08:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
6f44a3376b | |||
3a6b573ac3 | |||
cbe17927fb | |||
15f3f37948 | |||
de6760e427 | |||
83edd1b9bb | |||
613be34e95 | |||
58c65b9b8b | |||
6fcf6a521c | |||
81a174f865 | |||
b5e3cc2ea5 | |||
14f46ade6a |
Binary file not shown.
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "com.sinai-dev.unityexplorer",
|
||||
"version": "4.7.3",
|
||||
"version": "4.7.8",
|
||||
"displayName": "UnityExplorer",
|
||||
"description": "An in-game UI for exploring, debugging and modifying Unity games.",
|
||||
"unity": "2017.1",
|
||||
|
@ -54,6 +54,10 @@ namespace UnityExplorer.Config
|
||||
Handler.LoadConfig();
|
||||
InternalHandler.LoadConfig();
|
||||
|
||||
#if STANDALONE
|
||||
Loader.Standalone.ExplorerEditorBehaviour.Instance.LoadConfigs();
|
||||
#endif
|
||||
|
||||
//InitConsoleCallback();
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityExplorer.UI;
|
||||
using UniverseLib;
|
||||
#if CPP
|
||||
using UnhollowerRuntimeLib;
|
||||
#endif
|
||||
@ -29,5 +33,39 @@ namespace UnityExplorer
|
||||
{
|
||||
ExplorerCore.Update();
|
||||
}
|
||||
|
||||
// For editor, to clean up objects
|
||||
|
||||
internal void OnDestroy()
|
||||
{
|
||||
OnApplicationQuit();
|
||||
}
|
||||
|
||||
internal bool quitting;
|
||||
|
||||
internal void OnApplicationQuit()
|
||||
{
|
||||
if (quitting) return;
|
||||
quitting = true;
|
||||
|
||||
TryDestroy(UIManager.UIRoot?.transform.root.gameObject);
|
||||
|
||||
TryDestroy((typeof(Universe).Assembly.GetType("UniverseLib.UniversalBehaviour")
|
||||
.GetProperty("Instance", BindingFlags.Static | BindingFlags.NonPublic)
|
||||
.GetValue(null, null)
|
||||
as Component).gameObject);
|
||||
|
||||
TryDestroy(this.gameObject);
|
||||
}
|
||||
|
||||
internal void TryDestroy(GameObject obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (obj)
|
||||
Destroy(obj);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ namespace UnityExplorer
|
||||
public static class ExplorerCore
|
||||
{
|
||||
public const string NAME = "UnityExplorer";
|
||||
public const string VERSION = "4.7.6";
|
||||
public const string VERSION = "4.7.8";
|
||||
public const string AUTHOR = "Sinai";
|
||||
public const string GUID = "com.sinai.unityexplorer";
|
||||
|
||||
|
@ -39,6 +39,8 @@ namespace UnityExplorer.Hooks
|
||||
internal static Type pendingGenericDefinition;
|
||||
internal static MethodInfo pendingGenericMethod;
|
||||
|
||||
public static bool PendingGeneric => pendingGenericDefinition != null || pendingGenericMethod != null;
|
||||
|
||||
// Hook Source Editor UI
|
||||
public static GameObject EditorRoot { get; private set; }
|
||||
public static Text EditingHookLabel { get; private set; }
|
||||
|
@ -47,6 +47,9 @@ namespace UnityExplorer.Hooks
|
||||
|
||||
public static void EditPatchClicked(int index)
|
||||
{
|
||||
if (HookCreator.PendingGeneric)
|
||||
HookManagerPanel.genericArgsHandler.Cancel();
|
||||
|
||||
HookManagerPanel.Instance.SetPage(HookManagerPanel.Pages.HookSourceEditor);
|
||||
HookInstance hook = (HookInstance)currentHooks[index];
|
||||
HookCreator.SetEditedHook(hook);
|
||||
|
@ -6,27 +6,53 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityExplorer.Config;
|
||||
using UnityExplorer.UI;
|
||||
using UniverseLib;
|
||||
|
||||
namespace UnityExplorer.Loader.Standalone
|
||||
{
|
||||
public class ExplorerEditorBehaviour : MonoBehaviour
|
||||
{
|
||||
internal static ExplorerEditorBehaviour Instance { get; private set; }
|
||||
|
||||
public bool Hide_On_Startup = true;
|
||||
public KeyCode Master_Toggle_Key = KeyCode.F7;
|
||||
public UIManager.VerticalAnchor Main_Navbar_Anchor = UIManager.VerticalAnchor.Top;
|
||||
public bool Log_Unity_Debug = false;
|
||||
public float Startup_Delay_Time = 1f;
|
||||
public KeyCode World_MouseInspect_Keybind;
|
||||
public KeyCode UI_MouseInspect_Keybind;
|
||||
public bool Force_Unlock_Mouse = true;
|
||||
public KeyCode Force_Unlock_Toggle;
|
||||
public bool Disable_EventSystem_Override;
|
||||
|
||||
internal void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
|
||||
ExplorerEditorLoader.Initialize();
|
||||
DontDestroyOnLoad(this);
|
||||
this.gameObject.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
|
||||
internal void OnDestroy()
|
||||
{
|
||||
OnApplicationQuit();
|
||||
}
|
||||
|
||||
internal void OnApplicationQuit()
|
||||
{
|
||||
if (UI.UIManager.UIRoot)
|
||||
Destroy(UI.UIManager.UIRoot.transform.root.gameObject);
|
||||
Destroy(this.gameObject);
|
||||
}
|
||||
|
||||
internal void LoadConfigs()
|
||||
{
|
||||
ConfigManager.Hide_On_Startup.Value = this.Hide_On_Startup;
|
||||
ConfigManager.Master_Toggle.Value = this.Master_Toggle_Key;
|
||||
ConfigManager.Main_Navbar_Anchor.Value = this.Main_Navbar_Anchor;
|
||||
ConfigManager.Log_Unity_Debug.Value = this.Log_Unity_Debug;
|
||||
ConfigManager.Startup_Delay_Time.Value = this.Startup_Delay_Time;
|
||||
ConfigManager.World_MouseInspect_Keybind.Value = this.World_MouseInspect_Keybind;
|
||||
ConfigManager.UI_MouseInspect_Keybind.Value = this.UI_MouseInspect_Keybind;
|
||||
ConfigManager.Force_Unlock_Mouse.Value = this.Force_Unlock_Mouse;
|
||||
ConfigManager.Force_Unlock_Toggle.Value = this.Force_Unlock_Toggle;
|
||||
ConfigManager.Disable_EventSystem_Override.Value = this.Disable_EventSystem_Override;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ namespace UnityExplorer.Loader.Standalone
|
||||
protected override void CheckExplorerFolder()
|
||||
{
|
||||
if (explorerFolderDest == null)
|
||||
explorerFolderDest = Application.dataPath;
|
||||
explorerFolderDest = Path.GetDirectoryName(Application.dataPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,12 +34,15 @@ namespace UnityExplorer.ObjectExplorer
|
||||
private ScrollPool<ButtonCell> resultsScrollPool;
|
||||
private List<object> currentResults = new();
|
||||
|
||||
//public TypeCompleter typeAutocompleter;
|
||||
public TypeCompleter unityObjectTypeCompleter;
|
||||
public TypeCompleter allTypesCompleter;
|
||||
|
||||
public override GameObject UIRoot => uiRoot;
|
||||
private GameObject uiRoot;
|
||||
private GameObject sceneFilterRow;
|
||||
private GameObject childFilterRow;
|
||||
private GameObject classInputRow;
|
||||
public TypeCompleter typeAutocompleter;
|
||||
private GameObject nameInputRow;
|
||||
private InputFieldRef nameInputField;
|
||||
private Text resultsLabel;
|
||||
@ -98,14 +101,18 @@ namespace UnityExplorer.ObjectExplorer
|
||||
|
||||
nameInputRow.SetActive(context == SearchContext.UnityObject);
|
||||
|
||||
if (context == SearchContext.Class)
|
||||
typeAutocompleter.AllTypes = true;
|
||||
else
|
||||
switch (context)
|
||||
{
|
||||
typeAutocompleter.BaseType = context == SearchContext.UnityObject ? typeof(UnityEngine.Object) : typeof(object);
|
||||
typeAutocompleter.AllTypes = false;
|
||||
case SearchContext.UnityObject:
|
||||
unityObjectTypeCompleter.Enabled = true;
|
||||
allTypesCompleter.Enabled = false;
|
||||
break;
|
||||
case SearchContext.Singleton:
|
||||
case SearchContext.Class:
|
||||
allTypesCompleter.Enabled = true;
|
||||
unityObjectTypeCompleter.Enabled = false;
|
||||
break;
|
||||
}
|
||||
typeAutocompleter.CacheTypes();
|
||||
}
|
||||
|
||||
private void OnSceneFilterDropChanged(int value) => sceneFilter = (SceneFilter)value;
|
||||
@ -185,7 +192,9 @@ namespace UnityExplorer.ObjectExplorer
|
||||
InputFieldRef classInputField = UIFactory.CreateInputField(classInputRow, "ClassInput", "...");
|
||||
UIFactory.SetLayoutElement(classInputField.UIRoot, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
|
||||
|
||||
typeAutocompleter = new TypeCompleter(typeof(UnityEngine.Object), classInputField);
|
||||
unityObjectTypeCompleter = new(typeof(UnityEngine.Object), classInputField, true, false, true);
|
||||
allTypesCompleter = new(null, classInputField, true, false, true);
|
||||
allTypesCompleter.Enabled = false;
|
||||
classInputField.OnValueChanged += OnTypeInputChanged;
|
||||
|
||||
//unityObjectClassRow.SetActive(false);
|
||||
|
@ -135,7 +135,7 @@ namespace UnityExplorer.ObjectExplorer
|
||||
|
||||
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
foreach (Type type in asm.TryGetTypes())
|
||||
foreach (Type type in asm.GetTypes())
|
||||
{
|
||||
if (!string.IsNullOrEmpty(nameFilter) && !type.FullName.ContainsIgnoreCase(nameFilter))
|
||||
continue;
|
||||
@ -173,7 +173,7 @@ namespace UnityExplorer.ObjectExplorer
|
||||
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
// Search all non-static, non-enum classes.
|
||||
foreach (Type type in asm.TryGetTypes().Where(it => !(it.IsSealed && it.IsAbstract) && !it.IsEnum))
|
||||
foreach (Type type in asm.GetTypes().Where(it => !(it.IsSealed && it.IsAbstract) && !it.IsEnum))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -69,15 +69,22 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
if (CurrentHandler == provider)
|
||||
{
|
||||
Suggestions.Clear();
|
||||
CurrentHandler = null;
|
||||
UIRoot.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetSuggestions(IEnumerable<Suggestion> suggestions)
|
||||
public void SetSuggestions(List<Suggestion> suggestions, bool jumpToTop = false)
|
||||
{
|
||||
Suggestions = suggestions as List<Suggestion> ?? suggestions.ToList();
|
||||
SelectedIndex = 0;
|
||||
Suggestions = suggestions;
|
||||
|
||||
if (jumpToTop)
|
||||
{
|
||||
SelectedIndex = 0;
|
||||
if (scrollPool.DataSource.ItemCount > 0)
|
||||
scrollPool.JumpToIndex(0, null);
|
||||
}
|
||||
|
||||
if (!Suggestions.Any())
|
||||
base.UIRoot.SetActive(false);
|
||||
@ -86,7 +93,7 @@ namespace UnityExplorer.UI.Panels
|
||||
base.UIRoot.SetActive(true);
|
||||
base.UIRoot.transform.SetAsLastSibling();
|
||||
buttonListDataHandler.RefreshData();
|
||||
scrollPool.Refresh(true, true);
|
||||
scrollPool.Refresh(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,6 +201,12 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
private void SetCell(ButtonCell cell, int index)
|
||||
{
|
||||
if (CurrentHandler == null)
|
||||
{
|
||||
UIRoot.SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (index < 0 || index >= Suggestions.Count)
|
||||
{
|
||||
cell.Disable();
|
||||
|
@ -119,6 +119,8 @@ namespace UnityExplorer.UI.Panels
|
||||
{
|
||||
Rect.SetAnchorsFromString(split[1]);
|
||||
Rect.SetPositionFromString(split[2]);
|
||||
this.EnsureValidSize();
|
||||
this.EnsureValidPosition();
|
||||
this.SetActive(bool.Parse(split[0]));
|
||||
}
|
||||
catch
|
||||
|
@ -26,7 +26,6 @@ namespace UnityExplorer.UI
|
||||
Options,
|
||||
ConsoleLog,
|
||||
AutoCompleter,
|
||||
//MouseInspector,
|
||||
UIInspectorResults,
|
||||
HookManager,
|
||||
Clipboard,
|
||||
|
@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityExplorer.UI.Panels;
|
||||
using UniverseLib;
|
||||
using UniverseLib.UI.Models;
|
||||
@ -12,22 +15,22 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
|
||||
{
|
||||
public bool Enabled
|
||||
{
|
||||
get => _enabled;
|
||||
get => enabled;
|
||||
set
|
||||
{
|
||||
_enabled = value;
|
||||
if (!_enabled)
|
||||
enabled = value;
|
||||
if (!enabled)
|
||||
{
|
||||
AutoCompleteModal.Instance.ReleaseOwnership(this);
|
||||
if (getSuggestionsCoroutine != null)
|
||||
RuntimeHelper.StopCoroutine(getSuggestionsCoroutine);
|
||||
}
|
||||
}
|
||||
}
|
||||
private bool _enabled = true;
|
||||
bool enabled = true;
|
||||
|
||||
public event Action<Suggestion> SuggestionClicked;
|
||||
|
||||
public Type BaseType { get; set; }
|
||||
public Type[] GenericConstraints { get; set; }
|
||||
public bool AllTypes { get; set; }
|
||||
|
||||
public InputFieldRef InputField { get; }
|
||||
public bool AnchorToCaretPosition => false;
|
||||
|
||||
@ -35,11 +38,20 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
|
||||
readonly bool allowEnum;
|
||||
readonly bool allowGeneric;
|
||||
|
||||
private HashSet<Type> allowedTypes;
|
||||
public Type BaseType { get; set; }
|
||||
HashSet<Type> allowedTypes;
|
||||
string pendingInput;
|
||||
Coroutine getSuggestionsCoroutine;
|
||||
readonly Stopwatch cacheTypesStopwatch = new();
|
||||
|
||||
readonly List<Suggestion> suggestions = new();
|
||||
readonly HashSet<string> suggestedNames = new();
|
||||
private string chosenSuggestion;
|
||||
readonly HashSet<string> suggestedTypes = new();
|
||||
string chosenSuggestion;
|
||||
|
||||
readonly List<Suggestion> loadingSuggestions = new()
|
||||
{
|
||||
new("<color=grey>Loading...</color>", "")
|
||||
};
|
||||
|
||||
bool ISuggestionProvider.AllowNavigation => false;
|
||||
|
||||
@ -76,106 +88,89 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
|
||||
|
||||
inputField.OnValueChanged += OnInputFieldChanged;
|
||||
|
||||
if (BaseType != null || AllTypes)
|
||||
CacheTypes();
|
||||
}
|
||||
|
||||
public void CacheTypes()
|
||||
{
|
||||
if (!AllTypes)
|
||||
allowedTypes = ReflectionUtility.GetImplementationsOf(BaseType, allowAbstract, allowGeneric, allowEnum);
|
||||
else
|
||||
allowedTypes = GetAllAllowedTypes();
|
||||
|
||||
// Check generic parameter constraints
|
||||
if (GenericConstraints != null && GenericConstraints.Any())
|
||||
{
|
||||
List<Type> typesToRemove = new();
|
||||
foreach (Type type in allowedTypes)
|
||||
{
|
||||
bool allowed = true;
|
||||
foreach (Type constraint in GenericConstraints)
|
||||
{
|
||||
if (!constraint.IsAssignableFrom(type))
|
||||
{
|
||||
allowed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!allowed)
|
||||
typesToRemove.Add(type);
|
||||
}
|
||||
|
||||
foreach (Type type in typesToRemove)
|
||||
allowedTypes.Remove(type);
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<Type> GetAllAllowedTypes()
|
||||
{
|
||||
HashSet<Type> allAllowedTypes = new();
|
||||
foreach (KeyValuePair<string, Type> entry in ReflectionUtility.AllTypes)
|
||||
{
|
||||
Type type = entry.Value;
|
||||
|
||||
if ((!allowAbstract && type.IsAbstract)
|
||||
|| (!allowGeneric && type.IsGenericType)
|
||||
|| (!allowEnum && type.IsEnum))
|
||||
continue;
|
||||
|
||||
// skip <PrivateImplementationDetails> and <AnonymousClass> classes
|
||||
if (type.FullName.Contains("PrivateImplementationDetails")
|
||||
|| type.FullName.Contains("DisplayClass")
|
||||
|| type.FullName.Contains('<'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
allAllowedTypes.Add(type);
|
||||
}
|
||||
|
||||
return allAllowedTypes;
|
||||
CacheTypes();
|
||||
}
|
||||
|
||||
public void OnSuggestionClicked(Suggestion suggestion)
|
||||
{
|
||||
chosenSuggestion = suggestion.UnderlyingValue;
|
||||
InputField.Text = suggestion.UnderlyingValue;
|
||||
SuggestionClicked?.Invoke(suggestion);
|
||||
|
||||
suggestions.Clear();
|
||||
AutoCompleteModal.Instance.SetSuggestions(suggestions);
|
||||
chosenSuggestion = suggestion.UnderlyingValue;
|
||||
//AutoCompleteModal.Instance.SetSuggestions(suggestions, true);
|
||||
AutoCompleteModal.Instance.ReleaseOwnership(this);
|
||||
}
|
||||
|
||||
private void OnInputFieldChanged(string value)
|
||||
public void CacheTypes()
|
||||
{
|
||||
allowedTypes = null;
|
||||
cacheTypesStopwatch.Reset();
|
||||
cacheTypesStopwatch.Start();
|
||||
ReflectionUtility.GetImplementationsOf(BaseType, OnTypesCached, allowAbstract, allowGeneric, allowEnum);
|
||||
}
|
||||
|
||||
void OnTypesCached(HashSet<Type> set)
|
||||
{
|
||||
allowedTypes = set;
|
||||
|
||||
// ExplorerCore.Log($"Cached {allowedTypes.Count} TypeCompleter types in {cacheTypesStopwatch.ElapsedMilliseconds * 0.001f} seconds.");
|
||||
|
||||
if (pendingInput != null)
|
||||
{
|
||||
GetSuggestions(pendingInput);
|
||||
pendingInput = null;
|
||||
}
|
||||
}
|
||||
|
||||
void OnInputFieldChanged(string input)
|
||||
{
|
||||
if (!Enabled)
|
||||
return;
|
||||
|
||||
if (string.IsNullOrEmpty(value) || value == chosenSuggestion)
|
||||
{
|
||||
if (input != chosenSuggestion)
|
||||
chosenSuggestion = null;
|
||||
|
||||
if (string.IsNullOrEmpty(input) || input == chosenSuggestion)
|
||||
{
|
||||
if (getSuggestionsCoroutine != null)
|
||||
RuntimeHelper.StopCoroutine(getSuggestionsCoroutine);
|
||||
AutoCompleteModal.Instance.ReleaseOwnership(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetSuggestions(value);
|
||||
|
||||
AutoCompleteModal.TakeOwnership(this);
|
||||
AutoCompleteModal.Instance.SetSuggestions(suggestions);
|
||||
GetSuggestions(input);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetSuggestions(string input)
|
||||
void GetSuggestions(string input)
|
||||
{
|
||||
suggestions.Clear();
|
||||
suggestedNames.Clear();
|
||||
|
||||
if (!AllTypes && BaseType == null)
|
||||
if (allowedTypes == null)
|
||||
{
|
||||
ExplorerCore.LogWarning("Autocompleter Base type is null!");
|
||||
if (pendingInput != null)
|
||||
{
|
||||
AutoCompleteModal.TakeOwnership(this);
|
||||
AutoCompleteModal.Instance.SetSuggestions(loadingSuggestions, true);
|
||||
}
|
||||
|
||||
pendingInput = input;
|
||||
return;
|
||||
}
|
||||
|
||||
if (getSuggestionsCoroutine != null)
|
||||
RuntimeHelper.StopCoroutine(getSuggestionsCoroutine);
|
||||
|
||||
getSuggestionsCoroutine = RuntimeHelper.StartCoroutine(GetSuggestionsAsync(input));
|
||||
}
|
||||
|
||||
IEnumerator GetSuggestionsAsync(string input)
|
||||
{
|
||||
suggestions.Clear();
|
||||
suggestedTypes.Clear();
|
||||
|
||||
AutoCompleteModal.TakeOwnership(this);
|
||||
AutoCompleteModal.Instance.SetSuggestions(suggestions, true);
|
||||
|
||||
// shorthand types all inherit from System.Object
|
||||
if (shorthandToType.TryGetValue(input, out Type shorthand) && allowedTypes.Contains(shorthand))
|
||||
AddSuggestion(shorthand);
|
||||
@ -190,20 +185,47 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
|
||||
if (ReflectionUtility.GetTypeByName(input) is Type t && allowedTypes.Contains(t))
|
||||
AddSuggestion(t);
|
||||
|
||||
if (!suggestions.Any())
|
||||
AutoCompleteModal.Instance.SetSuggestions(loadingSuggestions, false);
|
||||
else
|
||||
AutoCompleteModal.Instance.SetSuggestions(suggestions, false);
|
||||
|
||||
Stopwatch sw = new();
|
||||
sw.Start();
|
||||
|
||||
// ExplorerCore.Log($"Checking {allowedTypes.Count} types...");
|
||||
|
||||
foreach (Type entry in allowedTypes)
|
||||
{
|
||||
if (AutoCompleteModal.CurrentHandler == null)
|
||||
yield break;
|
||||
|
||||
if (sw.ElapsedMilliseconds > 10)
|
||||
{
|
||||
yield return null;
|
||||
if (suggestions.Any())
|
||||
AutoCompleteModal.Instance.SetSuggestions(suggestions, false);
|
||||
|
||||
sw.Reset();
|
||||
sw.Start();
|
||||
}
|
||||
|
||||
if (entry.FullName.ContainsIgnoreCase(input))
|
||||
AddSuggestion(entry);
|
||||
}
|
||||
|
||||
AutoCompleteModal.Instance.SetSuggestions(suggestions, false);
|
||||
|
||||
// ExplorerCore.Log($"Fetched {suggestions.Count} TypeCompleter suggestions in {sw.ElapsedMilliseconds * 0.001f} seconds.");
|
||||
}
|
||||
|
||||
internal static readonly Dictionary<string, string> sharedTypeToLabel = new();
|
||||
|
||||
void AddSuggestion(Type type)
|
||||
{
|
||||
if (suggestedNames.Contains(type.FullName))
|
||||
if (suggestedTypes.Contains(type.FullName))
|
||||
return;
|
||||
suggestedNames.Add(type.FullName);
|
||||
suggestedTypes.Add(type.FullName);
|
||||
|
||||
if (!sharedTypeToLabel.ContainsKey(type.FullName))
|
||||
sharedTypeToLabel.Add(type.FullName, SignatureHighlighter.Parse(type, true));
|
||||
|
@ -15,22 +15,20 @@ namespace UnityExplorer.UI.Widgets
|
||||
|
||||
typeCompleter.Enabled = true;
|
||||
typeCompleter.BaseType = this.genericArgument;
|
||||
typeCompleter.CacheTypes();
|
||||
|
||||
Type[] constraints = this.genericArgument.GetGenericParameterConstraints();
|
||||
typeCompleter.GenericConstraints = constraints;
|
||||
|
||||
typeCompleter.CacheTypes();
|
||||
|
||||
StringBuilder sb = new($"<color={SignatureHighlighter.CONST}>{this.genericArgument.Name}</color>");
|
||||
|
||||
for (int j = 0; j < constraints.Length; j++)
|
||||
for (int i = 0; i < constraints.Length; i++)
|
||||
{
|
||||
if (j == 0) sb.Append(' ').Append('(');
|
||||
if (i == 0) sb.Append(' ').Append('(');
|
||||
else sb.Append(',').Append(' ');
|
||||
|
||||
sb.Append(SignatureHighlighter.Parse(constraints[j], false));
|
||||
sb.Append(SignatureHighlighter.Parse(constraints[i], false));
|
||||
|
||||
if (j + 1 == constraints.Length)
|
||||
if (i + 1 == constraints.Length)
|
||||
sb.Append(')');
|
||||
}
|
||||
|
||||
|
@ -79,11 +79,11 @@
|
||||
<!-- il2cpp nuget -->
|
||||
<ItemGroup Condition="'$(Configuration)'=='ML_Cpp_net6' or '$(Configuration)'=='ML_Cpp_net472' or '$(Configuration)'=='STANDALONE_Cpp' or '$(Configuration)'=='BIE_Cpp'">
|
||||
<PackageReference Include="Il2CppAssemblyUnhollower.BaseLib" Version="0.4.22" IncludeAssets="compile" />
|
||||
<PackageReference Include="UniverseLib.IL2CPP" Version="1.3.8" />
|
||||
<PackageReference Include="UniverseLib.IL2CPP" Version="1.3.10" />
|
||||
</ItemGroup>
|
||||
<!-- mono nuget -->
|
||||
<ItemGroup Condition="'$(Configuration)'=='BIE6_Mono' or '$(Configuration)'=='BIE5_Mono' or '$(Configuration)'=='ML_Mono' or '$(Configuration)'=='STANDALONE_Mono'">
|
||||
<PackageReference Include="UniverseLib.Mono" Version="1.3.8" />
|
||||
<PackageReference Include="UniverseLib.Mono" Version="1.3.10" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ~~~~~ ASSEMBLY REFERENCES ~~~~~ -->
|
||||
|
Reference in New Issue
Block a user