Implement .NET 7 runtime support and bindings generation

This commit is contained in:
2022-11-17 19:49:39 +02:00
parent fe943ca010
commit 96dc279ebd
89 changed files with 6009 additions and 503 deletions

View File

@@ -93,3 +93,14 @@
#endif
#define PACK_STRUCT(__Declaration__) PACK_BEGIN() __Declaration__ PACK_END()
#define SCRIPTING_EXPORT(name) __pragma(comment(linker, "/EXPORT:" #name "=" __FUNCDNAME__))
#define SCRIPTING_EXPORT_DEBUG(name) __pragma(message("/EXPORT:" #name "=" __FUNCDNAME__)) \
__pragma(comment(linker, "/EXPORT:" #name "=" __FUNCDNAME__))
// TODO: try this one with clang:
//#ifdef _MSC_VER
//#define SCRIPTING_EXPORT(name) __pragma(comment(linker, "/EXPORT:" #name "=" __FUNCDNAME__))
//#endif
//#ifdef __GNUC__
//#define SCRIPTING_EXPORT(name) asm(".section .drectve\n\t.ascii \" -export:" #name "=" __FUNCDNAME__ "\"");
//#endif

View File

@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using FlaxEngine;
namespace FlaxEditor.Content.Settings
@@ -562,8 +563,8 @@ namespace FlaxEditor.Content.Settings
/// <summary>
/// Loads the current game settings asset and applies it to the engine runtime configuration.
/// </summary>
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void Apply();
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Content.Settings.GameSettings::Apply")]
public static partial void Apply();
#endif
}
}

View File

@@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
using FlaxEngine;
namespace FlaxEditor.Content.Settings
@@ -24,14 +26,26 @@ namespace FlaxEditor.Content.Settings
/// Gets the current tags collection.
/// </summary>
/// <returns>The tags collection.</returns>
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern string[] GetCurrentTags();
internal static string[] GetCurrentTags()
{
return GetCurrentTags(out int _);
}
/// <summary>
/// Gets the current layer names (max 32 items but trims last empty items).
/// </summary>
/// <returns>The layers.</returns>
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern string[] GetCurrentLayers();
public static string[] GetCurrentLayers()
{
return GetCurrentLayers(out int _);
}
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Content.Settings.LayersAndTagsSettings::GetCurrentTags", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
[return: MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = "tagCount")]
internal static partial string[] GetCurrentTags(out int tagCount);
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEditor.Content.Settings.LayersAndTagsSettings::GetCurrentLayers", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.StringMarshaller))]
[return: MarshalUsing(typeof(FlaxEngine.ArrayMarshaller<,>), CountElementName = "layerCount")]
internal static partial string[] GetCurrentLayers(out int layerCount);
}
}

View File

@@ -18,6 +18,16 @@ namespace FlaxEngine.TypeConverters
return base.CanConvertFrom(context, sourceType);
}
/// <inheritdoc />
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return false;
}
return base.CanConvertTo(context, destinationType);
}
/// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
@@ -25,9 +35,9 @@ namespace FlaxEngine.TypeConverters
{
string[] v = str.Split(',');
if (v.Length == 4)
return new Color(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]), float.Parse(v[3]));
return new Color(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture), float.Parse(v[3], culture));
if (v.Length == 3)
return new Color(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]), 1.0f);
return new Color(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture), 1.0f);
throw new FormatException("Invalid Color value format.");
}
return base.ConvertFrom(context, culture, value);
@@ -39,7 +49,7 @@ namespace FlaxEngine.TypeConverters
if (destinationType == typeof(string))
{
var v = (Color)value;
return v.R + "," + v.G + "," + v.B + "," + v.A;
return v.R.ToString(culture) + "," + v.G.ToString(culture) + "," + v.B.ToString(culture) + "," + v.A.ToString(culture);
}
return base.ConvertTo(context, culture, value, destinationType);
}

View File

