Merge commit '2016297fce673c2ac48549a6d8e8a772cf29d4fe' into dotnet7
This commit is contained in:
4
.github/workflows/build_android.yml
vendored
4
.github/workflows/build_android.yml
vendored
@@ -1,6 +1,10 @@
|
|||||||
name: Build Android
|
name: Build Android
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
env:
|
||||||
|
DOTNET_NOLOGO: true
|
||||||
|
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
# Game
|
# Game
|
||||||
|
|||||||
4
.github/workflows/build_linux.yml
vendored
4
.github/workflows/build_linux.yml
vendored
@@ -1,6 +1,10 @@
|
|||||||
name: Build Linux
|
name: Build Linux
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
env:
|
||||||
|
DOTNET_NOLOGO: true
|
||||||
|
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
# Editor
|
# Editor
|
||||||
|
|||||||
4
.github/workflows/build_mac.yml
vendored
4
.github/workflows/build_mac.yml
vendored
@@ -1,6 +1,10 @@
|
|||||||
name: Build macOS
|
name: Build macOS
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
env:
|
||||||
|
DOTNET_NOLOGO: true
|
||||||
|
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
# Editor
|
# Editor
|
||||||
|
|||||||
4
.github/workflows/build_windows.yml
vendored
4
.github/workflows/build_windows.yml
vendored
@@ -1,6 +1,10 @@
|
|||||||
name: Build Windows
|
name: Build Windows
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
env:
|
||||||
|
DOTNET_NOLOGO: true
|
||||||
|
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
# Editor
|
# Editor
|
||||||
|
|||||||
4
.github/workflows/cd.yml
vendored
4
.github/workflows/cd.yml
vendored
@@ -4,6 +4,10 @@ on:
|
|||||||
- cron: '15 4 * * *'
|
- cron: '15 4 * * *'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
DOTNET_NOLOGO: true
|
||||||
|
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
# Windows
|
# Windows
|
||||||
|
|||||||
4
.github/workflows/tests.yml
vendored
4
.github/workflows/tests.yml
vendored
@@ -1,6 +1,10 @@
|
|||||||
name: Tests
|
name: Tests
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
env:
|
||||||
|
DOTNET_NOLOGO: true
|
||||||
|
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
# Tests on Linux
|
# Tests on Linux
|
||||||
|
|||||||
@@ -368,7 +368,7 @@ namespace FlaxEditor.Content.Import
|
|||||||
MaxSize = managed.MaxSize,
|
MaxSize = managed.MaxSize,
|
||||||
TextureGroup = managed.TextureGroup,
|
TextureGroup = managed.TextureGroup,
|
||||||
Size = managed.Size,
|
Size = managed.Size,
|
||||||
SpriteAreas = managed.SpriteAreas != IntPtr.Zero ? ((ManagedArray)ManagedHandle.FromIntPtr(managed.SpriteAreas).Target).GetArray<Rectangle>() : null,
|
SpriteAreas = managed.SpriteAreas != IntPtr.Zero ? ((ManagedArray)ManagedHandle.FromIntPtr(managed.SpriteAreas).Target).ToArray<Rectangle>() : null,
|
||||||
SpriteNames = managed.SpriteNames != IntPtr.Zero ? NativeInterop.GCHandleArrayToManagedArray<string>((ManagedArray)ManagedHandle.FromIntPtr(managed.SpriteNames).Target) : null,
|
SpriteNames = managed.SpriteNames != IntPtr.Zero ? NativeInterop.GCHandleArrayToManagedArray<string>((ManagedArray)ManagedHandle.FromIntPtr(managed.SpriteNames).Target) : null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,8 +166,8 @@ namespace FlaxEngine
|
|||||||
public unsafe class ManagedArray
|
public unsafe class ManagedArray
|
||||||
{
|
{
|
||||||
private ManagedHandle pinnedArrayHandle;
|
private ManagedHandle pinnedArrayHandle;
|
||||||
private ManagedHandle elementTypeHandle;
|
|
||||||
private IntPtr unmanagedData;
|
private IntPtr unmanagedData;
|
||||||
|
private Type elementType;
|
||||||
private int elementSize;
|
private int elementSize;
|
||||||
private int length;
|
private int length;
|
||||||
|
|
||||||
@@ -186,9 +186,11 @@ namespace FlaxEngine
|
|||||||
return managedArray;
|
return managedArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static ManagedArray AllocateNewArray(int length, int elementSize, Type elementType) => new ManagedArray((IntPtr)NativeInterop.NativeAlloc(length, elementSize), length, elementSize, elementType);
|
internal static ManagedArray AllocateNewArray(int length, Type elementType)
|
||||||
|
=> new ManagedArray((IntPtr)NativeInterop.NativeAlloc(length, Marshal.SizeOf(elementType)), length, elementType);
|
||||||
|
|
||||||
internal static ManagedArray AllocateNewArray(IntPtr ptr, int length, int elementSize, Type elementType) => new ManagedArray(ptr, length, elementSize, elementType);
|
internal static ManagedArray AllocateNewArray(IntPtr ptr, int length, Type elementType)
|
||||||
|
=> new ManagedArray(ptr, length, elementType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns an instance of ManagedArray from shared pool.
|
/// Returns an instance of ManagedArray from shared pool.
|
||||||
@@ -212,7 +214,7 @@ namespace FlaxEngine
|
|||||||
public static ManagedArray AllocatePooledArray<T>(int length) where T : unmanaged
|
public static ManagedArray AllocatePooledArray<T>(int length) where T : unmanaged
|
||||||
{
|
{
|
||||||
ManagedArray managedArray = ManagedArrayPool.Get();
|
ManagedArray managedArray = ManagedArrayPool.Get();
|
||||||
managedArray.Allocate((IntPtr)NativeInterop.NativeAlloc(length, Unsafe.SizeOf<T>()), length, Unsafe.SizeOf<T>(), typeof(T));
|
managedArray.Allocate((IntPtr)NativeInterop.NativeAlloc(length, Unsafe.SizeOf<T>()), length, typeof(T));
|
||||||
return managedArray;
|
return managedArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,33 +222,32 @@ namespace FlaxEngine
|
|||||||
|
|
||||||
internal void WrapArray(Array arr)
|
internal void WrapArray(Array arr)
|
||||||
{
|
{
|
||||||
var elementType = arr.GetType().GetElementType();
|
|
||||||
pinnedArrayHandle = ManagedHandle.Alloc(arr, GCHandleType.Pinned);
|
pinnedArrayHandle = ManagedHandle.Alloc(arr, GCHandleType.Pinned);
|
||||||
elementTypeHandle = NativeInterop.GetTypeGCHandle(elementType);
|
|
||||||
unmanagedData = Marshal.UnsafeAddrOfPinnedArrayElement(arr, 0);
|
unmanagedData = Marshal.UnsafeAddrOfPinnedArrayElement(arr, 0);
|
||||||
length = arr.Length;
|
length = arr.Length;
|
||||||
|
elementType = arr.GetType().GetElementType();
|
||||||
elementSize = Marshal.SizeOf(elementType);
|
elementSize = Marshal.SizeOf(elementType);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Allocate<T>(T* ptr, int length) where T : unmanaged
|
internal void Allocate<T>(T* ptr, int length) where T : unmanaged
|
||||||
{
|
{
|
||||||
unmanagedData = new IntPtr(ptr);
|
unmanagedData = new IntPtr(ptr);
|
||||||
elementTypeHandle = NativeInterop.GetTypeGCHandle(typeof(T));
|
|
||||||
this.length = length;
|
this.length = length;
|
||||||
|
elementType = typeof(T);
|
||||||
elementSize = Unsafe.SizeOf<T>();
|
elementSize = Unsafe.SizeOf<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Allocate(IntPtr ptr, int length, int elementSize, Type elementType)
|
internal void Allocate(IntPtr ptr, int length, Type elementType)
|
||||||
{
|
{
|
||||||
unmanagedData = ptr;
|
unmanagedData = ptr;
|
||||||
elementTypeHandle = NativeInterop.GetTypeGCHandle(elementType);
|
|
||||||
this.length = length;
|
this.length = length;
|
||||||
this.elementSize = elementSize;
|
this.elementType = elementType;
|
||||||
|
elementSize = Marshal.SizeOf(elementType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ManagedArray() { }
|
private ManagedArray() { }
|
||||||
|
|
||||||
private ManagedArray(IntPtr ptr, int length, int elementSize, Type elementType) => Allocate(ptr, length, elementSize, elementType);
|
private ManagedArray(IntPtr ptr, int length, Type elementType) => Allocate(ptr, length, elementType);
|
||||||
|
|
||||||
~ManagedArray()
|
~ManagedArray()
|
||||||
{
|
{
|
||||||
@@ -275,24 +276,45 @@ namespace FlaxEngine
|
|||||||
ManagedArrayPool.Put(this);
|
ManagedArrayPool.Put(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IntPtr GetPointer => unmanagedData;
|
internal IntPtr Pointer => unmanagedData;
|
||||||
|
|
||||||
internal int Length => length;
|
internal int Length => length;
|
||||||
|
|
||||||
internal int ElementSize => elementSize;
|
internal int ElementSize => elementSize;
|
||||||
|
|
||||||
internal Type ElementType => Unsafe.As<Type>(elementTypeHandle.Target);
|
public Span<T> ToSpan<T>() where T : struct => new Span<T>(unmanagedData.ToPointer(), length);
|
||||||
|
|
||||||
public Span<T> GetSpan<T>() where T : struct => new Span<T>(unmanagedData.ToPointer(), length);
|
public T[] ToArray<T>() where T : struct => new Span<T>(unmanagedData.ToPointer(), length).ToArray();
|
||||||
|
|
||||||
public T[] GetArray<T>() where T : struct => new Span<T>(unmanagedData.ToPointer(), length).ToArray();
|
public Array ToArray() => ArrayCast.ToArray(new Span<byte>(unmanagedData.ToPointer(), length * elementSize), elementType);
|
||||||
|
|
||||||
public Array GeSystemArray()
|
/// <summary>
|
||||||
|
/// Creates an Array of the specified type from span of bytes.
|
||||||
|
/// </summary>
|
||||||
|
private static class ArrayCast
|
||||||
{
|
{
|
||||||
Type elementType = Unsafe.As<Type>(elementTypeHandle.Target);
|
delegate Array GetDelegate(Span<byte> span);
|
||||||
Type arrayType = elementType.MakeArrayType();
|
[ThreadStatic] private static Dictionary<Type, GetDelegate> delegates;
|
||||||
IntPtr thisPtr = ManagedHandle.ToIntPtr(ManagedHandle.Alloc(this));
|
|
||||||
return (Array)NativeInterop.MarshalToManaged(thisPtr, arrayType);
|
internal static Array ToArray(Span<byte> span, Type type)
|
||||||
|
{
|
||||||
|
if (delegates == null)
|
||||||
|
delegates = new();
|
||||||
|
if (!delegates.TryGetValue(type, out var deleg))
|
||||||
|
{
|
||||||
|
deleg = typeof(ArrayCastInternal<>).MakeGenericType(type).GetMethod(nameof(ArrayCastInternal<int>.ToArray), BindingFlags.Static | BindingFlags.NonPublic).CreateDelegate<GetDelegate>();
|
||||||
|
delegates.Add(type, deleg);
|
||||||
|
}
|
||||||
|
return deleg(span);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ArrayCastInternal<T> where T : struct
|
||||||
|
{
|
||||||
|
internal static Array ToArray(Span<byte> span)
|
||||||
|
{
|
||||||
|
return MemoryMarshal.Cast<byte, T>(span).ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -703,8 +725,7 @@ namespace FlaxEngine
|
|||||||
[CustomMarshaller(typeof(Array), MarshalMode.UnmanagedToManagedOut, typeof(SystemArrayMarshaller.ManagedToNative))]
|
[CustomMarshaller(typeof(Array), MarshalMode.UnmanagedToManagedOut, typeof(SystemArrayMarshaller.ManagedToNative))]
|
||||||
[CustomMarshaller(typeof(Array), MarshalMode.ManagedToUnmanagedOut, typeof(SystemArrayMarshaller.NativeToManaged))]
|
[CustomMarshaller(typeof(Array), MarshalMode.ManagedToUnmanagedOut, typeof(SystemArrayMarshaller.NativeToManaged))]
|
||||||
[CustomMarshaller(typeof(Array), MarshalMode.UnmanagedToManagedIn, typeof(SystemArrayMarshaller.NativeToManaged))]
|
[CustomMarshaller(typeof(Array), MarshalMode.UnmanagedToManagedIn, typeof(SystemArrayMarshaller.NativeToManaged))]
|
||||||
[CustomMarshaller(typeof(Array), MarshalMode.ElementOut, typeof(SystemArrayMarshaller.NativeToManaged))]
|
public static unsafe class SystemArrayMarshaller
|
||||||
public static class SystemArrayMarshaller
|
|
||||||
{
|
{
|
||||||
public struct ManagedToNative
|
public struct ManagedToNative
|
||||||
{
|
{
|
||||||
@@ -727,17 +748,42 @@ namespace FlaxEngine
|
|||||||
|
|
||||||
public void Free()
|
public void Free()
|
||||||
{
|
{
|
||||||
if (managedArray != null)
|
if (managedArray == null)
|
||||||
{
|
return;
|
||||||
managedArray.FreePooled();
|
managedArray.FreePooled();
|
||||||
handle.Free();
|
handle.Free();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static class NativeToManaged
|
|
||||||
|
public struct NativeToManaged
|
||||||
{
|
{
|
||||||
public static Array ConvertToManaged(IntPtr unmanaged) => unmanaged != IntPtr.Zero ? Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(unmanaged).Target).GeSystemArray() : null;
|
ManagedHandle handle;
|
||||||
|
ManagedArray managedArray;
|
||||||
|
|
||||||
|
public void FromUnmanaged(IntPtr unmanaged)
|
||||||
|
{
|
||||||
|
if (unmanaged == IntPtr.Zero)
|
||||||
|
return;
|
||||||
|
handle = ManagedHandle.FromIntPtr(unmanaged);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Array ToManaged()
|
||||||
|
{
|
||||||
|
if (!handle.IsAllocated)
|
||||||
|
return null;
|
||||||
|
managedArray = Unsafe.As<ManagedArray>(handle.Target);
|
||||||
|
return managedArray.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Free()
|
||||||
|
{
|
||||||
|
if (!handle.IsAllocated)
|
||||||
|
return;
|
||||||
|
managedArray.Free();
|
||||||
|
handle.Free();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomMarshaller(typeof(Dictionary<,>), MarshalMode.ManagedToUnmanagedIn, typeof(DictionaryMarshaller<,>.ManagedToNative))]
|
[CustomMarshaller(typeof(Dictionary<,>), MarshalMode.ManagedToUnmanagedIn, typeof(DictionaryMarshaller<,>.ManagedToNative))]
|
||||||
@@ -827,7 +873,7 @@ namespace FlaxEngine
|
|||||||
if (unmanaged == null)
|
if (unmanaged == null)
|
||||||
return ReadOnlySpan<TUnmanagedElement>.Empty;
|
return ReadOnlySpan<TUnmanagedElement>.Empty;
|
||||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(new IntPtr(unmanaged)).Target);
|
ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(new IntPtr(unmanaged)).Target);
|
||||||
return managedArray.GetSpan<TUnmanagedElement>();
|
return managedArray.ToSpan<TUnmanagedElement>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Free(TUnmanagedElement* unmanaged)
|
public static void Free(TUnmanagedElement* unmanaged)
|
||||||
@@ -844,7 +890,7 @@ namespace FlaxEngine
|
|||||||
if (unmanaged == null)
|
if (unmanaged == null)
|
||||||
return Span<TUnmanagedElement>.Empty;
|
return Span<TUnmanagedElement>.Empty;
|
||||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(new IntPtr(unmanaged)).Target);
|
ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(new IntPtr(unmanaged)).Target);
|
||||||
return managedArray.GetSpan<TUnmanagedElement>();
|
return managedArray.ToSpan<TUnmanagedElement>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -870,7 +916,7 @@ namespace FlaxEngine
|
|||||||
if (unmanaged == null)
|
if (unmanaged == null)
|
||||||
return Span<TUnmanagedElement>.Empty;
|
return Span<TUnmanagedElement>.Empty;
|
||||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(new IntPtr(unmanaged)).Target);
|
ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(new IntPtr(unmanaged)).Target);
|
||||||
return managedArray.GetSpan<TUnmanagedElement>();
|
return managedArray.ToSpan<TUnmanagedElement>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Free(TUnmanagedElement* unmanaged)
|
public static void Free(TUnmanagedElement* unmanaged)
|
||||||
@@ -904,7 +950,7 @@ namespace FlaxEngine
|
|||||||
{
|
{
|
||||||
if (unmanagedArray == null)
|
if (unmanagedArray == null)
|
||||||
return Span<TUnmanagedElement>.Empty;
|
return Span<TUnmanagedElement>.Empty;
|
||||||
return unmanagedArray.GetSpan<TUnmanagedElement>();
|
return unmanagedArray.ToSpan<TUnmanagedElement>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TUnmanagedElement* ToUnmanaged() => (TUnmanagedElement*)ManagedHandle.ToIntPtr(handle);
|
public TUnmanagedElement* ToUnmanaged() => (TUnmanagedElement*)ManagedHandle.ToIntPtr(handle);
|
||||||
@@ -920,7 +966,7 @@ namespace FlaxEngine
|
|||||||
{
|
{
|
||||||
if (unmanagedArray == null)
|
if (unmanagedArray == null)
|
||||||
return ReadOnlySpan<TUnmanagedElement>.Empty;
|
return ReadOnlySpan<TUnmanagedElement>.Empty;
|
||||||
return unmanagedArray.GetSpan<TUnmanagedElement>();
|
return unmanagedArray.ToSpan<TUnmanagedElement>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Span<T> GetManagedValuesDestination(int numElements) => managedArray;
|
public Span<T> GetManagedValuesDestination(int numElements) => managedArray;
|
||||||
@@ -954,7 +1000,7 @@ namespace FlaxEngine
|
|||||||
if (unmanaged == null)
|
if (unmanaged == null)
|
||||||
return Span<TUnmanagedElement>.Empty;
|
return Span<TUnmanagedElement>.Empty;
|
||||||
ManagedArray unmanagedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(new IntPtr(unmanaged)).Target);
|
ManagedArray unmanagedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(new IntPtr(unmanaged)).Target);
|
||||||
return unmanagedArray.GetSpan<TUnmanagedElement>();
|
return unmanagedArray.ToSpan<TUnmanagedElement>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T[]? AllocateContainerForManagedElements(TUnmanagedElement* unmanaged, int numElements) => unmanaged is null ? null : new T[numElements];
|
public static T[]? AllocateContainerForManagedElements(TUnmanagedElement* unmanaged, int numElements) => unmanaged is null ? null : new T[numElements];
|
||||||
@@ -966,7 +1012,7 @@ namespace FlaxEngine
|
|||||||
if (unmanaged == null)
|
if (unmanaged == null)
|
||||||
return ReadOnlySpan<TUnmanagedElement>.Empty;
|
return ReadOnlySpan<TUnmanagedElement>.Empty;
|
||||||
ManagedArray array = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(new IntPtr(unmanaged)).Target);
|
ManagedArray array = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(new IntPtr(unmanaged)).Target);
|
||||||
return array.GetSpan<TUnmanagedElement>();
|
return array.ToSpan<TUnmanagedElement>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Free(TUnmanagedElement* unmanaged)
|
public static void Free(TUnmanagedElement* unmanaged)
|
||||||
@@ -1161,7 +1207,7 @@ namespace FlaxEngine
|
|||||||
|
|
||||||
internal static T[] GCHandleArrayToManagedArray<T>(ManagedArray ptrArray) where T : class
|
internal static T[] GCHandleArrayToManagedArray<T>(ManagedArray ptrArray) where T : class
|
||||||
{
|
{
|
||||||
Span<IntPtr> span = ptrArray.GetSpan<IntPtr>();
|
Span<IntPtr> span = ptrArray.ToSpan<IntPtr>();
|
||||||
T[] managedArray = new T[ptrArray.Length];
|
T[] managedArray = new T[ptrArray.Length];
|
||||||
for (int i = 0; i < managedArray.Length; i++)
|
for (int i = 0; i < managedArray.Length; i++)
|
||||||
managedArray[i] = span[i] != IntPtr.Zero ? (T)ManagedHandle.FromIntPtr(span[i]).Target : default;
|
managedArray[i] = span[i] != IntPtr.Zero ? (T)ManagedHandle.FromIntPtr(span[i]).Target : default;
|
||||||
@@ -1476,7 +1522,7 @@ namespace FlaxEngine
|
|||||||
internal static Array ToManagedArray(ManagedArray nativeArray)
|
internal static Array ToManagedArray(ManagedArray nativeArray)
|
||||||
{
|
{
|
||||||
T[] arr = new T[nativeArray.Length];
|
T[] arr = new T[nativeArray.Length];
|
||||||
IntPtr nativePtr = nativeArray.GetPointer;
|
IntPtr nativePtr = nativeArray.Pointer;
|
||||||
for (int i = 0; i < arr.Length; i++)
|
for (int i = 0; i < arr.Length; i++)
|
||||||
{
|
{
|
||||||
toManagedTypedMarshaller(ref arr[i], nativePtr, false);
|
toManagedTypedMarshaller(ref arr[i], nativePtr, false);
|
||||||
@@ -1683,11 +1729,11 @@ namespace FlaxEngine
|
|||||||
{
|
{
|
||||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(nativePtr).Target);
|
ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(nativePtr).Target);
|
||||||
if (ArrayFactory.GetMarshalledType(elementType) == elementType)
|
if (ArrayFactory.GetMarshalledType(elementType) == elementType)
|
||||||
managedValue = Unsafe.As<T[]>(managedArray.GetArray<T>());
|
managedValue = Unsafe.As<T[]>(managedArray.ToArray<T>());
|
||||||
else if (elementType.IsValueType)
|
else if (elementType.IsValueType)
|
||||||
managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray(managedArray));
|
managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray(managedArray));
|
||||||
else
|
else
|
||||||
managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray(managedArray.GetSpan<IntPtr>()));
|
managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray(managedArray.ToSpan<IntPtr>()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
managedValue = null;
|
managedValue = null;
|
||||||
@@ -1751,7 +1797,7 @@ namespace FlaxEngine
|
|||||||
if (nativePtr != IntPtr.Zero)
|
if (nativePtr != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(nativePtr).Target);
|
ManagedArray managedArray = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(nativePtr).Target);
|
||||||
managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray(managedArray.GetSpan<IntPtr>()));
|
managedValue = Unsafe.As<T[]>(MarshalHelper<T>.ToManagedArray(managedArray.ToSpan<IntPtr>()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
managedValue = null;
|
managedValue = null;
|
||||||
@@ -1790,8 +1836,8 @@ namespace FlaxEngine
|
|||||||
else if (elementType.IsValueType)
|
else if (elementType.IsValueType)
|
||||||
{
|
{
|
||||||
// Convert array of custom structures into internal native layout
|
// Convert array of custom structures into internal native layout
|
||||||
managedArray = ManagedArray.AllocateNewArray(arr.Length, Marshal.SizeOf(marshalledType), marshalledType);
|
managedArray = ManagedArray.AllocateNewArray(arr.Length, marshalledType);
|
||||||
IntPtr managedArrayPtr = managedArray.GetPointer;
|
IntPtr managedArrayPtr = managedArray.Pointer;
|
||||||
for (int i = 0; i < arr.Length; i++)
|
for (int i = 0; i < arr.Length; i++)
|
||||||
{
|
{
|
||||||
MarshalToNative(arr.GetValue(i), managedArrayPtr, elementType);
|
MarshalToNative(arr.GetValue(i), managedArrayPtr, elementType);
|
||||||
@@ -2246,7 +2292,7 @@ namespace FlaxEngine
|
|||||||
Type marshalledType = ArrayFactory.GetMarshalledType(type);
|
Type marshalledType = ArrayFactory.GetMarshalledType(type);
|
||||||
if (marshalledType.IsValueType)
|
if (marshalledType.IsValueType)
|
||||||
{
|
{
|
||||||
ManagedArray managedArray = ManagedArray.AllocateNewArray((int)size, Marshal.SizeOf(marshalledType), marshalledType);
|
ManagedArray managedArray = ManagedArray.AllocateNewArray((int)size, marshalledType);
|
||||||
return ManagedHandle.Alloc(managedArray/*, GCHandleType.Weak*/);
|
return ManagedHandle.Alloc(managedArray/*, GCHandleType.Weak*/);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2266,7 +2312,7 @@ namespace FlaxEngine
|
|||||||
if (managedArray.Length == 0)
|
if (managedArray.Length == 0)
|
||||||
return IntPtr.Zero;
|
return IntPtr.Zero;
|
||||||
Assert.IsTrue(index >= 0 && index < managedArray.Length);
|
Assert.IsTrue(index >= 0 && index < managedArray.Length);
|
||||||
return IntPtr.Add(managedArray.GetPointer, size * index);
|
return IntPtr.Add(managedArray.Pointer, size * index);
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
[UnmanagedCallersOnly]
|
||||||
@@ -2486,8 +2532,8 @@ namespace FlaxEngine
|
|||||||
internal static void SetArrayValueReference(ManagedHandle arrayHandle, IntPtr elementPtr, IntPtr valueHandle)
|
internal static void SetArrayValueReference(ManagedHandle arrayHandle, IntPtr elementPtr, IntPtr valueHandle)
|
||||||
{
|
{
|
||||||
ManagedArray managedArray = Unsafe.As<ManagedArray>(arrayHandle.Target);
|
ManagedArray managedArray = Unsafe.As<ManagedArray>(arrayHandle.Target);
|
||||||
int index = (int)(elementPtr.ToInt64() - managedArray.GetPointer.ToInt64()) / managedArray.ElementSize;
|
int index = (int)(elementPtr.ToInt64() - managedArray.Pointer.ToInt64()) / managedArray.ElementSize;
|
||||||
managedArray.GetSpan<IntPtr>()[index] = valueHandle;
|
managedArray.ToSpan<IntPtr>()[index] = valueHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
[UnmanagedCallersOnly]
|
||||||
|
|||||||
@@ -1526,23 +1526,23 @@ namespace Flax.Build.Bindings
|
|||||||
// Marshal blittable array elements back to original non-blittable elements
|
// Marshal blittable array elements back to original non-blittable elements
|
||||||
string originalElementTypeMarshaller = originalElementType + "Marshaller";
|
string originalElementTypeMarshaller = originalElementType + "Marshaller";
|
||||||
string internalElementType = $"{originalElementTypeMarshaller}.{originalElementType}Internal";
|
string internalElementType = $"{originalElementTypeMarshaller}.{originalElementType}Internal";
|
||||||
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? NativeInterop.NativeArrayToManagedArray<{originalElementType}, {internalElementType}>(((ManagedArray)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target).GetSpan<{internalElementType}>(), {originalElementTypeMarshaller}.ToManaged) : null");
|
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? NativeInterop.NativeArrayToManagedArray<{originalElementType}, {internalElementType}>(((ManagedArray)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target).ToSpan<{internalElementType}>(), {originalElementTypeMarshaller}.ToManaged) : null");
|
||||||
toNativeContent.Append($"ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(managed.{fieldInfo.Name}), GCHandleType.Weak))");
|
toNativeContent.Append($"ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(managed.{fieldInfo.Name}), GCHandleType.Weak))");
|
||||||
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<{internalElementType}> values = ((ManagedArray)handle.Target).GetSpan<{internalElementType}>(); foreach (var value in values) {{ {originalElementTypeMarshaller}.Free(value); }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
|
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<{internalElementType}> values = ((ManagedArray)handle.Target).ToSpan<{internalElementType}>(); foreach (var value in values) {{ {originalElementTypeMarshaller}.Free(value); }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
|
||||||
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<{internalElementType}> values = ((ManagedArray)handle.Target).GetSpan<{internalElementType}>(); foreach (var value in values) {{ {originalElementTypeMarshaller}.Free(value); }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
|
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<{internalElementType}> values = ((ManagedArray)handle.Target).ToSpan<{internalElementType}>(); foreach (var value in values) {{ {originalElementTypeMarshaller}.Free(value); }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
|
||||||
}
|
}
|
||||||
else if (fieldInfo.Type.GenericArgs[0].IsObjectRef)
|
else if (fieldInfo.Type.GenericArgs[0].IsObjectRef)
|
||||||
{
|
{
|
||||||
// Array elements passed as GCHandles
|
// Array elements passed as GCHandles
|
||||||
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? NativeInterop.GCHandleArrayToManagedArray<{originalElementType}>((ManagedArray)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target) : null");
|
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? NativeInterop.GCHandleArrayToManagedArray<{originalElementType}>((ManagedArray)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target) : null");
|
||||||
toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.{fieldInfo.Name})), GCHandleType.Weak)) : IntPtr.Zero");
|
toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.{fieldInfo.Name})), GCHandleType.Weak)) : IntPtr.Zero");
|
||||||
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<IntPtr> ptrs = ((ManagedArray)handle.Target).GetSpan<IntPtr>(); foreach (var ptr in ptrs) {{ if (ptr != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(ptr).Free(); }} }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
|
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<IntPtr> ptrs = ((ManagedArray)handle.Target).ToSpan<IntPtr>(); foreach (var ptr in ptrs) {{ if (ptr != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(ptr).Free(); }} }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
|
||||||
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<IntPtr> ptrs = ((ManagedArray)handle.Target).GetSpan<IntPtr>(); foreach (var ptr in ptrs) {{ if (ptr != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(ptr).Free(); }} }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
|
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<IntPtr> ptrs = ((ManagedArray)handle.Target).ToSpan<IntPtr>(); foreach (var ptr in ptrs) {{ if (ptr != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(ptr).Free(); }} }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Blittable array elements
|
// Blittable array elements
|
||||||
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ((ManagedArray)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target).GetArray<{originalElementType}>() : null");
|
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ((ManagedArray)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target).ToArray<{originalElementType}>() : null");
|
||||||
toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(managed.{fieldInfo.Name}), GCHandleType.Weak)) : IntPtr.Zero");
|
toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(managed.{fieldInfo.Name}), GCHandleType.Weak)) : IntPtr.Zero");
|
||||||
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
|
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
|
||||||
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
|
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
|
||||||
|
|||||||
Reference in New Issue
Block a user