Refactor NativeInterop.GetTypeSize
This commit is contained in:
@@ -1603,7 +1603,7 @@ namespace FlaxEngine.Interop
|
|||||||
private static IntPtr PinValue<T>(T value) where T : struct
|
private static IntPtr PinValue<T>(T value) where T : struct
|
||||||
{
|
{
|
||||||
// Store the converted value in unmanaged memory so it will not be relocated by the garbage collector.
|
// Store the converted value in unmanaged memory so it will not be relocated by the garbage collector.
|
||||||
int size = TypeHelpers<T>.MarshalSize;
|
int size = TypeHelpers<T>.Size;
|
||||||
uint index = Interlocked.Increment(ref pinnedAllocationsPointer) % (uint)pinnedAllocations.Length;
|
uint index = Interlocked.Increment(ref pinnedAllocationsPointer) % (uint)pinnedAllocations.Length;
|
||||||
ref (IntPtr ptr, int size) alloc = ref pinnedAllocations[index];
|
ref (IntPtr ptr, int size) alloc = ref pinnedAllocations[index];
|
||||||
if (alloc.size < size)
|
if (alloc.size < size)
|
||||||
@@ -1727,33 +1727,15 @@ namespace FlaxEngine.Interop
|
|||||||
|
|
||||||
internal static class TypeHelpers<T>
|
internal static class TypeHelpers<T>
|
||||||
{
|
{
|
||||||
public static readonly int MarshalSize;
|
public static readonly int Size = Unsafe.SizeOf<T>();
|
||||||
static TypeHelpers()
|
|
||||||
{
|
|
||||||
Type type = typeof(T);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var marshalType = type;
|
|
||||||
if (type.IsEnum)
|
|
||||||
marshalType = type.GetEnumUnderlyingType();
|
|
||||||
MarshalSize = Marshal.SizeOf(marshalType);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// Workaround the issue where structure defined within generic type instance (eg. MyType<int>.MyStruct) fails to get size
|
|
||||||
// https://github.com/dotnet/runtime/issues/46426
|
|
||||||
var obj = RuntimeHelpers.GetUninitializedObject(type);
|
|
||||||
MarshalSize = Marshal.SizeOf(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static int GetTypeSize(Type type)
|
internal static int GetTypeSize(Type type)
|
||||||
{
|
{
|
||||||
if (!_typeSizeCache.TryGetValue(type, out int size))
|
if (!_typeSizeCache.TryGetValue(type, out int size))
|
||||||
{
|
{
|
||||||
var marshalSizeField = typeof(TypeHelpers<>).MakeGenericType(type).GetField(nameof(TypeHelpers<int>.MarshalSize), BindingFlags.Static | BindingFlags.Public);
|
var sizeField = typeof(TypeHelpers<>).MakeGenericType(type).GetField(nameof(TypeHelpers<int>.Size), BindingFlags.Static | BindingFlags.Public);
|
||||||
size = (int)marshalSizeField.GetValue(null);
|
size = (int)sizeField.GetValue(null);
|
||||||
_typeSizeCache.AddOrUpdate(type, size, (t, v) => size);
|
_typeSizeCache.AddOrUpdate(type, size, (t, v) => size);
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
|
|||||||
Reference in New Issue
Block a user