Browse Source

C#: Fix exported properties of GodotObject[] type

This was a regression from 17b2838f39c634324710166d2f36458906ecaf4a.
`MarshalUtils` was changed in the source generators to use
`ConvertTo<T>` and `CreateFrom<T>`, which don't support `GodotObject[]`
because it would need reflection.
As such, we need to keep the custom cases for `GodotObject[]` in
`MarshalUtils`.
Ignacio Roldán Etcheverry 2 years ago
parent
commit
5c6c766732

+ 19 - 4
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs

@@ -304,7 +304,12 @@ namespace Godot.SourceGenerators
         {
             return marshalType switch
             {
-                // For generic Godot collections, VariantUtils.ConvertTo<T> is slower, so we need this special case
+                // We need a special case for GodotObjectOrDerived[], because it's not supported by VariantUtils.ConvertTo<T>
+                MarshalType.GodotObjectOrDerivedArray =>
+                    source.Append(VariantUtils, ".ConvertToSystemArrayOfGodotObject<",
+                        ((IArrayTypeSymbol)typeSymbol).ElementType.FullQualifiedNameIncludeGlobal(), ">(",
+                        inputExpr, ")"),
+                // We need a special case for generic Godot collections and GodotObjectOrDerived[], because VariantUtils.ConvertTo<T> is slower
                 MarshalType.GodotGenericDictionary =>
                     source.Append(VariantUtils, ".ConvertToDictionaryObject<",
                         ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedNameIncludeGlobal(), ", ",
@@ -324,7 +329,10 @@ namespace Godot.SourceGenerators
         {
             return marshalType switch
             {
-                // For generic Godot collections, VariantUtils.CreateFrom<T> is slower, so we need this special case
+                // We need a special case for GodotObjectOrDerived[], because it's not supported by VariantUtils.CreateFrom<T>
+                MarshalType.GodotObjectOrDerivedArray =>
+                    source.Append(VariantUtils, ".CreateFromSystemArrayOfGodotObject(", inputExpr, ")"),
+                // We need a special case for generic Godot collections and GodotObjectOrDerived[], because VariantUtils.CreateFrom<T> is slower
                 MarshalType.GodotGenericDictionary =>
                     source.Append(VariantUtils, ".CreateFromDictionary(", inputExpr, ")"),
                 MarshalType.GodotGenericArray =>
@@ -339,7 +347,11 @@ namespace Godot.SourceGenerators
         {
             return marshalType switch
             {
-                // For generic Godot collections, Variant.As<T> is slower, so we need this special case
+                // We need a special case for GodotObjectOrDerived[], because it's not supported by Variant.As<T>
+                MarshalType.GodotObjectOrDerivedArray =>
+                    source.Append(inputExpr, ".AsGodotObjectArray<",
+                        ((IArrayTypeSymbol)typeSymbol).ElementType.FullQualifiedNameIncludeGlobal(), ">()"),
+                // We need a special case for generic Godot collections and GodotObjectOrDerived[], because Variant.As<T> is slower
                 MarshalType.GodotGenericDictionary =>
                     source.Append(inputExpr, ".AsGodotDictionary<",
                         ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedNameIncludeGlobal(), ", ",
@@ -357,7 +369,10 @@ namespace Godot.SourceGenerators
         {
             return marshalType switch
             {
-                // For generic Godot collections, Variant.From<T> is slower, so we need this special case
+                // We need a special case for GodotObjectOrDerived[], because it's not supported by Variant.From<T>
+                MarshalType.GodotObjectOrDerivedArray =>
+                    source.Append("global::Godot.Variant.CreateFrom(", inputExpr, ")"),
+                // We need a special case for generic Godot collections, because Variant.From<T> is slower
                 MarshalType.GodotGenericDictionary or MarshalType.GodotGenericArray =>
                     source.Append("global::Godot.Variant.CreateFrom(", inputExpr, ")"),
                 _ => source.Append("global::Godot.Variant.From<",

+ 20 - 0
modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs

@@ -739,6 +739,26 @@ namespace Godot
                 if (typeof(Godot.Object).IsAssignableFrom(type))
                     return Convert.ChangeType(VariantUtils.ConvertTo<Godot.Object>(variant), type);
 
+                if (typeof(Godot.Object[]).IsAssignableFrom(type))
+                {
+                    static Godot.Object[] ConvertToSystemArrayOfGodotObject(in godot_array nativeArray, Type type)
+                    {
+                        var array = Collections.Array.CreateTakingOwnershipOfDisposableValue(
+                            NativeFuncs.godotsharp_array_new_copy(nativeArray));
+
+                        int length = array.Count;
+                        var ret = (Godot.Object[])Activator.CreateInstance(type, length)!;
+
+                        for (int i = 0; i < length; i++)
+                            ret[i] = array[i].AsGodotObject();
+
+                        return ret;
+                    }
+
+                    using var godotArray = NativeFuncs.godotsharp_variant_as_array(variant);
+                    return Convert.ChangeType(ConvertToSystemArrayOfGodotObject(godotArray, type), type);
+                }
+
                 if (type.IsEnum)
                 {
                     var enumUnderlyingType = type.GetEnumUnderlyingType();

+ 0 - 16
modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs

@@ -333,22 +333,6 @@ namespace Godot.NativeInterop
             return ret;
         }
 
-        // TODO: This needs reflection. Look for an alternative.
-        internal static Godot.Object[] ConvertNativeGodotArrayToSystemArrayOfGodotObjectType(in godot_array p_array,
-            Type type)
-        {
-            var array = Collections.Array.CreateTakingOwnershipOfDisposableValue(
-                NativeFuncs.godotsharp_array_new_copy(p_array));
-
-            int length = array.Count;
-            var ret = (Godot.Object[])Activator.CreateInstance(type, length)!;
-
-            for (int i = 0; i < length; i++)
-                ret[i] = array[i].AsGodotObject();
-
-            return ret;
-        }
-
         internal static StringName[] ConvertNativeGodotArrayToSystemArrayOfStringName(in godot_array p_array)
         {
             var array = Collections.Array.CreateTakingOwnershipOfDisposableValue(

+ 0 - 7
modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs

@@ -594,12 +594,5 @@ namespace Godot.NativeInterop
             using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var);
             return Marshaling.ConvertNativeGodotArrayToSystemArrayOfGodotObjectType<T>(godotArray);
         }
-
-        // ReSharper disable once RedundantNameQualifier
-        public static Godot.Object[] ConvertToSystemArrayOfGodotObject(in godot_variant p_var, Type type)
-        {
-            using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var);
-            return Marshaling.ConvertNativeGodotArrayToSystemArrayOfGodotObjectType(godotArray, type);
-        }
     }
 }