summaryrefslogtreecommitdiff
path: root/modules/mono
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono')
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs35
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedProperties.cs35
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalType.cs16
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs277
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs4
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs4
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs28
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs9
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs9
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs4
-rw-r--r--modules/mono/editor/bindings_generator.cpp18
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs454
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs14
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/GodotSerializationInfo.cs40
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/MethodInfo.cs6
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs12
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs12
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs30
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs554
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/SceneTreeExtensions.cs66
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs43
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs349
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs173
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs12
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs12
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj1
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Variant.cs264
30 files changed, 766 insertions, 1723 deletions
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs
index 86c639f7b6..a5b4cb81f6 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs
@@ -80,28 +80,9 @@ namespace Godot.SourceGenerators.Sample
[Export] private Vector3[] field_Vector3Array = { Vector3.Up, Vector3.Down, Vector3.Left, Vector3.Right };
[Export] private Color[] field_ColorArray = { Colors.Aqua, Colors.Aquamarine, Colors.Azure, Colors.Beige };
[Export] private Godot.Object[] field_GodotObjectOrDerivedArray = { null };
-
- // Generics
- [Export] private Godot.Collections.Dictionary<string, string> field_GodotGenericDictionary =
- new Godot.Collections.Dictionary<string, string> { { "key1", "value1" }, { "key2", "value2" } };
-
- [Export] private Godot.Collections.Array<string> field_GodotGenericArray =
- new Godot.Collections.Array<string> { "elem1", "elem2", "elem3" };
-
- [Export] private System.Collections.Generic.Dictionary<string, string> field_SystemGenericDictionary =
- new System.Collections.Generic.Dictionary<string, string> { { "key1", "value1" }, { "key2", "value2" } };
-
- [Export] private System.Collections.Generic.List<string> field_SystemGenericList =
- new System.Collections.Generic.List<string> { "elem1", "elem2", "elem3" };
-
- [Export] private System.Collections.Generic.IDictionary<string, string> field_GenericIDictionary =
- new System.Collections.Generic.Dictionary<string, string> { { "key1", "value1" }, { "key2", "value2" } };
-
- [Export] private System.Collections.Generic.ICollection<string> field_GenericICollection =
- new System.Collections.Generic.List<string> { "elem1", "elem2", "elem3" };
-
- [Export] private System.Collections.Generic.IEnumerable<string> field_GenericIEnumerable =
- new System.Collections.Generic.List<string> { "elem1", "elem2", "elem3" };
+ [Export] private StringName[] field_StringNameArray = { "foo", "bar" };
+ [Export] private NodePath[] field_NodePathArray = { "foo", "bar" };
+ [Export] private RID[] field_RIDArray = { default, default, default };
// Variant
[Export] private Variant field_Variant = "foo";
@@ -118,15 +99,5 @@ namespace Godot.SourceGenerators.Sample
[Export] private Godot.Collections.Array field_GodotArray =
new() { "foo", 10, Vector2.Up, Colors.Chocolate };
-
- [Export] private System.Collections.IDictionary field_IDictionary =
- new System.Collections.Generic.Dictionary<object, object>
- { { "foo", 10 }, { Vector2.Up, Colors.Chocolate } };
-
- [Export] private System.Collections.ICollection field_ICollection =
- new System.Collections.Generic.List<object> { "foo", 10, Vector2.Up, Colors.Chocolate };
-
- [Export] private System.Collections.IEnumerable field_IEnumerable =
- new System.Collections.Generic.List<object> { "foo", 10, Vector2.Up, Colors.Chocolate };
}
}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedProperties.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedProperties.cs
index 665eb7f2a8..eb35c88260 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedProperties.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedProperties.cs
@@ -80,28 +80,9 @@ namespace Godot.SourceGenerators.Sample
[Export] private Vector3[] property_Vector3Array { get; set; } = { Vector3.Up, Vector3.Down, Vector3.Left, Vector3.Right };
[Export] private Color[] property_ColorArray { get; set; } = { Colors.Aqua, Colors.Aquamarine, Colors.Azure, Colors.Beige };
[Export] private Godot.Object[] property_GodotObjectOrDerivedArray { get; set; } = { null };
-
- // Generics
- [Export] private Godot.Collections.Dictionary<string, string> property_GodotGenericDictionary { get; set; } =
- new Godot.Collections.Dictionary<string, string> { { "key1", "value1" }, { "key2", "value2" } };
-
- [Export] private Godot.Collections.Array<string> property_GodotGenericArray { get; set; } =
- new Godot.Collections.Array<string> { "elem1", "elem2", "elem3" };
-
- [Export] private System.Collections.Generic.Dictionary<string, string> property_SystemGenericDictionary { get; set; } =
- new System.Collections.Generic.Dictionary<string, string> { { "key1", "value1" }, { "key2", "value2" } };
-
- [Export] private System.Collections.Generic.List<string> property_SystemGenericList { get; set; } =
- new System.Collections.Generic.List<string> { "elem1", "elem2", "elem3" };
-
- [Export] private System.Collections.Generic.IDictionary<string, string> property_GenericIDictionary { get; set; } =
- new System.Collections.Generic.Dictionary<string, string> { { "key1", "value1" }, { "key2", "value2" } };
-
- [Export] private System.Collections.Generic.ICollection<string> property_GenericICollection { get; set; } =
- new System.Collections.Generic.List<string> { "elem1", "elem2", "elem3" };
-
- [Export] private System.Collections.Generic.IEnumerable<string> property_GenericIEnumerable { get; set; } =
- new System.Collections.Generic.List<string> { "elem1", "elem2", "elem3" };
+ [Export] private StringName[] field_StringNameArray { get; set; } = { "foo", "bar" };
+ [Export] private NodePath[] field_NodePathArray { get; set; } = { "foo", "bar" };
+ [Export] private RID[] field_RIDArray { get; set; } = { default, default, default };
// Variant
[Export] private Variant property_Variant { get; set; } = "foo";
@@ -118,15 +99,5 @@ namespace Godot.SourceGenerators.Sample
[Export] private Godot.Collections.Array property_GodotArray { get; set; } =
new() { "foo", 10, Vector2.Up, Colors.Chocolate };
-
- [Export] private System.Collections.IDictionary property_IDictionary { get; set; } =
- new System.Collections.Generic.Dictionary<object, object>
- { { "foo", 10 }, { Vector2.Up, Colors.Chocolate } };
-
- [Export] private System.Collections.ICollection property_ICollection { get; set; } =
- new System.Collections.Generic.List<object> { "foo", 10, Vector2.Up, Colors.Chocolate };
-
- [Export] private System.Collections.IEnumerable property_IEnumerable { get; set; } =
- new System.Collections.Generic.List<object> { "foo", 10, Vector2.Up, Colors.Chocolate };
}
}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalType.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalType.cs
index e967cbe662..3f767c8a5f 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalType.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalType.cs
@@ -53,16 +53,9 @@ namespace Godot.SourceGenerators
Vector3Array,
ColorArray,
GodotObjectOrDerivedArray,
- SystemArrayOfSupportedType,
-
- // Generics
- GodotGenericDictionary,
- GodotGenericArray,
- SystemGenericDictionary,
- SystemGenericList,
- GenericIDictionary,
- GenericICollection,
- GenericIEnumerable,
+ SystemArrayOfStringName,
+ SystemArrayOfNodePath,
+ SystemArrayOfRID,
// Variant
Variant,
@@ -74,8 +67,5 @@ namespace Godot.SourceGenerators
RID,
GodotDictionary,
GodotArray,
- IDictionary,
- ICollection,
- IEnumerable,
}
}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
index d132b6304f..4300037796 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
@@ -10,17 +10,6 @@ namespace Godot.SourceGenerators
public class TypeCache
{
public INamedTypeSymbol GodotObjectType { get; }
- public INamedTypeSymbol GodotGenericDictionary { get; }
- public INamedTypeSymbol GodotGenericArray { get; }
-
- // ReSharper disable once InconsistentNaming
- public INamedTypeSymbol IDictionary { get; }
-
- // ReSharper disable once InconsistentNaming
- public INamedTypeSymbol ICollection { get; }
- public INamedTypeSymbol GenericIDictionary { get; }
- public INamedTypeSymbol SystemGenericDictionary { get; }
- public INamedTypeSymbol SystemGenericList { get; }
public TypeCache(GeneratorExecutionContext context)
{
@@ -31,13 +20,6 @@ namespace Godot.SourceGenerators
}
GodotObjectType = GetTypeByMetadataNameOrThrow("Godot.Object");
- GodotGenericDictionary = GetTypeByMetadataNameOrThrow("Godot.Collections.Dictionary`2");
- GodotGenericArray = GetTypeByMetadataNameOrThrow("Godot.Collections.Array`1");
- IDictionary = GetTypeByMetadataNameOrThrow("System.Collections.IDictionary");
- ICollection = GetTypeByMetadataNameOrThrow("System.Collections.ICollection");
- GenericIDictionary = GetTypeByMetadataNameOrThrow("System.Collections.Generic.IDictionary`2");
- SystemGenericDictionary = GetTypeByMetadataNameOrThrow("System.Collections.Generic.Dictionary`2");
- SystemGenericList = GetTypeByMetadataNameOrThrow("System.Collections.Generic.List`1");
}
}
@@ -86,14 +68,9 @@ namespace Godot.SourceGenerators
MarshalType.Vector3Array => VariantType.PackedVector3Array,
MarshalType.ColorArray => VariantType.PackedColorArray,
MarshalType.GodotObjectOrDerivedArray => VariantType.Array,
- MarshalType.SystemArrayOfSupportedType => VariantType.Array,
- MarshalType.GodotGenericDictionary => VariantType.Dictionary,
- MarshalType.GodotGenericArray => VariantType.Array,
- MarshalType.SystemGenericDictionary => VariantType.Dictionary,
- MarshalType.SystemGenericList => VariantType.Array,
- MarshalType.GenericIDictionary => VariantType.Dictionary,
- MarshalType.GenericICollection => VariantType.Array,
- MarshalType.GenericIEnumerable => VariantType.Array,
+ MarshalType.SystemArrayOfStringName => VariantType.Array,
+ MarshalType.SystemArrayOfNodePath => VariantType.Array,
+ MarshalType.SystemArrayOfRID => VariantType.Array,
MarshalType.Variant => VariantType.Nil,
MarshalType.GodotObjectOrDerived => VariantType.Object,
MarshalType.StringName => VariantType.StringName,
@@ -101,9 +78,6 @@ namespace Godot.SourceGenerators
MarshalType.RID => VariantType.Rid,
MarshalType.GodotDictionary => VariantType.Dictionary,
MarshalType.GodotArray => VariantType.Array,
- MarshalType.IDictionary => VariantType.Dictionary,
- MarshalType.ICollection => VariantType.Array,
- MarshalType.IEnumerable => VariantType.Array,
_ => null
};
@@ -212,54 +186,22 @@ namespace Godot.SourceGenerators
return MarshalType.Vector3Array;
case { Name: "Color" }:
return MarshalType.ColorArray;
+ case { Name: "StringName" }:
+ return MarshalType.SystemArrayOfStringName;
+ case { Name: "NodePath" }:
+ return MarshalType.SystemArrayOfNodePath;
+ case { Name: "RID" }:
+ return MarshalType.SystemArrayOfRID;
}
}
- if (ConvertManagedTypeToMarshalType(elementType, typeCache) != null)
- return MarshalType.SystemArrayOfSupportedType;
-
return null;
}
- else if (type is INamedTypeSymbol { IsGenericType: true } genericType)
- {
- var genericTypeDef = genericType.ConstructedFrom;
-
- if (SymbolEqualityComparer.Default.Equals(genericTypeDef, typeCache.GodotGenericDictionary))
- return MarshalType.GodotGenericDictionary;
-
- if (SymbolEqualityComparer.Default.Equals(genericTypeDef, typeCache.GodotGenericArray))
- return MarshalType.GodotGenericArray;
-
- if (SymbolEqualityComparer.Default.Equals(genericTypeDef, typeCache.SystemGenericDictionary))
- return MarshalType.SystemGenericDictionary;
-
- if (SymbolEqualityComparer.Default.Equals(genericTypeDef, typeCache.SystemGenericList))
- return MarshalType.SystemGenericList;
-
- if (SymbolEqualityComparer.Default.Equals(genericTypeDef, typeCache.GenericIDictionary))
- return MarshalType.GenericIDictionary;
-
- return genericTypeDef.SpecialType switch
- {
- SpecialType.System_Collections_Generic_ICollection_T => MarshalType.GenericICollection,
- SpecialType.System_Collections_Generic_IEnumerable_T => MarshalType.GenericIEnumerable,
- _ => null
- };
- }
else
{
if (type.SimpleDerivesFrom(typeCache.GodotObjectType))
return MarshalType.GodotObjectOrDerived;
- if (SymbolEqualityComparer.Default.Equals(type, typeCache.IDictionary))
- return MarshalType.IDictionary;
-
- if (SymbolEqualityComparer.Default.Equals(type, typeCache.ICollection))
- return MarshalType.ICollection;
-
- if (specialType == SpecialType.System_Collections_IEnumerable)
- return MarshalType.IEnumerable;
-
if (type.ContainingAssembly.Name == "GodotSharp")
{
switch (type.ContainingNamespace.Name)
@@ -341,13 +283,9 @@ namespace Godot.SourceGenerators
string c, string d, string e, string f, string g)
=> source.Append(a).Append(b).Append(c).Append(d).Append(e).Append(f).Append(g);
- private static StringBuilder Append(this StringBuilder source, string a, string b,
- string c, string d, string e, string f, string g, string h)
- => source.Append(a).Append(b).Append(c).Append(d).Append(e).Append(f).Append(g).Append(h);
-
private const string VariantUtils = "global::Godot.NativeInterop.VariantUtils";
- public static StringBuilder AppendVariantToManagedExpr(this StringBuilder source,
+ public static StringBuilder AppendNativeVariantToManagedExpr(this StringBuilder source,
string inputExpr, ITypeSymbol typeSymbol, MarshalType marshalType)
{
return marshalType switch
@@ -438,30 +376,12 @@ namespace Godot.SourceGenerators
MarshalType.GodotObjectOrDerivedArray =>
source.Append(VariantUtils, ".ConvertToSystemArrayOfGodotObject<",
((IArrayTypeSymbol)typeSymbol).ElementType.FullQualifiedName(), ">(", inputExpr, ")"),
- MarshalType.SystemArrayOfSupportedType =>
- source.Append(VariantUtils, ".ConvertToSystemArrayOfSupportedType<",
- ((IArrayTypeSymbol)typeSymbol).ElementType.FullQualifiedName(), ">(", inputExpr, ")"),
- MarshalType.GodotGenericDictionary =>
- source.Append(VariantUtils, ".ConvertToGenericDictionaryObject<",
- ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedName(), ", ",
- ((INamedTypeSymbol)typeSymbol).TypeArguments[1].FullQualifiedName(), ">(", inputExpr, ")"),
- MarshalType.GodotGenericArray =>
- source.Append(VariantUtils, ".ConvertToGenericArrayObject<",
- ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedName(), ">(", inputExpr, ")"),
- MarshalType.SystemGenericDictionary =>
- source.Append(VariantUtils, ".ConvertToSystemGenericDictionary<",
- ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedName(), ", ",
- ((INamedTypeSymbol)typeSymbol).TypeArguments[1].FullQualifiedName(), ">(", inputExpr, ")"),
- MarshalType.SystemGenericList =>
- source.Append(VariantUtils, ".ConvertToSystemGenericList<",
- ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedName(), ">(", inputExpr, ")"),
- MarshalType.GenericIDictionary =>
- source.Append(VariantUtils, ".ConvertToGenericDictionaryObject<",
- ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedName(), ", ",
- ((INamedTypeSymbol)typeSymbol).TypeArguments[1].FullQualifiedName(), ">(", inputExpr, ")"),
- MarshalType.GenericICollection or MarshalType.GenericIEnumerable =>
- source.Append(VariantUtils, ".ConvertToGenericArrayObject<",
- ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedName(), ">(", inputExpr, ")"),
+ MarshalType.SystemArrayOfStringName =>
+ source.Append(VariantUtils, ".ConvertToSystemArrayOfStringName(", inputExpr, ")"),
+ MarshalType.SystemArrayOfNodePath =>
+ source.Append(VariantUtils, ".ConvertToSystemArrayOfNodePath(", inputExpr, ")"),
+ MarshalType.SystemArrayOfRID =>
+ source.Append(VariantUtils, ".ConvertToSystemArrayOfRID(", inputExpr, ")"),
MarshalType.Variant =>
source.Append("global::Godot.Variant.CreateCopyingBorrowed(", inputExpr, ")"),
MarshalType.GodotObjectOrDerived =>
@@ -477,16 +397,12 @@ namespace Godot.SourceGenerators
source.Append(VariantUtils, ".ConvertToDictionaryObject(", inputExpr, ")"),
MarshalType.GodotArray =>
source.Append(VariantUtils, ".ConvertToArrayObject(", inputExpr, ")"),
- MarshalType.IDictionary =>
- source.Append(VariantUtils, ".ConvertToDictionaryObject(", inputExpr, ")"),
- MarshalType.ICollection or MarshalType.IEnumerable =>
- source.Append(VariantUtils, ".ConvertToArrayObject(", inputExpr, ")"),
_ => throw new ArgumentOutOfRangeException(nameof(marshalType), marshalType,
"Received unexpected marshal type")
};
}
- public static StringBuilder AppendManagedToVariantExpr(
+ public static StringBuilder AppendManagedToNativeVariantExpr(
this StringBuilder source, string inputExpr, MarshalType marshalType)
{
return marshalType switch
@@ -575,22 +491,12 @@ namespace Godot.SourceGenerators
source.Append(VariantUtils, ".CreateFromPackedColorArray(", inputExpr, ")"),
MarshalType.GodotObjectOrDerivedArray =>
source.Append(VariantUtils, ".CreateFromSystemArrayOfGodotObject(", inputExpr, ")"),
- MarshalType.SystemArrayOfSupportedType =>
- source.Append(VariantUtils, ".CreateFromSystemArrayOfSupportedType(", inputExpr, ")"),
- MarshalType.GodotGenericDictionary =>
- source.Append(VariantUtils, ".CreateFromDictionary(", inputExpr, ")"),
- MarshalType.GodotGenericArray =>
- source.Append(VariantUtils, ".CreateFromArray(", inputExpr, ")"),
- MarshalType.SystemGenericDictionary =>
- source.Append(VariantUtils, ".CreateFromSystemDictionary(", inputExpr, ")"),
- MarshalType.SystemGenericList =>
- source.Append(VariantUtils, ".CreateFromSystemICollection(", inputExpr, ")"),
- MarshalType.GenericIDictionary =>
- source.Append(VariantUtils, ".CreateFromSystemGenericIDictionary(", inputExpr, ")"),
- MarshalType.GenericICollection =>
- source.Append(VariantUtils, ".CreateFromSystemGenericICollection(", inputExpr, ")"),
- MarshalType.GenericIEnumerable =>
- source.Append(VariantUtils, ".CreateFromSystemGenericIEnumerable(", inputExpr, ")"),
+ MarshalType.SystemArrayOfStringName =>
+ source.Append(VariantUtils, ".CreateFromSystemArrayOfStringName(", inputExpr, ")"),
+ MarshalType.SystemArrayOfNodePath =>
+ source.Append(VariantUtils, ".CreateFromSystemArrayOfNodePath(", inputExpr, ")"),
+ MarshalType.SystemArrayOfRID =>
+ source.Append(VariantUtils, ".CreateFromSystemArrayOfRID(", inputExpr, ")"),
MarshalType.Variant =>
source.Append(inputExpr, ".CopyNativeVariant()"),
MarshalType.GodotObjectOrDerived =>
@@ -605,15 +511,140 @@ namespace Godot.SourceGenerators
source.Append(VariantUtils, ".CreateFromDictionary(", inputExpr, ")"),
MarshalType.GodotArray =>
source.Append(VariantUtils, ".CreateFromArray(", inputExpr, ")"),
- MarshalType.IDictionary =>
- source.Append(VariantUtils, ".CreateFromSystemIDictionary(", inputExpr, ")"),
- MarshalType.ICollection =>
- source.Append(VariantUtils, ".CreateFromSystemICollection(", inputExpr, ")"),
- MarshalType.IEnumerable =>
- source.Append(VariantUtils, ".CreateFromSystemIEnumerable(", inputExpr, ")"),
_ => throw new ArgumentOutOfRangeException(nameof(marshalType), marshalType,
"Received unexpected marshal type")
};
}
+
+ public static StringBuilder AppendVariantToManagedExpr(this StringBuilder source,
+ string inputExpr, ITypeSymbol typeSymbol, MarshalType marshalType)
+ {
+ return marshalType switch
+ {
+ MarshalType.Boolean => source.Append(inputExpr, ".AsBool()"),
+ MarshalType.Char => source.Append(inputExpr, ".AsChar()"),
+ MarshalType.SByte => source.Append(inputExpr, ".AsSByte()"),
+ MarshalType.Int16 => source.Append(inputExpr, ".AsInt16()"),
+ MarshalType.Int32 => source.Append(inputExpr, ".AsInt32()"),
+ MarshalType.Int64 => source.Append(inputExpr, ".AsInt64()"),
+ MarshalType.Byte => source.Append(inputExpr, ".AsByte()"),
+ MarshalType.UInt16 => source.Append(inputExpr, ".AsUInt16()"),
+ MarshalType.UInt32 => source.Append(inputExpr, ".AsUInt32()"),
+ MarshalType.UInt64 => source.Append(inputExpr, ".AsUInt64()"),
+ MarshalType.Single => source.Append(inputExpr, ".AsSingle()"),
+ MarshalType.Double => source.Append(inputExpr, ".AsDouble()"),
+ MarshalType.String => source.Append(inputExpr, ".AsString()"),
+ MarshalType.Vector2 => source.Append(inputExpr, ".AsVector2()"),
+ MarshalType.Vector2i => source.Append(inputExpr, ".AsVector2i()"),
+ MarshalType.Rect2 => source.Append(inputExpr, ".AsRect2()"),
+ MarshalType.Rect2i => source.Append(inputExpr, ".AsRect2i()"),
+ MarshalType.Transform2D => source.Append(inputExpr, ".AsTransform2D()"),
+ MarshalType.Vector3 => source.Append(inputExpr, ".AsVector3()"),
+ MarshalType.Vector3i => source.Append(inputExpr, ".AsVector3i()"),
+ MarshalType.Basis => source.Append(inputExpr, ".AsBasis()"),
+ MarshalType.Quaternion => source.Append(inputExpr, ".AsQuaternion()"),
+ MarshalType.Transform3D => source.Append(inputExpr, ".AsTransform3D()"),
+ MarshalType.Vector4 => source.Append(inputExpr, ".AsVector4()"),
+ MarshalType.Vector4i => source.Append(inputExpr, ".AsVector4i()"),
+ MarshalType.Projection => source.Append(inputExpr, ".AsProjection()"),
+ MarshalType.AABB => source.Append(inputExpr, ".AsAABB()"),
+ MarshalType.Color => source.Append(inputExpr, ".AsColor()"),
+ MarshalType.Plane => source.Append(inputExpr, ".AsPlane()"),
+ MarshalType.Callable => source.Append(inputExpr, ".AsCallable()"),
+ MarshalType.SignalInfo => source.Append(inputExpr, ".AsSignalInfo()"),
+ MarshalType.Enum =>
+ source.Append("(", typeSymbol.FullQualifiedName(), ")", inputExpr, ".AsInt64()"),
+ MarshalType.ByteArray => source.Append(inputExpr, ".AsByteArray()"),
+ MarshalType.Int32Array => source.Append(inputExpr, ".AsInt32Array()"),
+ MarshalType.Int64Array => source.Append(inputExpr, ".AsInt64Array()"),
+ MarshalType.Float32Array => source.Append(inputExpr, ".AsFloat32Array()"),
+ MarshalType.Float64Array => source.Append(inputExpr, ".AsFloat64Array()"),
+ MarshalType.StringArray => source.Append(inputExpr, ".AsStringArray()"),
+ MarshalType.Vector2Array => source.Append(inputExpr, ".AsVector2Array()"),
+ MarshalType.Vector3Array => source.Append(inputExpr, ".AsVector3Array()"),
+ MarshalType.ColorArray => source.Append(inputExpr, ".AsColorArray()"),
+ MarshalType.GodotObjectOrDerivedArray => source.Append(inputExpr, ".AsGodotObjectArray<",
+ ((IArrayTypeSymbol)typeSymbol).ElementType.FullQualifiedName(), ">()"),
+ MarshalType.SystemArrayOfStringName => source.Append(inputExpr, ".AsSystemArrayOfStringName()"),
+ MarshalType.SystemArrayOfNodePath => source.Append(inputExpr, ".AsSystemArrayOfNodePath()"),
+ MarshalType.SystemArrayOfRID => source.Append(inputExpr, ".AsSystemArrayOfRID()"),
+ MarshalType.Variant => source.Append(inputExpr),
+ MarshalType.GodotObjectOrDerived => source.Append("(",
+ typeSymbol.FullQualifiedName(), ")", inputExpr, ".AsGodotObject()"),
+ MarshalType.StringName => source.Append(inputExpr, ".AsStringName()"),
+ MarshalType.NodePath => source.Append(inputExpr, ".AsNodePath()"),
+ MarshalType.RID => source.Append(inputExpr, ".AsRID()"),
+ MarshalType.GodotDictionary => source.Append(inputExpr, ".AsGodotDictionary()"),
+ MarshalType.GodotArray => source.Append(inputExpr, ".AsGodotArray()"),
+ _ => throw new ArgumentOutOfRangeException(nameof(marshalType), marshalType,
+ "Received unexpected marshal type")
+ };
+ }
+
+ public static StringBuilder AppendManagedToVariantExpr(this StringBuilder source,
+ string inputExpr, MarshalType marshalType)
+ {
+ switch (marshalType)
+ {
+ case MarshalType.Boolean:
+ case MarshalType.Char:
+ case MarshalType.SByte:
+ case MarshalType.Int16:
+ case MarshalType.Int32:
+ case MarshalType.Int64:
+ case MarshalType.Byte:
+ case MarshalType.UInt16:
+ case MarshalType.UInt32:
+ case MarshalType.UInt64:
+ case MarshalType.Single:
+ case MarshalType.Double:
+ case MarshalType.String:
+ case MarshalType.Vector2:
+ case MarshalType.Vector2i:
+ case MarshalType.Rect2:
+ case MarshalType.Rect2i:
+ case MarshalType.Transform2D:
+ case MarshalType.Vector3:
+ case MarshalType.Vector3i:
+ case MarshalType.Basis:
+ case MarshalType.Quaternion:
+ case MarshalType.Transform3D:
+ case MarshalType.Vector4:
+ case MarshalType.Vector4i:
+ case MarshalType.Projection:
+ case MarshalType.AABB:
+ case MarshalType.Color:
+ case MarshalType.Plane:
+ case MarshalType.Callable:
+ case MarshalType.SignalInfo:
+ case MarshalType.ByteArray:
+ case MarshalType.Int32Array:
+ case MarshalType.Int64Array:
+ case MarshalType.Float32Array:
+ case MarshalType.Float64Array:
+ case MarshalType.StringArray:
+ case MarshalType.Vector2Array:
+ case MarshalType.Vector3Array:
+ case MarshalType.ColorArray:
+ case MarshalType.GodotObjectOrDerivedArray:
+ case MarshalType.SystemArrayOfStringName:
+ case MarshalType.SystemArrayOfNodePath:
+ case MarshalType.SystemArrayOfRID:
+ case MarshalType.GodotObjectOrDerived:
+ case MarshalType.StringName:
+ case MarshalType.NodePath:
+ case MarshalType.RID:
+ case MarshalType.GodotDictionary:
+ case MarshalType.GodotArray:
+ return source.Append("Variant.CreateFrom(", inputExpr, ")");
+ case MarshalType.Enum:
+ return source.Append("Variant.CreateFrom((long)", inputExpr, ")");
+ case MarshalType.Variant:
+ return source.Append(inputExpr);
+ default:
+ throw new ArgumentOutOfRangeException(nameof(marshalType), marshalType,
+ "Received unexpected marshal type");
+ }
+ }
}
}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs
index 8ee9489fe2..1fdc04a262 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs
@@ -381,7 +381,7 @@ namespace Godot.SourceGenerators
if (i != 0)
source.Append(", ");
- source.AppendVariantToManagedExpr(string.Concat("args[", i.ToString(), "]"),
+ source.AppendNativeVariantToManagedExpr(string.Concat("args[", i.ToString(), "]"),
method.ParamTypeSymbols[i], method.ParamTypes[i]);
}
@@ -391,7 +391,7 @@ namespace Godot.SourceGenerators
{
source.Append(" ret = ");
- source.AppendManagedToVariantExpr("callRet", method.RetType.Value);
+ source.AppendManagedToNativeVariantExpr("callRet", method.RetType.Value);
source.Append(";\n");
source.Append(" return true;\n");
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
index 29a15e2d16..12a369fd72 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
@@ -293,7 +293,7 @@ namespace Godot.SourceGenerators
.Append(" ")
.Append(propertyMemberName)
.Append(" = ")
- .AppendVariantToManagedExpr("value", propertyTypeSymbol, propertyMarshalType)
+ .AppendNativeVariantToManagedExpr("value", propertyTypeSymbol, propertyMarshalType)
.Append(";\n")
.Append(" return true;\n")
.Append(" }\n");
@@ -315,7 +315,7 @@ namespace Godot.SourceGenerators
.Append(propertyMemberName)
.Append(") {\n")
.Append(" value = ")
- .AppendManagedToVariantExpr(propertyMemberName, propertyMarshalType)
+ .AppendManagedToNativeVariantExpr(propertyMemberName, propertyMarshalType)
.Append(";\n")
.Append(" return true;\n")
.Append(" }\n");
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
index 224a2d0a50..1b87c6e760 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
@@ -160,8 +160,8 @@ namespace Godot.SourceGenerators
source.Append(" info.AddProperty(GodotInternal.PropName_")
.Append(propertyName)
- .Append(", this.")
- .Append(propertyName)
+ .Append(", ")
+ .AppendManagedToVariantExpr(string.Concat("this.", propertyName), property.Type)
.Append(");\n");
}
@@ -173,8 +173,8 @@ namespace Godot.SourceGenerators
source.Append(" info.AddProperty(GodotInternal.PropName_")
.Append(fieldName)
- .Append(", this.")
- .Append(fieldName)
+ .Append(", ")
+ .AppendManagedToVariantExpr(string.Concat("this.", fieldName), field.Type)
.Append(");\n");
}
@@ -202,19 +202,17 @@ namespace Godot.SourceGenerators
foreach (var property in godotClassProperties)
{
string propertyName = property.PropertySymbol.Name;
- string propertyTypeQualifiedName = property.PropertySymbol.Type.FullQualifiedName();
- source.Append(" if (info.TryGetProperty<")
- .Append(propertyTypeQualifiedName)
- .Append(">(GodotInternal.PropName_")
+ source.Append(" if (info.TryGetProperty(GodotInternal.PropName_")
.Append(propertyName)
.Append(", out var _value_")
.Append(propertyName)
.Append("))\n")
.Append(" this.")
.Append(propertyName)
- .Append(" = _value_")
- .Append(propertyName)
+ .Append(" = ")
+ .AppendVariantToManagedExpr(string.Concat("_value_", propertyName),
+ property.PropertySymbol.Type, property.Type)
.Append(";\n");
}
@@ -223,19 +221,17 @@ namespace Godot.SourceGenerators
foreach (var field in godotClassFields)
{
string fieldName = field.FieldSymbol.Name;
- string fieldTypeQualifiedName = field.FieldSymbol.Type.FullQualifiedName();
- source.Append(" if (info.TryGetProperty<")
- .Append(fieldTypeQualifiedName)
- .Append(">(GodotInternal.PropName_")
+ source.Append(" if (info.TryGetProperty(GodotInternal.PropName_")
.Append(fieldName)
.Append(", out var _value_")
.Append(fieldName)
.Append("))\n")
.Append(" this.")
.Append(fieldName)
- .Append(" = _value_")
- .Append(fieldName)
+ .Append(" = ")
+ .AppendVariantToManagedExpr(string.Concat("_value_", fieldName),
+ field.FieldSymbol.Type, field.Type)
.Append(";\n");
}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
index 10f4ddd149..536ddb02f8 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
@@ -397,7 +397,7 @@ namespace Godot.SourceGenerators
if (i != 0)
source.Append(", ");
- source.AppendVariantToManagedExpr(string.Concat("args[", i.ToString(), "]"),
+ source.AppendNativeVariantToManagedExpr(string.Concat("args[", i.ToString(), "]"),
invokeMethodData.ParamTypeSymbols[i], invokeMethodData.ParamTypes[i]);
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs
index f8a810fd44..3c5b897719 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs
@@ -20,7 +20,7 @@ namespace GodotTools.Build
public bool OnlyClean { get; private set; }
// TODO Use List once we have proper serialization
- public Array<string> CustomProperties { get; private set; } = new Array<string>();
+ public Godot.Collections.Array CustomProperties { get; private set; } = new();
public string LogsDirPath =>
Path.Combine(GodotSharpDirs.BuildLogsDirs, $"{Solution.MD5Text()}_{Configuration}");
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
index 38d2eefd02..a8128be909 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
@@ -1,7 +1,6 @@
using Godot;
using System;
using System.Diagnostics.CodeAnalysis;
-using Godot.Collections;
using GodotTools.Internals;
using File = GodotTools.Utils.File;
using Path = System.IO.Path;
@@ -59,7 +58,7 @@ namespace GodotTools.Build
}
// TODO Use List once we have proper serialization.
- private Array<BuildIssue> _issues = new Array<BuildIssue>();
+ private Godot.Collections.Array _issues = new();
private ItemList _issuesList;
private PopupMenu _issuesListContextMenu;
private TextEdit _buildLog;
@@ -129,12 +128,12 @@ namespace GodotTools.Build
if (issueIndex < 0 || issueIndex >= _issues.Count)
throw new IndexOutOfRangeException("Issue index out of range");
- BuildIssue issue = _issues[issueIndex];
+ var issue = (BuildIssue)_issues[issueIndex];
if (string.IsNullOrEmpty(issue.ProjectFile) && string.IsNullOrEmpty(issue.File))
return;
- string projectDir = issue.ProjectFile.Length > 0 ?
+ string projectDir = !string.IsNullOrEmpty(issue.ProjectFile) ?
issue.ProjectFile.GetBaseDir() :
_buildInfo.Solution.GetBaseDir();
@@ -163,7 +162,7 @@ namespace GodotTools.Build
{
for (int i = 0; i < _issues.Count; i++)
{
- BuildIssue issue = _issues[i];
+ var issue = (BuildIssue)_issues[i];
if (!(issue.Warning ? WarningsVisible : ErrorsVisible))
continue;
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
index 506c0ec067..655be0ab5e 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
@@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
+using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GodotTools.BuildLogger;
@@ -156,9 +157,9 @@ namespace GodotTools.Build
AddLoggerArgument(buildInfo, arguments);
// Custom properties
- foreach (string customProperty in buildInfo.CustomProperties)
+ foreach (var customProperty in buildInfo.CustomProperties)
{
- arguments.Add("-p:" + customProperty);
+ arguments.Add("-p:" + (string)customProperty);
}
}
@@ -198,9 +199,9 @@ namespace GodotTools.Build
AddLoggerArgument(buildInfo, arguments);
// Custom properties
- foreach (string customProperty in buildInfo.CustomProperties)
+ foreach (var customProperty in buildInfo.CustomProperties)
{
- arguments.Add("-p:" + customProperty);
+ arguments.Add("-p:" + (string)customProperty);
}
// Publish output directory
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index 362bb18b36..dcc3f3db76 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -481,9 +481,9 @@ namespace GodotTools
_editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary
{
- ["type"] = Variant.Type.Int,
+ ["type"] = (int)Variant.Type.Int,
["name"] = "mono/editor/external_editor",
- ["hint"] = PropertyHint.Enum,
+ ["hint"] = (int)PropertyHint.Enum,
["hint_string"] = settingsHintStr
});
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
index a62fe29e7e..60602a5847 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
@@ -30,9 +30,9 @@ namespace GodotTools.Ides.Rider
Globals.EditorDef(EditorPathSettingName, "Optional");
editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary
{
- ["type"] = Variant.Type.String,
+ ["type"] = (int)Variant.Type.String,
["name"] = EditorPathSettingName,
- ["hint"] = PropertyHint.File,
+ ["hint"] = (int)PropertyHint.File,
["hint_string"] = ""
});
}
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 50820c6384..b879c95fa1 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -1664,8 +1664,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
if (arg_type->cname == name_cache.type_Array_generic || arg_type->cname == name_cache.type_Dictionary_generic) {
String arg_cs_type = arg_type->cs_type + _get_generic_type_parameters(*arg_type, iarg.type.generic_type_parameters);
- output << "new " << arg_cs_type << "(" << sformat(arg_type->cs_variant_to_managed,
- "args[" + itos(i) + "]", arg_type->cs_type, arg_type->name) << ")";
+ output << "new " << arg_cs_type << "(" << sformat(arg_type->cs_variant_to_managed, "args[" + itos(i) + "]", arg_type->cs_type, arg_type->name) << ")";
} else {
output << sformat(arg_type->cs_variant_to_managed,
"args[" + itos(i) + "]", arg_type->cs_type, arg_type->name);
@@ -2892,8 +2891,13 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
String() + "Return type is reference but hint is not '" _STR(PROPERTY_HINT_RESOURCE_TYPE) "'." +
" Are you returning a reference type by pointer? Method: '" + itype.name + "." + imethod.name + "'.");
} else if (return_info.type == Variant::ARRAY && return_info.hint == PROPERTY_HINT_ARRAY_TYPE) {
+// TODO: Enable once generic Array is re-implemented
+#if 0
imethod.return_type.cname = Variant::get_type_name(return_info.type) + "_@generic";
imethod.return_type.generic_type_parameters.push_back(TypeReference(return_info.hint_string));
+#else
+ imethod.return_type.cname = Variant::get_type_name(return_info.type);
+#endif
} else if (return_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
imethod.return_type.cname = return_info.hint_string;
} else if (return_info.type == Variant::NIL && return_info.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
@@ -2924,8 +2928,13 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
} else if (arginfo.class_name != StringName()) {
iarg.type.cname = arginfo.class_name;
} else if (arginfo.type == Variant::ARRAY && arginfo.hint == PROPERTY_HINT_ARRAY_TYPE) {
+// TODO: Enable once generic Array is re-implemented
+#if 0
iarg.type.cname = Variant::get_type_name(arginfo.type) + "_@generic";
iarg.type.generic_type_parameters.push_back(TypeReference(arginfo.hint_string));
+#else
+ iarg.type.cname = Variant::get_type_name(arginfo.type);
+#endif
} else if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
iarg.type.cname = arginfo.hint_string;
} else if (arginfo.type == Variant::NIL) {
@@ -3032,8 +3041,13 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
} else if (arginfo.class_name != StringName()) {
iarg.type.cname = arginfo.class_name;
} else if (arginfo.type == Variant::ARRAY && arginfo.hint == PROPERTY_HINT_ARRAY_TYPE) {
+// TODO: Enable once generic Array is re-implemented
+#if 0
iarg.type.cname = Variant::get_type_name(arginfo.type) + "_@generic";
iarg.type.generic_type_parameters.push_back(TypeReference(arginfo.hint_string));
+#else
+ iarg.type.cname = Variant::get_type_name(arginfo.type);
+#endif
} else if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
iarg.type.cname = arginfo.hint_string;
} else if (arginfo.type == Variant::NIL) {
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
index 8ceb7ea882..51d7d8195b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections;
-using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Godot.NativeInterop;
@@ -14,8 +13,8 @@ namespace Godot.Collections
/// such as <see cref="System.Array"/> or <see cref="List{T}"/>.
/// </summary>
public sealed class Array :
- IList<object>,
- IReadOnlyList<object>,
+ IList<Variant>,
+ IReadOnlyList<Variant>,
ICollection,
IDisposable
{
@@ -37,22 +36,90 @@ namespace Godot.Collections
/// </summary>
/// <param name="collection">The collection of elements to construct from.</param>
/// <returns>A new Godot Array.</returns>
- public Array(IEnumerable collection) : this()
+ public Array(IEnumerable<Variant> collection) : this()
{
if (collection == null)
throw new ArgumentNullException(nameof(collection));
- foreach (object element in collection)
+ foreach (Variant element in collection)
Add(element);
}
- // TODO: This must be removed. Lots of silent mistakes as it takes pretty much anything.
/// <summary>
/// Constructs a new <see cref="Array"/> from the given objects.
/// </summary>
/// <param name="array">The objects to put in the new array.</param>
/// <returns>A new Godot Array.</returns>
- public Array(params object[] array) : this()
+ public Array(Variant[] array) : this()
+ {
+ if (array == null)
+ throw new ArgumentNullException(nameof(array));
+
+ NativeValue = (godot_array.movable)NativeFuncs.godotsharp_array_new();
+ _weakReferenceToSelf = DisposablesTracker.RegisterDisposable(this);
+
+ int length = array.Length;
+
+ Resize(length);
+
+ for (int i = 0; i < length; i++)
+ this[i] = array[i];
+ }
+
+ public Array(Span<StringName> array) : this()
+ {
+ if (array == null)
+ throw new ArgumentNullException(nameof(array));
+
+ NativeValue = (godot_array.movable)NativeFuncs.godotsharp_array_new();
+ _weakReferenceToSelf = DisposablesTracker.RegisterDisposable(this);
+
+ int length = array.Length;
+
+ Resize(length);
+
+ for (int i = 0; i < length; i++)
+ this[i] = array[i];
+ }
+
+ public Array(Span<NodePath> array) : this()
+ {
+ if (array == null)
+ throw new ArgumentNullException(nameof(array));
+
+ NativeValue = (godot_array.movable)NativeFuncs.godotsharp_array_new();
+ _weakReferenceToSelf = DisposablesTracker.RegisterDisposable(this);
+
+ int length = array.Length;
+
+ Resize(length);
+
+ for (int i = 0; i < length; i++)
+ this[i] = array[i];
+ }
+
+ public Array(Span<RID> array) : this()
+ {
+ if (array == null)
+ throw new ArgumentNullException(nameof(array));
+
+ NativeValue = (godot_array.movable)NativeFuncs.godotsharp_array_new();
+ _weakReferenceToSelf = DisposablesTracker.RegisterDisposable(this);
+
+ int length = array.Length;
+
+ Resize(length);
+
+ for (int i = 0; i < length; i++)
+ this[i] = array[i];
+ }
+
+ // We must use ReadOnlySpan instead of Span here as this can accept implicit conversions
+ // from derived types (e.g.: Node[]). Implicit conversion from Derived[] to Base[] are
+ // fine as long as the array is not mutated. However, Span does this type checking at
+ // instantiation, so it's not possible to use it even when not mutating anything.
+ // ReSharper disable once RedundantNameQualifier
+ public Array(ReadOnlySpan<Godot.Object> array) : this()
{
if (array == null)
throw new ArgumentNullException(nameof(array));
@@ -170,15 +237,15 @@ namespace Godot.Collections
}
/// <summary>
- /// Returns the object at the given <paramref name="index"/>.
+ /// Returns the item at the given <paramref name="index"/>.
/// </summary>
- /// <value>The object at the given <paramref name="index"/>.</value>
- public unsafe object this[int index]
+ /// <value>The <see cref="Variant"/> item at the given <paramref name="index"/>.</value>
+ public unsafe Variant this[int index]
{
get
{
GetVariantBorrowElementAt(index, out godot_variant borrowElem);
- return Marshaling.ConvertVariantToManagedObject(borrowElem);
+ return Variant.CreateCopyingBorrowed(borrowElem);
}
set
{
@@ -186,29 +253,30 @@ namespace Godot.Collections
throw new ArgumentOutOfRangeException(nameof(index));
var self = (godot_array)NativeValue;
godot_variant* ptrw = NativeFuncs.godotsharp_array_ptrw(ref self);
- ptrw[index] = Marshaling.ConvertManagedObjectToVariant(value);
+ godot_variant* itemPtr = &ptrw[index];
+ (*itemPtr).Dispose();
+ *itemPtr = value.CopyNativeVariant();
}
}
/// <summary>
- /// Adds an object to the end of this <see cref="Array"/>.
+ /// Adds an item to the end of this <see cref="Array"/>.
/// This is the same as <c>append</c> or <c>push_back</c> in GDScript.
/// </summary>
- /// <param name="item">The object to add.</param>
- /// <returns>The new size after adding the object.</returns>
- public void Add(object item)
+ /// <param name="item">The <see cref="Variant"/> item to add.</param>
+ public void Add(Variant item)
{
- using godot_variant variantValue = Marshaling.ConvertManagedObjectToVariant(item);
+ godot_variant variantValue = (godot_variant)item.NativeVar;
var self = (godot_array)NativeValue;
_ = NativeFuncs.godotsharp_array_add(ref self, variantValue);
}
/// <summary>
- /// Checks if this <see cref="Array"/> contains the given object.
+ /// Checks if this <see cref="Array"/> contains the given item.
/// </summary>
- /// <param name="item">The item to look for.</param>
- /// <returns>Whether or not this array contains the given object.</returns>
- public bool Contains(object item) => IndexOf(item) != -1;
+ /// <param name="item">The <see cref="Variant"/> item to look for.</param>
+ /// <returns>Whether or not this array contains the given item.</returns>
+ public bool Contains(Variant item) => IndexOf(item) != -1;
/// <summary>
/// Erases all items from this <see cref="Array"/>.
@@ -216,32 +284,32 @@ namespace Godot.Collections
public void Clear() => Resize(0);
/// <summary>
- /// Searches this <see cref="Array"/> for an object
+ /// Searches this <see cref="Array"/> for an item
/// and returns its index or -1 if not found.
/// </summary>
- /// <param name="item">The object to search for.</param>
- /// <returns>The index of the object, or -1 if not found.</returns>
- public int IndexOf(object item)
+ /// <param name="item">The <see cref="Variant"/> item to search for.</param>
+ /// <returns>The index of the item, or -1 if not found.</returns>
+ public int IndexOf(Variant item)
{
- using godot_variant variantValue = Marshaling.ConvertManagedObjectToVariant(item);
+ godot_variant variantValue = (godot_variant)item.NativeVar;
var self = (godot_array)NativeValue;
return NativeFuncs.godotsharp_array_index_of(ref self, variantValue);
}
/// <summary>
- /// Inserts a new object at a given position in the array.
+ /// Inserts a new item at a given position in the array.
/// The position must be a valid position of an existing item,
/// or the position at the end of the array.
/// Existing items will be moved to the right.
/// </summary>
/// <param name="index">The index to insert at.</param>
- /// <param name="item">The object to insert.</param>
- public void Insert(int index, object item)
+ /// <param name="item">The <see cref="Variant"/> item to insert.</param>
+ public void Insert(int index, Variant item)
{
if (index < 0 || index > Count)
throw new ArgumentOutOfRangeException(nameof(index));
- using godot_variant variantValue = Marshaling.ConvertManagedObjectToVariant(item);
+ godot_variant variantValue = (godot_variant)item.NativeVar;
var self = (godot_array)NativeValue;
NativeFuncs.godotsharp_array_insert(ref self, index, variantValue);
}
@@ -251,7 +319,7 @@ namespace Godot.Collections
/// from this <see cref="Array"/>.
/// </summary>
/// <param name="item">The value to remove.</param>
- public bool Remove(object item)
+ public bool Remove(Variant item)
{
int index = IndexOf(item);
if (index >= 0)
@@ -285,19 +353,19 @@ namespace Godot.Collections
/// <returns>The number of elements.</returns>
public int Count => NativeValue.DangerousSelfRef.Size;
- public bool IsSynchronized => false;
+ bool ICollection.IsSynchronized => false;
- public object SyncRoot => false;
+ object ICollection.SyncRoot => false;
- public bool IsReadOnly => false;
+ bool ICollection<Variant>.IsReadOnly => false;
/// <summary>
/// Copies the elements of this <see cref="Array"/> to the given
- /// untyped C# array, starting at the given index.
+ /// <see cref="Variant"/> C# array, starting at the given index.
/// </summary>
/// <param name="array">The array to copy to.</param>
/// <param name="arrayIndex">The index to start at.</param>
- public void CopyTo(object[] array, int arrayIndex)
+ public void CopyTo(Variant[] array, int arrayIndex)
{
if (array == null)
throw new ArgumentNullException(nameof(array), "Value cannot be null.");
@@ -320,8 +388,7 @@ namespace Godot.Collections
{
for (int i = 0; i < count; i++)
{
- object obj = Marshaling.ConvertVariantToManagedObject(NativeValue.DangerousSelfRef.Elements[i]);
- array[arrayIndex] = obj;
+ array[arrayIndex] = Variant.CreateCopyingBorrowed(NativeValue.DangerousSelfRef.Elements[i]);
arrayIndex++;
}
}
@@ -364,37 +431,13 @@ namespace Godot.Collections
return Marshaling.ConvertVariantToManagedObjectOfType(borrowElem, type);
}
- internal void CopyToGeneric<T>(T[] array, int arrayIndex, Type type = null)
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array), "Value cannot be null.");
-
- if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(arrayIndex),
- "Number was less than the array's lower bound in the first dimension.");
-
- var typeOfElements = type ?? typeof(T);
-
- int count = Count;
-
- if (array.Length < (arrayIndex + count))
- throw new ArgumentException(
- "Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
-
- for (int i = 0; i < count; i++)
- {
- array[arrayIndex] = (T)GetAtAsType(i, typeOfElements);
- arrayIndex++;
- }
- }
-
// IEnumerable
/// <summary>
/// Gets an enumerator for this <see cref="Array"/>.
/// </summary>
/// <returns>An enumerator.</returns>
- public IEnumerator<object> GetEnumerator()
+ public IEnumerator<Variant> GetEnumerator()
{
int count = Count;
@@ -436,289 +479,4 @@ namespace Godot.Collections
elem = NativeValue.DangerousSelfRef.Elements[index];
}
}
-
- internal interface IGenericGodotArray
- {
- Array UnderlyingArray { get; }
- Type TypeOfElements { get; }
- }
-
- // TODO: Now we should be able to avoid boxing
- /// <summary>
- /// Typed wrapper around Godot's Array class, an array of Variant
- /// typed elements allocated in the engine in C++. Useful when
- /// interfacing with the engine. Otherwise prefer .NET collections
- /// such as arrays or <see cref="List{T}"/>.
- /// </summary>
- /// <typeparam name="T">The type of the array.</typeparam>
- [SuppressMessage("ReSharper", "RedundantExtendsListEntry")]
- [SuppressMessage("Naming", "CA1710", MessageId = "Identifiers should have correct suffix")]
- public sealed class Array<T> : IList<T>, ICollection<T>, IEnumerable<T>, IGenericGodotArray
- {
- private readonly Array _underlyingArray;
-
- internal ref godot_array.movable NativeValue
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => ref _underlyingArray.NativeValue;
- }
-
- // ReSharper disable StaticMemberInGenericType
- // Warning is about unique static fields being created for each generic type combination:
- // https://www.jetbrains.com/help/resharper/StaticMemberInGenericType.html
- // In our case this is exactly what we want.
- private static readonly Type TypeOfElements = typeof(T);
- // ReSharper restore StaticMemberInGenericType
-
- Array IGenericGodotArray.UnderlyingArray => _underlyingArray;
- Type IGenericGodotArray.TypeOfElements => TypeOfElements;
-
- /// <summary>
- /// Constructs a new empty <see cref="Array{T}"/>.
- /// </summary>
- public Array()
- {
- _underlyingArray = new Array();
- }
-
- /// <summary>
- /// Constructs a new <see cref="Array{T}"/> from the given collection's elements.
- /// </summary>
- /// <param name="collection">The collection of elements to construct from.</param>
- /// <returns>A new Godot Array.</returns>
- public Array(IEnumerable<T> collection)
- {
- if (collection == null)
- throw new ArgumentNullException(nameof(collection));
-
- _underlyingArray = new Array(collection);
- }
-
- /// <summary>
- /// Constructs a new <see cref="Array{T}"/> from the given items.
- /// </summary>
- /// <param name="array">The items to put in the new array.</param>
- /// <returns>A new Godot Array.</returns>
- public Array(params T[] array) : this()
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array));
-
- _underlyingArray = new Array(array);
- }
-
- /// <summary>
- /// Constructs a typed <see cref="Array{T}"/> from an untyped <see cref="Array"/>.
- /// </summary>
- /// <param name="array">The untyped array to construct from.</param>
- public Array(Array array)
- {
- _underlyingArray = array;
- }
-
- // Explicit name to make it very clear
- internal static Array<T> CreateTakingOwnershipOfDisposableValue(godot_array nativeValueToOwn)
- => new Array<T>(Array.CreateTakingOwnershipOfDisposableValue(nativeValueToOwn));
-
- /// <summary>
- /// Converts this typed <see cref="Array{T}"/> to an untyped <see cref="Array"/>.
- /// </summary>
- /// <param name="from">The typed array to convert.</param>
- public static explicit operator Array(Array<T> from)
- {
- return from?._underlyingArray;
- }
-
- /// <summary>
- /// Duplicates this <see cref="Array{T}"/>.
- /// </summary>
- /// <param name="deep">If <see langword="true"/>, performs a deep copy.</param>
- /// <returns>A new Godot Array.</returns>
- public Array<T> Duplicate(bool deep = false)
- {
- return new Array<T>(_underlyingArray.Duplicate(deep));
- }
-
- /// <summary>
- /// Resizes this <see cref="Array{T}"/> to the given size.
- /// </summary>
- /// <param name="newSize">The new size of the array.</param>
- /// <returns><see cref="Error.Ok"/> if successful, or an error code.</returns>
- public Error Resize(int newSize)
- {
- return _underlyingArray.Resize(newSize);
- }
-
- /// <summary>
- /// Shuffles the contents of this <see cref="Array{T}"/> into a random order.
- /// </summary>
- public void Shuffle()
- {
- _underlyingArray.Shuffle();
- }
-
- /// <summary>
- /// Concatenates these two <see cref="Array{T}"/>s.
- /// </summary>
- /// <param name="left">The first array.</param>
- /// <param name="right">The second array.</param>
- /// <returns>A new Godot Array with the contents of both arrays.</returns>
- public static Array<T> operator +(Array<T> left, Array<T> right)
- {
- if (left == null)
- {
- if (right == null)
- return new Array<T>();
-
- return right.Duplicate(deep: false);
- }
-
- if (right == null)
- return left.Duplicate(deep: false);
-
- return new Array<T>(left._underlyingArray + right._underlyingArray);
- }
-
- // IList<T>
-
- /// <summary>
- /// Returns the value at the given <paramref name="index"/>.
- /// </summary>
- /// <value>The value at the given <paramref name="index"/>.</value>
- public T this[int index]
- {
- get => (T)_underlyingArray.GetAtAsType(index, TypeOfElements);
- set => _underlyingArray[index] = value;
- }
-
- /// <summary>
- /// Searches this <see cref="Array{T}"/> for an item
- /// and returns its index or -1 if not found.
- /// </summary>
- /// <param name="item">The item to search for.</param>
- /// <returns>The index of the item, or -1 if not found.</returns>
- public int IndexOf(T item)
- {
- return _underlyingArray.IndexOf(item);
- }
-
- /// <summary>
- /// Inserts a new item at a given position in the <see cref="Array{T}"/>.
- /// The position must be a valid position of an existing item,
- /// or the position at the end of the array.
- /// Existing items will be moved to the right.
- /// </summary>
- /// <param name="index">The index to insert at.</param>
- /// <param name="item">The item to insert.</param>
- public void Insert(int index, T item)
- {
- _underlyingArray.Insert(index, item);
- }
-
- /// <summary>
- /// Removes an element from this <see cref="Array{T}"/> by index.
- /// </summary>
- /// <param name="index">The index of the element to remove.</param>
- public void RemoveAt(int index)
- {
- _underlyingArray.RemoveAt(index);
- }
-
- // ICollection<T>
-
- /// <summary>
- /// Returns the number of elements in this <see cref="Array{T}"/>.
- /// This is also known as the size or length of the array.
- /// </summary>
- /// <returns>The number of elements.</returns>
- public int Count => _underlyingArray.Count;
-
- bool ICollection<T>.IsReadOnly => false;
-
- /// <summary>
- /// Adds an item to the end of this <see cref="Array{T}"/>.
- /// This is the same as <c>append</c> or <c>push_back</c> in GDScript.
- /// </summary>
- /// <param name="item">The item to add.</param>
- /// <returns>The new size after adding the item.</returns>
- public void Add(T item)
- {
- _underlyingArray.Add(item);
- }
-
- /// <summary>
- /// Erases all items from this <see cref="Array{T}"/>.
- /// </summary>
- public void Clear()
- {
- _underlyingArray.Clear();
- }
-
- /// <summary>
- /// Checks if this <see cref="Array{T}"/> contains the given item.
- /// </summary>
- /// <param name="item">The item to look for.</param>
- /// <returns>Whether or not this array contains the given item.</returns>
- public bool Contains(T item)
- {
- return _underlyingArray.Contains(item);
- }
-
- /// <summary>
- /// Copies the elements of this <see cref="Array{T}"/> to the given
- /// C# array, starting at the given index.
- /// </summary>
- /// <param name="array">The C# array to copy to.</param>
- /// <param name="arrayIndex">The index to start at.</param>
- public void CopyTo(T[] array, int arrayIndex) =>
- _underlyingArray.CopyToGeneric(array, arrayIndex, TypeOfElements);
-
- /// <summary>
- /// Removes the first occurrence of the specified value
- /// from this <see cref="Array{T}"/>.
- /// </summary>
- /// <param name="item">The value to remove.</param>
- /// <returns>A <see langword="bool"/> indicating success or failure.</returns>
- public bool Remove(T item)
- {
- int index = IndexOf(item);
- if (index >= 0)
- {
- RemoveAt(index);
- return true;
- }
-
- return false;
- }
-
- // IEnumerable<T>
-
- /// <summary>
- /// Gets an enumerator for this <see cref="Array{T}"/>.
- /// </summary>
- /// <returns>An enumerator.</returns>
- public IEnumerator<T> GetEnumerator()
- {
- int count = _underlyingArray.Count;
-
- for (int i = 0; i < count; i++)
- {
- yield return this[i];
- }
- }
-
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-
- /// <summary>
- /// Converts this <see cref="Array{T}"/> to a string.
- /// </summary>
- /// <returns>A string representation of this array.</returns>
- public override string ToString() => _underlyingArray.ToString();
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static implicit operator Variant(Array<T> from) => Variant.From(from);
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static explicit operator Array<T>(Variant from) => from.AsGodotGenericArray<T>();
- }
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs
index 3636a08377..ae44f8f4ba 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs
@@ -206,11 +206,8 @@ namespace Godot.Bridge
// Save instance state
- var info = new GodotSerializationInfo(
- Collections.Dictionary<StringName, object>.CreateTakingOwnershipOfDisposableValue(
- NativeFuncs.godotsharp_dictionary_new_copy(*propertiesState)),
- Collections.Dictionary<StringName, Collections.Array>.CreateTakingOwnershipOfDisposableValue(
- NativeFuncs.godotsharp_dictionary_new_copy(*signalEventsState)));
+ using var info = GodotSerializationInfo.CreateCopyingBorrowed(
+ *propertiesState, *signalEventsState);
godotObject.SaveGodotObjectData(info);
}
@@ -236,11 +233,8 @@ namespace Godot.Bridge
// Restore instance state
- var info = new GodotSerializationInfo(
- Collections.Dictionary<StringName, object>.CreateTakingOwnershipOfDisposableValue(
- NativeFuncs.godotsharp_dictionary_new_copy(*propertiesState)),
- Collections.Dictionary<StringName, Collections.Array>.CreateTakingOwnershipOfDisposableValue(
- NativeFuncs.godotsharp_dictionary_new_copy(*signalEventsState)));
+ using var info = GodotSerializationInfo.CreateCopyingBorrowed(
+ *propertiesState, *signalEventsState);
godotObject.RestoreGodotObjectData(info);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/GodotSerializationInfo.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/GodotSerializationInfo.cs
index 53aeff8207..8f26967dcd 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/GodotSerializationInfo.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/GodotSerializationInfo.cs
@@ -1,35 +1,43 @@
using System;
-using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
+using Godot.NativeInterop;
namespace Godot.Bridge;
-public class GodotSerializationInfo
+public class GodotSerializationInfo : IDisposable
{
- private readonly Collections.Dictionary<StringName, object> _properties = new();
- private readonly Collections.Dictionary<StringName, Collections.Array> _signalEvents = new();
+ private readonly Collections.Dictionary _properties;
+ private readonly Collections.Dictionary _signalEvents;
- internal GodotSerializationInfo()
+ public void Dispose()
{
+ _properties?.Dispose();
+ _signalEvents?.Dispose();
+
+ GC.SuppressFinalize(this);
+ }
+
+ private GodotSerializationInfo(in godot_dictionary properties, in godot_dictionary signalEvents)
+ {
+ _properties = Collections.Dictionary.CreateTakingOwnershipOfDisposableValue(properties);
+ _signalEvents = Collections.Dictionary.CreateTakingOwnershipOfDisposableValue(signalEvents);
}
- internal GodotSerializationInfo(
- Collections.Dictionary<StringName, object> properties,
- Collections.Dictionary<StringName, Collections.Array> signalEvents
- )
+ internal static GodotSerializationInfo CreateCopyingBorrowed(
+ in godot_dictionary properties, in godot_dictionary signalEvents)
{
- _properties = properties;
- _signalEvents = signalEvents;
+ return new(NativeFuncs.godotsharp_dictionary_new_copy(properties),
+ NativeFuncs.godotsharp_dictionary_new_copy(signalEvents));
}
- public void AddProperty(StringName name, object value)
+ public void AddProperty(StringName name, Variant value)
{
_properties[name] = value;
}
- public bool TryGetProperty<T>(StringName name, [MaybeNullWhen(false)] out T value)
+ public bool TryGetProperty(StringName name, out Variant value)
{
- return _properties.TryGetValueAsType(name, out value);
+ return _properties.TryGetValue(name, out value);
}
public void AddSignalEventDelegate(StringName name, Delegate eventDelegate)
@@ -49,9 +57,9 @@ public class GodotSerializationInfo
public bool TryGetSignalEventDelegate<T>(StringName name, [MaybeNullWhen(false)] out T value)
where T : Delegate
{
- if (_signalEvents.TryGetValue(name, out Collections.Array serializedData))
+ if (_signalEvents.TryGetValue(name, out Variant serializedData))
{
- if (DelegateUtils.TryDeserializeDelegate(serializedData, out var eventDelegate))
+ if (DelegateUtils.TryDeserializeDelegate(serializedData.AsGodotArray(), out var eventDelegate))
{
value = eventDelegate as T;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/MethodInfo.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/MethodInfo.cs
index 50260163bd..647ae436ff 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/MethodInfo.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/MethodInfo.cs
@@ -11,10 +11,10 @@ public struct MethodInfo
public MethodFlags Flags { get; init; }
public int Id { get; init; } = 0;
public List<PropertyInfo>? Arguments { get; init; }
- public List<object>? DefaultArguments { get; init; }
+ public List<Variant>? DefaultArguments { get; init; }
- public MethodInfo(StringName name, PropertyInfo returnVal, MethodFlags flags, List<PropertyInfo>? arguments,
- List<object>? defaultArguments)
+ public MethodInfo(StringName name, PropertyInfo returnVal, MethodFlags flags,
+ List<PropertyInfo>? arguments, List<Variant>? defaultArguments)
{
Name = name;
ReturnVal = returnVal;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs
index 03094cbe81..0dc5ba7678 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs
@@ -608,8 +608,8 @@ namespace Godot.Bridge
methodParams.Add(new Collections.Dictionary()
{
{ "name", param.Name },
- { "type", param.Type },
- { "usage", param.Usage }
+ { "type", (int)param.Type },
+ { "usage", (int)param.Usage }
});
}
}
@@ -628,7 +628,7 @@ namespace Godot.Bridge
// RPC functions
- Collections.Dictionary<string, Collections.Dictionary> rpcFunctions = new();
+ Collections.Dictionary rpcFunctions = new();
top = scriptType;
@@ -665,7 +665,7 @@ namespace Godot.Bridge
}
*outRpcFunctionsDest = NativeFuncs.godotsharp_dictionary_new_copy(
- (godot_dictionary)((Collections.Dictionary)rpcFunctions).NativeValue);
+ (godot_dictionary)(rpcFunctions).NativeValue);
// Event signals
@@ -696,8 +696,8 @@ namespace Godot.Bridge
signalParams.Add(new Collections.Dictionary()
{
{ "name", param.Name },
- { "type", param.Type },
- { "usage", param.Usage }
+ { "type", (int)param.Type },
+ { "usage", (int)param.Usage }
});
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
index ef75ff446a..8d0e77d171 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
@@ -85,7 +85,7 @@ namespace Godot
/// </summary>
/// <param name="args">Arguments that will be passed to the method call.</param>
/// <returns>The value returned by the method.</returns>
- public unsafe object Call(params object[] args)
+ public unsafe Variant Call(params Variant[] args)
{
using godot_callable callable = Marshaling.ConvertCallableToNative(this);
@@ -106,13 +106,13 @@ namespace Godot
{
for (int i = 0; i < argc; i++)
{
- varargs[i] = Marshaling.ConvertManagedObjectToVariant(args[i]);
+ varargs[i] = (godot_variant)args[i].NativeVar;
argsPtr[i] = new IntPtr(&varargs[i]);
}
- using godot_variant ret = NativeFuncs.godotsharp_callable_call(callable,
+ godot_variant ret = NativeFuncs.godotsharp_callable_call(callable,
(godot_variant**)argsPtr, argc, out _);
- return Marshaling.ConvertVariantToManagedObject(ret);
+ return Variant.CreateTakingOwnershipOfDisposableValue(ret);
}
}
@@ -121,7 +121,7 @@ namespace Godot
/// Arguments can be passed and should match the method's signature.
/// </summary>
/// <param name="args">Arguments that will be passed to the method call.</param>
- public unsafe void CallDeferred(params object[] args)
+ public unsafe void CallDeferred(params Variant[] args)
{
using godot_callable callable = Marshaling.ConvertCallableToNative(this);
@@ -142,7 +142,7 @@ namespace Godot
{
for (int i = 0; i < argc; i++)
{
- varargs[i] = Marshaling.ConvertManagedObjectToVariant(args[i]);
+ varargs[i] = (godot_variant)args[i].NativeVar;
argsPtr[i] = new IntPtr(&varargs[i]);
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs
index 48eec66182..266038a0af 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs
@@ -99,7 +99,7 @@ namespace Godot
if (TrySerializeSingleDelegate(@delegate, out byte[]? buffer))
{
- serializedData.Add(buffer);
+ serializedData.Add((Span<byte>)buffer);
return true;
}
@@ -181,8 +181,18 @@ namespace Godot
if (variantType == Variant.Type.Nil)
return false;
+ static byte[] Var2Bytes(in godot_variant var)
+ {
+ NativeFuncs.godotsharp_var2bytes(var, false.ToGodotBool(), out var varBytes);
+ using (varBytes)
+ return Marshaling.ConvertNativePackedByteArrayToSystemArray(varBytes);
+ }
+
writer.Write(field.Name);
- byte[] valueBuffer = GD.Var2Bytes(field.GetValue(target));
+
+ var fieldValue = field.GetValue(target);
+ using var fieldValueVariant = Marshaling.ConvertManagedObjectToVariant(fieldValue);
+ byte[] valueBuffer = Var2Bytes(fieldValueVariant);
writer.Write(valueBuffer.Length);
writer.Write(valueBuffer);
}
@@ -320,9 +330,14 @@ namespace Godot
internal static bool TryDeserializeDelegate(Collections.Array serializedData,
[MaybeNullWhen(false)] out Delegate @delegate)
{
+ @delegate = null;
+
if (serializedData.Count == 1)
{
- object elem = serializedData[0];
+ var elem = serializedData[0].Obj;
+
+ if (elem == null)
+ return false;
if (elem is Collections.Array multiCastData)
return TryDeserializeDelegate(multiCastData, out @delegate);
@@ -330,12 +345,15 @@ namespace Godot
return TryDeserializeSingleDelegate((byte[])elem, out @delegate);
}
- @delegate = null;
-
var delegates = new List<Delegate>(serializedData.Count);
- foreach (object elem in serializedData)
+ foreach (Variant variantElem in serializedData)
{
+ var elem = variantElem.Obj;
+
+ if (elem == null)
+ continue;
+
if (elem is Collections.Array multiCastData)
{
if (TryDeserializeDelegate(multiCastData, out Delegate? oneDelegate))
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
index a71ee1190e..c3d500119a 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
@@ -2,10 +2,6 @@ using System;
using System.Collections.Generic;
using System.Collections;
using Godot.NativeInterop;
-using System.Diagnostics.CodeAnalysis;
-using System.Runtime.CompilerServices;
-using System.Linq;
-using System.Runtime.CompilerServices;
namespace Godot.Collections
{
@@ -15,9 +11,8 @@ namespace Godot.Collections
/// interfacing with the engine.
/// </summary>
public sealed class Dictionary :
- IDictionary<object, object>,
- IDictionary,
- IReadOnlyDictionary<object, object>,
+ IDictionary<Variant, Variant>,
+ IReadOnlyDictionary<Variant, Variant>,
IDisposable
{
internal godot_dictionary.movable NativeValue;
@@ -33,20 +28,6 @@ namespace Godot.Collections
_weakReferenceToSelf = DisposablesTracker.RegisterDisposable(this);
}
- /// <summary>
- /// Constructs a new <see cref="Dictionary"/> from the given dictionary's elements.
- /// </summary>
- /// <param name="dictionary">The dictionary to construct from.</param>
- /// <returns>A new Godot Dictionary.</returns>
- public Dictionary(IDictionary dictionary) : this()
- {
- if (dictionary == null)
- throw new ArgumentNullException(nameof(dictionary));
-
- foreach (DictionaryEntry entry in dictionary)
- Add(entry.Key, entry.Value);
- }
-
private Dictionary(godot_dictionary nativeValueToOwn)
{
NativeValue = (godot_dictionary.movable)(nativeValueToOwn.IsAllocated ?
@@ -102,7 +83,7 @@ namespace Godot.Collections
/// <summary>
/// Gets the collection of keys in this <see cref="Dictionary"/>.
/// </summary>
- public ICollection<object> Keys
+ public ICollection<Variant> Keys
{
get
{
@@ -116,7 +97,7 @@ namespace Godot.Collections
/// <summary>
/// Gets the collection of elements in this <see cref="Dictionary"/>.
/// </summary>
- public ICollection<object> Values
+ public ICollection<Variant> Values
{
get
{
@@ -127,13 +108,9 @@ namespace Godot.Collections
}
}
- IEnumerable<object> IReadOnlyDictionary<object, object>.Keys => Keys;
-
- IEnumerable<object> IReadOnlyDictionary<object, object>.Values => Values;
-
- ICollection IDictionary.Keys => Keys.ToList();
+ IEnumerable<Variant> IReadOnlyDictionary<Variant, Variant>.Keys => Keys;
- ICollection IDictionary.Values => Values.ToList();
+ IEnumerable<Variant> IReadOnlyDictionary<Variant, Variant>.Values => Values;
private (Array keys, Array values, int count) GetKeyValuePairs()
{
@@ -152,25 +129,20 @@ namespace Godot.Collections
return (keys, values, count);
}
- bool IDictionary.IsFixedSize => false;
-
- bool IDictionary.IsReadOnly => false;
-
/// <summary>
- /// Returns the object at the given <paramref name="key"/>.
+ /// Returns the value at the given <paramref name="key"/>.
/// </summary>
- /// <value>The object at the given <paramref name="key"/>.</value>
- public object this[object key]
+ /// <value>The value at the given <paramref name="key"/>.</value>
+ public Variant this[Variant key]
{
get
{
- using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(key);
var self = (godot_dictionary)NativeValue;
- if (NativeFuncs.godotsharp_dictionary_try_get_value(ref self, variantKey,
- out godot_variant value).ToBool())
+
+ if (NativeFuncs.godotsharp_dictionary_try_get_value(ref self,
+ (godot_variant)key.NativeVar, out godot_variant value).ToBool())
{
- using (value)
- return Marshaling.ConvertVariantToManagedObject(value);
+ return Variant.CreateTakingOwnershipOfDisposableValue(value);
}
else
{
@@ -179,33 +151,31 @@ namespace Godot.Collections
}
set
{
- using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(key);
- using godot_variant variantValue = Marshaling.ConvertManagedObjectToVariant(value);
var self = (godot_dictionary)NativeValue;
- NativeFuncs.godotsharp_dictionary_set_value(ref self, variantKey, variantValue);
+ NativeFuncs.godotsharp_dictionary_set_value(ref self,
+ (godot_variant)key.NativeVar, (godot_variant)value.NativeVar);
}
}
/// <summary>
- /// Adds an object <paramref name="value"/> at key <paramref name="key"/>
+ /// Adds an value <paramref name="value"/> at key <paramref name="key"/>
/// to this <see cref="Dictionary"/>.
/// </summary>
- /// <param name="key">The key at which to add the object.</param>
- /// <param name="value">The object to add.</param>
- public void Add(object key, object value)
+ /// <param name="key">The key at which to add the value.</param>
+ /// <param name="value">The value to add.</param>
+ public void Add(Variant key, Variant value)
{
- using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(key);
-
+ var variantKey = (godot_variant)key.NativeVar;
var self = (godot_dictionary)NativeValue;
if (NativeFuncs.godotsharp_dictionary_contains_key(ref self, variantKey).ToBool())
throw new ArgumentException("An element with the same key already exists", nameof(key));
- using godot_variant variantValue = Marshaling.ConvertManagedObjectToVariant(value);
+ godot_variant variantValue = (godot_variant)value.NativeVar;
NativeFuncs.godotsharp_dictionary_add(ref self, variantKey, variantValue);
}
- void ICollection<KeyValuePair<object, object>>.Add(KeyValuePair<object, object> item)
+ void ICollection<KeyValuePair<Variant, Variant>>.Add(KeyValuePair<Variant, Variant> item)
=> Add(item.Key, item.Value);
/// <summary>
@@ -222,16 +192,15 @@ namespace Godot.Collections
/// </summary>
/// <param name="key">The key to look for.</param>
/// <returns>Whether or not this dictionary contains the given key.</returns>
- public bool ContainsKey(object key)
+ public bool ContainsKey(Variant key)
{
- using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(key);
var self = (godot_dictionary)NativeValue;
- return NativeFuncs.godotsharp_dictionary_contains_key(ref self, variantKey).ToBool();
+ return NativeFuncs.godotsharp_dictionary_contains_key(ref self, (godot_variant)key.NativeVar).ToBool();
}
- public bool Contains(KeyValuePair<object, object> item)
+ public bool Contains(KeyValuePair<Variant, Variant> item)
{
- using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(item.Key);
+ godot_variant variantKey = (godot_variant)item.Key.NativeVar;
var self = (godot_dictionary)NativeValue;
bool found = NativeFuncs.godotsharp_dictionary_try_get_value(ref self,
variantKey, out godot_variant retValue).ToBool();
@@ -241,30 +210,24 @@ namespace Godot.Collections
if (!found)
return false;
- using godot_variant variantValue = Marshaling.ConvertManagedObjectToVariant(item.Value);
+ godot_variant variantValue = (godot_variant)item.Value.NativeVar;
return NativeFuncs.godotsharp_variant_equals(variantValue, retValue).ToBool();
}
}
- bool IDictionary.Contains(object key)
- {
- throw new NotImplementedException();
- }
-
/// <summary>
/// Removes an element from this <see cref="Dictionary"/> by key.
/// </summary>
/// <param name="key">The key of the element to remove.</param>
- public bool Remove(object key)
+ public bool Remove(Variant key)
{
- using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(key);
var self = (godot_dictionary)NativeValue;
- return NativeFuncs.godotsharp_dictionary_remove_key(ref self, variantKey).ToBool();
+ return NativeFuncs.godotsharp_dictionary_remove_key(ref self, (godot_variant)key.NativeVar).ToBool();
}
- public bool Remove(KeyValuePair<object, object> item)
+ public bool Remove(KeyValuePair<Variant, Variant> item)
{
- using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(item.Key);
+ godot_variant variantKey = (godot_variant)item.Key.NativeVar;
var self = (godot_dictionary)NativeValue;
bool found = NativeFuncs.godotsharp_dictionary_try_get_value(ref self,
variantKey, out godot_variant retValue).ToBool();
@@ -274,7 +237,7 @@ namespace Godot.Collections
if (!found)
return false;
- using godot_variant variantValue = Marshaling.ConvertManagedObjectToVariant(item.Value);
+ godot_variant variantValue = (godot_variant)item.Value.NativeVar;
if (NativeFuncs.godotsharp_variant_equals(variantValue, retValue).ToBool())
{
return NativeFuncs.godotsharp_dictionary_remove_key(
@@ -285,17 +248,6 @@ namespace Godot.Collections
}
}
- void IDictionary.Remove(object key)
- {
- _ = Remove(key);
- }
-
- // ICollection
-
- object ICollection.SyncRoot => this;
-
- bool ICollection.IsSynchronized => false;
-
/// <summary>
/// Returns the number of elements in this <see cref="Dictionary"/>.
/// This is also known as the size or length of the dictionary.
@@ -310,19 +262,15 @@ namespace Godot.Collections
}
}
- public bool IsReadOnly => false;
+ bool ICollection<KeyValuePair<Variant, Variant>>.IsReadOnly => false;
- public bool TryGetValue(object key, out object value)
+ public bool TryGetValue(Variant key, out Variant value)
{
- using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(key);
var self = (godot_dictionary)NativeValue;
bool found = NativeFuncs.godotsharp_dictionary_try_get_value(ref self,
- variantKey, out godot_variant retValue).ToBool();
+ (godot_variant)key.NativeVar, out godot_variant retValue).ToBool();
- using (retValue)
- {
- value = found ? Marshaling.ConvertVariantToManagedObject(retValue) : default;
- }
+ value = found ? Variant.CreateTakingOwnershipOfDisposableValue(retValue) : default;
return found;
}
@@ -333,7 +281,7 @@ namespace Godot.Collections
/// </summary>
/// <param name="array">The array to copy to.</param>
/// <param name="arrayIndex">The index to start at.</param>
- public void CopyTo(KeyValuePair<object, object>[] array, int arrayIndex)
+ public void CopyTo(KeyValuePair<Variant, Variant>[] array, int arrayIndex)
{
if (array == null)
throw new ArgumentNullException(nameof(array), "Value cannot be null.");
@@ -355,35 +303,13 @@ namespace Godot.Collections
}
}
- void ICollection.CopyTo(System.Array array, int arrayIndex)
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array), "Value cannot be null.");
-
- if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(arrayIndex),
- "Number was less than the array's lower bound in the first dimension.");
-
- var (keys, values, count) = GetKeyValuePairs();
-
- if (array.Length < (arrayIndex + count))
- throw new ArgumentException(
- "Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
-
- for (int i = 0; i < count; i++)
- {
- array.SetValue(new DictionaryEntry(keys[i], values[i]), arrayIndex);
- arrayIndex++;
- }
- }
-
// IEnumerable
/// <summary>
/// Gets an enumerator for this <see cref="Dictionary"/>.
/// </summary>
/// <returns>An enumerator.</returns>
- public IEnumerator<KeyValuePair<object, object>> GetEnumerator()
+ public IEnumerator<KeyValuePair<Variant, Variant>> GetEnumerator()
{
for (int i = 0; i < Count; i++)
{
@@ -393,84 +319,14 @@ namespace Godot.Collections
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
- IDictionaryEnumerator IDictionary.GetEnumerator() => new DictionaryEnumerator(this);
-
- private class DictionaryEnumerator : IDictionaryEnumerator
- {
- private readonly Dictionary _dictionary;
- private readonly int _count;
- private int _index = -1;
- private bool _dirty = true;
-
- private DictionaryEntry _entry;
-
- public DictionaryEnumerator(Dictionary dictionary)
- {
- _dictionary = dictionary;
- _count = dictionary.Count;
- }
-
- public object Current => Entry;
-
- public DictionaryEntry Entry
- {
- get
- {
- if (_dirty)
- {
- UpdateEntry();
- }
-
- return _entry;
- }
- }
-
- private void UpdateEntry()
- {
- _dirty = false;
- var self = (godot_dictionary)_dictionary.NativeValue;
- NativeFuncs.godotsharp_dictionary_key_value_pair_at(ref self, _index,
- out godot_variant key,
- out godot_variant value);
- using (key)
- using (value)
- {
- // FIXME: DictionaryEntry keys cannot be null, but Godot dictionaries allow null keys
- _entry = new DictionaryEntry(Marshaling.ConvertVariantToManagedObject(key)!,
- Marshaling.ConvertVariantToManagedObject(value));
- }
- }
-
- public object Key => Entry.Key;
-
- public object Value => Entry.Value;
-
- public bool MoveNext()
- {
- _index++;
- _dirty = true;
- return _index < _count;
- }
-
- public void Reset()
- {
- _index = -1;
- _dirty = true;
- }
- }
-
- private KeyValuePair<object, object> GetKeyValuePair(int index)
+ private KeyValuePair<Variant, Variant> GetKeyValuePair(int index)
{
var self = (godot_dictionary)NativeValue;
NativeFuncs.godotsharp_dictionary_key_value_pair_at(ref self, index,
out godot_variant key,
out godot_variant value);
- using (key)
- using (value)
- {
- return new KeyValuePair<object, object>(Marshaling.ConvertVariantToManagedObject(key),
- Marshaling.ConvertVariantToManagedObject(value));
- }
+ return new KeyValuePair<Variant, Variant>(Variant.CreateTakingOwnershipOfDisposableValue(key),
+ Variant.CreateTakingOwnershipOfDisposableValue(value));
}
/// <summary>
@@ -485,332 +341,4 @@ namespace Godot.Collections
return Marshaling.ConvertStringToManaged(str);
}
}
-
- internal interface IGenericGodotDictionary
- {
- Dictionary UnderlyingDictionary { get; }
- Type TypeOfKeys { get; }
- Type TypeOfValues { get; }
- }
-
- // TODO: Now we should be able to avoid boxing
-
- /// <summary>
- /// Typed wrapper around Godot's Dictionary class, a dictionary of Variant
- /// typed elements allocated in the engine in C++. Useful when
- /// interfacing with the engine. Otherwise prefer .NET collections
- /// such as <see cref="System.Collections.Generic.Dictionary{TKey, TValue}"/>.
- /// </summary>
- /// <typeparam name="TKey">The type of the dictionary's keys.</typeparam>
- /// <typeparam name="TValue">The type of the dictionary's values.</typeparam>
- public class Dictionary<TKey, TValue> :
- IDictionary<TKey, TValue>, IGenericGodotDictionary
- {
- private readonly Dictionary _underlyingDict;
-
- internal ref godot_dictionary.movable NativeValue
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => ref _underlyingDict.NativeValue;
- }
-
- // ReSharper disable StaticMemberInGenericType
- // Warning is about unique static fields being created for each generic type combination:
- // https://www.jetbrains.com/help/resharper/StaticMemberInGenericType.html
- // In our case this is exactly what we want.
- private static readonly Type TypeOfKeys = typeof(TKey);
-
- private static readonly Type TypeOfValues = typeof(TValue);
- // ReSharper restore StaticMemberInGenericType
-
- Dictionary IGenericGodotDictionary.UnderlyingDictionary => _underlyingDict;
- Type IGenericGodotDictionary.TypeOfKeys => TypeOfKeys;
- Type IGenericGodotDictionary.TypeOfValues => TypeOfValues;
-
- /// <summary>
- /// Constructs a new empty <see cref="Dictionary{TKey, TValue}"/>.
- /// </summary>
- public Dictionary()
- {
- _underlyingDict = new Dictionary();
- }
-
- /// <summary>
- /// Constructs a new <see cref="Dictionary{TKey, TValue}"/> from the given dictionary's elements.
- /// </summary>
- /// <param name="dictionary">The dictionary to construct from.</param>
- /// <returns>A new Godot Dictionary.</returns>
- public Dictionary(IDictionary<TKey, TValue> dictionary)
- {
- if (dictionary == null)
- throw new ArgumentNullException(nameof(dictionary));
-
- _underlyingDict = new Dictionary();
-
- foreach (KeyValuePair<TKey, TValue> entry in dictionary)
- Add(entry.Key, entry.Value);
- }
-
- /// <summary>
- /// Constructs a new <see cref="Dictionary{TKey, TValue}"/> from the given dictionary's elements.
- /// </summary>
- /// <param name="dictionary">The dictionary to construct from.</param>
- /// <returns>A new Godot Dictionary.</returns>
- public Dictionary(Dictionary dictionary)
- {
- _underlyingDict = dictionary;
- }
-
- // Explicit name to make it very clear
- internal static Dictionary<TKey, TValue> CreateTakingOwnershipOfDisposableValue(
- godot_dictionary nativeValueToOwn)
- => new Dictionary<TKey, TValue>(Dictionary.CreateTakingOwnershipOfDisposableValue(nativeValueToOwn));
-
- /// <summary>
- /// Converts this typed <see cref="Dictionary{TKey, TValue}"/> to an untyped <see cref="Dictionary"/>.
- /// </summary>
- /// <param name="from">The typed dictionary to convert.</param>
- public static explicit operator Dictionary(Dictionary<TKey, TValue> from)
- {
- return from?._underlyingDict;
- }
-
- /// <summary>
- /// Duplicates this <see cref="Dictionary{TKey, TValue}"/>.
- /// </summary>
- /// <param name="deep">If <see langword="true"/>, performs a deep copy.</param>
- /// <returns>A new Godot Dictionary.</returns>
- public Dictionary<TKey, TValue> Duplicate(bool deep = false)
- {
- return new Dictionary<TKey, TValue>(_underlyingDict.Duplicate(deep));
- }
-
- // IDictionary<TKey, TValue>
-
- /// <summary>
- /// Returns the value at the given <paramref name="key"/>.
- /// </summary>
- /// <value>The value at the given <paramref name="key"/>.</value>
- public TValue this[TKey key]
- {
- get
- {
- using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(key);
- var self = (godot_dictionary)_underlyingDict.NativeValue;
- if (NativeFuncs.godotsharp_dictionary_try_get_value(ref self,
- variantKey, out godot_variant value).ToBool())
- {
- using (value)
- return (TValue)Marshaling.ConvertVariantToManagedObjectOfType(value, TypeOfValues);
- }
- else
- {
- throw new KeyNotFoundException();
- }
- }
- set => _underlyingDict[key] = value;
- }
-
- /// <summary>
- /// Gets the collection of keys in this <see cref="Dictionary{TKey, TValue}"/>.
- /// </summary>
- public ICollection<TKey> Keys
- {
- get
- {
- godot_array keyArray;
- var self = (godot_dictionary)_underlyingDict.NativeValue;
- NativeFuncs.godotsharp_dictionary_keys(ref self, out keyArray);
- return Array<TKey>.CreateTakingOwnershipOfDisposableValue(keyArray);
- }
- }
-
- /// <summary>
- /// Gets the collection of elements in this <see cref="Dictionary{TKey, TValue}"/>.
- /// </summary>
- public ICollection<TValue> Values
- {
- get
- {
- godot_array valuesArray;
- var self = (godot_dictionary)_underlyingDict.NativeValue;
- NativeFuncs.godotsharp_dictionary_values(ref self, out valuesArray);
- return Array<TValue>.CreateTakingOwnershipOfDisposableValue(valuesArray);
- }
- }
-
- private KeyValuePair<TKey, TValue> GetKeyValuePair(int index)
- {
- var self = (godot_dictionary)_underlyingDict.NativeValue;
- NativeFuncs.godotsharp_dictionary_key_value_pair_at(ref self, index,
- out godot_variant key,
- out godot_variant value);
- using (key)
- using (value)
- {
- return new KeyValuePair<TKey, TValue>(
- (TKey)Marshaling.ConvertVariantToManagedObjectOfType(key, TypeOfKeys),
- (TValue)Marshaling.ConvertVariantToManagedObjectOfType(value, TypeOfValues));
- }
- }
-
- /// <summary>
- /// Adds an object <paramref name="value"/> at key <paramref name="key"/>
- /// to this <see cref="Dictionary{TKey, TValue}"/>.
- /// </summary>
- /// <param name="key">The key at which to add the object.</param>
- /// <param name="value">The object to add.</param>
- public void Add(TKey key, TValue value)
- {
- _underlyingDict.Add(key, value);
- }
-
- /// <summary>
- /// Checks if this <see cref="Dictionary{TKey, TValue}"/> contains the given key.
- /// </summary>
- /// <param name="key">The key to look for.</param>
- /// <returns>Whether or not this dictionary contains the given key.</returns>
- public bool ContainsKey(TKey key)
- {
- return _underlyingDict.ContainsKey(key);
- }
-
- /// <summary>
- /// Removes an element from this <see cref="Dictionary{TKey, TValue}"/> by key.
- /// </summary>
- /// <param name="key">The key of the element to remove.</param>
- public bool Remove(TKey key)
- {
- using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(key);
- var self = (godot_dictionary)_underlyingDict.NativeValue;
- return NativeFuncs.godotsharp_dictionary_remove_key(ref self, variantKey).ToBool();
- }
-
- /// <summary>
- /// Gets the object at the given <paramref name="key"/>.
- /// </summary>
- /// <param name="key">The key of the element to get.</param>
- /// <param name="value">The value at the given <paramref name="key"/>.</param>
- /// <returns>If an object was found for the given <paramref name="key"/>.</returns>
- public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
- {
- using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(key);
- var self = (godot_dictionary)_underlyingDict.NativeValue;
- bool found = NativeFuncs.godotsharp_dictionary_try_get_value(ref self,
- variantKey, out godot_variant retValue).ToBool();
-
- using (retValue)
- {
- value = found ?
- (TValue)Marshaling.ConvertVariantToManagedObjectOfType(retValue, TypeOfValues) :
- default;
- }
-
- return found;
- }
-
- // TODO: This is temporary. It's needed for the serialization generator. It won't be needed once we replace System.Object with a Variant type.
- internal bool TryGetValueAsType<TValueCustom>(TKey key, [MaybeNullWhen(false)] out TValueCustom value)
- {
- using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(key);
- var self = (godot_dictionary)_underlyingDict.NativeValue;
- bool found = NativeFuncs.godotsharp_dictionary_try_get_value(ref self,
- variantKey, out godot_variant retValue).ToBool();
-
- using (retValue)
- {
- value = found ?
- (TValueCustom)Marshaling.ConvertVariantToManagedObjectOfType(retValue, typeof(TValueCustom)) :
- default;
- }
-
- return found;
- }
-
- // ICollection<KeyValuePair<TKey, TValue>>
-
- /// <summary>
- /// Returns the number of elements in this <see cref="Dictionary{TKey, TValue}"/>.
- /// This is also known as the size or length of the dictionary.
- /// </summary>
- /// <returns>The number of elements.</returns>
- public int Count => _underlyingDict.Count;
-
- bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly => false;
-
- void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
- {
- _underlyingDict.Add(item.Key, item.Value);
- }
-
- /// <summary>
- /// Erases all the items from this <see cref="Dictionary{TKey, TValue}"/>.
- /// </summary>
- public void Clear()
- {
- _underlyingDict.Clear();
- }
-
- bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
- => _underlyingDict.Contains(new(item.Key, item.Value));
-
- /// <summary>
- /// Copies the elements of this <see cref="Dictionary{TKey, TValue}"/> to the given
- /// untyped C# array, starting at the given index.
- /// </summary>
- /// <param name="array">The array to copy to.</param>
- /// <param name="arrayIndex">The index to start at.</param>
- public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array), "Value cannot be null.");
-
- if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(arrayIndex),
- "Number was less than the array's lower bound in the first dimension.");
-
- int count = Count;
-
- if (array.Length < (arrayIndex + count))
- throw new ArgumentException(
- "Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
-
- for (int i = 0; i < count; i++)
- {
- array[arrayIndex] = GetKeyValuePair(i);
- arrayIndex++;
- }
- }
-
- bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
- => _underlyingDict.Remove(new(item.Key, item.Value));
-
- // IEnumerable<KeyValuePair<TKey, TValue>>
-
- /// <summary>
- /// Gets an enumerator for this <see cref="Dictionary{TKey, TValue}"/>.
- /// </summary>
- /// <returns>An enumerator.</returns>
- public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
- {
- for (int i = 0; i < Count; i++)
- {
- yield return GetKeyValuePair(i);
- }
- }
-
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-
- /// <summary>
- /// Converts this <see cref="Dictionary{TKey, TValue}"/> to a string.
- /// </summary>
- /// <returns>A string representation of this dictionary.</returns>
- public override string ToString() => _underlyingDict.ToString();
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static implicit operator Variant(Dictionary<TKey, TValue> from) => Variant.From(from);
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static explicit operator Dictionary<TKey, TValue>(Variant from) => from.AsGodotGenericDictionary<TKey, TValue>();
- }
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/SceneTreeExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/SceneTreeExtensions.cs
deleted file mode 100644
index fa8a1c6402..0000000000
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/SceneTreeExtensions.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-using System.Reflection;
-using Godot.Collections;
-using Godot.NativeInterop;
-
-namespace Godot
-{
- public partial class SceneTree
- {
- /// <summary>
- /// Returns a list of all nodes assigned to the given <paramref name="group"/>.
- /// </summary>
- /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam>
- public Array<T> GetNodesInGroup<T>(StringName group) where T : class
- {
- var array = GetNodesInGroup(group);
-
- if (array.Count == 0)
- return new Array<T>(array);
-
- var typeOfT = typeof(T);
- bool nativeBase = InternalIsClassNativeBase(typeOfT);
-
- if (nativeBase)
- {
- // Native type
- var field = typeOfT.GetField("NativeName",
- BindingFlags.DeclaredOnly | BindingFlags.Static |
- BindingFlags.Public | BindingFlags.NonPublic);
-
- var nativeName = (StringName)field!.GetValue(null);
- var nativeNameSelf = (godot_string_name)nativeName!.NativeValue;
- var inputSelf = (godot_array)array.NativeValue;
- NativeFuncs.godotsharp_array_filter_godot_objects_by_native(nativeNameSelf, inputSelf,
- out godot_array filteredArray);
- return Array<T>.CreateTakingOwnershipOfDisposableValue(filteredArray);
- }
- else
- {
- // Custom derived type
- var inputSelf = (godot_array)array.NativeValue;
- NativeFuncs.godotsharp_array_filter_godot_objects_by_non_native(inputSelf,
- out godot_array filteredArray);
-
- var filteredArrayWrapped = Array.CreateTakingOwnershipOfDisposableValue(filteredArray);
-
- // Re-use first array as its size is the same or greater than the filtered one
- var resWrapped = new Array<T>(array);
-
- int j = 0;
- for (int i = 0; i < filteredArrayWrapped.Count; i++)
- {
- if (filteredArrayWrapped[i] is T t)
- {
- resWrapped[j] = t;
- j++;
- }
- }
-
- // Remove trailing elements, since this was re-used
- resWrapped.Resize(j);
-
- return resWrapped;
- }
- }
- }
-}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
index 206a8f1c0a..9348cc1d00 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
@@ -21,12 +21,11 @@ namespace Godot
/// <param name="bytes">Byte array that will be decoded to a <c>Variant</c>.</param>
/// <param name="allowObjects">If objects should be decoded.</param>
/// <returns>The decoded <c>Variant</c>.</returns>
- public static object Bytes2Var(byte[] bytes, bool allowObjects = false)
+ public static Variant Bytes2Var(Span<byte> bytes, bool allowObjects = false)
{
using var varBytes = Marshaling.ConvertSystemArrayToNativePackedByteArray(bytes);
NativeFuncs.godotsharp_bytes2var(varBytes, allowObjects.ToGodotBool(), out godot_variant ret);
- using (ret)
- return Marshaling.ConvertVariantToManagedObject(ret);
+ return Variant.CreateTakingOwnershipOfDisposableValue(ret);
}
/// <summary>
@@ -44,12 +43,10 @@ namespace Godot
/// </code>
/// </example>
/// <returns>The <c>Variant</c> converted to the given <paramref name="type"/>.</returns>
- public static object Convert(object what, Variant.Type type)
+ public static Variant Convert(Variant what, Variant.Type type)
{
- using var whatVariant = Marshaling.ConvertManagedObjectToVariant(what);
- NativeFuncs.godotsharp_convert(whatVariant, (int)type, out godot_variant ret);
- using (ret)
- return Marshaling.ConvertVariantToManagedObject(ret);
+ NativeFuncs.godotsharp_convert((godot_variant)what.NativeVar, (int)type, out godot_variant ret);
+ return Variant.CreateTakingOwnershipOfDisposableValue(ret);
}
/// <summary>
@@ -83,10 +80,9 @@ namespace Godot
/// </example>
/// <param name="var">Variable that will be hashed.</param>
/// <returns>Hash of the variable passed.</returns>
- public static int Hash(object var)
+ public static int Hash(Variant var)
{
- using var variant = Marshaling.ConvertManagedObjectToVariant(var);
- return NativeFuncs.godotsharp_hash(variant);
+ return NativeFuncs.godotsharp_hash((godot_variant)var.NativeVar);
}
/// <summary>
@@ -515,16 +511,16 @@ namespace Godot
/// </summary>
/// <param name="what">Arguments that will converted to string.</param>
/// <returns>The string formed by the given arguments.</returns>
- public static string Str(params object[] what)
+ public static string Str(params Variant[] what)
{
- using var whatGodotArray = Marshaling.ConvertSystemArrayToNativeGodotArray(what);
- NativeFuncs.godotsharp_str(whatGodotArray, out godot_string ret);
+ using var whatGodot = new Godot.Collections.Array(what);
+ NativeFuncs.godotsharp_str((godot_array)whatGodot.NativeValue, out godot_string ret);
using (ret)
return Marshaling.ConvertStringToManaged(ret);
}
/// <summary>
- /// Converts a formatted string that was returned by <see cref="Var2Str(object)"/> to the original value.
+ /// Converts a formatted string that was returned by <see cref="Var2Str(Variant)"/> to the original value.
/// </summary>
/// <example>
/// <code>
@@ -535,27 +531,25 @@ namespace Godot
/// </example>
/// <param name="str">String that will be converted to Variant.</param>
/// <returns>The decoded <c>Variant</c>.</returns>
- public static object Str2Var(string str)
+ public static Variant Str2Var(string str)
{
using var godotStr = Marshaling.ConvertStringToNative(str);
NativeFuncs.godotsharp_str2var(godotStr, out godot_variant ret);
- using (ret)
- return Marshaling.ConvertVariantToManagedObject(ret);
+ return Variant.CreateTakingOwnershipOfDisposableValue(ret);
}
/// <summary>
/// Encodes a <c>Variant</c> value to a byte array.
/// If <paramref name="fullObjects"/> is <see langword="true"/> encoding objects is allowed
/// (and can potentially include code).
- /// Deserialization can be done with <see cref="Bytes2Var(byte[], bool)"/>.
+ /// Deserialization can be done with <see cref="Bytes2Var(Span{byte}, bool)"/>.
/// </summary>
/// <param name="var">Variant that will be encoded.</param>
/// <param name="fullObjects">If objects should be serialized.</param>
/// <returns>The <c>Variant</c> encoded as an array of bytes.</returns>
- public static byte[] Var2Bytes(object var, bool fullObjects = false)
+ public static byte[] Var2Bytes(Variant var, bool fullObjects = false)
{
- using var variant = Marshaling.ConvertManagedObjectToVariant(var);
- NativeFuncs.godotsharp_var2bytes(variant, fullObjects.ToGodotBool(), out var varBytes);
+ NativeFuncs.godotsharp_var2bytes((godot_variant)var.NativeVar, fullObjects.ToGodotBool(), out var varBytes);
using (varBytes)
return Marshaling.ConvertNativePackedByteArrayToSystemArray(varBytes);
}
@@ -577,10 +571,9 @@ namespace Godot
/// </example>
/// <param name="var">Variant that will be converted to string.</param>
/// <returns>The <c>Variant</c> encoded as a string.</returns>
- public static string Var2Str(object var)
+ public static string Var2Str(Variant var)
{
- using var variant = Marshaling.ConvertManagedObjectToVariant(var);
- NativeFuncs.godotsharp_var2str(variant, out godot_string ret);
+ NativeFuncs.godotsharp_var2str((godot_variant)var.NativeVar, out godot_string ret);
using (ret)
return Marshaling.ConvertStringToManaged(ret);
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs
index 8802f229b3..eee19aea46 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs
@@ -1,7 +1,4 @@
using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Reflection;
using System.Runtime.InteropServices;
// ReSharper disable InconsistentNaming
@@ -11,8 +8,6 @@ using System.Runtime.InteropServices;
#nullable enable
-// TODO: Consider removing support for IEnumerable
-
namespace Godot.NativeInterop
{
public static class Marshaling
@@ -113,10 +108,10 @@ namespace Godot.NativeInterop
if (type == typeof(byte[]))
return Variant.Type.PackedByteArray;
- if (type == typeof(Int32[]))
+ if (type == typeof(int[]))
return Variant.Type.PackedInt32Array;
- if (type == typeof(Int64[]))
+ if (type == typeof(long[]))
return Variant.Type.PackedInt64Array;
if (type == typeof(float[]))
@@ -151,27 +146,6 @@ namespace Godot.NativeInterop
}
else if (type.IsGenericType)
{
- var genericTypeDefinition = type.GetGenericTypeDefinition();
-
- if (genericTypeDefinition == typeof(Collections.Dictionary<,>))
- return Variant.Type.Dictionary;
-
- if (genericTypeDefinition == typeof(Collections.Array<>))
- return Variant.Type.Array;
-
- if (genericTypeDefinition == typeof(System.Collections.Generic.Dictionary<,>))
- return Variant.Type.Dictionary;
-
- if (genericTypeDefinition == typeof(System.Collections.Generic.List<>))
- return Variant.Type.Array;
-
- if (genericTypeDefinition == typeof(IDictionary<,>))
- return Variant.Type.Dictionary;
-
- if (genericTypeDefinition == typeof(ICollection<>) ||
- genericTypeDefinition == typeof(IEnumerable<>))
- return Variant.Type.Array;
-
if (typeof(Godot.Object).IsAssignableFrom(type))
return Variant.Type.Object;
}
@@ -194,15 +168,11 @@ namespace Godot.NativeInterop
if (typeof(RID) == type)
return Variant.Type.Rid;
- if (typeof(Collections.Dictionary) == type || typeof(System.Collections.IDictionary) == type)
+ if (typeof(Collections.Dictionary) == type)
return Variant.Type.Dictionary;
- if (typeof(Collections.Array) == type ||
- typeof(System.Collections.ICollection) == type ||
- typeof(System.Collections.IEnumerable) == type)
- {
+ if (typeof(Collections.Array) == type)
return Variant.Type.Array;
- }
}
break;
@@ -214,7 +184,6 @@ namespace Godot.NativeInterop
}
/* TODO: Reflection and type checking each time is slow. This will be replaced with source generators. */
-
public static godot_variant ConvertManagedObjectToVariant(object? p_obj)
{
if (p_obj == null)
@@ -228,19 +197,19 @@ namespace Godot.NativeInterop
return VariantUtils.CreateFromInt(@char);
case sbyte @int8:
return VariantUtils.CreateFromInt(@int8);
- case Int16 @int16:
+ case short @int16:
return VariantUtils.CreateFromInt(@int16);
- case Int32 @int32:
+ case int @int32:
return VariantUtils.CreateFromInt(@int32);
- case Int64 @int64:
+ case long @int64:
return VariantUtils.CreateFromInt(@int64);
case byte @uint8:
return VariantUtils.CreateFromInt(@uint8);
- case UInt16 @uint16:
+ case ushort @uint16:
return VariantUtils.CreateFromInt(@uint16);
- case UInt32 @uint32:
+ case uint @uint32:
return VariantUtils.CreateFromInt(@uint32);
- case UInt64 @uint64:
+ case ulong @uint64:
return VariantUtils.CreateFromInt(@uint64);
case float @float:
return VariantUtils.CreateFromFloat(@float);
@@ -288,9 +257,9 @@ namespace Godot.NativeInterop
return VariantUtils.CreateFromString(@string);
case byte[] byteArray:
return VariantUtils.CreateFromPackedByteArray(byteArray);
- case Int32[] int32Array:
+ case int[] int32Array:
return VariantUtils.CreateFromPackedInt32Array(int32Array);
- case Int64[] int64Array:
+ case long[] int64Array:
return VariantUtils.CreateFromPackedInt64Array(int64Array);
case float[] floatArray:
return VariantUtils.CreateFromPackedFloat32Array(floatArray);
@@ -305,11 +274,11 @@ namespace Godot.NativeInterop
case Color[] colorArray:
return VariantUtils.CreateFromPackedColorArray(colorArray);
case StringName[] stringNameArray:
- return VariantUtils.CreateFromSystemArrayOfSupportedType(stringNameArray);
+ return VariantUtils.CreateFromSystemArrayOfStringName(stringNameArray);
case NodePath[] nodePathArray:
- return VariantUtils.CreateFromSystemArrayOfSupportedType(nodePathArray);
+ return VariantUtils.CreateFromSystemArrayOfNodePath(nodePathArray);
case RID[] ridArray:
- return VariantUtils.CreateFromSystemArrayOfSupportedType(ridArray);
+ return VariantUtils.CreateFromSystemArrayOfRID(ridArray);
case Godot.Object[] godotObjectArray:
return VariantUtils.CreateFromSystemArrayOfGodotObject(godotObjectArray);
case Godot.Object godotObject:
@@ -326,49 +295,6 @@ namespace Godot.NativeInterop
return VariantUtils.CreateFromArray(godotArray);
case Variant variant:
return NativeFuncs.godotsharp_variant_new_copy((godot_variant)variant.NativeVar);
- case Collections.IGenericGodotDictionary genericGodotDictionary:
- {
- var godotDict = genericGodotDictionary.UnderlyingDictionary;
- if (godotDict == null)
- return new godot_variant();
- return VariantUtils.CreateFromDictionary(godotDict);
- }
- case Collections.IGenericGodotArray genericGodotArray:
- {
- var godotArray = genericGodotArray.UnderlyingArray;
- if (godotArray == null)
- return new godot_variant();
- return VariantUtils.CreateFromArray(godotArray);
- }
- default:
- {
- var type = p_obj.GetType();
-
- if (type.IsGenericType)
- {
- var genericTypeDefinition = type.GetGenericTypeDefinition();
-
- if (genericTypeDefinition == typeof(System.Collections.Generic.Dictionary<,>))
- {
- // TODO: Validate key and value types are compatible with Variant
- var godotDict = new Collections.Dictionary();
-
- foreach (KeyValuePair<object, object> entry in (IDictionary)p_obj)
- godotDict.Add(entry.Key, entry.Value);
-
- return VariantUtils.CreateFromDictionary(godotDict);
- }
-
- if (genericTypeDefinition == typeof(System.Collections.Generic.List<>))
- {
- // TODO: Validate element type is compatible with Variant
- using var nativeGodotArray = ConvertICollectionToNativeGodotArray((ICollection)p_obj);
- return VariantUtils.CreateFromArray(nativeGodotArray);
- }
- }
-
- break;
- }
}
GD.PushError("Attempted to convert an unmarshallable managed type to Variant. Name: '" +
@@ -495,11 +421,31 @@ namespace Godot.NativeInterop
}
if (type.IsArray || type.IsSZArray)
+ {
return ConvertVariantToSystemArrayOfType(p_var, type);
+ }
else if (type.IsGenericType)
- return ConvertVariantToManagedObjectOfGenericType(p_var, type);
+ {
+ if (typeof(Godot.Object).IsAssignableFrom(type))
+ {
+ var godotObject = VariantUtils.ConvertToGodotObject(p_var);
+
+ if (!type.IsInstanceOfType(godotObject))
+ {
+ GD.PushError("Invalid cast when marshaling Godot.Object type." +
+ $" `{godotObject.GetType()}` is not assignable to `{type.FullName}`.");
+ return null;
+ }
+
+ return godotObject;
+ }
+
+ return null;
+ }
else if (type == typeof(Variant))
+ {
return Variant.CreateCopyingBorrowed(p_var);
+ }
if (ConvertVariantToManagedObjectOfClass(p_var, type, out object? res))
return res;
@@ -518,10 +464,10 @@ namespace Godot.NativeInterop
if (type == typeof(byte[]))
return VariantUtils.ConvertAsPackedByteArrayToSystemArray(p_var);
- if (type == typeof(Int32[]))
+ if (type == typeof(int[]))
return VariantUtils.ConvertAsPackedInt32ArrayToSystemArray(p_var);
- if (type == typeof(Int64[]))
+ if (type == typeof(long[]))
return VariantUtils.ConvertAsPackedInt64ArrayToSystemArray(p_var);
if (type == typeof(float[]))
@@ -543,13 +489,13 @@ namespace Godot.NativeInterop
return VariantUtils.ConvertAsPackedColorArrayToSystemArray(p_var);
if (type == typeof(StringName[]))
- return VariantUtils.ConvertToSystemArrayOfSupportedType<StringName>(p_var);
+ return VariantUtils.ConvertToSystemArrayOfStringName(p_var);
if (type == typeof(NodePath[]))
- return VariantUtils.ConvertToSystemArrayOfSupportedType<NodePath>(p_var);
+ return VariantUtils.ConvertToSystemArrayOfNodePath(p_var);
if (type == typeof(RID[]))
- return VariantUtils.ConvertToSystemArrayOfSupportedType<RID>(p_var);
+ return VariantUtils.ConvertToSystemArrayOfRID(p_var);
if (typeof(Godot.Object[]).IsAssignableFrom(type))
return VariantUtils.ConvertToSystemArrayOfGodotObject(p_var, type);
@@ -618,15 +564,13 @@ namespace Godot.NativeInterop
return true;
}
- if (typeof(Collections.Dictionary) == type || typeof(System.Collections.IDictionary) == type)
+ if (typeof(Collections.Dictionary) == type)
{
res = VariantUtils.ConvertToDictionaryObject(p_var);
return true;
}
- if (typeof(Collections.Array) == type ||
- typeof(System.Collections.ICollection) == type ||
- typeof(System.Collections.IEnumerable) == type)
+ if (typeof(Collections.Array) == type)
{
res = VariantUtils.ConvertToArrayObject(p_var);
return true;
@@ -636,103 +580,6 @@ namespace Godot.NativeInterop
return false;
}
- private static object? ConvertVariantToManagedObjectOfGenericType(in godot_variant p_var, Type type)
- {
- static object ConvertVariantToGenericGodotCollectionsDictionary(in godot_variant p_var, Type fullType)
- {
- var underlyingDict = VariantUtils.ConvertToDictionaryObject(p_var);
- return Activator.CreateInstance(fullType,
- BindingFlags.Public | BindingFlags.Instance, null,
- args: new object[] { underlyingDict }, null)!;
- }
-
- static object ConvertVariantToGenericGodotCollectionsArray(in godot_variant p_var, Type fullType)
- {
- var underlyingArray = VariantUtils.ConvertToArrayObject(p_var);
- return Activator.CreateInstance(fullType,
- BindingFlags.Public | BindingFlags.Instance, null,
- args: new object[] { underlyingArray }, null)!;
- }
-
- var genericTypeDefinition = type.GetGenericTypeDefinition();
-
- if (genericTypeDefinition == typeof(Collections.Dictionary<,>))
- return ConvertVariantToGenericGodotCollectionsDictionary(p_var, type);
-
- if (genericTypeDefinition == typeof(Collections.Array<>))
- return ConvertVariantToGenericGodotCollectionsArray(p_var, type);
-
- if (genericTypeDefinition == typeof(System.Collections.Generic.Dictionary<,>))
- {
- using var godotDictionary = VariantUtils.ConvertToDictionaryObject(p_var);
-
- var dictionary = (System.Collections.IDictionary)Activator.CreateInstance(type,
- BindingFlags.Public | BindingFlags.Instance, null,
- args: new object[]
- {
- /* capacity: */ godotDictionary.Count
- }, null)!;
-
- foreach (KeyValuePair<object, object> pair in godotDictionary)
- dictionary.Add(pair.Key, pair.Value);
-
- return dictionary;
- }
-
- if (genericTypeDefinition == typeof(System.Collections.Generic.List<>))
- {
- using var godotArray = VariantUtils.ConvertToArrayObject(p_var);
-
- var list = (System.Collections.IList)Activator.CreateInstance(type,
- BindingFlags.Public | BindingFlags.Instance, null,
- args: new object[]
- {
- /* capacity: */ godotArray.Count
- }, null)!;
-
- foreach (object elem in godotArray)
- list.Add(elem);
-
- return list;
- }
-
- if (genericTypeDefinition == typeof(IDictionary<,>))
- {
- var genericArgs = type.GetGenericArguments();
- var keyType = genericArgs[0];
- var valueType = genericArgs[1];
- var genericGodotDictionaryType = typeof(Collections.Dictionary<,>)
- .MakeGenericType(keyType, valueType);
-
- return ConvertVariantToGenericGodotCollectionsDictionary(p_var, genericGodotDictionaryType);
- }
-
- if (genericTypeDefinition == typeof(ICollection<>) || genericTypeDefinition == typeof(IEnumerable<>))
- {
- var elementType = type.GetGenericArguments()[0];
- var genericGodotArrayType = typeof(Collections.Array<>)
- .MakeGenericType(elementType);
-
- return ConvertVariantToGenericGodotCollectionsArray(p_var, genericGodotArrayType);
- }
-
- if (typeof(Godot.Object).IsAssignableFrom(type))
- {
- var godotObject = VariantUtils.ConvertToGodotObject(p_var);
-
- if (!type.IsInstanceOfType(godotObject))
- {
- GD.PushError("Invalid cast when marshaling Godot.Object type." +
- $" `{godotObject.GetType()}` is not assignable to `{type.FullName}`.");
- return null;
- }
-
- return godotObject;
- }
-
- return null;
- }
-
public static unsafe object? ConvertVariantToManagedObject(in godot_variant p_var)
{
switch (p_var.Type)
@@ -949,20 +796,6 @@ namespace Godot.NativeInterop
// Array
- internal static T[] ConvertNativeGodotArrayToSystemArrayOfType<T>(in godot_array p_array)
- {
- var array = Collections.Array.CreateTakingOwnershipOfDisposableValue(
- NativeFuncs.godotsharp_array_new_copy(p_array));
-
- int length = array.Count;
- var ret = new T[length];
-
- // ConvertVariantToManagedObjectOfType handled by Collections.Array.CopyToGeneric<T>
- array.CopyToGeneric(ret, 0);
-
- return ret;
- }
-
internal static T[] ConvertNativeGodotArrayToSystemArrayOfGodotObjectType<T>(in godot_array p_array)
where T : Godot.Object
{
@@ -972,12 +805,13 @@ namespace Godot.NativeInterop
int length = array.Count;
var ret = new T[length];
- // ConvertVariantToManagedObjectOfType handled by Collections.Array.CopyToGeneric<T>
- array.CopyToGeneric(ret, 0);
+ for (int i = 0; i < length; i++)
+ ret[i] = (T)array[i].AsGodotObject();
return ret;
}
+ // TODO: This needs reflection. Look for an alternative.
internal static Godot.Object[] ConvertNativeGodotArrayToSystemArrayOfGodotObjectType(in godot_array p_array,
Type type)
{
@@ -987,93 +821,52 @@ namespace Godot.NativeInterop
int length = array.Count;
var ret = (Godot.Object[])Activator.CreateInstance(type, length)!;
- // ConvertVariantToManagedObjectOfType handled by Collections.Array.CopyToGeneric<T>
- array.CopyToGeneric(ret, 0, type.GetElementType());
+ for (int i = 0; i < length; i++)
+ ret[i] = array[i].AsGodotObject();
return ret;
}
- public static godot_array ConvertSystemArrayToNativeGodotArray<T>(T[] p_array)
+ internal static StringName[] ConvertNativeGodotArrayToSystemArrayOfStringName(in godot_array p_array)
{
- int length = p_array.Length;
-
- if (length == 0)
- return NativeFuncs.godotsharp_array_new();
+ var array = Collections.Array.CreateTakingOwnershipOfDisposableValue(
+ NativeFuncs.godotsharp_array_new_copy(p_array));
- using var array = new Collections.Array();
- array.Resize(length);
+ int length = array.Count;
+ var ret = new StringName[length];
for (int i = 0; i < length; i++)
- array[i] = p_array[i];
-
- var src = (godot_array)array.NativeValue;
- return NativeFuncs.godotsharp_array_new_copy(src);
- }
-
- public static godot_array ConvertICollectionToNativeGodotArray(ICollection p_array)
- {
- int length = p_array.Count;
-
- if (length == 0)
- return NativeFuncs.godotsharp_array_new();
-
- using var array = new Collections.Array();
- array.Resize(length);
-
- int i = 0;
- foreach (var elem in p_array)
- {
- array[i] = elem;
- i++;
- }
+ ret[i] = array[i].AsStringName();
- var src = (godot_array)array.NativeValue;
- return NativeFuncs.godotsharp_array_new_copy(src);
+ return ret;
}
- public static godot_array ConvertGenericICollectionToNativeGodotArray<T>(ICollection<T> p_array)
+ internal static NodePath[] ConvertNativeGodotArrayToSystemArrayOfNodePath(in godot_array p_array)
{
- int length = p_array.Count;
-
- if (length == 0)
- return NativeFuncs.godotsharp_array_new();
+ var array = Collections.Array.CreateTakingOwnershipOfDisposableValue(
+ NativeFuncs.godotsharp_array_new_copy(p_array));
- var array = new Collections.Array<T>();
- using var underlyingArray = (Collections.Array)array;
- array.Resize(length);
+ int length = array.Count;
+ var ret = new NodePath[length];
- int i = 0;
- foreach (var elem in p_array)
- {
- array[i] = elem;
- i++;
- }
+ for (int i = 0; i < length; i++)
+ ret[i] = array[i].AsNodePath();
- var src = (godot_array)underlyingArray.NativeValue;
- return NativeFuncs.godotsharp_array_new_copy(src);
+ return ret;
}
- public static godot_array ConvertIEnumerableToNativeGodotArray(IEnumerable p_array)
+ internal static RID[] ConvertNativeGodotArrayToSystemArrayOfRID(in godot_array p_array)
{
- using var array = new Collections.Array();
-
- foreach (var elem in p_array)
- array.Add(elem);
-
- var src = (godot_array)array.NativeValue;
- return NativeFuncs.godotsharp_array_new_copy(src);
- }
+ var array = Collections.Array.CreateTakingOwnershipOfDisposableValue(
+ NativeFuncs.godotsharp_array_new_copy(p_array));
- public static godot_array ConvertGenericIEnumerableToNativeGodotArray<T>(IEnumerable<T> p_array)
- {
- var array = new Collections.Array<T>();
- using var underlyingArray = (Collections.Array)array;
+ int length = array.Count;
+ var ret = new RID[length];
- foreach (var elem in p_array)
- array.Add(elem);
+ for (int i = 0; i < length; i++)
+ ret[i] = array[i].AsRID();
- var src = (godot_array)underlyingArray.NativeValue;
- return NativeFuncs.godotsharp_array_new_copy(src);
+ return ret;
}
// PackedByteArray
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs
index fe0d7104ea..1ce8965939 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs
@@ -210,21 +210,22 @@ namespace Godot.NativeInterop
public static godot_variant CreateFromPackedColorArray(Span<Color> from)
=> CreateFromPackedColorArray(Marshaling.ConvertSystemArrayToNativePackedColorArray(from));
- public static godot_variant CreateFromSystemArrayOfSupportedType<T>(T[]? from)
- {
- if (from == null)
- return default; // Nil
- using godot_array array = Marshaling.ConvertSystemArrayToNativeGodotArray(from);
- return CreateFromArray(array);
- }
+ public static godot_variant CreateFromSystemArrayOfStringName(Span<StringName> from)
+ => CreateFromArray(new Collections.Array(from));
+
+ public static godot_variant CreateFromSystemArrayOfNodePath(Span<NodePath> from)
+ => CreateFromArray(new Collections.Array(from));
+
+ public static godot_variant CreateFromSystemArrayOfRID(Span<RID> from)
+ => CreateFromArray(new Collections.Array(from));
// ReSharper disable once RedundantNameQualifier
public static godot_variant CreateFromSystemArrayOfGodotObject(Godot.Object[]? from)
{
if (from == null)
return default; // Nil
- using godot_array array = Marshaling.ConvertSystemArrayToNativeGodotArray(from);
- return CreateFromArray(array);
+ using var fromGodot = new Collections.Array(from);
+ return CreateFromArray((godot_array)fromGodot.NativeValue);
}
public static godot_variant CreateFromArray(godot_array from)
@@ -237,45 +238,6 @@ namespace Godot.NativeInterop
public static godot_variant CreateFromArray(Collections.Array? from)
=> from != null ? CreateFromArray((godot_array)from.NativeValue) : default;
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- // ReSharper disable once RedundantNameQualifier
- public static godot_variant CreateFromArray<T>(Collections.Array<T>? from)
- => from != null ? CreateFromArray((godot_array)((Collections.Array)from).NativeValue) : default;
-
- public static godot_variant CreateFromSystemICollection(System.Collections.ICollection? from)
- {
- if (from == null)
- return default; // Nil
- using var nativeGodotArray = Marshaling.ConvertICollectionToNativeGodotArray(from);
- return CreateFromArray(nativeGodotArray);
- }
-
- public static godot_variant CreateFromSystemGenericICollection<T>(
- System.Collections.Generic.ICollection<T>? from)
- {
- if (from == null)
- return default; // Nil
- using var nativeGodotArray = Marshaling.ConvertGenericICollectionToNativeGodotArray(from);
- return CreateFromArray(nativeGodotArray);
- }
-
- public static godot_variant CreateFromSystemIEnumerable(System.Collections.IEnumerable? from)
- {
- if (from == null)
- return default; // Nil
- using var nativeGodotArray = Marshaling.ConvertIEnumerableToNativeGodotArray(from);
- return CreateFromArray(nativeGodotArray);
- }
-
- public static godot_variant CreateFromSystemGenericIEnumerable<T>(
- System.Collections.Generic.IEnumerable<T>? from)
- {
- if (from == null)
- return default; // Nil
- using var nativeGodotArray = Marshaling.ConvertGenericIEnumerableToNativeGodotArray(from);
- return CreateFromArray(nativeGodotArray);
- }
-
public static godot_variant CreateFromDictionary(godot_dictionary from)
{
NativeFuncs.godotsharp_variant_new_dictionary(out godot_variant ret, from);
@@ -286,51 +248,6 @@ namespace Godot.NativeInterop
public static godot_variant CreateFromDictionary(Dictionary? from)
=> from != null ? CreateFromDictionary((godot_dictionary)from.NativeValue) : default;
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static godot_variant CreateFromDictionary<TKey, TValue>(Dictionary<TKey, TValue>? from)
- => from != null ? CreateFromDictionary((godot_dictionary)((Dictionary)from).NativeValue) : default;
-
- public static godot_variant CreateFromSystemDictionary<TKey, TValue>(
- System.Collections.Generic.Dictionary<TKey, TValue>? from) where TKey : notnull
- {
- if (from == null)
- return default; // Nil
-
- var godotDict = new Dictionary();
-
- foreach (var entry in from)
- godotDict.Add(entry.Key, entry.Value);
-
- return CreateFromDictionary(godotDict);
- }
-
- public static godot_variant CreateFromSystemIDictionary(System.Collections.IDictionary? from)
- {
- if (from == null)
- return default; // Nil
-
- var godotDict = new Dictionary();
-
- foreach (var entry in from)
- godotDict.Add(entry, entry);
-
- return CreateFromDictionary(godotDict);
- }
-
- public static godot_variant CreateFromSystemGenericIDictionary<TKey, TValue>(
- System.Collections.Generic.IDictionary<TKey, TValue>? from)
- {
- if (from == null)
- return default; // Nil
-
- var godotDict = new Dictionary<TKey, TValue>();
-
- foreach (var entry in from)
- godotDict.Add(entry.Key, entry.Value);
-
- return CreateFromDictionary(godotDict);
- }
-
public static godot_variant CreateFromStringName(godot_string_name from)
{
NativeFuncs.godotsharp_variant_new_string_name(out godot_variant ret, from);
@@ -381,17 +298,17 @@ namespace Godot.NativeInterop
p_var.Int :
NativeFuncs.godotsharp_variant_as_int(p_var));
- public static Int16 ConvertToInt16(in godot_variant p_var)
- => (Int16)(p_var.Type == Variant.Type.Int ?
+ public static short ConvertToInt16(in godot_variant p_var)
+ => (short)(p_var.Type == Variant.Type.Int ?
p_var.Int :
NativeFuncs.godotsharp_variant_as_int(p_var));
- public static Int32 ConvertToInt32(in godot_variant p_var)
- => (Int32)(p_var.Type == Variant.Type.Int ?
+ public static int ConvertToInt32(in godot_variant p_var)
+ => (int)(p_var.Type == Variant.Type.Int ?
p_var.Int :
NativeFuncs.godotsharp_variant_as_int(p_var));
- public static Int64 ConvertToInt64(in godot_variant p_var)
+ public static long ConvertToInt64(in godot_variant p_var)
=> p_var.Type == Variant.Type.Int ? p_var.Int : NativeFuncs.godotsharp_variant_as_int(p_var);
public static byte ConvertToUInt8(in godot_variant p_var)
@@ -399,18 +316,18 @@ namespace Godot.NativeInterop
p_var.Int :
NativeFuncs.godotsharp_variant_as_int(p_var));
- public static UInt16 ConvertToUInt16(in godot_variant p_var)
- => (UInt16)(p_var.Type == Variant.Type.Int ?
+ public static ushort ConvertToUInt16(in godot_variant p_var)
+ => (ushort)(p_var.Type == Variant.Type.Int ?
p_var.Int :
NativeFuncs.godotsharp_variant_as_int(p_var));
- public static UInt32 ConvertToUInt32(in godot_variant p_var)
- => (UInt32)(p_var.Type == Variant.Type.Int ?
+ public static uint ConvertToUInt32(in godot_variant p_var)
+ => (uint)(p_var.Type == Variant.Type.Int ?
p_var.Int :
NativeFuncs.godotsharp_variant_as_int(p_var));
- public static UInt64 ConvertToUInt64(in godot_variant p_var)
- => (UInt64)(p_var.Type == Variant.Type.Int ?
+ public static ulong ConvertToUInt64(in godot_variant p_var)
+ => (ulong)(p_var.Type == Variant.Type.Int ?
p_var.Int :
NativeFuncs.godotsharp_variant_as_int(p_var));
@@ -642,10 +559,22 @@ namespace Godot.NativeInterop
return Marshaling.ConvertNativePackedColorArrayToSystemArray(packedArray);
}
- public static T[] ConvertToSystemArrayOfSupportedType<T>(in godot_variant p_var)
+ public static StringName[] ConvertToSystemArrayOfStringName(in godot_variant p_var)
+ {
+ using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var);
+ return Marshaling.ConvertNativeGodotArrayToSystemArrayOfStringName(godotArray);
+ }
+
+ public static NodePath[] ConvertToSystemArrayOfNodePath(in godot_variant p_var)
+ {
+ using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var);
+ return Marshaling.ConvertNativeGodotArrayToSystemArrayOfNodePath(godotArray);
+ }
+
+ public static RID[] ConvertToSystemArrayOfRID(in godot_variant p_var)
{
using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var);
- return Marshaling.ConvertNativeGodotArrayToSystemArrayOfType<T>(godotArray);
+ return Marshaling.ConvertNativeGodotArrayToSystemArrayOfRID(godotArray);
}
public static T[] ConvertToSystemArrayOfGodotObject<T>(in godot_variant p_var)
@@ -662,37 +591,5 @@ namespace Godot.NativeInterop
using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var);
return Marshaling.ConvertNativeGodotArrayToSystemArrayOfGodotObjectType(godotArray, type);
}
-
- public static Array<T> ConvertToGenericArrayObject<T>(in godot_variant p_var) =>
- new(ConvertToArrayObject(p_var));
-
- public static Dictionary<TKey, TValue> ConvertToGenericDictionaryObject<TKey, TValue>(in godot_variant p_var) =>
- new(ConvertToDictionaryObject(p_var));
-
- public static System.Collections.Generic.List<T> ConvertToSystemGenericList<T>(in godot_variant p_var)
- {
- var godotArray = ConvertToArrayObject(p_var);
-
- var res = new System.Collections.Generic.List<T>(godotArray.Count);
-
- foreach (object elem in godotArray)
- res.Add((T)elem);
-
- return res;
- }
-
- public static System.Collections.Generic.Dictionary<TKey, TValue>
- ConvertToSystemGenericDictionary<TKey, TValue>(in godot_variant p_var)
- where TKey : notnull
- {
- var godotDictionary = ConvertToDictionaryObject(p_var);
-
- var res = new System.Collections.Generic.Dictionary<TKey, TValue>(godotDictionary.Count);
-
- foreach (System.Collections.Generic.KeyValuePair<object, object> pair in godotDictionary)
- res.Add((TKey)pair.Key, (TValue)pair.Value);
-
- return res;
- }
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs
index 04920ccfab..5cb678c280 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs
@@ -187,18 +187,6 @@ namespace Godot
return null;
}
- internal static bool InternalIsClassNativeBase(Type t)
- {
- // Check whether the type is declared in the GodotSharp or GodotSharpEditor assemblies
- var typeAssembly = t.Assembly;
-
- if (typeAssembly == CachedType.Assembly)
- return true;
-
- var typeAssemblyName = t.Assembly.GetName();
- return typeAssemblyName.Name == "GodotSharpEditor";
- }
-
// ReSharper disable once VirtualMemberNeverOverridden.Global
protected internal virtual bool SetGodotClassPropertyValue(in godot_string_name name, in godot_variant value)
{
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs
index 8ba3c403fa..96fb891086 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs
@@ -4,10 +4,10 @@ using Godot.NativeInterop;
namespace Godot
{
- public class SignalAwaiter : IAwaiter<object[]>, IAwaitable<object[]>
+ public class SignalAwaiter : IAwaiter<Variant[]>, IAwaitable<Variant[]>
{
private bool _completed;
- private object[] _result;
+ private Variant[] _result;
private Action _continuation;
public SignalAwaiter(Object source, StringName signal, Object target)
@@ -26,9 +26,9 @@ namespace Godot
_continuation = continuation;
}
- public object[] GetResult() => _result;
+ public Variant[] GetResult() => _result;
- public IAwaiter<object[]> GetAwaiter() => this;
+ public IAwaiter<Variant[]> GetAwaiter() => this;
[UnmanagedCallersOnly]
internal static unsafe void SignalCallback(IntPtr awaiterGCHandlePtr, godot_variant** args, int argCount,
@@ -48,10 +48,10 @@ namespace Godot
awaiter._completed = true;
- object[] signalArgs = new object[argCount];
+ Variant[] signalArgs = new Variant[argCount];
for (int i = 0; i < argCount; i++)
- signalArgs[i] = Marshaling.ConvertVariantToManagedObject(*args[i]);
+ signalArgs[i] = Variant.CreateCopyingBorrowed(*args[i]);
awaiter._result = signalArgs;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
index 0a61069a1e..d1ff6ade8a 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
+++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
@@ -78,7 +78,6 @@
<Compile Include="Core\Extensions\ObjectExtensions.cs" />
<Compile Include="Core\Extensions\PackedSceneExtensions.cs" />
<Compile Include="Core\Extensions\ResourceLoaderExtensions.cs" />
- <Compile Include="Core\Extensions\SceneTreeExtensions.cs" />
<Compile Include="Core\GD.cs" />
<Compile Include="Core\GodotSynchronizationContext.cs" />
<Compile Include="Core\GodotTaskScheduler.cs" />
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Variant.cs b/modules/mono/glue/GodotSharp/GodotSharp/Variant.cs
index c1c321829a..7c4df291ac 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Variant.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Variant.cs
@@ -105,6 +105,8 @@ public partial struct Variant : IDisposable
// TODO: Consider renaming Variant.Type to VariantType and this property to Type. VariantType would also avoid ambiguity with System.Type.
public Type VariantType => NativeVar.DangerousSelfRef.Type;
+ public override string ToString() => AsString();
+
public object? Obj
{
get
@@ -116,8 +118,6 @@ public partial struct Variant : IDisposable
}
}
- // TODO: Consider implicit operators
-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool AsBool() =>
VariantUtils.ConvertToBool((godot_variant)NativeVar);
@@ -211,6 +211,18 @@ public partial struct Variant : IDisposable
VariantUtils.ConvertToTransform3D((godot_variant)NativeVar);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Vector4 AsVector4() =>
+ VariantUtils.ConvertToVector4((godot_variant)NativeVar);
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Vector4i AsVector4i() =>
+ VariantUtils.ConvertToVector4i((godot_variant)NativeVar);
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Projection AsProjection() =>
+ VariantUtils.ConvertToProjection((godot_variant)NativeVar);
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public AABB AsAABB() =>
VariantUtils.ConvertToAABB((godot_variant)NativeVar);
@@ -272,25 +284,16 @@ public partial struct Variant : IDisposable
VariantUtils.ConvertToSystemArrayOfGodotObject<T>((godot_variant)NativeVar);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public T[] AsSystemArrayOfSupportedType<T>() =>
- VariantUtils.ConvertToSystemArrayOfSupportedType<T>((godot_variant)NativeVar);
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Collections.Dictionary<TKey, TValue> AsGodotGenericDictionary<TKey, TValue>() =>
- VariantUtils.ConvertToGenericDictionaryObject<TKey, TValue>((godot_variant)NativeVar);
+ public StringName[] AsSystemArrayOfStringName() =>
+ VariantUtils.ConvertToSystemArrayOfStringName((godot_variant)NativeVar);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Collections.Array<T> AsGodotGenericArray<T>() =>
- VariantUtils.ConvertToGenericArrayObject<T>((godot_variant)NativeVar);
+ public NodePath[] AsSystemArrayOfNodePath() =>
+ VariantUtils.ConvertToSystemArrayOfNodePath((godot_variant)NativeVar);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public System.Collections.Generic.Dictionary<TKey, TValue> AsSystemGenericDictionary<TKey, TValue>()
- where TKey : notnull =>
- VariantUtils.ConvertToSystemGenericDictionary<TKey, TValue>((godot_variant)NativeVar);
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public System.Collections.Generic.List<T> AsSystemGenericList<T>() =>
- VariantUtils.ConvertToSystemGenericList<T>((godot_variant)NativeVar);
+ public RID[] AsSystemArrayOfRID() =>
+ VariantUtils.ConvertToSystemArrayOfRID((godot_variant)NativeVar);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Godot.Object AsGodotObject() =>
@@ -388,6 +391,15 @@ public partial struct Variant : IDisposable
public static explicit operator Transform3D(Variant from) => from.AsTransform3D();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static explicit operator Vector4(Variant from) => from.AsVector4();
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static explicit operator Vector4i(Variant from) => from.AsVector4i();
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static explicit operator Projection(Variant from) => from.AsProjection();
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator AABB(Variant from) => from.AsAABB();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -430,6 +442,15 @@ public partial struct Variant : IDisposable
public static explicit operator Color[](Variant from) => from.AsColorArray();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static explicit operator StringName[](Variant from) => from.AsSystemArrayOfStringName();
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static explicit operator NodePath[](Variant from) => from.AsSystemArrayOfNodePath();
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static explicit operator RID[](Variant from) => from.AsSystemArrayOfRID();
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator Godot.Object(Variant from) => from.AsGodotObject();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -447,6 +468,161 @@ public partial struct Variant : IDisposable
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator Collections.Array(Variant from) => from.AsGodotArray();
+ // While we provide implicit conversion operators, normal methods are still needed for
+ // casts that are not done implicitly (e.g.: raw array to Span, enum to integer, etc).
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(bool from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(char from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(sbyte from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(short from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(int from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(long from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(byte from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(ushort from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(uint from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(ulong from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(float from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(double from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(string from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Vector2 from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Vector2i from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Rect2 from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Rect2i from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Transform2D from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Vector3 from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Vector3i from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Basis from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Quaternion from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Transform3D from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Vector4 from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Vector4i from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Projection from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(AABB from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Color from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Plane from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Callable from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(SignalInfo from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Span<byte> from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Span<int> from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Span<long> from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Span<float> from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Span<double> from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Span<string> from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Span<Vector2> from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Span<Vector3> from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Span<Color> from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Godot.Object[] from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Span<StringName> from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Span<NodePath> from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Span<RID> from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Godot.Object from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(StringName from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(NodePath from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(RID from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Collections.Dictionary from) => from;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Variant CreateFrom(Collections.Array from) => from;
+
+ // Implicit conversion operators
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Variant(bool from) =>
CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromBool(from));
@@ -540,6 +716,18 @@ public partial struct Variant : IDisposable
CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromTransform3D(from));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static implicit operator Variant(Vector4 from) =>
+ CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromVector4(from));
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static implicit operator Variant(Vector4i from) =>
+ CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromVector4i(from));
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static implicit operator Variant(Projection from) =>
+ CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromProjection(from));
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Variant(AABB from) =>
CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromAABB(from));
@@ -596,36 +784,20 @@ public partial struct Variant : IDisposable
CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromPackedColorArray(from));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static implicit operator Variant(Godot.Object[]? from) =>
+ public static implicit operator Variant(Godot.Object[] from) =>
CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemArrayOfGodotObject(from));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Variant From<TKey, TValue>(Collections.Dictionary<TKey, TValue> from) =>
- CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromDictionary(from));
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Variant From<T>(Collections.Array<T> from) =>
- CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromArray(from));
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Variant From<TKey, TValue>(System.Collections.Generic.Dictionary<TKey, TValue> from)
- where TKey : notnull => CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemDictionary(from));
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Variant From<T>(System.Collections.Generic.List<T> from) =>
- CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemICollection(from));
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Variant From<TKey, TValue>(System.Collections.Generic.IDictionary<TKey, TValue> from) =>
- CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemGenericIDictionary(from));
+ public static implicit operator Variant(Span<StringName> from) =>
+ CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemArrayOfStringName(from));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Variant From<T>(System.Collections.Generic.ICollection<T> from) =>
- CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemGenericICollection(from));
+ public static implicit operator Variant(Span<NodePath> from) =>
+ CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemArrayOfNodePath(from));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Variant From<T>(System.Collections.Generic.IEnumerable<T> from) =>
- CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemGenericIEnumerable(from));
+ public static implicit operator Variant(Span<RID> from) =>
+ CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemArrayOfRID(from));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Variant(Godot.Object from) =>
@@ -650,16 +822,4 @@ public partial struct Variant : IDisposable
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Variant(Collections.Array from) =>
CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromArray(from));
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Variant From(System.Collections.IDictionary from) =>
- CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemIDictionary(from));
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Variant From(System.Collections.ICollection from) =>
- CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemICollection(from));
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Variant From(System.Collections.IEnumerable from) =>
- CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemIEnumerable(from));
}