_wip
This commit is contained in:
@@ -1332,7 +1332,7 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp
|
||||
}
|
||||
|
||||
// Unbox result
|
||||
result = MUtils::UnboxVariant(resultObject);
|
||||
result = MUtils::UnboxVariant(resultObject, true);
|
||||
|
||||
#if 0
|
||||
// Helper method invocations logging
|
||||
@@ -1366,7 +1366,7 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp
|
||||
paramValue.SetString(MUtils::ToString((MString*)param));
|
||||
break;
|
||||
case VariantType::Object:
|
||||
paramValue = MUtils::UnboxVariant((MObject*)param);
|
||||
paramValue = MUtils::UnboxVariant((MObject*)param, true);
|
||||
break;
|
||||
case VariantType::Structure:
|
||||
{
|
||||
@@ -1383,7 +1383,7 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp
|
||||
{
|
||||
MType* paramType = mMethod->GetParameterType(paramIdx);
|
||||
if (MCore::Type::IsReference(paramType) && MCore::Type::GetType(paramType) == MTypes::Object)
|
||||
paramValue = MUtils::UnboxVariant((MObject*)outParams[paramIdx]);
|
||||
paramValue = MUtils::UnboxVariant((MObject*)outParams[paramIdx], true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1527,7 +1527,7 @@ bool ManagedBinaryModule::GetFieldValue(void* field, const Variant& instance, Va
|
||||
const auto mField = (MField*)field;
|
||||
resultObject = mField->GetValueBoxed(instanceObject);
|
||||
}
|
||||
result = MUtils::UnboxVariant(resultObject);
|
||||
result = MUtils::UnboxVariant(resultObject, true);
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
|
||||
@@ -304,7 +304,7 @@ MTypeObject* MUtils::BoxVariantType(const VariantType& value)
|
||||
return INTERNAL_TYPE_GET_OBJECT(mType);
|
||||
}
|
||||
|
||||
Variant MUtils::UnboxVariant(MObject* value)
|
||||
Variant MUtils::UnboxVariant(MObject* value, bool releaseHandle)
|
||||
{
|
||||
if (value == nullptr)
|
||||
return Variant::Null;
|
||||
@@ -345,7 +345,11 @@ Variant MUtils::UnboxVariant(MObject* value)
|
||||
case MTypes::R8:
|
||||
return *static_cast<double*>(unboxed);
|
||||
case MTypes::String:
|
||||
{
|
||||
if (releaseHandle)
|
||||
MUtils::FreeManaged<String>(value);
|
||||
return Variant(MUtils::ToString((MString*)value));
|
||||
}
|
||||
case MTypes::Ptr:
|
||||
return *static_cast<void**>(unboxed);
|
||||
case MTypes::ValueType:
|
||||
@@ -400,6 +404,8 @@ Variant MUtils::UnboxVariant(MObject* value)
|
||||
{
|
||||
Variant v;
|
||||
v.SetBlob(ptr, MCore::Array::GetLength((MArray*)value));
|
||||
if (releaseHandle)
|
||||
MUtils::FreeManaged<Array<byte>>(value);
|
||||
return v;
|
||||
}
|
||||
const StringAnsiView fullname = arrayClass->GetFullName();
|
||||
@@ -508,7 +514,10 @@ Variant MUtils::UnboxVariant(MObject* value)
|
||||
{
|
||||
// Array of Objects
|
||||
for (int32 i = 0; i < array.Count(); i++)
|
||||
array[i] = UnboxVariant(((MObject**)ptr)[i]);
|
||||
array[i] = UnboxVariant(((MObject**)ptr)[i], releaseHandle);
|
||||
|
||||
if (releaseHandle)
|
||||
MUtils::FreeManaged<Array<byte>>(value);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
@@ -527,10 +536,13 @@ Variant MUtils::UnboxVariant(MObject* value)
|
||||
{
|
||||
MObject* keyManaged = managedKeysPtr[i];
|
||||
MObject* valueManaged = managed.GetValue(keyManaged);
|
||||
native.Add(UnboxVariant(keyManaged), UnboxVariant(valueManaged));
|
||||
native.Add(UnboxVariant(keyManaged, releaseHandle), UnboxVariant(valueManaged, releaseHandle));
|
||||
}
|
||||
Variant v(MoveTemp(native));
|
||||
v.Type.SetTypeName(klass->GetFullName());
|
||||
if (releaseHandle)
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&value);
|
||||
//MUtils::FreeManaged<Dictionary<byte, byte>>(value);
|
||||
return v;
|
||||
}
|
||||
break;
|
||||
@@ -548,6 +560,8 @@ Variant MUtils::UnboxVariant(MObject* value)
|
||||
v.Type = MoveTemp(VariantType(VariantType::Enum, fullname));
|
||||
// TODO: what about 64-bit enum? use enum size with memcpy
|
||||
v.AsUint64 = *static_cast<uint32*>(MCore::Object::Unbox(value));
|
||||
if (releaseHandle)
|
||||
MUtils::FreeManaged<byte>(value);
|
||||
return v;
|
||||
}
|
||||
if (klass->IsValueType())
|
||||
@@ -565,10 +579,12 @@ Variant MUtils::UnboxVariant(MObject* value)
|
||||
type.Struct.Unbox(v.AsBlob.Data, value);
|
||||
return v;
|
||||
}
|
||||
return Variant(value);
|
||||
}
|
||||
|
||||
return Variant(value);
|
||||
auto variant = Variant(value);
|
||||
if (releaseHandle)
|
||||
MUtils::FreeManaged<byte>(value);
|
||||
return variant;
|
||||
}
|
||||
|
||||
MObject* MUtils::BoxVariant(const Variant& value)
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace MUtils
|
||||
extern FLAXENGINE_API MTypeObject* BoxScriptingTypeHandle(const ScriptingTypeHandle& value);
|
||||
extern FLAXENGINE_API VariantType UnboxVariantType(MType* type);
|
||||
extern FLAXENGINE_API MTypeObject* BoxVariantType(const VariantType& value);
|
||||
extern FLAXENGINE_API Variant UnboxVariant(MObject* value);
|
||||
extern FLAXENGINE_API Variant UnboxVariant(MObject* value, bool releaseHandle = false);
|
||||
extern FLAXENGINE_API MObject* BoxVariant(const Variant& value);
|
||||
}
|
||||
|
||||
@@ -51,8 +51,41 @@ struct MConverter
|
||||
void Unbox(T& result, MObject* data);
|
||||
void ToManagedArray(MArray* result, const Span<T>& data);
|
||||
void ToNativeArray(Span<T>& result, const MArray* data);
|
||||
void FreeManaged(MObject* data);
|
||||
};
|
||||
|
||||
#if USE_NETCORE
|
||||
// Special case for boolean values, the handles are fixed and should not be removed
|
||||
template<>
|
||||
struct MConverter<bool>
|
||||
{
|
||||
MObject* Box(const bool& data, const MClass* klass)
|
||||
{
|
||||
return MCore::Object::Box((void*)&data, klass);
|
||||
}
|
||||
|
||||
void Unbox(bool& result, MObject* data)
|
||||
{
|
||||
if (data)
|
||||
Platform::MemoryCopy(&result, MCore::Object::Unbox(data), sizeof(bool));
|
||||
}
|
||||
|
||||
void ToManagedArray(MArray* result, const Span<bool>& data)
|
||||
{
|
||||
Platform::MemoryCopy(MCore::Array::GetAddress(result), data.Get(), data.Length() * sizeof(bool));
|
||||
}
|
||||
|
||||
void ToNativeArray(Span<bool>& result, const MArray* data)
|
||||
{
|
||||
Platform::MemoryCopy(result.Get(), MCore::Array::GetAddress(data), result.Length() * sizeof(bool));
|
||||
}
|
||||
|
||||
void FreeManaged(MObject* data)
|
||||
{
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// Converter for POD types (that can use raw memory copy).
|
||||
template<typename T>
|
||||
struct MConverter<T, typename TEnableIf<TAnd<TIsPODType<T>, TNot<TIsBaseOf<class ScriptingObject, typename TRemovePointer<T>::Type>>>::Value>::Type>
|
||||
@@ -77,6 +110,11 @@ struct MConverter<T, typename TEnableIf<TAnd<TIsPODType<T>, TNot<TIsBaseOf<class
|
||||
{
|
||||
Platform::MemoryCopy(result.Get(), MCore::Array::GetAddress(data), result.Length() * sizeof(T));
|
||||
}
|
||||
|
||||
void FreeManaged(MObject* data)
|
||||
{
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&data);
|
||||
}
|
||||
};
|
||||
|
||||
// Converter for String.
|
||||
@@ -85,22 +123,22 @@ struct MConverter<String>
|
||||
{
|
||||
MObject* Box(const String& data, const MClass* klass)
|
||||
{
|
||||
#if USE_NETCORE
|
||||
/*#if USE_NETCORE
|
||||
MString* str = MUtils::ToString(data);
|
||||
return MCore::Object::Box(str, klass);
|
||||
#else
|
||||
#else*/
|
||||
return (MObject*)MUtils::ToString(data);
|
||||
#endif
|
||||
//#endif
|
||||
}
|
||||
|
||||
void Unbox(String& result, MObject* data)
|
||||
{
|
||||
#if USE_NETCORE
|
||||
/*#if USE_NETCORE
|
||||
MString* str = (MString*)MCore::Object::Unbox(data);
|
||||
result = MUtils::ToString(str);
|
||||
#else
|
||||
#else*/
|
||||
result = MUtils::ToString((MString*)data);
|
||||
#endif
|
||||
//#endif
|
||||
}
|
||||
|
||||
void ToManagedArray(MArray* result, const Span<String>& data)
|
||||
@@ -120,6 +158,13 @@ struct MConverter<String>
|
||||
for (int32 i = 0; i < result.Length(); i++)
|
||||
MUtils::ToString(dataPtr[i], result.Get()[i]);
|
||||
}
|
||||
|
||||
void FreeManaged(MObject* data)
|
||||
{
|
||||
//MString* str = (MString*)MCore::Object::Unbox(data);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&str);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&data);
|
||||
}
|
||||
};
|
||||
|
||||
// Converter for StringAnsi.
|
||||
@@ -153,6 +198,11 @@ struct MConverter<StringAnsi>
|
||||
for (int32 i = 0; i < result.Length(); i++)
|
||||
MUtils::ToString(dataPtr[i], result.Get()[i]);
|
||||
}
|
||||
|
||||
void FreeManaged(MObject* data)
|
||||
{
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&data);
|
||||
}
|
||||
};
|
||||
|
||||
// Converter for StringView.
|
||||
@@ -186,6 +236,11 @@ struct MConverter<StringView>
|
||||
for (int32 i = 0; i < result.Length(); i++)
|
||||
MUtils::ToString(dataPtr[i], result.Get()[i]);
|
||||
}
|
||||
|
||||
void FreeManaged(MObject* data)
|
||||
{
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&data);
|
||||
}
|
||||
};
|
||||
|
||||
// Converter for Variant.
|
||||
@@ -219,6 +274,10 @@ struct MConverter<Variant>
|
||||
for (int32 i = 0; i < result.Length(); i++)
|
||||
result.Get()[i] = MUtils::UnboxVariant(dataPtr[i]);
|
||||
}
|
||||
|
||||
void FreeManaged(MObject* data)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// Converter for Scripting Objects (collection of pointers).
|
||||
@@ -252,6 +311,10 @@ struct MConverter<T*, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Va
|
||||
for (int32 i = 0; i < result.Length(); i++)
|
||||
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
||||
}
|
||||
|
||||
void FreeManaged(MObject* data)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// Converter for Scripting Objects (collection of values).
|
||||
@@ -273,6 +336,10 @@ struct MConverter<T, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Val
|
||||
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects, data.Length()));
|
||||
Allocator::Free(objects);
|
||||
}
|
||||
|
||||
void FreeManaged(MObject* data)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// Converter for ScriptingObject References.
|
||||
@@ -309,6 +376,10 @@ struct MConverter<ScriptingObjectReference<T>>
|
||||
for (int32 i = 0; i < result.Length(); i++)
|
||||
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
||||
}
|
||||
|
||||
void FreeManaged(MObject* data)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// Converter for Asset References.
|
||||
@@ -345,6 +416,10 @@ struct MConverter<AssetReference<T>>
|
||||
for (int32 i = 0; i < result.Length(); i++)
|
||||
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
||||
}
|
||||
|
||||
void FreeManaged(MObject* data)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: use MarshalAs=Guid on SoftAssetReference to pass guid over bindings and not load asset in glue code
|
||||
@@ -370,6 +445,10 @@ struct MConverter<SoftAssetReference<T>>
|
||||
for (int32 i = 0; i < result.Length(); i++)
|
||||
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
||||
}
|
||||
|
||||
void FreeManaged(MObject* data)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// Converter for Array.
|
||||
@@ -395,6 +474,10 @@ struct MConverter<Array<T>>
|
||||
Span<T> resultSpan(result.Get(), length);
|
||||
converter.ToNativeArray(resultSpan, array);
|
||||
}
|
||||
|
||||
void FreeManaged(MObject* data)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
namespace MUtils
|
||||
@@ -435,6 +518,7 @@ namespace MUtils
|
||||
/// <summary>
|
||||
/// Unboxes MObject to the native value of the given type.
|
||||
/// </summary>
|
||||
///
|
||||
template<class T>
|
||||
T Unbox(MObject* object)
|
||||
{
|
||||
@@ -444,6 +528,32 @@ namespace MUtils
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unboxes MObject to the native value of the given type.
|
||||
/// </summary>
|
||||
/// <param name="object">The object.</param>
|
||||
/// <param name="releaseHandle">True if boxed managed handle should be released.</param>
|
||||
template<class T>
|
||||
T Unbox(MObject* object, bool releaseHandle)
|
||||
{
|
||||
MConverter<T> converter;
|
||||
T result;
|
||||
converter.Unbox(result, object);
|
||||
if (releaseHandle)
|
||||
converter.FreeManaged(object);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases the managed resources of a boxed object.
|
||||
/// </summary>
|
||||
template<class T>
|
||||
void FreeManaged(MObject* object)
|
||||
{
|
||||
MConverter<T> converter;
|
||||
converter.FreeManaged(object);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Links managed array data to the unmanaged BytesContainer.
|
||||
/// </summary>
|
||||
|
||||
@@ -883,7 +883,6 @@ bool MAssembly::LoadCorlib()
|
||||
|
||||
bool MAssembly::LoadImage(const String& assemblyPath, const StringView& nativePath)
|
||||
{
|
||||
// TODO: Use new hostfxr delegate load_assembly_bytes? (.NET 8+)
|
||||
// Open .Net assembly
|
||||
static void* LoadAssemblyImagePtr = GetStaticMethodPointer(TEXT("LoadAssemblyImage"));
|
||||
_handle = CallStaticMethod<void*, const Char*>(LoadAssemblyImagePtr, assemblyPath.Get());
|
||||
|
||||
Reference in New Issue
Block a user