Fix null-coalescing operators in the C# console crashing the game

This commit is contained in:
sinaioutlander 2020-10-28 07:14:00 +11:00
parent ff684d4d4b
commit b61ac481b9
16 changed files with 126 additions and 149 deletions

View File

@ -336,14 +336,15 @@
<Compile Include="Helpers\ReflectionHelpers.cs" />
<Compile Include="Helpers\UnityHelpers.cs" />
<Compile Include="UI\ForceUnlockCursor.cs" />
<Compile Include="Input\IAbstractInput.cs" />
<Compile Include="CacheObject\Tests\TestClass.cs" />
<Compile Include="Input\IHandleInput.cs" />
<Compile Include="Tests\Tests.cs" />
<Compile Include="Input\InputManager.cs" />
<Compile Include="Input\InputSystem.cs" />
<Compile Include="Input\LegacyInput.cs" />
<Compile Include="Input\NoInput.cs" />
<Compile Include="UI\Main\DebugConsole.cs" />
<Compile Include="UI\Main\InspectorManager.cs" />
<Compile Include="UI\Main\Inspectors\ReflectionInspector.cs" />
<Compile Include="UI\Main\MainMenu.cs" />
<Compile Include="UI\Main\ConsolePage.cs" />
<Compile Include="UI\Main\Console\AutoCompleter.cs" />

View File

@ -4,8 +4,6 @@ namespace ExplorerBeta.Input
{
public interface IHandleInput
{
void Init();
Vector2 MousePosition { get; }
bool GetKeyDown(KeyCode key);

View File

@ -29,8 +29,6 @@ namespace ExplorerBeta.Input
ExplorerCore.LogWarning("Could not find any Input module!");
m_inputModule = new NoInput();
}
m_inputModule.Init();
}
public static Vector3 MousePosition => m_inputModule.MousePosition;

View File

@ -7,6 +7,29 @@ namespace ExplorerBeta.Input
{
public class InputSystem : IHandleInput
{
public InputSystem()
{
ExplorerCore.Log("Initializing new InputSystem support...");
m_kbCurrentProp = TKeyboard.GetProperty("current");
m_kbIndexer = TKeyboard.GetProperty("Item", new Type[] { TKey });
var btnControl = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Controls.ButtonControl");
m_btnIsPressedProp = btnControl.GetProperty("isPressed");
m_btnWasPressedProp = btnControl.GetProperty("wasPressedThisFrame");
m_mouseCurrentProp = TMouse.GetProperty("current");
m_leftButtonProp = TMouse.GetProperty("leftButton");
m_rightButtonProp = TMouse.GetProperty("rightButton");
m_positionProp = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Pointer")
.GetProperty("position");
m_readVector2InputMethod = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.InputControl`1")
.MakeGenericType(typeof(Vector2))
.GetMethod("ReadValue");
}
public static Type TKeyboard => m_tKeyboard ?? (m_tKeyboard = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Keyboard"));
private static Type m_tKeyboard;
@ -80,28 +103,5 @@ namespace ExplorerBeta.Input
default: throw new NotImplementedException();
}
}
public void Init()
{
ExplorerCore.Log("Initializing new InputSystem support...");
m_kbCurrentProp = TKeyboard.GetProperty("current");
m_kbIndexer = TKeyboard.GetProperty("Item", new Type[] { TKey });
var btnControl = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Controls.ButtonControl");
m_btnIsPressedProp = btnControl.GetProperty("isPressed");
m_btnWasPressedProp = btnControl.GetProperty("wasPressedThisFrame");
m_mouseCurrentProp = TMouse.GetProperty("current");
m_leftButtonProp = TMouse.GetProperty("leftButton");
m_rightButtonProp = TMouse.GetProperty("rightButton");
m_positionProp = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Pointer")
.GetProperty("position");
m_readVector2InputMethod = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.InputControl`1")
.MakeGenericType(typeof(Vector2))
.GetMethod("ReadValue");
}
}
}

View File

