Refactor NativeInterop.GetTypeSize

This commit is contained in:
2024-04-23 20:19:26 +03:00
parent d70aa20a7a
commit 83b301684d

View File

@@ -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;