@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
return base.CanConvertFrom(context, sourceType);
}
/// <inheritdoc />
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return false;
}
return base.CanConvertTo(context, destinationType);
}
/// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string str)
{
string[] v = str.Split(',');
return new Double2(double.Parse(v[0]), double.Parse(v[1]));
return new Double2(double.Parse(v[0], culture), double.Parse(v[1], culture));
}
return base.ConvertFrom(context, culture, value);
}
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
if (destinationType == typeof(string))
{
var v = (Double2)value;
return v.X + "," + v.Y;
return v.X.ToString(culture) + "," + v.Y.ToString(culture);
}
return base.ConvertTo(context, culture, value, destinationType);
}

View File

@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
return base.CanConvertFrom(context, sourceType);
}
/// <inheritdoc />
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return false;
}
return base.CanConvertTo(context, destinationType);
}
/// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string str)
{
string[] v = str.Split(',');
return new Double3(double.Parse(v[0]), double.Parse(v[1]), double.Parse(v[2]));
return new Double3(double.Parse(v[0], culture), double.Parse(v[1], culture), double.Parse(v[2], culture));
}
return base.ConvertFrom(context, culture, value);
}
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
if (destinationType == typeof(string))
{
var v = (Double3)value;
return v.X + "," + v.Y + "," + v.Z;
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture);
}
return base.ConvertTo(context, culture, value, destinationType);
}

View File

@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
return base.CanConvertFrom(context, sourceType);
}
/// <inheritdoc />
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return false;
}
return base.CanConvertTo(context, destinationType);
}
/// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string str)
{
string[] v = str.Split(',');
return new Double4(double.Parse(v[0]), double.Parse(v[1]), double.Parse(v[2]), double.Parse(v[3]));
return new Double4(double.Parse(v[0], culture), double.Parse(v[1], culture), double.Parse(v[2], culture), double.Parse(v[3], culture));
}
return base.ConvertFrom(context, culture, value);
}
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
if (destinationType == typeof(string))
{
var v = (Double4)value;
return v.X + "," + v.Y + "," + v.Z + "," + v.W;
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture) + "," + v.W.ToString(culture);
}
return base.ConvertTo(context, culture, value, destinationType);
}

View File

@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
return base.CanConvertFrom(context, sourceType);
}
/// <inheritdoc />
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return false;
}
return base.CanConvertTo(context, destinationType);
}
/// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string str)
{
string[] v = str.Split(',');
return new Float2(float.Parse(v[0]), float.Parse(v[1]));
return new Float2(float.Parse(v[0], culture), float.Parse(v[1], culture));
}
return base.ConvertFrom(context, culture, value);
}
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
if (destinationType == typeof(string))
{
var v = (Float2)value;
return v.X + "," + v.Y;
return v.X.ToString(culture) + "," + v.Y.ToString(culture);
}
return base.ConvertTo(context, culture, value, destinationType);
}

View File

@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
return base.CanConvertFrom(context, sourceType);
}
/// <inheritdoc />
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return false;
}
return base.CanConvertTo(context, destinationType);
}
/// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string str)
{
string[] v = str.Split(',');
return new Float3(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]));
return new Float3(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture));
}
return base.ConvertFrom(context, culture, value);
}
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
if (destinationType == typeof(string))
{
var v = (Float3)value;
return v.X + "," + v.Y + "," + v.Z;
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture);
}
return base.ConvertTo(context, culture, value, destinationType);
}

View File

@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
return base.CanConvertFrom(context, sourceType);
}
/// <inheritdoc />
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return false;
}
return base.CanConvertTo(context, destinationType);
}
/// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string str)
{
string[] v = str.Split(',');
return new Float4(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]), float.Parse(v[3]));
return new Float4(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture), float.Parse(v[3], culture));
}
return base.ConvertFrom(context, culture, value);
}
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
if (destinationType == typeof(string))
{
var v = (Float4)value;
return v.X + "," + v.Y + "," + v.Z + "," + v.W;
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture) + "," + v.W.ToString(culture);
}
return base.ConvertTo(context, culture, value, destinationType);
}

View File

