mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +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)))
|
if (typeof(GodotObject).IsAssignableFrom(typeof(T)))
|
||||||
return CreateFromGodotObject(UnsafeAs<GodotObject>(from));
|
return CreateFromGodotObject(UnsafeAs<GodotObject>(from));
|
||||||
|
|
||||||
// `typeof(T).IsValueType` is optimized away
|
// `typeof(T).IsEnum` 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!
|
|
||||||
|
|
||||||
if (typeof(T).IsValueType && typeof(System.Enum).IsAssignableFrom(typeof(T)))
|
if (typeof(T).IsEnum)
|
||||||
{
|
{
|
||||||
// `Type.GetTypeCode(typeof(T).GetEnumUnderlyingType())` is not optimized away.
|
// `typeof(T).GetEnumUnderlyingType()` is optimized away
|
||||||
// Fortunately, `Unsafe.SizeOf<T>()` works and is optimized away.
|
|
||||||
// We don't need to know whether it's signed or unsigned.
|
|
||||||
|
|
||||||
if (Unsafe.SizeOf<T>() == 1)
|
var enumType = typeof(T).GetEnumUnderlyingType();
|
||||||
|
|
||||||
|
if (enumType == typeof(sbyte))
|
||||||
return CreateFromInt(UnsafeAs<sbyte>(from));
|
return CreateFromInt(UnsafeAs<sbyte>(from));
|
||||||
|
|
||||||
if (Unsafe.SizeOf<T>() == 2)
|
if (enumType == typeof(short))
|
||||||
return CreateFromInt(UnsafeAs<short>(from));
|
return CreateFromInt(UnsafeAs<short>(from));
|
||||||
|
|
||||||
if (Unsafe.SizeOf<T>() == 4)
|
if (enumType == typeof(int))
|
||||||
return CreateFromInt(UnsafeAs<int>(from));
|
return CreateFromInt(UnsafeAs<int>(from));
|
||||||
|
|
||||||
if (Unsafe.SizeOf<T>() == 8)
|
if (enumType == typeof(long))
|
||||||
return CreateFromInt(UnsafeAs<long>(from));
|
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>();
|
throw UnsupportedType<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,28 +397,38 @@ public partial class VariantUtils
|
||||||
if (typeof(GodotObject).IsAssignableFrom(typeof(T)))
|
if (typeof(GodotObject).IsAssignableFrom(typeof(T)))
|
||||||
return (T)(object)ConvertToGodotObject(variant);
|
return (T)(object)ConvertToGodotObject(variant);
|
||||||
|
|
||||||
// `typeof(T).IsValueType` is optimized away
|
// `typeof(T).IsEnum` 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!
|
|
||||||
|
|
||||||
if (typeof(T).IsValueType && typeof(System.Enum).IsAssignableFrom(typeof(T)))
|
if (typeof(T).IsEnum)
|
||||||
{
|
{
|
||||||
// `Type.GetTypeCode(typeof(T).GetEnumUnderlyingType())` is not optimized away.
|
// `typeof(T).GetEnumUnderlyingType()` is optimized away
|
||||||
// Fortunately, `Unsafe.SizeOf<T>()` works and is optimized away.
|
|
||||||
// We don't need to know whether it's signed or unsigned.
|
|
||||||
|
|
||||||
if (Unsafe.SizeOf<T>() == 1)
|
var enumType = typeof(T).GetEnumUnderlyingType();
|
||||||
|
|
||||||
|
if (enumType == typeof(sbyte))
|
||||||
return UnsafeAsT(ConvertToInt8(variant));
|
return UnsafeAsT(ConvertToInt8(variant));
|
||||||
|
|
||||||
if (Unsafe.SizeOf<T>() == 2)
|
if (enumType == typeof(short))
|
||||||
return UnsafeAsT(ConvertToInt16(variant));
|
return UnsafeAsT(ConvertToInt16(variant));
|
||||||
|
|
||||||
if (Unsafe.SizeOf<T>() == 4)
|
if (enumType == typeof(int))
|
||||||
return UnsafeAsT(ConvertToInt32(variant));
|
return UnsafeAsT(ConvertToInt32(variant));
|
||||||
|
|
||||||
if (Unsafe.SizeOf<T>() == 8)
|
if (enumType == typeof(long))
|
||||||
return UnsafeAsT(ConvertToInt64(variant));
|
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>();
|
throw UnsupportedType<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue