Show InputField for exceptions to view/copy full exception

This commit is contained in:
Sinai 2022-04-01 18:14:50 +11:00
parent 4e3d3a2e5c
commit bacac929e9
8 changed files with 58 additions and 61 deletions

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }
} }
} }

View File

@ -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;
} }

View File

@ -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));

View File

@ -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);

View File

@ -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;