mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-22 16:42:38 +08:00
Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
3b71b40843 | |||
1292affe6d | |||
6614762fe8 | |||
d81d6d034b | |||
5dfe3bbf0c | |||
dc81451ce5 | |||
d7ab0a23c6 | |||
1a01c740e2 | |||
040fb1f11a | |||
e44ff9e207 | |||
b5c69fc1ea | |||
4fdb2aacd8 | |||
48e688cb75 | |||
647b0d353d | |||
2b715f3dbe | |||
938a991594 | |||
f00134b283 | |||
3b6b9768fb | |||
5fbfa1b7aa | |||
7d26965c12 | |||
862523399a | |||
0afccadc64 | |||
0e37e8030c | |||
621a9cd72e | |||
56be5414f9 |
@ -414,11 +414,15 @@ namespace UnityExplorer.CSConsole
|
|||||||
|
|
||||||
static bool usingEventSystemDictionaryMembers;
|
static bool usingEventSystemDictionaryMembers;
|
||||||
|
|
||||||
static readonly AmbiguousMemberHandler<EventSystem, GameObject> m_CurrentSelected_Handler_Normal = new("m_CurrentSelected", "m_currentSelected");
|
static readonly AmbiguousMemberHandler<EventSystem, GameObject> m_CurrentSelected_Handler_Normal
|
||||||
static readonly AmbiguousMemberHandler<EventSystem, Dictionary<int, GameObject>> m_CurrentSelected_Handler_Dictionary = new("m_CurrentSelected", "m_currentSelected");
|
= new(true, true, "m_CurrentSelected", "m_currentSelected");
|
||||||
|
static readonly AmbiguousMemberHandler<EventSystem, Dictionary<int, GameObject>> m_CurrentSelected_Handler_Dictionary
|
||||||
|
= new(true, true, "m_CurrentSelected", "m_currentSelected");
|
||||||
|
|
||||||
static readonly AmbiguousMemberHandler<EventSystem, bool> m_SelectionGuard_Handler_Normal = new("m_SelectionGuard", "m_selectionGuard");
|
static readonly AmbiguousMemberHandler<EventSystem, bool> m_SelectionGuard_Handler_Normal
|
||||||
static readonly AmbiguousMemberHandler<EventSystem, Dictionary<int, bool>> m_SelectionGuard_Handler_Dictionary = new("m_SelectionGuard", "m_selectionGuard");
|
= new(true, true, "m_SelectionGuard", "m_selectionGuard");
|
||||||
|
static readonly AmbiguousMemberHandler<EventSystem, Dictionary<int, bool>> m_SelectionGuard_Handler_Dictionary
|
||||||
|
= new(true, true, "m_SelectionGuard", "m_selectionGuard");
|
||||||
|
|
||||||
static void SetCurrentSelectedGameObject(EventSystem instance, GameObject value)
|
static void SetCurrentSelectedGameObject(EventSystem instance, GameObject value)
|
||||||
{
|
{
|
||||||
|
83
src/CacheObject/CacheConstructor.cs
Normal file
83
src/CacheObject/CacheConstructor.cs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using UnityExplorer.Inspectors;
|
||||||
|
using UniverseLib.Utility;
|
||||||
|
|
||||||
|
namespace UnityExplorer.CacheObject
|
||||||
|
{
|
||||||
|
public class CacheConstructor : CacheMember
|
||||||
|
{
|
||||||
|
public ConstructorInfo CtorInfo { get; }
|
||||||
|
readonly Type typeForStructConstructor;
|
||||||
|
|
||||||
|
public override Type DeclaringType => typeForStructConstructor ?? CtorInfo.DeclaringType;
|
||||||
|
public override bool IsStatic => true;
|
||||||
|
public override bool ShouldAutoEvaluate => false;
|
||||||
|
public override bool CanWrite => false;
|
||||||
|
|
||||||
|
public CacheConstructor(ConstructorInfo ci)
|
||||||
|
{
|
||||||
|
this.CtorInfo = ci;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CacheConstructor(Type typeForStructConstructor)
|
||||||
|
{
|
||||||
|
this.typeForStructConstructor = typeForStructConstructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
||||||
|
{
|
||||||
|
// if is parameterless struct ctor
|
||||||
|
if (typeForStructConstructor != null)
|
||||||
|
{
|
||||||
|
this.Owner = inspector;
|
||||||
|
|
||||||
|
// eg. Vector3.Vector3()
|
||||||
|
this.NameLabelText = SignatureHighlighter.Parse(typeForStructConstructor, false);
|
||||||
|
NameLabelText += $".{NameLabelText}()";
|
||||||
|
|
||||||
|
this.NameForFiltering = SignatureHighlighter.RemoveHighlighting(NameLabelText);
|
||||||
|
this.NameLabelTextRaw = NameForFiltering;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.SetInspectorOwner(inspector, member);
|
||||||
|
|
||||||
|
Arguments = CtorInfo.GetParameters();
|
||||||
|
if (CtorInfo.DeclaringType.IsGenericTypeDefinition)
|
||||||
|
GenericArguments = CtorInfo.DeclaringType.GetGenericArguments();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override object TryEvaluate()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Type returnType = DeclaringType;
|
||||||
|
|
||||||
|
if (returnType.IsGenericTypeDefinition)
|
||||||
|
returnType = DeclaringType.MakeGenericType(Evaluator.TryParseGenericArguments());
|
||||||
|
|
||||||
|
object ret;
|
||||||
|
if (HasArguments)
|
||||||
|
ret = Activator.CreateInstance(returnType, Evaluator.TryParseArguments());
|
||||||
|
else
|
||||||
|
ret = Activator.CreateInstance(returnType, ArgumentUtility.EmptyArgs);
|
||||||
|
|
||||||
|
HadException = false;
|
||||||
|
LastException = null;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
HadException = true;
|
||||||
|
LastException = ex;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void TrySetValue(object value) => throw new NotImplementedException("You can't set a constructor");
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,11 @@ namespace UnityExplorer.CacheObject
|
|||||||
|
|
||||||
public override bool ShouldAutoEvaluate => true;
|
public override bool ShouldAutoEvaluate => true;
|
||||||
|
|
||||||
|
public CacheField(FieldInfo fi)
|
||||||
|
{
|
||||||
|
this.FieldInfo = fi;
|
||||||
|
}
|
||||||
|
|
||||||
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
||||||
{
|
{
|
||||||
base.SetInspectorOwner(inspector, member);
|
base.SetInspectorOwner(inspector, member);
|
||||||
|
@ -14,6 +14,8 @@ using UniverseLib.UI;
|
|||||||
using UnityExplorer.UI.Widgets;
|
using UnityExplorer.UI.Widgets;
|
||||||
using UniverseLib.Utility;
|
using UniverseLib.Utility;
|
||||||
using UniverseLib.UI.ObjectPool;
|
using UniverseLib.UI.ObjectPool;
|
||||||
|
using System.Collections;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
namespace UnityExplorer.CacheObject
|
namespace UnityExplorer.CacheObject
|
||||||
{
|
{
|
||||||
@ -34,10 +36,14 @@ namespace UnityExplorer.CacheObject
|
|||||||
public virtual void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
public virtual void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
||||||
{
|
{
|
||||||
this.Owner = inspector;
|
this.Owner = inspector;
|
||||||
this.NameLabelText = this is CacheMethod
|
this.NameLabelText = this switch
|
||||||
? SignatureHighlighter.HighlightMethod(member as MethodInfo)
|
{
|
||||||
: SignatureHighlighter.Parse(member.DeclaringType, false, member);
|
CacheMethod => SignatureHighlighter.HighlightMethod(member as MethodInfo),
|
||||||
this.NameForFiltering = $"{member.DeclaringType.Name}.{member.Name}";
|
CacheConstructor => SignatureHighlighter.HighlightConstructor(member as ConstructorInfo),
|
||||||
|
_ => SignatureHighlighter.Parse(member.DeclaringType, false, member),
|
||||||
|
};
|
||||||
|
|
||||||
|
this.NameForFiltering = SignatureHighlighter.RemoveHighlighting(NameLabelText);
|
||||||
this.NameLabelTextRaw = NameForFiltering;
|
this.NameLabelTextRaw = NameForFiltering;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,76 +170,75 @@ namespace UnityExplorer.CacheObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region Cache Member Util
|
#region Cache Member Util
|
||||||
|
|
||||||
//public static bool CanParseArgs(ParameterInfo[] parameters)
|
public static List<CacheMember> GetCacheMembers(object inspectorTarget, Type type, ReflectionInspector inspector)
|
||||||
//{
|
|
||||||
// foreach (var param in parameters)
|
|
||||||
// {
|
|
||||||
// var pType = param.ParameterType;
|
|
||||||
//
|
|
||||||
// if (pType.IsByRef && pType.HasElementType)
|
|
||||||
// pType = pType.GetElementType();
|
|
||||||
//
|
|
||||||
// if (pType != null && ParseUtility.CanParse(pType))
|
|
||||||
// continue;
|
|
||||||
// else
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// return true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
public static List<CacheMember> GetCacheMembers(object inspectorTarget, Type _type, ReflectionInspector _inspector)
|
|
||||||
{
|
{
|
||||||
var list = new List<CacheMember>();
|
//var list = new List<CacheMember>();
|
||||||
var cachedSigs = new HashSet<string>();
|
HashSet<string> cachedSigs = new();
|
||||||
|
List<CacheMember> props = new();
|
||||||
|
List<CacheMember> fields = new();
|
||||||
|
List<CacheMember> ctors = new();
|
||||||
|
List<CacheMember> methods = new();
|
||||||
|
|
||||||
var types = ReflectionUtility.GetAllBaseTypes(_type);
|
var types = ReflectionUtility.GetAllBaseTypes(type);
|
||||||
|
|
||||||
var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;
|
var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;
|
||||||
if (!_inspector.StaticOnly)
|
if (!inspector.StaticOnly)
|
||||||
flags |= BindingFlags.Instance;
|
flags |= BindingFlags.Instance;
|
||||||
|
|
||||||
var infos = new List<MemberInfo>();
|
if (!type.IsAbstract)
|
||||||
|
{
|
||||||
|
// Get non-static constructors of the main type.
|
||||||
|
// There's no reason to get the static cctor, it will be invoked when we inspect the class.
|
||||||
|
// Also no point getting ctors on inherited types.
|
||||||
|
foreach (var ctor in type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
|
||||||
|
TryCacheMember(ctor, ctors, cachedSigs, type, inspector);
|
||||||
|
|
||||||
|
// structs always have a parameterless constructor
|
||||||
|
if (type.IsValueType)
|
||||||
|
{
|
||||||
|
CacheConstructor cached = new(type);
|
||||||
|
cached.SetFallbackType(type);
|
||||||
|
cached.SetInspectorOwner(inspector, null);
|
||||||
|
ctors.Add(cached);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var declaringType in types)
|
foreach (var declaringType in types)
|
||||||
{
|
{
|
||||||
var target = inspectorTarget;
|
var target = inspectorTarget;
|
||||||
if (!_inspector.StaticOnly)
|
if (!inspector.StaticOnly)
|
||||||
target = target.TryCast(declaringType);
|
target = target.TryCast(declaringType);
|
||||||
|
|
||||||
infos.Clear();
|
foreach (var prop in declaringType.GetProperties(flags))
|
||||||
infos.AddRange(declaringType.GetProperties(flags));
|
if (prop.DeclaringType == declaringType)
|
||||||
infos.AddRange(declaringType.GetFields(flags));
|
TryCacheMember(prop, props, cachedSigs, declaringType, inspector);
|
||||||
infos.AddRange(declaringType.GetMethods(flags));
|
|
||||||
|
foreach (var field in declaringType.GetFields(flags))
|
||||||
|
if (field.DeclaringType == declaringType)
|
||||||
|
TryCacheMember(field, fields, cachedSigs, declaringType, inspector);
|
||||||
|
|
||||||
|
foreach (var method in declaringType.GetMethods(flags))
|
||||||
|
if (method.DeclaringType == declaringType)
|
||||||
|
TryCacheMember(method, methods, cachedSigs, declaringType, inspector);
|
||||||
|
|
||||||
foreach (var member in infos)
|
|
||||||
{
|
|
||||||
if (member.DeclaringType != declaringType)
|
|
||||||
continue;
|
|
||||||
TryCacheMember(member, list, cachedSigs, declaringType, _inspector);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var typeList = types.ToList();
|
|
||||||
|
|
||||||
var sorted = new List<CacheMember>();
|
var sorted = new List<CacheMember>();
|
||||||
sorted.AddRange(list.Where(it => it is CacheProperty)
|
sorted.AddRange(props.OrderBy(it => Array.IndexOf(types, it.DeclaringType))
|
||||||
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
|
.ThenBy(it => it.NameForFiltering));
|
||||||
.ThenBy(it => it.NameForFiltering));
|
sorted.AddRange(fields.OrderBy(it => Array.IndexOf(types, it.DeclaringType))
|
||||||
sorted.AddRange(list.Where(it => it is CacheField)
|
.ThenBy(it => it.NameForFiltering));
|
||||||
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
|
sorted.AddRange(ctors.OrderBy(it => Array.IndexOf(types, it.DeclaringType))
|
||||||
.ThenBy(it => it.NameForFiltering));
|
.ThenBy(it => it.NameForFiltering));
|
||||||
sorted.AddRange(list.Where(it => it is CacheMethod)
|
sorted.AddRange(methods.OrderBy(it => Array.IndexOf(types, it.DeclaringType))
|
||||||
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
|
.ThenBy(it => it.NameForFiltering));
|
||||||
.ThenBy(it => it.NameForFiltering));
|
|
||||||
|
|
||||||
return sorted;
|
return sorted;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void TryCacheMember(MemberInfo member, List<CacheMember> list, HashSet<string> cachedSigs,
|
private static void TryCacheMember(MemberInfo member, IList list, HashSet<string> cachedSigs,
|
||||||
Type declaringType, ReflectionInspector _inspector, bool ignorePropertyMethodInfos = true)
|
Type declaringType, ReflectionInspector inspector, bool ignorePropertyMethodInfos = true)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -248,6 +253,17 @@ namespace UnityExplorer.CacheObject
|
|||||||
Type returnType;
|
Type returnType;
|
||||||
switch (member.MemberType)
|
switch (member.MemberType)
|
||||||
{
|
{
|
||||||
|
case MemberTypes.Constructor:
|
||||||
|
{
|
||||||
|
var ci = member as ConstructorInfo;
|
||||||
|
sig += GetArgumentString(ci.GetParameters());
|
||||||
|
if (cachedSigs.Contains(sig))
|
||||||
|
return;
|
||||||
|
cached = new CacheConstructor(ci);
|
||||||
|
returnType = ci.DeclaringType;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case MemberTypes.Method:
|
case MemberTypes.Method:
|
||||||
{
|
{
|
||||||
var mi = member as MethodInfo;
|
var mi = member as MethodInfo;
|
||||||
@ -255,15 +271,11 @@ namespace UnityExplorer.CacheObject
|
|||||||
&& (mi.Name.StartsWith("get_") || mi.Name.StartsWith("set_")))
|
&& (mi.Name.StartsWith("get_") || mi.Name.StartsWith("set_")))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//var args = mi.GetParameters();
|
|
||||||
//if (!CanParseArgs(args))
|
|
||||||
// return;
|
|
||||||
|
|
||||||
sig += GetArgumentString(mi.GetParameters());
|
sig += GetArgumentString(mi.GetParameters());
|
||||||
if (cachedSigs.Contains(sig))
|
if (cachedSigs.Contains(sig))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cached = new CacheMethod() { MethodInfo = mi };
|
cached = new CacheMethod(mi);
|
||||||
returnType = mi.ReturnType;
|
returnType = mi.ReturnType;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -272,16 +284,12 @@ namespace UnityExplorer.CacheObject
|
|||||||
{
|
{
|
||||||
var pi = member as PropertyInfo;
|
var pi = member as PropertyInfo;
|
||||||
|
|
||||||
//var args = pi.GetIndexParameters();
|
|
||||||
//if (!CanParseArgs(args))
|
|
||||||
// return;
|
|
||||||
|
|
||||||
if (!pi.CanRead && pi.CanWrite)
|
if (!pi.CanRead && pi.CanWrite)
|
||||||
{
|
{
|
||||||
// write-only property, cache the set method instead.
|
// write-only property, cache the set method instead.
|
||||||
var setMethod = pi.GetSetMethod(true);
|
var setMethod = pi.GetSetMethod(true);
|
||||||
if (setMethod != null)
|
if (setMethod != null)
|
||||||
TryCacheMember(setMethod, list, cachedSigs, declaringType, _inspector, false);
|
TryCacheMember(setMethod, list, cachedSigs, declaringType, inspector, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,7 +297,7 @@ namespace UnityExplorer.CacheObject
|
|||||||
if (cachedSigs.Contains(sig))
|
if (cachedSigs.Contains(sig))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cached = new CacheProperty() { PropertyInfo = pi };
|
cached = new CacheProperty(pi);
|
||||||
returnType = pi.PropertyType;
|
returnType = pi.PropertyType;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -297,7 +305,7 @@ namespace UnityExplorer.CacheObject
|
|||||||
case MemberTypes.Field:
|
case MemberTypes.Field:
|
||||||
{
|
{
|
||||||
var fi = member as FieldInfo;
|
var fi = member as FieldInfo;
|
||||||
cached = new CacheField() { FieldInfo = fi };
|
cached = new CacheField(fi);
|
||||||
returnType = fi.FieldType;
|
returnType = fi.FieldType;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -308,7 +316,7 @@ namespace UnityExplorer.CacheObject
|
|||||||
cachedSigs.Add(sig);
|
cachedSigs.Add(sig);
|
||||||
|
|
||||||
cached.SetFallbackType(returnType);
|
cached.SetFallbackType(returnType);
|
||||||
cached.SetInspectorOwner(_inspector, member);
|
cached.SetInspectorOwner(inspector, member);
|
||||||
|
|
||||||
list.Add(cached);
|
list.Add(cached);
|
||||||
}
|
}
|
||||||
|
@ -11,13 +11,18 @@ namespace UnityExplorer.CacheObject
|
|||||||
{
|
{
|
||||||
public class CacheMethod : CacheMember
|
public class CacheMethod : CacheMember
|
||||||
{
|
{
|
||||||
public MethodInfo MethodInfo { get; internal set; }
|
public MethodInfo MethodInfo { get; }
|
||||||
public override Type DeclaringType => MethodInfo.DeclaringType;
|
public override Type DeclaringType => MethodInfo.DeclaringType;
|
||||||
public override bool CanWrite => false;
|
public override bool CanWrite => false;
|
||||||
public override bool IsStatic => MethodInfo.IsStatic;
|
public override bool IsStatic => MethodInfo.IsStatic;
|
||||||
|
|
||||||
public override bool ShouldAutoEvaluate => false;
|
public override bool ShouldAutoEvaluate => false;
|
||||||
|
|
||||||
|
public CacheMethod (MethodInfo mi)
|
||||||
|
{
|
||||||
|
this.MethodInfo = mi;
|
||||||
|
}
|
||||||
|
|
||||||
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
||||||
{
|
{
|
||||||
base.SetInspectorOwner(inspector, member);
|
base.SetInspectorOwner(inspector, member);
|
||||||
|
@ -19,6 +19,11 @@ namespace UnityExplorer.CacheObject
|
|||||||
|
|
||||||
public override bool ShouldAutoEvaluate => !HasArguments;
|
public override bool ShouldAutoEvaluate => !HasArguments;
|
||||||
|
|
||||||
|
public CacheProperty(PropertyInfo pi)
|
||||||
|
{
|
||||||
|
this.PropertyInfo = pi;
|
||||||
|
}
|
||||||
|
|
||||||
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
public override void SetInspectorOwner(ReflectionInspector inspector, MemberInfo member)
|
||||||
{
|
{
|
||||||
base.SetInspectorOwner(inspector, member);
|
base.SetInspectorOwner(inspector, member);
|
||||||
|
@ -29,8 +29,11 @@ namespace UnityExplorer.CacheObject.IValues
|
|||||||
private EnumCompleter enumCompleter;
|
private EnumCompleter enumCompleter;
|
||||||
|
|
||||||
private GameObject toggleHolder;
|
private GameObject toggleHolder;
|
||||||
private readonly List<Toggle> flagToggles = new List<Toggle>();
|
private readonly List<Toggle> flagToggles = new();
|
||||||
private readonly List<Text> flagTexts = new List<Text>();
|
private readonly List<Text> flagTexts = new();
|
||||||
|
|
||||||
|
public CachedEnumValue ValueAtIndex(int idx) => (CachedEnumValue)CurrentValues[idx];
|
||||||
|
public CachedEnumValue ValueAtKey(object key) => (CachedEnumValue)CurrentValues[key];
|
||||||
|
|
||||||
// Setting value from owner
|
// Setting value from owner
|
||||||
public override void SetValue(object value)
|
public override void SetValue(object value)
|
||||||
@ -70,13 +73,8 @@ namespace UnityExplorer.CacheObject.IValues
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var split = value.ToString().Split(',');
|
|
||||||
var set = new HashSet<string>();
|
|
||||||
foreach (var s in split)
|
|
||||||
set.Add(s.Trim());
|
|
||||||
|
|
||||||
for (int i = 0; i < CurrentValues.Count; i++)
|
for (int i = 0; i < CurrentValues.Count; i++)
|
||||||
flagToggles[i].isOn = set.Contains(ValueAtIdx(i).Name);
|
flagToggles[i].isOn = (value as Enum).HasFlag(ValueAtIndex(i).ActualValue as Enum);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -116,7 +114,7 @@ namespace UnityExplorer.CacheObject.IValues
|
|||||||
for (int i = 0; i < CurrentValues.Count; i++)
|
for (int i = 0; i < CurrentValues.Count; i++)
|
||||||
{
|
{
|
||||||
if (flagToggles[i].isOn)
|
if (flagToggles[i].isOn)
|
||||||
values.Add(ValueAtIdx(i).Name);
|
values.Add(ValueAtIndex(i).Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentOwner.SetUserValue(Enum.Parse(EnumType, string.Join(", ", values.ToArray())));
|
CurrentOwner.SetUserValue(Enum.Parse(EnumType, string.Join(", ", values.ToArray())));
|
||||||
@ -166,9 +164,6 @@ namespace UnityExplorer.CacheObject.IValues
|
|||||||
return UIRoot;
|
return UIRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CachedEnumValue ValueAtIdx(int idx) => (CachedEnumValue)CurrentValues[idx];
|
|
||||||
public CachedEnumValue ValueAtKey(object key) => (CachedEnumValue)CurrentValues[key];
|
|
||||||
|
|
||||||
private void SetupTogglesForEnumType()
|
private void SetupTogglesForEnumType()
|
||||||
{
|
{
|
||||||
toggleHolder.SetActive(true);
|
toggleHolder.SetActive(true);
|
||||||
@ -191,7 +186,7 @@ namespace UnityExplorer.CacheObject.IValues
|
|||||||
AddToggleRow();
|
AddToggleRow();
|
||||||
|
|
||||||
flagToggles[i].isOn = false;
|
flagToggles[i].isOn = false;
|
||||||
flagTexts[i].text = ValueAtIdx(i).Name;
|
flagTexts[i].text = ValueAtIndex(i).Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ namespace UnityExplorer
|
|||||||
public static class ExplorerCore
|
public static class ExplorerCore
|
||||||
{
|
{
|
||||||
public const string NAME = "UnityExplorer";
|
public const string NAME = "UnityExplorer";
|
||||||
public const string VERSION = "4.5.9";
|
public const string VERSION = "4.5.12";
|
||||||
public const string AUTHOR = "Sinai";
|
public const string AUTHOR = "Sinai";
|
||||||
public const string GUID = "com.sinai.unityexplorer";
|
public const string GUID = "com.sinai.unityexplorer";
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
this.Target = newTarget;
|
this.Target = newTarget;
|
||||||
GOControls.UpdateGameObjectInfo(true, true);
|
GOControls.UpdateGameObjectInfo(true, true);
|
||||||
GOControls.UpdateTransformControlValues(true);
|
GOControls.UpdateTransformControlValues(true);
|
||||||
TransformTree.RefreshData(true, false);
|
TransformTree.RefreshData(true, false, true, false);
|
||||||
UpdateComponents();
|
UpdateComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
|
|
||||||
GOControls.UpdateGameObjectInfo(false, false);
|
GOControls.UpdateGameObjectInfo(false, false);
|
||||||
|
|
||||||
TransformTree.RefreshData(true, false);
|
TransformTree.RefreshData(true, false, false, false);
|
||||||
UpdateComponents();
|
UpdateComponents();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,7 +220,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
var newObject = new GameObject(input);
|
var newObject = new GameObject(input);
|
||||||
newObject.transform.parent = GOTarget.transform;
|
newObject.transform.parent = GOTarget.transform;
|
||||||
|
|
||||||
TransformTree.RefreshData(true, false);
|
TransformTree.RefreshData(true, false, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAddComponentClicked(string input)
|
private void OnAddComponentClicked(string input)
|
||||||
|
@ -43,9 +43,10 @@ namespace UnityExplorer.Inspectors
|
|||||||
TabButton = UIFactory.CreateButton(UIRoot, "TabButton", "");
|
TabButton = UIFactory.CreateButton(UIRoot, "TabButton", "");
|
||||||
UIFactory.SetLayoutElement(TabButton.Component.gameObject, minWidth: 173, flexibleWidth: 0);
|
UIFactory.SetLayoutElement(TabButton.Component.gameObject, minWidth: 173, flexibleWidth: 0);
|
||||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(TabButton.Component.gameObject, false, false, true, true, 0, 0, 0, 3);
|
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(TabButton.Component.gameObject, false, false, true, true, 0, 0, 0, 3);
|
||||||
|
TabButton.GameObject.AddComponent<Mask>();
|
||||||
|
|
||||||
TabText = TabButton.Component.GetComponentInChildren<Text>();
|
TabText = TabButton.ButtonText;
|
||||||
UIFactory.SetLayoutElement(TabText.gameObject, minHeight: 25, minWidth: 173, flexibleWidth: 0);
|
UIFactory.SetLayoutElement(TabText.gameObject, minHeight: 25, minWidth: 150, flexibleWidth: 0);
|
||||||
TabText.alignment = TextAnchor.MiddleLeft;
|
TabText.alignment = TextAnchor.MiddleLeft;
|
||||||
TabText.fontSize = 12;
|
TabText.fontSize = 12;
|
||||||
TabText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
TabText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -8,6 +9,7 @@ using UnityEngine.UI;
|
|||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityExplorer.UI.Panels;
|
using UnityExplorer.UI.Panels;
|
||||||
using UniverseLib;
|
using UniverseLib;
|
||||||
|
using UniverseLib.Input;
|
||||||
|
|
||||||
namespace UnityExplorer.Inspectors.MouseInspectors
|
namespace UnityExplorer.Inspectors.MouseInspectors
|
||||||
{
|
{
|
||||||
@ -38,6 +40,12 @@ namespace UnityExplorer.Inspectors.MouseInspectors
|
|||||||
{
|
{
|
||||||
LastHitObjects.Clear();
|
LastHitObjects.Clear();
|
||||||
LastHitObjects.AddRange(currentHitObjects);
|
LastHitObjects.AddRange(currentHitObjects);
|
||||||
|
RuntimeHelper.StartCoroutine(SetPanelActiveCoro());
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator SetPanelActiveCoro()
|
||||||
|
{
|
||||||
|
yield return null;
|
||||||
var panel = UIManager.GetPanel<UiInspectorResultsPanel>(UIManager.Panels.UIInspectorResults);
|
var panel = UIManager.GetPanel<UiInspectorResultsPanel>(UIManager.Panels.UIInspectorResults);
|
||||||
panel.SetActive(true);
|
panel.SetActive(true);
|
||||||
panel.ShowResults();
|
panel.ShowResults();
|
||||||
|
@ -46,8 +46,9 @@ namespace UnityExplorer.Inspectors
|
|||||||
None = 0,
|
None = 0,
|
||||||
Property = 1,
|
Property = 1,
|
||||||
Field = 2,
|
Field = 2,
|
||||||
Method = 4,
|
Constructor = 4,
|
||||||
All = 7
|
Method = 8,
|
||||||
|
All = Property | Field | Method | Constructor,
|
||||||
}
|
}
|
||||||
|
|
||||||
// UI
|
// UI
|
||||||
@ -133,7 +134,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
currentBaseTabText = $"{prefix} {SignatureHighlighter.Parse(TargetType, false)}";
|
currentBaseTabText = $"{prefix} {SignatureHighlighter.Parse(TargetType, false)}";
|
||||||
Tab.TabText.text = currentBaseTabText;
|
Tab.TabText.text = currentBaseTabText;
|
||||||
NameText.text = SignatureHighlighter.Parse(TargetType, true);
|
NameText.text = SignatureHighlighter.Parse(TargetType, true);
|
||||||
HiddenNameText.Text = TargetType.FullName;
|
HiddenNameText.Text = SignatureHighlighter.RemoveHighlighting(NameText.text);
|
||||||
|
|
||||||
string asmText;
|
string asmText;
|
||||||
if (TargetType.Assembly is AssemblyBuilder || string.IsNullOrEmpty(TargetType.Assembly.Location))
|
if (TargetType.Assembly is AssemblyBuilder || string.IsNullOrEmpty(TargetType.Assembly.Location))
|
||||||
@ -153,7 +154,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
|
|
||||||
this.filterInputField.Text = "";
|
this.filterInputField.Text = "";
|
||||||
|
|
||||||
SetFilter("", StaticOnly ? BindingFlags.Static : BindingFlags.Instance);
|
SetFilter("", StaticOnly ? BindingFlags.Static : BindingFlags.Default);
|
||||||
scopeFilterButtons[BindingFlags.Default].Component.gameObject.SetActive(!StaticOnly);
|
scopeFilterButtons[BindingFlags.Default].Component.gameObject.SetActive(!StaticOnly);
|
||||||
scopeFilterButtons[BindingFlags.Instance].Component.gameObject.SetActive(!StaticOnly);
|
scopeFilterButtons[BindingFlags.Instance].Component.gameObject.SetActive(!StaticOnly);
|
||||||
|
|
||||||
@ -261,7 +262,8 @@ namespace UnityExplorer.Inspectors
|
|||||||
|
|
||||||
if ((member is CacheMethod && !MemberFilter.HasFlag(MemberFlags.Method))
|
if ((member is CacheMethod && !MemberFilter.HasFlag(MemberFlags.Method))
|
||||||
|| (member is CacheField && !MemberFilter.HasFlag(MemberFlags.Field))
|
|| (member is CacheField && !MemberFilter.HasFlag(MemberFlags.Field))
|
||||||
|| (member is CacheProperty && !MemberFilter.HasFlag(MemberFlags.Property)))
|
|| (member is CacheProperty && !MemberFilter.HasFlag(MemberFlags.Property))
|
||||||
|
|| (member is CacheConstructor && !MemberFilter.HasFlag(MemberFlags.Constructor)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(NameFilter) && !member.NameForFiltering.ContainsIgnoreCase(NameFilter))
|
if (!string.IsNullOrEmpty(NameFilter) && !member.NameForFiltering.ContainsIgnoreCase(NameFilter))
|
||||||
@ -462,6 +464,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
AddMemberTypeToggle(rowObj, MemberTypes.Property, 90);
|
AddMemberTypeToggle(rowObj, MemberTypes.Property, 90);
|
||||||
AddMemberTypeToggle(rowObj, MemberTypes.Field, 70);
|
AddMemberTypeToggle(rowObj, MemberTypes.Field, 70);
|
||||||
AddMemberTypeToggle(rowObj, MemberTypes.Method, 90);
|
AddMemberTypeToggle(rowObj, MemberTypes.Method, 90);
|
||||||
|
AddMemberTypeToggle(rowObj, MemberTypes.Constructor, 110);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddScopeFilterButton(GameObject parent, BindingFlags flags, bool setAsActive = false)
|
private void AddScopeFilterButton(GameObject parent, BindingFlags flags, bool setAsActive = false)
|
||||||
@ -480,25 +483,26 @@ namespace UnityExplorer.Inspectors
|
|||||||
{
|
{
|
||||||
var toggleObj = UIFactory.CreateToggle(parent, "Toggle_" + type, out Toggle toggle, out Text toggleText);
|
var toggleObj = UIFactory.CreateToggle(parent, "Toggle_" + type, out Toggle toggle, out Text toggleText);
|
||||||
UIFactory.SetLayoutElement(toggleObj, minHeight: 25, minWidth: width);
|
UIFactory.SetLayoutElement(toggleObj, minHeight: 25, minWidth: width);
|
||||||
var color = type switch
|
string color = type switch
|
||||||
{
|
{
|
||||||
MemberTypes.Method => SignatureHighlighter.METHOD_INSTANCE,
|
MemberTypes.Method => SignatureHighlighter.METHOD_INSTANCE,
|
||||||
MemberTypes.Field => SignatureHighlighter.FIELD_INSTANCE,
|
MemberTypes.Field => SignatureHighlighter.FIELD_INSTANCE,
|
||||||
MemberTypes.Property => SignatureHighlighter.PROP_INSTANCE,
|
MemberTypes.Property => SignatureHighlighter.PROP_INSTANCE,
|
||||||
|
MemberTypes.Constructor => SignatureHighlighter.CLASS_INSTANCE,
|
||||||
_ => throw new NotImplementedException()
|
_ => throw new NotImplementedException()
|
||||||
};
|
};
|
||||||
toggleText.text = $"<color={color}>{type}</color>";
|
toggleText.text = $"<color={color}>{type}</color>";
|
||||||
|
|
||||||
toggle.graphic.TryCast<Image>().color = color.ToColor() * 0.65f;
|
toggle.graphic.TryCast<Image>().color = color.ToColor() * 0.65f;
|
||||||
|
|
||||||
MemberFlags flag;
|
MemberFlags flag = type switch
|
||||||
switch (type)
|
|
||||||
{
|
{
|
||||||
case MemberTypes.Method: flag = MemberFlags.Method; break;
|
MemberTypes.Method => MemberFlags.Method,
|
||||||
case MemberTypes.Property: flag = MemberFlags.Property; break;
|
MemberTypes.Property => MemberFlags.Property,
|
||||||
case MemberTypes.Field: flag = MemberFlags.Field; break;
|
MemberTypes.Field => MemberFlags.Field,
|
||||||
default: return;
|
MemberTypes.Constructor => MemberFlags.Constructor,
|
||||||
}
|
_ => throw new NotImplementedException()
|
||||||
|
};
|
||||||
|
|
||||||
toggle.onValueChanged.AddListener((bool val) => { OnMemberTypeToggled(flag, val); });
|
toggle.onValueChanged.AddListener((bool val) => { OnMemberTypeToggled(flag, val); });
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ namespace UnityExplorer.ObjectExplorer
|
|||||||
public void UpdateTree()
|
public void UpdateTree()
|
||||||
{
|
{
|
||||||
SceneHandler.Update();
|
SceneHandler.Update();
|
||||||
Tree.RefreshData(true);
|
Tree.RefreshData(true, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void JumpToTransform(Transform transform)
|
public void JumpToTransform(Transform transform)
|
||||||
@ -94,7 +94,7 @@ namespace UnityExplorer.ObjectExplorer
|
|||||||
|
|
||||||
SceneHandler.SelectedScene = SceneHandler.LoadedScenes[value];
|
SceneHandler.SelectedScene = SceneHandler.LoadedScenes[value];
|
||||||
SceneHandler.Update();
|
SceneHandler.Update();
|
||||||
Tree.RefreshData(true);
|
Tree.RefreshData(true, true, true, false);
|
||||||
OnSelectedSceneChanged(SceneHandler.SelectedScene.Value);
|
OnSelectedSceneChanged(SceneHandler.SelectedScene.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ namespace UnityExplorer.ObjectExplorer
|
|||||||
}
|
}
|
||||||
|
|
||||||
Tree.CurrentFilter = input;
|
Tree.CurrentFilter = input;
|
||||||
Tree.RefreshData(true, true);
|
Tree.RefreshData(true, false, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TryLoadScene(LoadSceneMode mode, Dropdown allSceneDrop)
|
private void TryLoadScene(LoadSceneMode mode, Dropdown allSceneDrop)
|
||||||
@ -239,6 +239,17 @@ namespace UnityExplorer.ObjectExplorer
|
|||||||
|
|
||||||
refreshRow.SetActive(false);
|
refreshRow.SetActive(false);
|
||||||
|
|
||||||
|
// tree labels row
|
||||||
|
|
||||||
|
var labelsRow = UIFactory.CreateHorizontalGroup(toolbar, "LabelsRow", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
|
||||||
|
UIFactory.SetLayoutElement(labelsRow, minHeight: 30, flexibleHeight: 0);
|
||||||
|
|
||||||
|
var nameLabel = UIFactory.CreateLabel(labelsRow, "NameLabel", "Name", TextAnchor.MiddleLeft, color: Color.grey);
|
||||||
|
UIFactory.SetLayoutElement(nameLabel.gameObject, flexibleWidth: 9999, minHeight: 25);
|
||||||
|
|
||||||
|
var indexLabel = UIFactory.CreateLabel(labelsRow, "IndexLabel", "Sibling Index", TextAnchor.MiddleLeft, fontSize: 12, color: Color.grey);
|
||||||
|
UIFactory.SetLayoutElement(indexLabel.gameObject, minWidth: 100, flexibleWidth: 0, minHeight: 25);
|
||||||
|
|
||||||
// Transform Tree
|
// Transform Tree
|
||||||
|
|
||||||
var scrollPool = UIFactory.CreateScrollPool<TransformCell>(uiRoot, "TransformTree", out GameObject scrollObj,
|
var scrollPool = UIFactory.CreateScrollPool<TransformCell>(uiRoot, "TransformTree", out GameObject scrollObj,
|
||||||
@ -248,7 +259,7 @@ namespace UnityExplorer.ObjectExplorer
|
|||||||
|
|
||||||
Tree = new TransformTree(scrollPool, GetRootEntries);
|
Tree = new TransformTree(scrollPool, GetRootEntries);
|
||||||
Tree.Init();
|
Tree.Init();
|
||||||
Tree.RefreshData(true, true);
|
Tree.RefreshData(true, true, true, false);
|
||||||
//scrollPool.Viewport.GetComponent<Mask>().enabled = false;
|
//scrollPool.Viewport.GetComponent<Mask>().enabled = false;
|
||||||
//UIRoot.GetComponent<Mask>().enabled = false;
|
//UIRoot.GetComponent<Mask>().enabled = false;
|
||||||
|
|
||||||
|
@ -30,13 +30,13 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
|
|||||||
public override int MinWidth => -1;
|
public override int MinWidth => -1;
|
||||||
public override int MinHeight => -1;
|
public override int MinHeight => -1;
|
||||||
|
|
||||||
public override bool CanDragAndResize => false;
|
public override bool CanDragAndResize => true;
|
||||||
public override bool ShouldSaveActiveState => false;
|
public override bool ShouldSaveActiveState => false;
|
||||||
public override bool NavButtonWanted => false;
|
public override bool NavButtonWanted => false;
|
||||||
|
|
||||||
public static ISuggestionProvider CurrentHandler { get; private set; }
|
public static ISuggestionProvider CurrentHandler { get; private set; }
|
||||||
|
|
||||||
public static ButtonListHandler<Suggestion, ButtonCell> dataHandler;
|
public static ButtonListHandler<Suggestion, ButtonCell> buttonListDataHandler;
|
||||||
public static ScrollPool<ButtonCell> scrollPool;
|
public static ScrollPool<ButtonCell> scrollPool;
|
||||||
private static GameObject navigationTipRow;
|
private static GameObject navigationTipRow;
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
|
|||||||
{
|
{
|
||||||
base.UIRoot.SetActive(true);
|
base.UIRoot.SetActive(true);
|
||||||
base.UIRoot.transform.SetAsLastSibling();
|
base.UIRoot.transform.SetAsLastSibling();
|
||||||
dataHandler.RefreshData();
|
buttonListDataHandler.RefreshData();
|
||||||
scrollPool.Refresh(true, true);
|
scrollPool.Refresh(true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,20 +294,40 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
|
|||||||
|
|
||||||
// UI Construction
|
// UI Construction
|
||||||
|
|
||||||
|
const float MIN_X = 0.42f;
|
||||||
|
const float MAX_Y = 0.6f;
|
||||||
|
|
||||||
protected internal override void DoSetDefaultPosAndAnchors()
|
protected internal override void DoSetDefaultPosAndAnchors()
|
||||||
{
|
{
|
||||||
Rect.pivot = new Vector2(0f, 1f);
|
Rect.pivot = new Vector2(0f, 1f);
|
||||||
Rect.anchorMin = new Vector2(0.42f, 0.4f);
|
Rect.anchorMin = new Vector2(MIN_X, 0.4f);
|
||||||
Rect.anchorMax = new Vector2(0.68f, 0.6f);
|
Rect.anchorMax = new Vector2(0.68f, MAX_Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnFinishResize(RectTransform panel)
|
||||||
|
{
|
||||||
|
float xDiff = panel.anchorMin.x - MIN_X;
|
||||||
|
float yDiff = panel.anchorMax.y - MAX_Y;
|
||||||
|
|
||||||
|
if (xDiff != 0 || yDiff != 0)
|
||||||
|
{
|
||||||
|
panel.anchorMin = new(MIN_X, panel.anchorMin.y - yDiff);
|
||||||
|
panel.anchorMax = new(panel.anchorMax.x - xDiff, MAX_Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnFinishResize(panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ConstructPanelContent()
|
public override void ConstructPanelContent()
|
||||||
{
|
{
|
||||||
dataHandler = new ButtonListHandler<Suggestion, ButtonCell>(scrollPool, GetEntries, SetCell, ShouldDisplay, OnCellClicked);
|
// hide the titlebar
|
||||||
|
this.TitleBar.gameObject.SetActive(false);
|
||||||
|
|
||||||
|
buttonListDataHandler = new ButtonListHandler<Suggestion, ButtonCell>(scrollPool, GetEntries, SetCell, ShouldDisplay, OnCellClicked);
|
||||||
|
|
||||||
scrollPool = UIFactory.CreateScrollPool<ButtonCell>(this.uiContent, "AutoCompleter", out GameObject scrollObj,
|
scrollPool = UIFactory.CreateScrollPool<ButtonCell>(this.uiContent, "AutoCompleter", out GameObject scrollObj,
|
||||||
out GameObject scrollContent);
|
out GameObject scrollContent);
|
||||||
scrollPool.Initialize(dataHandler);
|
scrollPool.Initialize(buttonListDataHandler);
|
||||||
UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999);
|
UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999);
|
||||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(scrollContent, true, false, true, false);
|
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(scrollContent, true, false, true, false);
|
||||||
|
|
@ -108,22 +108,27 @@ namespace UnityExplorer.UI.Panels
|
|||||||
|
|
||||||
public override void SetActive(bool active)
|
public override void SetActive(bool active)
|
||||||
{
|
{
|
||||||
if (this.Enabled == active)
|
if (this.Enabled != active)
|
||||||
return;
|
|
||||||
|
|
||||||
base.SetActive(active);
|
|
||||||
|
|
||||||
if (!ApplyingSaveData)
|
|
||||||
SaveInternalData();
|
|
||||||
|
|
||||||
if (NavButtonWanted)
|
|
||||||
{
|
{
|
||||||
var color = active ? UniversalUI.EnabledButtonColor : UniversalUI.DisabledButtonColor;
|
base.SetActive(active);
|
||||||
RuntimeHelper.SetColorBlock(NavButton.Component, color, color * 1.2f);
|
|
||||||
|
if (!ApplyingSaveData)
|
||||||
|
SaveInternalData();
|
||||||
|
|
||||||
|
if (NavButtonWanted)
|
||||||
|
{
|
||||||
|
var color = active ? UniversalUI.EnabledButtonColor : UniversalUI.DisabledButtonColor;
|
||||||
|
RuntimeHelper.SetColorBlock(NavButton.Component, color, color * 1.2f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!active)
|
if (!active)
|
||||||
this.Dragger.WasDragging = false;
|
this.Dragger.WasDragging = false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.UIRoot.transform.SetAsLastSibling();
|
||||||
|
InvokeOnPanelsReordered();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Destroy()
|
public override void Destroy()
|
||||||
|
@ -184,26 +184,21 @@ namespace UnityExplorer.UI
|
|||||||
SetPanelActive(panel, !uiPanel.Enabled);
|
SetPanelActive(panel, !uiPanel.Enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetPanelActive(Panels panel, bool active)
|
public static void SetPanelActive(Panels panelType, bool active)
|
||||||
{
|
{
|
||||||
var obj = GetPanel(panel);
|
GetPanel(panelType)
|
||||||
SetPanelActive(obj, active);
|
.SetActive(active);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetPanelActive(UIPanel panel, bool active)
|
public static void SetPanelActive(UIPanel panel, bool active)
|
||||||
{
|
{
|
||||||
panel.SetActive(active);
|
panel.SetActive(active);
|
||||||
if (active)
|
|
||||||
{
|
|
||||||
panel.UIRoot.transform.SetAsLastSibling();
|
|
||||||
UIPanel.InvokeOnPanelsReordered();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetPanelActive(Transform transform, bool value)
|
internal static void SetPanelActive(Transform transform, bool value)
|
||||||
{
|
{
|
||||||
if (UIPanel.transformToPanelDict.TryGetValue(transform.GetInstanceID(), out UIPanel panel))
|
if (UIPanel.transformToPanelDict.TryGetValue(transform.GetInstanceID(), out UIPanel panel))
|
||||||
SetPanelActive(panel, value);
|
panel.SetActive(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// navbar
|
// navbar
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using UniverseLib;
|
using UniverseLib;
|
||||||
using UniverseLib.UI;
|
using UniverseLib.UI;
|
||||||
using UniverseLib.UI.Models;
|
using UniverseLib.UI.Models;
|
||||||
@ -67,7 +68,17 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
|
|||||||
{
|
{
|
||||||
allowedTypes = new();
|
allowedTypes = new();
|
||||||
foreach (var entry in ReflectionUtility.AllTypes)
|
foreach (var entry in ReflectionUtility.AllTypes)
|
||||||
allowedTypes.Add(entry.Value);
|
{
|
||||||
|
// skip <PrivateImplementationDetails> and <AnonymousClass> classes
|
||||||
|
var type = entry.Value;
|
||||||
|
if (type.FullName.Contains("PrivateImplementationDetails")
|
||||||
|
|| type.FullName.Contains("DisplayClass")
|
||||||
|
|| type.FullName.Contains('<'))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
allowedTypes.Add(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ using UniverseLib.UI;
|
|||||||
using UniverseLib;
|
using UniverseLib;
|
||||||
using UnityExplorer.CacheObject;
|
using UnityExplorer.CacheObject;
|
||||||
using UniverseLib.UI.ObjectPool;
|
using UniverseLib.UI.ObjectPool;
|
||||||
|
using UniverseLib.Utility;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Widgets
|
namespace UnityExplorer.UI.Widgets
|
||||||
{
|
{
|
||||||
@ -76,6 +77,9 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
|
|
||||||
public object[] TryParseArguments()
|
public object[] TryParseArguments()
|
||||||
{
|
{
|
||||||
|
if (!parameters.Any())
|
||||||
|
return ArgumentUtility.EmptyArgs;
|
||||||
|
|
||||||
object[] outArgs = new object[parameters.Length];
|
object[] outArgs = new object[parameters.Length];
|
||||||
|
|
||||||
for (int i = 0; i < parameters.Length; i++)
|
for (int i = 0; i < parameters.Length; i++)
|
||||||
|
@ -17,8 +17,9 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
public int ChildCount { get; internal set; }
|
public int ChildCount { get; internal set; }
|
||||||
public string Name { get; internal set; }
|
public string Name { get; internal set; }
|
||||||
public bool Enabled { get; internal set; }
|
public bool Enabled { get; internal set; }
|
||||||
|
public int SiblingIndex { get; internal set; }
|
||||||
|
|
||||||
public bool Expanded => Tree.IsCellExpanded(InstanceID);
|
public bool Expanded => Tree.IsTransformExpanded(InstanceID);
|
||||||
|
|
||||||
public CachedTransform(TransformTree tree, Transform transform, int depth, CachedTransform parent = null)
|
public CachedTransform(TransformTree tree, Transform transform, int depth, CachedTransform parent = null)
|
||||||
{
|
{
|
||||||
@ -26,27 +27,32 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
Value = transform;
|
Value = transform;
|
||||||
Parent = parent;
|
Parent = parent;
|
||||||
InstanceID = transform.GetInstanceID();
|
InstanceID = transform.GetInstanceID();
|
||||||
|
SiblingIndex = transform.GetSiblingIndex();
|
||||||
Update(transform, depth);
|
Update(transform, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Update(Transform transform, int depth)
|
public bool Update(Transform transform, int depth)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool changed = false;
|
||||||
|
|
||||||
if (Value != transform
|
if (Value != transform
|
||||||
|| depth != Depth
|
|| depth != Depth
|
||||||
|| ChildCount != transform.childCount
|
|| ChildCount != transform.childCount
|
||||||
|| Name != transform.name
|
|| Name != transform.name
|
||||||
|| Enabled != transform.gameObject.activeSelf)
|
|| Enabled != transform.gameObject.activeSelf
|
||||||
|
|| SiblingIndex != transform.GetSiblingIndex())
|
||||||
{
|
{
|
||||||
|
changed = true;
|
||||||
|
|
||||||
Value = transform;
|
Value = transform;
|
||||||
Depth = depth;
|
Depth = depth;
|
||||||
ChildCount = transform.childCount;
|
ChildCount = transform.childCount;
|
||||||
Name = transform.name;
|
Name = transform.name;
|
||||||
Enabled = transform.gameObject.activeSelf;
|
Enabled = transform.gameObject.activeSelf;
|
||||||
ret = true;
|
SiblingIndex = transform.GetSiblingIndex();
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ using UniverseLib.UI;
|
|||||||
using UniverseLib.UI.Models;
|
using UniverseLib.UI.Models;
|
||||||
using UniverseLib.UI.Widgets;
|
using UniverseLib.UI.Widgets;
|
||||||
using UniverseLib.UI.Widgets.ScrollView;
|
using UniverseLib.UI.Widgets.ScrollView;
|
||||||
|
using UniverseLib.Utility;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Widgets
|
namespace UnityExplorer.UI.Widgets
|
||||||
{
|
{
|
||||||
@ -36,6 +37,7 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
public ButtonRef ExpandButton;
|
public ButtonRef ExpandButton;
|
||||||
public ButtonRef NameButton;
|
public ButtonRef NameButton;
|
||||||
public Toggle EnabledToggle;
|
public Toggle EnabledToggle;
|
||||||
|
public InputFieldRef SiblingIndex;
|
||||||
|
|
||||||
public LayoutElement spacer;
|
public LayoutElement spacer;
|
||||||
|
|
||||||
@ -77,6 +79,15 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
|
|
||||||
EnabledToggle.Set(cached.Value.gameObject.activeSelf, false);
|
EnabledToggle.Set(cached.Value.gameObject.activeSelf, false);
|
||||||
|
|
||||||
|
if (!cached.Value.parent)
|
||||||
|
SiblingIndex.GameObject.SetActive(false);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SiblingIndex.GameObject.SetActive(true);
|
||||||
|
if (!SiblingIndex.Component.isFocused)
|
||||||
|
SiblingIndex.Text = cached.Value.GetSiblingIndex().ToString();
|
||||||
|
}
|
||||||
|
|
||||||
int childCount = cached.Value.childCount;
|
int childCount = cached.Value.childCount;
|
||||||
if (childCount > 0)
|
if (childCount > 0)
|
||||||
{
|
{
|
||||||
@ -97,6 +108,8 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
{
|
{
|
||||||
NameButton.ButtonText.text = $"[Destroyed]";
|
NameButton.ButtonText.text = $"[Destroyed]";
|
||||||
NameButton.ButtonText.color = Color.red;
|
NameButton.ButtonText.color = Color.red;
|
||||||
|
|
||||||
|
SiblingIndex.GameObject.SetActive(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,6 +131,17 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
OnEnableToggled?.Invoke(cachedTransform);
|
OnEnableToggled?.Invoke(cachedTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnSiblingIndexEndEdit(string input)
|
||||||
|
{
|
||||||
|
if (this.cachedTransform == null || !this.cachedTransform.Value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (int.TryParse(input.Trim(), out int index))
|
||||||
|
this.cachedTransform.Value.SetSiblingIndex(index);
|
||||||
|
|
||||||
|
this.SiblingIndex.Text = this.cachedTransform.Value.GetSiblingIndex().ToString();
|
||||||
|
}
|
||||||
|
|
||||||
public GameObject CreateContent(GameObject parent)
|
public GameObject CreateContent(GameObject parent)
|
||||||
{
|
{
|
||||||
UIRoot = UIFactory.CreateUIObject("TransformCell", parent);
|
UIRoot = UIFactory.CreateUIObject("TransformCell", parent);
|
||||||
@ -152,10 +176,22 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
nameLabel.horizontalOverflow = HorizontalWrapMode.Overflow;
|
nameLabel.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||||
nameLabel.alignment = TextAnchor.MiddleLeft;
|
nameLabel.alignment = TextAnchor.MiddleLeft;
|
||||||
|
|
||||||
Color normal = new Color(0.11f, 0.11f, 0.11f);
|
// Sibling index input
|
||||||
Color highlight = new Color(0.25f, 0.25f, 0.25f);
|
|
||||||
Color pressed = new Color(0.05f, 0.05f, 0.05f);
|
SiblingIndex = UIFactory.CreateInputField(this.UIRoot, "SiblingIndexInput", string.Empty);
|
||||||
Color disabled = new Color(1, 1, 1, 0);
|
SiblingIndex.Component.textComponent.fontSize = 11;
|
||||||
|
SiblingIndex.Component.textComponent.alignment = TextAnchor.MiddleRight;
|
||||||
|
var siblingImage = SiblingIndex.GameObject.GetComponent<Image>();
|
||||||
|
siblingImage.color = new(0f, 0f, 0f, 0.25f);
|
||||||
|
UIFactory.SetLayoutElement(SiblingIndex.GameObject, 35, 20, 0, 0);
|
||||||
|
SiblingIndex.Component.GetOnEndEdit().AddListener(OnSiblingIndexEndEdit);
|
||||||
|
|
||||||
|
// Setup selectables
|
||||||
|
|
||||||
|
Color normal = new(0.11f, 0.11f, 0.11f);
|
||||||
|
Color highlight = new(0.25f, 0.25f, 0.25f);
|
||||||
|
Color pressed = new(0.05f, 0.05f, 0.05f);
|
||||||
|
Color disabled = new(1, 1, 1, 0);
|
||||||
RuntimeHelper.SetColorBlock(ExpandButton.Component, normal, highlight, pressed, disabled);
|
RuntimeHelper.SetColorBlock(ExpandButton.Component, normal, highlight, pressed, disabled);
|
||||||
RuntimeHelper.SetColorBlock(NameButton.Component, normal, highlight, pressed, disabled);
|
RuntimeHelper.SetColorBlock(NameButton.Component, normal, highlight, pressed, disabled);
|
||||||
|
|
||||||
|
@ -2,12 +2,9 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Linq;
|
using System.Diagnostics;
|
||||||
using System.Text;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
|
||||||
using UniverseLib;
|
using UniverseLib;
|
||||||
using UniverseLib.UI.Widgets;
|
|
||||||
using UniverseLib.UI.Widgets.ScrollView;
|
using UniverseLib.UI.Widgets.ScrollView;
|
||||||
using UniverseLib.Utility;
|
using UniverseLib.Utility;
|
||||||
|
|
||||||
@ -20,22 +17,36 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
|
|
||||||
public ScrollPool<TransformCell> ScrollPool;
|
public ScrollPool<TransformCell> ScrollPool;
|
||||||
|
|
||||||
|
// IMPORTANT CAVEAT WITH OrderedDictionary:
|
||||||
|
// While the performance is mostly good, there are two methods we should NEVER use:
|
||||||
|
// - Remove(object)
|
||||||
|
// - set_Item[object]
|
||||||
|
// These two methods have extremely bad performance due to using IndexOfKey(), which iterates the whole dictionary.
|
||||||
|
// Currently we do not use either of these methods, so everything should be constant time hash lookups.
|
||||||
|
// We DO make use of get_Item[object], get_Item[index], Add, Insert and RemoveAt, which OrderedDictionary perfectly meets our needs for.
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Key: UnityEngine.Transform instance ID<br/>
|
/// Key: UnityEngine.Transform instance ID<br/>
|
||||||
/// Value: CachedTransform
|
/// Value: CachedTransform
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal readonly OrderedDictionary cachedTransforms = new OrderedDictionary();
|
internal readonly OrderedDictionary cachedTransforms = new();
|
||||||
|
|
||||||
// for keeping track of which actual transforms are expanded or not, outside of the cache data.
|
// for keeping track of which actual transforms are expanded or not, outside of the cache data.
|
||||||
private readonly HashSet<int> expandedInstanceIDs = new HashSet<int>();
|
private readonly HashSet<int> expandedInstanceIDs = new();
|
||||||
private readonly HashSet<int> autoExpandedIDs = new HashSet<int>();
|
private readonly HashSet<int> autoExpandedIDs = new();
|
||||||
|
|
||||||
private readonly HashSet<int> visited = new HashSet<int>();
|
// state for Traverse parse
|
||||||
private bool needRefresh;
|
private readonly HashSet<int> visited = new();
|
||||||
|
private bool needRefreshUI;
|
||||||
private int displayIndex;
|
private int displayIndex;
|
||||||
|
int prevDisplayIndex;
|
||||||
|
|
||||||
public int ItemCount => cachedTransforms.Count;
|
private Coroutine refreshCoroutine;
|
||||||
|
private readonly Stopwatch traversedThisFrame = new();
|
||||||
|
|
||||||
|
// ScrollPool item count. PrevDisplayIndex is the highest index + 1 from our last traverse.
|
||||||
|
public int ItemCount => prevDisplayIndex;
|
||||||
|
|
||||||
|
// Search filter
|
||||||
public bool Filtering => !string.IsNullOrEmpty(currentFilter);
|
public bool Filtering => !string.IsNullOrEmpty(currentFilter);
|
||||||
private bool wasFiltering;
|
private bool wasFiltering;
|
||||||
|
|
||||||
@ -62,44 +73,24 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
GetRootEntriesMethod = getRootEntriesMethod;
|
GetRootEntriesMethod = getRootEntriesMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnCellBorrowed(TransformCell cell)
|
// Initialize and reset
|
||||||
{
|
|
||||||
cell.OnExpandToggled += OnCellExpandToggled;
|
|
||||||
cell.OnGameObjectClicked += OnGameObjectClicked;
|
|
||||||
cell.OnEnableToggled += OnCellEnableToggled;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnGameObjectClicked(GameObject obj)
|
|
||||||
{
|
|
||||||
if (OnClickOverrideHandler != null)
|
|
||||||
OnClickOverrideHandler.Invoke(obj);
|
|
||||||
else
|
|
||||||
InspectorManager.Inspect(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnCellExpandToggled(CachedTransform cache)
|
|
||||||
{
|
|
||||||
var instanceID = cache.InstanceID;
|
|
||||||
if (expandedInstanceIDs.Contains(instanceID))
|
|
||||||
expandedInstanceIDs.Remove(instanceID);
|
|
||||||
else
|
|
||||||
expandedInstanceIDs.Add(instanceID);
|
|
||||||
|
|
||||||
RefreshData(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnCellEnableToggled(CachedTransform cache)
|
|
||||||
{
|
|
||||||
cache.Value.gameObject.SetActive(!cache.Value.gameObject.activeSelf);
|
|
||||||
|
|
||||||
RefreshData(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Must be called externally from owner of this TransformTree
|
||||||
public void Init()
|
public void Init()
|
||||||
{
|
{
|
||||||
ScrollPool.Initialize(this);
|
ScrollPool.Initialize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called to completely reset the tree, ie. switching inspected GameObject
|
||||||
|
public void Rebuild()
|
||||||
|
{
|
||||||
|
autoExpandedIDs.Clear();
|
||||||
|
expandedInstanceIDs.Clear();
|
||||||
|
|
||||||
|
RefreshData(true, true, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called to completely wipe our data (ie, GameObject inspector returning to pool)
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
this.cachedTransforms.Clear();
|
this.cachedTransforms.Clear();
|
||||||
@ -107,14 +98,21 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
autoExpandedIDs.Clear();
|
autoExpandedIDs.Clear();
|
||||||
expandedInstanceIDs.Clear();
|
expandedInstanceIDs.Clear();
|
||||||
this.ScrollPool.Refresh(true, true);
|
this.ScrollPool.Refresh(true, true);
|
||||||
|
if (refreshCoroutine != null)
|
||||||
|
{
|
||||||
|
RuntimeHelper.StopCoroutine(refreshCoroutine);
|
||||||
|
refreshCoroutine = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsCellExpanded(int instanceID)
|
// Checks if the given Instance ID is expanded or not
|
||||||
|
public bool IsTransformExpanded(int instanceID)
|
||||||
{
|
{
|
||||||
return Filtering ? autoExpandedIDs.Contains(instanceID)
|
return Filtering ? autoExpandedIDs.Contains(instanceID)
|
||||||
: expandedInstanceIDs.Contains(instanceID);
|
: expandedInstanceIDs.Contains(instanceID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Jumps to a specific Transform in the tree and highlights it.
|
||||||
public void JumpAndExpandToTransform(Transform transform)
|
public void JumpAndExpandToTransform(Transform transform)
|
||||||
{
|
{
|
||||||
// make sure all parents of the object are expanded
|
// make sure all parents of the object are expanded
|
||||||
@ -128,8 +126,9 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
parent = parent.parent;
|
parent = parent.parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh cached transforms (no UI rebuild yet)
|
// Refresh cached transforms (no UI rebuild yet).
|
||||||
RefreshData(false);
|
// Stop existing coroutine and do it oneshot.
|
||||||
|
RefreshData(false, false, true, true);
|
||||||
|
|
||||||
int transformID = transform.GetInstanceID();
|
int transformID = transform.GetInstanceID();
|
||||||
|
|
||||||
@ -162,62 +161,88 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
button.OnDeselect(null);
|
button.OnDeselect(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Rebuild()
|
// Perform a Traverse and optionally refresh the ScrollPool as well.
|
||||||
|
// If oneShot, then this happens instantly with no yield.
|
||||||
|
public void RefreshData(bool andRefreshUI, bool jumpToTop, bool stopExistingCoroutine, bool oneShot)
|
||||||
{
|
{
|
||||||
autoExpandedIDs.Clear();
|
if (refreshCoroutine != null)
|
||||||
expandedInstanceIDs.Clear();
|
{
|
||||||
|
if (stopExistingCoroutine)
|
||||||
|
{
|
||||||
|
RuntimeHelper.StopCoroutine(refreshCoroutine);
|
||||||
|
refreshCoroutine = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
RefreshData(true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RefreshData(bool andReload = false, bool jumpToTop = false)
|
|
||||||
{
|
|
||||||
visited.Clear();
|
visited.Clear();
|
||||||
displayIndex = 0;
|
displayIndex = 0;
|
||||||
needRefresh = false;
|
needRefreshUI = false;
|
||||||
|
traversedThisFrame.Reset();
|
||||||
|
traversedThisFrame.Start();
|
||||||
|
|
||||||
var rootObjects = GetRootEntriesMethod.Invoke();
|
IEnumerable<GameObject> rootObjects = GetRootEntriesMethod.Invoke();
|
||||||
|
|
||||||
//int displayIndex = 0;
|
refreshCoroutine = RuntimeHelper.StartCoroutine(RefreshCoroutine(rootObjects, andRefreshUI, jumpToTop, oneShot));
|
||||||
foreach (var obj in rootObjects)
|
}
|
||||||
if (obj) Traverse(obj.transform);
|
|
||||||
|
// Coroutine for batched updates, max 2000 gameobjects per frame so FPS doesn't get tanked when there is like 100k gameobjects.
|
||||||
|
// if "oneShot", then this will NOT be batched (if we need an immediate full update).
|
||||||
|
IEnumerator RefreshCoroutine(IEnumerable<GameObject> rootObjects, bool andRefreshUI, bool jumpToTop, bool oneShot)
|
||||||
|
{
|
||||||
|
foreach (var gameObj in rootObjects)
|
||||||
|
{
|
||||||
|
if (gameObj)
|
||||||
|
{
|
||||||
|
var enumerator = Traverse(gameObj.transform, null, 0, oneShot);
|
||||||
|
while (enumerator.MoveNext())
|
||||||
|
{
|
||||||
|
if (!oneShot)
|
||||||
|
yield return enumerator.Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Prune displayed transforms that we didnt visit in that traverse
|
// Prune displayed transforms that we didnt visit in that traverse
|
||||||
for (int i = cachedTransforms.Count - 1; i >= 0; i--)
|
for (int i = cachedTransforms.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
var obj = (CachedTransform)cachedTransforms[i];
|
var cached = (CachedTransform)cachedTransforms[i];
|
||||||
if (!visited.Contains(obj.InstanceID))
|
if (!visited.Contains(cached.InstanceID))
|
||||||
{
|
{
|
||||||
cachedTransforms.Remove(obj.InstanceID);
|
cachedTransforms.RemoveAt(i);
|
||||||
needRefresh = true;
|
needRefreshUI = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!needRefresh)
|
if (andRefreshUI && needRefreshUI)
|
||||||
return;
|
ScrollPool.Refresh(true, jumpToTop);
|
||||||
|
|
||||||
//displayedObjects.Clear();
|
prevDisplayIndex = displayIndex;
|
||||||
|
refreshCoroutine = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (andReload)
|
// Recursive method to check a Transform and its children (if expanded).
|
||||||
{
|
// Parent and depth can be null/default.
|
||||||
if (!jumpToTop)
|
private IEnumerator Traverse(Transform transform, CachedTransform parent, int depth, bool oneShot)
|
||||||
ScrollPool.Refresh(true);
|
|
||||||
else
|
|
||||||
ScrollPool.Refresh(true, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Traverse(Transform transform, CachedTransform parent = null, int depth = 0)
|
|
||||||
{
|
{
|
||||||
|
// Let's only tank 2ms of each frame (60->53fps)
|
||||||
|
if (traversedThisFrame.ElapsedMilliseconds > 2)
|
||||||
|
{
|
||||||
|
yield return null;
|
||||||
|
traversedThisFrame.Reset();
|
||||||
|
traversedThisFrame.Start();
|
||||||
|
}
|
||||||
|
|
||||||
int instanceID = transform.GetInstanceID();
|
int instanceID = transform.GetInstanceID();
|
||||||
|
|
||||||
if (visited.Contains(instanceID))
|
if (visited.Contains(instanceID))
|
||||||
return;
|
yield break;
|
||||||
|
|
||||||
if (Filtering)
|
if (Filtering)
|
||||||
{
|
{
|
||||||
if (!FilterHierarchy(transform))
|
if (!FilterHierarchy(transform))
|
||||||
return;
|
yield break;
|
||||||
|
|
||||||
visited.Add(instanceID);
|
visited.Add(instanceID);
|
||||||
|
|
||||||
@ -231,12 +256,25 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
if (cachedTransforms.Contains(instanceID))
|
if (cachedTransforms.Contains(instanceID))
|
||||||
{
|
{
|
||||||
cached = (CachedTransform)cachedTransforms[(object)instanceID];
|
cached = (CachedTransform)cachedTransforms[(object)instanceID];
|
||||||
|
int prevSiblingIdx = cached.SiblingIndex;
|
||||||
if (cached.Update(transform, depth))
|
if (cached.Update(transform, depth))
|
||||||
needRefresh = true;
|
{
|
||||||
|
needRefreshUI = true;
|
||||||
|
|
||||||
|
// If the sibling index changed, we need to shuffle it in our cached transforms list.
|
||||||
|
if (prevSiblingIdx != cached.SiblingIndex)
|
||||||
|
{
|
||||||
|
cachedTransforms.Remove(instanceID);
|
||||||
|
if (cachedTransforms.Count <= displayIndex)
|
||||||
|
cachedTransforms.Add(instanceID, cached);
|
||||||
|
else
|
||||||
|
cachedTransforms.Insert(displayIndex, instanceID, cached);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
needRefresh = true;
|
needRefreshUI = true;
|
||||||
cached = new CachedTransform(this, transform, depth, parent);
|
cached = new CachedTransform(this, transform, depth, parent);
|
||||||
if (cachedTransforms.Count <= displayIndex)
|
if (cachedTransforms.Count <= displayIndex)
|
||||||
cachedTransforms.Add(instanceID, cached);
|
cachedTransforms.Add(instanceID, cached);
|
||||||
@ -246,10 +284,17 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
|
|
||||||
displayIndex++;
|
displayIndex++;
|
||||||
|
|
||||||
if (IsCellExpanded(instanceID) && cached.Value.childCount > 0)
|
if (IsTransformExpanded(instanceID) && cached.Value.childCount > 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < transform.childCount; i++)
|
for (int i = 0; i < transform.childCount; i++)
|
||||||
Traverse(transform.GetChild(i), cached, depth + 1);
|
{
|
||||||
|
var enumerator = Traverse(transform.GetChild(i), cached, depth + 1, oneShot);
|
||||||
|
while (enumerator.MoveNext())
|
||||||
|
{
|
||||||
|
if (!oneShot)
|
||||||
|
yield return enumerator.Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,13 +321,44 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
if (Filtering)
|
if (Filtering)
|
||||||
{
|
{
|
||||||
if (cell.cachedTransform.Name.ContainsIgnoreCase(currentFilter))
|
if (cell.cachedTransform.Name.ContainsIgnoreCase(currentFilter))
|
||||||
{
|
|
||||||
cell.NameButton.ButtonText.color = Color.green;
|
cell.NameButton.ButtonText.color = Color.green;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cell.Disable();
|
cell.Disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnCellBorrowed(TransformCell cell)
|
||||||
|
{
|
||||||
|
cell.OnExpandToggled += OnCellExpandToggled;
|
||||||
|
cell.OnGameObjectClicked += OnGameObjectClicked;
|
||||||
|
cell.OnEnableToggled += OnCellEnableToggled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGameObjectClicked(GameObject obj)
|
||||||
|
{
|
||||||
|
if (OnClickOverrideHandler != null)
|
||||||
|
OnClickOverrideHandler.Invoke(obj);
|
||||||
|
else
|
||||||
|
InspectorManager.Inspect(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnCellExpandToggled(CachedTransform cache)
|
||||||
|
{
|
||||||
|
var instanceID = cache.InstanceID;
|
||||||
|
if (expandedInstanceIDs.Contains(instanceID))
|
||||||
|
expandedInstanceIDs.Remove(instanceID);
|
||||||
|
else
|
||||||
|
expandedInstanceIDs.Add(instanceID);
|
||||||
|
|
||||||
|
RefreshData(true, false, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnCellEnableToggled(CachedTransform cache)
|
||||||
|
{
|
||||||
|
cache.Value.gameObject.SetActive(!cache.Value.gameObject.activeSelf);
|
||||||
|
|
||||||
|
RefreshData(true, false, true, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,13 +175,13 @@
|
|||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="UniverseLib.Mono">
|
<Reference Include="UniverseLib.Mono">
|
||||||
<HintPath>packages\UniverseLib.1.2.11\lib\net35\UniverseLib.Mono.dll</HintPath>
|
<HintPath>packages\UniverseLib.1.2.16\lib\net35\UniverseLib.Mono.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- Il2Cpp refs -->
|
<!-- Il2Cpp refs -->
|
||||||
<ItemGroup Condition="'$(IsCpp)'=='true'">
|
<ItemGroup Condition="'$(IsCpp)'=='true'">
|
||||||
<Reference Include="UniverseLib.IL2CPP">
|
<Reference Include="UniverseLib.IL2CPP">
|
||||||
<HintPath>packages\UniverseLib.1.2.11\lib\net472\UniverseLib.IL2CPP.dll</HintPath>
|
<HintPath>packages\UniverseLib.1.2.16\lib\net472\UniverseLib.IL2CPP.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="UnhollowerBaseLib, Version=0.4.22.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="UnhollowerBaseLib, Version=0.4.22.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>packages\Il2CppAssemblyUnhollower.BaseLib.0.4.22\lib\net472\UnhollowerBaseLib.dll</HintPath>
|
<HintPath>packages\Il2CppAssemblyUnhollower.BaseLib.0.4.22\lib\net472\UnhollowerBaseLib.dll</HintPath>
|
||||||
@ -225,6 +225,7 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="CacheObject\CacheConstructor.cs" />
|
||||||
<Compile Include="Hooks\HookCell.cs" />
|
<Compile Include="Hooks\HookCell.cs" />
|
||||||
<Compile Include="Hooks\HookInstance.cs" />
|
<Compile Include="Hooks\HookInstance.cs" />
|
||||||
<Compile Include="Hooks\HookManager.cs" />
|
<Compile Include="Hooks\HookManager.cs" />
|
||||||
@ -312,7 +313,7 @@
|
|||||||
<Compile Include="UI\Panels\ObjectExplorerPanel.cs" />
|
<Compile Include="UI\Panels\ObjectExplorerPanel.cs" />
|
||||||
<Compile Include="UI\UIManager.cs" />
|
<Compile Include="UI\UIManager.cs" />
|
||||||
<Compile Include="UI\Panels\PanelDragger.cs" />
|
<Compile Include="UI\Panels\PanelDragger.cs" />
|
||||||
<Compile Include="UI\Widgets\AutoComplete\AutoCompleteModal.cs" />
|
<Compile Include="UI\Panels\AutoCompleteModal.cs" />
|
||||||
<Compile Include="UI\Widgets\AutoComplete\TypeCompleter.cs" />
|
<Compile Include="UI\Widgets\AutoComplete\TypeCompleter.cs" />
|
||||||
<Compile Include="ObjectExplorer\ObjectSearch.cs" />
|
<Compile Include="ObjectExplorer\ObjectSearch.cs" />
|
||||||
<Compile Include="ObjectExplorer\SceneExplorer.cs" />
|
<Compile Include="ObjectExplorer\SceneExplorer.cs" />
|
||||||
|
@ -6,6 +6,6 @@
|
|||||||
<package id="ILRepack.Lib.MSBuild.Task" version="2.0.18.2" targetFramework="net35" />
|
<package id="ILRepack.Lib.MSBuild.Task" version="2.0.18.2" targetFramework="net35" />
|
||||||
<package id="Mono.Cecil" version="0.10.4" targetFramework="net35" />
|
<package id="Mono.Cecil" version="0.10.4" targetFramework="net35" />
|
||||||
<package id="Samboy063.Tomlet" version="3.1.3" targetFramework="net472" />
|
<package id="Samboy063.Tomlet" version="3.1.3" targetFramework="net472" />
|
||||||
<package id="UniverseLib" version="1.2.11" targetFramework="net35" />
|
<package id="UniverseLib" version="1.2.16" targetFramework="net35" />
|
||||||
<package id="UniverseLib.Analyzers" version="1.0.3" targetFramework="net35" developmentDependency="true" />
|
<package id="UniverseLib.Analyzers" version="1.0.3" targetFramework="net35" developmentDependency="true" />
|
||||||
</packages>
|
</packages>
|
Reference in New Issue
Block a user