Skip to content

Commit f73d3db

Browse files
committed
Merge pull request #108527 from raulsntos/dotnet/enum-variant-conversion
[.NET] Fix enum from/to Variant conversion
2 parents c39edec + 8950744 commit f73d3db

File tree

1 file changed

+42
-22
lines changed

1 file changed

+42
-22
lines changed

modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.generic.cs

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -196,28 +196,38 @@ public static godot_variant CreateFrom<[MustBeVariant] T>(scoped in T from)
196196
if (typeof(GodotObject).IsAssignableFrom(typeof(T)))
197197
return CreateFromGodotObject(UnsafeAs<GodotObject>(from));
198198

199-
// `typeof(T).IsValueType` is optimized away
200-
// `typeof(T).IsEnum` is NOT optimized away: https://github.com/dotnet/runtime/issues/67113
201-
// Fortunately, `typeof(System.Enum).IsAssignableFrom(typeof(T))` does the job!
199+
// `typeof(T).IsEnum` is optimized away
202200

203-
if (typeof(T).IsValueType && typeof(System.Enum).IsAssignableFrom(typeof(T)))
201+
if (typeof(T).IsEnum)
204202
{
205-
// `Type.GetTypeCode(typeof(T).GetEnumUnderlyingType())` is not optimized away.
206-
// Fortunately, `Unsafe.SizeOf<T>()` works and is optimized away.
207-
// We don't need to know whether it's signed or unsigned.
203+
// `typeof(T).GetEnumUnderlyingType()` is optimized away
208204

209-
if (Unsafe.SizeOf<T>() == 1)
205+
var enumType = typeof(T).GetEnumUnderlyingType();
206+
207+
if (enumType == typeof(sbyte))
210208
return CreateFromInt(UnsafeAs<sbyte>(from));
211209

212-
if (Unsafe.SizeOf<T>() == 2)
210+
if (enumType == typeof(short))
213211
return CreateFromInt(UnsafeAs<short>(from));
214212

215-
if (Unsafe.SizeOf<T>() == 4)
213+
if (enumType == typeof(int))
216214
return CreateFromInt(UnsafeAs<int>(from));
217215

218-
if (Unsafe.SizeOf<T>() == 8)
216+
if (enumType == typeof(long))
219217
return CreateFromInt(UnsafeAs<long>(from));
220218

219+
if (enumType == typeof(byte))
220+
return CreateFromInt(UnsafeAs<byte>(from));
221+
222+
if (enumType == typeof(ushort))
223+
return CreateFromInt(UnsafeAs<ushort>(from));
224+
225+
if (enumType == typeof(uint))
226+
return CreateFromInt(UnsafeAs<uint>(from));
227+
228+
if (enumType == typeof(ulong))
229+
return CreateFromInt(UnsafeAs<ulong>(from));
230+
221231
throw UnsupportedType<T>();
222232
}
223233

@@ -387,28 +397,38 @@ public static T ConvertTo<[MustBeVariant] T>(in godot_variant variant)
387397
if (typeof(GodotObject).IsAssignableFrom(typeof(T)))
388398
return (T)(object)ConvertToGodotObject(variant);
389399

390-
// `typeof(T).IsValueType` is optimized away
391-
// `typeof(T).IsEnum` is NOT optimized away: https://github.com/dotnet/runtime/issues/67113
392-
// Fortunately, `typeof(System.Enum).IsAssignableFrom(typeof(T))` does the job!
400+
// `typeof(T).IsEnum` is optimized away
393401

394-
if (typeof(T).IsValueType && typeof(System.Enum).IsAssignableFrom(typeof(T)))
402+
if (typeof(T).IsEnum)
395403
{
396-
// `Type.GetTypeCode(typeof(T).GetEnumUnderlyingType())` is not optimized away.
397-
// Fortunately, `Unsafe.SizeOf<T>()` works and is optimized away.
398-
// We don't need to know whether it's signed or unsigned.
404+
// `typeof(T).GetEnumUnderlyingType()` is optimized away
399405

400-
if (Unsafe.SizeOf<T>() == 1)
406+
var enumType = typeof(T).GetEnumUnderlyingType();
407+
408+
if (enumType == typeof(sbyte))
401409
return UnsafeAsT(ConvertToInt8(variant));
402410

403-
if (Unsafe.SizeOf<T>() == 2)
411+
if (enumType == typeof(short))
404412
return UnsafeAsT(ConvertToInt16(variant));
405413

406-
if (Unsafe.SizeOf<T>() == 4)
414+
if (enumType == typeof(int))
407415
return UnsafeAsT(ConvertToInt32(variant));
408416

409-
if (Unsafe.SizeOf<T>() == 8)
417+
if (enumType == typeof(long))
410418
return UnsafeAsT(ConvertToInt64(variant));
411419

420+
if (enumType == typeof(byte))
421+
return UnsafeAsT(ConvertToUInt8(variant));
422+
423+
if (enumType == typeof(ushort))
424+
return UnsafeAsT(ConvertToUInt16(variant));
425+
426+
if (enumType == typeof(uint))
427+
return UnsafeAsT(ConvertToUInt32(variant));
428+
429+
if (enumType == typeof(ulong))
430+
return UnsafeAsT(ConvertToUInt64(variant));
431+
412432
throw UnsupportedType<T>();
413433
}
414434

0 commit comments

Comments
 (0)