@ -7,6 +7,17 @@ namespace ExplorerBeta.Input
{
public class LegacyInput : IHandleInput
{
public LegacyInput()
{
ExplorerCore.Log("Initializing Legacy Input support...");
m_mousePositionProp = TInput.GetProperty("mousePosition");
m_getKeyMethod = TInput.GetMethod("GetKey", new Type[] { typeof(KeyCode) });
m_getKeyDownMethod = TInput.GetMethod("GetKeyDown", new Type[] { typeof(KeyCode) });
m_getMouseButtonMethod = TInput.GetMethod("GetMouseButton", new Type[] { typeof(int) });
m_getMouseButtonDownMethod = TInput.GetMethod("GetMouseButtonDown", new Type[] { typeof(int) });
}
public static Type TInput => m_tInput ?? (m_tInput = ReflectionHelpers.GetTypeByName("UnityEngine.Input"));
private static Type m_tInput;
@ -25,16 +36,5 @@ namespace ExplorerBeta.Input
public bool GetMouseButton(int btn) => (bool)m_getMouseButtonMethod.Invoke(null, new object[] { btn });
public bool GetMouseButtonDown(int btn) => (bool)m_getMouseButtonDownMethod.Invoke(null, new object[] { btn });
public void Init()
{
ExplorerCore.Log("Initializing Legacy Input support...");
m_mousePositionProp = TInput.GetProperty("mousePosition");
m_getKeyMethod = TInput.GetMethod("GetKey", new Type[] { typeof(KeyCode) });
m_getKeyDownMethod = TInput.GetMethod("GetKeyDown", new Type[] { typeof(KeyCode) });
m_getMouseButtonMethod = TInput.GetMethod("GetMouseButton", new Type[] { typeof(int) });
m_getMouseButtonDownMethod = TInput.GetMethod("GetMouseButtonDown", new Type[] { typeof(int) });
}
}
}

View File

@ -13,7 +13,5 @@ namespace ExplorerBeta.Input
public bool GetMouseButton(int btn) => false;
public bool GetMouseButtonDown(int btn) => false;
public void Init() { }
}
}

View File

@ -159,7 +159,7 @@ namespace ExplorerBeta.UI.Main.Console
}
}
private static readonly char[] splitChars = new[] { '{', '}', ',', ';', '<', '>', '(', ')', '[', ']', '=', '|', '&' };
private static readonly char[] splitChars = new[] { '{', '}', ',', ';', '<', '>', '(', ')', '[', ']', '=', '|', '&', '?' };
public static void CheckAutocomplete()
{

View File

@ -28,7 +28,7 @@ namespace ExplorerBeta.UI.Main.Console
if in int into is join let lock long new null object on orderby out
ref remove return sbyte select short sizeof stackalloc string
switch throw true try typeof uint ulong ushort
value var where while yield"
var where while yield"
};
public static KeywordMatch invalidKeywordMatcher = new KeywordMatch()
@ -36,7 +36,7 @@ namespace ExplorerBeta.UI.Main.Console
highlightColor = new Color(0.95f, 0.10f, 0.10f, 1.0f),
keywords = @"abstract async base class delegate enum explicit extern fixed get
implicit interface internal namespace operator override params private protected public
using partial readonly sealed set static struct this unchecked unsafe virtual volatile void"
using partial readonly sealed set static struct this unchecked unsafe value virtual volatile void"
};
private static char[] delimiterSymbolCache = null;

View File

