wip 2 no leaks
This commit is contained in:
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
#define USE_CONCURRENT_DICT
|
#define USE_CONCURRENT_DICT
|
||||||
#define USE_GCHANDLE
|
#define USE_GCHANDLE
|
||||||
#define TRACK_HANDLES
|
//#define TRACK_HANDLES
|
||||||
|
|
||||||
|
|
||||||
#if USE_NETCORE
|
#if USE_NETCORE
|
||||||
using System;
|
using System;
|
||||||
@@ -351,6 +352,14 @@ namespace FlaxEngine.Interop
|
|||||||
return;
|
return;
|
||||||
handle.Free();
|
handle.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[System.Diagnostics.DebuggerStepThrough]
|
||||||
|
public static void Free(ManagedHandle handle)
|
||||||
|
{
|
||||||
|
if (handle == EmptyStringHandle)
|
||||||
|
return;
|
||||||
|
handle.Free();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -373,6 +382,9 @@ namespace FlaxEngine.Interop
|
|||||||
|
|
||||||
public static long Allocations => Interlocked.Read(ref _allocations);
|
public static long Allocations => Interlocked.Read(ref _allocations);
|
||||||
public static long Deallocations => Interlocked.Read(ref _deallocations);
|
public static long Deallocations => Interlocked.Read(ref _deallocations);
|
||||||
|
#else
|
||||||
|
public static long Allocations => 0;
|
||||||
|
public static long Deallocations => 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@@ -382,14 +394,14 @@ namespace FlaxEngine.Interop
|
|||||||
private ManagedHandle(object value, GCHandleType type) //=> handle = GCHandle.Alloc(value, type);
|
private ManagedHandle(object value, GCHandleType type) //=> handle = GCHandle.Alloc(value, type);
|
||||||
{
|
{
|
||||||
#if TRACK_HANDLES
|
#if TRACK_HANDLES
|
||||||
if (type == GCHandleType.Weak || type == GCHandleType.WeakTrackResurrection)
|
/*if (type == GCHandleType.Weak || type == GCHandleType.WeakTrackResurrection)
|
||||||
{
|
{
|
||||||
type = GCHandleType.Normal;
|
type = GCHandleType.Normal;
|
||||||
}
|
}*/
|
||||||
#endif
|
#endif
|
||||||
handle = GCHandle.Alloc(value, type);
|
handle = GCHandle.Alloc(value, type);
|
||||||
#if TRACK_HANDLES
|
#if TRACK_HANDLES
|
||||||
if (type == GCHandleType.Weak || type == GCHandleType.WeakTrackResurrection)
|
/*if (type == GCHandleType.Weak || type == GCHandleType.WeakTrackResurrection)
|
||||||
_weakHandles.Add((IntPtr)handle);
|
_weakHandles.Add((IntPtr)handle);
|
||||||
else if (_handles.Count < 14000)
|
else if (_handles.Count < 14000)
|
||||||
_handles.TryAdd((IntPtr)handle, value?.GetType().FullName ?? "");
|
_handles.TryAdd((IntPtr)handle, value?.GetType().FullName ?? "");
|
||||||
@@ -400,7 +412,7 @@ namespace FlaxEngine.Interop
|
|||||||
if (value?.GetType() == typeof(string))
|
if (value?.GetType() == typeof(string))
|
||||||
type = type;
|
type = type;
|
||||||
_handles2.TryAdd((IntPtr)handle, value?.GetType().FullName ?? "");
|
_handles2.TryAdd((IntPtr)handle, value?.GetType().FullName ?? "");
|
||||||
}
|
}*/
|
||||||
Interlocked.Increment(ref _allocations);
|
Interlocked.Increment(ref _allocations);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -424,7 +436,7 @@ namespace FlaxEngine.Interop
|
|||||||
if ((IntPtr)handle == IntPtr.Zero)
|
if ((IntPtr)handle == IntPtr.Zero)
|
||||||
return;
|
return;
|
||||||
#if TRACK_HANDLES
|
#if TRACK_HANDLES
|
||||||
if (_weakHandles.Remove((IntPtr)handle))
|
/*if (_weakHandles.Remove((IntPtr)handle))
|
||||||
{
|
{
|
||||||
if (!handle.IsAllocated)
|
if (!handle.IsAllocated)
|
||||||
handle = handle;
|
handle = handle;
|
||||||
@@ -437,7 +449,7 @@ namespace FlaxEngine.Interop
|
|||||||
else if (_handles2.Remove((IntPtr)handle, out _))
|
else if (_handles2.Remove((IntPtr)handle, out _))
|
||||||
{
|
{
|
||||||
handle = handle;
|
handle = handle;
|
||||||
}
|
}*/
|
||||||
Interlocked.Increment(ref _deallocations);
|
Interlocked.Increment(ref _deallocations);
|
||||||
#endif
|
#endif
|
||||||
handle.Free();
|
handle.Free();
|
||||||
|
|||||||
@@ -545,6 +545,18 @@ namespace FlaxEngine.Interop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
internal static void FreeArray(ManagedHandle handle)
|
||||||
|
{
|
||||||
|
if (!handle.IsAllocated)
|
||||||
|
return;
|
||||||
|
ManagedArray managedArray = Unsafe.As<ManagedArray>(handle.Target);
|
||||||
|
if (managedArray.ElementType.IsValueType)
|
||||||
|
managedArray.Free();
|
||||||
|
else
|
||||||
|
managedArray.FreePooled();
|
||||||
|
}
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
[UnmanagedCallersOnly]
|
||||||
internal static ManagedHandle GetArrayTypeFromElementType(ManagedHandle elementTypeHandle)
|
internal static ManagedHandle GetArrayTypeFromElementType(ManagedHandle elementTypeHandle)
|
||||||
{
|
{
|
||||||
@@ -613,6 +625,12 @@ namespace FlaxEngine.Interop
|
|||||||
return ManagedString.ToNative/*Weak*/(new string(text, 0, length, System.Text.Encoding.UTF8));
|
return ManagedString.ToNative/*Weak*/(new string(text, 0, length, System.Text.Encoding.UTF8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
internal static void FreeString(ManagedHandle handle)
|
||||||
|
{
|
||||||
|
ManagedString.Free(handle);
|
||||||
|
}
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
[UnmanagedCallersOnly]
|
||||||
internal static ManagedHandle GetObjectType(ManagedHandle handle)
|
internal static ManagedHandle GetObjectType(ManagedHandle handle)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ public:
|
|||||||
static MString* GetEmpty(MDomain* domain = nullptr);
|
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 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);
|
static StringView GetChars(MString* obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -93,6 +94,7 @@ public:
|
|||||||
struct FLAXENGINE_API Array
|
struct FLAXENGINE_API Array
|
||||||
{
|
{
|
||||||
static MArray* New(const MClass* elementKlass, int32 length);
|
static MArray* New(const MClass* elementKlass, int32 length);
|
||||||
|
static void Free(const MArray* array);
|
||||||
static MClass* GetClass(MClass* elementKlass);
|
static MClass* GetClass(MClass* elementKlass);
|
||||||
static MClass* GetArrayClass(const MArray* obj);
|
static MClass* GetArrayClass(const MArray* obj);
|
||||||
static int32 GetLength(const MArray* obj);
|
static int32 GetLength(const MArray* obj);
|
||||||
|
|||||||
@@ -49,9 +49,18 @@ struct MConverter
|
|||||||
{
|
{
|
||||||
MObject* Box(const T& data, const MClass* klass);
|
MObject* Box(const T& data, const MClass* klass);
|
||||||
void Unbox(T& result, MObject* data);
|
void Unbox(T& result, MObject* data);
|
||||||
|
void FreeManaged(MObject* data);
|
||||||
void ToManagedArray(MArray* result, const Span<T>& data);
|
void ToManagedArray(MArray* result, const Span<T>& data);
|
||||||
void ToNativeArray(Span<T>& result, const MArray* 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
|
#if USE_NETCORE
|
||||||
@@ -70,6 +79,10 @@ struct MConverter<bool>
|
|||||||
Platform::MemoryCopy(&result, MCore::Object::Unbox(data), sizeof(bool));
|
Platform::MemoryCopy(&result, MCore::Object::Unbox(data), sizeof(bool));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FreeManaged(MObject* data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void ToManagedArray(MArray* result, const Span<bool>& data)
|
void ToManagedArray(MArray* result, const Span<bool>& data)
|
||||||
{
|
{
|
||||||
Platform::MemoryCopy(MCore::Array::GetAddress(result), data.Get(), data.Length() * sizeof(bool));
|
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));
|
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
|
#endif
|
||||||
@@ -115,6 +130,12 @@ struct MConverter<T, typename TEnableIf<TAnd<TIsPODType<T>, TNot<TIsBaseOf<class
|
|||||||
{
|
{
|
||||||
MCore::GCHandle::Free(*(MGCHandle*)&data);
|
MCore::GCHandle::Free(*(MGCHandle*)&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FreeManagedArray(MArray* array)
|
||||||
|
{
|
||||||
|
MCore::Array::Free(array);
|
||||||
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Converter for String.
|
// Converter for String.
|
||||||
@@ -163,7 +184,17 @@ struct MConverter<String>
|
|||||||
{
|
{
|
||||||
//MString* str = (MString*)MCore::Object::Unbox(data);
|
//MString* str = (MString*)MCore::Object::Unbox(data);
|
||||||
//MCore::GCHandle::Free(*(MGCHandle*)&str);
|
//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)
|
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)
|
MObject* Box(const StringView& data, const MClass* klass)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
return (MObject*)MUtils::ToString(data);
|
return (MObject*)MUtils::ToString(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unbox(StringView& result, MObject* data)
|
void Unbox(StringView& result, MObject* data)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
result = MUtils::ToString((MString*)data);
|
result = MUtils::ToString((MString*)data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToManagedArray(MArray* result, const Span<StringView>& data)
|
void ToManagedArray(MArray* result, const Span<StringView>& data)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
if (data.Length() == 0)
|
if (data.Length() == 0)
|
||||||
return;
|
return;
|
||||||
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
||||||
@@ -232,6 +276,7 @@ struct MConverter<StringView>
|
|||||||
|
|
||||||
void ToNativeArray(Span<StringView>& result, const MArray* data)
|
void ToNativeArray(Span<StringView>& result, const MArray* data)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
MString** dataPtr = MCore::Array::GetAddress<MString*>(data);
|
MString** dataPtr = MCore::Array::GetAddress<MString*>(data);
|
||||||
for (int32 i = 0; i < result.Length(); i++)
|
for (int32 i = 0; i < result.Length(); i++)
|
||||||
MUtils::ToString(dataPtr[i], result.Get()[i]);
|
MUtils::ToString(dataPtr[i], result.Get()[i]);
|
||||||
@@ -239,7 +284,19 @@ struct MConverter<StringView>
|
|||||||
|
|
||||||
void FreeManaged(MObject* data)
|
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)
|
MObject* Box(const Variant& data, const MClass* klass)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
return MUtils::BoxVariant(data);
|
return MUtils::BoxVariant(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unbox(Variant& result, MObject* data)
|
void Unbox(Variant& result, MObject* data)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
result = MUtils::UnboxVariant(data);
|
result = MUtils::UnboxVariant(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToManagedArray(MArray* result, const Span<Variant>& data)
|
void ToManagedArray(MArray* result, const Span<Variant>& data)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
if (data.Length() == 0)
|
if (data.Length() == 0)
|
||||||
return;
|
return;
|
||||||
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
||||||
@@ -270,6 +330,7 @@ struct MConverter<Variant>
|
|||||||
|
|
||||||
void ToNativeArray(Span<Variant>& result, const MArray* data)
|
void ToNativeArray(Span<Variant>& result, const MArray* data)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
||||||
for (int32 i = 0; i < result.Length(); i++)
|
for (int32 i = 0; i < result.Length(); i++)
|
||||||
result.Get()[i] = MUtils::UnboxVariant(dataPtr[i]);
|
result.Get()[i] = MUtils::UnboxVariant(dataPtr[i]);
|
||||||
@@ -277,6 +338,14 @@ struct MConverter<Variant>
|
|||||||
|
|
||||||
void FreeManaged(MObject* data)
|
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)
|
MObject* Box(T* data, const MClass* klass)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
return data ? data->GetOrCreateManagedInstance() : nullptr;
|
return data ? data->GetOrCreateManagedInstance() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unbox(T*& result, MObject* data)
|
void Unbox(T*& result, MObject* data)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
result = (T*)ScriptingObject::ToNative(data);
|
result = (T*)ScriptingObject::ToNative(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,6 +385,13 @@ struct MConverter<T*, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Va
|
|||||||
|
|
||||||
void FreeManaged(MObject* data)
|
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)
|
MObject* Box(const T& data, const MClass* klass)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
return data.GetOrCreateManagedInstance();
|
return data.GetOrCreateManagedInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToManagedArray(MArray* result, const Span<T>& data)
|
void ToManagedArray(MArray* result, const Span<T>& data)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
if (data.Length() == 0)
|
if (data.Length() == 0)
|
||||||
return;
|
return;
|
||||||
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
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)
|
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)
|
MObject* Box(const ScriptingObjectReference<T>& data, const MClass* klass)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
return data.GetManagedInstance();
|
return data.GetManagedInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unbox(ScriptingObjectReference<T>& result, MObject* data)
|
void Unbox(ScriptingObjectReference<T>& result, MObject* data)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
result = (T*)ScriptingObject::ToNative(data);
|
result = (T*)ScriptingObject::ToNative(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToManagedArray(MArray* result, const Span<ScriptingObjectReference<T>>& data)
|
void ToManagedArray(MArray* result, const Span<ScriptingObjectReference<T>>& data)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
if (data.Length() == 0)
|
if (data.Length() == 0)
|
||||||
return;
|
return;
|
||||||
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
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)
|
void ToNativeArray(Span<ScriptingObjectReference<T>>& result, const MArray* data)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
||||||
for (int32 i = 0; i < result.Length(); i++)
|
for (int32 i = 0; i < result.Length(); i++)
|
||||||
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
||||||
@@ -379,6 +471,14 @@ struct MConverter<ScriptingObjectReference<T>>
|
|||||||
|
|
||||||
void FreeManaged(MObject* data)
|
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)
|
MObject* Box(const AssetReference<T>& data, const MClass* klass)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
return data.GetManagedInstance();
|
return data.GetManagedInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unbox(AssetReference<T>& result, MObject* data)
|
void Unbox(AssetReference<T>& result, MObject* data)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
result = (T*)ScriptingObject::ToNative(data);
|
result = (T*)ScriptingObject::ToNative(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,6 +514,7 @@ struct MConverter<AssetReference<T>>
|
|||||||
|
|
||||||
void ToNativeArray(Span<AssetReference<T>>& result, const MArray* data)
|
void ToNativeArray(Span<AssetReference<T>>& result, const MArray* data)
|
||||||
{
|
{
|
||||||
|
//PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
||||||
for (int32 i = 0; i < result.Length(); i++)
|
for (int32 i = 0; i < result.Length(); i++)
|
||||||
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
||||||
@@ -419,6 +522,13 @@ struct MConverter<AssetReference<T>>
|
|||||||
|
|
||||||
void FreeManaged(MObject* data)
|
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)
|
void ToManagedArray(MArray* result, const Span<SoftAssetReference<T>>& data)
|
||||||
{
|
{
|
||||||
|
//PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
if (data.Length() == 0)
|
if (data.Length() == 0)
|
||||||
return;
|
return;
|
||||||
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
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)
|
void ToNativeArray(Span<SoftAssetReference<T>>& result, const MArray* data)
|
||||||
{
|
{
|
||||||
|
//PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
||||||
for (int32 i = 0; i < result.Length(); i++)
|
for (int32 i = 0; i < result.Length(); i++)
|
||||||
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
||||||
@@ -448,6 +560,14 @@ struct MConverter<SoftAssetReference<T>>
|
|||||||
|
|
||||||
void FreeManaged(MObject* data)
|
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)
|
MObject* Box(const Array<T>& data, const MClass* klass)
|
||||||
{
|
{
|
||||||
|
PLATFORM_DEBUG_BREAK; // FIXME
|
||||||
if (!klass)
|
if (!klass)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
MArray* result = MCore::Array::New(klass->GetElementClass(), data.Count());
|
MArray* result = MCore::Array::New(klass->GetElementClass(), data.Count());
|
||||||
@@ -477,6 +598,19 @@ struct MConverter<Array<T>>
|
|||||||
|
|
||||||
void FreeManaged(MObject* data)
|
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);
|
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>
|
/// <summary>
|
||||||
/// Links managed array data to the unmanaged BytesContainer.
|
/// Links managed array data to the unmanaged BytesContainer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -690,6 +834,52 @@ namespace MUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if USE_NETCORE
|
#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>
|
/// <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.
|
/// 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>
|
/// </summary>
|
||||||
|
|||||||
@@ -462,12 +462,24 @@ StringView MCore::String::GetChars(MString* obj)
|
|||||||
return StringView(chars, length);
|
return StringView(chars, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCore::String::Free(MString* obj)
|
||||||
|
{
|
||||||
|
static void* FreeStringPtr = GetStaticMethodPointer(TEXT("FreeString"));
|
||||||
|
CallStaticMethod<void, void*>(FreeStringPtr, obj);
|
||||||
|
}
|
||||||
|
|
||||||
MArray* MCore::Array::New(const MClass* elementKlass, int32 length)
|
MArray* MCore::Array::New(const MClass* elementKlass, int32 length)
|
||||||
{
|
{
|
||||||
static void* NewArrayPtr = GetStaticMethodPointer(TEXT("NewArray"));
|
static void* NewArrayPtr = GetStaticMethodPointer(TEXT("NewArray"));
|
||||||
return (MArray*)CallStaticMethod<void*, void*, long long>(NewArrayPtr, elementKlass->_handle, length);
|
return (MArray*)CallStaticMethod<void*, void*, long long>(NewArrayPtr, elementKlass->_handle, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCore::Array::Free(const MArray* array)
|
||||||
|
{
|
||||||
|
static void* FreeArrayPtr = GetStaticMethodPointer(TEXT("FreeArray"));
|
||||||
|
CallStaticMethod<void, void*>(FreeArrayPtr, (void*)array);
|
||||||
|
}
|
||||||
|
|
||||||
MClass* MCore::Array::GetClass(MClass* elementKlass)
|
MClass* MCore::Array::GetClass(MClass* elementKlass)
|
||||||
{
|
{
|
||||||
static void* GetArrayTypeFromElementTypePtr = GetStaticMethodPointer(TEXT("GetArrayTypeFromElementType"));
|
static void* GetArrayTypeFromElementTypePtr = GetStaticMethodPointer(TEXT("GetArrayTypeFromElementType"));
|
||||||
|
|||||||
@@ -787,12 +787,20 @@ StringView MCore::String::GetChars(MString* obj)
|
|||||||
return StringView(mono_string_chars(obj), (int32)mono_string_length(obj));
|
return StringView(mono_string_chars(obj), (int32)mono_string_length(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCore::String::Free(MString* obj)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
MArray* MCore::Array::New(const MClass* elementKlass, int32 length)
|
MArray* MCore::Array::New(const MClass* elementKlass, int32 length)
|
||||||
{
|
{
|
||||||
// TODO: use shared empty arrays cache
|
// TODO: use shared empty arrays cache
|
||||||
return mono_array_new(mono_domain_get(), elementKlass->GetNative(), length);
|
return mono_array_new(mono_domain_get(), elementKlass->GetNative(), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCore::Array::Free(const MArray* array)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
MClass* MCore::Array::GetClass(MClass* elementKlass)
|
MClass* MCore::Array::GetClass(MClass* elementKlass)
|
||||||
{
|
{
|
||||||
MonoClass* monoClass = mono_array_class_get(elementKlass->GetNative(), 1);
|
MonoClass* monoClass = mono_array_class_get(elementKlass->GetNative(), 1);
|
||||||
|
|||||||
@@ -124,11 +124,19 @@ StringView MCore::String::GetChars(MString* obj)
|
|||||||
return StringView::Empty;
|
return StringView::Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCore::String::Free(MString* obj)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
MArray* MCore::Array::New(const MClass* elementKlass, int32 length)
|
MArray* MCore::Array::New(const MClass* elementKlass, int32 length)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCore::Array::Free(const MArray* array)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
MClass* MCore::Array::GetClass(MClass* elementKlass)
|
MClass* MCore::Array::GetClass(MClass* elementKlass)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -633,8 +633,62 @@ namespace Flax.Build.Bindings
|
|||||||
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.SystemArrayMarshaller))";
|
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.SystemArrayMarshaller))";
|
||||||
else if (returnValueType == "object[]")
|
else if (returnValueType == "object[]")
|
||||||
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.SystemObjectArrayMarshaller))";
|
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.SystemObjectArrayMarshaller))";
|
||||||
|
else if (functionInfo.ReturnType.IsArrayOrSpan || returnNativeType == "Array")
|
||||||
|
{
|
||||||
|
string unmanagedType = "";
|
||||||
|
if (functionInfo.ReturnType.GenericArgs != null && functionInfo.ReturnType.GenericArgs[0].IsPod(buildData, caller))
|
||||||
|
{
|
||||||
|
switch (functionInfo.ReturnType.GenericArgs[0].Type)
|
||||||
|
{
|
||||||
|
case "bool": unmanagedType = "U1"; break;
|
||||||
|
case "byte": unmanagedType = "U1"; break;
|
||||||
|
case "sbyte": unmanagedType = "I1"; break;
|
||||||
|
case "char": unmanagedType = "I2"; break;
|
||||||
|
case "short": case "int16": unmanagedType = "I2"; break;
|
||||||
|
case "ushort": case "uint16": unmanagedType = "U2"; break;
|
||||||
|
case "int": case "int32": unmanagedType = "I4"; break;
|
||||||
|
case "uint": case "uint32": unmanagedType = "U4"; break;
|
||||||
|
case "long": case "int64": unmanagedType = "I8"; break;
|
||||||
|
case "ulong": case "uint64": unmanagedType = "U8"; break;
|
||||||
|
case "float": unmanagedType = "R4"; break;
|
||||||
|
case "double": unmanagedType = "R8"; break;
|
||||||
|
|
||||||
|
case "Float2":
|
||||||
|
case "Double2":
|
||||||
|
case "Vector2":
|
||||||
|
case "Float3":
|
||||||
|
case "Double3":
|
||||||
|
case "Vector3":
|
||||||
|
case "Float4":
|
||||||
|
case "Double4":
|
||||||
|
case "Vector4":
|
||||||
|
case "Color":
|
||||||
|
case "Color32":
|
||||||
|
case "Guid":
|
||||||
|
unmanagedType = "Any"; // FIXME
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
unmanagedType = "Any";
|
||||||
|
//Log.Warning($"unknown type: '{parameterInfo.Type.GenericArgs[0].Type}'");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(unmanagedType))
|
||||||
|
{
|
||||||
|
string arraySubType = "";
|
||||||
|
if (unmanagedType != "Any")
|
||||||
|
arraySubType = $"ArraySubType = UnmanagedType.{unmanagedType}, ";
|
||||||
|
returnMarshalType = $"MarshalAs(UnmanagedType.LPArray, {arraySubType}SizeParamIndex = {(!functionInfo.IsStatic ? 1 : 0) + functionInfo.Parameters.Count + (functionInfo.Glue.CustomParameters.FindIndex(x => x.Name == $"__returnCount"))})";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
returnMarshalType = $"MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = \"__returnCount\")";
|
||||||
|
}
|
||||||
else if (functionInfo.ReturnType.Type == "Array" || functionInfo.ReturnType.Type == "Span" || functionInfo.ReturnType.Type == "DataContainer" || functionInfo.ReturnType.Type == "BytesContainer" || returnNativeType == "Array")
|
else if (functionInfo.ReturnType.Type == "Array" || functionInfo.ReturnType.Type == "Span" || functionInfo.ReturnType.Type == "DataContainer" || functionInfo.ReturnType.Type == "BytesContainer" || returnNativeType == "Array")
|
||||||
|
{
|
||||||
|
//[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = 8)]
|
||||||
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = nameof(__returnCount))";
|
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = nameof(__returnCount))";
|
||||||
|
}
|
||||||
else if (functionInfo.ReturnType.Type == "Dictionary")
|
else if (functionInfo.ReturnType.Type == "Dictionary")
|
||||||
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.DictionaryMarshaller<,>), ConstantElementCount = 0)";
|
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.DictionaryMarshaller<,>), ConstantElementCount = 0)";
|
||||||
else if (returnValueType == "byte[]")
|
else if (returnValueType == "byte[]")
|
||||||
@@ -686,11 +740,56 @@ namespace Flax.Build.Bindings
|
|||||||
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.SystemArrayMarshaller))";
|
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.SystemArrayMarshaller))";
|
||||||
else if (nativeType == "object[]")
|
else if (nativeType == "object[]")
|
||||||
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.SystemObjectArrayMarshaller))";
|
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.SystemObjectArrayMarshaller))";
|
||||||
else if (parameterInfo.Type.Type == "Array" && parameterInfo.Type.GenericArgs.Count > 0 && parameterInfo.Type.GenericArgs[0].Type == "bool")
|
else if (parameterInfo.Type.IsArrayOrSpan || nativeType == "Array")
|
||||||
parameterMarshalType = $"MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = {(!functionInfo.IsStatic ? 1 : 0) + functionInfo.Parameters.Count + (functionInfo.Glue.CustomParameters.FindIndex(x => x.Name == $"__{parameterInfo.Name}Count"))})";
|
|
||||||
else if (parameterInfo.Type.Type == "Array" || parameterInfo.Type.Type == "Span" || parameterInfo.Type.Type == "DataContainer" || parameterInfo.Type.Type == "BytesContainer" || nativeType == "Array")
|
|
||||||
{
|
{
|
||||||
parameterMarshalType = $"MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = \"__{parameterInfo.Name}Count\")";
|
string unmanagedType = "";
|
||||||
|
if (parameterInfo.Type.GenericArgs != null && parameterInfo.Type.GenericArgs[0].IsPod(buildData, caller))
|
||||||
|
{
|
||||||
|
switch (parameterInfo.Type.GenericArgs[0].Type)
|
||||||
|
{
|
||||||
|
case "bool": unmanagedType = "U1"; break;
|
||||||
|
case "byte": unmanagedType = "U1"; break;
|
||||||
|
case "sbyte": unmanagedType = "I1"; break;
|
||||||
|
case "char": unmanagedType = "I2"; break;
|
||||||
|
case "short": case "int16": unmanagedType = "I2"; break;
|
||||||
|
case "ushort": case "uint16": unmanagedType = "U2"; break;
|
||||||
|
case "int": case "int32": unmanagedType = "I4"; break;
|
||||||
|
case "uint": case "uint32": unmanagedType = "U4"; break;
|
||||||
|
case "long": case "int64": unmanagedType = "I8"; break;
|
||||||
|
case "ulong": case "uint64": unmanagedType = "U8"; break;
|
||||||
|
case "float": unmanagedType = "R4"; break;
|
||||||
|
case "double": unmanagedType = "R8"; break;
|
||||||
|
|
||||||
|
case "Float2":
|
||||||
|
case "Double2":
|
||||||
|
case "Vector2":
|
||||||
|
case "Float3":
|
||||||
|
case "Double3":
|
||||||
|
case "Vector3":
|
||||||
|
case "Float4":
|
||||||
|
case "Double4":
|
||||||
|
case "Vector4":
|
||||||
|
case "Color":
|
||||||
|
case "Color32":
|
||||||
|
case "Guid":
|
||||||
|
unmanagedType = "Any"; // FIXME
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
unmanagedType = "Any";
|
||||||
|
//Log.Warning($"unknown type: '{parameterInfo.Type.GenericArgs[0].Type}'");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(unmanagedType))
|
||||||
|
{
|
||||||
|
string arraySubType = "";
|
||||||
|
if (unmanagedType != "Any")
|
||||||
|
arraySubType = $"ArraySubType = UnmanagedType.{unmanagedType}, ";
|
||||||
|
parameterMarshalType = $"MarshalAs(UnmanagedType.LPArray, {arraySubType}SizeParamIndex = {(!functionInfo.IsStatic ? 1 : 0) + functionInfo.Parameters.Count + (functionInfo.Glue.CustomParameters.FindIndex(x => x.Name == $"__{parameterInfo.Name}Count"))})";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
parameterMarshalType = $"MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = \"__{parameterInfo.Name}Count\")";
|
||||||
if (!parameterInfo.IsOut && !parameterInfo.IsRef)
|
if (!parameterInfo.IsOut && !parameterInfo.IsRef)
|
||||||
parameterMarshalType += ", In"; // The usage of 'LibraryImportAttribute' does not follow recommendations. It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters.
|
parameterMarshalType += ", In"; // The usage of 'LibraryImportAttribute' does not follow recommendations. It is recommended to use explicit '[In]' and '[Out]' attributes on array parameters.
|
||||||
}
|
}
|
||||||
@@ -741,7 +840,7 @@ namespace Flax.Build.Bindings
|
|||||||
if (parameterInfo.IsOut && parameterInfo.DefaultValue == "var __resultAsRef")
|
if (parameterInfo.IsOut && parameterInfo.DefaultValue == "var __resultAsRef")
|
||||||
{
|
{
|
||||||
// TODO: make this code shared with MarshalUsing selection from the above
|
// TODO: make this code shared with MarshalUsing selection from the above
|
||||||
if (parameterInfo.Type.Type == "Array" || parameterInfo.Type.Type == "Span" || parameterInfo.Type.Type == "DataContainer" || parameterInfo.Type.Type == "BytesContainer")
|
if (parameterInfo.Type.IsArrayOrSpan)
|
||||||
parameterMarshalType = $"MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = \"{parameterInfo.Name}Count\")";
|
parameterMarshalType = $"MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = \"{parameterInfo.Name}Count\")";
|
||||||
else if (parameterInfo.Type.Type == "Dictionary")
|
else if (parameterInfo.Type.Type == "Dictionary")
|
||||||
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.DictionaryMarshaller<,>), ConstantElementCount = 0)";
|
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.DictionaryMarshaller<,>), ConstantElementCount = 0)";
|
||||||
|
|||||||
@@ -531,14 +531,25 @@ namespace Flax.Build.Bindings
|
|||||||
if ((typeInfo.Type == "Array" || typeInfo.Type == "Span" || typeInfo.Type == "DataContainer") && typeInfo.GenericArgs != null)
|
if ((typeInfo.Type == "Array" || typeInfo.Type == "Span" || typeInfo.Type == "DataContainer") && typeInfo.GenericArgs != null)
|
||||||
{
|
{
|
||||||
var arrayTypeInfo = typeInfo.GenericArgs[0];
|
var arrayTypeInfo = typeInfo.GenericArgs[0];
|
||||||
#if USE_NETCORE
|
|
||||||
// Boolean arrays does not support custom marshalling for some unknown reason
|
|
||||||
if (arrayTypeInfo.Type == "bool")
|
|
||||||
{
|
|
||||||
type = "bool*";
|
|
||||||
return "MUtils::ToBoolArray({0})";
|
|
||||||
}
|
|
||||||
var arrayApiType = FindApiTypeInfo(buildData, arrayTypeInfo, caller);
|
var arrayApiType = FindApiTypeInfo(buildData, arrayTypeInfo, caller);
|
||||||
|
#if USE_NETCORE
|
||||||
|
if (arrayApiType?.IsPod ?? false)
|
||||||
|
{
|
||||||
|
if (functionInfo == null)
|
||||||
|
{
|
||||||
|
// Storage type should be wrapped
|
||||||
|
type = $"NativeArray<{arrayApiType.FullNameNative}>";
|
||||||
|
return $"MUtils::ToNativeArrayWrapper<{arrayApiType.FullNameNative}>({{0}})/*sahho*/";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//type = arrayApiType.FullNameNative + "*/*wahho*/";
|
||||||
|
type = $"NativeArray<{arrayApiType.FullNameNative}>/*tahho*/";
|
||||||
|
//if (arrayTypeInfo.Type == "bool")
|
||||||
|
// return "MUtils::ToBoolArray({0})/*bahho*/";
|
||||||
|
return "MUtils::ToNativeArrayWrapper({0})/*nahhoa7eatra*/";
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
type = "MArray*";
|
type = "MArray*";
|
||||||
if (arrayApiType != null && arrayApiType.MarshalAs != null)
|
if (arrayApiType != null && arrayApiType.MarshalAs != null)
|
||||||
@@ -554,12 +565,14 @@ namespace Flax.Build.Bindings
|
|||||||
return "MUtils::ToArray({0}, " + GenerateCppGetMClass(buildData, arrayTypeInfo, caller, functionInfo) + ")";
|
return "MUtils::ToArray({0}, " + GenerateCppGetMClass(buildData, arrayTypeInfo, caller, functionInfo) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !USE_NETCORE
|
||||||
// Span
|
// Span
|
||||||
if (typeInfo.Type == "Span" && typeInfo.GenericArgs != null)
|
if (typeInfo.Type == "Span" && typeInfo.GenericArgs != null)
|
||||||
{
|
{
|
||||||
type = "MonoArray*";
|
type = "MonoArray*";
|
||||||
return "MUtils::Span({0}, " + GenerateCppGetMClass(buildData, typeInfo.GenericArgs[0], caller, functionInfo) + ")";
|
return "MUtils::Span({0}, " + GenerateCppGetMClass(buildData, typeInfo.GenericArgs[0], caller, functionInfo) + ")";
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// BytesContainer
|
// BytesContainer
|
||||||
if (typeInfo.Type == "BytesContainer" && typeInfo.GenericArgs == null)
|
if (typeInfo.Type == "BytesContainer" && typeInfo.GenericArgs == null)
|
||||||
@@ -590,7 +603,7 @@ namespace Flax.Build.Bindings
|
|||||||
{
|
{
|
||||||
CppIncludeFiles.Add("Engine/Scripting/Internal/ManagedBitArray.h");
|
CppIncludeFiles.Add("Engine/Scripting/Internal/ManagedBitArray.h");
|
||||||
#if USE_NETCORE
|
#if USE_NETCORE
|
||||||
// Boolean arrays does not support custom marshalling for some unknown reason
|
// Special case for copying bits to bytes
|
||||||
type = "bool*";
|
type = "bool*";
|
||||||
return "MUtils::ToBoolArray({0})";
|
return "MUtils::ToBoolArray({0})";
|
||||||
#else
|
#else
|
||||||
@@ -742,6 +755,7 @@ namespace Flax.Build.Bindings
|
|||||||
// Array
|
// Array
|
||||||
if (typeInfo.Type == "Array" && typeInfo.GenericArgs != null)
|
if (typeInfo.Type == "Array" && typeInfo.GenericArgs != null)
|
||||||
{
|
{
|
||||||
|
needLocalVariable = true;
|
||||||
var arrayTypeInfo = typeInfo.GenericArgs[0];
|
var arrayTypeInfo = typeInfo.GenericArgs[0];
|
||||||
var arrayApiType = FindApiTypeInfo(buildData, arrayTypeInfo, caller);
|
var arrayApiType = FindApiTypeInfo(buildData, arrayTypeInfo, caller);
|
||||||
if (arrayApiType != null && arrayApiType.MarshalAs != null)
|
if (arrayApiType != null && arrayApiType.MarshalAs != null)
|
||||||
@@ -761,10 +775,15 @@ namespace Flax.Build.Bindings
|
|||||||
genericArgs += ", " + typeInfo.GenericArgs[1];
|
genericArgs += ", " + typeInfo.GenericArgs[1];
|
||||||
result = $"Array<{genericArgs}>({result})";
|
result = $"Array<{genericArgs}>({result})";
|
||||||
}
|
}
|
||||||
|
else if (arrayApiType?.IsPod ?? false)
|
||||||
|
{
|
||||||
|
type = arrayApiType.FullNameNative + '*';
|
||||||
|
result = $"Array<{genericArgs}>(({arrayApiType.FullNameNative}*){{0}}, {{1}})/*xviox1 {arrayTypeInfo.Type}*/";
|
||||||
|
}
|
||||||
else if (arrayApiType?.Name == "bool")
|
else if (arrayApiType?.Name == "bool")
|
||||||
{
|
{
|
||||||
type = "bool*";
|
type = "bool*";
|
||||||
result = "Array<bool>({0}, {1})";
|
result = "Array<bool>({0}, {1})/*xviox2*/\"";
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -775,11 +794,20 @@ namespace Flax.Build.Bindings
|
|||||||
type = "MArray*";
|
type = "MArray*";
|
||||||
|
|
||||||
// Scripting Objects pointers has to be converted from managed object pointer into native object pointer to use Array converted for this
|
// Scripting Objects pointers has to be converted from managed object pointer into native object pointer to use Array converted for this
|
||||||
var t = FindApiTypeInfo(buildData, typeInfo.GenericArgs[0], caller);
|
var arrayApiType = FindApiTypeInfo(buildData, typeInfo.GenericArgs[0], caller);
|
||||||
if (typeInfo.GenericArgs[0].IsPtr && t != null && t.IsScriptingObject)
|
if (typeInfo.GenericArgs[0].IsPtr && arrayApiType != null && arrayApiType.IsScriptingObject)
|
||||||
{
|
{
|
||||||
|
// TODO: array needs to be freed
|
||||||
return "MUtils::ToSpan<" + typeInfo.GenericArgs[0] + ">(" + "MUtils::ToArray<" + typeInfo.GenericArgs[0] + ">({0}))";
|
return "MUtils::ToSpan<" + typeInfo.GenericArgs[0] + ">(" + "MUtils::ToArray<" + typeInfo.GenericArgs[0] + ">({0}))";
|
||||||
}
|
}
|
||||||
|
else if (arrayApiType?.IsPod ?? false)
|
||||||
|
{
|
||||||
|
type = arrayApiType.FullNameNative + '*';
|
||||||
|
var nativeName = arrayApiType.FullNameNative;
|
||||||
|
if (typeInfo.GenericArgs[0].IsConst)
|
||||||
|
nativeName = "const " + nativeName;
|
||||||
|
return $"Span<{nativeName}>({{0}}, {{1}})/*spantag */";
|
||||||
|
}
|
||||||
|
|
||||||
return "MUtils::ToSpan<" + typeInfo.GenericArgs[0] + ">({0})";
|
return "MUtils::ToSpan<" + typeInfo.GenericArgs[0] + ">({0})";
|
||||||
}
|
}
|
||||||
@@ -1250,7 +1278,11 @@ namespace Flax.Build.Bindings
|
|||||||
if (CppParamsThatNeedConversion[i] && (!FindApiTypeInfo(buildData, parameterInfo.Type, caller)?.IsStruct ?? false))
|
if (CppParamsThatNeedConversion[i] && (!FindApiTypeInfo(buildData, parameterInfo.Type, caller)?.IsStruct ?? false))
|
||||||
{
|
{
|
||||||
name = '*' + name;
|
name = '*' + name;
|
||||||
countParamName = '*' + countParamName;
|
countParamName = '*' + countParamName + "/*plop*/";
|
||||||
|
}
|
||||||
|
else if (parameterInfo.Type.IsRef)
|
||||||
|
{
|
||||||
|
countParamName = '*' + countParamName + "/*plipa*/";
|
||||||
}
|
}
|
||||||
|
|
||||||
string param = string.Empty;
|
string param = string.Empty;
|
||||||
@@ -1348,6 +1380,25 @@ namespace Flax.Build.Bindings
|
|||||||
contents.Append(';');
|
contents.Append(';');
|
||||||
contents.AppendLine();
|
contents.AppendLine();
|
||||||
|
|
||||||
|
#if false
|
||||||
|
for (var i = 0; i < functionInfo.Parameters.Count; i++)
|
||||||
|
{
|
||||||
|
var parameterInfo = functionInfo.Parameters[i];
|
||||||
|
if (CppParamsThatNeedConversion[i] || CppParamsThatNeedLocalVariable[i])
|
||||||
|
{
|
||||||
|
var apiType = FindApiTypeInfo(buildData, parameterInfo.Type, caller);
|
||||||
|
if (parameterInfo.Type.Type == "Array")
|
||||||
|
{
|
||||||
|
contents.Append(indent).AppendLine($"/* converthing: {parameterInfo.Name} Type == {parameterInfo.Type.Type} ({parameterInfo.Type.ToString()}) */");
|
||||||
|
contents.Append(indent).AppendLine($"/* converthing2: {parameterInfo.Name} IsArray == {parameterInfo.Type.IsArray} */");
|
||||||
|
contents.Append(indent).AppendLine($"/* converthing3: {parameterInfo.Name} apitype == {apiType?.Name ?? ""} */");
|
||||||
|
//contents.Append(indent).AppendLine($"MUtils::FreeManagedArray<{parameterInfo.Type.GenericArgs[0].ToString(false)}>({parameterInfo.Name}Temp);");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Convert special parameters back to managed world
|
// Convert special parameters back to managed world
|
||||||
if (!useInlinedReturn)
|
if (!useInlinedReturn)
|
||||||
{
|
{
|
||||||
@@ -1359,6 +1410,7 @@ namespace Flax.Build.Bindings
|
|||||||
if (CppParamsThatNeedConversion[i])
|
if (CppParamsThatNeedConversion[i])
|
||||||
{
|
{
|
||||||
var value = string.Format(CppParamsThatNeedConversionWrappers[i], parameterInfo.Name + "Temp");
|
var value = string.Format(CppParamsThatNeedConversionWrappers[i], parameterInfo.Name + "Temp");
|
||||||
|
var elementType = parameterInfo.Type.GenericArgs != null ? FindApiTypeInfo(buildData, parameterInfo.Type.GenericArgs[0], caller) : null;
|
||||||
|
|
||||||
// MObject* parameters returned by reference need write barrier for GC
|
// MObject* parameters returned by reference need write barrier for GC
|
||||||
if (parameterInfo.IsOut)
|
if (parameterInfo.IsOut)
|
||||||
@@ -1368,14 +1420,30 @@ namespace Flax.Build.Bindings
|
|||||||
{
|
{
|
||||||
if (apiType.IsClass)
|
if (apiType.IsClass)
|
||||||
{
|
{
|
||||||
contents.Append(indent).AppendFormat("MCore::GC::WriteRef({0}, (MObject*){1});", parameterInfo.Name, value).AppendLine();
|
|
||||||
#if USE_NETCORE
|
#if USE_NETCORE
|
||||||
if (parameterInfo.Type.Type == "Array")
|
if (parameterInfo.Type.Type == "Array")
|
||||||
{
|
{
|
||||||
|
if (elementType?.IsPod ?? false)
|
||||||
|
{
|
||||||
|
contents.Append(indent).Append($"// isgigs1a").AppendLine();
|
||||||
|
contents.Append(indent).Append($"*{parameterInfo.Name} = ({parameterInfo.Type.GenericArgs[0]}*)MCore::GC::AllocateMemory(sizeof({parameterInfo.Type.GenericArgs[0]}) * {parameterInfo.Name}Temp.Count());").AppendLine();
|
||||||
|
contents.Append(indent).Append($"Platform::MemoryCopy(*{parameterInfo.Name}, {parameterInfo.Name}Temp.Get(), sizeof({parameterInfo.Type.GenericArgs[0]}) * {parameterInfo.Name}Temp.Count());").AppendLine();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
contents.Append(indent).Append($"// isgigs1b").AppendLine();
|
||||||
|
contents.Append(indent).AppendFormat("MCore::GC::WriteRef({0}, (MObject*){1});", parameterInfo.Name, value).AppendLine();
|
||||||
|
}
|
||||||
|
|
||||||
// Array marshallers need to know amount of items written in the buffer
|
// Array marshallers need to know amount of items written in the buffer
|
||||||
contents.Append(indent).AppendFormat("*__{0}Count = {1}.Count();", parameterInfo.Name, parameterInfo.Name + "Temp").AppendLine();
|
contents.Append(indent).AppendFormat("*__{0}Count = {1}.Count();", parameterInfo.Name, parameterInfo.Name + "Temp").AppendLine();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
contents.Append(indent).Append($"// isgigs2").AppendLine();
|
||||||
|
contents.Append(indent).AppendFormat("MCore::GC::WriteRef({0}, (MObject*){1});", parameterInfo.Name, value).AppendLine();
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (apiType.IsStruct && !apiType.IsPod)
|
if (apiType.IsStruct && !apiType.IsPod)
|
||||||
@@ -1391,22 +1459,30 @@ namespace Flax.Build.Bindings
|
|||||||
// BytesContainer
|
// BytesContainer
|
||||||
if (parameterInfo.Type.Type == "BytesContainer" && parameterInfo.Type.GenericArgs == null)
|
if (parameterInfo.Type.Type == "BytesContainer" && parameterInfo.Type.GenericArgs == null)
|
||||||
{
|
{
|
||||||
|
contents.Append(indent).Append($"// hshsf").AppendLine();
|
||||||
contents.Append(indent).AppendFormat("MCore::GC::WriteRef({0}, (MObject*){1});", parameterInfo.Name, value).AppendLine();
|
contents.Append(indent).AppendFormat("MCore::GC::WriteRef({0}, (MObject*){1});", parameterInfo.Name, value).AppendLine();
|
||||||
|
|
||||||
// Array marshallers need to know amount of items written in the buffer
|
// Array marshallers need to know amount of items written in the buffer
|
||||||
contents.Append(indent).AppendFormat("*__{0}Count = {1}.Length();", parameterInfo.Name, parameterInfo.Name + "Temp").AppendLine();
|
//contents.Append(indent).AppendFormat("*__{0}Count = {1}.Length();", parameterInfo.Name, parameterInfo.Name + "Temp").AppendLine();
|
||||||
continue;
|
//continue;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
throw new Exception($"Unsupported type of parameter '{parameterInfo}' in method '{functionInfo}' to be passed using 'out'");
|
throw new Exception($"Unsupported type of parameter '{parameterInfo}' in method '{functionInfo}' to be passed using 'out'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
contents.Append(indent).AppendFormat("*{0} = {1};", parameterInfo.Name, value).AppendLine();
|
else if (parameterInfo.Type.Type == "Array" && (elementType?.IsPod ?? false))
|
||||||
|
contents.Append(indent).AppendFormat("*{0} = {1}.data;", parameterInfo.Name, value).AppendLine();
|
||||||
|
else
|
||||||
|
contents.Append(indent).AppendFormat("*{0} = {1};", parameterInfo.Name, value).AppendLine();
|
||||||
#if USE_NETCORE
|
#if USE_NETCORE
|
||||||
if (parameterInfo.Type.Type == "Array")
|
if (parameterInfo.Type.Type == "Array" || (parameterInfo.Type.Type == "BytesContainer" && parameterInfo.Type.GenericArgs == null))
|
||||||
{
|
{
|
||||||
|
contents.Append(indent).Append("// hshshj").AppendLine();
|
||||||
// Array marshallers need to know amount of items written in the buffer
|
// Array marshallers need to know amount of items written in the buffer
|
||||||
contents.Append(indent).AppendFormat("*__{0}Count = {1}.Count();", parameterInfo.Name, parameterInfo.Name + "Temp").AppendLine();
|
if (parameterInfo.Type.Type is "Span" or "BytesContainer")
|
||||||
|
contents.Append(indent).AppendFormat("*__{0}Count = {1}.Length();", parameterInfo.Name, parameterInfo.Name + "Temp").AppendLine();
|
||||||
|
else
|
||||||
|
contents.Append(indent).AppendFormat("*__{0}Count = {1}.Count();", parameterInfo.Name, parameterInfo.Name + "Temp").AppendLine();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1721,6 +1797,52 @@ namespace Flax.Build.Bindings
|
|||||||
contents.Append($" MCore::GCHandle::Free(__param{i}_handle);").AppendLine();
|
contents.Append($" MCore::GCHandle::Free(__param{i}_handle);").AppendLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (paramValue.Contains("MUtils::ToArray(")) // FIXME
|
||||||
|
{
|
||||||
|
var genericType = parameterInfo.Type.GenericArgs[0].ToString(false);
|
||||||
|
if (paramIsRef)
|
||||||
|
{
|
||||||
|
//contents.Append($" MUtils::FreeManaged<{parameterInfo.Type.ToString(false)}>((MObject*)__param_{parameterInfo.Name});").AppendLine();
|
||||||
|
/*if (useThunk)
|
||||||
|
{
|
||||||
|
// Release the original handle
|
||||||
|
contents.Append($" if (__param_orig_{parameterInfo.Name} != __param_{parameterInfo.Name}) //asdf1a").AppendLine();
|
||||||
|
contents.Append($" MUtils::FreeManaged<{parameterInfo.Type.ToString(false)}>((MObject*)__param_{parameterInfo.Name});").AppendLine();
|
||||||
|
}*/
|
||||||
|
contents.Append($" MUtils::FreeManagedArray<{genericType}>(__param_{parameterInfo.Name}); //fgfgh3").AppendLine();
|
||||||
|
if (useThunk)
|
||||||
|
{
|
||||||
|
// Release the original handle
|
||||||
|
contents.Append($" if (__param_orig_{parameterInfo.Name} != __param_{ parameterInfo.Name})").AppendLine();
|
||||||
|
contents.Append($" MUtils::FreeManagedArray<{genericType}>(__param_orig_{parameterInfo.Name}); //fgfgh4").AppendLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (apiType != null && !apiType.IsInBuild)
|
||||||
|
{
|
||||||
|
// int: ispod, isvaluetype
|
||||||
|
// vector: ispod, isvaluetype, isstruct
|
||||||
|
// guid: ispod, isvaluetype, isstruct, isinbuild
|
||||||
|
contents.Append($" MUtils::FreeManagedArray<{genericType}>((MArray*)params[{i}]); //fgfgh5").AppendLine();
|
||||||
|
//contents.Append($" auto __param{i}_handle = *(MGCHandle*)¶ms[{i}]; // asdf1b").AppendLine();
|
||||||
|
//contents.Append($" ASSERT((((unsigned long long)__param{i}_handle & 0xC000000000000000) >> 62) == 0);").AppendLine();
|
||||||
|
//contents.Append($" MCore::GCHandle::Free(__param{i}_handle);").AppendLine();
|
||||||
|
}
|
||||||
|
else if (apiType != null && !apiType.IsValueType)
|
||||||
|
{
|
||||||
|
if (parameterInfo.Type.Type.ToLower().Contains("string"))
|
||||||
|
apiType = apiType;
|
||||||
|
contents.Append($" MUtils::FreeManagedArray<{genericType}>((MArray*)params[{i}]); //fgfgh6").AppendLine();
|
||||||
|
}
|
||||||
|
else //if (apiType != null)
|
||||||
|
{
|
||||||
|
if (parameterInfo.Type.Type.ToLower().Contains("string"))
|
||||||
|
apiType = apiType;
|
||||||
|
//contents.Append($" //asdf1c {parameterInfo.Type.Type}").AppendLine();
|
||||||
|
contents.Append($" auto __param{i}_handle = *(MGCHandle*)¶ms[{i}]; //fgfgh7").AppendLine();
|
||||||
|
//contents.Append($" ASSERT((((unsigned long long)__param{i}_handle & 0xC000000000000000) >> 62) == 0);").AppendLine();
|
||||||
|
contents.Append($" MCore::GCHandle::Free(__param{i}_handle);").AppendLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
contents.AppendLine(" WrapperCallInstance = prevWrapperCallInstance;");
|
contents.AppendLine(" WrapperCallInstance = prevWrapperCallInstance;");
|
||||||
@@ -3108,7 +3230,9 @@ namespace Flax.Build.Bindings
|
|||||||
header.AppendFormat(" DLLEXPORT USED MObject* Box(const {0}& data, const MClass* klass)", fullName).AppendLine();
|
header.AppendFormat(" DLLEXPORT USED MObject* Box(const {0}& data, const MClass* klass)", fullName).AppendLine();
|
||||||
header.Append(" {").AppendLine();
|
header.Append(" {").AppendLine();
|
||||||
header.Append(" auto managed = ToManaged(data);").AppendLine();
|
header.Append(" auto managed = ToManaged(data);").AppendLine();
|
||||||
header.Append(" return MCore::Object::Box((void*)&managed, klass);").AppendLine();
|
header.Append(" auto boxed = MCore::Object::Box((void*)&managed, klass);").AppendLine();
|
||||||
|
header.Append(" ::FreeManaged(managed);").AppendLine();
|
||||||
|
header.Append(" return boxed;").AppendLine();
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
|
|
||||||
header.AppendFormat(" DLLEXPORT USED void Unbox({0}& result, MObject* data)", fullName).AppendLine();
|
header.AppendFormat(" DLLEXPORT USED void Unbox({0}& result, MObject* data)", fullName).AppendLine();
|
||||||
@@ -3125,8 +3249,8 @@ namespace Flax.Build.Bindings
|
|||||||
header.AppendFormat(" {0}* resultPtr = ({0}*)MCore::Array::GetAddress(result);", wrapperName).AppendLine();
|
header.AppendFormat(" {0}* resultPtr = ({0}*)MCore::Array::GetAddress(result);", wrapperName).AppendLine();
|
||||||
header.Append(" for (int32 i = 0; i < data.Length(); i++)").AppendLine();
|
header.Append(" for (int32 i = 0; i < data.Length(); i++)").AppendLine();
|
||||||
header.Append(" {").AppendLine();
|
header.Append(" {").AppendLine();
|
||||||
header.Append(" auto managed = ToManaged(data[i]);").AppendLine();
|
header.Append(" auto managed = ToManaged(data[i]);").AppendLine();
|
||||||
header.Append(" MCore::GC::WriteValue(&resultPtr[i], &managed, 1, klass);").AppendLine();
|
header.Append(" MCore::GC::WriteValue(&resultPtr[i], &managed, 1, klass);").AppendLine();
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
|
|
||||||
@@ -3134,14 +3258,32 @@ namespace Flax.Build.Bindings
|
|||||||
header.Append(" {").AppendLine();
|
header.Append(" {").AppendLine();
|
||||||
header.AppendFormat(" {0}* dataPtr = ({0}*)MCore::Array::GetAddress(data);", wrapperName).AppendLine();
|
header.AppendFormat(" {0}* dataPtr = ({0}*)MCore::Array::GetAddress(data);", wrapperName).AppendLine();
|
||||||
header.Append(" for (int32 i = 0; i < result.Length(); i++)").AppendLine();
|
header.Append(" for (int32 i = 0; i < result.Length(); i++)").AppendLine();
|
||||||
header.Append(" result[i] = ToNative(dataPtr[i]);").AppendLine();
|
header.Append(" result[i] = ToNative(dataPtr[i]);").AppendLine();
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
|
|
||||||
header.AppendFormat(" DLLEXPORT USED void FreeManaged(MObject* data)", fullName).AppendLine();
|
header.AppendFormat(" DLLEXPORT USED void FreeManaged(MObject* data)").AppendLine();
|
||||||
header.Append(" {").AppendLine();
|
header.Append(" {").AppendLine();
|
||||||
|
if (false) // FIXME: unboxing allocates temporary handles which FreeManaged does not free...
|
||||||
|
{
|
||||||
|
header.AppendFormat(" auto managed = reinterpret_cast<{0}*>(MCore::Object::Unbox(data));", wrapperName).AppendLine();
|
||||||
|
header.Append(" ::FreeManaged(*managed);").AppendLine();
|
||||||
|
}
|
||||||
|
header.Append(" MCore::GCHandle::Free(*(MGCHandle*)&data);").AppendLine();
|
||||||
|
header.Append(" }").AppendLine();
|
||||||
|
|
||||||
|
header.AppendFormat(" DLLEXPORT USED void FreeManagedArray(MArray* array)").AppendLine();
|
||||||
|
header.Append(" {").AppendLine();
|
||||||
|
header.AppendFormat(" {0}* resultPtr = ({0}*)MCore::Array::GetAddress(array);", wrapperName).AppendLine();
|
||||||
|
header.Append(" const auto length = MCore::Array::GetLength(array);").AppendLine();
|
||||||
|
header.Append(" for (int32 i = 0; i < length; ++i)").AppendLine();
|
||||||
|
header.Append(" {").AppendLine();
|
||||||
|
header.AppendFormat(" ::FreeManaged(*reinterpret_cast<{0}*>(&resultPtr[i]));", wrapperName).AppendLine();
|
||||||
|
header.Append(" }").AppendLine();
|
||||||
|
//header.Append(" PLATFORM_DEBUG_BREAK; // FIXME 1").AppendLine();
|
||||||
//header.AppendFormat(" auto managed = MCore::Object::Unbox(data);", wrapperName).AppendLine();
|
//header.AppendFormat(" auto managed = MCore::Object::Unbox(data);", wrapperName).AppendLine();
|
||||||
//header.AppendFormat(" ::FreeManaged(*reinterpret_cast<{0}*>(managed));", wrapperName).AppendLine();
|
//header.AppendFormat(" ::FreeManaged(*reinterpret_cast<{0}*>(managed));", wrapperName).AppendLine();
|
||||||
header.AppendFormat(" MCore::GCHandle::Free(*(MGCHandle*)&data);", wrapperName).AppendLine();
|
header.Append(" MCore::Array::Free(array);").AppendLine();
|
||||||
|
header.Append(" MCore::GCHandle::Free(*(MGCHandle*)&array);").AppendLine();
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
|
|
||||||
header.Append('}').Append(';').AppendLine();
|
header.Append('}').Append(';').AppendLine();
|
||||||
@@ -3191,9 +3333,11 @@ namespace Flax.Build.Bindings
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
CppNonPodTypesConvertingGeneration = true;
|
CppNonPodTypesConvertingGeneration = true;
|
||||||
var wrapper = GenerateCppWrapperManagedToNative(buildData, fieldInfo.Type, apiType, out _, out _, null, out _);
|
var wrapper = GenerateCppWrapperManagedToNative(buildData, fieldInfo.Type, apiType, out var fieldTypeName, out var fieldType, null, out _);
|
||||||
CppNonPodTypesConvertingGeneration = false;
|
CppNonPodTypesConvertingGeneration = false;
|
||||||
|
|
||||||
|
var arrayCountName = $"value.{fieldInfo.Name}.length";
|
||||||
|
|
||||||
if (fieldInfo.Type.IsArray)
|
if (fieldInfo.Type.IsArray)
|
||||||
{
|
{
|
||||||
// Fixed-size array needs to unbox every item manually
|
// Fixed-size array needs to unbox every item manually
|
||||||
@@ -3206,7 +3350,7 @@ namespace Flax.Build.Bindings
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wrapper = string.Format(wrapper.Remove(wrapper.Length - 6), string.Format("value.{0}", fieldInfo.Name));
|
wrapper = string.Format(wrapper.Remove(wrapper.Length - 6), string.Format("value.{0}", fieldInfo.Name), arrayCountName);
|
||||||
header.AppendFormat(" auto tmp{0} = {1};", fieldInfo.Name, wrapper).AppendLine();
|
header.AppendFormat(" auto tmp{0} = {1};", fieldInfo.Name, wrapper).AppendLine();
|
||||||
header.AppendFormat(" for (int32 i = 0; i < {0} && i < tmp{1}.Count(); i++)", fieldInfo.Type.ArraySize, fieldInfo.Name).AppendLine();
|
header.AppendFormat(" for (int32 i = 0; i < {0} && i < tmp{1}.Count(); i++)", fieldInfo.Type.ArraySize, fieldInfo.Name).AppendLine();
|
||||||
header.AppendFormat(" result.{0}[i] = tmp{0}[i];", fieldInfo.Name).AppendLine();
|
header.AppendFormat(" result.{0}[i] = tmp{0}[i];", fieldInfo.Name).AppendLine();
|
||||||
@@ -3217,7 +3361,22 @@ namespace Flax.Build.Bindings
|
|||||||
if (string.IsNullOrEmpty(wrapper))
|
if (string.IsNullOrEmpty(wrapper))
|
||||||
header.AppendFormat(" result.{0} = value.{0};", fieldInfo.Name).AppendLine();
|
header.AppendFormat(" result.{0} = value.{0};", fieldInfo.Name).AppendLine();
|
||||||
else
|
else
|
||||||
header.AppendFormat(" result.{0} = {1};", fieldInfo.Name, string.Format(wrapper, string.Format("value.{0}", fieldInfo.Name))).AppendLine();
|
{
|
||||||
|
var arrayElementType = fieldInfo.Type.GenericArgs != null ? FindApiTypeInfo(buildData, fieldInfo.Type.GenericArgs[0], apiType) : null;
|
||||||
|
var ispod = (arrayElementType?.IsPod.ToString() ?? "null");
|
||||||
|
header.Append($" // {fieldInfo.Type.Type}, {fieldType?.FullNameNative}, {fieldType?.Name}, {fieldTypeName}, {ispod}").AppendLine();
|
||||||
|
if (fieldInfo.Type.IsArrayOrSpan && (arrayElementType?.IsPod ?? false))
|
||||||
|
{
|
||||||
|
header.AppendFormat(" result.{0} = {1}; /*kaek1 */", fieldInfo.Name, string.Format(wrapper, $"value.{fieldInfo.Name}.data", $"value.{fieldInfo.Name}.length")).AppendLine();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
header.AppendFormat(" result.{0} = {1}; /*kaek2 */", fieldInfo.Name, string.Format(wrapper, $"value.{fieldInfo.Name}", $"value.{fieldInfo.Name}.lengthnot")).AppendLine();
|
||||||
|
}
|
||||||
|
//var fieldType = FindApiTypeInfo(buildData, fieldInfo.Type, apiType);
|
||||||
|
|
||||||
|
//header.AppendFormat(" result.{0} = {1}; /*kaek2*/", fieldInfo.Name, string.Format(wrapper, $"value.{fieldInfo.Name}")).AppendLine();
|
||||||
|
}
|
||||||
/*if (wrapper.Contains("::ToNative(")) // FIXME
|
/*if (wrapper.Contains("::ToNative(")) // FIXME
|
||||||
{
|
{
|
||||||
header.Append($" auto __param{fieldInfo.Name}_handle = *(MGCHandle*)&value.{fieldInfo.Name};").AppendLine();
|
header.Append($" auto __param{fieldInfo.Name}_handle = *(MGCHandle*)&value.{fieldInfo.Name};").AppendLine();
|
||||||
@@ -3242,15 +3401,85 @@ namespace Flax.Build.Bindings
|
|||||||
var wrapper = GenerateCppWrapperManagedToNative(buildData, fieldInfo.Type, apiType, out var managedType, out var fieldApiType, null, out _);
|
var wrapper = GenerateCppWrapperManagedToNative(buildData, fieldInfo.Type, apiType, out var managedType, out var fieldApiType, null, out _);
|
||||||
CppNonPodTypesConvertingGeneration = false;
|
CppNonPodTypesConvertingGeneration = false;
|
||||||
|
|
||||||
if (wrapper.Contains("::ToNative(")) // FIXME fieldApiType.IsScriptingObject
|
if (fieldInfo.Type.IsArray)
|
||||||
{
|
{
|
||||||
|
//header.Append($" fixed_array_type = fixed_array_type; // {fieldInfo.Name} ({managedType}) is fixed array").AppendLine();
|
||||||
|
}
|
||||||
|
else if (string.IsNullOrEmpty(wrapper))
|
||||||
|
{
|
||||||
|
if (managedType == "bool")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (fieldInfo.Type.Type == "String" || managedType == "MString*")
|
||||||
|
{
|
||||||
|
if (fieldInfo.Type.Type != "String")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
if (managedType != "MString*")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
header.Append($" MCore::String::Free(value.{fieldInfo.Name});").AppendLine();
|
||||||
|
}
|
||||||
|
else if (fieldInfo.Type.Type == "Span")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (fieldInfo.Type.Type == "Array")
|
||||||
|
{
|
||||||
|
if (managedType == "MArray*")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (managedType == "Char*" || managedType == "char*")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//header.Append($" unhandled_type = unhandled_type; // {fieldInfo.Name} ({managedType}) should be cleaned? // asdfggg56").AppendLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (fieldApiType == null)
|
||||||
|
{
|
||||||
|
header.Append($" weird_type = weird_type; // {fieldInfo.Name} ({managedType}) is a weird one // okdfiodftg").AppendLine();
|
||||||
|
}
|
||||||
|
else if (fieldApiType.IsScriptingObject)
|
||||||
|
{
|
||||||
|
header.Append($" // {fieldInfo.Name} is a permanent handle // asdf2").AppendLine();
|
||||||
|
}
|
||||||
|
else if (!fieldApiType.IsPod) // FIXMEb
|
||||||
|
{
|
||||||
|
if (fieldApiType.IsClass)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
header.Append($" ::FreeManaged(value.{fieldInfo.Name}); // asdfggg588").AppendLine();
|
||||||
|
//header.Append($" unhandled_type = unhandled_type; // {fieldInfo.Name} ({managedType}) should be cleaned? // asdfggg588").AppendLine();
|
||||||
|
}
|
||||||
header.Append($" auto __param{fieldInfo.Name}_handle = *(MGCHandle*)&value.{fieldInfo.Name};").AppendLine();
|
header.Append($" auto __param{fieldInfo.Name}_handle = *(MGCHandle*)&value.{fieldInfo.Name};").AppendLine();
|
||||||
//header.Append($" ASSERT((((unsigned long long)__param{fieldInfo.Name}_handle & 0xC000000000000000) >> 62) == 0); // asdf3").AppendLine();
|
//header.Append($" ASSERT((((unsigned long long)__param{fieldInfo.Name}_handle & 0xC000000000000000) >> 62) == 0); // asdf3").AppendLine();
|
||||||
header.Append($" if ((((unsigned long long)__param{fieldInfo.Name}_handle & 0xC000000000000000) >> 62) != 0) // asdf3").AppendLine();
|
header.Append($" if ((((unsigned long long)__param{fieldInfo.Name}_handle & 0xC000000000000000) >> 62) != 0) // asdf3").AppendLine();
|
||||||
header.Append($" __param{fieldInfo.Name}_handle = __param{fieldInfo.Name}_handle;").AppendLine();
|
header.Append($" __param{fieldInfo.Name}_handle = __param{fieldInfo.Name}_handle;").AppendLine();
|
||||||
|
|
||||||
header.Append($" MCore::GCHandle::Free(__param{fieldInfo.Name}_handle);").AppendLine();
|
header.Append($" MCore::GCHandle::Free(__param{fieldInfo.Name}_handle);").AppendLine();
|
||||||
}
|
}
|
||||||
|
else if (fieldApiType.IsPod)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (classInfo != null)
|
if (classInfo != null)
|
||||||
{
|
{
|
||||||
@@ -3337,9 +3566,27 @@ namespace Flax.Build.Bindings
|
|||||||
header.AppendFormat(" Unbox(result[i], dataPtr[i]);", fullName).AppendLine();
|
header.AppendFormat(" Unbox(result[i], dataPtr[i]);", fullName).AppendLine();
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
|
|
||||||
header.AppendFormat(" DLLEXPORT USED void FreeManaged(MObject* data) // honk1", fullName).AppendLine();
|
header.AppendFormat(" DLLEXPORT USED void FreeManaged(MObject* data)").AppendLine();
|
||||||
header.Append(" {").AppendLine();
|
header.Append(" {").AppendLine();
|
||||||
//header.Append(" ::FreeManaged(reinterpret_cast<OnlineUserManaged*>(MCore::Object::Unbox(data)));").AppendLine();
|
header.Append(" PLATFORM_DEBUG_BREAK; // FIXME 2b").AppendLine();
|
||||||
|
header.Append(" MCore::GCHandle::Free(*(MGCHandle*)&data);").AppendLine();
|
||||||
|
header.Append(" }").AppendLine();
|
||||||
|
|
||||||
|
header.AppendFormat(" DLLEXPORT USED void FreeManagedArray(MArray* array)").AppendLine();
|
||||||
|
header.Append(" {").AppendLine();
|
||||||
|
header.Append(" PLATFORM_DEBUG_BREAK; // FIXME 2").AppendLine();
|
||||||
|
header.Append(" MObject** resultPtr = (MObject**)MCore::Array::GetAddress(array);").AppendLine();
|
||||||
|
header.Append(" const auto length = MCore::Array::GetLength(array);").AppendLine();
|
||||||
|
header.Append(" for (int32 i = 0; i < length; ++i)").AppendLine();
|
||||||
|
header.Append(" {").AppendLine();
|
||||||
|
header.Append(" FreeManaged(resultPtr[i]);").AppendLine();
|
||||||
|
//header.AppendFormat(" MCore::GCHandle::Free(*(MGCHandle*)&resultPtr[i]);", wrapperName).AppendLine();
|
||||||
|
header.Append(" }").AppendLine();
|
||||||
|
//header.Append(" PLATFORM_DEBUG_BREAK; // FIXME 1").AppendLine();
|
||||||
|
//header.AppendFormat(" auto managed = MCore::Object::Unbox(data);", wrapperName).AppendLine();
|
||||||
|
//header.AppendFormat(" ::FreeManaged(*reinterpret_cast<{0}*>(managed));", wrapperName).AppendLine();
|
||||||
|
header.Append(" MCore::Array::Free(array);").AppendLine();
|
||||||
|
header.Append(" MCore::GCHandle::Free(*(MGCHandle*)&array);").AppendLine();
|
||||||
header.Append(" }").AppendLine();
|
header.Append(" }").AppendLine();
|
||||||
|
|
||||||
header.Append('}').Append(';').AppendLine();
|
header.Append('}').Append(';').AppendLine();
|
||||||
|
|||||||
@@ -18,30 +18,42 @@ namespace Flax.Build.Bindings
|
|||||||
public bool IsRef;
|
public bool IsRef;
|
||||||
public bool IsMoveRef;
|
public bool IsMoveRef;
|
||||||
public bool IsPtr;
|
public bool IsPtr;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is this a fixed-length type of array.
|
||||||
|
/// </summary>
|
||||||
public bool IsArray;
|
public bool IsArray;
|
||||||
|
|
||||||
|
|
||||||
public bool IsBitField;
|
public bool IsBitField;
|
||||||
public int ArraySize;
|
public int ArraySize;
|
||||||
public int BitSize;
|
public int BitSize;
|
||||||
public List<TypeInfo> GenericArgs;
|
public List<TypeInfo> GenericArgs;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this type is void.
|
/// Is this a void type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsVoid => Type == "void" && !IsPtr;
|
public bool IsVoid => Type == "void" && !IsPtr;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this type is constant reference to a value.
|
/// Is this a constant reference to a value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsConstRef => IsRef && IsConst;
|
public bool IsConstRef => IsRef && IsConst;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this type is a reference to another object.
|
/// Is this a reference to another FlaxEngine.Object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsObjectRef => (Type == "ScriptingObjectReference" ||
|
public bool IsObjectRef => Type is "ScriptingObjectReference"
|
||||||
Type == "AssetReference" ||
|
or "AssetReference"
|
||||||
Type == "WeakAssetReference" ||
|
or "WeakAssetReference"
|
||||||
Type == "SoftAssetReference" ||
|
or "SoftAssetReference"
|
||||||
Type == "SoftObjectReference") && GenericArgs != null;
|
or "SoftObjectReference"
|
||||||
|
&& GenericArgs != null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is this an inbuilt container type.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsArrayOrSpan => Type is "Array" or "Span" or "DataContainer" or "BytesContainer";
|
||||||
|
|
||||||
public TypeInfo()
|
public TypeInfo()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user