initial nativestring and nativearray marshalling
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Cooker / Cook (Mac) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Cooker / Cook (Mac) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled
This commit is contained in:
@@ -47,6 +47,7 @@ static_assert(sizeof(InternalImpulse) == sizeof(AnimGraphImpulse), "Please updat
|
||||
|
||||
DEFINE_INTERNAL_CALL(bool) AnimGraphInternal_HasConnection(InternalContext* context, int32 boxId)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
const auto box = context->Node->TryGetBox(boxId);
|
||||
if (box == nullptr)
|
||||
DebugLog::ThrowArgumentOutOfRange("boxId");
|
||||
@@ -55,6 +56,7 @@ DEFINE_INTERNAL_CALL(bool) AnimGraphInternal_HasConnection(InternalContext* cont
|
||||
|
||||
DEFINE_INTERNAL_CALL(MObject*) AnimGraphInternal_GetInputValue(InternalContext* context, int32 boxId)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
const auto box = context->Node->TryGetBox(boxId);
|
||||
if (box == nullptr)
|
||||
DebugLog::ThrowArgumentOutOfRange("boxId");
|
||||
@@ -72,6 +74,7 @@ DEFINE_INTERNAL_CALL(MObject*) AnimGraphInternal_GetInputValue(InternalContext*
|
||||
|
||||
DEFINE_INTERNAL_CALL(AnimGraphImpulse*) AnimGraphInternal_GetOutputImpulseData(InternalContext* context)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
const auto nodes = context->Node->GetNodes(context->GraphExecutor);
|
||||
context->GraphExecutor->InitNodes(nodes);
|
||||
return nodes;
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace FlaxEditor.Content.Settings
|
||||
/// <returns>The layers.</returns>
|
||||
public static string[] GetCurrentLayers()
|
||||
{
|
||||
return GetCurrentLayers(out int _);
|
||||
return Internal_GetCurrentLayers();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -56,7 +56,7 @@ namespace FlaxEditor.Content.Settings
|
||||
}
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "LayersAndTagsSettingsInternal_GetCurrentLayers", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
[return: MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "layerCount")]
|
||||
internal static partial string[] GetCurrentLayers(out int layerCount);
|
||||
[return: MarshalUsing(typeof(FlaxEngine.Interop.NativeSpanMarshaller<string, FlaxEngine.Interop.NativeString>), ConstantElementCount = FlaxEngine.Interop.MarshallerFlags.SkipDisposeElements)]
|
||||
internal static partial string[] Internal_GetCurrentLayers();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,11 +183,11 @@ namespace FlaxEngine.Interop
|
||||
if (returnType == typeof(string))
|
||||
return ManagedString.ToNative/*Weak*/(Unsafe.As<string>(returnObject));
|
||||
if (returnType == typeof(IntPtr))
|
||||
return (IntPtr)(object)returnObject;
|
||||
return (IntPtr)returnObject;
|
||||
if (returnType == typeof(ManagedHandle))
|
||||
return ManagedHandle.ToIntPtr((ManagedHandle)(object)returnObject);
|
||||
return ManagedHandle.ToIntPtr((ManagedHandle)returnObject);
|
||||
if (returnType == typeof(Type) || returnType == typeof(TypeHolder))
|
||||
return returnObject != null ? ManagedHandle.ToIntPtr(GetTypeManagedHandle(Unsafe.As<Type>(returnObject))) : IntPtr.Zero;
|
||||
return ManagedHandle.ToIntPtr(GetTypeManagedHandle(Unsafe.As<Type>(returnObject)));
|
||||
if (returnType.IsArray)
|
||||
{
|
||||
var elementType = returnType.GetElementType();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma warning disable CS0162
|
||||
#define USE_CONCURRENT_DICT
|
||||
#define USE_GCHANDLE
|
||||
//#define TRACK_HANDLES
|
||||
@@ -311,20 +311,24 @@ namespace FlaxEngine.Interop
|
||||
{
|
||||
internal static ManagedHandle EmptyStringHandle = ManagedHandle.Alloc(string.Empty);
|
||||
|
||||
[System.Diagnostics.DebuggerStepThrough]
|
||||
//[System.Diagnostics.DebuggerStepThrough]
|
||||
public static unsafe IntPtr ToNative(string str)
|
||||
{
|
||||
if (str == null)
|
||||
return IntPtr.Zero;
|
||||
else if (str == string.Empty)
|
||||
return ManagedHandle.ToIntPtr(EmptyStringHandle);
|
||||
Assert.IsTrue(str.Length > 0);
|
||||
return ManagedHandle.ToIntPtr(str);
|
||||
//else if (str == string.Empty)
|
||||
// return ManagedHandle.ToIntPtr(EmptyStringHandle);
|
||||
//return ManagedHandle.ToIntPtr(str);
|
||||
|
||||
NativeString* nativeString = (NativeString*)NativeMemory.AlignedAlloc((UIntPtr)Unsafe.SizeOf<NativeString>(), 16);
|
||||
*nativeString = new NativeString(str);
|
||||
return (IntPtr)nativeString;
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerStepThrough]
|
||||
//[System.Diagnostics.DebuggerStepThrough]
|
||||
public static unsafe IntPtr ToNativeWeak(string str)
|
||||
{
|
||||
throw new Exception("not used");
|
||||
if (str == null)
|
||||
return IntPtr.Zero;
|
||||
else if (str == string.Empty)
|
||||
@@ -333,28 +337,39 @@ namespace FlaxEngine.Interop
|
||||
return ManagedHandle.ToIntPtr(str, GCHandleType.Weak);
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerStepThrough]
|
||||
public static string ToManaged(IntPtr ptr)
|
||||
//[System.Diagnostics.DebuggerStepThrough]
|
||||
public static unsafe string ToManaged(IntPtr ptr)
|
||||
{
|
||||
if (ptr == IntPtr.Zero)
|
||||
return null;
|
||||
return Unsafe.As<string>(ManagedHandle.FromIntPtr(ptr).Target);
|
||||
//return Unsafe.As<string>(ManagedHandle.FromIntPtr(ptr).Target);
|
||||
NativeString* str = (NativeString*)ptr.ToPointer();
|
||||
return str->ToString();
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerStepThrough]
|
||||
public static void Free(IntPtr ptr)
|
||||
//[System.Diagnostics.DebuggerStepThrough]
|
||||
public static unsafe void Free(IntPtr ptr)
|
||||
{
|
||||
if (ptr == IntPtr.Zero)
|
||||
return;
|
||||
ManagedHandle handle = ManagedHandle.FromIntPtr(ptr);
|
||||
if (handle == EmptyStringHandle)
|
||||
return;
|
||||
handle.Free();
|
||||
//ManagedHandle handle = ManagedHandle.FromIntPtr(ptr);
|
||||
//if (handle == EmptyStringHandle)
|
||||
// return;
|
||||
//handle.Free();
|
||||
Free((NativeString*)ptr.ToPointer());
|
||||
}
|
||||
|
||||
//[System.Diagnostics.DebuggerStepThrough]
|
||||
public static unsafe void Free(NativeString* str)
|
||||
{
|
||||
if (str->Data != null)
|
||||
NativeMemory.AlignedFree(str->Data);
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerStepThrough]
|
||||
public static void Free(ManagedHandle handle)
|
||||
{
|
||||
throw new Exception("not used");
|
||||
if (handle == EmptyStringHandle)
|
||||
return;
|
||||
handle.Free();
|
||||
@@ -537,7 +552,8 @@ namespace FlaxEngine.Interop
|
||||
internal static class ManagedHandlePool
|
||||
{
|
||||
[ThreadStatic]
|
||||
private static List<(bool InUse, ManagedHandle Handle)> _pool;
|
||||
private static List<(bool InUse, ManagedHandle Handle)> __poolField;
|
||||
private static List<(bool InUse, ManagedHandle Handle)> _pool => __poolField ??= [];
|
||||
|
||||
internal static void TryCollectWeakHandles(bool force = false)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -527,34 +527,49 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle NewArray(ManagedHandle typeHandle, long size)
|
||||
internal static IntPtr NewArray(ManagedHandle typeHandle, long size)
|
||||
{
|
||||
Type elementType = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
Type marshalledType = ArrayFactory.GetMarshalledType(elementType);
|
||||
Type arrayType = ArrayFactory.GetArrayType(elementType);
|
||||
if (marshalledType.IsValueType)
|
||||
{
|
||||
ManagedArray managedArray = ManagedArray.AllocateNewArray((int)size, arrayType, marshalledType);
|
||||
return ManagedHandle.Alloc(managedArray);
|
||||
IntPtr arrayPtr = (IntPtr)NativeMemory.AlignedAlloc((UIntPtr)Unsafe.SizeOf<NativeArrayTypeless>(), 16);
|
||||
IntPtr dataPtr = (IntPtr)NativeMemory.AlignedAlloc((UIntPtr)(RuntimeHelpers.SizeOf(marshalledType.TypeHandle) * size), 16);
|
||||
Unsafe.Write<IntPtr>(arrayPtr.ToPointer(), dataPtr);
|
||||
Unsafe.Write<long>(IntPtr.Add(arrayPtr, Unsafe.SizeOf<IntPtr>()).ToPointer(), size);
|
||||
|
||||
return arrayPtr;
|
||||
//ManagedArray managedArray = ManagedArray.AllocateNewArray((int)size, arrayType, marshalledType);
|
||||
//return ManagedHandle.Alloc(managedArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array arr = ArrayFactory.CreateArray(elementType, size);
|
||||
/*Array arr = ArrayFactory.CreateArray(elementType, size);
|
||||
ManagedArray managedArray = ManagedArray.WrapNewArray(arr, arrayType);
|
||||
return ManagedHandle.Alloc(managedArray);
|
||||
return ManagedHandle.Alloc(managedArray);*/
|
||||
IntPtr arrayPtr = (IntPtr)NativeMemory.AlignedAlloc((UIntPtr)Unsafe.SizeOf<NativeArrayTypeless>(), 16);
|
||||
IntPtr dataPtr = (IntPtr)NativeMemory.AlignedAlloc((UIntPtr)(Unsafe.SizeOf<IntPtr>() * size), 16);
|
||||
Unsafe.Write<IntPtr>(arrayPtr.ToPointer(), dataPtr);
|
||||
Unsafe.Write<long>(IntPtr.Add(arrayPtr, Unsafe.SizeOf<IntPtr>()).ToPointer(), size);
|
||||
|
||||
return arrayPtr;
|
||||
}
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void FreeArray(ManagedHandle handle)
|
||||
internal static void FreeArray(void* ptr)
|
||||
{
|
||||
if (!handle.IsAllocated)
|
||||
if (ptr == null)
|
||||
return;
|
||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(handle.Target);
|
||||
|
||||
NativeArrayTypeless* array = (NativeArrayTypeless*)ptr;
|
||||
array->Free();
|
||||
/*ManagedArray managedArray = Unsafe.As<ManagedArray>(handle.Target);
|
||||
if (managedArray.ElementType.IsValueType)
|
||||
managedArray.Free();
|
||||
else
|
||||
managedArray.FreePooled();
|
||||
managedArray.FreePooled();*/
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
@@ -575,14 +590,15 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static IntPtr GetArrayPointer(ManagedHandle arrayHandle)
|
||||
internal static IntPtr GetArrayPointer(void* ptr)
|
||||
{
|
||||
if (!arrayHandle.IsAllocated)
|
||||
if (ptr == null)
|
||||
return IntPtr.Zero;
|
||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(arrayHandle.Target);
|
||||
if (managedArray.Length == 0)
|
||||
NativeArrayTypeless* array = (NativeArrayTypeless*)ptr;
|
||||
if (array->Length == 0)
|
||||
return IntPtr.Zero;
|
||||
return managedArray.Pointer;
|
||||
|
||||
return (IntPtr)array->Data;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
@@ -599,12 +615,16 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static int GetArrayLength(ManagedHandle arrayHandle)
|
||||
internal static int GetArrayLength(void* ptr)
|
||||
{
|
||||
if (!arrayHandle.IsAllocated)
|
||||
return 0;
|
||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(arrayHandle.Target);
|
||||
return managedArray.Length;
|
||||
//if (ptr == null)
|
||||
// return 0;
|
||||
NativeArrayTypeless* array = (NativeArrayTypeless*)ptr;
|
||||
return array->Length;
|
||||
/* if (!arrayHandle.IsAllocated)
|
||||
return 0;
|
||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(arrayHandle.Target);
|
||||
return managedArray.Length;*/
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
@@ -626,9 +646,9 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void FreeString(ManagedHandle handle)
|
||||
internal static void FreeString(NativeString* str)
|
||||
{
|
||||
ManagedString.Free(handle);
|
||||
ManagedString.Free(str);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
|
||||
@@ -198,8 +198,8 @@ namespace FlaxEngine.Interop
|
||||
public static T[] GCHandleArrayToManagedArray<T>(NativeArray<IntPtr> ptrArray, T[] buffer = null) where T : class
|
||||
{
|
||||
ReadOnlySpan<IntPtr> span = ptrArray.AsReadOnlySpan();
|
||||
if (buffer != null)
|
||||
buffer = buffer;
|
||||
//if (buffer != null)
|
||||
// buffer = buffer;
|
||||
if (buffer == null || buffer.Length < ptrArray.Length)
|
||||
buffer = new T[ptrArray.Length];
|
||||
for (int i = 0; i < ptrArray.Length; i++)
|
||||
@@ -426,7 +426,7 @@ namespace FlaxEngine.Interop
|
||||
|
||||
if (!toManagedMarshallers.TryGetValue(type, out var deleg))
|
||||
deleg = toManagedMarshallers.GetOrAdd(type, Factory);
|
||||
return deleg(nativePtr, type.IsByRef);
|
||||
return deleg(nativePtr, type.IsByRef && false);
|
||||
}
|
||||
|
||||
internal static void MarshalToNative(object managedObject, IntPtr nativePtr, Type type)
|
||||
@@ -552,6 +552,7 @@ namespace FlaxEngine.Interop
|
||||
internal static int[] marshallableFieldOffsets;
|
||||
internal static MarshalFieldTypedDelegate[] toManagedFieldMarshallers;
|
||||
internal static MarshalFieldTypedDelegate[] toNativeFieldMarshallers;
|
||||
private static int marshalledSize;
|
||||
|
||||
private static MarshalToNativeTypedDelegate toNativeTypedMarshaller;
|
||||
private static MarshalToManagedTypedDelegate toManagedTypedMarshaller;
|
||||
@@ -582,7 +583,36 @@ namespace FlaxEngine.Interop
|
||||
MethodInfo toManagedFieldMethod;
|
||||
MethodInfo toNativeFieldMethod;
|
||||
|
||||
if (fieldType.IsPointer)
|
||||
if (fieldType == typeof(string))
|
||||
fieldType = fieldType;
|
||||
|
||||
if (fieldType == typeof(SoftTypeReference))
|
||||
{
|
||||
if (type.IsValueType)
|
||||
{
|
||||
toManagedFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToManagedFieldSoftTypeReferenceValueType), bindingFlags);
|
||||
toNativeFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToNativeFieldSoftTypeReferenceValueType), bindingFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
toManagedFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToManagedFieldSoftTypeReferenceReferenceType), bindingFlags);
|
||||
toNativeFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToNativeFieldSoftTypeReferenceReferenceType), bindingFlags);
|
||||
}
|
||||
}
|
||||
else if (fieldType == typeof(string))
|
||||
{
|
||||
if (type.IsValueType)
|
||||
{
|
||||
toManagedFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToManagedFieldStringValueType), bindingFlags);
|
||||
toNativeFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToNativeFieldStringValueType), bindingFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
toManagedFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToManagedFieldStringReferenceType), bindingFlags);
|
||||
toNativeFieldMethod = typeof(MarshalHelper<>).MakeGenericType(type).GetMethod(nameof(MarshalHelper<T>.ToNativeFieldStringReferenceType), bindingFlags);
|
||||
}
|
||||
}
|
||||
else if (fieldType.IsPointer)
|
||||
{
|
||||
if (type.IsValueType)
|
||||
{
|
||||
@@ -666,6 +696,15 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
}
|
||||
|
||||
/*if (marshallableFieldOffsets != null)
|
||||
{
|
||||
for (int i = 1; i < marshallableFieldOffsets.Length; i++)
|
||||
{
|
||||
if (marshallableFieldOffsets[i - 1] > marshallableFieldOffsets[i])
|
||||
throw new NativeInteropException("marshal field offsets");
|
||||
}
|
||||
}*/
|
||||
|
||||
// Setup marshallers for managed and native directions
|
||||
MethodInfo toManagedMethod;
|
||||
if (type.IsValueType)
|
||||
@@ -682,18 +721,31 @@ namespace FlaxEngine.Interop
|
||||
//toManagedDelegate = toManagedMethod.CreateDelegate();//.CreateDelegate(typeof(ToManagedDelegate<,>).MakeGenericType(type, toManagedMethod.GetParameters()[0].ParameterType));
|
||||
string methodName = nameof(MarshalInternalHelper<ValueTypePlaceholder, ValueTypePlaceholder>.ToManagedMarshaller);
|
||||
toManagedMethod = typeof(MarshalInternalHelper<,>).MakeGenericType(types).GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic);
|
||||
marshalledSize = RuntimeHelpers.SizeOf(internalType.TypeHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
string methodName;
|
||||
if (type == typeof(IntPtr))
|
||||
{
|
||||
methodName = nameof(MarshalHelperValueType<ValueTypePlaceholder>.ToManagedPointer);
|
||||
marshalledSize = Unsafe.SizeOf<IntPtr>();
|
||||
}
|
||||
else if (type == typeof(ManagedHandle))
|
||||
{
|
||||
methodName = nameof(MarshalHelperValueType<ValueTypePlaceholder>.ToManagedHandle);
|
||||
marshalledSize = Unsafe.SizeOf<IntPtr>();
|
||||
}
|
||||
else if (marshallableFields != null)
|
||||
{
|
||||
methodName = nameof(MarshalHelperValueType<ValueTypePlaceholder>.ToManagedWithMarshallableFields);
|
||||
marshalledSize = RuntimeHelpers.SizeOf(type.TypeHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
methodName = nameof(MarshalHelperValueType<ValueTypePlaceholder>.ToManaged);
|
||||
marshalledSize = RuntimeHelpers.SizeOf(type.TypeHandle);
|
||||
}
|
||||
toManagedMethod = typeof(MarshalHelperValueType<>).MakeGenericType(type).GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic);
|
||||
}
|
||||
}
|
||||
@@ -707,10 +759,14 @@ namespace FlaxEngine.Interop
|
||||
methodName = nameof(MarshalHelperValueType<ValueTypePlaceholder>.ToManagedArray);
|
||||
else
|
||||
methodName = nameof(MarshalHelperValueType<ValueTypePlaceholder>.ToManagedArrayMarshalled);
|
||||
toManagedMethod = typeof(MarshalHelperValueType<>).MakeGenericType(type.GetElementType()).GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic);
|
||||
toManagedMethod = typeof(MarshalHelperValueType<>).MakeGenericType(elementType).GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic);
|
||||
marshalledSize = RuntimeHelpers.SizeOf(elementType.TypeHandle);
|
||||
}
|
||||
else
|
||||
toManagedMethod = typeof(MarshalHelperReferenceType<>).MakeGenericType(type.GetElementType()).GetMethod(nameof(MarshalHelperReferenceType<ReferenceTypePlaceholder>.ToManagedArray), BindingFlags.Static | BindingFlags.NonPublic);
|
||||
{
|
||||
toManagedMethod = typeof(MarshalHelperReferenceType<>).MakeGenericType(elementType).GetMethod(nameof(MarshalHelperReferenceType<ReferenceTypePlaceholder>.ToManagedArray), BindingFlags.Static | BindingFlags.NonPublic);
|
||||
marshalledSize = Unsafe.SizeOf<IntPtr>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -726,7 +782,10 @@ namespace FlaxEngine.Interop
|
||||
else
|
||||
throw new NativeInteropException($"Unsupported type '{type.FullName}'");
|
||||
toManagedMethod = typeof(MarshalHelperReferenceType<>).MakeGenericType(type).GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic);
|
||||
marshalledSize = Unsafe.SizeOf<IntPtr>();
|
||||
}
|
||||
if (marshalledSize <= 0)
|
||||
throw new NativeInteropException($"Missing marshalled size for type '{type.FullName}'");
|
||||
toManagedTypedMarshaller = toManagedMethod.CreateDelegate<MarshalToManagedTypedDelegate>();
|
||||
|
||||
MethodInfo toNativeMethod;
|
||||
@@ -802,6 +861,18 @@ namespace FlaxEngine.Interop
|
||||
return arr;
|
||||
}
|
||||
|
||||
internal static Array ToManagedArray2(NativeArrayTypeless nativeArray)
|
||||
{
|
||||
T[] arr = new T[nativeArray.Length];
|
||||
IntPtr nativePtr = (IntPtr)nativeArray.Data;
|
||||
for (int i = 0; i < arr.Length; i++)
|
||||
{
|
||||
toManagedTypedMarshaller(ref arr[i], nativePtr, false);
|
||||
nativePtr += marshalledSize;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
internal static void ToNative(ref T managedValue, IntPtr nativePtr)
|
||||
{
|
||||
toNativeTypedMarshaller(ref managedValue, nativePtr);
|
||||
@@ -871,6 +942,106 @@ namespace FlaxEngine.Interop
|
||||
fieldSize = IntPtr.Size;
|
||||
}
|
||||
|
||||
private static void ToManagedFieldStringValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
NativeString nativeValue = Unsafe.Read<NativeString>(nativeFieldPtr.ToPointer());
|
||||
string value = nativeValue.ToString();
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, value);
|
||||
#else
|
||||
ref string fieldValueRef = ref FieldHelper.GetValueTypeFieldReference<T, string>(fieldOffset, ref fieldOwner);
|
||||
fieldValueRef = value;
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void ToManagedFieldStringReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
NativeString nativeValue = Unsafe.Read<NativeString>(nativeFieldPtr.ToPointer());
|
||||
string value = nativeValue.ToString();
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, value);
|
||||
#else
|
||||
ref string fieldValueRef = ref FieldHelper.GetReferenceTypeFieldReference<T, string>(fieldOffset, ref fieldOwner);
|
||||
fieldValueRef = value;
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void ToNativeFieldStringValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
string fieldValue = field.GetValue(fieldOwner);
|
||||
#else
|
||||
string fieldValue = FieldHelper.GetValueTypeFieldReference<T, string>(fieldOffset, ref fieldOwner);
|
||||
#endif
|
||||
NativeString value = new NativeString(fieldValue);
|
||||
Unsafe.Write<NativeString>(nativeFieldPtr.ToPointer(), value);
|
||||
}
|
||||
|
||||
private static void ToNativeFieldStringReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
string fieldValue = field.GetValue(fieldOwner);
|
||||
#else
|
||||
string fieldValue = FieldHelper.GetReferenceTypeFieldReference<T, string>(fieldOffset, ref fieldOwner);
|
||||
#endif
|
||||
NativeString value = new NativeString(fieldValue);
|
||||
Unsafe.Write<NativeString>(nativeFieldPtr.ToPointer(), value);
|
||||
}
|
||||
|
||||
private static void ToManagedFieldSoftTypeReferenceValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
NativeString nativeValue = Unsafe.Read<NativeString>(nativeFieldPtr.ToPointer());
|
||||
SoftTypeReference value = new SoftTypeReference(nativeValue.ToString());
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, value);
|
||||
#else
|
||||
ref SoftTypeReference fieldValueRef = ref FieldHelper.GetValueTypeFieldReference<T, SoftTypeReference>(fieldOffset, ref fieldOwner);
|
||||
fieldValueRef = value;
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void ToManagedFieldSoftTypeReferenceReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
NativeString nativeValue = Unsafe.Read<NativeString>(nativeFieldPtr.ToPointer());
|
||||
SoftTypeReference value = new SoftTypeReference(nativeValue.ToString());
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, value);
|
||||
#else
|
||||
ref SoftTypeReference fieldValueRef = ref FieldHelper.GetReferenceTypeFieldReference<T, SoftTypeReference>(fieldOffset, ref fieldOwner);
|
||||
fieldValueRef = value;
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void ToNativeFieldSoftTypeReferenceValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
SoftTypeReference fieldValue = field.GetValue(fieldOwner);
|
||||
#else
|
||||
SoftTypeReference fieldValue = FieldHelper.GetValueTypeFieldReference<T, SoftTypeReference>(fieldOffset, ref fieldOwner);
|
||||
#endif
|
||||
NativeString value = new NativeString(fieldValue);
|
||||
Unsafe.Write<NativeString>(nativeFieldPtr.ToPointer(), value);
|
||||
}
|
||||
|
||||
private static void ToNativeFieldSoftTypeReferenceReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class
|
||||
{
|
||||
fieldSize = Unsafe.SizeOf<NativeString>();
|
||||
#if USE_AOT || DOTNET_HOST_MONO
|
||||
SoftTypeReference fieldValue = field.GetValue(fieldOwner);
|
||||
#else
|
||||
SoftTypeReference fieldValue = FieldHelper.GetReferenceTypeFieldReference<T, SoftTypeReference>(fieldOffset, ref fieldOwner);
|
||||
#endif
|
||||
NativeString value = new NativeString(fieldValue);
|
||||
Unsafe.Write<NativeString>(nativeFieldPtr.ToPointer(), value);
|
||||
}
|
||||
|
||||
private static IntPtr EnsureAlignment(IntPtr ptr, int alignment)
|
||||
{
|
||||
if (ptr % alignment != 0)
|
||||
@@ -1203,9 +1374,8 @@ namespace FlaxEngine.Interop
|
||||
if (nativePtr != IntPtr.Zero)
|
||||
{
|
||||
int length = Unsafe.Read<int>(IntPtr.Add(nativePtr, Unsafe.SizeOf<IntPtr>()).ToPointer());
|
||||
nativePtr = Unsafe.Read<IntPtr>(nativePtr.ToPointer());
|
||||
|
||||
var span = new Span<T>(nativePtr.ToPointer(), length);
|
||||
IntPtr data = Unsafe.Read<IntPtr>(nativePtr.ToPointer());
|
||||
var span = new Span<T>(data.ToPointer(), length);
|
||||
managedValue = span.ToArray();
|
||||
//ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(nativePtr).Target);
|
||||
//managedValue = Unsafe.As<T[]>(managedArray.ToArray<T>());
|
||||
@@ -1221,8 +1391,12 @@ namespace FlaxEngine.Interop
|
||||
|
||||
if (nativePtr != IntPtr.Zero)
|
||||
{
|
||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(nativePtr).Target);
|
||||
managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray(managedArray));
|
||||
int length = Unsafe.Read<int>(IntPtr.Add(nativePtr, Unsafe.SizeOf<IntPtr>()).ToPointer());
|
||||
IntPtr data = Unsafe.Read<IntPtr>(nativePtr.ToPointer());
|
||||
NativeArrayTypeless array = new(data, length);
|
||||
managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray2(array)); // element size for internal structure needed here
|
||||
//ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(nativePtr).Target);
|
||||
//managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray(managedArray));
|
||||
}
|
||||
else
|
||||
managedValue = null;
|
||||
@@ -1234,6 +1408,13 @@ namespace FlaxEngine.Interop
|
||||
var fields = MarshalHelper<T>.marshallableFields;
|
||||
var offsets = MarshalHelper<T>.marshallableFieldOffsets;
|
||||
var marshallers = MarshalHelper<T>.toNativeFieldMarshallers;
|
||||
|
||||
for (int i = 1; i < offsets.Length; i++)
|
||||
{
|
||||
if (offsets[i - 1] > offsets[i])
|
||||
fieldPtr = fieldPtr;
|
||||
}
|
||||
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
marshallers[i](fields[i], offsets[i], ref managedValue, nativePtr, out int fieldSize);
|
||||
@@ -1297,8 +1478,9 @@ namespace FlaxEngine.Interop
|
||||
|
||||
if (nativePtr != IntPtr.Zero)
|
||||
{
|
||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(nativePtr).Target);
|
||||
managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray(managedArray.ToSpan<IntPtr>()));
|
||||
NativeArray<IntPtr>* array = (NativeArray<IntPtr>*)nativePtr;
|
||||
var span = array->AsSpan();
|
||||
managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray(span));
|
||||
}
|
||||
else
|
||||
managedValue = null;
|
||||
@@ -1329,34 +1511,59 @@ namespace FlaxEngine.Interop
|
||||
|
||||
internal static void ToNativeArray(ref T managedValue, IntPtr nativePtr)
|
||||
{
|
||||
IntPtr managedPtr;
|
||||
IntPtr arrayDataPtr;
|
||||
int arrayLength;
|
||||
if (managedValue == null)
|
||||
managedPtr = IntPtr.Zero;
|
||||
{
|
||||
arrayDataPtr = IntPtr.Zero;
|
||||
arrayLength = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Type type = typeof(T);
|
||||
var elementType = type.GetElementType();
|
||||
var arr = Unsafe.As<Array>(managedValue);
|
||||
arrayLength = arr.Length;
|
||||
var marshalledType = ArrayFactory.GetMarshalledType(elementType);
|
||||
ManagedArray managedArray;
|
||||
if (marshalledType == elementType)
|
||||
managedArray = ManagedArray.WrapNewArray(arr, type);
|
||||
{
|
||||
var elementLength = RuntimeHelpers.SizeOf(marshalledType.TypeHandle);
|
||||
var bytesLength = elementLength * arrayLength;
|
||||
byte* ptr = (byte*)NativeMemory.AlignedAlloc((UIntPtr)bytesLength, 16);
|
||||
arrayDataPtr = (IntPtr)ptr;
|
||||
for (int i = 0; i < arr.Length; i++)
|
||||
{
|
||||
MarshalToNative(arr.GetValue(i), (IntPtr)ptr, elementType);
|
||||
ptr += elementLength;
|
||||
}
|
||||
}
|
||||
else if (elementType.IsValueType)
|
||||
{
|
||||
// Convert array of custom structures into internal native layout
|
||||
managedArray = ManagedArray.AllocateNewArray(arr.Length, type, marshalledType);
|
||||
IntPtr managedArrayPtr = managedArray.Pointer;
|
||||
var elementLength = RuntimeHelpers.SizeOf(marshalledType.TypeHandle);
|
||||
var bytesLength = elementLength * arrayLength;
|
||||
byte* ptr = (byte*)NativeMemory.AlignedAlloc((UIntPtr)bytesLength, 16);
|
||||
arrayDataPtr = (IntPtr)ptr;
|
||||
for (int i = 0; i < arr.Length; i++)
|
||||
{
|
||||
MarshalToNative(arr.GetValue(i), managedArrayPtr, elementType);
|
||||
managedArrayPtr += managedArray.ElementSize;
|
||||
MarshalToNative(arr.GetValue(i), (IntPtr)ptr, elementType);
|
||||
ptr += elementLength;
|
||||
}
|
||||
}
|
||||
else
|
||||
managedArray = ManagedArrayToGCHandleWrappedArray(arr);
|
||||
managedPtr = ManagedHandle.ToIntPtr(managedArray/*, GCHandleType.Weak*/);
|
||||
{
|
||||
byte* ptr = (byte*)NativeMemory.AlignedAlloc((UIntPtr)(Unsafe.SizeOf<IntPtr>() * arrayLength), 16);
|
||||
arrayDataPtr = (IntPtr)ptr;
|
||||
for (int i = 0; i < arr.Length; i++)
|
||||
{
|
||||
var obj = arr.GetValue(i);
|
||||
Unsafe.Write<IntPtr>(ptr, obj != null ? ManagedHandle.ToIntPtr(obj) : IntPtr.Zero);
|
||||
ptr += Unsafe.SizeOf<IntPtr>();
|
||||
}
|
||||
}
|
||||
}
|
||||
Unsafe.Write<IntPtr>(nativePtr.ToPointer(), managedPtr);
|
||||
Unsafe.Write<IntPtr>(nativePtr.ToPointer(), arrayDataPtr);
|
||||
Unsafe.Write<long>(IntPtr.Add(nativePtr, Unsafe.SizeOf<IntPtr>()).ToPointer(), arrayLength);
|
||||
}
|
||||
|
||||
internal static void ToNative(ref T managedValue, IntPtr nativePtr)
|
||||
@@ -1819,7 +2026,7 @@ namespace FlaxEngine.Interop
|
||||
|
||||
internal static void InitMethods()
|
||||
{
|
||||
return;
|
||||
#if false
|
||||
MakeNewCustomDelegateFunc =
|
||||
typeof(Expression).Assembly.GetType("System.Linq.Expressions.Compiler.DelegateHelpers")
|
||||
.GetMethod("MakeNewCustomDelegate", BindingFlags.NonPublic | BindingFlags.Static).CreateDelegate<Func<Type[], Type>>();
|
||||
@@ -1851,6 +2058,7 @@ namespace FlaxEngine.Interop
|
||||
var ret = MakeNewCustomDelegateFuncCollectible(new[] { typeof(void) });
|
||||
Assert.IsTrue(ret.IsCollectible);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1871,7 +2079,7 @@ namespace FlaxEngine.Interop
|
||||
return MakeNewCustomDelegateFunc(parameters);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
internal static class ObjectArrayPool
|
||||
{
|
||||
@@ -1978,8 +2186,8 @@ namespace FlaxEngine.Interop
|
||||
internal MethodInfo method;
|
||||
internal MethodInvoker invoker;
|
||||
internal Type[] parameterTypes;
|
||||
internal Invoker.InvokeThunkDelegate methodDelegate;
|
||||
internal object methodDelegateContext;
|
||||
//internal Invoker.InvokeThunkDelegate methodDelegate;
|
||||
//internal object methodDelegateContext;
|
||||
|
||||
internal static object[] objectPool = new object[128];
|
||||
internal static int objectPoolIndex = 0;
|
||||
@@ -2137,7 +2345,7 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
internal class NativeInteropException : Exception
|
||||
{
|
||||
|
||||
@@ -35,6 +35,11 @@ DEFINE_INTERNAL_CALL(MObject*) UtilsInternal_ExtractArrayFromList(MObject* obj)
|
||||
}
|
||||
#endif
|
||||
|
||||
//#if USE_NETCORE
|
||||
//APgI_TYPEDEF() typedef MString* ManagedString;
|
||||
API_TYPEDEF() typedef String* ManagedString;
|
||||
//#endif
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) PlatformInternal_MemoryCopy(void* dst, const void* src, uint64 size)
|
||||
{
|
||||
Platform::MemoryCopy(dst, src, size);
|
||||
@@ -50,24 +55,33 @@ DEFINE_INTERNAL_CALL(int32) PlatformInternal_MemoryCompare(const void* buf1, con
|
||||
return Platform::MemoryCompare(buf1, buf2, size);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogWrite(LogType level, MString* msgObj)
|
||||
{
|
||||
#if LOG_ENABLE
|
||||
StringView msg;
|
||||
MUtils::ToString(msgObj, msg);
|
||||
Log::Logger::Write(level, msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_Log(LogType level, MString* msgObj, ScriptingObject* obj, MString* stackTrace)
|
||||
DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogWrite(LogType level, ManagedString msgObj)
|
||||
{
|
||||
#if LOG_ENABLE
|
||||
if (msgObj == nullptr)
|
||||
return;
|
||||
#if USE_NETCORE
|
||||
StringView msg(*msgObj);
|
||||
#else
|
||||
StringView msg;
|
||||
MUtils::ToString(msgObj, msg);
|
||||
#endif
|
||||
Log::Logger::Write(level, msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_Log(LogType level, ManagedString msgObj, ScriptingObject* obj, ManagedString stackTrace)
|
||||
{
|
||||
#if LOG_ENABLE
|
||||
if (msgObj == nullptr)
|
||||
return;
|
||||
#if USE_NETCORE
|
||||
StringView msg(*msgObj);
|
||||
#else
|
||||
// Get info
|
||||
StringView msg;
|
||||
MUtils::ToString(msgObj, msg);
|
||||
#endif
|
||||
//const String objName = obj ? obj->ToString() : String::Empty;
|
||||
|
||||
// Send event
|
||||
@@ -79,6 +93,7 @@ DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_Log(LogType level, MString* m
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogException(MObject* exception, ScriptingObject* obj)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
#if USE_CSHARP
|
||||
if (exception == nullptr)
|
||||
return;
|
||||
@@ -117,11 +132,17 @@ namespace
|
||||
#endif
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEvent(MString* nameObj)
|
||||
DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEvent(ManagedString nameObj)
|
||||
{
|
||||
#if COMPILE_WITH_PROFILER
|
||||
if (nameObj == nullptr)
|
||||
return;
|
||||
#if USE_NETCORE
|
||||
StringView name(*nameObj);
|
||||
#else
|
||||
StringView name;
|
||||
MUtils::ToString(nameObj, name);
|
||||
#endif
|
||||
ProfilerCPU::BeginEvent(*name);
|
||||
#if TRACY_ENABLE
|
||||
#if PROFILE_CPU_USE_TRANSIENT_DATA
|
||||
@@ -173,10 +194,16 @@ DEFINE_INTERNAL_CALL(void) ProfilerInternal_EndEvent()
|
||||
#endif
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEventGPU(MString* nameObj)
|
||||
DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEventGPU(ManagedString nameObj)
|
||||
{
|
||||
#if COMPILE_WITH_PROFILER
|
||||
#if USE_NETCORE
|
||||
if (nameObj == nullptr)
|
||||
return;
|
||||
const StringView nameChars(*nameObj);
|
||||
#else
|
||||
const StringView nameChars = MCore::String::GetChars(nameObj);
|
||||
#endif
|
||||
const auto index = ProfilerGPU::BeginEvent(nameChars.Get());
|
||||
ManagedEventsGPU.Push(index);
|
||||
#endif
|
||||
@@ -197,6 +224,7 @@ DEFINE_INTERNAL_CALL(bool) ScriptingInternal_HasGameModulesLoaded()
|
||||
|
||||
DEFINE_INTERNAL_CALL(bool) ScriptingInternal_IsTypeFromGameScripts(MTypeObject* type)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
return Scripting::IsTypeFromGameScripts(MUtils::GetClass(INTERNAL_TYPE_OBJECT_GET(type)));
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ void ManagedSerialization::Serialize(ISerializable::SerializeStream& stream, MOb
|
||||
|
||||
// Write result data
|
||||
stream.RawValue(MCore::String::GetChars(invokeResultStr));
|
||||
MCore::String::Free(invokeResultStr);
|
||||
}
|
||||
|
||||
void ManagedSerialization::SerializeDiff(ISerializable::SerializeStream& stream, MObject* object, MObject* other)
|
||||
@@ -79,6 +80,7 @@ void ManagedSerialization::SerializeDiff(ISerializable::SerializeStream& stream,
|
||||
|
||||
// Write result data
|
||||
stream.RawValue(MCore::String::GetChars(invokeResultStr));
|
||||
MCore::String::Free(invokeResultStr);
|
||||
}
|
||||
|
||||
void ManagedSerialization::Deserialize(ISerializable::DeserializeStream& stream, MObject* object)
|
||||
|
||||
@@ -41,6 +41,118 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_NETCORE
|
||||
StringView MUtils::ToString(MString* str)
|
||||
{
|
||||
if (str == nullptr)
|
||||
return StringView::Empty;
|
||||
return StringView(*(String*)str);
|
||||
}
|
||||
|
||||
StringAnsi MUtils::ToStringAnsi(MString* str)
|
||||
{
|
||||
if (str == nullptr)
|
||||
return StringAnsi::Empty;
|
||||
return StringAnsi(*(String*)str);
|
||||
}
|
||||
|
||||
void MUtils::ToString(MString* str, String& result)
|
||||
{
|
||||
if (str)
|
||||
{
|
||||
const StringView chars = StringView(*(String*)str);
|
||||
result.Set(chars.Get(), chars.Length());
|
||||
}
|
||||
else
|
||||
result.Clear();
|
||||
}
|
||||
|
||||
void MUtils::ToString(MString* str, StringView& result)
|
||||
{
|
||||
if (str)
|
||||
result = StringView(*(String*)str);
|
||||
else
|
||||
result = StringView();
|
||||
}
|
||||
|
||||
void MUtils::ToString(MString* str, Variant& result)
|
||||
{
|
||||
result.SetString(str ? StringView(*(String*)str) : StringView::Empty);
|
||||
}
|
||||
|
||||
void MUtils::ToString(MString* str, StringAnsi& result)
|
||||
{
|
||||
if (str)
|
||||
{
|
||||
const StringView chars = StringView(*(String*)str);
|
||||
result.Set(chars.Get(), chars.Length());
|
||||
}
|
||||
else
|
||||
result.Clear();
|
||||
}
|
||||
|
||||
MString* MUtils::ToString(const char* str)
|
||||
{
|
||||
CRASH;
|
||||
if (str == nullptr || *str == 0)
|
||||
return (MString*)(New<String>());
|
||||
return (MString*)(New<String>(str, StringUtils::Length(str)));
|
||||
}
|
||||
|
||||
MString* MUtils::ToString(const StringAnsi& str)
|
||||
{
|
||||
CRASH;
|
||||
const int32 len = str.Length();
|
||||
if (len <= 0)
|
||||
return (MString*)(New<String>());
|
||||
return (MString*)(New<String>(str.Get(), len));
|
||||
}
|
||||
|
||||
MString* MUtils::ToString(const String& str)
|
||||
{
|
||||
CRASH;
|
||||
const int32 len = str.Length();
|
||||
if (len <= 0)
|
||||
return (MString*)(New<String>());
|
||||
return (MString*)(New<String>(str.Get(), len));
|
||||
}
|
||||
|
||||
MString* MUtils::ToString(const String& str, MDomain* domain)
|
||||
{
|
||||
CRASH;
|
||||
const int32 len = str.Length();
|
||||
if (len <= 0)
|
||||
return (MString*)(New<String>());
|
||||
return (MString*)(New<String>(str.Get(), len));
|
||||
}
|
||||
|
||||
MString* MUtils::ToString(const StringAnsiView& str)
|
||||
{
|
||||
CRASH;
|
||||
const int32 len = str.Length();
|
||||
if (len <= 0)
|
||||
return (MString*)(New<String>());
|
||||
return (MString*)(New<String>(str.Get(), len));
|
||||
}
|
||||
|
||||
MString* MUtils::ToString(const StringView& str)
|
||||
{
|
||||
CRASH;
|
||||
const int32 len = str.Length();
|
||||
if (len <= 0)
|
||||
return (MString*)(New<String>());
|
||||
return (MString*)(New<String>(str.Get(), len));
|
||||
}
|
||||
|
||||
MString* MUtils::ToString(const StringView& str, MDomain* domain)
|
||||
{
|
||||
CRASH;
|
||||
const int32 len = str.Length();
|
||||
if (len <= 0)
|
||||
return (MString*)(New<String>());
|
||||
return (MString*)(New<String>(str.Get(), len));
|
||||
}
|
||||
#else
|
||||
StringView MUtils::ToString(MString* str)
|
||||
{
|
||||
if (str == nullptr)
|
||||
@@ -144,6 +256,7 @@ MString* MUtils::ToString(const StringView& str, MDomain* domain)
|
||||
return MCore::String::GetEmpty(domain);
|
||||
return MCore::String::New(str.Get(), len, domain);
|
||||
}
|
||||
#endif
|
||||
|
||||
ScriptingTypeHandle MUtils::UnboxScriptingTypeHandle(MTypeObject* value)
|
||||
{
|
||||
|
||||
@@ -85,6 +85,41 @@ struct NativeArray
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// A simple POD type Span used with interop between managed and unmanaged sides.
|
||||
/// </summary>
|
||||
template<typename T>
|
||||
struct NativeSpan
|
||||
{
|
||||
public:
|
||||
T* Data;
|
||||
int32 Length;
|
||||
|
||||
public:
|
||||
static NativeSpan<T> AsSpan(T* data, int32 length)
|
||||
{
|
||||
return { data, length };
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
NativeSpan<T> ToNativeSpan(const T* data, int32 length)
|
||||
{
|
||||
return { data, length };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NativeSpan<T> ToNativeSpan(const Array<T>& array)
|
||||
{
|
||||
return { array.Get(), array.Count() };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NativeSpan<T> ToNativeSpan(const Span<T>& span)
|
||||
{
|
||||
return { span.Get(), span.Length() };
|
||||
}
|
||||
|
||||
#if USE_NETCORE
|
||||
// Special case for boolean values, the handles are fixed and should not be removed
|
||||
template<>
|
||||
@@ -128,7 +163,7 @@ struct MConverter<bool>
|
||||
void FreeManagedArray(MArray* array)
|
||||
{
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
@@ -176,7 +211,7 @@ struct MConverter<T, typename TEnableIf<TAnd<TIsPODType<T>, TNot<TIsBaseOf<class
|
||||
void FreeManagedArray(MArray* array)
|
||||
{
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -241,12 +276,13 @@ struct MConverter<String>
|
||||
|
||||
void FreeManagedArray(MArray* array)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
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);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -299,12 +335,13 @@ struct MConverter<StringAnsi>
|
||||
|
||||
void FreeManagedArray(MArray* array)
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK;
|
||||
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);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -368,7 +405,7 @@ struct MConverter<StringView>
|
||||
for (int32 i = 0; i < length; i++)
|
||||
MCore::String::Free(dataPtr[i]);
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -427,7 +464,7 @@ struct MConverter<Variant>
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK; // FIXME
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -485,7 +522,6 @@ struct MConverter<T*, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Va
|
||||
void FreeManagedArray(MArray* array)
|
||||
{
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -540,7 +576,7 @@ struct MConverter<T, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Val
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK; // FIXME
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -602,7 +638,7 @@ struct MConverter<ScriptingObjectReference<T>>
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK; // FIXME
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -663,7 +699,7 @@ struct MConverter<AssetReference<T>>
|
||||
void FreeManagedArray(MArray* array)
|
||||
{
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -725,7 +761,7 @@ struct MConverter<SoftAssetReference<T>>
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK; // FIXME
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -778,7 +814,7 @@ struct MConverter<Array<T>>
|
||||
{
|
||||
PLATFORM_DEBUG_BREAK; // FIXME
|
||||
MCore::Array::Free(array);
|
||||
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
//MCore::GCHandle::Free(*(MGCHandle*)&array);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1031,6 +1067,27 @@ namespace MUtils
|
||||
}
|
||||
|
||||
#if USE_NETCORE
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
FORCE_INLINE String ToNativeString(const StringAnsi& str)
|
||||
{
|
||||
return String(str);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
FORCE_INLINE String ToNativeString(const StringAnsiView& str)
|
||||
{
|
||||
return String(str);
|
||||
}
|
||||
|
||||
|
||||
/// <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>
|
||||
@@ -1040,7 +1097,7 @@ namespace MUtils
|
||||
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);
|
||||
T* arr = (T*)MCore::GC::AllocateMemory(data.Count() * sizeof(T), false);
|
||||
Platform::MemoryCopy(arr, data.Get(), data.Count() * sizeof(T));
|
||||
return arr;
|
||||
}
|
||||
@@ -1116,7 +1173,7 @@ namespace MUtils
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
NativeArray<U> arr;
|
||||
arr.length = data.Length();
|
||||
arr.data = arr.length > 0 ? (U*)MCore::GC::AllocateMemory(arr.length * sizeof(U), true) : nullptr;
|
||||
arr.data = arr.length > 0 ? (U*)MCore::GC::AllocateMemory(arr.length * sizeof(U), false) : nullptr;
|
||||
|
||||
// Convert to managed
|
||||
MConverter<T, U> converter;
|
||||
@@ -1136,7 +1193,7 @@ namespace MUtils
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
NativeArray<T> arr;
|
||||
arr.length = data.Length();
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true) : nullptr;
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), false) : nullptr;
|
||||
|
||||
// Convert to managed
|
||||
MConverter<T> converter;
|
||||
@@ -1188,7 +1245,7 @@ namespace MUtils
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
NativeArray<T> arr;
|
||||
arr.length = data.Length();
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true) : nullptr;
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), false) : nullptr;
|
||||
|
||||
// Convert to managed
|
||||
MConverter<T, U> converter;
|
||||
@@ -1208,7 +1265,7 @@ namespace MUtils
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
NativeArray<T> arr;
|
||||
arr.length = data.Length();
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true) : nullptr;
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), false) : nullptr;
|
||||
Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(T));
|
||||
return arr;
|
||||
}
|
||||
@@ -1239,7 +1296,7 @@ namespace MUtils
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
NativeArray<T> arr;
|
||||
arr.length = data.Length();
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true) : nullptr;
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), false) : nullptr;
|
||||
//Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(T));
|
||||
|
||||
// Convert to managed
|
||||
@@ -1261,7 +1318,7 @@ namespace MUtils
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
NativeArray<T> arr;
|
||||
arr.length = data.Length();
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true) : nullptr;
|
||||
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), false) : nullptr;
|
||||
Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(T));
|
||||
return arr;
|
||||
}
|
||||
@@ -1302,7 +1359,7 @@ namespace MUtils
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
NativeArray<MObject*> arr;
|
||||
arr.length = data.Length();
|
||||
arr.data = arr.length > 0 ? (MObject**)MCore::GC::AllocateMemory(arr.length * sizeof(MObject*), true) : nullptr;
|
||||
arr.data = arr.length > 0 ? (MObject**)MCore::GC::AllocateMemory(arr.length * sizeof(MObject*), false) : nullptr;
|
||||
|
||||
// Convert to managed
|
||||
MConverter<T> converter;
|
||||
@@ -1320,7 +1377,7 @@ namespace MUtils
|
||||
FORCE_INLINE bool* ToBoolArray(const Array<bool>& data)
|
||||
{
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
bool* arr = (bool*)MCore::GC::AllocateMemory(data.Count() * sizeof(bool), true);
|
||||
bool* arr = (bool*)MCore::GC::AllocateMemory(data.Count() * sizeof(bool), false);
|
||||
memcpy(arr, data.Get(), data.Count() * sizeof(bool));
|
||||
return arr;
|
||||
}
|
||||
@@ -1334,7 +1391,7 @@ namespace MUtils
|
||||
FORCE_INLINE bool* ToBoolArray(const BitArray<AllocationType>& data)
|
||||
{
|
||||
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
||||
bool* arr = (bool*)MCore::GC::AllocateMemory(data.Count() * sizeof(bool), true);
|
||||
bool* arr = (bool*)MCore::GC::AllocateMemory(data.Count() * sizeof(bool), false);
|
||||
for (int i = 0; i < data.Count(); i++)
|
||||
arr[i] = data[i];
|
||||
return arr;
|
||||
|
||||
@@ -290,7 +290,7 @@ namespace FlaxEngine
|
||||
/// </summary>
|
||||
/// <param name="ptr">The pointer to the unmanaged (native) object.</param>
|
||||
/// <returns>The object.</returns>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FromUnmanagedPtr", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FromUnmanagedPtr")]
|
||||
public static partial Object FromUnmanagedPtr(IntPtr ptr);
|
||||
|
||||
/// <summary>
|
||||
@@ -315,37 +315,43 @@ namespace FlaxEngine
|
||||
|
||||
#region Internal Calls
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Create1", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Create1")]
|
||||
internal static partial Object Internal_Create1([MarshalUsing(typeof(Interop.SystemTypeMarshaller))] Type type);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Create2", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
internal static partial Object Internal_Create2(string typeName);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceCreated", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceCreated")]
|
||||
internal static partial void Internal_ManagedInstanceCreated(Object managedInstance, IntPtr typeClass);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceDeleted", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceDeleted")]
|
||||
internal static partial void Internal_ManagedInstanceDeleted(IntPtr nativeInstance);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Destroy", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Destroy")]
|
||||
internal static partial void Internal_Destroy(IntPtr obj, float timeLeft);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_DestroyNow", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_DestroyNow")]
|
||||
internal static partial void Internal_DestroyNow(IntPtr obj);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_GetTypeName", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
internal static partial string Internal_GetTypeName(IntPtr obj);
|
||||
internal static string Internal_GetTypeName(IntPtr obj)
|
||||
{
|
||||
Internal_GetTypeName(obj, out string typeName);
|
||||
return typeName;
|
||||
}
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FindObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_GetTypeName", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
internal static partial void Internal_GetTypeName(IntPtr obj, [MarshalUsing(typeof(Interop.StringAnsiViewMarshaller))] out string typeName);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FindObject")]
|
||||
internal static partial Object Internal_FindObject(ref Guid id, [MarshalUsing(typeof(Interop.SystemTypeMarshaller))] Type type, [MarshalAs(UnmanagedType.U1)] bool skipLog = false);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_TryFindObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_TryFindObject")]
|
||||
internal static partial Object Internal_TryFindObject(ref Guid id, [MarshalUsing(typeof(Interop.SystemTypeMarshaller))] Type type);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ChangeID", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ChangeID")]
|
||||
internal static partial void Internal_ChangeID(IntPtr obj, ref Guid id);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_GetUnmanagedInterface", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_GetUnmanagedInterface")]
|
||||
internal static partial IntPtr Internal_GetUnmanagedInterface(IntPtr obj, [MarshalUsing(typeof(Interop.SystemTypeMarshaller))] Type type);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -431,6 +431,7 @@ MClass* MCore::Object::GetClass(const MObject* obj)
|
||||
|
||||
MString* MCore::Object::ToString(const MObject* obj)
|
||||
{
|
||||
CRASH;
|
||||
static void* GetObjectStringPtr = GetStaticMethodPointer(TEXT("GetObjectString"));
|
||||
return (MString*)CallStaticMethod<void*, const void*>(GetObjectStringPtr, obj);
|
||||
}
|
||||
@@ -443,28 +444,34 @@ int32 MCore::Object::GetHashCode(const MObject* obj)
|
||||
|
||||
MString* MCore::String::GetEmpty(const MDomain* domain)
|
||||
{
|
||||
CRASH;
|
||||
static void* GetStringEmptyPtr = GetStaticMethodPointer(TEXT("GetStringEmpty"));
|
||||
return (MString*)CallStaticMethod<void*>(GetStringEmptyPtr);
|
||||
}
|
||||
|
||||
MString* MCore::String::New(const char* str, int32 length, const MDomain* domain)
|
||||
{
|
||||
CRASH;
|
||||
static void* NewStringUTF8Ptr = GetStaticMethodPointer(TEXT("NewStringUTF8"));
|
||||
return (MString*)CallStaticMethod<void*, const char*, int>(NewStringUTF8Ptr, str, length);
|
||||
}
|
||||
|
||||
MString* MCore::String::New(const Char* str, int32 length, const MDomain* domain)
|
||||
{
|
||||
CRASH;
|
||||
static void* NewStringUTF16Ptr = GetStaticMethodPointer(TEXT("NewStringUTF16"));
|
||||
return (MString*)CallStaticMethod<void*, const Char*, int>(NewStringUTF16Ptr, str, length);
|
||||
}
|
||||
|
||||
StringView MCore::String::GetChars(const MString* obj)
|
||||
{
|
||||
int32 length = 0;
|
||||
::String& str = *(::String*)obj;
|
||||
return StringView(str);
|
||||
//CRASH;
|
||||
/*int32 length = 0;
|
||||
static void* GetStringPointerPtr = GetStaticMethodPointer(TEXT("GetStringPointer"));
|
||||
const Char* chars = CallStaticMethod<const Char*, const void*, int*>(GetStringPointerPtr, obj, &length);
|
||||
return StringView(chars, length);
|
||||
return StringView(chars, length);*/
|
||||
}
|
||||
|
||||
void MCore::String::Free(const MString* obj)
|
||||
@@ -605,6 +612,8 @@ void MCore::GC::WriteArrayRef(MArray* dst, Span<MObject*> refs)
|
||||
|
||||
void* MCore::GC::AllocateMemory(int32 size, bool coTaskMem)
|
||||
{
|
||||
if (coTaskMem == true)
|
||||
coTaskMem = coTaskMem;
|
||||
static void* AllocMemoryPtr = GetStaticMethodPointer(TEXT("AllocMemory"));
|
||||
return CallStaticMethod<void*, int, bool>(AllocMemoryPtr, size, coTaskMem);
|
||||
}
|
||||
@@ -613,6 +622,8 @@ void MCore::GC::FreeMemory(void* ptr, bool coTaskMem)
|
||||
{
|
||||
if (!ptr)
|
||||
return;
|
||||
if (coTaskMem == true)
|
||||
coTaskMem = coTaskMem;
|
||||
static void* FreeMemoryPtr = GetStaticMethodPointer(TEXT("FreeMemory"));
|
||||
CallStaticMethod<void, void*, bool>(FreeMemoryPtr, ptr, coTaskMem);
|
||||
}
|
||||
@@ -1323,11 +1334,13 @@ MException::MException(MObject* exception)
|
||||
MMethod* exceptionMsgGetter = exceptionMsgProp->GetGetMethod();
|
||||
MString* exceptionMsg = (MString*)exceptionMsgGetter->Invoke(exception, nullptr, nullptr);
|
||||
Message = MUtils::ToString(exceptionMsg);
|
||||
MCore::String::Free(exceptionMsg);
|
||||
|
||||
MProperty* exceptionStackProp = exceptionClass->GetProperty("StackTrace");
|
||||
MMethod* exceptionStackGetter = exceptionStackProp->GetGetMethod();
|
||||
MString* exceptionStackTrace = (MString*)exceptionStackGetter->Invoke(exception, nullptr, nullptr);
|
||||
StackTrace = MUtils::ToString(exceptionStackTrace);
|
||||
MCore::String::Free(exceptionStackTrace);
|
||||
|
||||
MProperty* innerExceptionProp = exceptionClass->GetProperty("InnerException");
|
||||
MMethod* innerExceptionGetter = innerExceptionProp->GetGetMethod();
|
||||
|
||||
@@ -395,7 +395,7 @@ namespace FlaxEngine
|
||||
/// Returns true if game scripts assembly has been loaded.
|
||||
/// </summary>
|
||||
/// <returns>True if game scripts assembly is loaded, otherwise false.</returns>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_HasGameModulesLoaded", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_HasGameModulesLoaded")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
public static partial bool HasGameModulesLoaded();
|
||||
|
||||
@@ -403,14 +403,14 @@ namespace FlaxEngine
|
||||
/// Returns true if given type is from one of the game scripts assemblies.
|
||||
/// </summary>
|
||||
/// <returns>True if the type is from game assembly, otherwise false.</returns>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_IsTypeFromGameScripts", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_IsTypeFromGameScripts")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
public static partial bool IsTypeFromGameScripts([MarshalUsing(typeof(SystemTypeMarshaller))] Type type);
|
||||
|
||||
/// <summary>
|
||||
/// Flushes the removed objects (disposed objects using Object.Destroy).
|
||||
/// </summary>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_FlushRemovedObjects", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_FlushRemovedObjects")]
|
||||
public static partial void FlushRemovedObjects();
|
||||
}
|
||||
|
||||
@@ -426,26 +426,26 @@ namespace FlaxEngine
|
||||
/// Begins profiling a piece of code with a custom label.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the event.</param>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_BeginEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_BeginEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
public static partial void BeginEvent(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Ends profiling an event.
|
||||
/// </summary>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_EndEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_EndEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
public static partial void EndEvent();
|
||||
|
||||
/// <summary>
|
||||
/// Begins GPU profiling a piece of code with a custom label.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the event.</param>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_BeginEventGPU", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_BeginEventGPU", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||
public static partial void BeginEventGPU(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Ends GPU profiling an event.
|
||||
/// </summary>
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_EndEventGPU", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_EndEventGPU")]
|
||||
public static partial void EndEventGPU();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,15 @@
|
||||
#define ScriptingObject_unmanagedPtr "__unmanagedPtr"
|
||||
#define ScriptingObject_id "__internalId"
|
||||
|
||||
//#if USE_NETCORE
|
||||
//APgI_TYPEDEF() typedef MString* ManagedString;
|
||||
//APgI_TYPEDEF() typedef MString* ManagedStringView;
|
||||
//APgI_TYPEDEF() typedef MString* ManagedStringAnsiView;
|
||||
API_TYPEDEF() typedef String ManagedString;
|
||||
API_TYPEDEF() typedef StringView ManagedStringView;
|
||||
API_TYPEDEF() typedef StringAnsiView ManagedStringAnsiView;
|
||||
//#endif
|
||||
|
||||
// TODO: don't leak memory (use some kind of late manual GC for those wrapper objects)
|
||||
typedef Pair<ScriptingObject*, ScriptingTypeHandle> ScriptingObjectsInterfaceKey;
|
||||
Dictionary<ScriptingObjectsInterfaceKey, void*> ScriptingObjectsInterfaceWrappers;
|
||||
@@ -611,12 +620,16 @@ DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_Create1(MTypeObject* type)
|
||||
return managedInstance;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_Create2(MString* typeNameObj)
|
||||
DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_Create2(ManagedStringView typeNameObj)
|
||||
{
|
||||
// Get typename
|
||||
if (typeNameObj == nullptr)
|
||||
DebugLog::ThrowArgumentNull("typeName");
|
||||
#if USE_NETCORE
|
||||
const StringView typeNameChars = typeNameObj;
|
||||
#else
|
||||
const StringView typeNameChars = MCore::String::GetChars(typeNameObj);
|
||||
#endif
|
||||
const StringAsANSI<100> typeNameData(typeNameChars.Get(), typeNameChars.Length());
|
||||
const StringAnsiView typeName(typeNameData.Get(), typeNameChars.Length());
|
||||
|
||||
@@ -711,10 +724,15 @@ DEFINE_INTERNAL_CALL(void) ObjectInternal_DestroyNow(ScriptingObject* obj)
|
||||
obj->DeleteObjectNow();
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(MString*) ObjectInternal_GetTypeName(ScriptingObject* obj)
|
||||
DEFINE_INTERNAL_CALL(void) ObjectInternal_GetTypeName(ScriptingObject* obj, ManagedStringAnsiView* typeName)
|
||||
{
|
||||
#if USE_NETCORE
|
||||
INTERNAL_CALL_CHECK(obj);
|
||||
*typeName = obj->GetType().Fullname;
|
||||
#else
|
||||
INTERNAL_CALL_CHECK_RETURN(obj, nullptr);
|
||||
return MUtils::ToString(obj->GetType().Fullname);
|
||||
*typeName = MUtils::ToString(obj->GetType().Fullname);
|
||||
#endif
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_FindObject(Guid* id, MTypeObject* type, bool skipLog = false)
|
||||
|
||||
@@ -99,6 +99,7 @@ void UICanvas::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
// Write result data
|
||||
stream.RawValue(MCore::String::GetChars(invokeResultStr));
|
||||
}
|
||||
MCore::String::Free(invokeResultStr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -118,6 +118,7 @@ void UIControl::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
const StringView invokeResultStrChars = MCore::String::GetChars(invokeResultStr);
|
||||
stream.JKEY("Data");
|
||||
stream.RawValue(invokeResultStrChars);
|
||||
MCore::String::Free(invokeResultStr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user