@ -27,66 +27,28 @@ namespace ExplorerBeta.UI.Main.Console
public static object CurrentTarget()
{
throw new NotImplementedException("TODO");
return InspectorManager.Instance?.m_activeInspector?.Target;
}
public static object[] AllTargets()
{
throw new NotImplementedException("TODO");
int count = InspectorManager.Instance?.m_currentInspectors.Count ?? 0;
object[] ret = new object[count];
for (int i = 0; i < count; i++)
{
ret[i] = InspectorManager.Instance?.m_currentInspectors[i].Target;
}
return ret;
}
public static void Inspect(object obj)
{
throw new NotImplementedException("TODO");
InspectorManager.Instance.Inspect(obj);
}
public static void Inspect(Type type)
{
throw new NotImplementedException("TODO");
InspectorManager.Instance.Inspect(type);
}
// public static void Help()
// {
// ExplorerCore.Log(@"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// C# Console Help
//The following helper methods are available:
//void Log(object message)
// prints a message to the console window and debug log
// usage: Log(""hello world"");
//void AddUsing(string directive)
// adds a using directive to the console.
// usage: AddUsing(""UnityEngine.UI"");
//void GetUsing()
// logs the current using directives to the debug console
// usage: GetUsing();
//void Reset()
// resets the C# console, clearing all variables and using directives.
// usage: Reset();
//");
//TODO:
//ExplorerCore.Log("object CurrentTarget()");
//ExplorerCore.Log(" returns the target object of the current tab (in tab view mode only)");
//ExplorerCore.Log(" usage: var target = CurrentTarget();");
//ExplorerCore.Log("");
//ExplorerCore.Log("object[] AllTargets()");
//ExplorerCore.Log(" returns an object[] array containing all currently inspected objects");
//ExplorerCore.Log(" usage: var targets = AllTargets();");
//ExplorerCore.Log("");
//ExplorerCore.Log("void Inspect(object obj)");
//ExplorerCore.Log(" inspects the provided object in a new window.");
//ExplorerCore.Log(" usage: Inspect(Camera.main);");
//ExplorerCore.Log("");
//ExplorerCore.Log("void Inspect(Type type)");
//ExplorerCore.Log(" attempts to inspect the provided type with static-only reflection.");
//ExplorerCore.Log(" usage: Inspect(typeof(Camera));");
//}
}
}

View File

@ -324,16 +324,14 @@ namespace ExplorerBeta.UI.Main
The following helper methods are available:
* <color=#c74e26>Log(""message"");</color> logs a message to the debug console
* <color=#c74e26>AddUsing(""SomeNamespace"");</color> adds a using directive to the C# console
* <color=#c74e26>GetUsing();</color> logs the current using directives to the debug console
* <color=#c74e26>Reset();</color> resets all using directives and variables
TODO:
* <color=#c74e26>CurrentTarget();</color> returns the currently inspected target on the Home page
* <color=#c74e26>AllTargets();</color> returns an object[] array containing all inspected instances
* <color=#c74e26>Inspect(someObject)</color> to inspect an instance, eg. Inspect(Camera.main);
* <color=#c74e26>Inspect(typeof(SomeClass))</color> to inspect a Class with static reflection
* <color=#add490>Log(""message"");</color> logs a message to the debug console
* <color=#add490>CurrentTarget();</color> returns the currently inspected target on the Home page
* <color=#add490>AllTargets();</color> returns an object[] array containing all inspected instances
* <color=#add490>Inspect(someObject)</color> to inspect an instance, eg. Inspect(Camera.main);
* <color=#add490>Inspect(typeof(SomeClass))</color> to inspect a Class with static reflection
* <color=#add490>AddUsing(""SomeNamespace"");</color> adds a using directive to the C# console
* <color=#add490>GetUsing();</color> logs the current using directives to the debug console
* <color=#add490>Reset();</color> resets all using directives and variables
";
var linesTextObj = UIFactory.CreateUIObject("LinesText", mainTextObj.gameObject);

View File

