|
|
|
|
@@ -49,9 +49,18 @@ struct MConverter
|
|
|
|
|
{
|
|
|
|
|
MObject* Box(const T& data, const MClass* klass);
|
|
|
|
|
void Unbox(T& result, MObject* data);
|
|
|
|
|
void FreeManaged(MObject* data);
|
|
|
|
|
void ToManagedArray(MArray* result, const Span<T>& data);
|
|
|
|
|
void ToNativeArray(Span<T>& result, const MArray* data);
|
|
|
|
|
void FreeManaged(MObject* data);
|
|
|
|
|
void FreeManagedArray(MArray* array);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Simple array used to pass arrays of blittable data between managed and unmanaged side.
|
|
|
|
|
template<typename T>
|
|
|
|
|
struct NativeArray
|
|
|
|
|
{
|
|
|
|
|
T* data;
|
|
|
|
|
int32 length;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#if USE_NETCORE
|
|
|
|
|
@@ -70,6 +79,10 @@ struct MConverter<bool>
|
|
|
|
|
Platform::MemoryCopy(&result, MCore::Object::Unbox(data), sizeof(bool));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeManaged(MObject* data)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ToManagedArray(MArray* result, const Span<bool>& data)
|
|
|
|
|
{
|
|
|
|
|
Platform::MemoryCopy(MCore::Array::GetAddress(result), data.Get(), data.Length() * sizeof(bool));
|
|
|
|
|
@@ -80,8 +93,10 @@ struct MConverter<bool>
|
|
|
|
|
Platform::MemoryCopy(result.Get(), MCore::Array::GetAddress(data), result.Length() * sizeof(bool));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeManaged(MObject* data)
|
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
|
|
|
{
|
|
|
|
|
MCore::Array::Free(array);
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
@@ -115,6 +130,12 @@ struct MConverter<T, typename TEnableIf<TAnd<TIsPODType<T>, TNot<TIsBaseOf<class
|
|
|
|
|
{
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
|
|
|
{
|
|
|
|
|
MCore::Array::Free(array);
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Converter for String.
|
|
|
|
|
@@ -163,7 +184,17 @@ struct MConverter<String>
|
|
|
|
|
{
|
|
|
|
|
//MString* str = (MString*)MCore::Object::Unbox(data);
|
|
|
|
|
//MCore::GCHandle::Free(*(MGCHandle*)&str);
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&data);
|
|
|
|
|
MCore::String::Free((MString*)data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
|
|
|
{
|
|
|
|
|
MString** dataPtr = MCore::Array::GetAddress<MString*>(array);
|
|
|
|
|
auto length = MCore::Array::GetLength(array);
|
|
|
|
|
for (int32 i = 0; i < length; i++)
|
|
|
|
|
MCore::String::Free(dataPtr[i]);
|
|
|
|
|
MCore::Array::Free(array);
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -201,7 +232,17 @@ struct MConverter<StringAnsi>
|
|
|
|
|
|
|
|
|
|
void FreeManaged(MObject* data)
|
|
|
|
|
{
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&data);
|
|
|
|
|
MCore::String::Free((MString*)data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
|
|
|
{
|
|
|
|
|
MString** dataPtr = MCore::Array::GetAddress<MString*>(array);
|
|
|
|
|
auto length = MCore::Array::GetLength(array);
|
|
|
|
|
for (int32 i = 0; i < length; i++)
|
|
|
|
|
MCore::String::Free(dataPtr[i]);
|
|
|
|
|
MCore::Array::Free(array);
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -211,16 +252,19 @@ struct MConverter<StringView>
|
|
|
|
|
{
|
|
|
|
|
MObject* Box(const StringView& data, const MClass* klass)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
return (MObject*)MUtils::ToString(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Unbox(StringView& result, MObject* data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
result = MUtils::ToString((MString*)data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ToManagedArray(MArray* result, const Span<StringView>& data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
if (data.Length() == 0)
|
|
|
|
|
return;
|
|
|
|
|
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
|
|
|
|
@@ -232,6 +276,7 @@ struct MConverter<StringView>
|
|
|
|
|
|
|
|
|
|
void ToNativeArray(Span<StringView>& result, const MArray* data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
MString** dataPtr = MCore::Array::GetAddress<MString*>(data);
|
|
|
|
|
for (int32 i = 0; i < result.Length(); i++)
|
|
|
|
|
MUtils::ToString(dataPtr[i], result.Get()[i]);
|
|
|
|
|
@@ -239,7 +284,19 @@ struct MConverter<StringView>
|
|
|
|
|
|
|
|
|
|
void FreeManaged(MObject* data)
|
|
|
|
|
{
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&data);
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
MCore::String::Free((MString*)data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
MString** dataPtr = MCore::Array::GetAddress<MString*>(array);
|
|
|
|
|
auto length = MCore::Array::GetLength(array);
|
|
|
|
|
for (int32 i = 0; i < length; i++)
|
|
|
|
|
MCore::String::Free(dataPtr[i]);
|
|
|
|
|
MCore::Array::Free(array);
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -249,16 +306,19 @@ struct MConverter<Variant>
|
|
|
|
|
{
|
|
|
|
|
MObject* Box(const Variant& data, const MClass* klass)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
return MUtils::BoxVariant(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Unbox(Variant& result, MObject* data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
result = MUtils::UnboxVariant(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ToManagedArray(MArray* result, const Span<Variant>& data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
if (data.Length() == 0)
|
|
|
|
|
return;
|
|
|
|
|
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
|
|
|
|
@@ -270,6 +330,7 @@ struct MConverter<Variant>
|
|
|
|
|
|
|
|
|
|
void ToNativeArray(Span<Variant>& result, const MArray* data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
|
|
|
|
for (int32 i = 0; i < result.Length(); i++)
|
|
|
|
|
result.Get()[i] = MUtils::UnboxVariant(dataPtr[i]);
|
|
|
|
|
@@ -277,6 +338,14 @@ struct MConverter<Variant>
|
|
|
|
|
|
|
|
|
|
void FreeManaged(MObject* data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
MCore::Array::Free(array);
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -286,11 +355,13 @@ struct MConverter<T*, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Va
|
|
|
|
|
{
|
|
|
|
|
MObject* Box(T* data, const MClass* klass)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
return data ? data->GetOrCreateManagedInstance() : nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Unbox(T*& result, MObject* data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
result = (T*)ScriptingObject::ToNative(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -314,6 +385,13 @@ struct MConverter<T*, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Va
|
|
|
|
|
|
|
|
|
|
void FreeManaged(MObject* data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
|
|
|
{
|
|
|
|
|
MCore::Array::Free(array);
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -323,11 +401,13 @@ struct MConverter<T, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Val
|
|
|
|
|
{
|
|
|
|
|
MObject* Box(const T& data, const MClass* klass)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
return data.GetOrCreateManagedInstance();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ToManagedArray(MArray* result, const Span<T>& data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
if (data.Length() == 0)
|
|
|
|
|
return;
|
|
|
|
|
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
|
|
|
|
@@ -339,6 +419,14 @@ struct MConverter<T, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Val
|
|
|
|
|
|
|
|
|
|
void FreeManaged(MObject* data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
MCore::Array::Free(array);
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -351,16 +439,19 @@ struct MConverter<ScriptingObjectReference<T>>
|
|
|
|
|
{
|
|
|
|
|
MObject* Box(const ScriptingObjectReference<T>& data, const MClass* klass)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
return data.GetManagedInstance();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Unbox(ScriptingObjectReference<T>& result, MObject* data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
result = (T*)ScriptingObject::ToNative(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ToManagedArray(MArray* result, const Span<ScriptingObjectReference<T>>& data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
if (data.Length() == 0)
|
|
|
|
|
return;
|
|
|
|
|
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
|
|
|
|
@@ -372,6 +463,7 @@ struct MConverter<ScriptingObjectReference<T>>
|
|
|
|
|
|
|
|
|
|
void ToNativeArray(Span<ScriptingObjectReference<T>>& result, const MArray* data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
|
|
|
|
for (int32 i = 0; i < result.Length(); i++)
|
|
|
|
|
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
|
|
|
|
@@ -379,6 +471,14 @@ struct MConverter<ScriptingObjectReference<T>>
|
|
|
|
|
|
|
|
|
|
void FreeManaged(MObject* data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
MCore::Array::Free(array);
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -391,11 +491,13 @@ struct MConverter<AssetReference<T>>
|
|
|
|
|
{
|
|
|
|
|
MObject* Box(const AssetReference<T>& data, const MClass* klass)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
return data.GetManagedInstance();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Unbox(AssetReference<T>& result, MObject* data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
result = (T*)ScriptingObject::ToNative(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -412,6 +514,7 @@ struct MConverter<AssetReference<T>>
|
|
|
|
|
|
|
|
|
|
void ToNativeArray(Span<AssetReference<T>>& result, const MArray* data)
|
|
|
|
|
{
|
|
|
|
|
//PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
|
|
|
|
for (int32 i = 0; i < result.Length(); i++)
|
|
|
|
|
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
|
|
|
|
@@ -419,6 +522,13 @@ struct MConverter<AssetReference<T>>
|
|
|
|
|
|
|
|
|
|
void FreeManaged(MObject* data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
|
|
|
{
|
|
|
|
|
MCore::Array::Free(array);
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -430,6 +540,7 @@ struct MConverter<SoftAssetReference<T>>
|
|
|
|
|
{
|
|
|
|
|
void ToManagedArray(MArray* result, const Span<SoftAssetReference<T>>& data)
|
|
|
|
|
{
|
|
|
|
|
//PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
if (data.Length() == 0)
|
|
|
|
|
return;
|
|
|
|
|
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
|
|
|
|
@@ -441,6 +552,7 @@ struct MConverter<SoftAssetReference<T>>
|
|
|
|
|
|
|
|
|
|
void ToNativeArray(Span<SoftAssetReference<T>>& result, const MArray* data)
|
|
|
|
|
{
|
|
|
|
|
//PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
|
|
|
|
for (int32 i = 0; i < result.Length(); i++)
|
|
|
|
|
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
|
|
|
|
@@ -448,6 +560,14 @@ struct MConverter<SoftAssetReference<T>>
|
|
|
|
|
|
|
|
|
|
void FreeManaged(MObject* data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
MCore::Array::Free(array);
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -457,6 +577,7 @@ struct MConverter<Array<T>>
|
|
|
|
|
{
|
|
|
|
|
MObject* Box(const Array<T>& data, const MClass* klass)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
if (!klass)
|
|
|
|
|
return nullptr;
|
|
|
|
|
MArray* result = MCore::Array::New(klass->GetElementClass(), data.Count());
|
|
|
|
|
@@ -477,6 +598,19 @@ struct MConverter<Array<T>>
|
|
|
|
|
|
|
|
|
|
void FreeManaged(MObject* data)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
MArray* array = (MArray*)data;
|
|
|
|
|
MConverter<T> converter;
|
|
|
|
|
converter.FreeManagedArray(array);
|
|
|
|
|
//MCore::Array::Free(array);
|
|
|
|
|
//MCore::GCHandle::Free(*(MGCHandle*)&data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
|
|
|
{
|
|
|
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
|
|
|
MCore::Array::Free(array);
|
|
|
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -554,6 +688,16 @@ namespace MUtils
|
|
|
|
|
converter.FreeManaged(object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Releases the managed resources of a boxed object.
|
|
|
|
|
/// </summary>
|
|
|
|
|
template<class T>
|
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
|
|
|
{
|
|
|
|
|
MConverter<T> converter;
|
|
|
|
|
converter.FreeManagedArray(array);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Links managed array data to the unmanaged BytesContainer.
|
|
|
|
|
/// </summary>
|
|
|
|
|
@@ -690,6 +834,52 @@ namespace MUtils
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if USE_NETCORE
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Allocates new boolean array and copies data from the given unmanaged data container. The managed runtime is responsible for releasing the returned array data.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="data">The input data.</param>
|
|
|
|
|
/// <returns>The output array.</returns>
|
|
|
|
|
template<typename T>
|
|
|
|
|
FORCE_INLINE T* ToNativeArray(const Array<T>& data)
|
|
|
|
|
{
|
|
|
|
|
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
|
|
|
|
T* arr = (T*)MCore::GC::AllocateMemory(data.Count() * sizeof(T), true);
|
|
|
|
|
Platform::MemoryCopy(arr, data.Get(), data.Count() * sizeof(T));
|
|
|
|
|
return arr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Allocates new boolean array and copies data from the given unmanaged data container. The managed runtime is responsible for releasing the returned array data.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="data">The input data.</param>
|
|
|
|
|
/// <returns>The output array.</returns>
|
|
|
|
|
template<typename T, typename AllocationType = HeapAllocation>
|
|
|
|
|
FORCE_INLINE NativeArray<T> ToNativeArrayWrapper(const Array<T, AllocationType>& data)
|
|
|
|
|
{
|
|
|
|
|
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
|
|
|
|
NativeArray<T> arr;
|
|
|
|
|
arr.length = data.Count();
|
|
|
|
|
arr.data = (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true);
|
|
|
|
|
Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(T));
|
|
|
|
|
return arr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Allocates new boolean array and copies data from the given unmanaged data container. The managed runtime is responsible for releasing the returned array data.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="data">The input data.</param>
|
|
|
|
|
/// <returns>The output array.</returns>
|
|
|
|
|
template<typename T>
|
|
|
|
|
FORCE_INLINE NativeArray<T> ToNativeArrayWrapper(const Span<T>& data)
|
|
|
|
|
{
|
|
|
|
|
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
|
|
|
|
NativeArray<T> arr;
|
|
|
|
|
arr.length = data.Length();
|
|
|
|
|
arr.data = (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true);
|
|
|
|
|
Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(T));
|
|
|
|
|
return arr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Allocates new boolean array and copies data from the given unmanaged data container. The managed runtime is responsible for releasing the returned array data.
|
|
|
|
|
/// </summary>
|
|
|
|
|
|