wip 2 no leaks
This commit is contained in:
@@ -84,6 +84,7 @@ public:
|
||||
static MString* GetEmpty(MDomain* domain = nullptr);
|
||||
static MString* New(const char* str, int32 length, MDomain* domain = nullptr);
|
||||
static MString* New(const Char* str, int32 length, MDomain* domain = nullptr);
|
||||
static void Free(MString* obj);
|
||||
static StringView GetChars(MString* obj);
|
||||
};
|
||||
|
||||
@@ -93,6 +94,7 @@ public:
|
||||
struct FLAXENGINE_API Array
|
||||
{
|
||||
static MArray* New(const MClass* elementKlass, int32 length);
|
||||
static void Free(const MArray* array);
|
||||
static MClass* GetClass(MClass* elementKlass);
|
||||
static MClass* GetArrayClass(const MArray* obj);
|
||||
static int32 GetLength(const MArray* obj);
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user