mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-01-07 10:03:38 +08:00
Improved Enumerable and Dictionary enumeration in IL2CPP
This commit is contained in:
parent
a9faec8cf9
commit
d181c0bee9
@ -90,6 +90,7 @@ namespace UnityExplorer
|
|||||||
{
|
{
|
||||||
UIManager.Init();
|
UIManager.Init();
|
||||||
Log("Initialized UnityExplorer UI.");
|
Log("Initialized UnityExplorer UI.");
|
||||||
|
// InspectorManager.Instance.Inspect(Tests.TestClass.Instance);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@ namespace UnityExplorer.Helpers
|
|||||||
return list.ToArray();
|
return list.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type GetActualType(object obj)
|
public static Type GetActualType(this object obj)
|
||||||
{
|
{
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
return null;
|
return null;
|
||||||
@ -107,6 +107,19 @@ namespace UnityExplorer.Helpers
|
|||||||
|
|
||||||
private static readonly Dictionary<Type, IntPtr> CppClassPointers = new Dictionary<Type, IntPtr>();
|
private static readonly Dictionary<Type, IntPtr> CppClassPointers = new Dictionary<Type, IntPtr>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempt to cast the object to its underlying type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">The object you want to cast.</param>
|
||||||
|
/// <returns>The object, as the underlying type if successful or the input value if not.</returns>
|
||||||
|
public static object Il2CppCast(this object obj) => Il2CppCast(obj, GetActualType(obj));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempt to cast the object to the provided type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">The object you want to cast.</param>
|
||||||
|
/// <param name="castTo">The Type you want to cast to.</param>
|
||||||
|
/// <returns>The object, as the type (or a normal C# object) if successful or the input value if not.</returns>
|
||||||
public static object Il2CppCast(this object obj, Type castTo)
|
public static object Il2CppCast(this object obj, Type castTo)
|
||||||
{
|
{
|
||||||
if (!(obj is Il2CppSystem.Object ilObj))
|
if (!(obj is Il2CppSystem.Object ilObj))
|
||||||
@ -126,6 +139,39 @@ namespace UnityExplorer.Helpers
|
|||||||
return Activator.CreateInstance(castTo, ilObj.Pointer);
|
return Activator.CreateInstance(castTo, ilObj.Pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static readonly Dictionary<Type, MethodInfo> s_unboxMethods = new Dictionary<Type, MethodInfo>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempt to unbox the object to the underlying struct type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">The object which is a struct underneath.</param>
|
||||||
|
/// <returns>The struct if successful, otherwise null.</returns>
|
||||||
|
public static object Unbox(this object obj) => Unbox(obj, GetActualType(obj));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempt to unbox the object to the struct type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">The object which is a struct underneath.</param>
|
||||||
|
/// <param name="type">The type of the struct you want to unbox to.</param>
|
||||||
|
/// <returns>The struct if successful, otherwise null.</returns>
|
||||||
|
public static object Unbox(this object obj, Type type)
|
||||||
|
{
|
||||||
|
if (!type.IsValueType)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (!(obj is Il2CppSystem.Object))
|
||||||
|
return obj;
|
||||||
|
|
||||||
|
if (!s_unboxMethods.ContainsKey(type))
|
||||||
|
{
|
||||||
|
s_unboxMethods.Add(type, typeof(Il2CppObjectBase)
|
||||||
|
.GetMethod("Unbox")
|
||||||
|
.MakeGenericMethod(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_unboxMethods[type].Invoke(obj, new object[0]);
|
||||||
|
}
|
||||||
|
|
||||||
public static bool Il2CppTypeNotNull(Type type) => Il2CppTypeNotNull(type, out _);
|
public static bool Il2CppTypeNotNull(Type type) => Il2CppTypeNotNull(type, out _);
|
||||||
|
|
||||||
public static bool Il2CppTypeNotNull(Type type, out IntPtr il2cppPtr)
|
public static bool Il2CppTypeNotNull(Type type, out IntPtr il2cppPtr)
|
||||||
@ -215,50 +261,56 @@ namespace UnityExplorer.Helpers
|
|||||||
public static bool LoadModule(string module) => true;
|
public static bool LoadModule(string module) => true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CPP
|
||||||
|
internal static IntPtr s_cppEnumerableClassPtr;
|
||||||
|
#endif
|
||||||
|
|
||||||
public static bool IsEnumerable(Type t)
|
public static bool IsEnumerable(Type t)
|
||||||
{
|
{
|
||||||
if (typeof(IEnumerable).IsAssignableFrom(t))
|
if (typeof(IEnumerable).IsAssignableFrom(t))
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
|
#if CPP
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (s_cppEnumerableClassPtr == IntPtr.Zero)
|
||||||
|
Il2CppTypeNotNull(typeof(Il2CppSystem.Collections.IEnumerable), out s_cppEnumerableClassPtr);
|
||||||
|
|
||||||
|
if (s_cppEnumerableClassPtr != IntPtr.Zero
|
||||||
|
&& Il2CppTypeNotNull(t, out IntPtr classPtr)
|
||||||
|
&& il2cpp_class_is_assignable_from(s_cppEnumerableClassPtr, classPtr))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
catch { }
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#if CPP
|
#if CPP
|
||||||
if (t.IsGenericType && t.GetGenericTypeDefinition() is Type g)
|
internal static IntPtr s_cppDictionaryClassPtr;
|
||||||
{
|
|
||||||
return typeof(Il2CppSystem.Collections.Generic.List<>).IsAssignableFrom(g)
|
|
||||||
|| typeof(Il2CppSystem.Collections.Generic.IList<>).IsAssignableFrom(g)
|
|
||||||
|| typeof(Il2CppSystem.Collections.Generic.HashSet<>).IsAssignableFrom(g);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return typeof(Il2CppSystem.Collections.IList).IsAssignableFrom(t);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsDictionary(Type t)
|
public static bool IsDictionary(Type t)
|
||||||
{
|
{
|
||||||
if (typeof(IDictionary).IsAssignableFrom(t))
|
if (typeof(IDictionary).IsAssignableFrom(t))
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
#if CPP
|
#if CPP
|
||||||
if (t.IsGenericType && t.GetGenericTypeDefinition() is Type g)
|
try
|
||||||
{
|
{
|
||||||
return typeof(Il2CppSystem.Collections.Generic.Dictionary<,>).IsAssignableFrom(g)
|
if (s_cppDictionaryClassPtr == IntPtr.Zero)
|
||||||
|| typeof(Il2CppSystem.Collections.Generic.IDictionary<,>).IsAssignableFrom(g);
|
if (!Il2CppTypeNotNull(typeof(Il2CppSystem.Collections.IDictionary), out s_cppDictionaryClassPtr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (Il2CppTypeNotNull(t, out IntPtr classPtr))
|
||||||
|
{
|
||||||
|
if (il2cpp_class_is_assignable_from(s_cppDictionaryClassPtr, classPtr))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
catch { }
|
||||||
{
|
|
||||||
return typeof(Il2CppSystem.Collections.IDictionary).IsAssignableFrom(t)
|
|
||||||
|| typeof(Il2CppSystem.Collections.Hashtable).IsAssignableFrom(t);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
#endif
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ExceptionToString(Exception e, bool innerMost = false)
|
public static string ExceptionToString(Exception e, bool innerMost = false)
|
||||||
|
@ -10,6 +10,9 @@ using UnityExplorer.Helpers;
|
|||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityExplorer.UI.Shared;
|
using UnityExplorer.UI.Shared;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
#if CPP
|
||||||
|
using CppDictionary = Il2CppSystem.Collections.IDictionary;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace UnityExplorer.Inspectors.Reflection
|
namespace UnityExplorer.Inspectors.Reflection
|
||||||
{
|
{
|
||||||
@ -44,7 +47,11 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal IDictionary RefIDictionary;
|
internal IDictionary RefIDictionary;
|
||||||
|
#if CPP
|
||||||
|
internal CppDictionary RefCppDictionary;
|
||||||
|
#else
|
||||||
|
internal IDictionary RefCppDictionary = null;
|
||||||
|
#endif
|
||||||
internal Type m_typeOfKeys;
|
internal Type m_typeOfKeys;
|
||||||
internal Type m_typeofValues;
|
internal Type m_typeofValues;
|
||||||
|
|
||||||
@ -65,6 +72,11 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
RefIDictionary = Value as IDictionary;
|
RefIDictionary = Value as IDictionary;
|
||||||
|
|
||||||
|
#if CPP
|
||||||
|
try { RefCppDictionary = (Value as Il2CppSystem.Object).TryCast<CppDictionary>(); }
|
||||||
|
catch { }
|
||||||
|
#endif
|
||||||
|
|
||||||
if (m_subContentParent.activeSelf)
|
if (m_subContentParent.activeSelf)
|
||||||
{
|
{
|
||||||
GetCacheEntries();
|
GetCacheEntries();
|
||||||
@ -129,13 +141,6 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
{
|
{
|
||||||
var value = RefIDictionary[key];
|
var value = RefIDictionary[key];
|
||||||
|
|
||||||
//if (index >= m_rowHolders.Count)
|
|
||||||
//{
|
|
||||||
// AddRowHolder();
|
|
||||||
//}
|
|
||||||
|
|
||||||
//var holder = m_rowHolders[index];
|
|
||||||
|
|
||||||
var cacheKey = new CachePaired(index, this, this.RefIDictionary, PairTypes.Key, m_listContent);
|
var cacheKey = new CachePaired(index, this, this.RefIDictionary, PairTypes.Key, m_listContent);
|
||||||
cacheKey.CreateIValue(key, this.m_typeOfKeys);
|
cacheKey.CreateIValue(key, this.m_typeOfKeys);
|
||||||
cacheKey.Disable();
|
cacheKey.Disable();
|
||||||
@ -206,9 +211,10 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
RefreshDisplay();
|
RefreshDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region CPP fixes
|
#region CPP fixes
|
||||||
#if CPP
|
#if CPP
|
||||||
// temp fix for Il2Cpp IDictionary until interfaces are fixed
|
// temp fix for Il2Cpp IDictionary until interfaces are fixed
|
||||||
|
|
||||||
private IDictionary EnumerateWithReflection()
|
private IDictionary EnumerateWithReflection()
|
||||||
{
|
{
|
||||||
var valueType = Value?.GetType() ?? FallbackType;
|
var valueType = Value?.GetType() ?? FallbackType;
|
||||||
@ -222,8 +228,8 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
var valueList = new List<object>();
|
var valueList = new List<object>();
|
||||||
|
|
||||||
// store entries with reflection
|
// store entries with reflection
|
||||||
EnumerateWithReflection(keys, keyList);
|
EnumerateCollection(keys, keyList);
|
||||||
EnumerateWithReflection(values, valueList);
|
EnumerateCollection(values, valueList);
|
||||||
|
|
||||||
// make actual mono dictionary
|
// make actual mono dictionary
|
||||||
var dict = (IDictionary)Activator.CreateInstance(typeof(Dictionary<,>)
|
var dict = (IDictionary)Activator.CreateInstance(typeof(Dictionary<,>)
|
||||||
@ -236,7 +242,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EnumerateWithReflection(object collection, List<object> list)
|
private void EnumerateCollection(object collection, List<object> list)
|
||||||
{
|
{
|
||||||
// invoke GetEnumerator
|
// invoke GetEnumerator
|
||||||
var enumerator = collection.GetType().GetMethod("GetEnumerator").Invoke(collection, null);
|
var enumerator = collection.GetType().GetMethod("GetEnumerator").Invoke(collection, null);
|
||||||
@ -253,9 +259,9 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region UI CONSTRUCTION
|
#region UI CONSTRUCTION
|
||||||
|
|
||||||
internal GameObject m_listContent;
|
internal GameObject m_listContent;
|
||||||
internal LayoutElement m_listLayout;
|
internal LayoutElement m_listLayout;
|
||||||
@ -309,6 +315,6 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
// m_rowHolders.Add(obj);
|
// m_rowHolders.Add(obj);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,11 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
|
|
||||||
internal IEnumerable RefIEnumerable;
|
internal IEnumerable RefIEnumerable;
|
||||||
internal IList RefIList;
|
internal IList RefIList;
|
||||||
|
#if CPP
|
||||||
|
internal Il2CppSystem.Collections.ICollection CppICollection;
|
||||||
|
#else
|
||||||
|
internal ICollection CppICollection = null;
|
||||||
|
#endif
|
||||||
|
|
||||||
internal readonly Type m_baseEntryType;
|
internal readonly Type m_baseEntryType;
|
||||||
|
|
||||||
@ -49,6 +54,14 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
RefIEnumerable = Value as IEnumerable;
|
RefIEnumerable = Value as IEnumerable;
|
||||||
RefIList = Value as IList;
|
RefIList = Value as IList;
|
||||||
|
|
||||||
|
#if CPP
|
||||||
|
if (Value != null && RefIList == null)
|
||||||
|
{
|
||||||
|
try { CppICollection = (Value as Il2CppSystem.Object).TryCast<Il2CppSystem.Collections.ICollection>(); }
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (m_subContentParent.activeSelf)
|
if (m_subContentParent.activeSelf)
|
||||||
{
|
{
|
||||||
GetCacheEntries();
|
GetCacheEntries();
|
||||||
@ -77,8 +90,8 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
if (Value != null)
|
if (Value != null)
|
||||||
{
|
{
|
||||||
string count = "?";
|
string count = "?";
|
||||||
if (m_recacheWanted && RefIList != null)
|
if (m_recacheWanted && (RefIList != null || CppICollection != null))
|
||||||
count = RefIList.Count.ToString();
|
count = RefIList?.Count.ToString() ?? CppICollection.Count.ToString();
|
||||||
else if (!m_recacheWanted)
|
else if (!m_recacheWanted)
|
||||||
count = m_entries.Count.ToString();
|
count = m_entries.Count.ToString();
|
||||||
|
|
||||||
@ -169,89 +182,62 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
RefreshDisplay();
|
RefreshDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region CPP Helpers
|
#region CPP Helpers
|
||||||
|
|
||||||
#if CPP
|
#if CPP
|
||||||
// some temp fixes for Il2Cpp IEnumerables until interfaces are fixed
|
// some temp fixes for Il2Cpp IEnumerables until interfaces are fixed
|
||||||
|
|
||||||
|
internal static readonly Dictionary<Type, MethodInfo> s_getEnumeratorMethods = new Dictionary<Type, MethodInfo>();
|
||||||
|
|
||||||
|
internal static readonly Dictionary<Type, EnumeratorInfo> s_enumeratorInfos = new Dictionary<Type, EnumeratorInfo>();
|
||||||
|
|
||||||
|
internal class EnumeratorInfo
|
||||||
|
{
|
||||||
|
internal MethodInfo moveNext;
|
||||||
|
internal PropertyInfo current;
|
||||||
|
}
|
||||||
|
|
||||||
private IEnumerable EnumerateWithReflection()
|
private IEnumerable EnumerateWithReflection()
|
||||||
{
|
{
|
||||||
if (Value.IsNullOrDestroyed())
|
if (Value == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var genericDef = Value.GetType().GetGenericTypeDefinition();
|
// new test
|
||||||
|
var CppEnumerable = (Value as Il2CppSystem.Object)?.TryCast<Il2CppSystem.Collections.IEnumerable>();
|
||||||
if (genericDef == typeof(Il2CppSystem.Collections.Generic.List<>))
|
if (CppEnumerable != null)
|
||||||
return CppListToMono(genericDef);
|
|
||||||
else if (genericDef == typeof(Il2CppSystem.Collections.Generic.HashSet<>))
|
|
||||||
return CppHashSetToMono();
|
|
||||||
else
|
|
||||||
return CppIListToMono();
|
|
||||||
}
|
|
||||||
|
|
||||||
// List<T>.ToArray()
|
|
||||||
private IEnumerable CppListToMono(Type genericTypeDef)
|
|
||||||
{
|
|
||||||
if (genericTypeDef == null) return null;
|
|
||||||
|
|
||||||
return genericTypeDef
|
|
||||||
.MakeGenericType(new Type[] { this.m_baseEntryType })
|
|
||||||
.GetMethod("ToArray")
|
|
||||||
.Invoke(Value, new object[0]) as IEnumerable;
|
|
||||||
}
|
|
||||||
|
|
||||||
// HashSet.GetEnumerator
|
|
||||||
private IEnumerable CppHashSetToMono()
|
|
||||||
{
|
|
||||||
var set = new HashSet<object>();
|
|
||||||
|
|
||||||
// invoke GetEnumerator
|
|
||||||
var enumerator = Value.GetType().GetMethod("GetEnumerator").Invoke(Value, null);
|
|
||||||
// get the type of it
|
|
||||||
var enumeratorType = enumerator.GetType();
|
|
||||||
// reflect MoveNext and Current
|
|
||||||
var moveNext = enumeratorType.GetMethod("MoveNext");
|
|
||||||
var current = enumeratorType.GetProperty("Current");
|
|
||||||
// iterate
|
|
||||||
while ((bool)moveNext.Invoke(enumerator, null))
|
|
||||||
set.Add(current.GetValue(enumerator));
|
|
||||||
|
|
||||||
return set;
|
|
||||||
}
|
|
||||||
|
|
||||||
// IList.Item
|
|
||||||
private IList CppIListToMono()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var genericType = typeof(List<>).MakeGenericType(new Type[] { this.m_baseEntryType });
|
var type = Value.GetType();
|
||||||
var list = (IList)Activator.CreateInstance(genericType);
|
if (!s_getEnumeratorMethods.ContainsKey(type))
|
||||||
|
s_getEnumeratorMethods.Add(type, type.GetMethod("GetEnumerator"));
|
||||||
|
|
||||||
|
var enumerator = s_getEnumeratorMethods[type].Invoke(Value, null);
|
||||||
|
var enumeratorType = enumerator.GetType();
|
||||||
|
|
||||||
for (int i = 0; ; i++)
|
if (!s_enumeratorInfos.ContainsKey(enumeratorType))
|
||||||
{
|
{
|
||||||
try
|
s_enumeratorInfos.Add(enumeratorType, new EnumeratorInfo
|
||||||
{
|
{
|
||||||
var itm = Value?.GetType()
|
current = enumeratorType.GetProperty("Current"),
|
||||||
.GetProperty("Item")
|
moveNext = enumeratorType.GetMethod("MoveNext"),
|
||||||
.GetValue(Value, new object[] { i });
|
});
|
||||||
list.Add(itm);
|
|
||||||
}
|
|
||||||
catch { break; }
|
|
||||||
}
|
}
|
||||||
|
var info = s_enumeratorInfos[enumeratorType];
|
||||||
|
|
||||||
|
// iterate
|
||||||
|
var list = new List<object>();
|
||||||
|
while ((bool)info.moveNext.Invoke(enumerator, null))
|
||||||
|
list.Add(info.current.GetValue(enumerator));
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
return null;
|
||||||
ExplorerCore.Log("Exception converting Il2Cpp IList to Mono IList: " + e.GetType() + ", " + e.Message);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region UI CONSTRUCTION
|
#region UI CONSTRUCTION
|
||||||
|
|
||||||
internal GameObject m_listContent;
|
internal GameObject m_listContent;
|
||||||
internal LayoutElement m_listLayout;
|
internal LayoutElement m_listLayout;
|
||||||
@ -296,6 +282,6 @@ namespace UnityExplorer.Inspectors.Reflection
|
|||||||
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
contentFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,6 +128,8 @@ namespace UnityExplorer.Tests
|
|||||||
public static Il2CppSystem.Collections.Generic.HashSet<string> CppHashSetTest;
|
public static Il2CppSystem.Collections.Generic.HashSet<string> CppHashSetTest;
|
||||||
public static Il2CppSystem.Collections.Generic.List<string> CppStringTest;
|
public static Il2CppSystem.Collections.Generic.List<string> CppStringTest;
|
||||||
public static Il2CppSystem.Collections.IList CppIList;
|
public static Il2CppSystem.Collections.IList CppIList;
|
||||||
|
public static Il2CppSystem.Collections.Generic.Dictionary<string, string> CppDictTest;
|
||||||
|
public static Il2CppSystem.Collections.Generic.Dictionary<int, float> CppDictTest2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public TestClass()
|
public TestClass()
|
||||||
@ -143,21 +145,7 @@ namespace UnityExplorer.Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CPP
|
#if CPP
|
||||||
//TestTexture = UIManager.MakeSolidTexture(Color.white, 1000, 600);
|
TextureSpriteTest();
|
||||||
TestTexture = new Texture();
|
|
||||||
TestTexture.name = "TestTexture";
|
|
||||||
|
|
||||||
var r = new Rect(0, 0, TestTexture.width, TestTexture.height);
|
|
||||||
var v2 = Vector2.zero;
|
|
||||||
var v4 = Vector4.zero;
|
|
||||||
TestSprite = Sprite.CreateSprite_Injected((Texture2D)TestTexture, ref r, ref v2, 100f, 0u, SpriteMeshType.Tight, ref v4, false);
|
|
||||||
|
|
||||||
GameObject.DontDestroyOnLoad(TestTexture);
|
|
||||||
GameObject.DontDestroyOnLoad(TestSprite);
|
|
||||||
|
|
||||||
//// test loading a tex from file
|
|
||||||
//var dataToLoad = System.IO.File.ReadAllBytes(@"Mods\UnityExplorer\Tex_Nemundis_Nebula.png");
|
|
||||||
//ExplorerCore.Log($"Tex load success: {TestTexture.LoadImage(dataToLoad, false)}");
|
|
||||||
|
|
||||||
CppHashSetTest = new Il2CppSystem.Collections.Generic.HashSet<string>();
|
CppHashSetTest = new Il2CppSystem.Collections.Generic.HashSet<string>();
|
||||||
CppHashSetTest.Add("1");
|
CppHashSetTest.Add("1");
|
||||||
@ -167,9 +155,38 @@ namespace UnityExplorer.Tests
|
|||||||
CppStringTest = new Il2CppSystem.Collections.Generic.List<string>();
|
CppStringTest = new Il2CppSystem.Collections.Generic.List<string>();
|
||||||
CppStringTest.Add("1");
|
CppStringTest.Add("1");
|
||||||
CppStringTest.Add("2");
|
CppStringTest.Add("2");
|
||||||
|
|
||||||
|
CppDictTest = new Il2CppSystem.Collections.Generic.Dictionary<string, string>();
|
||||||
|
CppDictTest.Add("key1", "value1");
|
||||||
|
CppDictTest.Add("key2", "value2");
|
||||||
|
CppDictTest.Add("key3", "value3");
|
||||||
|
|
||||||
|
CppDictTest2 = new Il2CppSystem.Collections.Generic.Dictionary<int, float>();
|
||||||
|
CppDictTest2.Add(0, 0.5f);
|
||||||
|
CppDictTest2.Add(1, 0.5f);
|
||||||
|
CppDictTest2.Add(2, 0.5f);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TextureSpriteTest()
|
||||||
|
{
|
||||||
|
//TestTexture = UIManager.MakeSolidTexture(Color.white, 1000, 600);
|
||||||
|
//TestTexture = new Texture();
|
||||||
|
//TestTexture.name = "TestTexture";
|
||||||
|
|
||||||
|
//var r = new Rect(0, 0, TestTexture.width, TestTexture.height);
|
||||||
|
//var v2 = Vector2.zero;
|
||||||
|
//var v4 = Vector4.zero;
|
||||||
|
//TestSprite = Sprite.CreateSprite_Injected((Texture2D)TestTexture, ref r, ref v2, 100f, 0u, SpriteMeshType.Tight, ref v4, false);
|
||||||
|
|
||||||
|
//GameObject.DontDestroyOnLoad(TestTexture);
|
||||||
|
//GameObject.DontDestroyOnLoad(TestSprite);
|
||||||
|
|
||||||
|
//// test loading a tex from file
|
||||||
|
//var dataToLoad = System.IO.File.ReadAllBytes(@"Mods\UnityExplorer\Tex_Nemundis_Nebula.png");
|
||||||
|
//ExplorerCore.Log($"Tex load success: {TestTexture.LoadImage(dataToLoad, false)}");
|
||||||
|
}
|
||||||
|
|
||||||
public static string TestRefInOutGeneric<T>(ref string arg0, in int arg1, out string arg2) where T : Component
|
public static string TestRefInOutGeneric<T>(ref string arg0, in int arg1, out string arg2) where T : Component
|
||||||
{
|
{
|
||||||
arg2 = "this is arg2";
|
arg2 = "this is arg2";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user