summaryrefslogtreecommitdiff
path: root/modules/mono/glue/GodotSharp
diff options
context:
space:
mode:
authorIgnacio Roldán Etcheverry <ignalfonsore@gmail.com>2021-12-28 23:25:16 +0100
committerIgnacio Roldán Etcheverry <ignalfonsore@gmail.com>2022-08-22 03:36:51 +0200
commite5e7a795b14487e7eb0cfb011a8e0518769ce533 (patch)
tree57a0322ef0c11d8944f9a95708d243dcc3e4c5a4 /modules/mono/glue/GodotSharp
parent34db8d2c6c4d2c714772479145c235c9f4189bdb (diff)
C#: Code cleanup and greatly reduce use of C# pointers
Diffstat (limited to 'modules/mono/glue/GodotSharp')
-rw-r--r--modules/mono/glue/GodotSharp/.editorconfig8
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs142
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs8
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs31
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs41
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs66
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs8
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/DebuggingUtils.cs14
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs6
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs205
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs15
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/SceneTreeExtensions.cs18
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs115
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropStructs.cs692
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropUtils.cs27
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs599
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs364
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.extended.cs61
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeVariantPtrArgs.cs20
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantSpanHelpers.cs10
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs350
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs70
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs53
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs14
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs75
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs22
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs12
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/FodyWeavers.xml3
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/GenerateGodotCustomUnsafe.targets93
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj9
37 files changed, 1968 insertions, 1209 deletions
diff --git a/modules/mono/glue/GodotSharp/.editorconfig b/modules/mono/glue/GodotSharp/.editorconfig
new file mode 100644
index 0000000000..d4e71b1bd9
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/.editorconfig
@@ -0,0 +1,8 @@
+[**/Generated/**.cs]
+# Validate parameter is non-null before using it
+# Useful for generated code, as it disables nullable
+dotnet_diagnostic.CA1062.severity = error
+# CA1069: Enums should not have duplicate values
+dotnet_diagnostic.CA1069.severity = none
+# CA1708: Identifiers should differ by more than case
+dotnet_diagnostic.CA1708.severity = none
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
index 2aa2ece803..9fa221a0cc 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Collections;
using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
using Godot.NativeInterop;
namespace Godot.Collections
@@ -14,14 +15,14 @@ namespace Godot.Collections
/// </summary>
public sealed class Array : IList, IDisposable
{
- public godot_array NativeValue;
+ internal godot_array.movable NativeValue;
/// <summary>
/// Constructs a new empty <see cref="Array"/>.
/// </summary>
public Array()
{
- NativeValue = NativeFuncs.godotsharp_array_new();
+ NativeValue = (godot_array.movable)NativeFuncs.godotsharp_array_new();
}
/// <summary>
@@ -32,7 +33,7 @@ namespace Godot.Collections
public Array(IEnumerable collection) : this()
{
if (collection == null)
- throw new NullReferenceException($"Parameter '{nameof(collection)} cannot be null.'");
+ throw new ArgumentNullException(nameof(collection));
foreach (object element in collection)
Add(element);
@@ -47,9 +48,9 @@ namespace Godot.Collections
public Array(params object[] array) : this()
{
if (array == null)
- throw new NullReferenceException($"Parameter '{nameof(array)} cannot be null.'");
+ throw new ArgumentNullException(nameof(array));
- NativeValue = NativeFuncs.godotsharp_array_new();
+ NativeValue = (godot_array.movable)NativeFuncs.godotsharp_array_new();
int length = array.Length;
Resize(length);
@@ -60,7 +61,9 @@ namespace Godot.Collections
private Array(godot_array nativeValueToOwn)
{
- NativeValue = nativeValueToOwn;
+ NativeValue = (godot_array.movable)(nativeValueToOwn.IsAllocated ?
+ nativeValueToOwn :
+ NativeFuncs.godotsharp_array_new());
}
// Explicit name to make it very clear
@@ -84,7 +87,7 @@ namespace Godot.Collections
public void Dispose(bool disposing)
{
// Always dispose `NativeValue` even if disposing is true
- NativeValue.Dispose();
+ NativeValue.DangerousSelfRef.Dispose();
}
/// <summary>
@@ -95,7 +98,8 @@ namespace Godot.Collections
public Array Duplicate(bool deep = false)
{
godot_array newArray;
- NativeFuncs.godotsharp_array_duplicate(ref NativeValue, deep.ToGodotBool(), out newArray);
+ var self = (godot_array)NativeValue;
+ NativeFuncs.godotsharp_array_duplicate(ref self, deep.ToGodotBool(), out newArray);
return CreateTakingOwnershipOfDisposableValue(newArray);
}
@@ -104,12 +108,20 @@ namespace Godot.Collections
/// </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) => NativeFuncs.godotsharp_array_resize(ref NativeValue, newSize);
+ public Error Resize(int newSize)
+ {
+ var self = (godot_array)NativeValue;
+ return NativeFuncs.godotsharp_array_resize(ref self, newSize);
+ }
/// <summary>
/// Shuffles the contents of this <see cref="Array"/> into a random order.
/// </summary>
- public void Shuffle() => NativeFuncs.godotsharp_array_shuffle(ref NativeValue);
+ public void Shuffle()
+ {
+ var self = (godot_array)NativeValue;
+ NativeFuncs.godotsharp_array_shuffle(ref self);
+ }
/// <summary>
/// Concatenates these two <see cref="Array"/>s.
@@ -119,6 +131,17 @@ namespace Godot.Collections
/// <returns>A new Godot Array with the contents of both arrays.</returns>
public static Array operator +(Array left, Array right)
{
+ if (left == null)
+ {
+ if (right == null)
+ return new Array();
+
+ return right.Duplicate(deep: false);
+ }
+
+ if (right == null)
+ return left.Duplicate(deep: false);
+
int leftCount = left.Count;
int rightCount = right.Count;
@@ -146,14 +169,15 @@ namespace Godot.Collections
get
{
GetVariantBorrowElementAt(index, out godot_variant borrowElem);
- return Marshaling.variant_to_mono_object(&borrowElem);
+ return Marshaling.ConvertVariantToManagedObject(borrowElem);
}
set
{
if (index < 0 || index >= Count)
- throw new IndexOutOfRangeException();
- godot_variant* ptrw = NativeFuncs.godotsharp_array_ptrw(ref NativeValue);
- ptrw[index] = Marshaling.mono_object_to_variant(value);
+ throw new ArgumentOutOfRangeException(nameof(index));
+ var self = (godot_array)NativeValue;
+ godot_variant* ptrw = NativeFuncs.godotsharp_array_ptrw(ref self);
+ ptrw[index] = Marshaling.ConvertManagedObjectToVariant(value);
}
}
@@ -163,10 +187,11 @@ namespace Godot.Collections
/// </summary>
/// <param name="value">The object to add.</param>
/// <returns>The new size after adding the object.</returns>
- public unsafe int Add(object value)
+ public int Add(object value)
{
- using godot_variant variantValue = Marshaling.mono_object_to_variant(value);
- return NativeFuncs.godotsharp_array_add(ref NativeValue, &variantValue);
+ using godot_variant variantValue = Marshaling.ConvertManagedObjectToVariant(value);
+ var self = (godot_array)NativeValue;
+ return NativeFuncs.godotsharp_array_add(ref self, variantValue);
}
/// <summary>
@@ -187,10 +212,11 @@ namespace Godot.Collections
/// </summary>
/// <param name="value">The object to search for.</param>
/// <returns>The index of the object, or -1 if not found.</returns>
- public unsafe int IndexOf(object value)
+ public int IndexOf(object value)
{
- using godot_variant variantValue = Marshaling.mono_object_to_variant(value);
- return NativeFuncs.godotsharp_array_index_of(ref NativeValue, &variantValue);
+ using godot_variant variantValue = Marshaling.ConvertManagedObjectToVariant(value);
+ var self = (godot_array)NativeValue;
+ return NativeFuncs.godotsharp_array_index_of(ref self, variantValue);
}
/// <summary>
@@ -201,13 +227,14 @@ namespace Godot.Collections
/// </summary>
/// <param name="index">The index to insert at.</param>
/// <param name="value">The object to insert.</param>
- public unsafe void Insert(int index, object value)
+ public void Insert(int index, object value)
{
if (index < 0 || index > Count)
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
- using godot_variant variantValue = Marshaling.mono_object_to_variant(value);
- NativeFuncs.godotsharp_array_insert(ref NativeValue, index, &variantValue);
+ using godot_variant variantValue = Marshaling.ConvertManagedObjectToVariant(value);
+ var self = (godot_array)NativeValue;
+ NativeFuncs.godotsharp_array_insert(ref self, index, variantValue);
}
/// <summary>
@@ -229,9 +256,10 @@ namespace Godot.Collections
public void RemoveAt(int index)
{
if (index < 0 || index > Count)
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
- NativeFuncs.godotsharp_array_remove_at(ref NativeValue, index);
+ var self = (godot_array)NativeValue;
+ NativeFuncs.godotsharp_array_remove_at(ref self, index);
}
// ICollection
@@ -241,7 +269,7 @@ namespace Godot.Collections
/// This is also known as the size or length of the array.
/// </summary>
/// <returns>The number of elements.</returns>
- public int Count => NativeValue.Size;
+ public int Count => NativeValue.DangerousSelfRef.Size;
object ICollection.SyncRoot => this;
@@ -252,21 +280,21 @@ namespace Godot.Collections
/// untyped C# array, starting at the given index.
/// </summary>
/// <param name="array">The array to copy to.</param>
- /// <param name="destIndex">The index to start at.</param>
- public void CopyTo(System.Array array, int destIndex)
+ /// <param name="index">The index to start at.</param>
+ public void CopyTo(System.Array array, int index)
{
if (array == null)
throw new ArgumentNullException(nameof(array), "Value cannot be null.");
- if (destIndex < 0)
+ if (index < 0)
{
- throw new ArgumentOutOfRangeException(nameof(destIndex),
+ throw new ArgumentOutOfRangeException(nameof(index),
"Number was less than the array's lower bound in the first dimension.");
}
int count = Count;
- if (array.Length < (destIndex + count))
+ if (array.Length < (index + count))
{
throw new ArgumentException(
"Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
@@ -276,9 +304,9 @@ namespace Godot.Collections
{
for (int i = 0; i < count; i++)
{
- object obj = Marshaling.variant_to_mono_object(&(*NativeValue._p)._arrayVector._ptr[i]);
- array.SetValue(obj, destIndex);
- destIndex++;
+ object obj = Marshaling.ConvertVariantToManagedObject(NativeValue.DangerousSelfRef.Elements[i]);
+ array.SetValue(obj, index);
+ index++;
}
}
}
@@ -303,11 +331,12 @@ namespace Godot.Collections
/// Converts this <see cref="Array"/> to a string.
/// </summary>
/// <returns>A string representation of this array.</returns>
- public override unsafe string ToString()
+ public override string ToString()
{
- using godot_string str = default;
- NativeFuncs.godotsharp_array_to_string(ref NativeValue, &str);
- return Marshaling.mono_string_from_godot(str);
+ var self = (godot_array)NativeValue;
+ NativeFuncs.godotsharp_array_to_string(ref self, out godot_string str);
+ using (str)
+ return Marshaling.ConvertStringToManaged(str);
}
/// <summary>
@@ -316,7 +345,7 @@ namespace Godot.Collections
internal void GetVariantBorrowElementAt(int index, out godot_variant elem)
{
if (index < 0 || index >= Count)
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
GetVariantBorrowElementAtUnchecked(index, out elem);
}
@@ -325,7 +354,7 @@ namespace Godot.Collections
/// </summary>
internal unsafe void GetVariantBorrowElementAtUnchecked(int index, out godot_variant elem)
{
- elem = (*NativeValue._p)._arrayVector._ptr[index];
+ elem = NativeValue.DangerousSelfRef.Elements[index];
}
}
@@ -344,11 +373,16 @@ namespace Godot.Collections
/// </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 NativeValue => ref _underlyingArray.NativeValue;
+ 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:
@@ -376,7 +410,7 @@ namespace Godot.Collections
public Array(IEnumerable<T> collection)
{
if (collection == null)
- throw new NullReferenceException($"Parameter '{nameof(collection)} cannot be null.'");
+ throw new ArgumentNullException(nameof(collection));
_underlyingArray = new Array(collection);
}
@@ -389,9 +423,7 @@ namespace Godot.Collections
public Array(params T[] array) : this()
{
if (array == null)
- {
- throw new NullReferenceException($"Parameter '{nameof(array)} cannot be null.'");
- }
+ throw new ArgumentNullException(nameof(array));
_underlyingArray = new Array(array);
}
@@ -415,7 +447,7 @@ namespace Godot.Collections
/// <param name="from">The typed array to convert.</param>
public static explicit operator Array(Array<T> from)
{
- return from._underlyingArray;
+ return from?._underlyingArray;
}
/// <summary>
@@ -454,6 +486,17 @@ namespace Godot.Collections
/// <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);
}
@@ -468,10 +511,7 @@ namespace Godot.Collections
get
{
_underlyingArray.GetVariantBorrowElementAt(index, out godot_variant borrowElem);
- unsafe
- {
- return (T)Marshaling.variant_to_mono_object_of_type(&borrowElem, TypeOfElements);
- }
+ return (T)Marshaling.ConvertVariantToManagedObjectOfType(borrowElem, TypeOfElements);
}
set => _underlyingArray[index] = value;
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
index 437878818c..e1e2df199b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
@@ -167,7 +167,7 @@ namespace Godot
case 2:
return Column2;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(column));
}
}
set
@@ -184,7 +184,7 @@ namespace Godot
Column2 = value;
return;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(column));
}
}
}
@@ -386,7 +386,7 @@ namespace Godot
case 2:
return Row2;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
}
}
@@ -413,7 +413,7 @@ namespace Godot
Row2 = value;
return;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs
index db27989bdb..6bb1ba27e9 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs
@@ -18,22 +18,24 @@ namespace Godot.Bridge
if (godotObject == null)
{
*ret = default;
- (*refCallError).error = godot_variant_call_error_error.GODOT_CALL_ERROR_CALL_ERROR_INSTANCE_IS_NULL;
+ (*refCallError).Error = godot_variant_call_error_error.GODOT_CALL_ERROR_CALL_ERROR_INSTANCE_IS_NULL;
return false.ToGodotBool();
}
- using godot_string dest = default;
- NativeFuncs.godotsharp_string_name_as_string(&dest, method);
- string methodStr = Marshaling.mono_string_from_godot(dest);
+ NativeFuncs.godotsharp_string_name_as_string(out godot_string dest, CustomUnsafe.AsRef(method));
+ string methodStr;
+ using (dest)
+ methodStr = Marshaling.ConvertStringToManaged(dest);
- bool methodInvoked = godotObject.InternalGodotScriptCall(methodStr, args, argCount, out godot_variant retValue);
+ bool methodInvoked = godotObject.InternalGodotScriptCall(methodStr, new NativeVariantPtrArgs(args),
+ argCount, out godot_variant retValue);
if (!methodInvoked)
{
*ret = default;
// This is important, as it tells Object::call that no method was called.
// Otherwise, it would prevent Object::call from calling native methods.
- (*refCallError).error = godot_variant_call_error_error.GODOT_CALL_ERROR_CALL_ERROR_INVALID_METHOD;
+ (*refCallError).Error = godot_variant_call_error_error.GODOT_CALL_ERROR_CALL_ERROR_INVALID_METHOD;
return false.ToGodotBool();
}
@@ -60,12 +62,15 @@ namespace Godot.Bridge
throw new InvalidOperationException();
var nameManaged = StringName.CreateTakingOwnershipOfDisposableValue(
- NativeFuncs.godotsharp_string_name_new_copy(name));
+ NativeFuncs.godotsharp_string_name_new_copy(CustomUnsafe.AsRef(name)));
- if (godotObject.InternalGodotScriptSetFieldOrPropViaReflection(nameManaged.ToString(), value))
+ if (godotObject.InternalGodotScriptSetFieldOrPropViaReflection(
+ nameManaged.ToString(), CustomUnsafe.AsRef(value)))
+ {
return true.ToGodotBool();
+ }
- object valueManaged = Marshaling.variant_to_mono_object(value);
+ object valueManaged = Marshaling.ConvertVariantToManagedObject(CustomUnsafe.AsRef(value));
return godotObject._Set(nameManaged, valueManaged).ToGodotBool();
}
@@ -89,10 +94,10 @@ namespace Godot.Bridge
throw new InvalidOperationException();
var nameManaged = StringName.CreateTakingOwnershipOfDisposableValue(
- NativeFuncs.godotsharp_string_name_new_copy(name));
+ NativeFuncs.godotsharp_string_name_new_copy(CustomUnsafe.AsRef(name)));
if (godotObject.InternalGodotScriptGetFieldOrPropViaReflection(nameManaged.ToString(),
- out godot_variant outRetValue))
+ out godot_variant outRetValue))
{
*outRet = outRetValue;
return true.ToGodotBool();
@@ -106,7 +111,7 @@ namespace Godot.Bridge
return false.ToGodotBool();
}
- *outRet = Marshaling.mono_object_to_variant(ret);
+ *outRet = Marshaling.ConvertManagedObjectToVariant(ret);
return true.ToGodotBool();
}
catch (Exception e)
@@ -158,7 +163,7 @@ namespace Godot.Bridge
return;
}
- *outRes = Marshaling.mono_string_to_godot(resultStr);
+ *outRes = Marshaling.ConvertStringToNative(resultStr);
*outValid = true.ToGodotBool();
}
catch (Exception e)
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs
index 9655887e52..689d6cddbb 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs
@@ -104,8 +104,8 @@ namespace Godot.Bridge
for (int i = 0; i < paramCount; i++)
{
- invokeParams[i] = Marshaling.variant_to_mono_object_of_type(
- args[i], parameters[i].ParameterType);
+ invokeParams[i] = Marshaling.ConvertVariantToManagedObjectOfType(
+ *args[i], parameters[i].ParameterType);
}
ctor.Invoke(obj, invokeParams);
@@ -149,7 +149,7 @@ namespace Godot.Bridge
return;
}
- *outRes = NativeFuncs.godotsharp_string_name_new_copy(nativeName.NativeValue);
+ *outRes = NativeFuncs.godotsharp_string_name_new_copy((godot_string_name)nativeName.NativeValue);
}
catch (Exception e)
{
@@ -177,7 +177,7 @@ namespace Godot.Bridge
{
// Performance is not critical here as this will be replaced with a generated dictionary.
using var stringName = StringName.CreateTakingOwnershipOfDisposableValue(
- NativeFuncs.godotsharp_string_name_new_copy(nativeTypeName));
+ NativeFuncs.godotsharp_string_name_new_copy(CustomUnsafe.AsRef(nativeTypeName)));
string nativeTypeNameStr = stringName.ToString();
if (nativeTypeNameStr[0] == '_')
@@ -277,7 +277,8 @@ namespace Godot.Bridge
*outOwnerIsNull = false.ToGodotBool();
- owner.InternalRaiseEventSignal(eventSignalName, args, argCount);
+ owner.InternalRaiseEventSignal(CustomUnsafe.AsRef(eventSignalName),
+ new NativeVariantPtrArgs(args), argCount);
}
catch (Exception e)
{
@@ -302,9 +303,10 @@ namespace Godot.Bridge
// Legacy signals
foreach (var signalDelegate in top
- .GetNestedTypes(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Public)
- .Where(nestedType => typeof(Delegate).IsAssignableFrom(nestedType))
- .Where(@delegate => @delegate.GetCustomAttributes().OfType<SignalAttribute>().Any()))
+ .GetNestedTypes(BindingFlags.DeclaredOnly | BindingFlags.NonPublic |
+ BindingFlags.Public)
+ .Where(nestedType => typeof(Delegate).IsAssignableFrom(nestedType))
+ .Where(@delegate => @delegate.GetCustomAttributes().OfType<SignalAttribute>().Any()))
{
var invokeMethod = signalDelegate.GetMethod("Invoke");
@@ -315,7 +317,7 @@ namespace Godot.Bridge
foreach (var parameters in invokeMethod.GetParameters())
{
- var paramType = Marshaling.managed_to_variant_type(
+ var paramType = Marshaling.ConvertManagedTypeToVariantType(
parameters.ParameterType, out bool nilIsVariant);
signalParams.Add(new Dictionary()
{
@@ -341,8 +343,8 @@ namespace Godot.Bridge
BindingFlags.NonPublic | BindingFlags.Public);
foreach (var eventSignalField in fields
- .Where(f => typeof(Delegate).IsAssignableFrom(f.FieldType))
- .Where(f => foundEventSignals.Contains(f.Name)))
+ .Where(f => typeof(Delegate).IsAssignableFrom(f.FieldType))
+ .Where(f => foundEventSignals.Contains(f.Name)))
{
var delegateType = eventSignalField.FieldType;
var invokeMethod = delegateType.GetMethod("Invoke");
@@ -354,7 +356,7 @@ namespace Godot.Bridge
foreach (var parameters in invokeMethod.GetParameters())
{
- var paramType = Marshaling.managed_to_variant_type(
+ var paramType = Marshaling.ConvertManagedTypeToVariantType(
parameters.ParameterType, out bool nilIsVariant);
signalParams.Add(new Dictionary()
{
@@ -370,7 +372,7 @@ namespace Godot.Bridge
top = top.BaseType;
}
- *outRetSignals = NativeFuncs.godotsharp_dictionary_new_copy(signals.NativeValue);
+ *outRetSignals = NativeFuncs.godotsharp_dictionary_new_copy((godot_dictionary)signals.NativeValue);
}
catch (Exception e)
{
@@ -387,7 +389,7 @@ namespace Godot.Bridge
// Performance is not critical here as this will be replaced with source generators.
using var signals = new Dictionary();
- string signalNameStr = Marshaling.mono_string_from_godot(*signalName);
+ string signalNameStr = Marshaling.ConvertStringToManaged(*signalName);
Type top = _scriptBridgeMap[scriptPtr];
Type native = Object.InternalGetClassNativeBase(top);
@@ -401,7 +403,7 @@ namespace Godot.Bridge
.Where(nestedType => typeof(Delegate).IsAssignableFrom(nestedType))
.Where(@delegate => @delegate.GetCustomAttributes().OfType<SignalAttribute>().Any())
.Any(signalDelegate => signalDelegate.Name == signalNameStr)
- )
+ )
{
return true.ToGodotBool();
}
@@ -413,7 +415,7 @@ namespace Godot.Bridge
BindingFlags.NonPublic | BindingFlags.Public)
.Where(ev => ev.GetCustomAttributes().OfType<SignalAttribute>().Any())
.Any(eventSignal => eventSignal.Name == signalNameStr)
- )
+ )
{
return true.ToGodotBool();
}
@@ -440,7 +442,7 @@ namespace Godot.Bridge
if (!_scriptBridgeMap.TryGetValue(scriptPtr, out var scriptType))
return false.ToGodotBool();
- string methodStr = Marshaling.mono_string_from_godot(*method);
+ string methodStr = Marshaling.ConvertStringToManaged(*method);
if (deep.ToBool())
{
@@ -517,7 +519,7 @@ namespace Godot.Bridge
{
try
{
- string scriptPathStr = Marshaling.mono_string_from_godot(*scriptPath);
+ string scriptPathStr = Marshaling.ConvertStringToManaged(*scriptPath);
if (!_scriptLookupMap.TryGetValue(scriptPathStr, out var lookupInfo))
return false.ToGodotBool();
@@ -612,7 +614,8 @@ namespace Godot.Bridge
}
*outRpcFunctionsDest =
- NativeFuncs.godotsharp_dictionary_new_copy(((Dictionary)rpcFunctions).NativeValue);
+ NativeFuncs.godotsharp_dictionary_new_copy(
+ (godot_dictionary)((Dictionary)rpcFunctions).NativeValue);
}
catch (Exception e)
{
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
index 2722b64e6d..ef75ff446a 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
@@ -1,5 +1,7 @@
using System;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using Godot.NativeInterop;
namespace Godot
{
@@ -24,7 +26,7 @@ namespace Godot
/// }
/// </code>
/// </example>
- public struct Callable
+ public readonly struct Callable
{
private readonly Object _target;
private readonly StringName _method;
@@ -34,10 +36,12 @@ namespace Godot
/// Object that contains the method.
/// </summary>
public Object Target => _target;
+
/// <summary>
/// Name of the method that will be called.
/// </summary>
public StringName Method => _method;
+
/// <summary>
/// Delegate of the method that will be called.
/// </summary>
@@ -73,15 +77,43 @@ namespace Godot
_delegate = @delegate;
}
+ private const int VarArgsSpanThreshold = 5;
+
/// <summary>
/// Calls the method represented by this <see cref="Callable"/>.
/// 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>
/// <returns>The value returned by the method.</returns>
- public object Call(params object[] args)
+ public unsafe object Call(params object[] args)
{
- return godot_icall_Callable_Call(ref this, args);
+ using godot_callable callable = Marshaling.ConvertCallableToNative(this);
+
+ int argc = args.Length;
+
+ Span<godot_variant.movable> argsStoreSpan = argc <= VarArgsSpanThreshold ?
+ stackalloc godot_variant.movable[VarArgsSpanThreshold].Cleared() :
+ new godot_variant.movable[argc];
+
+ Span<IntPtr> argsSpan = argc <= 10 ?
+ stackalloc IntPtr[argc] :
+ new IntPtr[argc];
+
+ using var variantSpanDisposer = new VariantSpanDisposer(argsStoreSpan);
+
+ fixed (godot_variant* varargs = &MemoryMarshal.GetReference(argsStoreSpan).DangerousSelfRef)
+ fixed (IntPtr* argsPtr = &MemoryMarshal.GetReference(argsSpan))
+ {
+ for (int i = 0; i < argc; i++)
+ {
+ varargs[i] = Marshaling.ConvertManagedObjectToVariant(args[i]);
+ argsPtr[i] = new IntPtr(&varargs[i]);
+ }
+
+ using godot_variant ret = NativeFuncs.godotsharp_callable_call(callable,
+ (godot_variant**)argsPtr, argc, out _);
+ return Marshaling.ConvertVariantToManagedObject(ret);
+ }
}
/// <summary>
@@ -89,9 +121,33 @@ 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 void CallDeferred(params object[] args)
+ public unsafe void CallDeferred(params object[] args)
{
- godot_icall_Callable_CallDeferred(ref this, args);
+ using godot_callable callable = Marshaling.ConvertCallableToNative(this);
+
+ int argc = args.Length;
+
+ Span<godot_variant.movable> argsStoreSpan = argc <= VarArgsSpanThreshold ?
+ stackalloc godot_variant.movable[VarArgsSpanThreshold].Cleared() :
+ new godot_variant.movable[argc];
+
+ Span<IntPtr> argsSpan = argc <= 10 ?
+ stackalloc IntPtr[argc] :
+ new IntPtr[argc];
+
+ using var variantSpanDisposer = new VariantSpanDisposer(argsStoreSpan);
+
+ fixed (godot_variant* varargs = &MemoryMarshal.GetReference(argsStoreSpan).DangerousSelfRef)
+ fixed (IntPtr* argsPtr = &MemoryMarshal.GetReference(argsSpan))
+ {
+ for (int i = 0; i < argc; i++)
+ {
+ varargs[i] = Marshaling.ConvertManagedObjectToVariant(args[i]);
+ argsPtr[i] = new IntPtr(&varargs[i]);
+ }
+
+ NativeFuncs.godotsharp_callable_call_deferred(callable, (godot_variant**)argsPtr, argc);
+ }
}
[MethodImpl(MethodImplOptions.InternalCall)]
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
index a6324504fc..ed0e1efd35 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
@@ -210,7 +210,7 @@ namespace Godot
case 3:
return a;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
}
}
set
@@ -230,7 +230,7 @@ namespace Godot
a = value;
return;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
}
}
}
@@ -841,7 +841,7 @@ namespace Godot
return ParseCol4(str, ofs) * 16 + ParseCol4(str, ofs + 1);
}
- private string ToHex32(float val)
+ private static string ToHex32(float val)
{
byte b = (byte)Mathf.RoundToInt(Mathf.Clamp(val * 255, 0, 255));
return b.HexEncode();
@@ -849,7 +849,7 @@ namespace Godot
internal static bool HtmlIsValid(string color)
{
- if (color.Length == 0)
+ if (string.IsNullOrEmpty(color))
{
return false;
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DebuggingUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DebuggingUtils.cs
index e446b3db1c..39904b6154 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DebuggingUtils.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DebuggingUtils.cs
@@ -18,7 +18,7 @@ namespace Godot
else
sb.Append(type);
- sb.Append(" ");
+ sb.Append(' ');
}
[UnmanagedCallersOnly]
@@ -55,15 +55,15 @@ namespace Godot
if (methodBase is MethodInfo)
sb.AppendTypeName(((MethodInfo)methodBase).ReturnType);
- sb.Append(methodBase.DeclaringType.FullName);
- sb.Append(".");
+ sb.Append(methodBase.DeclaringType?.FullName ?? "<unknown>");
+ sb.Append('.');
sb.Append(methodBase.Name);
if (methodBase.IsGenericMethod)
{
Type[] genericParams = methodBase.GetGenericArguments();
- sb.Append("<");
+ sb.Append('<');
for (int j = 0; j < genericParams.Length; j++)
{
@@ -73,10 +73,10 @@ namespace Godot
sb.AppendTypeName(genericParams[j]);
}
- sb.Append(">");
+ sb.Append('>');
}
- sb.Append("(");
+ sb.Append('(');
bool varArgs = (methodBase.CallingConvention & CallingConventions.VarArgs) != 0;
@@ -93,7 +93,7 @@ namespace Godot
sb.AppendTypeName(parameter[i].ParameterType);
}
- sb.Append(")");
+ sb.Append(')');
methodDecl = sb.ToString();
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs
index 87c93e35f5..02ae392f47 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs
@@ -48,13 +48,13 @@ namespace Godot
for (uint i = 0; i < argc; i++)
{
- managedArgs[i] = Marshaling.variant_to_mono_object_of_type(
- args[i], parameterInfos[i].ParameterType);
+ managedArgs[i] = Marshaling.ConvertVariantToManagedObjectOfType(
+ *args[i], parameterInfos[i].ParameterType);
}
object invokeRet = @delegate.DynamicInvoke(managedArgs);
- *outRet = Marshaling.mono_object_to_variant(invokeRet);
+ *outRet = Marshaling.ConvertManagedObjectToVariant(invokeRet);
}
catch (Exception e)
{
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
index c21d53b4d4..89fc2210b8 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections;
using Godot.NativeInterop;
using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
namespace Godot.Collections
{
@@ -15,14 +16,14 @@ namespace Godot.Collections
IDictionary,
IDisposable
{
- public godot_dictionary NativeValue;
+ internal godot_dictionary.movable NativeValue;
/// <summary>
/// Constructs a new empty <see cref="Dictionary"/>.
/// </summary>
public Dictionary()
{
- NativeValue = NativeFuncs.godotsharp_dictionary_new();
+ NativeValue = (godot_dictionary.movable)NativeFuncs.godotsharp_dictionary_new();
}
/// <summary>
@@ -33,7 +34,7 @@ namespace Godot.Collections
public Dictionary(IDictionary dictionary) : this()
{
if (dictionary == null)
- throw new NullReferenceException($"Parameter '{nameof(dictionary)} cannot be null.'");
+ throw new ArgumentNullException(nameof(dictionary));
foreach (DictionaryEntry entry in dictionary)
Add(entry.Key, entry.Value);
@@ -41,7 +42,9 @@ namespace Godot.Collections
private Dictionary(godot_dictionary nativeValueToOwn)
{
- NativeValue = nativeValueToOwn;
+ NativeValue = (godot_dictionary.movable)(nativeValueToOwn.IsAllocated ?
+ nativeValueToOwn :
+ NativeFuncs.godotsharp_dictionary_new());
}
// Explicit name to make it very clear
@@ -65,7 +68,7 @@ namespace Godot.Collections
public void Dispose(bool disposing)
{
// Always dispose `NativeValue` even if disposing is true
- NativeValue.Dispose();
+ NativeValue.DangerousSelfRef.Dispose();
}
/// <summary>
@@ -76,7 +79,8 @@ namespace Godot.Collections
public Dictionary Duplicate(bool deep = false)
{
godot_dictionary newDictionary;
- NativeFuncs.godotsharp_dictionary_duplicate(ref NativeValue, deep.ToGodotBool(), out newDictionary);
+ var self = (godot_dictionary)NativeValue;
+ NativeFuncs.godotsharp_dictionary_duplicate(ref self, deep.ToGodotBool(), out newDictionary);
return CreateTakingOwnershipOfDisposableValue(newDictionary);
}
@@ -90,7 +94,8 @@ namespace Godot.Collections
get
{
godot_array keysArray;
- NativeFuncs.godotsharp_dictionary_keys(ref NativeValue, out keysArray);
+ var self = (godot_dictionary)NativeValue;
+ NativeFuncs.godotsharp_dictionary_keys(ref self, out keysArray);
return Array.CreateTakingOwnershipOfDisposableValue(keysArray);
}
}
@@ -103,22 +108,25 @@ namespace Godot.Collections
get
{
godot_array valuesArray;
- NativeFuncs.godotsharp_dictionary_values(ref NativeValue, out valuesArray);
+ var self = (godot_dictionary)NativeValue;
+ NativeFuncs.godotsharp_dictionary_values(ref self, out valuesArray);
return Array.CreateTakingOwnershipOfDisposableValue(valuesArray);
}
}
private (Array keys, Array values, int count) GetKeyValuePairs()
{
+ var self = (godot_dictionary)NativeValue;
+
godot_array keysArray;
- NativeFuncs.godotsharp_dictionary_keys(ref NativeValue, out keysArray);
+ NativeFuncs.godotsharp_dictionary_keys(ref self, out keysArray);
var keys = Array.CreateTakingOwnershipOfDisposableValue(keysArray);
godot_array valuesArray;
- NativeFuncs.godotsharp_dictionary_keys(ref NativeValue, out valuesArray);
+ NativeFuncs.godotsharp_dictionary_keys(ref self, out valuesArray);
var values = Array.CreateTakingOwnershipOfDisposableValue(valuesArray);
- int count = NativeFuncs.godotsharp_dictionary_count(ref NativeValue);
+ int count = NativeFuncs.godotsharp_dictionary_count(ref self);
return (keys, values, count);
}
@@ -131,16 +139,17 @@ namespace Godot.Collections
/// Returns the object at the given <paramref name="key"/>.
/// </summary>
/// <value>The object at the given <paramref name="key"/>.</value>
- public unsafe object this[object key]
+ public object this[object key]
{
get
{
- using godot_variant variantKey = Marshaling.mono_object_to_variant(key);
- if (NativeFuncs.godotsharp_dictionary_try_get_value(ref NativeValue, &variantKey,
- out godot_variant value).ToBool())
+ 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())
{
using (value)
- return Marshaling.variant_to_mono_object(&value);
+ return Marshaling.ConvertVariantToManagedObject(value);
}
else
{
@@ -149,9 +158,10 @@ namespace Godot.Collections
}
set
{
- using godot_variant variantKey = Marshaling.mono_object_to_variant(key);
- using godot_variant variantValue = Marshaling.mono_object_to_variant(value);
- NativeFuncs.godotsharp_dictionary_set_value(ref NativeValue, &variantKey, &variantValue);
+ 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);
}
}
@@ -161,31 +171,38 @@ namespace Godot.Collections
/// </summary>
/// <param name="key">The key at which to add the object.</param>
/// <param name="value">The object to add.</param>
- public unsafe void Add(object key, object value)
+ public void Add(object key, object value)
{
- using godot_variant variantKey = Marshaling.mono_object_to_variant(key);
+ using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(key);
+
+ var self = (godot_dictionary)NativeValue;
- if (NativeFuncs.godotsharp_dictionary_contains_key(ref NativeValue, &variantKey).ToBool())
+ 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.mono_object_to_variant(value);
- NativeFuncs.godotsharp_dictionary_add(ref NativeValue, &variantKey, &variantValue);
+ using godot_variant variantValue = Marshaling.ConvertManagedObjectToVariant(value);
+ NativeFuncs.godotsharp_dictionary_add(ref self, variantKey, variantValue);
}
/// <summary>
/// Erases all items from this <see cref="Dictionary"/>.
/// </summary>
- public void Clear() => NativeFuncs.godotsharp_dictionary_clear(ref NativeValue);
+ public void Clear()
+ {
+ var self = (godot_dictionary)NativeValue;
+ NativeFuncs.godotsharp_dictionary_clear(ref self);
+ }
/// <summary>
/// Checks if this <see cref="Dictionary"/> 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 unsafe bool Contains(object key)
+ public bool Contains(object key)
{
- using godot_variant variantKey = Marshaling.mono_object_to_variant(key);
- return NativeFuncs.godotsharp_dictionary_contains_key(ref NativeValue, &variantKey).ToBool();
+ using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(key);
+ var self = (godot_dictionary)NativeValue;
+ return NativeFuncs.godotsharp_dictionary_contains_key(ref self, variantKey).ToBool();
}
/// <summary>
@@ -198,10 +215,11 @@ namespace Godot.Collections
/// Removes an element from this <see cref="Dictionary"/> by key.
/// </summary>
/// <param name="key">The key of the element to remove.</param>
- public unsafe void Remove(object key)
+ public void Remove(object key)
{
- using godot_variant variantKey = Marshaling.mono_object_to_variant(key);
- NativeFuncs.godotsharp_dictionary_remove_key(ref NativeValue, &variantKey);
+ using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(key);
+ var self = (godot_dictionary)NativeValue;
+ NativeFuncs.godotsharp_dictionary_remove_key(ref self, variantKey);
}
// ICollection
@@ -215,7 +233,14 @@ namespace Godot.Collections
/// This is also known as the size or length of the dictionary.
/// </summary>
/// <returns>The number of elements.</returns>
- public int Count => NativeFuncs.godotsharp_dictionary_count(ref NativeValue);
+ public int Count
+ {
+ get
+ {
+ var self = (godot_dictionary)NativeValue;
+ return NativeFuncs.godotsharp_dictionary_count(ref self);
+ }
+ }
/// <summary>
/// Copies the elements of this <see cref="Dictionary"/> to the given
@@ -279,17 +304,19 @@ namespace Godot.Collections
}
}
- private unsafe void UpdateEntry()
+ private void UpdateEntry()
{
_dirty = false;
- NativeFuncs.godotsharp_dictionary_key_value_pair_at(ref _dictionary.NativeValue, _index,
+ 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)
{
- _entry = new DictionaryEntry(Marshaling.variant_to_mono_object(&key),
- Marshaling.variant_to_mono_object(&value));
+ // FIXME: DictionaryEntry keys cannot be null, but Godot dictionaries allow null keys
+ _entry = new DictionaryEntry(Marshaling.ConvertVariantToManagedObject(key)!,
+ Marshaling.ConvertVariantToManagedObject(value));
}
}
@@ -315,11 +342,12 @@ namespace Godot.Collections
/// Converts this <see cref="Dictionary"/> to a string.
/// </summary>
/// <returns>A string representation of this dictionary.</returns>
- public override unsafe string ToString()
+ public override string ToString()
{
- using godot_string str = default;
- NativeFuncs.godotsharp_dictionary_to_string(ref NativeValue, &str);
- return Marshaling.mono_string_from_godot(str);
+ var self = (godot_dictionary)NativeValue;
+ NativeFuncs.godotsharp_dictionary_to_string(ref self, out godot_string str);
+ using (str)
+ return Marshaling.ConvertStringToManaged(str);
}
}
@@ -345,7 +373,11 @@ namespace Godot.Collections
{
private readonly Dictionary _underlyingDict;
- internal ref godot_dictionary NativeValue => ref _underlyingDict.NativeValue;
+ 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:
@@ -375,10 +407,10 @@ namespace Godot.Collections
/// <returns>A new Godot Dictionary.</returns>
public Dictionary(IDictionary<TKey, TValue> dictionary)
{
- _underlyingDict = new Dictionary();
-
if (dictionary == null)
- throw new NullReferenceException($"Parameter '{nameof(dictionary)} cannot be null.'");
+ throw new ArgumentNullException(nameof(dictionary));
+
+ _underlyingDict = new Dictionary();
foreach (KeyValuePair<TKey, TValue> entry in dictionary)
Add(entry.Key, entry.Value);
@@ -405,7 +437,7 @@ namespace Godot.Collections
/// <param name="from">The typed dictionary to convert.</param>
public static explicit operator Dictionary(Dictionary<TKey, TValue> from)
{
- return from._underlyingDict;
+ return from?._underlyingDict;
}
/// <summary>
@@ -428,19 +460,17 @@ namespace Godot.Collections
{
get
{
- unsafe
+ 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 godot_variant variantKey = Marshaling.mono_object_to_variant(key);
- if (NativeFuncs.godotsharp_dictionary_try_get_value(ref _underlyingDict.NativeValue,
- &variantKey, out godot_variant value).ToBool())
- {
- using (value)
- return (TValue)Marshaling.variant_to_mono_object_of_type(&value, TypeOfValues);
- }
- else
- {
- throw new KeyNotFoundException();
- }
+ using (value)
+ return (TValue)Marshaling.ConvertVariantToManagedObjectOfType(value, TypeOfValues);
+ }
+ else
+ {
+ throw new KeyNotFoundException();
}
}
set => _underlyingDict[key] = value;
@@ -454,7 +484,8 @@ namespace Godot.Collections
get
{
godot_array keyArray;
- NativeFuncs.godotsharp_dictionary_keys(ref _underlyingDict.NativeValue, out keyArray);
+ var self = (godot_dictionary)_underlyingDict.NativeValue;
+ NativeFuncs.godotsharp_dictionary_keys(ref self, out keyArray);
return Array<TKey>.CreateTakingOwnershipOfDisposableValue(keyArray);
}
}
@@ -467,21 +498,23 @@ namespace Godot.Collections
get
{
godot_array valuesArray;
- NativeFuncs.godotsharp_dictionary_values(ref _underlyingDict.NativeValue, out valuesArray);
+ var self = (godot_dictionary)_underlyingDict.NativeValue;
+ NativeFuncs.godotsharp_dictionary_values(ref self, out valuesArray);
return Array<TValue>.CreateTakingOwnershipOfDisposableValue(valuesArray);
}
}
- private unsafe KeyValuePair<TKey, TValue> GetKeyValuePair(int index)
+ private KeyValuePair<TKey, TValue> GetKeyValuePair(int index)
{
- NativeFuncs.godotsharp_dictionary_key_value_pair_at(ref _underlyingDict.NativeValue, 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.variant_to_mono_object(&key),
- (TValue)Marshaling.variant_to_mono_object(&value));
+ return new KeyValuePair<TKey, TValue>((TKey)Marshaling.ConvertVariantToManagedObject(key),
+ (TValue)Marshaling.ConvertVariantToManagedObject(value));
}
}
@@ -510,10 +543,11 @@ namespace Godot.Collections
/// 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 unsafe bool Remove(TKey key)
+ public bool Remove(TKey key)
{
- using godot_variant variantKey = Marshaling.mono_object_to_variant(key);
- return NativeFuncs.godotsharp_dictionary_remove_key(ref _underlyingDict.NativeValue, &variantKey).ToBool();
+ using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(key);
+ var self = (godot_dictionary)_underlyingDict.NativeValue;
+ return NativeFuncs.godotsharp_dictionary_remove_key(ref self, variantKey).ToBool();
}
/// <summary>
@@ -522,16 +556,17 @@ namespace Godot.Collections
/// <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 unsafe bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
+ public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
{
- using godot_variant variantKey = Marshaling.mono_object_to_variant(key);
- bool found = NativeFuncs.godotsharp_dictionary_try_get_value(ref _underlyingDict.NativeValue,
- &variantKey, out godot_variant retValue).ToBool();
+ 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.variant_to_mono_object_of_type(&retValue, TypeOfValues) :
+ (TValue)Marshaling.ConvertVariantToManagedObjectOfType(retValue, TypeOfValues) :
default;
}
@@ -562,19 +597,20 @@ namespace Godot.Collections
_underlyingDict.Clear();
}
- unsafe bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
+ bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
{
- using godot_variant variantKey = Marshaling.mono_object_to_variant(item.Key);
- bool found = NativeFuncs.godotsharp_dictionary_try_get_value(ref _underlyingDict.NativeValue,
- &variantKey, out godot_variant retValue).ToBool();
+ using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(item.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)
{
if (!found)
return false;
- using godot_variant variantValue = Marshaling.mono_object_to_variant(item.Value);
- return NativeFuncs.godotsharp_variant_equals(&variantValue, &retValue).ToBool();
+ using godot_variant variantValue = Marshaling.ConvertManagedObjectToVariant(item.Value);
+ return NativeFuncs.godotsharp_variant_equals(variantValue, retValue).ToBool();
}
}
@@ -606,22 +642,23 @@ namespace Godot.Collections
}
}
- unsafe bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
+ bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
{
- using godot_variant variantKey = Marshaling.mono_object_to_variant(item.Key);
- bool found = NativeFuncs.godotsharp_dictionary_try_get_value(ref _underlyingDict.NativeValue,
- &variantKey, out godot_variant retValue).ToBool();
+ using godot_variant variantKey = Marshaling.ConvertManagedObjectToVariant(item.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)
{
if (!found)
return false;
- using godot_variant variantValue = Marshaling.mono_object_to_variant(item.Value);
- if (NativeFuncs.godotsharp_variant_equals(&variantValue, &retValue).ToBool())
+ using godot_variant variantValue = Marshaling.ConvertManagedObjectToVariant(item.Value);
+ if (NativeFuncs.godotsharp_variant_equals(variantValue, retValue).ToBool())
{
return NativeFuncs.godotsharp_dictionary_remove_key(
- ref _underlyingDict.NativeValue, &variantKey).ToBool();
+ ref self, variantKey).ToBool();
}
return false;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs
index 340780bb45..4094ceeb22 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs
@@ -35,17 +35,14 @@ namespace Godot
if (!IsInstanceValid(obj))
return null;
- using godot_ref weakRef = default;
-
- unsafe
+ NativeFuncs.godotsharp_weakref(GetPtr(obj), out godot_ref weakRef);
+ using (weakRef)
{
- NativeFuncs.godotsharp_weakref(GetPtr(obj), &weakRef);
- }
+ if (weakRef.IsNull)
+ return null;
- if (weakRef.IsNull)
- return null;
-
- return (WeakRef)InteropUtils.UnmanagedGetManaged(weakRef._reference);
+ return (WeakRef)InteropUtils.UnmanagedGetManaged(weakRef.Reference);
+ }
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/SceneTreeExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/SceneTreeExtensions.cs
index 17bca19fab..fa8a1c6402 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/SceneTreeExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/SceneTreeExtensions.cs
@@ -1,5 +1,4 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using Godot.Collections;
using Godot.NativeInterop;
@@ -11,7 +10,7 @@ namespace Godot
/// 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 unsafe Array<T> GetNodesInGroup<T>(StringName group) where T : class
+ public Array<T> GetNodesInGroup<T>(StringName group) where T : class
{
var array = GetNodesInGroup(group);
@@ -29,19 +28,18 @@ namespace Godot
BindingFlags.Public | BindingFlags.NonPublic);
var nativeName = (StringName)field!.GetValue(null);
- godot_string_name nativeNameAux = nativeName.NativeValue;
- godot_array inputAux = array.NativeValue;
- godot_array filteredArray;
- NativeFuncs.godotsharp_array_filter_godot_objects_by_native(
- &nativeNameAux, &inputAux, &filteredArray);
+ 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
- godot_array inputAux = array.NativeValue;
- godot_array filteredArray;
- NativeFuncs.godotsharp_array_filter_godot_objects_by_non_native(&inputAux, &filteredArray);
+ 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);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
index 39271d3daf..02ae32f46e 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
@@ -26,12 +26,12 @@ 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 unsafe object Bytes2Var(byte[] bytes, bool allowObjects = false)
+ public static object Bytes2Var(byte[] bytes, bool allowObjects = false)
{
- using var varBytes = Marshaling.mono_array_to_PackedByteArray(bytes);
- using godot_variant ret = default;
- NativeFuncs.godotsharp_bytes2var(&varBytes, allowObjects.ToGodotBool(), &ret);
- return Marshaling.variant_to_mono_object(&ret);
+ using var varBytes = Marshaling.ConvertSystemArrayToNativePackedByteArray(bytes);
+ NativeFuncs.godotsharp_bytes2var(varBytes, allowObjects.ToGodotBool(), out godot_variant ret);
+ using (ret)
+ return Marshaling.ConvertVariantToManagedObject(ret);
}
/// <summary>
@@ -49,12 +49,12 @@ namespace Godot
/// </code>
/// </example>
/// <returns>The <c>Variant</c> converted to the given <paramref name="type"/>.</returns>
- public static unsafe object Convert(object what, Variant.Type type)
+ public static object Convert(object what, Variant.Type type)
{
- using var whatVariant = Marshaling.mono_object_to_variant(what);
- using godot_variant ret = default;
- NativeFuncs.godotsharp_convert(&whatVariant, (int)type, &ret);
- return Marshaling.variant_to_mono_object(&ret);
+ using var whatVariant = Marshaling.ConvertManagedObjectToVariant(what);
+ NativeFuncs.godotsharp_convert(whatVariant, (int)type, out godot_variant ret);
+ using (ret)
+ return Marshaling.ConvertVariantToManagedObject(ret);
}
/// <summary>
@@ -88,10 +88,10 @@ namespace Godot
/// </example>
/// <param name="var">Variable that will be hashed.</param>
/// <returns>Hash of the variable passed.</returns>
- public static unsafe int Hash(object var)
+ public static int Hash(object var)
{
- using var variant = Marshaling.mono_object_to_variant(var);
- return NativeFuncs.godotsharp_hash(&variant);
+ using var variant = Marshaling.ConvertManagedObjectToVariant(var);
+ return NativeFuncs.godotsharp_hash(variant);
}
/// <summary>
@@ -207,10 +207,10 @@ namespace Godot
/// </code>
/// </example>
/// <param name="message">Error message.</param>
- public static unsafe void PushError(string message)
+ public static void PushError(string message)
{
- using var godotStr = Marshaling.mono_string_to_godot(message);
- NativeFuncs.godotsharp_pusherror(&godotStr);
+ using var godotStr = Marshaling.ConvertStringToNative(message);
+ NativeFuncs.godotsharp_pusherror(godotStr);
}
/// <summary>
@@ -220,10 +220,10 @@ namespace Godot
/// GD.PushWarning("test warning"); // Prints "test warning" to debugger and terminal as warning call
/// </example>
/// <param name="message">Warning message.</param>
- public static unsafe void PushWarning(string message)
+ public static void PushWarning(string message)
{
- using var godotStr = Marshaling.mono_string_to_godot(message);
- NativeFuncs.godotsharp_pushwarning(&godotStr);
+ using var godotStr = Marshaling.ConvertStringToNative(message);
+ NativeFuncs.godotsharp_pushwarning(godotStr);
}
/// <summary>
@@ -242,11 +242,11 @@ namespace Godot
/// </code>
/// </example>
/// <param name="what">Arguments that will be printed.</param>
- public static unsafe void Print(params object[] what)
+ public static void Print(params object[] what)
{
string str = string.Concat(GetPrintParams(what));
- using var godotStr = Marshaling.mono_string_to_godot(str);
- NativeFuncs.godotsharp_print(&godotStr);
+ using var godotStr = Marshaling.ConvertStringToNative(str);
+ NativeFuncs.godotsharp_print(godotStr);
}
/// <summary>
@@ -273,11 +273,11 @@ namespace Godot
/// </code>
/// </example>
/// <param name="what">Arguments that will be printed.</param>
- public static unsafe void PrintRich(params object[] what)
+ public static void PrintRich(params object[] what)
{
string str = string.Concat(GetPrintParams(what));
- using var godotStr = Marshaling.mono_string_to_godot(str);
- NativeFuncs.godotsharp_print_rich(&godotStr);
+ using var godotStr = Marshaling.ConvertStringToNative(str);
+ NativeFuncs.godotsharp_print_rich(godotStr);
}
/// <summary>
@@ -297,11 +297,11 @@ namespace Godot
/// </code>
/// </example>
/// <param name="what">Arguments that will be printed.</param>
- public static unsafe void PrintErr(params object[] what)
+ public static void PrintErr(params object[] what)
{
string str = string.Concat(GetPrintParams(what));
- using var godotStr = Marshaling.mono_string_to_godot(str);
- NativeFuncs.godotsharp_printerr(&godotStr);
+ using var godotStr = Marshaling.ConvertStringToNative(str);
+ NativeFuncs.godotsharp_printerr(godotStr);
}
/// <summary>
@@ -319,11 +319,11 @@ namespace Godot
/// </code>
/// </example>
/// <param name="what">Arguments that will be printed.</param>
- public static unsafe void PrintRaw(params object[] what)
+ public static void PrintRaw(params object[] what)
{
string str = string.Concat(GetPrintParams(what));
- using var godotStr = Marshaling.mono_string_to_godot(str);
- NativeFuncs.godotsharp_printraw(&godotStr);
+ using var godotStr = Marshaling.ConvertStringToNative(str);
+ NativeFuncs.godotsharp_printraw(godotStr);
}
/// <summary>
@@ -335,11 +335,11 @@ namespace Godot
/// </code>
/// </example>
/// <param name="what">Arguments that will be printed.</param>
- public static unsafe void PrintS(params object[] what)
+ public static void PrintS(params object[] what)
{
string str = string.Join(' ', GetPrintParams(what));
- using var godotStr = Marshaling.mono_string_to_godot(str);
- NativeFuncs.godotsharp_prints(&godotStr);
+ using var godotStr = Marshaling.ConvertStringToNative(str);
+ NativeFuncs.godotsharp_prints(godotStr);
}
/// <summary>
@@ -351,11 +351,11 @@ namespace Godot
/// </code>
/// </example>
/// <param name="what">Arguments that will be printed.</param>
- public static unsafe void PrintT(params object[] what)
+ public static void PrintT(params object[] what)
{
string str = string.Join('\t', GetPrintParams(what));
- using var godotStr = Marshaling.mono_string_to_godot(str);
- NativeFuncs.godotsharp_printt(&godotStr);
+ using var godotStr = Marshaling.ConvertStringToNative(str);
+ NativeFuncs.godotsharp_printt(godotStr);
}
/// <summary>
@@ -520,12 +520,12 @@ namespace Godot
/// </summary>
/// <param name="what">Arguments that will converted to string.</param>
/// <returns>The string formed by the given arguments.</returns>
- public static unsafe string Str(params object[] what)
+ public static string Str(params object[] what)
{
- using var whatGodotArray = Marshaling.mono_array_to_Array(what);
- using godot_string ret = default;
- NativeFuncs.godotsharp_str(&whatGodotArray, &ret);
- return Marshaling.mono_string_from_godot(ret);
+ using var whatGodotArray = Marshaling.ConvertSystemArrayToNativeGodotArray(what);
+ NativeFuncs.godotsharp_str(whatGodotArray, out godot_string ret);
+ using (ret)
+ return Marshaling.ConvertStringToManaged(ret);
}
/// <summary>
@@ -540,12 +540,12 @@ namespace Godot
/// </example>
/// <param name="str">String that will be converted to Variant.</param>
/// <returns>The decoded <c>Variant</c>.</returns>
- public static unsafe object Str2Var(string str)
+ public static object Str2Var(string str)
{
- using var godotStr = Marshaling.mono_string_to_godot(str);
- using godot_variant ret = default;
- NativeFuncs.godotsharp_str2var(&godotStr, &ret);
- return Marshaling.variant_to_mono_object(&ret);
+ using var godotStr = Marshaling.ConvertStringToNative(str);
+ NativeFuncs.godotsharp_str2var(godotStr, out godot_variant ret);
+ using (ret)
+ return Marshaling.ConvertVariantToManagedObject(ret);
}
/// <summary>
@@ -557,13 +557,12 @@ namespace Godot
/// <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 unsafe byte[] Var2Bytes(object var, bool fullObjects = false)
+ public static byte[] Var2Bytes(object var, bool fullObjects = false)
{
- using var variant = Marshaling.mono_object_to_variant(var);
- using godot_packed_byte_array varBytes = default;
- NativeFuncs.godotsharp_var2bytes(&variant, fullObjects.ToGodotBool(), &varBytes);
+ using var variant = Marshaling.ConvertManagedObjectToVariant(var);
+ NativeFuncs.godotsharp_var2bytes(variant, fullObjects.ToGodotBool(), out var varBytes);
using (varBytes)
- return Marshaling.PackedByteArray_to_mono_array(&varBytes);
+ return Marshaling.ConvertNativePackedByteArrayToSystemArray(varBytes);
}
/// <summary>
@@ -583,12 +582,12 @@ 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 unsafe string Var2Str(object var)
+ public static string Var2Str(object var)
{
- using var variant = Marshaling.mono_object_to_variant(var);
- using godot_string ret = default;
- NativeFuncs.godotsharp_var2str(&variant, &ret);
- return Marshaling.mono_string_from_godot(ret);
+ using var variant = Marshaling.ConvertManagedObjectToVariant(var);
+ NativeFuncs.godotsharp_var2str(variant, out godot_string ret);
+ using (ret)
+ return Marshaling.ConvertStringToManaged(ret);
}
/// <summary>
@@ -597,7 +596,7 @@ namespace Godot
/// <returns>The <see cref="Variant.Type"/> for the given <paramref name="type"/>.</returns>
public static Variant.Type TypeToVariantType(Type type)
{
- return Marshaling.managed_to_variant_type(type, out bool _);
+ return Marshaling.ConvertManagedTypeToVariantType(type, out bool _);
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropStructs.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropStructs.cs
index 0942d8f722..ef20819d62 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropStructs.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropStructs.cs
@@ -10,7 +10,10 @@ using System.Runtime.InteropServices;
namespace Godot.NativeInterop
{
- internal static class GodotBoolExtensions
+ // NOTES:
+ // ref structs cannot implement interfaces, but they still work in `using` directives if they declare Dispose()
+
+ public static class GodotBoolExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe godot_bool ToGodotBool(this bool @bool)
@@ -35,9 +38,9 @@ namespace Godot.NativeInterop
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_ref : IDisposable
+ public ref struct godot_ref
{
- internal IntPtr _reference;
+ private IntPtr _reference;
public void Dispose()
{
@@ -47,7 +50,17 @@ namespace Godot.NativeInterop
_reference = IntPtr.Zero;
}
- public bool IsNull => _reference == IntPtr.Zero;
+ public readonly IntPtr Reference
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _reference;
+ }
+
+ public readonly bool IsNull
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _reference == IntPtr.Zero;
+ }
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
@@ -63,41 +76,53 @@ namespace Godot.NativeInterop
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_variant_call_error
+ public ref struct godot_variant_call_error
{
- public godot_variant_call_error_error error;
- public int argument;
- public int expected;
+ private godot_variant_call_error_error error;
+ private int argument;
+ private int expected;
+
+ public godot_variant_call_error_error Error
+ {
+ readonly get => error;
+ set => error = value;
+ }
+
+ public int Argument
+ {
+ readonly get => argument;
+ set => argument = value;
+ }
+
+ public Godot.Variant.Type Expected
+ {
+ readonly get => (Godot.Variant.Type)expected;
+ set => expected = (int)value;
+ }
}
[StructLayout(LayoutKind.Explicit)]
// ReSharper disable once InconsistentNaming
- public struct godot_variant : IDisposable
+ public ref struct godot_variant
{
// Variant.Type is generated as an enum of type long, so we can't use for the field as it must only take 32-bits.
[FieldOffset(0)] private int _typeField;
// There's padding here
- [FieldOffset(8)] internal godot_variant_data _data;
-
- public Variant.Type _type
- {
- get => (Variant.Type)_typeField;
- set => _typeField = (int)value;
- }
+ [FieldOffset(8)] private godot_variant_data _data;
[StructLayout(LayoutKind.Explicit)]
// ReSharper disable once InconsistentNaming
- internal unsafe struct godot_variant_data
+ private unsafe ref struct godot_variant_data
{
[FieldOffset(0)] public godot_bool _bool;
[FieldOffset(0)] public long _int;
[FieldOffset(0)] public double _float;
- [FieldOffset(0)] public Transform2D* _transform2d;
+ [FieldOffset(0)] public Transform2D* _transform2D;
[FieldOffset(0)] public AABB* _aabb;
[FieldOffset(0)] public Basis* _basis;
- [FieldOffset(0)] public Transform3D* _transform3d;
+ [FieldOffset(0)] public Transform3D* _transform3D;
[FieldOffset(0)] public Vector4* _vector4;
[FieldOffset(0)] public Vector4i* _vector4i;
[FieldOffset(0)] public Projection* _projection;
@@ -125,7 +150,7 @@ namespace Godot.NativeInterop
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- internal struct godot_variant_obj_data
+ public struct godot_variant_obj_data
{
public UInt64 id;
public IntPtr obj;
@@ -133,7 +158,7 @@ namespace Godot.NativeInterop
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- private struct godot_variant_data_mem
+ public struct godot_variant_data_mem
{
#pragma warning disable 169
private real_t _mem0;
@@ -144,9 +169,225 @@ namespace Godot.NativeInterop
}
}
+ public Variant.Type Type
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => (Variant.Type)_typeField;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _typeField = (int)value;
+ }
+
+ public godot_bool Bool
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._bool;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._bool = value;
+ }
+
+ public long Int
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._int;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._int = value;
+ }
+
+ public double Float
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._float;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._float = value;
+ }
+
+ public readonly unsafe Transform2D* Transform2D
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _data._transform2D;
+ }
+
+ public readonly unsafe AABB* AABB
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _data._aabb;
+ }
+
+ public readonly unsafe Basis* Basis
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _data._basis;
+ }
+
+ public readonly unsafe Transform3D* Transform3D
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _data._transform3D;
+ }
+
+ public readonly unsafe Vector4* Vector4
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _data._vector4;
+ }
+
+ public readonly unsafe Vector4i* Vector4i
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _data._vector4i;
+ }
+
+ public readonly unsafe Projection* Projection
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _data._projection;
+ }
+
+ public godot_string_name StringName
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_string_name;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_string_name = value;
+ }
+
+ public godot_string String
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_string;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_string = value;
+ }
+
+ public Vector3 Vector3
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_vector3;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_vector3 = value;
+ }
+
+ public Vector3i Vector3i
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_vector3i;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_vector3i = value;
+ }
+
+ public Vector2 Vector2
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_vector2;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_vector2 = value;
+ }
+
+ public Vector2i Vector2i
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_vector2i;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_vector2i = value;
+ }
+
+ public Rect2 Rect2
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_rect2;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_rect2 = value;
+ }
+
+ public Rect2i Rect2i
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_rect2i;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_rect2i = value;
+ }
+
+ public Plane Plane
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_plane;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_plane = value;
+ }
+
+ public Quaternion Quaternion
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_quaternion;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_quaternion = value;
+ }
+
+ public Color Color
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_color;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_color = value;
+ }
+
+ public godot_node_path NodePath
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_node_path;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_node_path = value;
+ }
+
+ public RID RID
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_rid;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_rid = value;
+ }
+
+ public godot_callable Callable
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_callable;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_callable = value;
+ }
+
+ public godot_signal Signal
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_signal;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_signal = value;
+ }
+
+ public godot_dictionary Dictionary
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_dictionary;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_dictionary = value;
+ }
+
+ public godot_array Array
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ readonly get => _data._m_array;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set => _data._m_array = value;
+ }
+
+ public readonly IntPtr Object
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _data._m_obj_data.obj;
+ }
+
public void Dispose()
{
- switch (_type)
+ switch (Type)
{
case Variant.Type.Nil:
case Variant.Type.Bool:
@@ -166,15 +407,36 @@ namespace Godot.NativeInterop
}
NativeFuncs.godotsharp_variant_destroy(ref this);
- _type = Variant.Type.Nil;
+ Type = Variant.Type.Nil;
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ // ReSharper disable once InconsistentNaming
+ internal struct movable
+ {
+ // Variant.Type is generated as an enum of type long, so we can't use for the field as it must only take 32-bits.
+ [FieldOffset(0)] private int _typeField;
+
+ // There's padding here
+
+ [FieldOffset(8)] private godot_variant_data.godot_variant_data_mem _data;
+
+ public static unsafe explicit operator movable(in godot_variant value)
+ => *(movable*)CustomUnsafe.AsPointer(ref CustomUnsafe.AsRef(value));
+
+ public static unsafe explicit operator godot_variant(movable value)
+ => *(godot_variant*)Unsafe.AsPointer(ref value);
+
+ public unsafe ref godot_variant DangerousSelfRef =>
+ ref CustomUnsafe.AsRef((godot_variant*)Unsafe.AsPointer(ref this));
}
}
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_string : IDisposable
+ public ref struct godot_string
{
- internal IntPtr _ptr;
+ private IntPtr _ptr;
public void Dispose()
{
@@ -184,15 +446,25 @@ namespace Godot.NativeInterop
_ptr = IntPtr.Zero;
}
+ public readonly IntPtr Buffer
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr;
+ }
+
// Size including the null termination character
- public unsafe int Size => _ptr != IntPtr.Zero ? *((int*)_ptr - 1) : 0;
+ public readonly unsafe int Size
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr != IntPtr.Zero ? *((int*)_ptr - 1) : 0;
+ }
}
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_string_name : IDisposable
+ public ref struct godot_string_name
{
- internal IntPtr _data;
+ private IntPtr _data;
public void Dispose()
{
@@ -202,18 +474,41 @@ namespace Godot.NativeInterop
_data = IntPtr.Zero;
}
- // An static method because an instance method could result in a hidden copy if called on an `in` parameter.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool IsEmpty(in godot_string_name name) =>
+ public readonly bool IsAllocated
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _data != IntPtr.Zero;
+ }
+
+ public readonly bool IsEmpty
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
// This is all that's needed to check if it's empty. Equivalent to `== StringName()` in C++.
- name._data == IntPtr.Zero;
+ get => _data == IntPtr.Zero;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ // ReSharper disable once InconsistentNaming
+ internal struct movable
+ {
+ private IntPtr _data;
+
+ public static unsafe explicit operator movable(in godot_string_name value)
+ => *(movable*)CustomUnsafe.AsPointer(ref CustomUnsafe.AsRef(value));
+
+ public static unsafe explicit operator godot_string_name(movable value)
+ => *(godot_string_name*)Unsafe.AsPointer(ref value);
+
+ public unsafe ref godot_string_name DangerousSelfRef =>
+ ref CustomUnsafe.AsRef((godot_string_name*)Unsafe.AsPointer(ref this));
+ }
}
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_node_path : IDisposable
+ public ref struct godot_node_path
{
- internal IntPtr _data;
+ private IntPtr _data;
public void Dispose()
{
@@ -223,49 +518,98 @@ namespace Godot.NativeInterop
_data = IntPtr.Zero;
}
- // An static method because an instance method could result in a hidden copy if called on an `in` parameter.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool IsEmpty(in godot_node_path nodePath) =>
+ public readonly bool IsAllocated
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _data != IntPtr.Zero;
+ }
+
+ public readonly bool IsEmpty
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
// This is all that's needed to check if it's empty. It's what the `is_empty()` C++ method does.
- nodePath._data == IntPtr.Zero;
+ get => _data == IntPtr.Zero;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ // ReSharper disable once InconsistentNaming
+ internal struct movable
+ {
+ private IntPtr _data;
+
+ public static unsafe explicit operator movable(in godot_node_path value)
+ => *(movable*)CustomUnsafe.AsPointer(ref CustomUnsafe.AsRef(value));
+
+ public static unsafe explicit operator godot_node_path(movable value)
+ => *(godot_node_path*)Unsafe.AsPointer(ref value);
+
+ public unsafe ref godot_node_path DangerousSelfRef =>
+ ref CustomUnsafe.AsRef((godot_node_path*)Unsafe.AsPointer(ref this));
+ }
}
[StructLayout(LayoutKind.Explicit)]
// ReSharper disable once InconsistentNaming
- public struct godot_signal : IDisposable
+ public ref struct godot_signal
{
- [FieldOffset(0)] public godot_string_name _name;
+ [FieldOffset(0)] private godot_string_name _name;
// There's padding here on 32-bit
- [FieldOffset(8)] public UInt64 _objectId;
+ [FieldOffset(8)] private UInt64 _objectId;
+
+ public godot_signal(godot_string_name name, ulong objectId)
+ {
+ _name = name;
+ _objectId = objectId;
+ }
+
+ public godot_string_name Name
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _name;
+ }
+
+ public UInt64 ObjectId
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _objectId;
+ }
public void Dispose()
{
- if (_name._data == IntPtr.Zero)
+ if (!_name.IsAllocated)
return;
NativeFuncs.godotsharp_signal_destroy(ref this);
- _name._data = IntPtr.Zero;
+ _name = default;
}
}
[StructLayout(LayoutKind.Explicit)]
// ReSharper disable once InconsistentNaming
- public struct godot_callable : IDisposable
+ public ref struct godot_callable
{
- [FieldOffset(0)] public godot_string_name _method;
+ [FieldOffset(0)] private godot_string_name _method;
// There's padding here on 32-bit
- [FieldOffset(8)] public UInt64 _objectId;
- [FieldOffset(8)] public IntPtr _custom;
+ // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
+ [FieldOffset(8)] private UInt64 _objectId;
+ [FieldOffset(8)] private IntPtr _custom;
+
+ public godot_callable(godot_string_name method, ulong objectId) : this()
+ {
+ _method = method;
+ _objectId = objectId;
+ }
public void Dispose()
{
- if (_method._data == IntPtr.Zero && _custom == IntPtr.Zero)
+ // _custom needs freeing as well
+ if (!_method.IsAllocated && _custom == IntPtr.Zero)
return;
NativeFuncs.godotsharp_callable_destroy(ref this);
- _method._data = IntPtr.Zero;
+ _method = default;
_custom = IntPtr.Zero;
}
}
@@ -275,29 +619,55 @@ namespace Godot.NativeInterop
// be re-assigned a new value (the copy constructor checks if `_p` is null so that's fine).
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_array : IDisposable
+ public ref struct godot_array
{
- internal unsafe ArrayPrivate* _p;
+ private unsafe ArrayPrivate* _p;
[StructLayout(LayoutKind.Sequential)]
- internal struct ArrayPrivate
+ private struct ArrayPrivate
{
private uint _safeRefCount;
- internal VariantVector _arrayVector;
- // There's more here, but we don't care as we never store this in C#
+ public VariantVector _arrayVector;
+ // There are more fields here, but we don't care as we never store this in C#
+
+ public readonly int Size
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _arrayVector.Size;
+ }
}
[StructLayout(LayoutKind.Sequential)]
- internal struct VariantVector
+ private struct VariantVector
{
- internal IntPtr _writeProxy;
- internal unsafe godot_variant* _ptr;
+ private IntPtr _writeProxy;
+ public unsafe godot_variant* _ptr;
- public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
+ public readonly unsafe int Size
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr != null ? *((int*)_ptr - 1) : 0;
+ }
+ }
+
+ public readonly unsafe godot_variant* Elements
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _p->_arrayVector._ptr;
}
- public unsafe int Size => _p != null ? _p->_arrayVector.Size : 0;
+ public readonly unsafe bool IsAllocated
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _p != null;
+ }
+
+ public readonly unsafe int Size
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _p != null ? _p->Size : 0;
+ }
public unsafe void Dispose()
{
@@ -306,6 +676,22 @@ namespace Godot.NativeInterop
NativeFuncs.godotsharp_array_destroy(ref this);
_p = null;
}
+
+ [StructLayout(LayoutKind.Sequential)]
+ // ReSharper disable once InconsistentNaming
+ internal struct movable
+ {
+ private unsafe ArrayPrivate* _p;
+
+ public static unsafe explicit operator movable(in godot_array value)
+ => *(movable*)CustomUnsafe.AsPointer(ref CustomUnsafe.AsRef(value));
+
+ public static unsafe explicit operator godot_array(movable value)
+ => *(godot_array*)Unsafe.AsPointer(ref value);
+
+ public unsafe ref godot_array DangerousSelfRef =>
+ ref CustomUnsafe.AsRef((godot_array*)Unsafe.AsPointer(ref this));
+ }
}
// IMPORTANT:
@@ -314,9 +700,15 @@ namespace Godot.NativeInterop
// be re-assigned a new value (the copy constructor checks if `_p` is null so that's fine).
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_dictionary : IDisposable
+ public ref struct godot_dictionary
{
- internal IntPtr _p;
+ private IntPtr _p;
+
+ public readonly bool IsAllocated
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _p != IntPtr.Zero;
+ }
public void Dispose()
{
@@ -325,14 +717,30 @@ namespace Godot.NativeInterop
NativeFuncs.godotsharp_dictionary_destroy(ref this);
_p = IntPtr.Zero;
}
+
+ [StructLayout(LayoutKind.Sequential)]
+ // ReSharper disable once InconsistentNaming
+ internal struct movable
+ {
+ private IntPtr _p;
+
+ public static unsafe explicit operator movable(in godot_dictionary value)
+ => *(movable*)CustomUnsafe.AsPointer(ref CustomUnsafe.AsRef(value));
+
+ public static unsafe explicit operator godot_dictionary(movable value)
+ => *(godot_dictionary*)Unsafe.AsPointer(ref value);
+
+ public unsafe ref godot_dictionary DangerousSelfRef =>
+ ref CustomUnsafe.AsRef((godot_dictionary*)Unsafe.AsPointer(ref this));
+ }
}
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_packed_byte_array : IDisposable
+ public ref struct godot_packed_byte_array
{
- internal IntPtr _writeProxy;
- internal unsafe byte* _ptr;
+ private IntPtr _writeProxy;
+ private unsafe byte* _ptr;
public unsafe void Dispose()
{
@@ -342,15 +750,25 @@ namespace Godot.NativeInterop
_ptr = null;
}
- public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
+ public readonly unsafe byte* Buffer
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr;
+ }
+
+ public readonly unsafe int Size
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr != null ? *((int*)_ptr - 1) : 0;
+ }
}
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_packed_int32_array : IDisposable
+ public ref struct godot_packed_int32_array
{
- internal IntPtr _writeProxy;
- internal unsafe int* _ptr;
+ private IntPtr _writeProxy;
+ private unsafe int* _ptr;
public unsafe void Dispose()
{
@@ -360,15 +778,25 @@ namespace Godot.NativeInterop
_ptr = null;
}
- public unsafe int Size => _ptr != null ? *(_ptr - 1) : 0;
+ public readonly unsafe int* Buffer
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr;
+ }
+
+ public readonly unsafe int Size
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr != null ? *(_ptr - 1) : 0;
+ }
}
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_packed_int64_array : IDisposable
+ public ref struct godot_packed_int64_array
{
- internal IntPtr _writeProxy;
- internal unsafe long* _ptr;
+ private IntPtr _writeProxy;
+ private unsafe long* _ptr;
public unsafe void Dispose()
{
@@ -378,15 +806,25 @@ namespace Godot.NativeInterop
_ptr = null;
}
- public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
+ public readonly unsafe long* Buffer
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr;
+ }
+
+ public readonly unsafe int Size
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr != null ? *((int*)_ptr - 1) : 0;
+ }
}
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_packed_float32_array : IDisposable
+ public ref struct godot_packed_float32_array
{
- internal IntPtr _writeProxy;
- internal unsafe float* _ptr;
+ private IntPtr _writeProxy;
+ private unsafe float* _ptr;
public unsafe void Dispose()
{
@@ -396,15 +834,25 @@ namespace Godot.NativeInterop
_ptr = null;
}
- public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
+ public readonly unsafe float* Buffer
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr;
+ }
+
+ public readonly unsafe int Size
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr != null ? *((int*)_ptr - 1) : 0;
+ }
}
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_packed_float64_array : IDisposable
+ public ref struct godot_packed_float64_array
{
- internal IntPtr _writeProxy;
- internal unsafe double* _ptr;
+ private IntPtr _writeProxy;
+ private unsafe double* _ptr;
public unsafe void Dispose()
{
@@ -414,15 +862,25 @@ namespace Godot.NativeInterop
_ptr = null;
}
- public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
+ public readonly unsafe double* Buffer
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr;
+ }
+
+ public readonly unsafe int Size
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr != null ? *((int*)_ptr - 1) : 0;
+ }
}
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_packed_string_array : IDisposable
+ public ref struct godot_packed_string_array
{
- internal IntPtr _writeProxy;
- internal unsafe godot_string* _ptr;
+ private IntPtr _writeProxy;
+ private unsafe godot_string* _ptr;
public unsafe void Dispose()
{
@@ -432,15 +890,25 @@ namespace Godot.NativeInterop
_ptr = null;
}
- public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
+ public readonly unsafe godot_string* Buffer
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr;
+ }
+
+ public readonly unsafe int Size
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr != null ? *((int*)_ptr - 1) : 0;
+ }
}
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_packed_vector2_array : IDisposable
+ public ref struct godot_packed_vector2_array
{
- internal IntPtr _writeProxy;
- internal unsafe Vector2* _ptr;
+ private IntPtr _writeProxy;
+ private unsafe Vector2* _ptr;
public unsafe void Dispose()
{
@@ -450,15 +918,25 @@ namespace Godot.NativeInterop
_ptr = null;
}
- public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
+ public readonly unsafe Vector2* Buffer
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr;
+ }
+
+ public readonly unsafe int Size
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr != null ? *((int*)_ptr - 1) : 0;
+ }
}
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_packed_vector3_array : IDisposable
+ public ref struct godot_packed_vector3_array
{
- internal IntPtr _writeProxy;
- internal unsafe Vector3* _ptr;
+ private IntPtr _writeProxy;
+ private unsafe Vector3* _ptr;
public unsafe void Dispose()
{
@@ -468,15 +946,25 @@ namespace Godot.NativeInterop
_ptr = null;
}
- public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
+ public readonly unsafe Vector3* Buffer
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr;
+ }
+
+ public readonly unsafe int Size
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr != null ? *((int*)_ptr - 1) : 0;
+ }
}
[StructLayout(LayoutKind.Sequential)]
// ReSharper disable once InconsistentNaming
- public struct godot_packed_color_array : IDisposable
+ public ref struct godot_packed_color_array
{
- internal IntPtr _writeProxy;
- internal unsafe Color* _ptr;
+ private IntPtr _writeProxy;
+ private unsafe Color* _ptr;
public unsafe void Dispose()
{
@@ -486,6 +974,16 @@ namespace Godot.NativeInterop
_ptr = null;
}
- public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
+ public readonly unsafe Color* Buffer
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr;
+ }
+
+ public readonly unsafe int Size
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _ptr != null ? *((int*)_ptr - 1) : 0;
+ }
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropUtils.cs
index 5779421c69..8ddf28ba16 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropUtils.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropUtils.cs
@@ -1,5 +1,4 @@
using System;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Godot.Bridge;
@@ -16,22 +15,19 @@ namespace Godot.NativeInterop
return null;
IntPtr gcHandlePtr;
- godot_bool has_cs_script_instance = false.ToGodotBool();
+ godot_bool hasCsScriptInstance;
// First try to get the tied managed instance from a CSharpInstance script instance
- unsafe
- {
- gcHandlePtr = NativeFuncs.godotsharp_internal_unmanaged_get_script_instance_managed(
- unmanaged, &has_cs_script_instance);
- }
+ gcHandlePtr = NativeFuncs.godotsharp_internal_unmanaged_get_script_instance_managed(
+ unmanaged, out hasCsScriptInstance);
if (gcHandlePtr != IntPtr.Zero)
return (Object)GCHandle.FromIntPtr(gcHandlePtr).Target;
// Otherwise, if the object has a CSharpInstance script instance, return null
- if (has_cs_script_instance.ToBool())
+ if (hasCsScriptInstance.ToBool())
return null;
// If it doesn't have a CSharpInstance script instance, try with native instance bindings
@@ -58,12 +54,9 @@ namespace Godot.NativeInterop
if (type == nativeType)
{
- unsafe
- {
- godot_string_name nativeNameAux = nativeName.NativeValue;
- NativeFuncs.godotsharp_internal_tie_native_managed_to_unmanaged(
- GCHandle.ToIntPtr(gcHandle), unmanaged, &nativeNameAux, refCounted.ToGodotBool());
- }
+ var nativeNameSelf = (godot_string_name)nativeName.NativeValue;
+ NativeFuncs.godotsharp_internal_tie_native_managed_to_unmanaged(
+ GCHandle.ToIntPtr(gcHandle), unmanaged, nativeNameSelf, refCounted.ToGodotBool());
}
else
{
@@ -88,10 +81,10 @@ namespace Godot.NativeInterop
GCHandle.ToIntPtr(strongGCHandle), unmanaged);
}
- public static unsafe Object EngineGetSingleton(string name)
+ public static Object EngineGetSingleton(string name)
{
- using godot_string src = Marshaling.mono_string_to_godot(name);
- return UnmanagedGetManaged(NativeFuncs.godotsharp_engine_get_singleton(&src));
+ using godot_string src = Marshaling.ConvertStringToNative(name);
+ return UnmanagedGetManaged(NativeFuncs.godotsharp_engine_get_singleton(src));
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs
index 74232425bb..d1a1450f04 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs
@@ -1,19 +1,21 @@
using System;
using System.Collections;
using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.InteropServices;
// ReSharper disable InconsistentNaming
+// We want to use full name qualifiers here even if redundant for clarity
+// ReSharper disable RedundantNameQualifier
+
+#nullable enable
+
namespace Godot.NativeInterop
{
- // We want to use full name qualifiers here even if redundant for clarity
- [SuppressMessage("ReSharper", "RedundantNameQualifier")]
public static class Marshaling
{
- public static Variant.Type managed_to_variant_type(Type type, out bool r_nil_is_variant)
+ internal static Variant.Type ConvertManagedTypeToVariantType(Type type, out bool r_nil_is_variant)
{
r_nil_is_variant = false;
@@ -106,7 +108,7 @@ namespace Godot.NativeInterop
if (type.IsArray || type.IsSZArray)
{
- if (type == typeof(Byte[]))
+ if (type == typeof(byte[]))
return Variant.Type.PackedByteArray;
if (type == typeof(Int32[]))
@@ -133,6 +135,15 @@ namespace Godot.NativeInterop
if (type == typeof(Color[]))
return Variant.Type.PackedColorArray;
+ if (type == typeof(StringName[]))
+ return Variant.Type.Array;
+
+ if (type == typeof(NodePath[]))
+ return Variant.Type.Array;
+
+ if (type == typeof(RID[]))
+ return Variant.Type.Array;
+
if (typeof(Godot.Object[]).IsAssignableFrom(type))
return Variant.Type.Array;
@@ -161,6 +172,9 @@ namespace Godot.NativeInterop
if (genericTypeDefinition == typeof(ICollection<>) ||
genericTypeDefinition == typeof(IEnumerable<>))
return Variant.Type.Array;
+
+ if (typeof(Godot.Object).IsAssignableFrom(type))
+ return Variant.Type.Object;
}
else if (type == typeof(object))
{
@@ -200,44 +214,9 @@ namespace Godot.NativeInterop
return Variant.Type.Nil;
}
- public static bool try_get_array_element_type(Type p_array_type, out Type r_elem_type)
- {
- if (p_array_type.IsArray || p_array_type.IsSZArray)
- {
- r_elem_type = p_array_type.GetElementType();
- return true;
- }
- else if (p_array_type.IsGenericType)
- {
- var genericTypeDefinition = p_array_type.GetGenericTypeDefinition();
-
- if (typeof(Collections.Array) == genericTypeDefinition ||
- typeof(System.Collections.Generic.List<>) == genericTypeDefinition ||
- typeof(System.Collections.ICollection) == genericTypeDefinition ||
- typeof(System.Collections.IEnumerable) == genericTypeDefinition)
- {
- r_elem_type = p_array_type.GetGenericArguments()[0];
- return true;
- }
- }
-
- r_elem_type = null;
- return false;
- }
-
/* TODO: Reflection and type checking each time is slow. This will be replaced with source generators. */
- public static godot_variant mono_object_to_variant(object p_obj)
- {
- return mono_object_to_variant_impl(p_obj);
- }
-
- public static godot_variant mono_object_to_variant_no_err(object p_obj)
- {
- return mono_object_to_variant_impl(p_obj);
- }
-
- private static unsafe godot_variant mono_object_to_variant_impl(object p_obj, bool p_fail_with_err = true)
+ public static godot_variant ConvertManagedObjectToVariant(object? p_obj)
{
if (p_obj == null)
return new godot_variant();
@@ -248,7 +227,7 @@ namespace Godot.NativeInterop
return VariantUtils.CreateFromBool(@bool);
case char @char:
return VariantUtils.CreateFromInt(@char);
- case SByte @int8:
+ case sbyte @int8:
return VariantUtils.CreateFromInt(@int8);
case Int16 @int16:
return VariantUtils.CreateFromInt(@int16);
@@ -256,7 +235,7 @@ namespace Godot.NativeInterop
return VariantUtils.CreateFromInt(@int32);
case Int64 @int64:
return VariantUtils.CreateFromInt(@int64);
- case Byte @uint8:
+ case byte @uint8:
return VariantUtils.CreateFromInt(@uint8);
case UInt16 @uint16:
return VariantUtils.CreateFromInt(@uint16);
@@ -311,58 +290,72 @@ namespace Godot.NativeInterop
case string @string:
{
return VariantUtils.CreateFromStringTakingOwnershipOfDisposableValue(
- mono_string_to_godot(@string));
+ ConvertStringToNative(@string));
}
- case Byte[] byteArray:
+ case byte[] byteArray:
{
- using godot_packed_byte_array array = mono_array_to_PackedByteArray(byteArray);
- return VariantUtils.CreateFromPackedByteArray(&array);
+ using godot_packed_byte_array array = ConvertSystemArrayToNativePackedByteArray(byteArray);
+ return VariantUtils.CreateFromPackedByteArray(array);
}
case Int32[] int32Array:
{
- using godot_packed_int32_array array = mono_array_to_PackedInt32Array(int32Array);
- return VariantUtils.CreateFromPackedInt32Array(&array);
+ using godot_packed_int32_array array = ConvertSystemArrayToNativePackedInt32Array(int32Array);
+ return VariantUtils.CreateFromPackedInt32Array(array);
}
case Int64[] int64Array:
{
- using godot_packed_int64_array array = mono_array_to_PackedInt64Array(int64Array);
- return VariantUtils.CreateFromPackedInt64Array(&array);
+ using godot_packed_int64_array array = ConvertSystemArrayToNativePackedInt64Array(int64Array);
+ return VariantUtils.CreateFromPackedInt64Array(array);
}
case float[] floatArray:
{
- using godot_packed_float32_array array = mono_array_to_PackedFloat32Array(floatArray);
- return VariantUtils.CreateFromPackedFloat32Array(&array);
+ using godot_packed_float32_array array = ConvertSystemArrayToNativePackedFloat32Array(floatArray);
+ return VariantUtils.CreateFromPackedFloat32Array(array);
}
case double[] doubleArray:
{
- using godot_packed_float64_array array = mono_array_to_PackedFloat64Array(doubleArray);
- return VariantUtils.CreateFromPackedFloat64Array(&array);
+ using godot_packed_float64_array array = ConvertSystemArrayToNativePackedFloat64Array(doubleArray);
+ return VariantUtils.CreateFromPackedFloat64Array(array);
}
case string[] stringArray:
{
- using godot_packed_string_array array = mono_array_to_PackedStringArray(stringArray);
- return VariantUtils.CreateFromPackedStringArray(&array);
+ using godot_packed_string_array array = ConvertSystemArrayToNativePackedStringArray(stringArray);
+ return VariantUtils.CreateFromPackedStringArray(array);
}
case Vector2[] vector2Array:
{
- using godot_packed_vector2_array array = mono_array_to_PackedVector2Array(vector2Array);
- return VariantUtils.CreateFromPackedVector2Array(&array);
+ using godot_packed_vector2_array array = ConvertSystemArrayToNativePackedVector2Array(vector2Array);
+ return VariantUtils.CreateFromPackedVector2Array(array);
}
case Vector3[] vector3Array:
{
- using godot_packed_vector3_array array = mono_array_to_PackedVector3Array(vector3Array);
- return VariantUtils.CreateFromPackedVector3Array(&array);
+ using godot_packed_vector3_array array = ConvertSystemArrayToNativePackedVector3Array(vector3Array);
+ return VariantUtils.CreateFromPackedVector3Array(array);
}
case Color[] colorArray:
{
- using godot_packed_color_array array = mono_array_to_PackedColorArray(colorArray);
- return VariantUtils.CreateFromPackedColorArray(&array);
+ using godot_packed_color_array array = ConvertSystemArrayToNativePackedColorArray(colorArray);
+ return VariantUtils.CreateFromPackedColorArray(array);
+ }
+ case StringName[] stringNameArray:
+ {
+ using godot_array array = ConvertSystemArrayToNativeGodotArray(stringNameArray);
+ return VariantUtils.CreateFromArray(array);
+ }
+ case NodePath[] nodePathArray:
+ {
+ using godot_array array = ConvertSystemArrayToNativeGodotArray(nodePathArray);
+ return VariantUtils.CreateFromArray(array);
+ }
+ case RID[] ridArray:
+ {
+ using godot_array array = ConvertSystemArrayToNativeGodotArray(ridArray);
+ return VariantUtils.CreateFromArray(array);
}
case Godot.Object[] godotObjectArray:
{
- // ReSharper disable once CoVariantArrayConversion
- using godot_array array = mono_array_to_Array(godotObjectArray);
- return VariantUtils.CreateFromArray(&array);
+ using godot_array array = ConvertSystemArrayToNativeGodotArray(godotObjectArray);
+ return VariantUtils.CreateFromArray(array);
}
case object[] objectArray: // Last one to avoid catching others like string[] and Godot.Object[]
{
@@ -370,45 +363,38 @@ namespace Godot.NativeInterop
// so we need to check the actual type to make sure it's truly `object[]`.
if (objectArray.GetType() == typeof(object[]))
{
- using godot_array array = mono_array_to_Array(objectArray);
- return VariantUtils.CreateFromArray(&array);
+ using godot_array array = ConvertSystemArrayToNativeGodotArray(objectArray);
+ return VariantUtils.CreateFromArray(array);
}
- if (p_fail_with_err)
- {
- GD.PushError("Attempted to convert a managed array of unmarshallable element type to Variant.");
- return new godot_variant();
- }
- else
- {
- return new godot_variant();
- }
+ GD.PushError("Attempted to convert a managed array of unmarshallable element type to Variant.");
+ return new godot_variant();
}
case Godot.Object godotObject:
return VariantUtils.CreateFromGodotObject(godotObject.NativeInstance);
case StringName stringName:
- return VariantUtils.CreateFromStringName(ref stringName.NativeValue);
+ return VariantUtils.CreateFromStringName(stringName.NativeValue.DangerousSelfRef);
case NodePath nodePath:
- return VariantUtils.CreateFromNodePath(ref nodePath.NativeValue);
+ return VariantUtils.CreateFromNodePath((godot_node_path)nodePath.NativeValue);
case RID rid:
return VariantUtils.CreateFromRID(rid);
case Collections.Dictionary godotDictionary:
- return VariantUtils.CreateFromDictionary(godotDictionary.NativeValue);
+ return VariantUtils.CreateFromDictionary((godot_dictionary)godotDictionary.NativeValue);
case Collections.Array godotArray:
- return VariantUtils.CreateFromArray(godotArray.NativeValue);
+ return VariantUtils.CreateFromArray((godot_array)godotArray.NativeValue);
case Collections.IGenericGodotDictionary genericGodotDictionary:
{
var godotDict = genericGodotDictionary.UnderlyingDictionary;
if (godotDict == null)
return new godot_variant();
- return VariantUtils.CreateFromDictionary(godotDict.NativeValue);
+ return VariantUtils.CreateFromDictionary((godot_dictionary)godotDict.NativeValue);
}
case Collections.IGenericGodotArray genericGodotArray:
{
var godotArray = genericGodotArray.UnderlyingArray;
if (godotArray == null)
return new godot_variant();
- return VariantUtils.CreateFromArray(godotArray.NativeValue);
+ return VariantUtils.CreateFromArray((godot_array)godotArray.NativeValue);
}
default:
{
@@ -426,14 +412,14 @@ namespace Godot.NativeInterop
foreach (KeyValuePair<object, object> entry in (IDictionary)p_obj)
godotDict.Add(entry.Key, entry.Value);
- return VariantUtils.CreateFromDictionary(godotDict.NativeValue);
+ return VariantUtils.CreateFromDictionary((godot_dictionary)godotDict.NativeValue);
}
if (genericTypeDefinition == typeof(System.Collections.Generic.List<>))
{
// TODO: Validate element type is compatible with Variant
- var nativeGodotArray = mono_array_to_Array((IList)p_obj);
- return VariantUtils.CreateFromArray(&nativeGodotArray);
+ using var nativeGodotArray = ConvertIListToNativeGodotArray((IList)p_obj);
+ return VariantUtils.CreateFromArray(nativeGodotArray);
}
}
@@ -441,38 +427,31 @@ namespace Godot.NativeInterop
}
}
- if (p_fail_with_err)
- {
- GD.PushError("Attempted to convert an unmarshallable managed type to Variant. Name: '" +
- p_obj.GetType().FullName + ".");
- return new godot_variant();
- }
- else
- {
- return new godot_variant();
- }
+ GD.PushError("Attempted to convert an unmarshallable managed type to Variant. Name: '" +
+ p_obj.GetType().FullName + ".");
+ return new godot_variant();
}
- public static unsafe string variant_to_mono_string(godot_variant* p_var)
+ private static string? ConvertVariantToManagedString(in godot_variant p_var)
{
- switch ((*p_var)._type)
+ switch (p_var.Type)
{
case Variant.Type.Nil:
return null; // Otherwise, Variant -> String would return the string "Null"
case Variant.Type.String:
{
// We avoid the internal call if the stored type is the same we want.
- return mono_string_from_godot((*p_var)._data._m_string);
+ return ConvertStringToManaged(p_var.String);
}
default:
{
using godot_string godotString = NativeFuncs.godotsharp_variant_as_string(p_var);
- return mono_string_from_godot(godotString);
+ return ConvertStringToManaged(godotString);
}
}
}
- public static unsafe object variant_to_mono_object_of_type(godot_variant* p_var, Type type)
+ public static object? ConvertVariantToManagedObjectOfType(in godot_variant p_var, Type type)
{
// This function is only needed to set the value of properties. Fields have their own implementation, set_value_from_variant.
switch (Type.GetTypeCode(type))
@@ -502,7 +481,7 @@ namespace Godot.NativeInterop
case TypeCode.Double:
return VariantUtils.ConvertToFloat64(p_var);
case TypeCode.String:
- return variant_to_mono_string(p_var);
+ return ConvertVariantToManagedString(p_var);
default:
{
if (type == typeof(Vector2))
@@ -556,13 +535,13 @@ namespace Godot.NativeInterop
if (type == typeof(Callable))
{
using godot_callable callable = NativeFuncs.godotsharp_variant_as_callable(p_var);
- return ConvertCallableToManaged(&callable);
+ return ConvertCallableToManaged(in callable);
}
if (type == typeof(SignalInfo))
{
using godot_signal signal = NativeFuncs.godotsharp_variant_as_signal(p_var);
- return ConvertSignalToManaged(&signal);
+ return ConvertSignalToManaged(in signal);
}
if (type.IsEnum)
@@ -597,12 +576,12 @@ namespace Godot.NativeInterop
}
if (type.IsArray || type.IsSZArray)
- return variant_to_mono_array_of_type(p_var, type);
+ return ConvertVariantToSystemArrayOfType(p_var, type);
else if (type.IsGenericType)
- return variant_to_mono_object_of_genericinst(p_var, type);
+ return ConvertVariantToManagedObjectOfGenericType(p_var, type);
else if (type == typeof(object))
- return variant_to_mono_object(p_var);
- if (variant_to_mono_object_of_class(p_var, type, out object res))
+ return ConvertVariantToManagedObject(p_var);
+ if (ConvertVariantToManagedObjectOfClass(p_var, type, out object? res))
return res;
break;
@@ -614,72 +593,90 @@ namespace Godot.NativeInterop
return null;
}
- private static unsafe object variant_to_mono_array_of_type(godot_variant* p_var, Type type)
+ private static object? ConvertVariantToSystemArrayOfType(in godot_variant p_var, Type type)
{
- if (type == typeof(Byte[]))
+ if (type == typeof(byte[]))
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_byte_array(p_var);
- return PackedByteArray_to_mono_array(&packedArray);
+ return ConvertNativePackedByteArrayToSystemArray(packedArray);
}
if (type == typeof(Int32[]))
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_int32_array(p_var);
- return PackedInt32Array_to_mono_array(&packedArray);
+ return ConvertNativePackedInt32ArrayToSystemArray(packedArray);
}
if (type == typeof(Int64[]))
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_int64_array(p_var);
- return PackedInt64Array_to_mono_array(&packedArray);
+ return ConvertNativePackedInt64ArrayToSystemArray(packedArray);
}
if (type == typeof(float[]))
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_float32_array(p_var);
- return PackedFloat32Array_to_mono_array(&packedArray);
+ return ConvertNativePackedFloat32ArrayToSystemArray(packedArray);
}
if (type == typeof(double[]))
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_float64_array(p_var);
- return PackedFloat64Array_to_mono_array(&packedArray);
+ return ConvertNativePackedFloat64ArrayToSystemArray(packedArray);
}
if (type == typeof(string[]))
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_string_array(p_var);
- return PackedStringArray_to_mono_array(&packedArray);
+ return ConvertNativePackedStringArrayToSystemArray(packedArray);
}
if (type == typeof(Vector2[]))
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_vector2_array(p_var);
- return PackedVector2Array_to_mono_array(&packedArray);
+ return ConvertNativePackedVector2ArrayToSystemArray(packedArray);
}
if (type == typeof(Vector3[]))
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_vector3_array(p_var);
- return PackedVector3Array_to_mono_array(&packedArray);
+ return ConvertNativePackedVector3ArrayToSystemArray(packedArray);
}
if (type == typeof(Color[]))
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_color_array(p_var);
- return PackedColorArray_to_mono_array(&packedArray);
+ return ConvertNativePackedColorArrayToSystemArray(packedArray);
+ }
+
+ if (type == typeof(StringName[]))
+ {
+ using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var);
+ return ConvertNativeGodotArrayToSystemArrayOfType(godotArray, type);
+ }
+
+ if (type == typeof(NodePath[]))
+ {
+ using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var);
+ return ConvertNativeGodotArrayToSystemArrayOfType(godotArray, type);
+ }
+
+ if (type == typeof(RID[]))
+ {
+ using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var);
+ return ConvertNativeGodotArrayToSystemArrayOfType(godotArray, type);
}
if (typeof(Godot.Object[]).IsAssignableFrom(type))
{
using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var);
- return Array_to_mono_array_of_godot_object_type(&godotArray, type);
+ return ConvertNativeGodotArrayToSystemArrayOfType(godotArray, type);
}
if (type == typeof(object[]))
{
using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var);
- return Array_to_mono_array(&godotArray);
+ return ConvertNativeGodotArrayToSystemArray(godotArray);
}
GD.PushError("Attempted to convert Variant to array of unsupported element type. Name: " +
@@ -687,7 +684,8 @@ namespace Godot.NativeInterop
return null;
}
- private static unsafe bool variant_to_mono_object_of_class(godot_variant* p_var, Type type, out object res)
+ private static bool ConvertVariantToManagedObjectOfClass(in godot_variant p_var, Type type,
+ out object? res)
{
if (typeof(Godot.Object).IsAssignableFrom(type))
{
@@ -735,33 +733,33 @@ namespace Godot.NativeInterop
return false;
}
- private static unsafe object variant_to_mono_object_of_genericinst(godot_variant* p_var, Type type)
+ private static object? ConvertVariantToManagedObjectOfGenericType(in godot_variant p_var, Type type)
{
- static object variant_to_generic_godot_collections_dictionary(godot_variant* p_var, Type fullType)
+ static object ConvertVariantToGenericGodotCollectionsDictionary(in godot_variant p_var, Type fullType)
{
var underlyingDict = Collections.Dictionary.CreateTakingOwnershipOfDisposableValue(
VariantUtils.ConvertToDictionary(p_var));
return Activator.CreateInstance(fullType,
BindingFlags.Public | BindingFlags.Instance, null,
- args: new object[] { underlyingDict }, null);
+ args: new object[] { underlyingDict }, null)!;
}
- static object variant_to_generic_godot_collections_array(godot_variant* p_var, Type fullType)
+ static object ConvertVariantToGenericGodotCollectionsArray(in godot_variant p_var, Type fullType)
{
var underlyingArray = Collections.Array.CreateTakingOwnershipOfDisposableValue(
VariantUtils.ConvertToArray(p_var));
return Activator.CreateInstance(fullType,
BindingFlags.Public | BindingFlags.Instance, null,
- args: new object[] { underlyingArray }, null);
+ args: new object[] { underlyingArray }, null)!;
}
var genericTypeDefinition = type.GetGenericTypeDefinition();
if (genericTypeDefinition == typeof(Collections.Dictionary<,>))
- return variant_to_generic_godot_collections_dictionary(p_var, type);
+ return ConvertVariantToGenericGodotCollectionsDictionary(p_var, type);
if (genericTypeDefinition == typeof(Collections.Array<>))
- return variant_to_generic_godot_collections_array(p_var, type);
+ return ConvertVariantToGenericGodotCollectionsArray(p_var, type);
if (genericTypeDefinition == typeof(System.Collections.Generic.Dictionary<,>))
{
@@ -773,7 +771,7 @@ namespace Godot.NativeInterop
args: new object[]
{
/* capacity: */ godotDictionary.Count
- }, null);
+ }, null)!;
foreach (System.Collections.DictionaryEntry pair in godotDictionary)
dictionary.Add(pair.Key, pair.Value);
@@ -791,7 +789,7 @@ namespace Godot.NativeInterop
args: new object[]
{
/* capacity: */ godotArray.Count
- }, null);
+ }, null)!;
foreach (object elem in godotArray)
list.Add(elem);
@@ -807,7 +805,7 @@ namespace Godot.NativeInterop
var genericGodotDictionaryType = typeof(Collections.Dictionary<,>)
.MakeGenericType(keyType, valueType);
- return variant_to_generic_godot_collections_dictionary(p_var, genericGodotDictionaryType);
+ return ConvertVariantToGenericGodotCollectionsDictionary(p_var, genericGodotDictionaryType);
}
if (genericTypeDefinition == typeof(ICollection<>) || genericTypeDefinition == typeof(IEnumerable<>))
@@ -816,138 +814,141 @@ namespace Godot.NativeInterop
var genericGodotArrayType = typeof(Collections.Array<>)
.MakeGenericType(elementType);
- return variant_to_generic_godot_collections_array(p_var, genericGodotArrayType);
+ return ConvertVariantToGenericGodotCollectionsArray(p_var, genericGodotArrayType);
}
+ if (typeof(Godot.Object).IsAssignableFrom(type))
+ return InteropUtils.UnmanagedGetManaged(VariantUtils.ConvertToGodotObject(p_var));
+
return null;
}
- public static unsafe object variant_to_mono_object(godot_variant* p_var)
+ public static unsafe object? ConvertVariantToManagedObject(in godot_variant p_var)
{
- switch ((*p_var)._type)
+ switch (p_var.Type)
{
case Variant.Type.Bool:
- return (*p_var)._data._bool.ToBool();
+ return p_var.Bool.ToBool();
case Variant.Type.Int:
- return (*p_var)._data._int;
+ return p_var.Int;
case Variant.Type.Float:
{
#if REAL_T_IS_DOUBLE
- return (*p_var)._data._float;
+ return p_var.Float;
#else
- return (float)(*p_var)._data._float;
+ return (float)p_var.Float;
#endif
}
case Variant.Type.String:
- return mono_string_from_godot((*p_var)._data._m_string);
+ return ConvertStringToManaged(p_var.String);
case Variant.Type.Vector2:
- return (*p_var)._data._m_vector2;
+ return p_var.Vector2;
case Variant.Type.Vector2i:
- return (*p_var)._data._m_vector2i;
+ return p_var.Vector2i;
case Variant.Type.Rect2:
- return (*p_var)._data._m_rect2;
+ return p_var.Rect2;
case Variant.Type.Rect2i:
- return (*p_var)._data._m_rect2i;
+ return p_var.Rect2i;
case Variant.Type.Vector3:
- return (*p_var)._data._m_vector3;
+ return p_var.Vector3;
case Variant.Type.Vector3i:
- return (*p_var)._data._m_vector3i;
+ return p_var.Vector3i;
case Variant.Type.Transform2d:
- return *(*p_var)._data._transform2d;
+ return *p_var.Transform2D;
case Variant.Type.Vector4:
- return *(*p_var)._data._vector4;
+ return *p_var.Vector4;
case Variant.Type.Vector4i:
- return *(*p_var)._data._vector4i;
+ return *p_var.Vector4i;
case Variant.Type.Plane:
- return (*p_var)._data._m_plane;
+ return p_var.Plane;
case Variant.Type.Quaternion:
- return (*p_var)._data._m_quaternion;
+ return p_var.Quaternion;
case Variant.Type.Aabb:
- return *(*p_var)._data._aabb;
+ return *p_var.AABB;
case Variant.Type.Basis:
- return *(*p_var)._data._basis;
+ return *p_var.Basis;
case Variant.Type.Transform3d:
- return *(*p_var)._data._transform3d;
+ return *p_var.Transform3D;
case Variant.Type.Projection:
- return *(*p_var)._data._projection;
+ return *p_var.Projection;
case Variant.Type.Color:
- return (*p_var)._data._m_color;
+ return p_var.Color;
case Variant.Type.StringName:
{
// The Variant owns the value, so we need to make a copy
return StringName.CreateTakingOwnershipOfDisposableValue(
- NativeFuncs.godotsharp_string_name_new_copy(&(*p_var)._data._m_string_name));
+ NativeFuncs.godotsharp_string_name_new_copy(p_var.StringName));
}
case Variant.Type.NodePath:
{
// The Variant owns the value, so we need to make a copy
return NodePath.CreateTakingOwnershipOfDisposableValue(
- NativeFuncs.godotsharp_node_path_new_copy(&(*p_var)._data._m_node_path));
+ NativeFuncs.godotsharp_node_path_new_copy(p_var.NodePath));
}
case Variant.Type.Rid:
- return (*p_var)._data._m_rid;
+ return p_var.RID;
case Variant.Type.Object:
- return InteropUtils.UnmanagedGetManaged((*p_var)._data._m_obj_data.obj);
+ return InteropUtils.UnmanagedGetManaged(p_var.Object);
case Variant.Type.Callable:
- return ConvertCallableToManaged(&(*p_var)._data._m_callable);
+ return ConvertCallableToManaged(p_var.Callable);
case Variant.Type.Signal:
- return ConvertSignalToManaged(&(*p_var)._data._m_signal);
+ return ConvertSignalToManaged(p_var.Signal);
case Variant.Type.Dictionary:
{
// The Variant owns the value, so we need to make a copy
return Collections.Dictionary.CreateTakingOwnershipOfDisposableValue(
- NativeFuncs.godotsharp_dictionary_new_copy(&(*p_var)._data._m_dictionary));
+ NativeFuncs.godotsharp_dictionary_new_copy(p_var.Dictionary));
}
case Variant.Type.Array:
{
// The Variant owns the value, so we need to make a copy
return Collections.Array.CreateTakingOwnershipOfDisposableValue(
- NativeFuncs.godotsharp_array_new_copy(&(*p_var)._data._m_array));
+ NativeFuncs.godotsharp_array_new_copy(p_var.Array));
}
case Variant.Type.PackedByteArray:
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_byte_array(p_var);
- return PackedByteArray_to_mono_array(&packedArray);
+ return ConvertNativePackedByteArrayToSystemArray(packedArray);
}
case Variant.Type.PackedInt32Array:
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_int32_array(p_var);
- return PackedInt32Array_to_mono_array(&packedArray);
+ return ConvertNativePackedInt32ArrayToSystemArray(packedArray);
}
case Variant.Type.PackedInt64Array:
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_int64_array(p_var);
- return PackedInt64Array_to_mono_array(&packedArray);
+ return ConvertNativePackedInt64ArrayToSystemArray(packedArray);
}
case Variant.Type.PackedFloat32Array:
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_float32_array(p_var);
- return PackedFloat32Array_to_mono_array(&packedArray);
+ return ConvertNativePackedFloat32ArrayToSystemArray(packedArray);
}
case Variant.Type.PackedFloat64Array:
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_float64_array(p_var);
- return PackedFloat64Array_to_mono_array(&packedArray);
+ return ConvertNativePackedFloat64ArrayToSystemArray(packedArray);
}
case Variant.Type.PackedStringArray:
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_string_array(p_var);
- return PackedStringArray_to_mono_array(&packedArray);
+ return ConvertNativePackedStringArrayToSystemArray(packedArray);
}
case Variant.Type.PackedVector2Array:
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_vector2_array(p_var);
- return PackedVector2Array_to_mono_array(&packedArray);
+ return ConvertNativePackedVector2ArrayToSystemArray(packedArray);
}
case Variant.Type.PackedVector3Array:
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_vector3_array(p_var);
- return PackedVector3Array_to_mono_array(&packedArray);
+ return ConvertNativePackedVector3ArrayToSystemArray(packedArray);
}
case Variant.Type.PackedColorArray:
{
using var packedArray = NativeFuncs.godotsharp_variant_as_packed_color_array(p_var);
- return PackedColorArray_to_mono_array(&packedArray);
+ return ConvertNativePackedColorArrayToSystemArray(packedArray);
}
default:
return null;
@@ -956,26 +957,25 @@ namespace Godot.NativeInterop
// String
- public static unsafe godot_string mono_string_to_godot(string p_mono_string)
+ public static unsafe godot_string ConvertStringToNative(string? p_mono_string)
{
if (p_mono_string == null)
return new godot_string();
fixed (char* methodChars = p_mono_string)
{
- godot_string dest;
- NativeFuncs.godotsharp_string_new_with_utf16_chars(&dest, methodChars);
+ NativeFuncs.godotsharp_string_new_with_utf16_chars(out godot_string dest, methodChars);
return dest;
}
}
- public static unsafe string mono_string_from_godot(in godot_string p_string)
+ public static unsafe string ConvertStringToManaged(in godot_string p_string)
{
- if (p_string._ptr == IntPtr.Zero)
+ if (p_string.Buffer == IntPtr.Zero)
return string.Empty;
const int sizeOfChar32 = 4;
- byte* bytes = (byte*)p_string._ptr;
+ byte* bytes = (byte*)p_string.Buffer;
int size = p_string.Size;
if (size == 0)
return string.Empty;
@@ -987,54 +987,45 @@ namespace Godot.NativeInterop
// Callable
public static godot_callable ConvertCallableToNative(ref Callable p_managed_callable)
+ => ConvertCallableToNative(p_managed_callable);
+
+ public static godot_callable ConvertCallableToNative(Callable p_managed_callable)
{
if (p_managed_callable.Delegate != null)
{
- unsafe
- {
- godot_callable callable;
- NativeFuncs.godotsharp_callable_new_with_delegate(
- GCHandle.ToIntPtr(GCHandle.Alloc(p_managed_callable.Delegate)), &callable);
- return callable;
- }
+ NativeFuncs.godotsharp_callable_new_with_delegate(
+ GCHandle.ToIntPtr(GCHandle.Alloc(p_managed_callable.Delegate)),
+ out godot_callable callable);
+ return callable;
}
else
{
- unsafe
- {
- godot_string_name method;
-
- if (p_managed_callable.Method != null && !p_managed_callable.Method.IsEmpty)
- {
- godot_string_name src = p_managed_callable.Method.NativeValue;
- method = NativeFuncs.godotsharp_string_name_new_copy(&src);
- }
- else
- {
- method = default;
- }
+ godot_string_name method;
- return new godot_callable
- {
- _method = method, // Takes ownership of disposable
- _objectId = p_managed_callable.Target.GetInstanceId()
- };
+ if (p_managed_callable.Method != null && !p_managed_callable.Method.IsEmpty)
+ {
+ var src = (godot_string_name)p_managed_callable.Method.NativeValue;
+ method = NativeFuncs.godotsharp_string_name_new_copy(src);
}
+ else
+ {
+ method = default;
+ }
+
+ return new godot_callable(method /* Takes ownership of disposable */,
+ p_managed_callable.Target.GetInstanceId());
}
}
- public static unsafe Callable ConvertCallableToManaged(godot_callable* p_callable)
+ public static Callable ConvertCallableToManaged(in godot_callable p_callable)
{
- IntPtr delegateGCHandle;
- IntPtr godotObject;
- godot_string_name name;
-
- if (NativeFuncs.godotsharp_callable_get_data_for_marshalling(
- p_callable, &delegateGCHandle, &godotObject, &name).ToBool())
+ if (NativeFuncs.godotsharp_callable_get_data_for_marshalling(p_callable,
+ out IntPtr delegateGCHandle, out IntPtr godotObject,
+ out godot_string_name name).ToBool())
{
if (delegateGCHandle != IntPtr.Zero)
{
- return new Callable((Delegate)GCHandle.FromIntPtr(delegateGCHandle).Target);
+ return new Callable((Delegate?)GCHandle.FromIntPtr(delegateGCHandle).Target);
}
else
{
@@ -1053,39 +1044,32 @@ namespace Godot.NativeInterop
public static godot_signal ConvertSignalToNative(ref SignalInfo p_managed_signal)
{
ulong ownerId = p_managed_signal.Owner.GetInstanceId();
- unsafe
- {
- godot_string_name name;
-
- if (p_managed_signal.Name != null && !p_managed_signal.Name.IsEmpty)
- {
- godot_string_name src = p_managed_signal.Name.NativeValue;
- name = NativeFuncs.godotsharp_string_name_new_copy(&src);
- }
- else
- {
- name = default;
- }
+ godot_string_name name;
- return new godot_signal()
- {
- _name = name,
- _objectId = ownerId
- };
+ if (p_managed_signal.Name != null && !p_managed_signal.Name.IsEmpty)
+ {
+ var src = (godot_string_name)p_managed_signal.Name.NativeValue;
+ name = NativeFuncs.godotsharp_string_name_new_copy(src);
}
+ else
+ {
+ name = default;
+ }
+
+ return new godot_signal(name, ownerId);
}
- public static unsafe SignalInfo ConvertSignalToManaged(godot_signal* p_signal)
+ public static SignalInfo ConvertSignalToManaged(in godot_signal p_signal)
{
- var owner = GD.InstanceFromId((*p_signal)._objectId);
+ var owner = GD.InstanceFromId(p_signal.ObjectId);
var name = StringName.CreateTakingOwnershipOfDisposableValue(
- NativeFuncs.godotsharp_string_name_new_copy(&(*p_signal)._name));
+ NativeFuncs.godotsharp_string_name_new_copy(p_signal.Name));
return new SignalInfo(owner, name);
}
// Array
- public static unsafe object[] Array_to_mono_array(godot_array* p_array)
+ public static object[] ConvertNativeGodotArrayToSystemArray(in godot_array p_array)
{
var array = Collections.Array.CreateTakingOwnershipOfDisposableValue(
NativeFuncs.godotsharp_array_new_copy(p_array));
@@ -1093,27 +1077,27 @@ namespace Godot.NativeInterop
int length = array.Count;
var ret = new object[length];
- array.CopyTo(ret, 0); // variant_to_mono_object handled by Collections.Array
+ array.CopyTo(ret, 0); // ConvertVariantToManagedObject handled by Collections.Array
return ret;
}
- public static unsafe object Array_to_mono_array_of_godot_object_type(godot_array* p_array, Type type)
+ private static object ConvertNativeGodotArrayToSystemArrayOfType(in godot_array p_array, Type type)
{
var array = Collections.Array.CreateTakingOwnershipOfDisposableValue(
NativeFuncs.godotsharp_array_new_copy(p_array));
int length = array.Count;
- object ret = Activator.CreateInstance(type, length);
+ object ret = Activator.CreateInstance(type, length)!;
- // variant_to_mono_object handled by Collections.Array
- // variant_to_mono_object_of_type is not needed because target element types are Godot.Object (or derived)
+ // ConvertVariantToManagedObject handled by Collections.Array
+ // ConvertVariantToManagedObjectOfType is not needed because target element types are Godot.Object (or derived)
array.CopyTo((object[])ret, 0);
return ret;
}
- public static godot_array mono_array_to_Array(object[] p_array)
+ public static godot_array ConvertSystemArrayToNativeGodotArray(object[] p_array)
{
int length = p_array.Length;
@@ -1126,14 +1110,28 @@ namespace Godot.NativeInterop
for (int i = 0; i < length; i++)
array[i] = p_array[i];
- godot_array src = array.NativeValue;
- unsafe
- {
- return NativeFuncs.godotsharp_array_new_copy(&src);
- }
+ var src = (godot_array)array.NativeValue;
+ return NativeFuncs.godotsharp_array_new_copy(src);
+ }
+
+ public static godot_array ConvertSystemArrayToNativeGodotArray<T>(T[] p_array)
+ {
+ int length = p_array.Length;
+
+ if (length == 0)
+ return NativeFuncs.godotsharp_array_new();
+
+ using var array = new Collections.Array();
+ array.Resize(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 mono_array_to_Array(IList p_array)
+ public static godot_array ConvertIListToNativeGodotArray(IList p_array)
{
int length = p_array.Count;
@@ -1146,26 +1144,25 @@ namespace Godot.NativeInterop
for (int i = 0; i < length; i++)
array[i] = p_array[i];
- godot_array src = array.NativeValue;
- unsafe
- {
- return NativeFuncs.godotsharp_array_new_copy(&src);
- }
+ var src = (godot_array)array.NativeValue;
+ return NativeFuncs.godotsharp_array_new_copy(src);
}
// PackedByteArray
- public static unsafe byte[] PackedByteArray_to_mono_array(godot_packed_byte_array* p_array)
+ public static unsafe byte[] ConvertNativePackedByteArrayToSystemArray(in godot_packed_byte_array p_array)
{
- byte* buffer = (*p_array)._ptr;
- int size = (*p_array).Size;
+ byte* buffer = p_array.Buffer;
+ int size = p_array.Size;
+ if (size == 0)
+ return Array.Empty<byte>();
var array = new byte[size];
fixed (byte* dest = array)
Buffer.MemoryCopy(buffer, dest, size, size);
return array;
}
- public static unsafe godot_packed_byte_array mono_array_to_PackedByteArray(Span<byte> p_array)
+ public static unsafe godot_packed_byte_array ConvertSystemArrayToNativePackedByteArray(Span<byte> p_array)
{
if (p_array.IsEmpty)
return new godot_packed_byte_array();
@@ -1175,10 +1172,12 @@ namespace Godot.NativeInterop
// PackedInt32Array
- public static unsafe int[] PackedInt32Array_to_mono_array(godot_packed_int32_array* p_array)
+ public static unsafe int[] ConvertNativePackedInt32ArrayToSystemArray(godot_packed_int32_array p_array)
{
- int* buffer = (*p_array)._ptr;
- int size = (*p_array).Size;
+ int* buffer = p_array.Buffer;
+ int size = p_array.Size;
+ if (size == 0)
+ return Array.Empty<int>();
int sizeInBytes = size * sizeof(int);
var array = new int[size];
fixed (int* dest = array)
@@ -1186,7 +1185,7 @@ namespace Godot.NativeInterop
return array;
}
- public static unsafe godot_packed_int32_array mono_array_to_PackedInt32Array(Span<int> p_array)
+ public static unsafe godot_packed_int32_array ConvertSystemArrayToNativePackedInt32Array(Span<int> p_array)
{
if (p_array.IsEmpty)
return new godot_packed_int32_array();
@@ -1196,10 +1195,12 @@ namespace Godot.NativeInterop
// PackedInt64Array
- public static unsafe long[] PackedInt64Array_to_mono_array(godot_packed_int64_array* p_array)
+ public static unsafe long[] ConvertNativePackedInt64ArrayToSystemArray(godot_packed_int64_array p_array)
{
- long* buffer = (*p_array)._ptr;
- int size = (*p_array).Size;
+ long* buffer = p_array.Buffer;
+ int size = p_array.Size;
+ if (size == 0)
+ return Array.Empty<long>();
int sizeInBytes = size * sizeof(long);
var array = new long[size];
fixed (long* dest = array)
@@ -1207,7 +1208,7 @@ namespace Godot.NativeInterop
return array;
}
- public static unsafe godot_packed_int64_array mono_array_to_PackedInt64Array(Span<long> p_array)
+ public static unsafe godot_packed_int64_array ConvertSystemArrayToNativePackedInt64Array(Span<long> p_array)
{
if (p_array.IsEmpty)
return new godot_packed_int64_array();
@@ -1217,10 +1218,12 @@ namespace Godot.NativeInterop
// PackedFloat32Array
- public static unsafe float[] PackedFloat32Array_to_mono_array(godot_packed_float32_array* p_array)
+ public static unsafe float[] ConvertNativePackedFloat32ArrayToSystemArray(godot_packed_float32_array p_array)
{
- float* buffer = (*p_array)._ptr;
- int size = (*p_array).Size;
+ float* buffer = p_array.Buffer;
+ int size = p_array.Size;
+ if (size == 0)
+ return Array.Empty<float>();
int sizeInBytes = size * sizeof(float);
var array = new float[size];
fixed (float* dest = array)
@@ -1228,7 +1231,8 @@ namespace Godot.NativeInterop
return array;
}
- public static unsafe godot_packed_float32_array mono_array_to_PackedFloat32Array(Span<float> p_array)
+ public static unsafe godot_packed_float32_array ConvertSystemArrayToNativePackedFloat32Array(
+ Span<float> p_array)
{
if (p_array.IsEmpty)
return new godot_packed_float32_array();
@@ -1238,10 +1242,12 @@ namespace Godot.NativeInterop
// PackedFloat64Array
- public static unsafe double[] PackedFloat64Array_to_mono_array(godot_packed_float64_array* p_array)
+ public static unsafe double[] ConvertNativePackedFloat64ArrayToSystemArray(godot_packed_float64_array p_array)
{
- double* buffer = (*p_array)._ptr;
- int size = (*p_array).Size;
+ double* buffer = p_array.Buffer;
+ int size = p_array.Size;
+ if (size == 0)
+ return Array.Empty<double>();
int sizeInBytes = size * sizeof(double);
var array = new double[size];
fixed (double* dest = array)
@@ -1249,7 +1255,8 @@ namespace Godot.NativeInterop
return array;
}
- public static unsafe godot_packed_float64_array mono_array_to_PackedFloat64Array(Span<double> p_array)
+ public static unsafe godot_packed_float64_array ConvertSystemArrayToNativePackedFloat64Array(
+ Span<double> p_array)
{
if (p_array.IsEmpty)
return new godot_packed_float64_array();
@@ -1259,19 +1266,19 @@ namespace Godot.NativeInterop
// PackedStringArray
- public static unsafe string[] PackedStringArray_to_mono_array(godot_packed_string_array* p_array)
+ public static unsafe string[] ConvertNativePackedStringArrayToSystemArray(godot_packed_string_array p_array)
{
- godot_string* buffer = (*p_array)._ptr;
- if (buffer == null)
- return new string[] { };
- int size = (*p_array).Size;
+ godot_string* buffer = p_array.Buffer;
+ int size = p_array.Size;
+ if (size == 0)
+ return Array.Empty<string>();
var array = new string[size];
for (int i = 0; i < size; i++)
- array[i] = mono_string_from_godot(buffer[i]);
+ array[i] = ConvertStringToManaged(buffer[i]);
return array;
}
- public static unsafe godot_packed_string_array mono_array_to_PackedStringArray(Span<string> p_array)
+ public static godot_packed_string_array ConvertSystemArrayToNativePackedStringArray(Span<string> p_array)
{
godot_packed_string_array dest = new godot_packed_string_array();
@@ -1283,8 +1290,8 @@ namespace Godot.NativeInterop
for (int i = 0; i < p_array.Length; i++)
{
- using godot_string godotStrElem = mono_string_to_godot(p_array[i]);
- NativeFuncs.godotsharp_packed_string_array_add(&dest, &godotStrElem);
+ using godot_string godotStrElem = ConvertStringToNative(p_array[i]);
+ NativeFuncs.godotsharp_packed_string_array_add(ref dest, godotStrElem);
}
return dest;
@@ -1292,10 +1299,12 @@ namespace Godot.NativeInterop
// PackedVector2Array
- public static unsafe Vector2[] PackedVector2Array_to_mono_array(godot_packed_vector2_array* p_array)
+ public static unsafe Vector2[] ConvertNativePackedVector2ArrayToSystemArray(godot_packed_vector2_array p_array)
{
- Vector2* buffer = (*p_array)._ptr;
- int size = (*p_array).Size;
+ Vector2* buffer = p_array.Buffer;
+ int size = p_array.Size;
+ if (size == 0)
+ return Array.Empty<Vector2>();
int sizeInBytes = size * sizeof(Vector2);
var array = new Vector2[size];
fixed (Vector2* dest = array)
@@ -1303,7 +1312,8 @@ namespace Godot.NativeInterop
return array;
}
- public static unsafe godot_packed_vector2_array mono_array_to_PackedVector2Array(Span<Vector2> p_array)
+ public static unsafe godot_packed_vector2_array ConvertSystemArrayToNativePackedVector2Array(
+ Span<Vector2> p_array)
{
if (p_array.IsEmpty)
return new godot_packed_vector2_array();
@@ -1313,10 +1323,12 @@ namespace Godot.NativeInterop
// PackedVector3Array
- public static unsafe Vector3[] PackedVector3Array_to_mono_array(godot_packed_vector3_array* p_array)
+ public static unsafe Vector3[] ConvertNativePackedVector3ArrayToSystemArray(godot_packed_vector3_array p_array)
{
- Vector3* buffer = (*p_array)._ptr;
- int size = (*p_array).Size;
+ Vector3* buffer = p_array.Buffer;
+ int size = p_array.Size;
+ if (size == 0)
+ return Array.Empty<Vector3>();
int sizeInBytes = size * sizeof(Vector3);
var array = new Vector3[size];
fixed (Vector3* dest = array)
@@ -1324,7 +1336,8 @@ namespace Godot.NativeInterop
return array;
}
- public static unsafe godot_packed_vector3_array mono_array_to_PackedVector3Array(Span<Vector3> p_array)
+ public static unsafe godot_packed_vector3_array ConvertSystemArrayToNativePackedVector3Array(
+ Span<Vector3> p_array)
{
if (p_array.IsEmpty)
return new godot_packed_vector3_array();
@@ -1334,10 +1347,12 @@ namespace Godot.NativeInterop
// PackedColorArray
- public static unsafe Color[] PackedColorArray_to_mono_array(godot_packed_color_array* p_array)
+ public static unsafe Color[] ConvertNativePackedColorArrayToSystemArray(godot_packed_color_array p_array)
{
- Color* buffer = (*p_array)._ptr;
- int size = (*p_array).Size;
+ Color* buffer = p_array.Buffer;
+ int size = p_array.Size;
+ if (size == 0)
+ return Array.Empty<Color>();
int sizeInBytes = size * sizeof(Color);
var array = new Color[size];
fixed (Color* dest = array)
@@ -1345,7 +1360,7 @@ namespace Godot.NativeInterop
return array;
}
- public static unsafe godot_packed_color_array mono_array_to_PackedColorArray(Span<Color> p_array)
+ public static unsafe godot_packed_color_array ConvertSystemArrayToNativePackedColorArray(Span<Color> p_array)
{
if (p_array.IsEmpty)
return new godot_packed_color_array();
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs
index 8bc785f375..f1cccfed0a 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs
@@ -1,15 +1,23 @@
using System;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
// ReSharper disable InconsistentNaming
namespace Godot.NativeInterop
{
-#if !NET
- // This improves P/Invoke performance.
- // The attribute is not available with .NET Core and it's not needed there.
- [System.Security.SuppressUnmanagedCodeSecurity]
-#endif
+ /*
+ * TODO:
+ * P/Invoke pins by-ref parameters in case the managed memory is moved.
+ * That's not needed here since we use "ref structs" which are stack-only.
+ * Unfortunately, the runtime is not smart enough and pins them anyway.
+ * We want to avoid pinning, so we must wrap these DllImports in methods
+ * that reinterpret refs and pointers with CustomUnsafe.AsPointer/AsRef.
+ * I wish such unnecessary boilerplate wasn't needed...
+ */
+
+ [SuppressMessage("Interoperability", "CA1401",
+ MessageId = "P/Invokes should not be visible" /* Meh. What are you gonna do about it? */)]
public static unsafe partial class NativeFuncs
{
private const string GodotDllName = "__Internal";
@@ -17,15 +25,15 @@ namespace Godot.NativeInterop
// Custom functions
[DllImport(GodotDllName)]
- public static extern IntPtr godotsharp_method_bind_get_method(ref godot_string_name p_classname,
+ public static extern IntPtr godotsharp_method_bind_get_method(in godot_string_name p_classname,
char* p_methodname);
[DllImport(GodotDllName)]
public static extern delegate* unmanaged<IntPtr> godotsharp_get_class_constructor(
- ref godot_string_name p_classname);
+ in godot_string_name p_classname);
[DllImport(GodotDllName)]
- public static extern IntPtr godotsharp_engine_get_singleton(godot_string* p_name);
+ public static extern IntPtr godotsharp_engine_get_singleton(in godot_string p_name);
[DllImport(GodotDllName)]
internal static extern void godotsharp_internal_object_disposed(IntPtr ptr);
@@ -35,61 +43,64 @@ namespace Godot.NativeInterop
[DllImport(GodotDllName)]
internal static extern void godotsharp_internal_object_connect_event_signal(IntPtr obj,
- godot_string_name* eventSignal);
+ in godot_string_name eventSignal);
[DllImport(GodotDllName)]
internal static extern Error godotsharp_internal_signal_awaiter_connect(IntPtr source,
- ref godot_string_name signal,
+ in godot_string_name signal,
IntPtr target, IntPtr awaiterHandlePtr);
[DllImport(GodotDllName)]
- public static extern void godotsharp_internal_tie_native_managed_to_unmanaged(IntPtr gcHandleIntPtr,
- IntPtr unmanaged, godot_string_name* nativeName, godot_bool refCounted);
+ internal static extern void godotsharp_internal_tie_native_managed_to_unmanaged(IntPtr gcHandleIntPtr,
+ IntPtr unmanaged, in godot_string_name nativeName, godot_bool refCounted);
[DllImport(GodotDllName)]
- public static extern void godotsharp_internal_tie_user_managed_to_unmanaged(IntPtr gcHandleIntPtr,
+ internal static extern void godotsharp_internal_tie_user_managed_to_unmanaged(IntPtr gcHandleIntPtr,
IntPtr unmanaged, IntPtr scriptPtr, godot_bool refCounted);
[DllImport(GodotDllName)]
- public static extern void godotsharp_internal_tie_managed_to_unmanaged_with_pre_setup(
+ internal static extern void godotsharp_internal_tie_managed_to_unmanaged_with_pre_setup(
IntPtr gcHandleIntPtr, IntPtr unmanaged);
[DllImport(GodotDllName)]
- public static extern IntPtr godotsharp_internal_unmanaged_get_script_instance_managed(IntPtr p_unmanaged,
- godot_bool* r_has_cs_script_instance);
+ internal static extern IntPtr godotsharp_internal_unmanaged_get_script_instance_managed(IntPtr p_unmanaged,
+ out godot_bool r_has_cs_script_instance);
[DllImport(GodotDllName)]
- public static extern IntPtr godotsharp_internal_unmanaged_get_instance_binding_managed(IntPtr p_unmanaged);
+ internal static extern IntPtr godotsharp_internal_unmanaged_get_instance_binding_managed(IntPtr p_unmanaged);
[DllImport(GodotDllName)]
- public static extern IntPtr godotsharp_internal_unmanaged_instance_binding_create_managed(IntPtr p_unmanaged,
+ internal static extern IntPtr godotsharp_internal_unmanaged_instance_binding_create_managed(IntPtr p_unmanaged,
IntPtr oldGCHandlePtr);
[DllImport(GodotDllName)]
- public static extern IntPtr godotsharp_internal_new_csharp_script();
+ internal static extern IntPtr godotsharp_internal_new_csharp_script();
[DllImport(GodotDllName)]
- public static extern void godotsharp_array_filter_godot_objects_by_native(godot_string_name* p_native_name,
- godot_array* p_input, godot_array* r_output);
+ internal static extern void godotsharp_array_filter_godot_objects_by_native(in godot_string_name p_native_name,
+ in godot_array p_input, out godot_array r_output);
[DllImport(GodotDllName)]
- public static extern void godotsharp_array_filter_godot_objects_by_non_native(godot_array* p_input,
- godot_array* r_output);
+ internal static extern void godotsharp_array_filter_godot_objects_by_non_native(in godot_array p_input,
+ out godot_array r_output);
[DllImport(GodotDllName)]
public static extern void godotsharp_ref_destroy(ref godot_ref p_instance);
[DllImport(GodotDllName)]
- public static extern void godotsharp_string_name_new_from_string(godot_string_name* dest, godot_string* name);
+ public static extern void godotsharp_string_name_new_from_string(out godot_string_name r_dest,
+ in godot_string p_name);
[DllImport(GodotDllName)]
- public static extern void godotsharp_node_path_new_from_string(godot_node_path* dest, godot_string* name);
+ public static extern void godotsharp_node_path_new_from_string(out godot_node_path r_dest,
+ in godot_string p_name);
[DllImport(GodotDllName)]
- public static extern void godotsharp_string_name_as_string(godot_string* r_dest, godot_string_name* p_name);
+ public static extern void
+ godotsharp_string_name_as_string(out godot_string r_dest, in godot_string_name p_name);
[DllImport(GodotDllName)]
- public static extern void godotsharp_node_path_as_string(godot_string* r_dest, godot_node_path* p_np);
+ public static extern void godotsharp_node_path_as_string(out godot_string r_dest, in godot_node_path p_np);
[DllImport(GodotDllName)]
public static extern godot_packed_byte_array godotsharp_packed_byte_array_new_mem_copy(byte* p_src,
@@ -124,16 +135,24 @@ namespace Godot.NativeInterop
int p_length);
[DllImport(GodotDllName)]
- public static extern void godotsharp_packed_string_array_add(godot_packed_string_array* r_dest,
- godot_string* p_element);
+ public static extern void godotsharp_packed_string_array_add(ref godot_packed_string_array r_dest,
+ in godot_string p_element);
[DllImport(GodotDllName)]
public static extern void godotsharp_callable_new_with_delegate(IntPtr p_delegate_handle,
- godot_callable* r_callable);
+ out godot_callable r_callable);
+
+ [DllImport(GodotDllName)]
+ internal static extern godot_bool godotsharp_callable_get_data_for_marshalling(in godot_callable p_callable,
+ out IntPtr r_delegate_handle, out IntPtr r_object, out godot_string_name r_name);
[DllImport(GodotDllName)]
- public static extern godot_bool godotsharp_callable_get_data_for_marshalling(godot_callable* p_callable,
- IntPtr* r_delegate_handle, IntPtr* r_object, godot_string_name* r_name);
+ internal static extern godot_variant godotsharp_callable_call(in godot_callable p_callable,
+ godot_variant** p_args, int p_arg_count, out godot_variant_call_error p_call_error);
+
+ [DllImport(GodotDllName)]
+ internal static extern void godotsharp_callable_call_deferred(in godot_callable p_callable,
+ godot_variant** p_args, int p_arg_count);
// GDNative functions
@@ -145,219 +164,223 @@ namespace Godot.NativeInterop
[DllImport(GodotDllName)]
public static extern godot_variant godotsharp_method_bind_call(IntPtr p_method_bind, IntPtr p_instance,
- godot_variant** p_args, int p_arg_count, godot_variant_call_error* p_call_error);
+ godot_variant** p_args, int p_arg_count, out godot_variant_call_error p_call_error);
// variant.h
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_string_name(godot_variant* r_dest, godot_string_name* p_s);
+ public static extern void
+ godotsharp_variant_new_string_name(out godot_variant r_dest, in godot_string_name p_s);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_node_path(godot_variant* r_dest, godot_node_path* p_np);
+ public static extern void godotsharp_variant_new_node_path(out godot_variant r_dest, in godot_node_path p_np);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_object(godot_variant* r_dest, IntPtr p_obj);
+ public static extern void godotsharp_variant_new_object(out godot_variant r_dest, IntPtr p_obj);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_transform2d(godot_variant* r_dest, Transform2D* p_t2d);
+ public static extern void godotsharp_variant_new_transform2d(out godot_variant r_dest, in Transform2D p_t2d);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_vector4(godot_variant* r_dest, Vector4* p_vec4);
+ public static extern void godotsharp_variant_new_vector4(out godot_variant r_dest, in Vector4 p_vec4);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_vector4i(godot_variant* r_dest, Vector4i* p_vec4i);
+ public static extern void godotsharp_variant_new_vector4i(out godot_variant r_dest, in Vector4i p_vec4i);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_basis(godot_variant* r_dest, Basis* p_basis);
+ public static extern void godotsharp_variant_new_basis(out godot_variant r_dest, in Basis p_basis);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_transform3d(godot_variant* r_dest, Transform3D* p_trans);
+ public static extern void godotsharp_variant_new_transform3d(out godot_variant r_dest, in Transform3D p_trans);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_projection(godot_variant* r_dest, Projection* p_proj);
+ public static extern void godotsharp_variant_new_projection(out godot_variant r_dest, in Projection p_proj);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_aabb(godot_variant* r_dest, AABB* p_aabb);
+ public static extern void godotsharp_variant_new_aabb(out godot_variant r_dest, in AABB p_aabb);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_dictionary(godot_variant* r_dest, godot_dictionary* p_dict);
+ public static extern void godotsharp_variant_new_dictionary(out godot_variant r_dest,
+ in godot_dictionary p_dict);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_array(godot_variant* r_dest, godot_array* p_arr);
+ public static extern void godotsharp_variant_new_array(out godot_variant r_dest, in godot_array p_arr);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_packed_byte_array(godot_variant* r_dest,
- godot_packed_byte_array* p_pba);
+ public static extern void godotsharp_variant_new_packed_byte_array(out godot_variant r_dest,
+ in godot_packed_byte_array p_pba);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_packed_int32_array(godot_variant* r_dest,
- godot_packed_int32_array* p_pia);
+ public static extern void godotsharp_variant_new_packed_int32_array(out godot_variant r_dest,
+ in godot_packed_int32_array p_pia);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_packed_int64_array(godot_variant* r_dest,
- godot_packed_int64_array* p_pia);
+ public static extern void godotsharp_variant_new_packed_int64_array(out godot_variant r_dest,
+ in godot_packed_int64_array p_pia);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_packed_float32_array(godot_variant* r_dest,
- godot_packed_float32_array* p_pra);
+ public static extern void godotsharp_variant_new_packed_float32_array(out godot_variant r_dest,
+ in godot_packed_float32_array p_pra);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_packed_float64_array(godot_variant* r_dest,
- godot_packed_float64_array* p_pra);
+ public static extern void godotsharp_variant_new_packed_float64_array(out godot_variant r_dest,
+ in godot_packed_float64_array p_pra);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_packed_string_array(godot_variant* r_dest,
- godot_packed_string_array* p_psa);
+ public static extern void godotsharp_variant_new_packed_string_array(out godot_variant r_dest,
+ in godot_packed_string_array p_psa);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_packed_vector2_array(godot_variant* r_dest,
- godot_packed_vector2_array* p_pv2a);
+ public static extern void godotsharp_variant_new_packed_vector2_array(out godot_variant r_dest,
+ in godot_packed_vector2_array p_pv2a);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_packed_vector3_array(godot_variant* r_dest,
- godot_packed_vector3_array* p_pv3a);
+ public static extern void godotsharp_variant_new_packed_vector3_array(out godot_variant r_dest,
+ in godot_packed_vector3_array p_pv3a);
[DllImport(GodotDllName)]
- public static extern void godotsharp_variant_new_packed_color_array(godot_variant* r_dest,
- godot_packed_color_array* p_pca);
+ public static extern void godotsharp_variant_new_packed_color_array(out godot_variant r_dest,
+ in godot_packed_color_array p_pca);
[DllImport(GodotDllName)]
- public static extern godot_bool godotsharp_variant_as_bool(godot_variant* p_self);
+ public static extern godot_bool godotsharp_variant_as_bool(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Int64 godotsharp_variant_as_int(godot_variant* p_self);
+ public static extern Int64 godotsharp_variant_as_int(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern double godotsharp_variant_as_float(godot_variant* p_self);
+ public static extern double godotsharp_variant_as_float(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern godot_string godotsharp_variant_as_string(godot_variant* p_self);
+ public static extern godot_string godotsharp_variant_as_string(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Vector2 godotsharp_variant_as_vector2(godot_variant* p_self);
+ public static extern Vector2 godotsharp_variant_as_vector2(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Vector2i godotsharp_variant_as_vector2i(godot_variant* p_self);
+ public static extern Vector2i godotsharp_variant_as_vector2i(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Rect2 godotsharp_variant_as_rect2(godot_variant* p_self);
+ public static extern Rect2 godotsharp_variant_as_rect2(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Rect2i godotsharp_variant_as_rect2i(godot_variant* p_self);
+ public static extern Rect2i godotsharp_variant_as_rect2i(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Vector3 godotsharp_variant_as_vector3(godot_variant* p_self);
+ public static extern Vector3 godotsharp_variant_as_vector3(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Vector3i godotsharp_variant_as_vector3i(godot_variant* p_self);
+ public static extern Vector3i godotsharp_variant_as_vector3i(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Transform2D godotsharp_variant_as_transform2d(godot_variant* p_self);
+ public static extern Transform2D godotsharp_variant_as_transform2d(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Vector4 godotsharp_variant_as_vector4(godot_variant* p_self);
+ public static extern Vector4 godotsharp_variant_as_vector4(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Vector4i godotsharp_variant_as_vector4i(godot_variant* p_self);
+ public static extern Vector4i godotsharp_variant_as_vector4i(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Plane godotsharp_variant_as_plane(godot_variant* p_self);
+ public static extern Plane godotsharp_variant_as_plane(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Quaternion godotsharp_variant_as_quaternion(godot_variant* p_self);
+ public static extern Quaternion godotsharp_variant_as_quaternion(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern AABB godotsharp_variant_as_aabb(godot_variant* p_self);
+ public static extern AABB godotsharp_variant_as_aabb(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Basis godotsharp_variant_as_basis(godot_variant* p_self);
+ public static extern Basis godotsharp_variant_as_basis(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Transform3D godotsharp_variant_as_transform3d(godot_variant* p_self);
+ public static extern Transform3D godotsharp_variant_as_transform3d(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Projection godotsharp_variant_as_projection(godot_variant* p_self);
+ public static extern Projection godotsharp_variant_as_projection(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern Color godotsharp_variant_as_color(godot_variant* p_self);
+ public static extern Color godotsharp_variant_as_color(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern godot_string_name godotsharp_variant_as_string_name(godot_variant* p_self);
+ public static extern godot_string_name godotsharp_variant_as_string_name(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern godot_node_path godotsharp_variant_as_node_path(godot_variant* p_self);
+ public static extern godot_node_path godotsharp_variant_as_node_path(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern RID godotsharp_variant_as_rid(godot_variant* p_self);
+ public static extern RID godotsharp_variant_as_rid(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern godot_callable godotsharp_variant_as_callable(godot_variant* p_self);
+ public static extern godot_callable godotsharp_variant_as_callable(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern godot_signal godotsharp_variant_as_signal(godot_variant* p_self);
+ public static extern godot_signal godotsharp_variant_as_signal(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern godot_dictionary godotsharp_variant_as_dictionary(godot_variant* p_self);
+ public static extern godot_dictionary godotsharp_variant_as_dictionary(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern godot_array godotsharp_variant_as_array(godot_variant* p_self);
+ public static extern godot_array godotsharp_variant_as_array(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern godot_packed_byte_array godotsharp_variant_as_packed_byte_array(godot_variant* p_self);
+ public static extern godot_packed_byte_array godotsharp_variant_as_packed_byte_array(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern godot_packed_int32_array godotsharp_variant_as_packed_int32_array(godot_variant* p_self);
+ public static extern godot_packed_int32_array godotsharp_variant_as_packed_int32_array(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern godot_packed_int64_array godotsharp_variant_as_packed_int64_array(godot_variant* p_self);
+ public static extern godot_packed_int64_array godotsharp_variant_as_packed_int64_array(in godot_variant p_self);
[DllImport(GodotDllName)]
public static extern godot_packed_float32_array godotsharp_variant_as_packed_float32_array(
- godot_variant* p_self);
+ in godot_variant p_self);
[DllImport(GodotDllName)]
public static extern godot_packed_float64_array godotsharp_variant_as_packed_float64_array(
- godot_variant* p_self);
+ in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern godot_packed_string_array godotsharp_variant_as_packed_string_array(godot_variant* p_self);
+ public static extern godot_packed_string_array godotsharp_variant_as_packed_string_array(
+ in godot_variant p_self);
[DllImport(GodotDllName)]
public static extern godot_packed_vector2_array godotsharp_variant_as_packed_vector2_array(
- godot_variant* p_self);
+ in godot_variant p_self);
[DllImport(GodotDllName)]
public static extern godot_packed_vector3_array godotsharp_variant_as_packed_vector3_array(
- godot_variant* p_self);
+ in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern godot_packed_color_array godotsharp_variant_as_packed_color_array(godot_variant* p_self);
+ public static extern godot_packed_color_array godotsharp_variant_as_packed_color_array(in godot_variant p_self);
[DllImport(GodotDllName)]
- public static extern godot_bool godotsharp_variant_equals(godot_variant* p_a, godot_variant* p_b);
+ public static extern godot_bool godotsharp_variant_equals(in godot_variant p_a, in godot_variant p_b);
// string.h
[DllImport(GodotDllName)]
- public static extern void godotsharp_string_new_with_utf16_chars(godot_string* r_dest, char* p_contents);
+ public static extern void godotsharp_string_new_with_utf16_chars(out godot_string r_dest, char* p_contents);
// string_name.h
[DllImport(GodotDllName)]
- public static extern void godotsharp_string_name_new_copy(godot_string_name* r_dest, godot_string_name* p_src);
+ public static extern void godotsharp_string_name_new_copy(out godot_string_name r_dest,
+ in godot_string_name p_src);
// node_path.h
[DllImport(GodotDllName)]
- public static extern void godotsharp_node_path_new_copy(godot_node_path* r_dest, godot_node_path* p_src);
+ public static extern void godotsharp_node_path_new_copy(out godot_node_path r_dest, in godot_node_path p_src);
// array.h
[DllImport(GodotDllName)]
- public static extern void godotsharp_array_new(godot_array* p_self);
+ public static extern void godotsharp_array_new(out godot_array r_dest);
[DllImport(GodotDllName)]
- public static extern void godotsharp_array_new_copy(godot_array* r_dest, godot_array* p_src);
+ public static extern void godotsharp_array_new_copy(out godot_array r_dest, in godot_array p_src);
[DllImport(GodotDllName)]
public static extern godot_variant* godotsharp_array_ptrw(ref godot_array p_self);
@@ -365,10 +388,11 @@ namespace Godot.NativeInterop
// dictionary.h
[DllImport(GodotDllName)]
- public static extern void godotsharp_dictionary_new(godot_dictionary* p_self);
+ public static extern void godotsharp_dictionary_new(out godot_dictionary r_dest);
[DllImport(GodotDllName)]
- public static extern void godotsharp_dictionary_new_copy(godot_dictionary* r_dest, godot_dictionary* p_src);
+ public static extern void godotsharp_dictionary_new_copy(out godot_dictionary r_dest,
+ in godot_dictionary p_src);
// destroy functions
@@ -426,17 +450,17 @@ namespace Godot.NativeInterop
// Array
[DllImport(GodotDllName)]
- public static extern int godotsharp_array_add(ref godot_array p_self, godot_variant* p_item);
+ public static extern int godotsharp_array_add(ref godot_array p_self, in godot_variant p_item);
[DllImport(GodotDllName)]
public static extern void
godotsharp_array_duplicate(ref godot_array p_self, godot_bool p_deep, out godot_array r_dest);
[DllImport(GodotDllName)]
- public static extern int godotsharp_array_index_of(ref godot_array p_self, godot_variant* p_item);
+ public static extern int godotsharp_array_index_of(ref godot_array p_self, in godot_variant p_item);
[DllImport(GodotDllName)]
- public static extern void godotsharp_array_insert(ref godot_array p_self, int p_index, godot_variant* p_item);
+ public static extern void godotsharp_array_insert(ref godot_array p_self, int p_index, in godot_variant p_item);
[DllImport(GodotDllName)]
public static extern void godotsharp_array_remove_at(ref godot_array p_self, int p_index);
@@ -448,18 +472,18 @@ namespace Godot.NativeInterop
public static extern Error godotsharp_array_shuffle(ref godot_array p_self);
[DllImport(GodotDllName)]
- public static extern void godotsharp_array_to_string(ref godot_array p_self, godot_string* r_str);
+ public static extern void godotsharp_array_to_string(ref godot_array p_self, out godot_string r_str);
// Dictionary
[DllImport(GodotDllName)]
public static extern godot_bool godotsharp_dictionary_try_get_value(ref godot_dictionary p_self,
- godot_variant* p_key,
+ in godot_variant p_key,
out godot_variant r_value);
[DllImport(GodotDllName)]
- public static extern void godotsharp_dictionary_set_value(ref godot_dictionary p_self, godot_variant* p_key,
- godot_variant* p_value);
+ public static extern void godotsharp_dictionary_set_value(ref godot_dictionary p_self, in godot_variant p_key,
+ in godot_variant p_value);
[DllImport(GodotDllName)]
public static extern void godotsharp_dictionary_keys(ref godot_dictionary p_self, out godot_array r_dest);
@@ -475,15 +499,15 @@ namespace Godot.NativeInterop
out godot_variant r_key, out godot_variant r_value);
[DllImport(GodotDllName)]
- public static extern void godotsharp_dictionary_add(ref godot_dictionary p_self, godot_variant* p_key,
- godot_variant* p_value);
+ public static extern void godotsharp_dictionary_add(ref godot_dictionary p_self, in godot_variant p_key,
+ in godot_variant p_value);
[DllImport(GodotDllName)]
public static extern void godotsharp_dictionary_clear(ref godot_dictionary p_self);
[DllImport(GodotDllName)]
public static extern godot_bool godotsharp_dictionary_contains_key(ref godot_dictionary p_self,
- godot_variant* p_key);
+ in godot_variant p_key);
[DllImport(GodotDllName)]
public static extern void godotsharp_dictionary_duplicate(ref godot_dictionary p_self, godot_bool p_deep,
@@ -491,149 +515,153 @@ namespace Godot.NativeInterop
[DllImport(GodotDllName)]
public static extern godot_bool godotsharp_dictionary_remove_key(ref godot_dictionary p_self,
- godot_variant* p_key);
+ in godot_variant p_key);
[DllImport(GodotDllName)]
- public static extern void godotsharp_dictionary_to_string(ref godot_dictionary p_self, godot_string* r_str);
+ public static extern void godotsharp_dictionary_to_string(ref godot_dictionary p_self, out godot_string r_str);
// StringExtensions
[DllImport(GodotDllName)]
- public static extern void godotsharp_string_md5_buffer(godot_string* p_self,
- godot_packed_byte_array* r_md5_buffer);
+ public static extern void godotsharp_string_md5_buffer(in godot_string p_self,
+ out godot_packed_byte_array r_md5_buffer);
[DllImport(GodotDllName)]
- public static extern void godotsharp_string_md5_text(godot_string* p_self, godot_string* r_md5_text);
+ public static extern void godotsharp_string_md5_text(in godot_string p_self, out godot_string r_md5_text);
[DllImport(GodotDllName)]
- public static extern int godotsharp_string_rfind(godot_string* p_self, godot_string* p_what, int p_from);
+ public static extern int godotsharp_string_rfind(in godot_string p_self, in godot_string p_what, int p_from);
[DllImport(GodotDllName)]
- public static extern int godotsharp_string_rfindn(godot_string* p_self, godot_string* p_what, int p_from);
+ public static extern int godotsharp_string_rfindn(in godot_string p_self, in godot_string p_what, int p_from);
[DllImport(GodotDllName)]
- public static extern void godotsharp_string_sha256_buffer(godot_string* p_self,
- godot_packed_byte_array* r_sha256_buffer);
+ public static extern void godotsharp_string_sha256_buffer(in godot_string p_self,
+ out godot_packed_byte_array r_sha256_buffer);
[DllImport(GodotDllName)]
- public static extern void godotsharp_string_sha256_text(godot_string* p_self, godot_string* r_sha256_text);
+ public static extern void godotsharp_string_sha256_text(in godot_string p_self,
+ out godot_string r_sha256_text);
[DllImport(GodotDllName)]
- public static extern void godotsharp_string_simplify_path(godot_string* p_self, godot_string* r_simplified_path);
+ public static extern void godotsharp_string_simplify_path(in godot_string p_self,
+ out godot_string r_simplified_path);
// NodePath
[DllImport(GodotDllName)]
- public static extern void godotsharp_node_path_get_as_property_path(ref godot_node_path p_self,
+ public static extern void godotsharp_node_path_get_as_property_path(in godot_node_path p_self,
ref godot_node_path r_dest);
[DllImport(GodotDllName)]
- public static extern void godotsharp_node_path_get_concatenated_names(ref godot_node_path p_self,
- godot_string* r_names);
+ public static extern void godotsharp_node_path_get_concatenated_names(in godot_node_path p_self,
+ out godot_string r_names);
[DllImport(GodotDllName)]
- public static extern void godotsharp_node_path_get_concatenated_subnames(ref godot_node_path p_self,
- godot_string* r_subnames);
+ public static extern void godotsharp_node_path_get_concatenated_subnames(in godot_node_path p_self,
+ out godot_string r_subnames);
[DllImport(GodotDllName)]
- public static extern void godotsharp_node_path_get_name(ref godot_node_path p_self, int p_idx,
- godot_string* r_name);
+ public static extern void godotsharp_node_path_get_name(in godot_node_path p_self, int p_idx,
+ out godot_string r_name);
[DllImport(GodotDllName)]
- public static extern int godotsharp_node_path_get_name_count(ref godot_node_path p_self);
+ public static extern int godotsharp_node_path_get_name_count(in godot_node_path p_self);
[DllImport(GodotDllName)]
- public static extern void godotsharp_node_path_get_subname(ref godot_node_path p_self, int p_idx,
- godot_string* r_subname);
+ public static extern void godotsharp_node_path_get_subname(in godot_node_path p_self, int p_idx,
+ out godot_string r_subname);
[DllImport(GodotDllName)]
- public static extern int godotsharp_node_path_get_subname_count(ref godot_node_path p_self);
+ public static extern int godotsharp_node_path_get_subname_count(in godot_node_path p_self);
[DllImport(GodotDllName)]
- public static extern godot_bool godotsharp_node_path_is_absolute(ref godot_node_path p_self);
+ public static extern godot_bool godotsharp_node_path_is_absolute(in godot_node_path p_self);
// GD, etc
[DllImport(GodotDllName)]
- public static extern void godotsharp_bytes2var(godot_packed_byte_array* p_bytes, godot_bool p_allow_objects,
- godot_variant* r_ret);
+ internal static extern void godotsharp_bytes2var(in godot_packed_byte_array p_bytes,
+ godot_bool p_allow_objects,
+ out godot_variant r_ret);
[DllImport(GodotDllName)]
- public static extern void godotsharp_convert(godot_variant* p_what, int p_type, godot_variant* r_ret);
+ internal static extern void godotsharp_convert(in godot_variant p_what, int p_type,
+ out godot_variant r_ret);
[DllImport(GodotDllName)]
- public static extern int godotsharp_hash(godot_variant* var);
+ internal static extern int godotsharp_hash(in godot_variant p_var);
[DllImport(GodotDllName)]
- public static extern IntPtr godotsharp_instance_from_id(ulong instanceId);
+ internal static extern IntPtr godotsharp_instance_from_id(ulong p_instance_id);
[DllImport(GodotDllName)]
- public static extern void godotsharp_print(godot_string* p_what);
+ internal static extern void godotsharp_print(in godot_string p_what);
[DllImport(GodotDllName)]
- public static extern void godotsharp_print_rich(godot_string* p_what);
+ public static extern void godotsharp_print_rich(in godot_string p_what);
[DllImport(GodotDllName)]
- public static extern void godotsharp_printerr(godot_string* p_what);
+ internal static extern void godotsharp_printerr(in godot_string p_what);
[DllImport(GodotDllName)]
- public static extern void godotsharp_printraw(godot_string* p_what);
+ internal static extern void godotsharp_printraw(in godot_string p_what);
[DllImport(GodotDllName)]
- public static extern void godotsharp_prints(godot_string* p_what);
+ internal static extern void godotsharp_prints(in godot_string p_what);
[DllImport(GodotDllName)]
- public static extern void godotsharp_printt(godot_string* p_what);
+ internal static extern void godotsharp_printt(in godot_string p_what);
[DllImport(GodotDllName)]
- public static extern float godotsharp_randf();
+ internal static extern float godotsharp_randf();
[DllImport(GodotDllName)]
- public static extern uint godotsharp_randi();
+ internal static extern uint godotsharp_randi();
[DllImport(GodotDllName)]
- public static extern void godotsharp_randomize();
+ internal static extern void godotsharp_randomize();
[DllImport(GodotDllName)]
- public static extern double godotsharp_randf_range(double from, double to);
+ internal static extern double godotsharp_randf_range(double from, double to);
[DllImport(GodotDllName)]
- public static extern double godotsharp_randfn(double mean, double deviation);
+ internal static extern double godotsharp_randfn(double mean, double deviation);
[DllImport(GodotDllName)]
- public static extern int godotsharp_randi_range(int from, int to);
+ internal static extern int godotsharp_randi_range(int from, int to);
[DllImport(GodotDllName)]
- public static extern uint godotsharp_rand_from_seed(ulong seed, out ulong newSeed);
+ internal static extern uint godotsharp_rand_from_seed(ulong seed, out ulong newSeed);
[DllImport(GodotDllName)]
- public static extern void godotsharp_seed(ulong seed);
+ internal static extern void godotsharp_seed(ulong seed);
[DllImport(GodotDllName)]
- public static extern void godotsharp_weakref(IntPtr obj, godot_ref* r_weak_ref);
+ internal static extern void godotsharp_weakref(IntPtr p_obj, out godot_ref r_weak_ref);
[DllImport(GodotDllName)]
- public static extern string godotsharp_str(godot_array* p_what, godot_string* r_ret);
+ internal static extern void godotsharp_str(in godot_array p_what, out godot_string r_ret);
[DllImport(GodotDllName)]
- public static extern void godotsharp_str2var(godot_string* p_str, godot_variant* r_ret);
+ internal static extern void godotsharp_str2var(in godot_string p_str, out godot_variant r_ret);
[DllImport(GodotDllName)]
- public static extern void godotsharp_var2bytes(godot_variant* what, godot_bool fullObjects,
- godot_packed_byte_array* bytes);
+ internal static extern void godotsharp_var2bytes(in godot_variant p_what, godot_bool p_full_objects,
+ out godot_packed_byte_array r_bytes);
[DllImport(GodotDllName)]
- public static extern void godotsharp_var2str(godot_variant* var, godot_string* r_ret);
+ internal static extern void godotsharp_var2str(in godot_variant p_var, out godot_string r_ret);
[DllImport(GodotDllName)]
- public static extern void godotsharp_pusherror(godot_string* type);
+ internal static extern void godotsharp_pusherror(in godot_string p_str);
[DllImport(GodotDllName)]
- public static extern void godotsharp_pushwarning(godot_string* type);
+ internal static extern void godotsharp_pushwarning(in godot_string p_str);
// Object
[DllImport(GodotDllName)]
- public static extern string godotsharp_object_to_string(IntPtr ptr, godot_string* r_str);
+ public static extern void godotsharp_object_to_string(IntPtr ptr, out godot_string r_str);
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.extended.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.extended.cs
index 089883c7e8..0c49660cf0 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.extended.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.extended.cs
@@ -1,83 +1,60 @@
-using System;
-using System.Runtime.CompilerServices;
-
// ReSharper disable InconsistentNaming
namespace Godot.NativeInterop
{
- public static unsafe partial class NativeFuncs
+ public static partial class NativeFuncs
{
- public static godot_string_name godotsharp_string_name_new_copy(godot_string_name* src)
+ public static godot_string_name godotsharp_string_name_new_copy(in godot_string_name src)
{
- godot_string_name ret;
- godotsharp_string_name_new_copy(&ret, src);
+ if (src.IsEmpty)
+ return default;
+ godotsharp_string_name_new_copy(out godot_string_name ret, src);
return ret;
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static godot_string_name godotsharp_string_name_new_copy(godot_string_name src)
- => godotsharp_string_name_new_copy(&src);
-
- public static godot_node_path godotsharp_node_path_new_copy(godot_node_path* src)
+ public static godot_node_path godotsharp_node_path_new_copy(in godot_node_path src)
{
- godot_node_path ret;
- godotsharp_node_path_new_copy(&ret, src);
+ if (src.IsEmpty)
+ return default;
+ godotsharp_node_path_new_copy(out godot_node_path ret, src);
return ret;
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static godot_node_path godotsharp_node_path_new_copy(godot_node_path src)
- => godotsharp_node_path_new_copy(&src);
-
public static godot_array godotsharp_array_new()
{
- godot_array ret;
- godotsharp_array_new(&ret);
+ godotsharp_array_new(out godot_array ret);
return ret;
}
- public static godot_array godotsharp_array_new_copy(godot_array* src)
+ public static godot_array godotsharp_array_new_copy(in godot_array src)
{
- godot_array ret;
- godotsharp_array_new_copy(&ret, src);
+ godotsharp_array_new_copy(out godot_array ret, src);
return ret;
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static godot_array godotsharp_array_new_copy(godot_array src)
- => godotsharp_array_new_copy(&src);
-
public static godot_dictionary godotsharp_dictionary_new()
{
- godot_dictionary ret;
- godotsharp_dictionary_new(&ret);
+ godotsharp_dictionary_new(out godot_dictionary ret);
return ret;
}
- public static godot_dictionary godotsharp_dictionary_new_copy(godot_dictionary* src)
+ public static godot_dictionary godotsharp_dictionary_new_copy(in godot_dictionary src)
{
- godot_dictionary ret;
- godotsharp_dictionary_new_copy(&ret, src);
+ godotsharp_dictionary_new_copy(out godot_dictionary ret, src);
return ret;
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static godot_dictionary godotsharp_dictionary_new_copy(godot_dictionary src)
- => godotsharp_dictionary_new_copy(&src);
-
public static godot_string_name godotsharp_string_name_new_from_string(string name)
{
- godot_string_name ret;
- using godot_string src = Marshaling.mono_string_to_godot(name);
- godotsharp_string_name_new_from_string(&ret, &src);
+ using godot_string src = Marshaling.ConvertStringToNative(name);
+ godotsharp_string_name_new_from_string(out godot_string_name ret, src);
return ret;
}
public static godot_node_path godotsharp_node_path_new_from_string(string name)
{
- godot_node_path ret;
- using godot_string src = Marshaling.mono_string_to_godot(name);
- godotsharp_node_path_new_from_string(&ret, &src);
+ using godot_string src = Marshaling.ConvertStringToNative(name);
+ godotsharp_node_path_new_from_string(out godot_node_path ret, src);
return ret;
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeVariantPtrArgs.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeVariantPtrArgs.cs
new file mode 100644
index 0000000000..422df74c23
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeVariantPtrArgs.cs
@@ -0,0 +1,20 @@
+using System.Runtime.CompilerServices;
+
+namespace Godot.NativeInterop
+{
+ // Our source generators will add trampolines methods that access variant arguments.
+ // This struct makes that possible without having to enable `AllowUnsafeBlocks` in game projects.
+
+ public unsafe ref struct NativeVariantPtrArgs
+ {
+ private godot_variant** _args;
+
+ internal NativeVariantPtrArgs(godot_variant** args) => _args = args;
+
+ public ref godot_variant this[int index]
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => ref *_args[index];
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantSpanHelpers.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantSpanHelpers.cs
index 2814f9d506..46f31bbf4e 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantSpanHelpers.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantSpanHelpers.cs
@@ -2,13 +2,13 @@ using System;
namespace Godot.NativeInterop
{
- internal ref struct VariantSpanDisposer
+ internal readonly ref struct VariantSpanDisposer
{
- private readonly Span<godot_variant> _variantSpan;
+ private readonly Span<godot_variant.movable> _variantSpan;
// IMPORTANT: The span element must be default initialized.
// Make sure call Clear() on the span if it was created with stackalloc.
- public VariantSpanDisposer(Span<godot_variant> variantSpan)
+ public VariantSpanDisposer(Span<godot_variant.movable> variantSpan)
{
_variantSpan = variantSpan;
}
@@ -16,7 +16,7 @@ namespace Godot.NativeInterop
public void Dispose()
{
for (int i = 0; i < _variantSpan.Length; i++)
- _variantSpan[i].Dispose();
+ _variantSpan[i].DangerousSelfRef.Dispose();
}
}
@@ -24,7 +24,7 @@ namespace Godot.NativeInterop
{
// Used to make sure we always initialize the span values to the default,
// as we need that in order to safely dispose all elements after.
- public static Span<godot_variant> Cleared(this Span<godot_variant> span)
+ public static Span<godot_variant.movable> Cleared(this Span<godot_variant.movable> span)
{
span.Clear();
return span;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs
index e52454a2e3..f69cc40314 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs
@@ -1,5 +1,4 @@
using System;
-using System.Runtime.CompilerServices;
// ReSharper disable InconsistentNaming
@@ -8,378 +7,353 @@ namespace Godot.NativeInterop
public static class VariantUtils
{
public static godot_variant CreateFromRID(RID from)
- => new() { _type = Variant.Type.Rid, _data = { _m_rid = from } };
+ => new() { Type = Variant.Type.Rid, RID = from };
public static godot_variant CreateFromBool(bool from)
- => new() { _type = Variant.Type.Bool, _data = { _bool = from.ToGodotBool() } };
+ => new() { Type = Variant.Type.Bool, Bool = from.ToGodotBool() };
public static godot_variant CreateFromInt(long from)
- => new() { _type = Variant.Type.Int, _data = { _int = from } };
+ => new() { Type = Variant.Type.Int, Int = from };
public static godot_variant CreateFromInt(ulong from)
- => new() { _type = Variant.Type.Int, _data = { _int = (long)from } };
+ => new() { Type = Variant.Type.Int, Int = (long)from };
public static godot_variant CreateFromFloat(double from)
- => new() { _type = Variant.Type.Float, _data = { _float = from } };
+ => new() { Type = Variant.Type.Float, Float = from };
public static godot_variant CreateFromVector2(Vector2 from)
- => new() { _type = Variant.Type.Vector2, _data = { _m_vector2 = from } };
+ => new() { Type = Variant.Type.Vector2, Vector2 = from };
public static godot_variant CreateFromVector2i(Vector2i from)
- => new() { _type = Variant.Type.Vector2i, _data = { _m_vector2i = from } };
+ => new() { Type = Variant.Type.Vector2i, Vector2i = from };
public static godot_variant CreateFromVector3(Vector3 from)
- => new() { _type = Variant.Type.Vector3, _data = { _m_vector3 = from } };
+ => new() { Type = Variant.Type.Vector3, Vector3 = from };
public static godot_variant CreateFromVector3i(Vector3i from)
- => new() { _type = Variant.Type.Vector3i, _data = { _m_vector3i = from } };
+ => new() { Type = Variant.Type.Vector3i, Vector3i = from };
public static godot_variant CreateFromRect2(Rect2 from)
- => new() { _type = Variant.Type.Rect2, _data = { _m_rect2 = from } };
+ => new() { Type = Variant.Type.Rect2, Rect2 = from };
public static godot_variant CreateFromRect2i(Rect2i from)
- => new() { _type = Variant.Type.Rect2i, _data = { _m_rect2i = from } };
+ => new() { Type = Variant.Type.Rect2i, Rect2i = from };
public static godot_variant CreateFromQuaternion(Quaternion from)
- => new() { _type = Variant.Type.Quaternion, _data = { _m_quaternion = from } };
+ => new() { Type = Variant.Type.Quaternion, Quaternion = from };
public static godot_variant CreateFromColor(Color from)
- => new() { _type = Variant.Type.Color, _data = { _m_color = from } };
+ => new() { Type = Variant.Type.Color, Color = from };
public static godot_variant CreateFromPlane(Plane from)
- => new() { _type = Variant.Type.Plane, _data = { _m_plane = from } };
+ => new() { Type = Variant.Type.Plane, Plane = from };
- public static unsafe godot_variant CreateFromTransform2D(Transform2D from)
+ public static godot_variant CreateFromTransform2D(Transform2D from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_transform2d(&ret, &from);
+ NativeFuncs.godotsharp_variant_new_transform2d(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromVector4(Vector4 from)
+ public static godot_variant CreateFromVector4(Vector4 from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_vector4(&ret, &from);
+ NativeFuncs.godotsharp_variant_new_vector4(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromVector4i(Vector4i from)
+ public static godot_variant CreateFromVector4i(Vector4i from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_vector4i(&ret, &from);
+ NativeFuncs.godotsharp_variant_new_vector4i(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromBasis(Basis from)
+ public static godot_variant CreateFromBasis(Basis from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_basis(&ret, &from);
+ NativeFuncs.godotsharp_variant_new_basis(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromTransform3D(Transform3D from)
+ public static godot_variant CreateFromTransform3D(Transform3D from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_transform3d(&ret, &from);
+ NativeFuncs.godotsharp_variant_new_transform3d(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromProjection(Projection from)
+ public static godot_variant CreateFromProjection(Projection from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_projection(&ret, &from);
+ NativeFuncs.godotsharp_variant_new_projection(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromAABB(AABB from)
+ public static godot_variant CreateFromAABB(AABB from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_aabb(&ret, &from);
+ NativeFuncs.godotsharp_variant_new_aabb(out godot_variant ret, from);
return ret;
}
// Explicit name to make it very clear
public static godot_variant CreateFromCallableTakingOwnershipOfDisposableValue(godot_callable from)
- => new() { _type = Variant.Type.Callable, _data = { _m_callable = from } };
+ => new() { Type = Variant.Type.Callable, Callable = from };
// Explicit name to make it very clear
public static godot_variant CreateFromSignalTakingOwnershipOfDisposableValue(godot_signal from)
- => new() { _type = Variant.Type.Signal, _data = { _m_signal = from } };
+ => new() { Type = Variant.Type.Signal, Signal = from };
// Explicit name to make it very clear
public static godot_variant CreateFromStringTakingOwnershipOfDisposableValue(godot_string from)
- => new() { _type = Variant.Type.String, _data = { _m_string = from } };
+ => new() { Type = Variant.Type.String, String = from };
- public static unsafe godot_variant CreateFromPackedByteArray(godot_packed_byte_array* from)
+ public static godot_variant CreateFromPackedByteArray(in godot_packed_byte_array from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_packed_byte_array(&ret, from);
+ NativeFuncs.godotsharp_variant_new_packed_byte_array(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromPackedInt32Array(godot_packed_int32_array* from)
+ public static godot_variant CreateFromPackedInt32Array(in godot_packed_int32_array from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_packed_int32_array(&ret, from);
+ NativeFuncs.godotsharp_variant_new_packed_int32_array(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromPackedInt64Array(godot_packed_int64_array* from)
+ public static godot_variant CreateFromPackedInt64Array(in godot_packed_int64_array from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_packed_int64_array(&ret, from);
+ NativeFuncs.godotsharp_variant_new_packed_int64_array(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromPackedFloat32Array(godot_packed_float32_array* from)
+ public static godot_variant CreateFromPackedFloat32Array(in godot_packed_float32_array from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_packed_float32_array(&ret, from);
+ NativeFuncs.godotsharp_variant_new_packed_float32_array(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromPackedFloat64Array(godot_packed_float64_array* from)
+ public static godot_variant CreateFromPackedFloat64Array(in godot_packed_float64_array from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_packed_float64_array(&ret, from);
+ NativeFuncs.godotsharp_variant_new_packed_float64_array(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromPackedStringArray(godot_packed_string_array* from)
+ public static godot_variant CreateFromPackedStringArray(in godot_packed_string_array from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_packed_string_array(&ret, from);
+ NativeFuncs.godotsharp_variant_new_packed_string_array(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromPackedVector2Array(godot_packed_vector2_array* from)
+ public static godot_variant CreateFromPackedVector2Array(in godot_packed_vector2_array from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_packed_vector2_array(&ret, from);
+ NativeFuncs.godotsharp_variant_new_packed_vector2_array(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromPackedVector3Array(godot_packed_vector3_array* from)
+ public static godot_variant CreateFromPackedVector3Array(in godot_packed_vector3_array from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_packed_vector3_array(&ret, from);
+ NativeFuncs.godotsharp_variant_new_packed_vector3_array(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromPackedColorArray(godot_packed_color_array* from)
+ public static godot_variant CreateFromPackedColorArray(in godot_packed_color_array from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_packed_color_array(&ret, from);
+ NativeFuncs.godotsharp_variant_new_packed_color_array(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromArray(godot_array* from)
+ public static godot_variant CreateFromArray(godot_array from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_array(&ret, from);
+ NativeFuncs.godotsharp_variant_new_array(out godot_variant ret, from);
return ret;
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static unsafe godot_variant CreateFromArray(godot_array from)
- => CreateFromArray(&from);
-
- public static unsafe godot_variant CreateFromDictionary(godot_dictionary* from)
+ public static godot_variant CreateFromDictionary(godot_dictionary from)
{
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_dictionary(&ret, from);
+ NativeFuncs.godotsharp_variant_new_dictionary(out godot_variant ret, from);
return ret;
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static unsafe godot_variant CreateFromDictionary(godot_dictionary from)
- => CreateFromDictionary(&from);
-
- public static unsafe godot_variant CreateFromStringName(ref godot_string_name arg1)
+ public static godot_variant CreateFromStringName(godot_string_name from)
{
- godot_variant ret;
- godot_string_name src = arg1;
- NativeFuncs.godotsharp_variant_new_string_name(&ret, &src);
+ NativeFuncs.godotsharp_variant_new_string_name(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromNodePath(ref godot_node_path arg1)
+ public static godot_variant CreateFromNodePath(godot_node_path from)
{
- godot_variant ret;
- godot_node_path src = arg1;
- NativeFuncs.godotsharp_variant_new_node_path(&ret, &src);
+ NativeFuncs.godotsharp_variant_new_node_path(out godot_variant ret, from);
return ret;
}
- public static unsafe godot_variant CreateFromGodotObject(IntPtr from)
+ public static godot_variant CreateFromGodotObject(IntPtr from)
{
if (from == IntPtr.Zero)
return new godot_variant();
- godot_variant ret;
- NativeFuncs.godotsharp_variant_new_object(&ret, from);
+ NativeFuncs.godotsharp_variant_new_object(out godot_variant ret, from);
return ret;
}
// We avoid the internal call if the stored type is the same we want.
- public static unsafe bool ConvertToBool(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Bool ?
- (*p_var)._data._bool.ToBool() :
+ public static bool ConvertToBool(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Bool ?
+ p_var.Bool.ToBool() :
NativeFuncs.godotsharp_variant_as_bool(p_var).ToBool();
- public static unsafe char ConvertToChar(godot_variant* p_var)
- => (char)((*p_var)._type == Variant.Type.Int ?
- (*p_var)._data._int :
+ public static char ConvertToChar(in godot_variant p_var)
+ => (char)(p_var.Type == Variant.Type.Int ?
+ p_var.Int :
NativeFuncs.godotsharp_variant_as_int(p_var));
- public static unsafe sbyte ConvertToInt8(godot_variant* p_var)
- => (sbyte)((*p_var)._type == Variant.Type.Int ?
- (*p_var)._data._int :
+ public static sbyte ConvertToInt8(in godot_variant p_var)
+ => (sbyte)(p_var.Type == Variant.Type.Int ?
+ p_var.Int :
NativeFuncs.godotsharp_variant_as_int(p_var));
- public static unsafe Int16 ConvertToInt16(godot_variant* p_var)
- => (Int16)((*p_var)._type == Variant.Type.Int ?
- (*p_var)._data._int :
+ public static Int16 ConvertToInt16(in godot_variant p_var)
+ => (Int16)(p_var.Type == Variant.Type.Int ?
+ p_var.Int :
NativeFuncs.godotsharp_variant_as_int(p_var));
- public static unsafe Int32 ConvertToInt32(godot_variant* p_var)
- => (Int32)((*p_var)._type == Variant.Type.Int ?
- (*p_var)._data._int :
+ public static Int32 ConvertToInt32(in godot_variant p_var)
+ => (Int32)(p_var.Type == Variant.Type.Int ?
+ p_var.Int :
NativeFuncs.godotsharp_variant_as_int(p_var));
- public static unsafe Int64 ConvertToInt64(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Int ? (*p_var)._data._int : NativeFuncs.godotsharp_variant_as_int(p_var);
+ public static Int64 ConvertToInt64(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Int ? p_var.Int : NativeFuncs.godotsharp_variant_as_int(p_var);
- public static unsafe byte ConvertToUInt8(godot_variant* p_var)
- => (byte)((*p_var)._type == Variant.Type.Int ?
- (*p_var)._data._int :
+ public static byte ConvertToUInt8(in godot_variant p_var)
+ => (byte)(p_var.Type == Variant.Type.Int ?
+ p_var.Int :
NativeFuncs.godotsharp_variant_as_int(p_var));
- public static unsafe UInt16 ConvertToUInt16(godot_variant* p_var)
- => (UInt16)((*p_var)._type == Variant.Type.Int ?
- (*p_var)._data._int :
+ public static UInt16 ConvertToUInt16(in godot_variant p_var)
+ => (UInt16)(p_var.Type == Variant.Type.Int ?
+ p_var.Int :
NativeFuncs.godotsharp_variant_as_int(p_var));
- public static unsafe UInt32 ConvertToUInt32(godot_variant* p_var)
- => (UInt32)((*p_var)._type == Variant.Type.Int ?
- (*p_var)._data._int :
+ public static UInt32 ConvertToUInt32(in godot_variant p_var)
+ => (UInt32)(p_var.Type == Variant.Type.Int ?
+ p_var.Int :
NativeFuncs.godotsharp_variant_as_int(p_var));
- public static unsafe UInt64 ConvertToUInt64(godot_variant* p_var)
- => (UInt64)((*p_var)._type == Variant.Type.Int ?
- (*p_var)._data._int :
+ public static UInt64 ConvertToUInt64(in godot_variant p_var)
+ => (UInt64)(p_var.Type == Variant.Type.Int ?
+ p_var.Int :
NativeFuncs.godotsharp_variant_as_int(p_var));
- public static unsafe float ConvertToFloat32(godot_variant* p_var)
- => (float)((*p_var)._type == Variant.Type.Float ?
- (*p_var)._data._float :
+ public static float ConvertToFloat32(in godot_variant p_var)
+ => (float)(p_var.Type == Variant.Type.Float ?
+ p_var.Float :
NativeFuncs.godotsharp_variant_as_float(p_var));
- public static unsafe double ConvertToFloat64(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Float ?
- (*p_var)._data._float :
+ public static double ConvertToFloat64(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Float ?
+ p_var.Float :
NativeFuncs.godotsharp_variant_as_float(p_var);
- public static unsafe Vector2 ConvertToVector2(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Vector2 ?
- (*p_var)._data._m_vector2 :
+ public static Vector2 ConvertToVector2(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Vector2 ?
+ p_var.Vector2 :
NativeFuncs.godotsharp_variant_as_vector2(p_var);
- public static unsafe Vector2i ConvertToVector2i(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Vector2i ?
- (*p_var)._data._m_vector2i :
+ public static Vector2i ConvertToVector2i(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Vector2i ?
+ p_var.Vector2i :
NativeFuncs.godotsharp_variant_as_vector2i(p_var);
- public static unsafe Rect2 ConvertToRect2(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Rect2 ?
- (*p_var)._data._m_rect2 :
+ public static Rect2 ConvertToRect2(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Rect2 ?
+ p_var.Rect2 :
NativeFuncs.godotsharp_variant_as_rect2(p_var);
- public static unsafe Rect2i ConvertToRect2i(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Rect2i ?
- (*p_var)._data._m_rect2i :
+ public static Rect2i ConvertToRect2i(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Rect2i ?
+ p_var.Rect2i :
NativeFuncs.godotsharp_variant_as_rect2i(p_var);
- public static unsafe Transform2D ConvertToTransform2D(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Transform2d ?
- *(*p_var)._data._transform2d :
+ public static unsafe Transform2D ConvertToTransform2D(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Transform2d ?
+ *p_var.Transform2D :
NativeFuncs.godotsharp_variant_as_transform2d(p_var);
- public static unsafe Vector3 ConvertToVector3(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Vector3 ?
- (*p_var)._data._m_vector3 :
+ public static Vector3 ConvertToVector3(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Vector3 ?
+ p_var.Vector3 :
NativeFuncs.godotsharp_variant_as_vector3(p_var);
- public static unsafe Vector3i ConvertToVector3i(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Vector3i ?
- (*p_var)._data._m_vector3i :
+ public static Vector3i ConvertToVector3i(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Vector3i ?
+ p_var.Vector3i :
NativeFuncs.godotsharp_variant_as_vector3i(p_var);
- public static unsafe Vector4 ConvertToVector4(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Vector4 ? *(*p_var)._data._vector4 : NativeFuncs.godotsharp_variant_as_vector4(p_var);
+ public static unsafe Vector4 ConvertToVector4(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Vector4 ?
+ *p_var.Vector4 :
+ NativeFuncs.godotsharp_variant_as_vector4(p_var);
- public static unsafe Vector4i ConvertToVector4i(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Vector4i ? *(*p_var)._data._vector4i : NativeFuncs.godotsharp_variant_as_vector4i(p_var);
+ public static unsafe Vector4i ConvertToVector4i(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Vector4i ?
+ *p_var.Vector4i :
+ NativeFuncs.godotsharp_variant_as_vector4i(p_var);
- public static unsafe Basis ConvertToBasis(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Basis ?
- *(*p_var)._data._basis :
+ public static unsafe Basis ConvertToBasis(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Basis ?
+ *p_var.Basis :
NativeFuncs.godotsharp_variant_as_basis(p_var);
- public static unsafe Quaternion ConvertToQuaternion(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Quaternion ?
- (*p_var)._data._m_quaternion :
+ public static Quaternion ConvertToQuaternion(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Quaternion ?
+ p_var.Quaternion :
NativeFuncs.godotsharp_variant_as_quaternion(p_var);
- public static unsafe Transform3D ConvertToTransform3D(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Transform3d ?
- *(*p_var)._data._transform3d :
+ public static unsafe Transform3D ConvertToTransform3D(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Transform3d ?
+ *p_var.Transform3D :
NativeFuncs.godotsharp_variant_as_transform3d(p_var);
- public static unsafe Projection ConvertToProjection(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Projection ? *(*p_var)._data._projection : NativeFuncs.godotsharp_variant_as_projection(p_var);
+ public static unsafe Projection ConvertToProjection(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Projection ?
+ *p_var.Projection :
+ NativeFuncs.godotsharp_variant_as_projection(p_var);
- public static unsafe AABB ConvertToAABB(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Aabb ?
- *(*p_var)._data._aabb :
+ public static unsafe AABB ConvertToAABB(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Aabb ?
+ *p_var.AABB :
NativeFuncs.godotsharp_variant_as_aabb(p_var);
- public static unsafe Color ConvertToColor(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Color ?
- (*p_var)._data._m_color :
+ public static Color ConvertToColor(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Color ?
+ p_var.Color :
NativeFuncs.godotsharp_variant_as_color(p_var);
- public static unsafe Plane ConvertToPlane(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Plane ?
- (*p_var)._data._m_plane :
+ public static Plane ConvertToPlane(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Plane ?
+ p_var.Plane :
NativeFuncs.godotsharp_variant_as_plane(p_var);
- public static unsafe IntPtr ConvertToGodotObject(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Object ? (*p_var)._data._m_obj_data.obj : IntPtr.Zero;
+ public static IntPtr ConvertToGodotObject(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Object ? p_var.Object : IntPtr.Zero;
- public static unsafe RID ConvertToRID(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Rid ?
- (*p_var)._data._m_rid :
+ public static RID ConvertToRID(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Rid ?
+ p_var.RID :
NativeFuncs.godotsharp_variant_as_rid(p_var);
- public static unsafe godot_string_name ConvertToStringName(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.StringName ?
- NativeFuncs.godotsharp_string_name_new_copy(&(*p_var)._data._m_string_name) :
+ public static godot_string_name ConvertToStringName(in godot_variant p_var)
+ => p_var.Type == Variant.Type.StringName ?
+ NativeFuncs.godotsharp_string_name_new_copy(p_var.StringName) :
NativeFuncs.godotsharp_variant_as_string_name(p_var);
- public static unsafe godot_node_path ConvertToNodePath(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.NodePath ?
- NativeFuncs.godotsharp_node_path_new_copy(&(*p_var)._data._m_node_path) :
+ public static godot_node_path ConvertToNodePath(in godot_variant p_var)
+ => p_var.Type == Variant.Type.NodePath ?
+ NativeFuncs.godotsharp_node_path_new_copy(p_var.NodePath) :
NativeFuncs.godotsharp_variant_as_node_path(p_var);
- public static unsafe godot_array ConvertToArray(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Array ?
- NativeFuncs.godotsharp_array_new_copy(&(*p_var)._data._m_array) :
+ public static godot_array ConvertToArray(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Array ?
+ NativeFuncs.godotsharp_array_new_copy(p_var.Array) :
NativeFuncs.godotsharp_variant_as_array(p_var);
- public static unsafe godot_dictionary ConvertToDictionary(godot_variant* p_var)
- => (*p_var)._type == Variant.Type.Dictionary ?
- NativeFuncs.godotsharp_dictionary_new_copy(&(*p_var)._data._m_dictionary) :
+ public static godot_dictionary ConvertToDictionary(in godot_variant p_var)
+ => p_var.Type == Variant.Type.Dictionary ?
+ NativeFuncs.godotsharp_dictionary_new_copy(p_var.Dictionary) :
NativeFuncs.godotsharp_variant_as_dictionary(p_var);
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
index b18606b47e..d7b736fbcf 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
@@ -1,5 +1,4 @@
using System;
-using System.Runtime.CompilerServices;
using Godot.NativeInterop;
namespace Godot
@@ -42,7 +41,7 @@ namespace Godot
/// </example>
public sealed class NodePath : IDisposable
{
- public godot_node_path NativeValue;
+ internal godot_node_path.movable NativeValue;
~NodePath()
{
@@ -61,12 +60,12 @@ namespace Godot
public void Dispose(bool disposing)
{
// Always dispose `NativeValue` even if disposing is true
- NativeValue.Dispose();
+ NativeValue.DangerousSelfRef.Dispose();
}
private NodePath(godot_node_path nativeValueToOwn)
{
- NativeValue = nativeValueToOwn;
+ NativeValue = (godot_node_path.movable)nativeValueToOwn;
}
// Explicit name to make it very clear
@@ -112,7 +111,7 @@ namespace Godot
public NodePath(string path)
{
if (!string.IsNullOrEmpty(path))
- NativeValue = NativeFuncs.godotsharp_node_path_new_from_string(path);
+ NativeValue = (godot_node_path.movable)NativeFuncs.godotsharp_node_path_new_from_string(path);
}
/// <summary>
@@ -125,22 +124,21 @@ namespace Godot
/// Converts this <see cref="NodePath"/> to a string.
/// </summary>
/// <param name="from">The <see cref="NodePath"/> to convert.</param>
- public static implicit operator string(NodePath from) => from.ToString();
+ public static implicit operator string(NodePath from) => from?.ToString();
/// <summary>
/// Converts this <see cref="NodePath"/> to a string.
/// </summary>
/// <returns>A string representation of this <see cref="NodePath"/>.</returns>
- public override unsafe string ToString()
+ public override string ToString()
{
if (IsEmpty)
return string.Empty;
- godot_string dest;
- godot_node_path src = NativeValue;
- NativeFuncs.godotsharp_node_path_as_string(&dest, &src);
+ var src = (godot_node_path)NativeValue;
+ NativeFuncs.godotsharp_node_path_as_string(out godot_string dest, src);
using (dest)
- return Marshaling.mono_string_from_godot(dest);
+ return Marshaling.ConvertStringToManaged(dest);
}
/// <summary>
@@ -161,7 +159,8 @@ namespace Godot
public NodePath GetAsPropertyPath()
{
godot_node_path propertyPath = default;
- NativeFuncs.godotsharp_node_path_get_as_property_path(ref NativeValue, ref propertyPath);
+ var self = (godot_node_path)NativeValue;
+ NativeFuncs.godotsharp_node_path_get_as_property_path(self, ref propertyPath);
return CreateTakingOwnershipOfDisposableValue(propertyPath);
}
@@ -175,11 +174,12 @@ namespace Godot
/// </code>
/// </example>
/// <returns>The names concatenated with <c>/</c>.</returns>
- public unsafe string GetConcatenatedNames()
+ public string GetConcatenatedNames()
{
- using godot_string names = default;
- NativeFuncs.godotsharp_node_path_get_concatenated_names(ref NativeValue, &names);
- return Marshaling.mono_string_from_godot(names);
+ var self = (godot_node_path)NativeValue;
+ NativeFuncs.godotsharp_node_path_get_concatenated_names(self, out godot_string names);
+ using (names)
+ return Marshaling.ConvertStringToManaged(names);
}
/// <summary>
@@ -193,11 +193,12 @@ namespace Godot
/// </code>
/// </example>
/// <returns>The subnames concatenated with <c>:</c>.</returns>
- public unsafe string GetConcatenatedSubNames()
+ public string GetConcatenatedSubNames()
{
- using godot_string subNames = default;
- NativeFuncs.godotsharp_node_path_get_concatenated_subnames(ref NativeValue, &subNames);
- return Marshaling.mono_string_from_godot(subNames);
+ var self = (godot_node_path)NativeValue;
+ NativeFuncs.godotsharp_node_path_get_concatenated_subnames(self, out godot_string subNames);
+ using (subNames)
+ return Marshaling.ConvertStringToManaged(subNames);
}
/// <summary>
@@ -213,11 +214,12 @@ namespace Godot
/// </example>
/// <param name="idx">The name index.</param>
/// <returns>The name at the given index <paramref name="idx"/>.</returns>
- public unsafe string GetName(int idx)
+ public string GetName(int idx)
{
- using godot_string name = default;
- NativeFuncs.godotsharp_node_path_get_name(ref NativeValue, idx, &name);
- return Marshaling.mono_string_from_godot(name);
+ var self = (godot_node_path)NativeValue;
+ NativeFuncs.godotsharp_node_path_get_name(self, idx, out godot_string name);
+ using (name)
+ return Marshaling.ConvertStringToManaged(name);
}
/// <summary>
@@ -228,7 +230,8 @@ namespace Godot
/// <returns>The number of node names which make up the path.</returns>
public int GetNameCount()
{
- return NativeFuncs.godotsharp_node_path_get_name_count(ref NativeValue);
+ var self = (godot_node_path)NativeValue;
+ return NativeFuncs.godotsharp_node_path_get_name_count(self);
}
/// <summary>
@@ -236,11 +239,12 @@ namespace Godot
/// </summary>
/// <param name="idx">The subname index.</param>
/// <returns>The subname at the given index <paramref name="idx"/>.</returns>
- public unsafe string GetSubName(int idx)
+ public string GetSubName(int idx)
{
- using godot_string subName = default;
- NativeFuncs.godotsharp_node_path_get_subname(ref NativeValue, idx, &subName);
- return Marshaling.mono_string_from_godot(subName);
+ var self = (godot_node_path)NativeValue;
+ NativeFuncs.godotsharp_node_path_get_subname(self, idx, out godot_string subName);
+ using (subName)
+ return Marshaling.ConvertStringToManaged(subName);
}
/// <summary>
@@ -251,7 +255,8 @@ namespace Godot
/// <returns>The number of subnames in the path.</returns>
public int GetSubNameCount()
{
- return NativeFuncs.godotsharp_node_path_get_subname_count(ref NativeValue);
+ var self = (godot_node_path)NativeValue;
+ return NativeFuncs.godotsharp_node_path_get_subname_count(self);
}
/// <summary>
@@ -263,13 +268,14 @@ namespace Godot
/// <returns>If the <see cref="NodePath"/> is an absolute path.</returns>
public bool IsAbsolute()
{
- return NativeFuncs.godotsharp_node_path_is_absolute(ref NativeValue).ToBool();
+ var self = (godot_node_path)NativeValue;
+ return NativeFuncs.godotsharp_node_path_is_absolute(self).ToBool();
}
/// <summary>
/// Returns <see langword="true"/> if the node path is empty.
/// </summary>
/// <returns>If the <see cref="NodePath"/> is empty.</returns>
- public bool IsEmpty => godot_node_path.IsEmpty(in NativeValue);
+ public bool IsEmpty => NativeValue.DangerousSelfRef.IsEmpty;
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs
index 98266ffdfc..5f4dc50c72 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs
@@ -1,7 +1,6 @@
using System;
using System.Linq;
using System.Reflection;
-using System.Runtime.CompilerServices;
using Godot.NativeInterop;
namespace Godot
@@ -47,16 +46,13 @@ namespace Godot
while (top != null && top != native)
{
foreach (var eventSignal in top.GetEvents(
- BindingFlags.DeclaredOnly | BindingFlags.Instance |
- BindingFlags.NonPublic | BindingFlags.Public)
- .Where(ev => ev.GetCustomAttributes().OfType<SignalAttribute>().Any()))
+ BindingFlags.DeclaredOnly | BindingFlags.Instance |
+ BindingFlags.NonPublic | BindingFlags.Public)
+ .Where(ev => ev.GetCustomAttributes().OfType<SignalAttribute>().Any()))
{
- unsafe
- {
- using var eventSignalName = new StringName(eventSignal.Name);
- godot_string_name eventSignalNameAux = eventSignalName.NativeValue;
- NativeFuncs.godotsharp_internal_object_connect_event_signal(NativePtr, &eventSignalNameAux);
- }
+ using var eventSignalName = new StringName(eventSignal.Name);
+ var eventSignalNameSelf = (godot_string_name)eventSignalName.NativeValue;
+ NativeFuncs.godotsharp_internal_object_connect_event_signal(NativePtr, eventSignalNameSelf);
}
top = top.BaseType;
@@ -128,11 +124,11 @@ namespace Godot
/// Converts this <see cref="Object"/> to a string.
/// </summary>
/// <returns>A string representation of this object.</returns>
- public override unsafe string ToString()
+ public override string ToString()
{
- using godot_string str = default;
- NativeFuncs.godotsharp_object_to_string(GetPtr(this), &str);
- return Marshaling.mono_string_from_godot(str);
+ NativeFuncs.godotsharp_object_to_string(GetPtr(this), out godot_string str);
+ using (str)
+ return Marshaling.ConvertStringToManaged(str);
}
/// <summary>
@@ -189,7 +185,7 @@ namespace Godot
return assemblyName.Name == "GodotSharp" || assemblyName.Name == "GodotSharpEditor";
}
- internal unsafe bool InternalGodotScriptCallViaReflection(string method, godot_variant** args, int argCount,
+ internal bool InternalGodotScriptCallViaReflection(string method, NativeVariantPtrArgs args, int argCount,
out godot_variant ret)
{
// Performance is not critical here as this will be replaced with source generators.
@@ -213,13 +209,13 @@ namespace Godot
for (int i = 0; i < paramCount; i++)
{
- invokeParams[i] = Marshaling.variant_to_mono_object_of_type(
+ invokeParams[i] = Marshaling.ConvertVariantToManagedObjectOfType(
args[i], parameters[i].ParameterType);
}
object retObj = methodInfo.Invoke(this, invokeParams);
- ret = Marshaling.mono_object_to_variant(retObj);
+ ret = Marshaling.ConvertManagedObjectToVariant(retObj);
return true;
}
}
@@ -231,7 +227,7 @@ namespace Godot
return false;
}
- internal unsafe bool InternalGodotScriptSetFieldOrPropViaReflection(string name, godot_variant* value)
+ internal bool InternalGodotScriptSetFieldOrPropViaReflection(string name, in godot_variant value)
{
// Performance is not critical here as this will be replaced with source generators.
Type top = GetType();
@@ -245,7 +241,7 @@ namespace Godot
if (fieldInfo != null)
{
- object valueManaged = Marshaling.variant_to_mono_object_of_type(value, fieldInfo.FieldType);
+ object valueManaged = Marshaling.ConvertVariantToManagedObjectOfType(value, fieldInfo.FieldType);
fieldInfo.SetValue(this, valueManaged);
return true;
@@ -257,7 +253,8 @@ namespace Godot
if (propertyInfo != null)
{
- object valueManaged = Marshaling.variant_to_mono_object_of_type(value, propertyInfo.PropertyType);
+ object valueManaged =
+ Marshaling.ConvertVariantToManagedObjectOfType(value, propertyInfo.PropertyType);
propertyInfo.SetValue(this, valueManaged);
return true;
@@ -284,7 +281,7 @@ namespace Godot
if (fieldInfo != null)
{
object valueManaged = fieldInfo.GetValue(this);
- value = Marshaling.mono_object_to_variant(valueManaged);
+ value = Marshaling.ConvertManagedObjectToVariant(valueManaged);
return true;
}
@@ -295,7 +292,7 @@ namespace Godot
if (propertyInfo != null)
{
object valueManaged = propertyInfo.GetValue(this);
- value = Marshaling.mono_object_to_variant(valueManaged);
+ value = Marshaling.ConvertManagedObjectToVariant(valueManaged);
return true;
}
@@ -306,7 +303,7 @@ namespace Godot
return false;
}
- internal unsafe void InternalRaiseEventSignal(godot_string_name* eventSignalName, godot_variant** args,
+ internal unsafe void InternalRaiseEventSignal(in godot_string_name eventSignalName, NativeVariantPtrArgs args,
int argc)
{
// Performance is not critical here as this will be replaced with source generators.
@@ -360,9 +357,9 @@ namespace Godot
var managedArgs = new object[argc];
- for (uint i = 0; i < argc; i++)
+ for (int i = 0; i < argc; i++)
{
- managedArgs[i] = Marshaling.variant_to_mono_object_of_type(
+ managedArgs[i] = Marshaling.ConvertVariantToManagedObjectOfType(
args[i], parameterInfos[i].ParameterType);
}
@@ -379,7 +376,8 @@ namespace Godot
IntPtr methodBind;
fixed (char* methodChars = method)
{
- methodBind = NativeFuncs.godotsharp_method_bind_get_method(ref type.NativeValue, methodChars);
+ var typeSelf = (godot_string_name)type.NativeValue;
+ methodBind = NativeFuncs.godotsharp_method_bind_get_method(typeSelf, methodChars);
}
if (methodBind == IntPtr.Zero)
@@ -391,7 +389,8 @@ namespace Godot
internal static unsafe delegate* unmanaged<IntPtr> ClassDB_get_constructor(StringName type)
{
// for some reason the '??' operator doesn't support 'delegate*'
- var nativeConstructor = NativeFuncs.godotsharp_get_class_constructor(ref type.NativeValue);
+ var typeSelf = (godot_string_name)type.NativeValue;
+ var nativeConstructor = NativeFuncs.godotsharp_get_class_constructor(typeSelf);
if (nativeConstructor == null)
throw new NativeConstructorNotFoundException(type);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
index e38dca414f..369b95c7cb 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
@@ -73,7 +73,7 @@ namespace Godot
case 3:
return w;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
}
}
set
@@ -93,7 +93,7 @@ namespace Godot
w = value;
break;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs
index 62dec81582..c8bf686afa 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs
@@ -8,19 +8,21 @@ namespace Godot
{
private bool _completed;
private object[] _result;
- private Action _action;
+ private Action _continuation;
public SignalAwaiter(Object source, StringName signal, Object target)
{
- NativeFuncs.godotsharp_internal_signal_awaiter_connect(Object.GetPtr(source), ref signal.NativeValue,
+ using godot_string_name signalSrc = NativeFuncs.godotsharp_string_name_new_copy(
+ (godot_string_name)(signal?.NativeValue ?? default));
+ NativeFuncs.godotsharp_internal_signal_awaiter_connect(Object.GetPtr(source), in signalSrc,
Object.GetPtr(target), GCHandle.ToIntPtr(GCHandle.Alloc(this)));
}
public bool IsCompleted => _completed;
- public void OnCompleted(Action action)
+ public void OnCompleted(Action continuation)
{
- this._action = action;
+ _continuation = continuation;
}
public object[] GetResult() => _result;
@@ -48,11 +50,11 @@ namespace Godot
object[] signalArgs = new object[argCount];
for (int i = 0; i < argCount; i++)
- signalArgs[i] = Marshaling.variant_to_mono_object(args[i]);
+ signalArgs[i] = Marshaling.ConvertVariantToManagedObject(*args[i]);
awaiter._result = signalArgs;
- awaiter._action?.Invoke();
+ awaiter._continuation?.Invoke();
}
catch (Exception e)
{
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs
index da01300586..3f50df0a0d 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalInfo.cs
@@ -3,7 +3,7 @@ namespace Godot
/// <summary>
/// Represents a signal defined in an object.
/// </summary>
- public struct SignalInfo
+ public readonly struct SignalInfo
{
private readonly Object _owner;
private readonly StringName _signalName;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
index dfdef81f9e..ce89e134b8 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
@@ -1,12 +1,13 @@
using System;
using System.Collections.Generic;
using System.Globalization;
-using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Text.RegularExpressions;
using Godot.NativeInterop;
+#nullable enable
+
namespace Godot
{
/// <summary>
@@ -1077,12 +1078,12 @@ namespace Godot
/// <seealso cref="MD5Text(string)"/>
/// <param name="instance">The string to hash.</param>
/// <returns>The MD5 hash of the string.</returns>
- public static unsafe byte[] MD5Buffer(this string instance)
+ public static byte[] MD5Buffer(this string instance)
{
- using godot_string instanceStr = Marshaling.mono_string_to_godot(instance);
- using godot_packed_byte_array md5Buffer = default;
- NativeFuncs.godotsharp_string_md5_buffer(&instanceStr, &md5Buffer);
- return Marshaling.PackedByteArray_to_mono_array(&md5Buffer);
+ using godot_string instanceStr = Marshaling.ConvertStringToNative(instance);
+ NativeFuncs.godotsharp_string_md5_buffer(instanceStr, out var md5Buffer);
+ using (md5Buffer)
+ return Marshaling.ConvertNativePackedByteArrayToSystemArray(md5Buffer);
}
/// <summary>
@@ -1091,12 +1092,12 @@ namespace Godot
/// <seealso cref="MD5Buffer(string)"/>
/// <param name="instance">The string to hash.</param>
/// <returns>The MD5 hash of the string.</returns>
- public static unsafe string MD5Text(this string instance)
+ public static string MD5Text(this string instance)
{
- using godot_string instanceStr = Marshaling.mono_string_to_godot(instance);
- using godot_string md5Text = default;
- NativeFuncs.godotsharp_string_md5_text(&instanceStr, &md5Text);
- return Marshaling.mono_string_from_godot(md5Text);
+ using godot_string instanceStr = Marshaling.ConvertStringToNative(instance);
+ NativeFuncs.godotsharp_string_md5_text(instanceStr, out var md5Text);
+ using (md5Text)
+ return Marshaling.ConvertStringToManaged(md5Text);
}
/// <summary>
@@ -1251,11 +1252,11 @@ namespace Godot
/// <param name="what">The substring to search in the string.</param>
/// <param name="from">The position at which to start searching.</param>
/// <returns>The position at which the substring was found, or -1 if not found.</returns>
- public static unsafe int RFind(this string instance, string what, int from = -1)
+ public static int RFind(this string instance, string what, int from = -1)
{
- using godot_string instanceStr = Marshaling.mono_string_to_godot(instance);
- using godot_string whatStr = Marshaling.mono_string_to_godot(instance);
- return NativeFuncs.godotsharp_string_rfind(&instanceStr, &whatStr, from);
+ using godot_string instanceStr = Marshaling.ConvertStringToNative(instance);
+ using godot_string whatStr = Marshaling.ConvertStringToNative(instance);
+ return NativeFuncs.godotsharp_string_rfind(instanceStr, whatStr, from);
}
/// <summary>
@@ -1267,11 +1268,11 @@ namespace Godot
/// <param name="what">The substring to search in the string.</param>
/// <param name="from">The position at which to start searching.</param>
/// <returns>The position at which the substring was found, or -1 if not found.</returns>
- public static unsafe int RFindN(this string instance, string what, int from = -1)
+ public static int RFindN(this string instance, string what, int from = -1)
{
- using godot_string instanceStr = Marshaling.mono_string_to_godot(instance);
- using godot_string whatStr = Marshaling.mono_string_to_godot(instance);
- return NativeFuncs.godotsharp_string_rfindn(&instanceStr, &whatStr, from);
+ using godot_string instanceStr = Marshaling.ConvertStringToNative(instance);
+ using godot_string whatStr = Marshaling.ConvertStringToNative(instance);
+ return NativeFuncs.godotsharp_string_rfindn(instanceStr, whatStr, from);
}
/// <summary>
@@ -1326,12 +1327,12 @@ namespace Godot
/// <seealso cref="SHA256Text(string)"/>
/// <param name="instance">The string to hash.</param>
/// <returns>The SHA-256 hash of the string.</returns>
- public static unsafe byte[] SHA256Buffer(this string instance)
+ public static byte[] SHA256Buffer(this string instance)
{
- using godot_string instanceStr = Marshaling.mono_string_to_godot(instance);
- using godot_packed_byte_array sha256Buffer = default;
- NativeFuncs.godotsharp_string_sha256_buffer(&instanceStr, &sha256Buffer);
- return Marshaling.PackedByteArray_to_mono_array(&sha256Buffer);
+ using godot_string instanceStr = Marshaling.ConvertStringToNative(instance);
+ NativeFuncs.godotsharp_string_sha256_buffer(instanceStr, out var sha256Buffer);
+ using (sha256Buffer)
+ return Marshaling.ConvertNativePackedByteArrayToSystemArray(sha256Buffer);
}
/// <summary>
@@ -1340,12 +1341,12 @@ namespace Godot
/// <seealso cref="SHA256Buffer(string)"/>
/// <param name="instance">The string to hash.</param>
/// <returns>The SHA-256 hash of the string.</returns>
- public static unsafe string SHA256Text(this string instance)
+ public static string SHA256Text(this string instance)
{
- using godot_string instanceStr = Marshaling.mono_string_to_godot(instance);
- using godot_string sha256Text = default;
- NativeFuncs.godotsharp_string_sha256_text(&instanceStr, &sha256Text);
- return Marshaling.mono_string_from_godot(sha256Text);
+ using godot_string instanceStr = Marshaling.ConvertStringToNative(instance);
+ NativeFuncs.godotsharp_string_sha256_text(instanceStr, out var sha256Text);
+ using (sha256Text)
+ return Marshaling.ConvertStringToManaged(sha256Text);
}
/// <summary>
@@ -1396,12 +1397,12 @@ namespace Godot
/// <summary>
/// Returns a simplified canonical path.
/// </summary>
- public static unsafe string SimplifyPath(this string instance)
+ public static string SimplifyPath(this string instance)
{
- using godot_string instanceStr = Marshaling.mono_string_to_godot(instance);
- using godot_string simplifiedPath = default;
- NativeFuncs.godotsharp_string_simplify_path(&instanceStr, &simplifiedPath);
- return Marshaling.mono_string_from_godot(simplifiedPath);
+ using godot_string instanceStr = Marshaling.ConvertStringToNative(instance);
+ NativeFuncs.godotsharp_string_simplify_path(instanceStr, out godot_string simplifiedPath);
+ using (simplifiedPath)
+ return Marshaling.ConvertStringToManaged(simplifiedPath);
}
/// <summary>
@@ -1602,7 +1603,7 @@ namespace Godot
/// <seealso cref="XMLUnescape(string)"/>
/// <param name="instance">The string to escape.</param>
/// <returns>The escaped string.</returns>
- public static string XMLEscape(this string instance)
+ public static string? XMLEscape(this string instance)
{
return SecurityElement.Escape(instance);
}
@@ -1614,9 +1615,9 @@ namespace Godot
/// <seealso cref="XMLEscape(string)"/>
/// <param name="instance">The string to unescape.</param>
/// <returns>The unescaped string.</returns>
- public static string XMLUnescape(this string instance)
+ public static string? XMLUnescape(this string instance)
{
- return SecurityElement.FromString(instance).Text;
+ return SecurityElement.FromString(instance)?.Text;
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs
index 84b0ab623c..e8bda9b219 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs
@@ -1,5 +1,4 @@
using System;
-using System.Runtime.CompilerServices;
using Godot.NativeInterop;
namespace Godot
@@ -13,7 +12,7 @@ namespace Godot
/// </summary>
public sealed class StringName : IDisposable
{
- public godot_string_name NativeValue;
+ internal godot_string_name.movable NativeValue;
~StringName()
{
@@ -32,12 +31,12 @@ namespace Godot
public void Dispose(bool disposing)
{
// Always dispose `NativeValue` even if disposing is true
- NativeValue.Dispose();
+ NativeValue.DangerousSelfRef.Dispose();
}
private StringName(godot_string_name nativeValueToOwn)
{
- NativeValue = nativeValueToOwn;
+ NativeValue = (godot_string_name.movable)nativeValueToOwn;
}
// Explicit name to make it very clear
@@ -58,7 +57,7 @@ namespace Godot
public StringName(string name)
{
if (!string.IsNullOrEmpty(name))
- NativeValue = NativeFuncs.godotsharp_string_name_new_from_string(name);
+ NativeValue = (godot_string_name.movable)NativeFuncs.godotsharp_string_name_new_from_string(name);
}
/// <summary>
@@ -71,28 +70,27 @@ namespace Godot
/// Converts a <see cref="StringName"/> to a string.
/// </summary>
/// <param name="from">The <see cref="StringName"/> to convert.</param>
- public static implicit operator string(StringName from) => from.ToString();
+ public static implicit operator string(StringName from) => from?.ToString();
/// <summary>
/// Converts this <see cref="StringName"/> to a string.
/// </summary>
/// <returns>A string representation of this <see cref="StringName"/>.</returns>
- public override unsafe string ToString()
+ public override string ToString()
{
if (IsEmpty)
return string.Empty;
- godot_string dest;
- godot_string_name src = NativeValue;
- NativeFuncs.godotsharp_string_name_as_string(&dest, &src);
+ var src = (godot_string_name)NativeValue;
+ NativeFuncs.godotsharp_string_name_as_string(out godot_string dest, src);
using (dest)
- return Marshaling.mono_string_from_godot(dest);
+ return Marshaling.ConvertStringToManaged(dest);
}
/// <summary>
/// Check whether this <see cref="StringName"/> is empty.
/// </summary>
/// <returns>If the <see cref="StringName"/> is empty.</returns>
- public bool IsEmpty => godot_string_name.IsEmpty(in NativeValue);
+ public bool IsEmpty => NativeValue.DangerousSelfRef.IsEmpty;
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
index 68d097eb4e..1e3a13ba8e 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
@@ -93,7 +93,7 @@ namespace Godot
case 2:
return origin;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(column));
}
}
set
@@ -110,7 +110,7 @@ namespace Godot
origin = value;
return;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(column));
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
index 9eaf4f3252..27de87d7d4 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
@@ -52,7 +52,7 @@ namespace Godot
case 3:
return origin;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(column));
}
}
set
@@ -72,7 +72,7 @@ namespace Godot
origin = value;
return;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(column));
}
}
}
@@ -168,7 +168,7 @@ namespace Godot
/// <param name="target">The object to look at.</param>
/// <param name="up">The relative up direction.</param>
/// <returns>The resulting transform.</returns>
- public Transform3D LookingAt(Vector3 target, Vector3 up)
+ public readonly Transform3D LookingAt(Vector3 target, Vector3 up)
{
Transform3D t = this;
t.SetLookAt(origin, target, up);
@@ -194,7 +194,7 @@ namespace Godot
/// <param name="axis">The axis to rotate around. Must be normalized.</param>
/// <param name="angle">The angle to rotate, in radians.</param>
/// <returns>The rotated transformation matrix.</returns>
- public Transform3D Rotated(Vector3 axis, real_t angle)
+ public readonly Transform3D Rotated(Vector3 axis, real_t angle)
{
return new Transform3D(new Basis(axis, angle), new Vector3()) * this;
}
@@ -443,7 +443,7 @@ namespace Godot
/// </summary>
/// <param name="obj">The object to compare with.</param>
/// <returns>Whether or not the transform and the object are exactly equal.</returns>
- public override bool Equals(object obj)
+ public override readonly bool Equals(object obj)
{
if (obj is Transform3D)
{
@@ -460,7 +460,7 @@ namespace Godot
/// </summary>
/// <param name="other">The other transform to compare.</param>
/// <returns>Whether or not the matrices are exactly equal.</returns>
- public bool Equals(Transform3D other)
+ public readonly bool Equals(Transform3D other)
{
return basis.Equals(other.basis) && origin.Equals(other.origin);
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
index 67f70390dd..6223f3ae53 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
@@ -62,7 +62,7 @@ namespace Godot
case 1:
return y;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
}
}
set
@@ -76,7 +76,7 @@ namespace Godot
y = value;
return;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
index b61954a84c..e4c3f869b1 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
@@ -62,7 +62,7 @@ namespace Godot
case 1:
return y;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
}
}
set
@@ -76,7 +76,7 @@ namespace Godot
y = value;
return;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
index 67a98efc2d..7e98969d34 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
@@ -74,7 +74,7 @@ namespace Godot
case 2:
return z;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
}
}
set
@@ -91,7 +91,7 @@ namespace Godot
z = value;
return;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
index 0d4894f206..88b58e20cd 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
@@ -74,7 +74,7 @@ namespace Godot
case 2:
return z;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
}
}
set
@@ -91,7 +91,7 @@ namespace Godot
z = value;
return;
default:
- throw new IndexOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(index));
}
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/FodyWeavers.xml b/modules/mono/glue/GodotSharp/GodotSharp/FodyWeavers.xml
new file mode 100644
index 0000000000..d7abb3c982
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/FodyWeavers.xml
@@ -0,0 +1,3 @@
+<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
+ <InlineIL />
+</Weavers>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GenerateGodotCustomUnsafe.targets b/modules/mono/glue/GodotSharp/GodotSharp/GenerateGodotCustomUnsafe.targets
new file mode 100644
index 0000000000..f572f8a75c
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/GenerateGodotCustomUnsafe.targets
@@ -0,0 +1,93 @@
+<Project>
+ <!-- Generate Godot.NativeInterop.CustomUnsafe C# class-->
+
+ <!--
+ Ref structs are not allowed as generic type parameters, so we can't use Unsafe.AsPointer<T>/AsRef<T>.
+ As a workaround we generate overloads of those methods for our structs using Fody with inline IL.
+ -->
+
+ <ItemGroup>
+ <PackageReference Include="Fody" Version="6.6.0" PrivateAssets="all" />
+ <PackageReference Include="InlineIL.Fody" Version="1.7.1" PrivateAssets="all" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <GodotInteropStructs Include="godot_ref" />
+ <GodotInteropStructs Include="godot_variant_call_error" />
+ <GodotInteropStructs Include="godot_variant" />
+ <GodotInteropStructs Include="godot_string" />
+ <GodotInteropStructs Include="godot_string_name" />
+ <GodotInteropStructs Include="godot_node_path" />
+ <GodotInteropStructs Include="godot_signal" />
+ <GodotInteropStructs Include="godot_callable" />
+ <GodotInteropStructs Include="godot_array" />
+ <GodotInteropStructs Include="godot_dictionary" />
+ <GodotInteropStructs Include="godot_packed_byte_array" />
+ <GodotInteropStructs Include="godot_packed_int32_array" />
+ <GodotInteropStructs Include="godot_packed_int64_array" />
+ <GodotInteropStructs Include="godot_packed_float32_array" />
+ <GodotInteropStructs Include="godot_packed_float64_array" />
+ <GodotInteropStructs Include="godot_packed_string_array" />
+ <GodotInteropStructs Include="godot_packed_vector2_array" />
+ <GodotInteropStructs Include="godot_packed_vector3_array" />
+ <GodotInteropStructs Include="godot_packed_color_array" />
+ </ItemGroup>
+
+ <Target Name="GenerateGodotCustomUnsafe"
+ DependsOnTargets="_GenerateGodotCustomUnsafe"
+ BeforeTargets="PrepareForBuild;CompileDesignTime;BeforeCompile;CoreCompile">
+ <ItemGroup>
+ <Compile Include="$(IntermediateOutputPath)CustomUnsafe.%(GodotInteropStructs.Identity).g.cs" />
+ <FileWrites Include="$(IntermediateOutputPath)CustomUnsafe.%(GodotInteropStructs.Identity).g.cs" />
+ </ItemGroup>
+ </Target>
+ <Target Name="_GenerateGodotCustomUnsafe"
+ Inputs="$(MSBuildProjectFile);$(MSBuildThisFileDirectory);@(GodotInteropStructs)"
+ Outputs="$(IntermediateOutputPath)CustomUnsafe.%(GodotInteropStructs.Identity).g.cs">
+ <PropertyGroup>
+ <GodotInteropStruct>%(GodotInteropStructs.Identity)</GodotInteropStruct>
+ <GenerateGodotCustomUnsafeCode><![CDATA[
+using System.Runtime.CompilerServices%3b
+using InlineIL%3b
+using static InlineIL.IL.Emit%3b
+
+namespace Godot.NativeInterop
+{
+ public static partial class CustomUnsafe
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static unsafe $(GodotInteropStruct)* AsPointer(ref $(GodotInteropStruct) value)
+ {
+ Ldarg(nameof(value))%3b
+ Conv_U()%3b
+ return ($(GodotInteropStruct)*)IL.ReturnPointer()%3b
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static unsafe $(GodotInteropStruct)* ReadOnlyRefAsPointer(in $(GodotInteropStruct) value)
+ {
+ Ldarg(nameof(value))%3b
+ Conv_U()%3b
+ return ($(GodotInteropStruct)*)IL.ReturnPointer()%3b
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static unsafe ref $(GodotInteropStruct) AsRef($(GodotInteropStruct)* source)
+ {
+ return ref *source%3b
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static unsafe ref $(GodotInteropStruct) AsRef(in $(GodotInteropStruct) source)
+ {
+ return ref *ReadOnlyRefAsPointer(in source)%3b
+ }
+ }
+}
+]]></GenerateGodotCustomUnsafeCode>
+ </PropertyGroup>
+ <WriteLinesToFile Lines="$(GenerateGodotCustomUnsafeCode)"
+ File="$(IntermediateOutputPath)CustomUnsafe.%(GodotInteropStructs.Identity).g.cs"
+ Overwrite="True" WriteOnlyWhenDifferent="True" />
+ </Target>
+</Project>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
index 763ded8809..a06b448136 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
+++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
@@ -10,6 +10,8 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>9</LangVersion>
+ <AnalysisMode>Recommended</AnalysisMode>
+
<!-- Disabled temporarily as it pollutes the warnings, but we need to document public APIs. -->
<NoWarn>CS1591</NoWarn>
</PropertyGroup>
@@ -20,6 +22,12 @@
<PackageReference Include="ReflectionAnalyzers" Version="0.1.22-dev" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers" />
<!--PackageReference Include="IDisposableAnalyzers" Version="3.4.13" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers" /-->
</ItemGroup>
+ <!-- Targets for generating Godot.NativeInterop.CustomUnsafe -->
+ <Import Project="GenerateGodotCustomUnsafe.targets" />
+ <ItemGroup>
+ <None Include="GenerateGodotCustomUnsafe.targets" />
+ </ItemGroup>
+ <!-- Sources -->
<ItemGroup>
<Compile Include="Core\AABB.cs" />
<Compile Include="Core\Array.cs" />
@@ -62,6 +70,7 @@
<Compile Include="Core\NativeInterop\ExceptionUtils.cs" />
<Compile Include="Core\NativeInterop\InteropUtils.cs" />
<Compile Include="Core\NativeInterop\NativeFuncs.extended.cs" />
+ <Compile Include="Core\NativeInterop\NativeVariantPtrArgs.cs" />
<Compile Include="Core\NativeInterop\VariantSpanHelpers.cs" />
<Compile Include="Core\NativeInterop\VariantUtils.cs" />
<Compile Include="Core\NodePath.cs" />