mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-16 14:17:51 +08:00
1.7.5
* Added support for Enums with [Flags] attribute (can set each flag individually) * Added support for easier bitwise operations on ints (or any primitive assignable to int), and viewing the int as binary. This is intended for things like `Camera.cullingMask`, etc. * Fixed an issue with Enums that contain duplicate values, for example `CameraClearFlags` (has duplicate values for 2).
This commit is contained in:
parent
2006a9ea76
commit
f203ae37fc
@ -121,11 +121,6 @@ namespace Explorer
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is pretty ugly, could probably make a cleaner implementation.
|
|
||||||
// However, the only cleaner ways I can think of are slower and probably not worth it.
|
|
||||||
|
|
||||||
// Note: the order is somewhat important.
|
|
||||||
|
|
||||||
if (mi != null)
|
if (mi != null)
|
||||||
{
|
{
|
||||||
holder = new CacheMethod();
|
holder = new CacheMethod();
|
||||||
@ -140,7 +135,14 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
else if (valueType.IsEnum)
|
else if (valueType.IsEnum)
|
||||||
{
|
{
|
||||||
holder = new CacheEnum();
|
if (valueType.GetCustomAttributes(typeof(FlagsAttribute), false) is object[] attributes && attributes.Length > 0)
|
||||||
|
{
|
||||||
|
holder = new CacheEnumFlags();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
holder = new CacheEnum();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (valueType == typeof(Vector2) || valueType == typeof(Vector3) || valueType == typeof(Vector4))
|
else if (valueType == typeof(Vector2) || valueType == typeof(Vector3) || valueType == typeof(Vector4))
|
||||||
{
|
{
|
||||||
|
@ -23,7 +23,18 @@ namespace Explorer
|
|||||||
|
|
||||||
if (ValueType != null)
|
if (ValueType != null)
|
||||||
{
|
{
|
||||||
EnumNames = Enum.GetNames(ValueType);
|
// using GetValues not GetNames, to catch instances of weird enums (eg CameraClearFlags)
|
||||||
|
var values = Enum.GetValues(ValueType);
|
||||||
|
|
||||||
|
var list = new List<string>();
|
||||||
|
foreach (var value in values)
|
||||||
|
{
|
||||||
|
var v = value.ToString();
|
||||||
|
if (list.Contains(v)) continue;
|
||||||
|
list.Add(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
EnumNames = list.ToArray();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -37,12 +48,12 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
if (GUILayout.Button("<", new GUILayoutOption[] { GUILayout.Width(25) }))
|
if (GUILayout.Button("<", new GUILayoutOption[] { GUILayout.Width(25) }))
|
||||||
{
|
{
|
||||||
SetEnum(ref Value, -1);
|
SetEnum(-1);
|
||||||
SetValue();
|
SetValue();
|
||||||
}
|
}
|
||||||
if (GUILayout.Button(">", new GUILayoutOption[] { GUILayout.Width(25) }))
|
if (GUILayout.Button(">", new GUILayoutOption[] { GUILayout.Width(25) }))
|
||||||
{
|
{
|
||||||
SetEnum(ref Value, 1);
|
SetEnum(1);
|
||||||
SetValue();
|
SetValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,15 +61,15 @@ namespace Explorer
|
|||||||
GUILayout.Label(Value.ToString() + "<color=#2df7b2><i> (" + ValueType + ")</i></color>", null);
|
GUILayout.Label(Value.ToString() + "<color=#2df7b2><i> (" + ValueType + ")</i></color>", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetEnum(ref object value, int change)
|
public void SetEnum(int change)
|
||||||
{
|
{
|
||||||
var names = EnumNames.ToList();
|
var names = EnumNames.ToList();
|
||||||
|
|
||||||
int newindex = names.IndexOf(value.ToString()) + change;
|
int newindex = names.IndexOf(Value.ToString()) + change;
|
||||||
|
|
||||||
if ((change < 0 && newindex >= 0) || (change > 0 && newindex < names.Count))
|
if (newindex >= 0 && newindex < names.Count)
|
||||||
{
|
{
|
||||||
value = Enum.Parse(ValueType, names[newindex]);
|
Value = Enum.Parse(ValueType, EnumNames[newindex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
127
src/CachedObjects/Struct/CacheEnumFlags.cs
Normal file
127
src/CachedObjects/Struct/CacheEnumFlags.cs
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using MelonLoader;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Explorer
|
||||||
|
{
|
||||||
|
public class CacheEnumFlags : CacheObjectBase, IExpandHeight
|
||||||
|
{
|
||||||
|
public string[] EnumNames = new string[0];
|
||||||
|
public bool[] m_enabledFlags = new bool[0];
|
||||||
|
|
||||||
|
public bool IsExpanded { get; set; }
|
||||||
|
public float WhiteSpace { get; set; } = 215f;
|
||||||
|
|
||||||
|
public override void Init()
|
||||||
|
{
|
||||||
|
base.Init();
|
||||||
|
|
||||||
|
if (ValueType == null && Value != null)
|
||||||
|
{
|
||||||
|
ValueType = Value.GetType();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ValueType != null)
|
||||||
|
{
|
||||||
|
EnumNames = Enum.GetNames(ValueType);
|
||||||
|
|
||||||
|
m_enabledFlags = new bool[EnumNames.Length];
|
||||||
|
|
||||||
|
UpdateValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReflectionException = "Unknown, could not get Enum names.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetFlagsFromInput()
|
||||||
|
{
|
||||||
|
string val = "";
|
||||||
|
for (int i = 0; i < EnumNames.Length; i++)
|
||||||
|
{
|
||||||
|
if (m_enabledFlags[i])
|
||||||
|
{
|
||||||
|
if (val != "") val += ", ";
|
||||||
|
val += EnumNames[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value = Enum.Parse(ValueType, val);
|
||||||
|
SetValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateValue()
|
||||||
|
{
|
||||||
|
base.UpdateValue();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var enabledNames = Value.ToString().Split(',').Select(it => it.Trim());
|
||||||
|
|
||||||
|
for (int i = 0; i < EnumNames.Length; i++)
|
||||||
|
{
|
||||||
|
m_enabledFlags[i] = enabledNames.Contains(EnumNames[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MelonLogger.Log(e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override void DrawValue(Rect window, float width)
|
||||||
|
{
|
||||||
|
if (CanWrite)
|
||||||
|
{
|
||||||
|
if (!IsExpanded)
|
||||||
|
{
|
||||||
|
if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
|
||||||
|
{
|
||||||
|
IsExpanded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
|
||||||
|
{
|
||||||
|
IsExpanded = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.Label(Value.ToString() + "<color=#2df7b2><i> (" + ValueType + ")</i></color>", null);
|
||||||
|
|
||||||
|
if (IsExpanded)
|
||||||
|
{
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
var whitespace = CalcWhitespace(window);
|
||||||
|
|
||||||
|
for (int i = 0; i < EnumNames.Length; i++)
|
||||||
|
{
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUIUnstrip.Space(whitespace);
|
||||||
|
|
||||||
|
m_enabledFlags[i] = GUILayout.Toggle(m_enabledFlags[i], EnumNames[i], null);
|
||||||
|
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUIUnstrip.Space(whitespace);
|
||||||
|
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
|
||||||
|
{
|
||||||
|
SetFlagsFromInput();
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
|
using UnhollowerRuntimeLib;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
@ -16,6 +18,12 @@ namespace Explorer
|
|||||||
public MethodInfo ParseMethod => m_parseMethod ?? (m_parseMethod = Value.GetType().GetMethod("Parse", new Type[] { typeof(string) }));
|
public MethodInfo ParseMethod => m_parseMethod ?? (m_parseMethod = Value.GetType().GetMethod("Parse", new Type[] { typeof(string) }));
|
||||||
private MethodInfo m_parseMethod;
|
private MethodInfo m_parseMethod;
|
||||||
|
|
||||||
|
private bool m_canBitwiseOperate;
|
||||||
|
private bool m_inBitwiseMode;
|
||||||
|
private string m_bitwiseOperatorInput = "0";
|
||||||
|
private string m_bitwiseToString;
|
||||||
|
//private BitArray m_bitMask; // not needed I think
|
||||||
|
|
||||||
public override void Init()
|
public override void Init()
|
||||||
{
|
{
|
||||||
if (ValueType == null)
|
if (ValueType == null)
|
||||||
@ -37,17 +45,31 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
m_isBool = true;
|
m_isBool = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_canBitwiseOperate = typeof(int).IsAssignableFrom(ValueType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateValue()
|
public override void UpdateValue()
|
||||||
{
|
{
|
||||||
base.UpdateValue();
|
base.UpdateValue();
|
||||||
|
|
||||||
|
RefreshToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RefreshToString()
|
||||||
|
{
|
||||||
m_valueToString = Value?.ToString();
|
m_valueToString = Value?.ToString();
|
||||||
|
|
||||||
|
if (m_inBitwiseMode)
|
||||||
|
{
|
||||||
|
var _int = (int)Value;
|
||||||
|
m_bitwiseToString = Convert.ToString(_int, toBase: 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DrawValue(Rect window, float width)
|
public override void DrawValue(Rect window, float width)
|
||||||
{
|
{
|
||||||
|
// bool uses Toggle
|
||||||
if (m_isBool)
|
if (m_isBool)
|
||||||
{
|
{
|
||||||
var b = (bool)Value;
|
var b = (bool)Value;
|
||||||
@ -65,35 +87,127 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
GUILayout.Label(label, null);
|
GUILayout.Label(label, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all other non-bool values use TextField
|
||||||
|
|
||||||
|
GUILayout.BeginVertical(null);
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
|
||||||
|
// using ValueType.Name instead of ValueTypeName, because we only want the short name.
|
||||||
|
GUILayout.Label("<color=#2df7b2><i>" + ValueType.Name + "</i></color>", new GUILayoutOption[] { GUILayout.Width(50) });
|
||||||
|
|
||||||
|
int dynSize = 25 + (m_valueToString.Length * 15);
|
||||||
|
var maxwidth = window.width - 310f;
|
||||||
|
if (CanWrite) maxwidth -= 60;
|
||||||
|
|
||||||
|
if (dynSize > maxwidth)
|
||||||
|
{
|
||||||
|
m_valueToString = GUILayout.TextArea(m_valueToString, new GUILayoutOption[] { GUILayout.MaxWidth(maxwidth) });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// using ValueType.Name instead of ValueTypeName, because we only want the short name.
|
m_valueToString = GUILayout.TextField(m_valueToString, new GUILayoutOption[] { GUILayout.MaxWidth(dynSize) });
|
||||||
GUILayout.Label("<color=#2df7b2><i>" + ValueType.Name + "</i></color>", new GUILayoutOption[] { GUILayout.Width(50) });
|
}
|
||||||
|
|
||||||
int dynSize = 25 + (m_valueToString.Length * 15);
|
if (CanWrite)
|
||||||
var maxwidth = window.width - 310f;
|
{
|
||||||
if (CanWrite) maxwidth -= 60;
|
if (GUILayout.Button("<color=#00FF00>Apply</color>", new GUILayoutOption[] { GUILayout.Width(60) }))
|
||||||
|
|
||||||
if (dynSize > maxwidth)
|
|
||||||
{
|
{
|
||||||
m_valueToString = GUILayout.TextArea(m_valueToString, new GUILayoutOption[] { GUILayout.MaxWidth(maxwidth) });
|
SetValueFromInput(m_valueToString);
|
||||||
}
|
RefreshToString();
|
||||||
else
|
|
||||||
{
|
|
||||||
m_valueToString = GUILayout.TextField(m_valueToString, new GUILayoutOption[] { GUILayout.MaxWidth(dynSize) });
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_canBitwiseOperate)
|
||||||
|
{
|
||||||
|
bool orig = m_inBitwiseMode;
|
||||||
|
m_inBitwiseMode = GUILayout.Toggle(m_inBitwiseMode, "Bitwise?", null);
|
||||||
|
if (orig != m_inBitwiseMode)
|
||||||
|
{
|
||||||
|
RefreshToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GUIUnstrip.Space(10);
|
||||||
|
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
if (m_inBitwiseMode)
|
||||||
|
{
|
||||||
if (CanWrite)
|
if (CanWrite)
|
||||||
{
|
{
|
||||||
if (GUILayout.Button("<color=#00FF00>Apply</color>", new GUILayoutOption[] { GUILayout.Width(60) }))
|
GUILayout.BeginHorizontal(null);
|
||||||
|
|
||||||
|
GUI.skin.label.alignment = TextAnchor.MiddleRight;
|
||||||
|
GUILayout.Label("RHS:", new GUILayoutOption[] { GUILayout.Width(35) });
|
||||||
|
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
||||||
|
|
||||||
|
if (GUILayout.Button("~", new GUILayoutOption[] { GUILayout.Width(25) }))
|
||||||
{
|
{
|
||||||
SetValueFromInput(m_valueToString);
|
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
|
||||||
|
{
|
||||||
|
Value = ~bit;
|
||||||
|
RefreshToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button("<<", new GUILayoutOption[] { GUILayout.Width(25) }))
|
||||||
|
{
|
||||||
|
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
|
||||||
|
{
|
||||||
|
Value = (int)Value << bit;
|
||||||
|
RefreshToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (GUILayout.Button(">>", new GUILayoutOption[] { GUILayout.Width(25) }))
|
||||||
|
{
|
||||||
|
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
|
||||||
|
{
|
||||||
|
Value = (int)Value >> bit;
|
||||||
|
RefreshToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (GUILayout.Button("|", new GUILayoutOption[] { GUILayout.Width(25) }))
|
||||||
|
{
|
||||||
|
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
|
||||||
|
{
|
||||||
|
Value = (int)Value | bit;
|
||||||
|
RefreshToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (GUILayout.Button("&", new GUILayoutOption[] { GUILayout.Width(25) }))
|
||||||
|
{
|
||||||
|
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
|
||||||
|
{
|
||||||
|
Value = (int)Value & bit;
|
||||||
|
RefreshToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
|
||||||
|
{
|
||||||
|
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
|
||||||
|
{
|
||||||
|
Value = (int)Value ^ bit;
|
||||||
|
RefreshToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bitwiseOperatorInput = GUILayout.TextField(m_bitwiseOperatorInput, new GUILayoutOption[] { GUILayout.Width(55) });
|
||||||
|
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
}
|
}
|
||||||
|
|
||||||
GUIUnstrip.Space(10);
|
GUILayout.BeginHorizontal(null);
|
||||||
|
GUILayout.Label($"<color=cyan>Binary:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
|
||||||
|
GUILayout.TextField(m_bitwiseToString, null);
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GUILayout.EndVertical();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetValueFromInput(string valueString)
|
public void SetValueFromInput(string valueString)
|
||||||
@ -113,6 +227,16 @@ namespace Explorer
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Value = ParseMethod.Invoke(null, new object[] { valueString });
|
Value = ParseMethod.Invoke(null, new object[] { valueString });
|
||||||
|
|
||||||
|
//if (m_inBitwiseMode)
|
||||||
|
//{
|
||||||
|
// var method = typeof(Convert).GetMethod($"To{ValueType.Name}", new Type[] { typeof(string), typeof(int) });
|
||||||
|
// Value = method.Invoke(null, new object[] { valueString, 2 });
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// Value = ParseMethod.Invoke(null, new object[] { valueString });
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,7 @@ namespace Explorer
|
|||||||
public class CppExplorer : MelonMod
|
public class CppExplorer : MelonMod
|
||||||
{
|
{
|
||||||
public const string NAME = "CppExplorer";
|
public const string NAME = "CppExplorer";
|
||||||
public const string VERSION = "1.7.4";
|
public const string VERSION = "1.7.5";
|
||||||
public const string AUTHOR = "Sinai";
|
public const string AUTHOR = "Sinai";
|
||||||
public const string GUID = "com.sinai.cppexplorer";
|
public const string GUID = "com.sinai.cppexplorer";
|
||||||
|
|
||||||
|
@ -83,6 +83,7 @@
|
|||||||
<Compile Include="CachedObjects\Struct\CacheEnum.cs" />
|
<Compile Include="CachedObjects\Struct\CacheEnum.cs" />
|
||||||
<Compile Include="CachedObjects\Object\CacheGameObject.cs" />
|
<Compile Include="CachedObjects\Object\CacheGameObject.cs" />
|
||||||
<Compile Include="CachedObjects\Object\CacheList.cs" />
|
<Compile Include="CachedObjects\Object\CacheList.cs" />
|
||||||
|
<Compile Include="CachedObjects\Struct\CacheEnumFlags.cs" />
|
||||||
<Compile Include="CachedObjects\Struct\CachePrimitive.cs" />
|
<Compile Include="CachedObjects\Struct\CachePrimitive.cs" />
|
||||||
<Compile Include="CachedObjects\Other\CacheOther.cs" />
|
<Compile Include="CachedObjects\Other\CacheOther.cs" />
|
||||||
<Compile Include="CachedObjects\Other\CacheMethod.cs" />
|
<Compile Include="CachedObjects\Other\CacheMethod.cs" />
|
||||||
|
@ -568,7 +568,7 @@ namespace Explorer
|
|||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
bool b = m_localContext;
|
bool b = m_localContext;
|
||||||
b = GUILayout.Toggle(b, "<color=" + (b ? "lime" : "red") + ">Use local transform values?</color>", null);
|
b = GUILayout.Toggle(b, "<color=" + (b ? "lime" : "orange") + ">Use local transform values?</color>", null);
|
||||||
if (b != m_localContext)
|
if (b != m_localContext)
|
||||||
{
|
{
|
||||||
m_localContext = b;
|
m_localContext = b;
|
||||||
@ -609,7 +609,7 @@ namespace Explorer
|
|||||||
private void BoolToggle(ref bool value, string message)
|
private void BoolToggle(ref bool value, string message)
|
||||||
{
|
{
|
||||||
string lbl = "<color=";
|
string lbl = "<color=";
|
||||||
lbl += value ? "lime" : "red";
|
lbl += value ? "lime" : "orange";
|
||||||
lbl += $">{message}</color>";
|
lbl += $">{message}</color>";
|
||||||
|
|
||||||
value = GUILayout.Toggle(value, lbl, null);
|
value = GUILayout.Toggle(value, lbl, null);
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System;
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using MelonLoader;
|
||||||
|
|
||||||
// used to test multiple generic constraints
|
// used to test multiple generic constraints
|
||||||
public class TestGeneric : IComparable<string>
|
public class TestGeneric : IComparable<string>
|
||||||
@ -11,10 +14,33 @@ public class TestGeneric : IComparable<string>
|
|||||||
public int CompareTo(string other) => throw new NotImplementedException();
|
public int CompareTo(string other) => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum TestFlags
|
||||||
|
{
|
||||||
|
Red,
|
||||||
|
Green,
|
||||||
|
Blue
|
||||||
|
}
|
||||||
|
|
||||||
|
// test non-flags weird enum
|
||||||
|
public enum WeirdEnum
|
||||||
|
{
|
||||||
|
First = 1,
|
||||||
|
Second,
|
||||||
|
Third = 2,
|
||||||
|
Fourth,
|
||||||
|
Fifth
|
||||||
|
}
|
||||||
|
|
||||||
namespace Explorer.Tests
|
namespace Explorer.Tests
|
||||||
{
|
{
|
||||||
public class TestClass
|
public class TestClass
|
||||||
{
|
{
|
||||||
|
public static TestFlags testFlags = TestFlags.Blue | TestFlags.Green;
|
||||||
|
public static WeirdEnum testWeird = WeirdEnum.First;
|
||||||
|
|
||||||
|
public static int testBitmask;
|
||||||
|
|
||||||
public static TestClass Instance => m_instance ?? (m_instance = new TestClass());
|
public static TestClass Instance => m_instance ?? (m_instance = new TestClass());
|
||||||
private static TestClass m_instance;
|
private static TestClass m_instance;
|
||||||
|
|
||||||
@ -24,13 +50,14 @@ namespace Explorer.Tests
|
|||||||
ILHashSetTest.Add("1");
|
ILHashSetTest.Add("1");
|
||||||
ILHashSetTest.Add("2");
|
ILHashSetTest.Add("2");
|
||||||
ILHashSetTest.Add("3");
|
ILHashSetTest.Add("3");
|
||||||
|
|
||||||
|
testBitmask = 1 | 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int StaticProperty => 5;
|
public static int StaticProperty => 5;
|
||||||
public static int StaticField = 5;
|
public static int StaticField = 5;
|
||||||
public int NonStaticField;
|
public int NonStaticField;
|
||||||
|
|
||||||
|
|
||||||
public static string TestGeneric<C, T>(string arg0) where C : Component where T : TestGeneric, IComparable<string>
|
public static string TestGeneric<C, T>(string arg0) where C : Component where T : TestGeneric, IComparable<string>
|
||||||
{
|
{
|
||||||
return $"C: '{typeof(C).FullName}', T: '{typeof(T).FullName}', arg0: '{arg0}'";
|
return $"C: '{typeof(C).FullName}', T: '{typeof(T).FullName}', arg0: '{arg0}'";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user