@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
return base.CanConvertFrom(context, sourceType);
}
/// <inheritdoc />
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return false;
}
return base.CanConvertTo(context, destinationType);
}
/// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string str)
{
string[] v = str.Split(',');
return new Int2(int.Parse(v[0]), int.Parse(v[1]));
return new Int2(int.Parse(v[0], culture), int.Parse(v[1], culture));
}
return base.ConvertFrom(context, culture, value);
}
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
if (destinationType == typeof(string))
{
var v = (Int2)value;
return v.X + "," + v.Y;
return v.X.ToString(culture) + "," + v.Y.ToString(culture);
}
return base.ConvertTo(context, culture, value, destinationType);
}

View File

@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
return base.CanConvertFrom(context, sourceType);
}
/// <inheritdoc />
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return false;
}
return base.CanConvertTo(context, destinationType);
}
/// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string str)
{
string[] v = str.Split(',');
return new Int3(int.Parse(v[0]), int.Parse(v[1]), int.Parse(v[2]));
return new Int3(int.Parse(v[0], culture), int.Parse(v[1], culture), int.Parse(v[2], culture));
}
return base.ConvertFrom(context, culture, value);
}
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
if (destinationType == typeof(string))
{
var v = (Int3)value;
return v.X + "," + v.Y + "," + v.Z;
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture);
}
return base.ConvertTo(context, culture, value, destinationType);
}

View File

@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
return base.CanConvertFrom(context, sourceType);
}
/// <inheritdoc />
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return false;
}
return base.CanConvertTo(context, destinationType);
}
/// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string str)
{
string[] v = str.Split(',');
return new Int4(int.Parse(v[0]), int.Parse(v[1]), int.Parse(v[2]), int.Parse(v[3]));
return new Int4(int.Parse(v[0], culture), int.Parse(v[1], culture), int.Parse(v[2], culture), int.Parse(v[3], culture));
}
return base.ConvertFrom(context, culture, value);
}
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
if (destinationType == typeof(string))
{
var v = (Int4)value;
return v.X + "," + v.Y + "," + v.Z + "," + v.W;
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture) + "," + v.W.ToString(culture);
}
return base.ConvertTo(context, culture, value, destinationType);
}

View File

@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
return base.CanConvertFrom(context, sourceType);
}
/// <inheritdoc />
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return false;
}
return base.CanConvertTo(context, destinationType);
}
/// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string str)
{
string[] v = str.Split(',');
return new Quaternion(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]), float.Parse(v[3]));
return new Quaternion(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture), float.Parse(v[3], culture));
}
return base.ConvertFrom(context, culture, value);
}
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
if (destinationType == typeof(string))
{
var v = (Quaternion)value;
return v.X + "," + v.Y + "," + v.Z + "," + v.W;
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture) + "," + v.W.ToString(culture);
}
return base.ConvertTo(context, culture, value, destinationType);
}

View File

@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
return base.CanConvertFrom(context, sourceType);
}
/// <inheritdoc />
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return false;
}
return base.CanConvertTo(context, destinationType);
}
/// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string str)
{
string[] v = str.Split(',');
return new Vector2(float.Parse(v[0]), float.Parse(v[1]));
return new Vector2(float.Parse(v[0], culture), float.Parse(v[1], culture));
}
return base.ConvertFrom(context, culture, value);
}
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
if (destinationType == typeof(string))
{
var v = (Vector2)value;
return v.X + "," + v.Y;
return v.X.ToString(culture) + "," + v.Y.ToString(culture);
}
return base.ConvertTo(context, culture, value, destinationType);
}

View File

@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
return base.CanConvertFrom(context, sourceType);
}
/// <inheritdoc />
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return false;
}
return base.CanConvertTo(context, destinationType);
}
/// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string str)
{
string[] v = str.Split(',');
return new Vector3(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]));
return new Vector3(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture));
}
return base.ConvertFrom(context, culture, value);
}
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
if (destinationType == typeof(string))
{
var v = (Vector3)value;
return v.X + "," + v.Y + "," + v.Z;
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture);
}
return base.ConvertTo(context, culture, value, destinationType);
}

View File

