|
|
|
|
@@ -23,12 +23,10 @@
|
|
|
|
|
#include "Engine/Scripting/ScriptingObject.h"
|
|
|
|
|
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
|
|
|
|
#include "Engine/Scripting/ManagedCLR/MCore.h"
|
|
|
|
|
#include "Engine/Scripting/ManagedCLR/MCore.h"
|
|
|
|
|
#include "Engine/Scripting/ManagedCLR/MUtils.h"
|
|
|
|
|
#include "Engine/Utilities/Crc.h"
|
|
|
|
|
#include "Engine/Utilities/StringConverter.h"
|
|
|
|
|
#if USE_MONO
|
|
|
|
|
#include <mono/metadata/object.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
@@ -108,15 +106,14 @@ VariantType::VariantType(Types type, const StringAnsiView& typeName)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VariantType::VariantType(Types type, _MonoClass* klass)
|
|
|
|
|
VariantType::VariantType(Types type, MClass* klass)
|
|
|
|
|
{
|
|
|
|
|
Type = type;
|
|
|
|
|
TypeName = nullptr;
|
|
|
|
|
#if USE_MONO
|
|
|
|
|
#if USE_CSHARP
|
|
|
|
|
if (klass)
|
|
|
|
|
{
|
|
|
|
|
MString typeName;
|
|
|
|
|
MUtils::GetClassFullname(klass, typeName);
|
|
|
|
|
const StringAnsi& typeName = klass->GetFullName();
|
|
|
|
|
const int32 length = typeName.Length();
|
|
|
|
|
TypeName = static_cast<char*>(Allocator::Allocate(length + 1));
|
|
|
|
|
Platform::MemoryCopy(TypeName, typeName.Get(), length);
|
|
|
|
|
@@ -166,7 +163,7 @@ VariantType::VariantType(const StringAnsiView& typeName)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Try using managed class
|
|
|
|
|
#if USE_MONO
|
|
|
|
|
#if USE_CSHARP
|
|
|
|
|
if (const auto mclass = Scripting::FindClass(typeName))
|
|
|
|
|
{
|
|
|
|
|
new(this) VariantType(ManagedObject, typeName);
|
|
|
|
|
@@ -615,21 +612,21 @@ Variant::Variant(Asset* v)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if USE_MONO
|
|
|
|
|
#if USE_CSHARP
|
|
|
|
|
|
|
|
|
|
Variant::Variant(_MonoObject* v)
|
|
|
|
|
: Type(VariantType::ManagedObject, v ? mono_object_get_class(v) : nullptr)
|
|
|
|
|
Variant::Variant(MObject* v)
|
|
|
|
|
: Type(VariantType::ManagedObject, v ? MCore::Object::GetClass(v) : nullptr)
|
|
|
|
|
{
|
|
|
|
|
#if USE_NETCORE
|
|
|
|
|
AsUint64 = v ? MUtils::NewGCHandle(v, true) : 0;
|
|
|
|
|
AsUint64 = v ? MCore::GCHandle::New(v, true) : 0;
|
|
|
|
|
#else
|
|
|
|
|
AsUint = v ? MUtils::NewGCHandle(v, true) : 0;
|
|
|
|
|
AsUint = v ? MCore::GCHandle::New(v, true) : 0;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
Variant::Variant(_MonoObject* v)
|
|
|
|
|
Variant::Variant(MObject* v)
|
|
|
|
|
: Type(VariantType::ManagedObject, nullptr)
|
|
|
|
|
{
|
|
|
|
|
AsUint = 0;
|
|
|
|
|
@@ -964,13 +961,12 @@ Variant::~Variant()
|
|
|
|
|
case VariantType::ManagedObject:
|
|
|
|
|
#if USE_NETCORE
|
|
|
|
|
if (AsUint64)
|
|
|
|
|
MUtils::FreeGCHandle(AsUint64);
|
|
|
|
|
break;
|
|
|
|
|
MCore::GCHandle::Free(AsUint64);
|
|
|
|
|
#elif USE_MONO
|
|
|
|
|
if (AsUint)
|
|
|
|
|
MUtils::FreeGCHandle(AsUint);
|
|
|
|
|
break;
|
|
|
|
|
MCore::GCHandle::Free(AsUint);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
default: ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -1098,9 +1094,9 @@ Variant& Variant::operator=(const Variant& other)
|
|
|
|
|
break;
|
|
|
|
|
case VariantType::ManagedObject:
|
|
|
|
|
#if USE_NETCORE
|
|
|
|
|
AsUint64 = other.AsUint64 ? MUtils::NewGCHandle(MUtils::GetGCHandleTarget(other.AsUint64), true) : 0;
|
|
|
|
|
AsUint64 = other.AsUint64 ? MCore::GCHandle::New(MCore::GCHandle::GetTarget(other.AsUint64), true) : 0;
|
|
|
|
|
#elif USE_MONO
|
|
|
|
|
AsUint = other.AsUint ? MUtils::NewGCHandle(MUtils::GetGCHandleTarget(other.AsUint), true) : 0;
|
|
|
|
|
AsUint = other.AsUint ? MCore::GCHandle::New(MCore::GCHandle::GetTarget(other.AsUint), true) : 0;
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
case VariantType::Null:
|
|
|
|
|
@@ -1226,9 +1222,13 @@ bool Variant::operator==(const Variant& other) const
|
|
|
|
|
return false;
|
|
|
|
|
return AsBlob.Length == other.AsBlob.Length && StringUtils::Compare(static_cast<const char*>(AsBlob.Data), static_cast<const char*>(other.AsBlob.Data), AsBlob.Length - 1) == 0;
|
|
|
|
|
case VariantType::ManagedObject:
|
|
|
|
|
#if USE_MONO
|
|
|
|
|
#if USE_NETCORE
|
|
|
|
|
// TODO: invoke C# Equality logic?
|
|
|
|
|
return AsUint == other.AsUint || MUtils::GetGCHandleTarget(AsUint) == MUtils::GetGCHandleTarget(other.AsUint);
|
|
|
|
|
return AsUint64 == other.AsUint64 || MCore::GCHandle::GetTarget(AsUint64) == MCore::GCHandle::GetTarget(other.AsUint64);
|
|
|
|
|
#elif USE_MONO
|
|
|
|
|
return AsUint == other.AsUint || MCore::GCHandle::GetTarget(AsUint) == MCore::GCHandle::GetTarget(other.AsUint);
|
|
|
|
|
#else
|
|
|
|
|
return nullptr;
|
|
|
|
|
#endif
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
@@ -1320,9 +1320,11 @@ Variant::operator bool() const
|
|
|
|
|
return AsAsset != nullptr;
|
|
|
|
|
case VariantType::ManagedObject:
|
|
|
|
|
#if USE_NETCORE
|
|
|
|
|
return AsUint64 != 0 && MUtils::GetGCHandleTarget(AsUint64) != nullptr;
|
|
|
|
|
return AsUint64 != 0 && MCore::GCHandle::GetTarget(AsUint64) != nullptr;
|
|
|
|
|
#elif USE_MONO
|
|
|
|
|
return AsUint != 0 && MUtils::GetGCHandleTarget(AsUint) != nullptr;
|
|
|
|
|
return AsUint != 0 && MCore::GCHandle::GetTarget(AsUint) != nullptr;
|
|
|
|
|
#else
|
|
|
|
|
return nullptr;
|
|
|
|
|
#endif
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
@@ -1592,9 +1594,11 @@ Variant::operator void*() const
|
|
|
|
|
return AsBlob.Data;
|
|
|
|
|
case VariantType::ManagedObject:
|
|
|
|
|
#if USE_NETCORE
|
|
|
|
|
return AsUint64 ? MUtils::GetGCHandleTarget(AsUint64) : nullptr;
|
|
|
|
|
return AsUint64 ? MCore::GCHandle::GetTarget(AsUint64) : nullptr;
|
|
|
|
|
#elif USE_MONO
|
|
|
|
|
return AsUint ? MUtils::GetGCHandleTarget(AsUint) : nullptr;
|
|
|
|
|
return AsUint ? MCore::GCHandle::GetTarget(AsUint) : nullptr;
|
|
|
|
|
#else
|
|
|
|
|
return nullptr;
|
|
|
|
|
#endif
|
|
|
|
|
default:
|
|
|
|
|
return nullptr;
|
|
|
|
|
@@ -1636,12 +1640,12 @@ Variant::operator ScriptingObject*() const
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Variant::operator _MonoObject*() const
|
|
|
|
|
Variant::operator MObject*() const
|
|
|
|
|
{
|
|
|
|
|
#if USE_NETCORE
|
|
|
|
|
return Type.Type == VariantType::ManagedObject && AsUint64 ? MUtils::GetGCHandleTarget(AsUint64) : nullptr;
|
|
|
|
|
return Type.Type == VariantType::ManagedObject && AsUint64 ? MCore::GCHandle::GetTarget(AsUint64) : nullptr;
|
|
|
|
|
#elif USE_MONO
|
|
|
|
|
return Type.Type == VariantType::ManagedObject && AsUint ? MUtils::GetGCHandleTarget(AsUint) : nullptr;
|
|
|
|
|
return Type.Type == VariantType::ManagedObject && AsUint ? MCore::GCHandle::GetTarget(AsUint) : nullptr;
|
|
|
|
|
#else
|
|
|
|
|
return nullptr;
|
|
|
|
|
#endif
|
|
|
|
|
@@ -2356,12 +2360,10 @@ void Variant::SetType(const VariantType& type)
|
|
|
|
|
case VariantType::ManagedObject:
|
|
|
|
|
#if USE_NETCORE
|
|
|
|
|
if (AsUint64)
|
|
|
|
|
MUtils::FreeGCHandle(AsUint64);
|
|
|
|
|
break;
|
|
|
|
|
MCore::GCHandle::Free(AsUint64);
|
|
|
|
|
#elif USE_MONO
|
|
|
|
|
if (AsUint)
|
|
|
|
|
MUtils::FreeGCHandle(AsUint);
|
|
|
|
|
break;
|
|
|
|
|
MCore::GCHandle::Free(AsUint);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
default: ;
|
|
|
|
|
@@ -2471,12 +2473,10 @@ void Variant::SetType(VariantType&& type)
|
|
|
|
|
case VariantType::ManagedObject:
|
|
|
|
|
#if USE_NETCORE
|
|
|
|
|
if (AsUint64)
|
|
|
|
|
MUtils::FreeGCHandle(AsUint64);
|
|
|
|
|
break;
|
|
|
|
|
MCore::GCHandle::Free(AsUint64);
|
|
|
|
|
#elif USE_MONO
|
|
|
|
|
if (AsUint)
|
|
|
|
|
MUtils::FreeGCHandle(AsUint);
|
|
|
|
|
break;
|
|
|
|
|
MCore::GCHandle::Free(AsUint);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
default: ;
|
|
|
|
|
@@ -2652,17 +2652,17 @@ void Variant::SetObject(ScriptingObject* object)
|
|
|
|
|
object->Deleted.Bind<Variant, &Variant::OnObjectDeleted>(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Variant::SetManagedObject(_MonoObject* object)
|
|
|
|
|
void Variant::SetManagedObject(MObject* object)
|
|
|
|
|
{
|
|
|
|
|
#if USE_MONO
|
|
|
|
|
#if USE_CSHARP
|
|
|
|
|
if (object)
|
|
|
|
|
{
|
|
|
|
|
if (Type.Type != VariantType::ManagedObject)
|
|
|
|
|
SetType(VariantType(VariantType::ManagedObject, mono_object_get_class(object)));
|
|
|
|
|
SetType(VariantType(VariantType::ManagedObject, MCore::Object::GetClass(object)));
|
|
|
|
|
#if USE_NETCORE
|
|
|
|
|
AsUint64 = MUtils::NewGCHandle(object, true);
|
|
|
|
|
AsUint64 = MCore::GCHandle::New(object, true);
|
|
|
|
|
#else
|
|
|
|
|
AsUint = MUtils::NewGCHandle(object, true);
|
|
|
|
|
AsUint = MCore::GCHandle::New(object, true);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
@@ -2783,9 +2783,11 @@ String Variant::ToString() const
|
|
|
|
|
return String((const char*)AsBlob.Data, AsBlob.Length ? AsBlob.Length - 1 : 0);
|
|
|
|
|
case VariantType::ManagedObject:
|
|
|
|
|
#if USE_NETCORE
|
|
|
|
|
return AsUint64 ? String(MUtils::ToString(mono_object_to_string(MUtils::GetGCHandleTarget(AsUint64), nullptr))) : TEXT("null");
|
|
|
|
|
return AsUint64 ? String(MUtils::ToString(MCore::Object::ToString(MCore::GCHandle::GetTarget(AsUint64)))) : TEXT("null");
|
|
|
|
|
#elif USE_MONO
|
|
|
|
|
return AsUint ? String(MUtils::ToString(mono_object_to_string(MUtils::GetGCHandleTarget(AsUint), nullptr))) : TEXT("null");
|
|
|
|
|
return AsUint ? String(MUtils::ToString(MCore::Object::ToString(MCore::GCHandle::GetTarget(AsUint)))) : TEXT("null");
|
|
|
|
|
#else
|
|
|
|
|
return String::Empty;
|
|
|
|
|
#endif
|
|
|
|
|
default:
|
|
|
|
|
return String::Empty;
|
|
|
|
|
@@ -3688,17 +3690,17 @@ void Variant::AllocStructure()
|
|
|
|
|
AsBlob.Data = Allocator::Allocate(AsBlob.Length);
|
|
|
|
|
*((int16*)AsBlob.Data) = 0;
|
|
|
|
|
}
|
|
|
|
|
#if USE_MONO
|
|
|
|
|
#if USE_CSHARP
|
|
|
|
|
else if (const auto mclass = Scripting::FindClass(typeName))
|
|
|
|
|
{
|
|
|
|
|
// Fallback to C#-only types
|
|
|
|
|
MCore::AttachThread();
|
|
|
|
|
auto instance = mclass->CreateInstance();
|
|
|
|
|
MCore::Thread::Attach();
|
|
|
|
|
MObject* instance = mclass->CreateInstance();
|
|
|
|
|
if (instance)
|
|
|
|
|
{
|
|
|
|
|
#if 0
|
|
|
|
|
void* data = mono_object_unbox(instance);
|
|
|
|
|
int32 instanceSize = mono_class_instance_size(mclass->GetNative());
|
|
|
|
|
void* data = MCore::Object::Unbox(instance);
|
|
|
|
|
int32 instanceSize = mclass->GetInstanceSize();
|
|
|
|
|
AsBlob.Length = instanceSize - (int32)((uintptr)data - (uintptr)instance);
|
|
|
|
|
AsBlob.Data = Allocator::Allocate(AsBlob.Length);
|
|
|
|
|
Platform::MemoryCopy(AsBlob.Data, data, AsBlob.Length);
|
|
|
|
|
@@ -3706,9 +3708,9 @@ void Variant::AllocStructure()
|
|
|
|
|
Type.Type = VariantType::ManagedObject;
|
|
|
|
|
|
|
|
|
|
#if USE_NETCORE
|
|
|
|
|
AsUint64 = MUtils::NewGCHandle(instance, true);
|
|
|
|
|
AsUint64 = MCore::GCHandle::New(instance, true);
|
|
|
|
|
#else
|
|
|
|
|
AsUint = MUtils::NewGCHandle(instance, true);
|
|
|
|
|
AsUint = MCore::GCHandle::New(instance, true);
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
@@ -3802,9 +3804,11 @@ uint32 GetHash(const Variant& key)
|
|
|
|
|
return GetHash((const char*)key.AsBlob.Data);
|
|
|
|
|
case VariantType::ManagedObject:
|
|
|
|
|
#if USE_NETCORE
|
|
|
|
|
return key.AsUint64 ? (uint32)mono_object_hash(MUtils::GetGCHandleTarget(key.AsUint64)) : 0;
|
|
|
|
|
return key.AsUint64 ? (uint32)MCore::Object::GetHashCode(MCore::GCHandle::GetTarget(key.AsUint64)) : 0;
|
|
|
|
|
#elif USE_MONO
|
|
|
|
|
return key.AsUint ? (uint32)mono_object_hash(MUtils::GetGCHandleTarget(key.AsUint)) : 0;
|
|
|
|
|
return key.AsUint ? (uint32)MCore::Object::GetHashCode(MCore::GCHandle::GetTarget(key.AsUint)) : 0;
|
|
|
|
|
#else
|
|
|
|
|
return 0;
|
|
|
|
|
#endif
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
|