@ -19,8 +19,9 @@ namespace ExplorerBeta.UI.Main
public InspectorBase m_activeInspector;
public readonly List<InspectorBase> m_currentInspectors = new List<InspectorBase>();
public GameObject m_tabBarContent;
public GameObject m_rightPaneContent;
public GameObject m_inspectorContent;
public void Update()
{
@ -121,11 +122,11 @@ namespace ExplorerBeta.UI.Main
public void ConstructInspectorPane()
{
m_rightPaneContent = UIFactory.CreateVerticalGroup(HomePage.Instance.Content, new Color(72f / 255f, 72f / 255f, 72f / 255f));
LayoutElement rightLayout = m_rightPaneContent.AddComponent<LayoutElement>();
var mainObj = UIFactory.CreateVerticalGroup(HomePage.Instance.Content, new Color(72f / 255f, 72f / 255f, 72f / 255f));
LayoutElement rightLayout = mainObj.AddComponent<LayoutElement>();
rightLayout.flexibleWidth = 999999;
VerticalLayoutGroup rightGroup = m_rightPaneContent.GetComponent<VerticalLayoutGroup>();
var rightGroup = mainObj.GetComponent<VerticalLayoutGroup>();
rightGroup.childForceExpandHeight = true;
rightGroup.childForceExpandWidth = true;
rightGroup.childControlHeight = true;
@ -136,40 +137,40 @@ namespace ExplorerBeta.UI.Main
rightGroup.padding.top = 8;
rightGroup.padding.bottom = 8;
GameObject inspectorTitle = UIFactory.CreateLabel(m_rightPaneContent, TextAnchor.UpperLeft);
var inspectorTitle = UIFactory.CreateLabel(mainObj, TextAnchor.UpperLeft);
Text title = inspectorTitle.GetComponent<Text>();
title.text = "Inspector";
title.fontSize = 20;
LayoutElement titleLayout = inspectorTitle.AddComponent<LayoutElement>();
var titleLayout = inspectorTitle.AddComponent<LayoutElement>();
titleLayout.minHeight = 30;
titleLayout.flexibleHeight = 0;
m_tabBarContent = UIFactory.CreateGridGroup(m_rightPaneContent, new Vector2(185, 20), new Vector2(5, 2), new Color(0.1f, 0.1f, 0.1f, 1));
m_tabBarContent = UIFactory.CreateGridGroup(mainObj, new Vector2(185, 20), new Vector2(5, 2), new Color(0.1f, 0.1f, 0.1f, 1));
GridLayoutGroup gridGroup = m_tabBarContent.GetComponent<GridLayoutGroup>();
var gridGroup = m_tabBarContent.GetComponent<GridLayoutGroup>();
gridGroup.padding.top = 4;
gridGroup.padding.left = 4;
gridGroup.padding.right = 4;
gridGroup.padding.bottom = 4;
// TEMP DUMMY INSPECTOR
// inspector content area
GameObject dummyInspectorObj = UIFactory.CreateVerticalGroup(m_rightPaneContent, new Color(0.1f, 0.1f, 0.1f, 1.0f));
m_inspectorContent = UIFactory.CreateVerticalGroup(mainObj, new Color(0.1f, 0.1f, 0.1f, 1.0f));
VerticalLayoutGroup dummyGroup = dummyInspectorObj.GetComponent<VerticalLayoutGroup>();
dummyGroup.childForceExpandHeight = true;
dummyGroup.childForceExpandWidth = true;
dummyGroup.childControlHeight = true;
dummyGroup.childControlWidth = true;
dummyGroup.spacing = 5;
dummyGroup.padding.top = 5;
dummyGroup.padding.left = 5;
dummyGroup.padding.right = 5;
dummyGroup.padding.bottom = 5;
var contentGroup = m_inspectorContent.GetComponent<VerticalLayoutGroup>();
contentGroup.childForceExpandHeight = true;
contentGroup.childForceExpandWidth = true;
contentGroup.childControlHeight = true;
contentGroup.childControlWidth = true;
contentGroup.spacing = 5;
contentGroup.padding.top = 5;
contentGroup.padding.left = 5;
contentGroup.padding.right = 5;
contentGroup.padding.bottom = 5;
LayoutElement dummyLayout = dummyInspectorObj.AddComponent<LayoutElement>();
dummyLayout.preferredHeight = 900;
dummyLayout.flexibleHeight = 10000;
var contentLayout = m_inspectorContent.AddComponent<LayoutElement>();
contentLayout.preferredHeight = 900;
contentLayout.flexibleHeight = 10000;
}
#endregion

View File

@ -1,4 +1,6 @@
using UnityEngine;
using System;
using System.Collections.Generic;
using UnityEngine;
namespace ExplorerBeta.UI.Main.Inspectors
{

View File

@ -3,25 +3,13 @@ using ExplorerBeta.Helpers;
namespace ExplorerBeta.UI.Main.Inspectors
{
public class InstanceInspector : InspectorBase
public class InstanceInspector : ReflectionInspector
{
// todo
public override string TabLabel => $" [R] {m_targetTypeShortName}";
private readonly string m_targetTypeShortName;
public override string TabLabel => $" [R] {base.TabLabel}";
public InstanceInspector(object target) : base(target)
{
// todo
Type type = ReflectionHelpers.GetActualType(target);
if (type == null)
{
// TODO
return;
}
m_targetTypeShortName = type.Name;
}

View File

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ExplorerBeta.Helpers;
namespace ExplorerBeta.UI.Main.Inspectors
{
public class ReflectionInspector : InspectorBase
{
public override string TabLabel => m_targetTypeShortName;
private readonly string m_targetTypeShortName;
public ReflectionInspector(object target) : base(target)
{
Type type = ReflectionHelpers.GetActualType(target);
if (type == null)
{
// TODO
return;
}
m_targetTypeShortName = type.Name;
}
}
}

View File

@ -2,9 +2,9 @@
namespace ExplorerBeta.UI.Main.Inspectors
{
public class StaticInspector : InspectorBase
public class StaticInspector : ReflectionInspector
{
public override string TabLabel => " [S] TODO";
public override string TabLabel => $" [S] {base.TabLabel}";
public StaticInspector(Type type) : base(type)
{

View File

@ -9,7 +9,6 @@ using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
namespace ExplorerBeta.UI.Main
{
public class SceneExplorer
@ -404,7 +403,7 @@ namespace ExplorerBeta.UI.Main
Button inspectButton = m_mainInspectBtn.GetComponent<Button>();
inspectButton.onClick.AddListener(new Action(() => { InspectorManager.Instance.Inspect(m_selectedSceneObject); }));
GameObject scrollObj = UIFactory.CreateScrollView(leftPane, out m_sceneListCanvas, new Color(0.15f, 0.15f, 0.15f, 1));
GameObject scrollObj = UIFactory.CreateScrollView(leftPane, out m_sceneListCanvas, new Color(0.1f, 0.1f, 0.1f));
Scrollbar scroll = scrollObj.transform.Find("Scrollbar Vertical").GetComponent<Scrollbar>();
ColorBlock colors = scroll.colors;
colors.normalColor = new Color(0.6f, 0.6f, 0.6f, 1.0f);
@ -423,7 +422,7 @@ namespace ExplorerBeta.UI.Main
{
int thisIndex = m_sceneListTexts.Count();
GameObject btnGroupObj = UIFactory.CreateHorizontalGroup(m_sceneListCanvas, new Color(0.15f, 0.15f, 0.15f));
GameObject btnGroupObj = UIFactory.CreateHorizontalGroup(m_sceneListCanvas, new Color(0.1f, 0.1f, 0.1f));
HorizontalLayoutGroup btnGroup = btnGroupObj.GetComponent<HorizontalLayoutGroup>();
btnGroup.childForceExpandWidth = true;
btnGroup.childControlWidth = true;
@ -443,8 +442,8 @@ namespace ExplorerBeta.UI.Main
mainBtnLayout.flexibleWidth = 0;
Button mainBtn = mainButtonObj.GetComponent<Button>();
ColorBlock mainColors = mainBtn.colors;
mainColors.normalColor = new Color(0, 0, 0, 0);
mainColors.highlightedColor = new Color(0.3f, 0.3f, 0.3f, 1);
mainColors.normalColor = new Color(0.1f, 0.1f, 0.1f);
mainColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 1);
mainBtn.colors = mainColors;
#if CPP
mainBtn.onClick.AddListener(new Action(() => { SceneListObjectClicked(thisIndex); }));
@ -468,7 +467,8 @@ namespace ExplorerBeta.UI.Main
Button inspectBtn = inspectBtnObj.GetComponent<Button>();
ColorBlock inspectColors = inspectBtn.colors;
inspectColors.normalColor = new Color(1, 1, 1, 0.05f);
inspectColors.normalColor = new Color(0.15f, 0.15f, 0.15f);
mainColors.highlightedColor = new Color(0.2f, 0.2f, 0.2f, 0.5f);
inspectBtn.colors = inspectColors;
inspectBtn.onClick.AddListener(new Action(() => { InspectorManager.Instance.Inspect(m_sceneShortList[thisIndex]); }));
}