@@ -18,13 +18,23 @@ namespace FlaxEngine.TypeConverters
return base.CanConvertFrom(context, sourceType);
}
/// <inheritdoc />
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return false;
}
return base.CanConvertTo(context, destinationType);
}
/// <inheritdoc />
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string str)
{
string[] v = str.Split(',');
return new Vector4(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]), float.Parse(v[3]));
return new Vector4(float.Parse(v[0], culture), float.Parse(v[1], culture), float.Parse(v[2], culture), float.Parse(v[3], culture));
}
return base.ConvertFrom(context, culture, value);
}
@@ -35,7 +45,7 @@ namespace FlaxEngine.TypeConverters
if (destinationType == typeof(string))
{
var v = (Vector4)value;
return v.X + "," + v.Y + "," + v.Z + "," + v.W;
return v.X.ToString(culture) + "," + v.Y.ToString(culture) + "," + v.Z.ToString(culture) + "," + v.W.ToString(culture);
}
return base.ConvertTo(context, culture, value, destinationType);
}

View File

@@ -619,7 +619,11 @@ Variant::Variant(Asset* v)
Variant::Variant(_MonoObject* v)
: Type(VariantType::ManagedObject, v ? mono_object_get_class(v) : nullptr)
{
AsUint = v ? mono_gchandle_new(v, true) : 0;
#if USE_NETCORE
AsUint64 = v ? MUtils::NewGCHandle(v, true) : 0;
#else
AsUint = v ? MUtils::NewGCHandle(v, true) : 0;
#endif
}
#else
@@ -957,9 +961,13 @@ Variant::~Variant()
Delete(AsDictionary);
break;
case VariantType::ManagedObject:
#if USE_MONO
#if USE_NETCORE
if (AsUint64)
MUtils::FreeGCHandle(AsUint64);
break;
#elif USE_MONO
if (AsUint)
mono_gchandle_free(AsUint);
MUtils::FreeGCHandle(AsUint);
break;
#endif
default: ;
@@ -1088,8 +1096,10 @@ Variant& Variant::operator=(const Variant& other)
AsDictionary = New<Dictionary<Variant, Variant>>(*other.AsDictionary);
break;
case VariantType::ManagedObject:
#if USE_MONO
AsUint = other.AsUint ? mono_gchandle_new(mono_gchandle_get_target(other.AsUint), true) : 0;
#if USE_NETCORE
AsUint64 = other.AsUint64 ? MUtils::NewGCHandle(MUtils::GetGCHandleTarget(other.AsUint64), true) : 0;
#elif USE_MONO
AsUint = other.AsUint ? MUtils::NewGCHandle(MUtils::GetGCHandleTarget(other.AsUint), true) : 0;
#endif
break;
case VariantType::Null:
@@ -1217,7 +1227,7 @@ bool Variant::operator==(const Variant& other) const
case VariantType::ManagedObject:
#if USE_MONO
// TODO: invoke C# Equality logic?
return AsUint == other.AsUint || mono_gchandle_get_target(AsUint) == mono_gchandle_get_target(other.AsUint);
return AsUint == other.AsUint || MUtils::GetGCHandleTarget(AsUint) == MUtils::GetGCHandleTarget(other.AsUint);
#endif
default:
return false;
@@ -1308,8 +1318,10 @@ Variant::operator bool() const
case VariantType::Asset:
return AsAsset != nullptr;
case VariantType::ManagedObject:
#if USE_MONO
return AsUint != 0 && mono_gchandle_get_target(AsUint) != nullptr;
#if USE_NETCORE
return AsUint64 != 0 && MUtils::GetGCHandleTarget(AsUint64) != nullptr;
#elif USE_MONO
return AsUint != 0 && MUtils::GetGCHandleTarget(AsUint) != nullptr;
#endif
default:
return false;
@@ -1578,8 +1590,10 @@ Variant::operator void*() const
case VariantType::Blob:
return AsBlob.Data;
case VariantType::ManagedObject:
#if USE_MONO
return AsUint ? mono_gchandle_get_target(AsUint) : nullptr;
#if USE_NETCORE
return AsUint64 ? MUtils::GetGCHandleTarget(AsUint64) : nullptr;
#elif USE_MONO
return AsUint ? MUtils::GetGCHandleTarget(AsUint) : nullptr;
#endif
default:
return nullptr;
@@ -1623,8 +1637,10 @@ Variant::operator ScriptingObject*() const
Variant::operator _MonoObject*() const
{
#if USE_MONO
return Type.Type == VariantType::ManagedObject && AsUint ? mono_gchandle_get_target(AsUint) : nullptr;
#if USE_NETCORE
return Type.Type == VariantType::ManagedObject && AsUint64 ? MUtils::GetGCHandleTarget(AsUint64) : nullptr;
#elif USE_MONO
return Type.Type == VariantType::ManagedObject && AsUint ? MUtils::GetGCHandleTarget(AsUint) : nullptr;
#else
return nullptr;
#endif
@@ -2337,9 +2353,14 @@ void Variant::SetType(const VariantType& type)
Delete(AsDictionary);
break;
case VariantType::ManagedObject:
#if USE_MONO
#if USE_NETCORE
if (AsUint64)
MUtils::FreeGCHandle(AsUint64);
break;
#elif USE_MONO
if (AsUint)
mono_gchandle_free(AsUint);
MUtils::FreeGCHandle(AsUint);
break;
#endif
break;
default: ;
@@ -2447,9 +2468,14 @@ void Variant::SetType(VariantType&& type)
Delete(AsDictionary);
break;
case VariantType::ManagedObject:
#if USE_MONO
#if USE_NETCORE
if (AsUint64)
MUtils::FreeGCHandle(AsUint64);
break;
#elif USE_MONO
if (AsUint)
mono_gchandle_free(AsUint);
MUtils::FreeGCHandle(AsUint);
break;
#endif
break;
default: ;
@@ -2632,7 +2658,11 @@ void Variant::SetManagedObject(_MonoObject* object)
{
if (Type.Type != VariantType::ManagedObject)
SetType(VariantType(VariantType::ManagedObject, mono_object_get_class(object)));
AsUint = mono_gchandle_new(object, true);
#if USE_NETCORE
AsUint64 = MUtils::NewGCHandle(object, true);
#else
AsUint = MUtils::NewGCHandle(object, true);
#endif
}
else
{
@@ -2751,8 +2781,10 @@ String Variant::ToString() const
case VariantType::Typename:
return String((const char*)AsBlob.Data, AsBlob.Length ? AsBlob.Length - 1 : 0);
case VariantType::ManagedObject:
#if USE_MONO
return AsUint ? String(MUtils::ToString(mono_object_to_string(mono_gchandle_get_target(AsUint), nullptr))) : TEXT("null");
#if USE_NETCORE
return AsUint64 ? String(MUtils::ToString(mono_object_to_string(MUtils::GetGCHandleTarget(AsUint64), nullptr))) : TEXT("null");
#elif USE_MONO
return AsUint ? String(MUtils::ToString(mono_object_to_string(MUtils::GetGCHandleTarget(AsUint), nullptr))) : TEXT("null");
#endif
default:
return String::Empty;
@@ -3671,7 +3703,12 @@ void Variant::AllocStructure()
Platform::MemoryCopy(AsBlob.Data, data, AsBlob.Length);
#else
Type.Type = VariantType::ManagedObject;
AsUint = mono_gchandle_new(instance, true);
#if USE_NETCORE
AsUint64 = MUtils::NewGCHandle(instance, true);
#else
AsUint = MUtils::NewGCHandle(instance, true);
#endif
#endif
}
else
@@ -3763,8 +3800,10 @@ uint32 GetHash(const Variant& key)
case VariantType::Typename:
return GetHash((const char*)key.AsBlob.Data);
case VariantType::ManagedObject:
#if USE_MONO
return key.AsUint ? (uint32)mono_object_hash(mono_gchandle_get_target(key.AsUint)) : 0;
#if USE_NETCORE
return key.AsUint64 ? (uint32)mono_object_hash(MUtils::GetGCHandleTarget(key.AsUint64)) : 0;
#elif USE_MONO
return key.AsUint ? (uint32)mono_object_hash(MUtils::GetGCHandleTarget(key.AsUint)) : 0;
#endif
default:
return 0;