mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-03 03:52:28 +08:00
Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
d6a07f05ea | |||
27d5398dea | |||
7a5570a070 | |||
d40537775f | |||
9b6f3fd3ea | |||
bacac929e9 |
@ -72,13 +72,11 @@ namespace UnityExplorer.CacheObject
|
|||||||
else
|
else
|
||||||
ret = Activator.CreateInstance(returnType, ArgumentUtility.EmptyArgs);
|
ret = Activator.CreateInstance(returnType, ArgumentUtility.EmptyArgs);
|
||||||
|
|
||||||
HadException = false;
|
|
||||||
LastException = null;
|
LastException = null;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
HadException = true;
|
|
||||||
LastException = ex;
|
LastException = ex;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -32,13 +32,11 @@ namespace UnityExplorer.CacheObject
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var ret = FieldInfo.GetValue(DeclaringInstance);
|
var ret = FieldInfo.GetValue(DeclaringInstance);
|
||||||
HadException = false;
|
|
||||||
LastException = null;
|
LastException = null;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
HadException = true;
|
|
||||||
LastException = ex;
|
LastException = ex;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -45,13 +45,11 @@ namespace UnityExplorer.CacheObject
|
|||||||
ret = methodInfo.Invoke(DeclaringInstance, Evaluator.TryParseArguments());
|
ret = methodInfo.Invoke(DeclaringInstance, Evaluator.TryParseArguments());
|
||||||
else
|
else
|
||||||
ret = methodInfo.Invoke(DeclaringInstance, ArgumentUtility.EmptyArgs);
|
ret = methodInfo.Invoke(DeclaringInstance, ArgumentUtility.EmptyArgs);
|
||||||
HadException = false;
|
|
||||||
LastException = null;
|
LastException = null;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
HadException = true;
|
|
||||||
LastException = ex;
|
LastException = ex;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,6 @@ namespace UnityExplorer.CacheObject
|
|||||||
public abstract bool ShouldAutoEvaluate { get; }
|
public abstract bool ShouldAutoEvaluate { get; }
|
||||||
public abstract bool HasArguments { get; }
|
public abstract bool HasArguments { get; }
|
||||||
public abstract bool CanWrite { get; }
|
public abstract bool CanWrite { get; }
|
||||||
public bool HadException { get; protected set; }
|
|
||||||
public Exception LastException { get; protected set; }
|
public Exception LastException { get; protected set; }
|
||||||
|
|
||||||
public virtual void SetFallbackType(Type fallbackType)
|
public virtual void SetFallbackType(Type fallbackType)
|
||||||
@ -106,8 +105,8 @@ namespace UnityExplorer.CacheObject
|
|||||||
if (CellView != null)
|
if (CellView != null)
|
||||||
SetDataToCell(CellView);
|
SetDataToCell(CellView);
|
||||||
|
|
||||||
// If the owner's parent CacheObject is set, we are setting the value of an inspected struct.
|
// If the owner's ParentCacheObject is set, we are setting the value of an inspected struct.
|
||||||
// Set the inspector target as the value back to that parent cacheobject.
|
// Set the inspector target as the value back to that parent.
|
||||||
if (Owner.ParentCacheObject != null)
|
if (Owner.ParentCacheObject != null)
|
||||||
Owner.ParentCacheObject.SetUserValue(Owner.Target);
|
Owner.ParentCacheObject.SetUserValue(Owner.Target);
|
||||||
}
|
}
|
||||||
@ -137,7 +136,7 @@ namespace UnityExplorer.CacheObject
|
|||||||
{
|
{
|
||||||
var prevState = State;
|
var prevState = State;
|
||||||
|
|
||||||
if (HadException)
|
if (LastException != null)
|
||||||
{
|
{
|
||||||
LastValueWasNull = true;
|
LastValueWasNull = true;
|
||||||
LastValueType = FallbackType;
|
LastValueType = FallbackType;
|
||||||
@ -158,7 +157,7 @@ namespace UnityExplorer.CacheObject
|
|||||||
{
|
{
|
||||||
// If we changed states (always needs IValue change)
|
// If we changed states (always needs IValue change)
|
||||||
// or if the value is null, and the fallback type isnt string (we always want to edit strings).
|
// or if the value is null, and the fallback type isnt string (we always want to edit strings).
|
||||||
if (State != prevState || (State != ValueState.String && Value.IsNullOrDestroyed()))
|
if (State != prevState || (State != ValueState.String && State != ValueState.Exception && Value.IsNullOrDestroyed()))
|
||||||
{
|
{
|
||||||
// need to return IValue
|
// need to return IValue
|
||||||
ReleaseIValue();
|
ReleaseIValue();
|
||||||
@ -206,7 +205,7 @@ namespace UnityExplorer.CacheObject
|
|||||||
return $"<i>{NOT_YET_EVAL} ({SignatureHighlighter.Parse(FallbackType, true)})</i>";
|
return $"<i>{NOT_YET_EVAL} ({SignatureHighlighter.Parse(FallbackType, true)})</i>";
|
||||||
|
|
||||||
case ValueState.Exception:
|
case ValueState.Exception:
|
||||||
return $"<i><color=red>{LastException.ReflectionExToString()}</color></i>";
|
return $"<i><color=#eb4034>{LastException.ReflectionExToString()}</color></i>";
|
||||||
|
|
||||||
// bool and number dont want the label for the value at all
|
// bool and number dont want the label for the value at all
|
||||||
case ValueState.Boolean:
|
case ValueState.Boolean:
|
||||||
@ -291,36 +290,36 @@ namespace UnityExplorer.CacheObject
|
|||||||
switch (State)
|
switch (State)
|
||||||
{
|
{
|
||||||
case ValueState.Exception:
|
case ValueState.Exception:
|
||||||
SetValueState(cell, ValueStateArgs.Default);
|
SetValueState(cell, new(true, subContentButtonActive: true));
|
||||||
break;
|
break;
|
||||||
case ValueState.Boolean:
|
case ValueState.Boolean:
|
||||||
SetValueState(cell, new ValueStateArgs(false, toggleActive: true, applyActive: CanWrite));
|
SetValueState(cell, new(false, toggleActive: true, applyActive: CanWrite));
|
||||||
break;
|
break;
|
||||||
case ValueState.Number:
|
case ValueState.Number:
|
||||||
SetValueState(cell, new ValueStateArgs(false, typeLabelActive: true, inputActive: true, applyActive: CanWrite));
|
SetValueState(cell, new(false, typeLabelActive: true, inputActive: true, applyActive: CanWrite));
|
||||||
break;
|
break;
|
||||||
case ValueState.String:
|
case ValueState.String:
|
||||||
if (LastValueWasNull)
|
if (LastValueWasNull)
|
||||||
SetValueState(cell, new ValueStateArgs(true, subContentButtonActive: true));
|
SetValueState(cell, new(true, subContentButtonActive: true));
|
||||||
else
|
else
|
||||||
SetValueState(cell, new ValueStateArgs(true, false, SignatureHighlighter.StringOrange, subContentButtonActive: true));
|
SetValueState(cell, new(true, false, SignatureHighlighter.StringOrange, subContentButtonActive: true));
|
||||||
break;
|
break;
|
||||||
case ValueState.Enum:
|
case ValueState.Enum:
|
||||||
SetValueState(cell, new ValueStateArgs(true, subContentButtonActive: CanWrite));
|
SetValueState(cell, new(true, subContentButtonActive: CanWrite));
|
||||||
break;
|
break;
|
||||||
case ValueState.Color:
|
case ValueState.Color:
|
||||||
case ValueState.ValueStruct:
|
case ValueState.ValueStruct:
|
||||||
if (ParseUtility.CanParse(LastValueType))
|
if (ParseUtility.CanParse(LastValueType))
|
||||||
SetValueState(cell, new ValueStateArgs(false, false, null, true, false, true, CanWrite, true, true));
|
SetValueState(cell, new(false, false, null, true, false, true, CanWrite, true, true));
|
||||||
else
|
else
|
||||||
SetValueState(cell, new ValueStateArgs(true, inspectActive: true, subContentButtonActive: true));
|
SetValueState(cell, new(true, inspectActive: true, subContentButtonActive: true));
|
||||||
break;
|
break;
|
||||||
case ValueState.Collection:
|
case ValueState.Collection:
|
||||||
case ValueState.Dictionary:
|
case ValueState.Dictionary:
|
||||||
SetValueState(cell, new ValueStateArgs(true, inspectActive: !LastValueWasNull, subContentButtonActive: !LastValueWasNull));
|
SetValueState(cell, new(true, inspectActive: !LastValueWasNull, subContentButtonActive: !LastValueWasNull));
|
||||||
break;
|
break;
|
||||||
case ValueState.Unsupported:
|
case ValueState.Unsupported:
|
||||||
SetValueState(cell, new ValueStateArgs(true, inspectActive: !LastValueWasNull));
|
SetValueState(cell, new (true, inspectActive: !LastValueWasNull));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,8 +367,10 @@ namespace UnityExplorer.CacheObject
|
|||||||
if (cell.InspectButton != null)
|
if (cell.InspectButton != null)
|
||||||
cell.InspectButton.Component.gameObject.SetActive(args.inspectActive && !LastValueWasNull);
|
cell.InspectButton.Component.gameObject.SetActive(args.inspectActive && !LastValueWasNull);
|
||||||
|
|
||||||
// allow IValue for null strings though
|
// set subcontent button if needed, and for null strings and exceptions
|
||||||
cell.SubContentButton.Component.gameObject.SetActive(args.subContentButtonActive && (!LastValueWasNull || State == ValueState.String));
|
cell.SubContentButton.Component.gameObject.SetActive(
|
||||||
|
args.subContentButtonActive
|
||||||
|
&& (!LastValueWasNull || State == ValueState.String || State == ValueState.Exception));
|
||||||
}
|
}
|
||||||
|
|
||||||
// CacheObjectCell Apply
|
// CacheObjectCell Apply
|
||||||
@ -401,7 +402,7 @@ namespace UnityExplorer.CacheObject
|
|||||||
{
|
{
|
||||||
if (this.IValue == null)
|
if (this.IValue == null)
|
||||||
{
|
{
|
||||||
var ivalueType = InteractiveValue.GetIValueTypeForState(State);
|
Type ivalueType = InteractiveValue.GetIValueTypeForState(State);
|
||||||
|
|
||||||
if (ivalueType == null)
|
if (ivalueType == null)
|
||||||
return;
|
return;
|
||||||
@ -455,6 +456,7 @@ namespace UnityExplorer.CacheObject
|
|||||||
{
|
{
|
||||||
inactiveIValueHolder = new GameObject("Temp_IValue_Holder");
|
inactiveIValueHolder = new GameObject("Temp_IValue_Holder");
|
||||||
GameObject.DontDestroyOnLoad(inactiveIValueHolder);
|
GameObject.DontDestroyOnLoad(inactiveIValueHolder);
|
||||||
|
inactiveIValueHolder.hideFlags = HideFlags.HideAndDontSave;
|
||||||
inactiveIValueHolder.transform.parent = UniversalUI.PoolHolder.transform;
|
inactiveIValueHolder.transform.parent = UniversalUI.PoolHolder.transform;
|
||||||
inactiveIValueHolder.SetActive(false);
|
inactiveIValueHolder.SetActive(false);
|
||||||
}
|
}
|
||||||
@ -467,9 +469,20 @@ namespace UnityExplorer.CacheObject
|
|||||||
|
|
||||||
public struct ValueStateArgs
|
public struct ValueStateArgs
|
||||||
{
|
{
|
||||||
public ValueStateArgs(bool valueActive = true, bool valueRichText = true, Color? valueColor = null,
|
public static ValueStateArgs Default { get; } = new(true);
|
||||||
bool typeLabelActive = false, bool toggleActive = false, bool inputActive = false, bool applyActive = false,
|
|
||||||
bool inspectActive = false, bool subContentButtonActive = false)
|
public Color valueColor;
|
||||||
|
public bool valueActive, valueRichText, typeLabelActive, toggleActive, inputActive, applyActive, inspectActive, subContentButtonActive;
|
||||||
|
|
||||||
|
public ValueStateArgs(bool valueActive = true,
|
||||||
|
bool valueRichText = true,
|
||||||
|
Color? valueColor = null,
|
||||||
|
bool typeLabelActive = false,
|
||||||
|
bool toggleActive = false,
|
||||||
|
bool inputActive = false,
|
||||||
|
bool applyActive = false,
|
||||||
|
bool inspectActive = false,
|
||||||
|
bool subContentButtonActive = false)
|
||||||
{
|
{
|
||||||
this.valueActive = valueActive;
|
this.valueActive = valueActive;
|
||||||
this.valueRichText = valueRichText;
|
this.valueRichText = valueRichText;
|
||||||
@ -481,14 +494,6 @@ namespace UnityExplorer.CacheObject
|
|||||||
this.inspectActive = inspectActive;
|
this.inspectActive = inspectActive;
|
||||||
this.subContentButtonActive = subContentButtonActive;
|
this.subContentButtonActive = subContentButtonActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ValueStateArgs Default => _default;
|
|
||||||
private static ValueStateArgs _default = new ValueStateArgs(true);
|
|
||||||
|
|
||||||
public bool valueActive, valueRichText, typeLabelActive, toggleActive,
|
|
||||||
inputActive, applyActive, inspectActive, subContentButtonActive;
|
|
||||||
|
|
||||||
public Color valueColor;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,13 +40,11 @@ namespace UnityExplorer.CacheObject
|
|||||||
ret = PropertyInfo.GetValue(DeclaringInstance, this.Evaluator.TryParseArguments());
|
ret = PropertyInfo.GetValue(DeclaringInstance, this.Evaluator.TryParseArguments());
|
||||||
else
|
else
|
||||||
ret = PropertyInfo.GetValue(DeclaringInstance, null);
|
ret = PropertyInfo.GetValue(DeclaringInstance, null);
|
||||||
HadException = false;
|
|
||||||
LastException = null;
|
LastException = null;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
HadException = true;
|
|
||||||
LastException = ex;
|
LastException = ex;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,9 @@ namespace UnityExplorer.CacheObject.IValues
|
|||||||
{
|
{
|
||||||
base.OnBorrowed(owner);
|
base.OnBorrowed(owner);
|
||||||
|
|
||||||
inputField.Component.readOnly = !owner.CanWrite;
|
bool canWrite = owner.CanWrite && owner.State != ValueState.Exception;
|
||||||
ApplyButton.Component.gameObject.SetActive(owner.CanWrite);
|
inputField.Component.readOnly = !canWrite;
|
||||||
|
ApplyButton.Component.gameObject.SetActive(canWrite);
|
||||||
|
|
||||||
SaveFilePath.Text = Path.Combine(ConfigManager.Default_Output_Path.Value, "untitled.txt");
|
SaveFilePath.Text = Path.Combine(ConfigManager.Default_Output_Path.Value, "untitled.txt");
|
||||||
}
|
}
|
||||||
@ -47,6 +48,9 @@ namespace UnityExplorer.CacheObject.IValues
|
|||||||
|
|
||||||
public override void SetValue(object value)
|
public override void SetValue(object value)
|
||||||
{
|
{
|
||||||
|
if (CurrentOwner.State == ValueState.Exception)
|
||||||
|
value = CurrentOwner.LastException.ToString();
|
||||||
|
|
||||||
RealValue = value as string;
|
RealValue = value as string;
|
||||||
SaveFileRow.SetActive(IsStringTooLong(RealValue));
|
SaveFileRow.SetActive(IsStringTooLong(RealValue));
|
||||||
|
|
||||||
|
@ -16,22 +16,16 @@ namespace UnityExplorer.CacheObject.IValues
|
|||||||
{
|
{
|
||||||
public static Type GetIValueTypeForState(ValueState state)
|
public static Type GetIValueTypeForState(ValueState state)
|
||||||
{
|
{
|
||||||
switch (state)
|
return state switch
|
||||||
{
|
{
|
||||||
case ValueState.String:
|
ValueState.Exception or ValueState.String => typeof(InteractiveString),
|
||||||
return typeof(InteractiveString);
|
ValueState.Enum => typeof(InteractiveEnum),
|
||||||
case ValueState.Enum:
|
ValueState.Collection => typeof(InteractiveList),
|
||||||
return typeof(InteractiveEnum);
|
ValueState.Dictionary => typeof(InteractiveDictionary),
|
||||||
case ValueState.Collection:
|
ValueState.ValueStruct => typeof(InteractiveValueStruct),
|
||||||
return typeof(InteractiveList);
|
ValueState.Color => typeof(InteractiveColor),
|
||||||
case ValueState.Dictionary:
|
_ => null,
|
||||||
return typeof(InteractiveDictionary);
|
};
|
||||||
case ValueState.ValueStruct:
|
|
||||||
return typeof(InteractiveValueStruct);
|
|
||||||
case ValueState.Color:
|
|
||||||
return typeof(InteractiveColor);
|
|
||||||
default: return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameObject UIRoot { get; set; }
|
public GameObject UIRoot { get; set; }
|
||||||
@ -39,28 +33,28 @@ namespace UnityExplorer.CacheObject.IValues
|
|||||||
|
|
||||||
public virtual bool CanWrite => this.CurrentOwner.CanWrite;
|
public virtual bool CanWrite => this.CurrentOwner.CanWrite;
|
||||||
|
|
||||||
public CacheObjectBase CurrentOwner => m_owner;
|
public CacheObjectBase CurrentOwner => owner;
|
||||||
private CacheObjectBase m_owner;
|
private CacheObjectBase owner;
|
||||||
|
|
||||||
public bool PendingValueWanted;
|
public bool PendingValueWanted;
|
||||||
|
|
||||||
public virtual void OnBorrowed(CacheObjectBase owner)
|
public virtual void OnBorrowed(CacheObjectBase owner)
|
||||||
{
|
{
|
||||||
if (this.m_owner != null)
|
if (this.owner != null)
|
||||||
{
|
{
|
||||||
ExplorerCore.LogWarning("Setting an IValue's owner but there is already one set. Maybe it wasn't cleaned up?");
|
ExplorerCore.LogWarning("Setting an IValue's owner but there is already one set. Maybe it wasn't cleaned up?");
|
||||||
ReleaseFromOwner();
|
ReleaseFromOwner();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.m_owner = owner;
|
this.owner = owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ReleaseFromOwner()
|
public virtual void ReleaseFromOwner()
|
||||||
{
|
{
|
||||||
if (this.m_owner == null)
|
if (this.owner == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.m_owner = null;
|
this.owner = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void SetValue(object value);
|
public abstract void SetValue(object value);
|
||||||
|
@ -9,29 +9,26 @@ using UnhollowerRuntimeLib;
|
|||||||
|
|
||||||
namespace UnityExplorer
|
namespace UnityExplorer
|
||||||
{
|
{
|
||||||
// Handles all Behaviour update calls for UnityExplorer (Update, FixedUpdate, OnPostRender).
|
|
||||||
// Basically just a wrapper which calls the corresponding methods in ExplorerCore.
|
|
||||||
|
|
||||||
public class ExplorerBehaviour : MonoBehaviour
|
public class ExplorerBehaviour : MonoBehaviour
|
||||||
{
|
{
|
||||||
internal static ExplorerBehaviour Instance { get; private set; }
|
internal static ExplorerBehaviour Instance { get; private set; }
|
||||||
|
|
||||||
|
#if CPP
|
||||||
|
public ExplorerBehaviour(IntPtr ptr) : base(ptr) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
internal static void Setup()
|
internal static void Setup()
|
||||||
{
|
{
|
||||||
#if CPP
|
#if CPP
|
||||||
ClassInjector.RegisterTypeInIl2Cpp<ExplorerBehaviour>();
|
ClassInjector.RegisterTypeInIl2Cpp<ExplorerBehaviour>();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var obj = new GameObject("ExplorerBehaviour");
|
GameObject obj = new("ExplorerBehaviour");
|
||||||
GameObject.DontDestroyOnLoad(obj);
|
DontDestroyOnLoad(obj);
|
||||||
obj.hideFlags |= HideFlags.HideAndDontSave;
|
obj.hideFlags = HideFlags.HideAndDontSave;
|
||||||
Instance = obj.AddComponent<ExplorerBehaviour>();
|
Instance = obj.AddComponent<ExplorerBehaviour>();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CPP
|
|
||||||
public ExplorerBehaviour(IntPtr ptr) : base(ptr) { }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
internal void Update()
|
internal void Update()
|
||||||
{
|
{
|
||||||
ExplorerCore.Update();
|
ExplorerCore.Update();
|
||||||
|
@ -15,7 +15,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.6.2";
|
public const string VERSION = "4.6.4";
|
||||||
public const string AUTHOR = "Sinai";
|
public const string AUTHOR = "Sinai";
|
||||||
public const string GUID = "com.sinai.unityexplorer";
|
public const string GUID = "com.sinai.unityexplorer";
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@ namespace UnityExplorer.Tests
|
|||||||
|
|
||||||
public static object LiterallyAnything = null;
|
public static object LiterallyAnything = null;
|
||||||
|
|
||||||
|
public static string Exception => throw new Exception("This is a test.");
|
||||||
|
|
||||||
// Test enumerables
|
// Test enumerables
|
||||||
public static int[,,] MultiDimensionalArray = new int[45, 45, 45];
|
public static int[,,] MultiDimensionalArray = new int[45, 45, 45];
|
||||||
public static List<object> ListOfInts;
|
public static List<object> ListOfInts;
|
||||||
|
@ -10,7 +10,7 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
{
|
{
|
||||||
public TransformTree Tree { get; }
|
public TransformTree Tree { get; }
|
||||||
public Transform Value { get; private set; }
|
public Transform Value { get; private set; }
|
||||||
public int InstanceID { get; private set; }
|
public int InstanceID { get; }
|
||||||
public CachedTransform Parent { get; internal set; }
|
public CachedTransform Parent { get; internal set; }
|
||||||
|
|
||||||
public int Depth { get; internal set; }
|
public int Depth { get; internal set; }
|
||||||
@ -23,10 +23,11 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
|
|
||||||
public CachedTransform(TransformTree tree, Transform transform, int depth, CachedTransform parent = null)
|
public CachedTransform(TransformTree tree, Transform transform, int depth, CachedTransform parent = null)
|
||||||
{
|
{
|
||||||
|
InstanceID = transform.GetInstanceID();
|
||||||
|
|
||||||
Tree = tree;
|
Tree = tree;
|
||||||
Value = transform;
|
Value = transform;
|
||||||
Parent = parent;
|
Parent = parent;
|
||||||
InstanceID = transform.GetInstanceID();
|
|
||||||
SiblingIndex = transform.GetSiblingIndex();
|
SiblingIndex = transform.GetSiblingIndex();
|
||||||
Update(transform, depth);
|
Update(transform, depth);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
public Action<GameObject> OnGameObjectClicked;
|
public Action<GameObject> OnGameObjectClicked;
|
||||||
|
|
||||||
public CachedTransform cachedTransform;
|
public CachedTransform cachedTransform;
|
||||||
public int cellIndex;
|
|
||||||
|
|
||||||
public GameObject UIRoot { get; set; }
|
public GameObject UIRoot { get; set; }
|
||||||
public RectTransform Rect { get; set; }
|
public RectTransform Rect { get; set; }
|
||||||
@ -53,7 +52,7 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
UIRoot.SetActive(false);
|
UIRoot.SetActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConfigureCell(CachedTransform cached, int cellIndex)
|
public void ConfigureCell(CachedTransform cached)
|
||||||
{
|
{
|
||||||
if (cached == null)
|
if (cached == null)
|
||||||
{
|
{
|
||||||
@ -64,7 +63,6 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
if (!Enabled)
|
if (!Enabled)
|
||||||
Enable();
|
Enable();
|
||||||
|
|
||||||
this.cellIndex = cellIndex;
|
|
||||||
cachedTransform = cached;
|
cachedTransform = cached;
|
||||||
|
|
||||||
spacer.minWidth = cached.Depth * 15;
|
spacer.minWidth = cached.Depth * 15;
|
||||||
|
@ -22,8 +22,8 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
// - Remove(object)
|
// - Remove(object)
|
||||||
// - set_Item[object]
|
// - set_Item[object]
|
||||||
// These two methods have extremely bad performance due to using IndexOfKey(), which iterates the whole dictionary.
|
// 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.
|
// Currently we do not use either of these methods, so everything should be constant time lookups.
|
||||||
// We DO make use of get_Item[object], get_Item[index], Add, Insert and RemoveAt, which OrderedDictionary perfectly meets our needs for.
|
// We DO make use of get_Item[object], get_Item[index], Add, Insert, Contains and RemoveAt, which OrderedDictionary meets our needs for.
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Key: UnityEngine.Transform instance ID<br/>
|
/// Key: UnityEngine.Transform instance ID<br/>
|
||||||
/// Value: CachedTransform
|
/// Value: CachedTransform
|
||||||
@ -182,31 +182,38 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
traversedThisFrame.Reset();
|
traversedThisFrame.Reset();
|
||||||
traversedThisFrame.Start();
|
traversedThisFrame.Start();
|
||||||
|
|
||||||
IEnumerable<GameObject> rootObjects = GetRootEntriesMethod.Invoke();
|
refreshCoroutine = RuntimeHelper.StartCoroutine(RefreshCoroutine(andRefreshUI, jumpToTop, oneShot));
|
||||||
|
|
||||||
refreshCoroutine = RuntimeHelper.StartCoroutine(RefreshCoroutine(rootObjects, andRefreshUI, jumpToTop, oneShot));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Coroutine for batched updates, max 2000 gameobjects per frame so FPS doesn't get tanked when there is like 100k gameobjects.
|
IEnumerator RefreshCoroutine(bool andRefreshUI, bool jumpToTop, bool oneShot)
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
|
// Instead of doing string.IsNullOrEmpty(CurrentFilter) many times, let's just do it once per update.
|
||||||
|
bool filtering = Filtering;
|
||||||
|
|
||||||
|
IEnumerable<GameObject> rootObjects = GetRootEntriesMethod();
|
||||||
foreach (var gameObj in rootObjects)
|
foreach (var gameObj in rootObjects)
|
||||||
{
|
{
|
||||||
if (gameObj)
|
if (!gameObj)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
IEnumerator enumerator = Traverse(gameObj.transform, null, 0, oneShot, filtering);
|
||||||
|
while (enumerator.MoveNext())
|
||||||
{
|
{
|
||||||
var enumerator = Traverse(gameObj.transform, null, 0, oneShot);
|
if (!oneShot)
|
||||||
while (enumerator.MoveNext())
|
yield return enumerator.Current;
|
||||||
{
|
|
||||||
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--)
|
||||||
{
|
{
|
||||||
|
if (traversedThisFrame.ElapsedMilliseconds > 2)
|
||||||
|
{
|
||||||
|
yield return null;
|
||||||
|
traversedThisFrame.Reset();
|
||||||
|
traversedThisFrame.Start();
|
||||||
|
}
|
||||||
|
|
||||||
var cached = (CachedTransform)cachedTransforms[i];
|
var cached = (CachedTransform)cachedTransforms[i];
|
||||||
if (!visited.Contains(cached.InstanceID))
|
if (!visited.Contains(cached.InstanceID))
|
||||||
{
|
{
|
||||||
@ -224,9 +231,8 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
|
|
||||||
// Recursive method to check a Transform and its children (if expanded).
|
// Recursive method to check a Transform and its children (if expanded).
|
||||||
// Parent and depth can be null/default.
|
// Parent and depth can be null/default.
|
||||||
private IEnumerator Traverse(Transform transform, CachedTransform parent, int depth, bool oneShot)
|
private IEnumerator Traverse(Transform transform, CachedTransform parent, int depth, bool oneShot, bool filtering)
|
||||||
{
|
{
|
||||||
// Let's only tank 2ms of each frame (60->53fps)
|
|
||||||
if (traversedThisFrame.ElapsedMilliseconds > 2)
|
if (traversedThisFrame.ElapsedMilliseconds > 2)
|
||||||
{
|
{
|
||||||
yield return null;
|
yield return null;
|
||||||
@ -236,21 +242,20 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
|
|
||||||
int instanceID = transform.GetInstanceID();
|
int instanceID = transform.GetInstanceID();
|
||||||
|
|
||||||
|
// Unlikely, but since this method is async it could theoretically happen in extremely rare circumstances
|
||||||
if (visited.Contains(instanceID))
|
if (visited.Contains(instanceID))
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
if (Filtering)
|
if (filtering)
|
||||||
{
|
{
|
||||||
if (!FilterHierarchy(transform))
|
if (!FilterHierarchy(transform))
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
visited.Add(instanceID);
|
|
||||||
|
|
||||||
if (!autoExpandedIDs.Contains(instanceID))
|
if (!autoExpandedIDs.Contains(instanceID))
|
||||||
autoExpandedIDs.Add(instanceID);
|
autoExpandedIDs.Add(instanceID);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
visited.Add(instanceID);
|
visited.Add(instanceID);
|
||||||
|
|
||||||
CachedTransform cached;
|
CachedTransform cached;
|
||||||
if (cachedTransforms.Contains(instanceID))
|
if (cachedTransforms.Contains(instanceID))
|
||||||
@ -288,7 +293,7 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < transform.childCount; i++)
|
for (int i = 0; i < transform.childCount; i++)
|
||||||
{
|
{
|
||||||
var enumerator = Traverse(transform.GetChild(i), cached, depth + 1, oneShot);
|
var enumerator = Traverse(transform.GetChild(i), cached, depth + 1, oneShot, filtering);
|
||||||
while (enumerator.MoveNext())
|
while (enumerator.MoveNext())
|
||||||
{
|
{
|
||||||
if (!oneShot)
|
if (!oneShot)
|
||||||
@ -317,7 +322,7 @@ namespace UnityExplorer.UI.Widgets
|
|||||||
{
|
{
|
||||||
if (index < cachedTransforms.Count)
|
if (index < cachedTransforms.Count)
|
||||||
{
|
{
|
||||||
cell.ConfigureCell((CachedTransform)cachedTransforms[index], index);
|
cell.ConfigureCell((CachedTransform)cachedTransforms[index]);
|
||||||
if (Filtering)
|
if (Filtering)
|
||||||
{
|
{
|
||||||
if (cell.cachedTransform.Name.ContainsIgnoreCase(currentFilter))
|
if (cell.cachedTransform.Name.ContainsIgnoreCase(currentFilter))
|
||||||
|
@ -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.17\lib\net35\UniverseLib.Mono.dll</HintPath>
|
<HintPath>packages\UniverseLib.1.2.18\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.17\lib\net472\UniverseLib.IL2CPP.dll</HintPath>
|
<HintPath>packages\UniverseLib.1.2.18\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>
|
||||||
|
@ -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.17" targetFramework="net35" />
|
<package id="UniverseLib" version="1.2.18" 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