mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 07:53:26 +00:00
Merge pull request #108527 from raulsntos/dotnet/enum-variant-conversion
[.NET] Fix enum from/to Variant conversion
This commit is contained in:
commit
f73d3db412
1 changed files with 42 additions and 22 deletions
|
@ -196,28 +196,38 @@ public partial class VariantUtils
|
|||
if (typeof(GodotObject).IsAssignableFrom(typeof(T)))
|
||||
return CreateFromGodotObject(UnsafeAs<GodotObject>(from));
|
||||
|
||||
// `typeof(T).IsValueType` is optimized away
|
||||
// `typeof(T).IsEnum` is NOT optimized away: https://github.com/dotnet/runtime/issues/67113
|
||||
// Fortunately, `typeof(System.Enum).IsAssignableFrom(typeof(T))` does the job!
|
||||
// `typeof(T).IsEnum` is optimized away
|
||||
|
||||
if (typeof(T).IsValueType && typeof(System.Enum).IsAssignableFrom(typeof(T)))
|
||||
if (typeof(T).IsEnum)
|
||||
{
|
||||
// `Type.GetTypeCode(typeof(T).GetEnumUnderlyingType())` is not optimized away.
|
||||
// Fortunately, `Unsafe.SizeOf<T>()` works and is optimized away.
|
||||
// We don't need to know whether it's signed or unsigned.
|
||||
// `typeof(T).GetEnumUnderlyingType()` is optimized away
|
||||
|
||||
if (Unsafe.SizeOf<T>() == 1)
|
||||
var enumType = typeof(T).GetEnumUnderlyingType();
|
||||
|
||||
if (enumType == typeof(sbyte))
|
||||
return CreateFromInt(UnsafeAs<sbyte>(from));
|
||||
|
||||
if (Unsafe.SizeOf<T>() == 2)
|
||||
if (enumType == typeof(short))
|
||||
return CreateFromInt(UnsafeAs<short>(from));
|
||||
|
||||
if (Unsafe.SizeOf<T>() == 4)
|
||||
if (enumType == typeof(int))
|
||||
return CreateFromInt(UnsafeAs<int>(from));
|
||||
|
||||
if (Unsafe.SizeOf<T>() == 8)
|
||||
if (enumType == typeof(long))
|
||||
return CreateFromInt(UnsafeAs<long>(from));
|
||||
|
||||
if (enumType == typeof(byte))
|
||||
return CreateFromInt(UnsafeAs<byte>(from));
|
||||
|
||||
if (enumType == typeof(ushort))
|
||||
return CreateFromInt(UnsafeAs<ushort>(from));
|
||||
|
||||
if (enumType == typeof(uint))
|
||||
return CreateFromInt(UnsafeAs<uint>(from));
|
||||
|
||||
if (enumType == typeof(ulong))
|
||||
return CreateFromInt(UnsafeAs<ulong>(from));
|
||||
|
||||
throw UnsupportedType<T>();
|
||||
}
|
||||
|
||||
|
@ -387,28 +397,38 @@ public partial class VariantUtils
|
|||
if (typeof(GodotObject).IsAssignableFrom(typeof(T)))
|
||||
return (T)(object)ConvertToGodotObject(variant);
|
||||
|
||||
// `typeof(T).IsValueType` is optimized away
|
||||
// `typeof(T).IsEnum` is NOT optimized away: https://github.com/dotnet/runtime/issues/67113
|
||||
// Fortunately, `typeof(System.Enum).IsAssignableFrom(typeof(T))` does the job!
|
||||
// `typeof(T).IsEnum` is optimized away
|
||||
|
||||
if (typeof(T).IsValueType && typeof(System.Enum).IsAssignableFrom(typeof(T)))
|
||||
if (typeof(T).IsEnum)
|
||||
{
|
||||
// `Type.GetTypeCode(typeof(T).GetEnumUnderlyingType())` is not optimized away.
|
||||
// Fortunately, `Unsafe.SizeOf<T>()` works and is optimized away.
|
||||
// We don't need to know whether it's signed or unsigned.
|
||||
// `typeof(T).GetEnumUnderlyingType()` is optimized away
|
||||
|
||||
if (Unsafe.SizeOf<T>() == 1)
|
||||
var enumType = typeof(T).GetEnumUnderlyingType();
|
||||
|
||||
if (enumType == typeof(sbyte))
|
||||
return UnsafeAsT(ConvertToInt8(variant));
|
||||
|
||||
if (Unsafe.SizeOf<T>() == 2)
|
||||
if (enumType == typeof(short))
|
||||
return UnsafeAsT(ConvertToInt16(variant));
|
||||
|
||||
if (Unsafe.SizeOf<T>() == 4)
|
||||
if (enumType == typeof(int))
|
||||
return UnsafeAsT(ConvertToInt32(variant));
|
||||
|
||||
if (Unsafe.SizeOf<T>() == 8)
|
||||
if (enumType == typeof(long))
|
||||
return UnsafeAsT(ConvertToInt64(variant));
|
||||
|
||||
if (enumType == typeof(byte))
|
||||
return UnsafeAsT(ConvertToUInt8(variant));
|
||||
|
||||
if (enumType == typeof(ushort))
|
||||
return UnsafeAsT(ConvertToUInt16(variant));
|
||||
|
||||
if (enumType == typeof(uint))
|
||||
return UnsafeAsT(ConvertToUInt32(variant));
|
||||
|
||||
if (enumType == typeof(ulong))
|
||||
return UnsafeAsT(ConvertToUInt64(variant));
|
||||
|
||||
throw UnsupportedType<T>();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue