472 lines
15 KiB
C#
472 lines
15 KiB
C#
using System;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.InteropServices;
|
|
#if REAL_T_IS_DOUBLE
|
|
using real_t = System.Double;
|
|
#else
|
|
using real_t = System.Single;
|
|
|
|
#endif
|
|
|
|
namespace Godot.NativeInterop
|
|
{
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_bool
|
|
{
|
|
public byte _value;
|
|
|
|
public unsafe godot_bool(bool value) => _value = *(byte*)&value;
|
|
|
|
public static unsafe implicit operator bool(godot_bool godotBool) => *(bool*)&godotBool._value;
|
|
public static implicit operator godot_bool(bool @bool) => new godot_bool(@bool);
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_ref : IDisposable
|
|
{
|
|
internal IntPtr _reference;
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_reference == IntPtr.Zero)
|
|
return;
|
|
NativeFuncs.godotsharp_ref_destroy(ref this);
|
|
_reference = IntPtr.Zero;
|
|
}
|
|
|
|
public bool IsNull => _reference == IntPtr.Zero;
|
|
}
|
|
|
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
|
internal enum godot_variant_call_error_error
|
|
{
|
|
GODOT_CALL_ERROR_CALL_OK = 0,
|
|
GODOT_CALL_ERROR_CALL_ERROR_INVALID_METHOD,
|
|
GODOT_CALL_ERROR_CALL_ERROR_INVALID_ARGUMENT,
|
|
GODOT_CALL_ERROR_CALL_ERROR_TOO_MANY_ARGUMENTS,
|
|
GODOT_CALL_ERROR_CALL_ERROR_TOO_FEW_ARGUMENTS,
|
|
GODOT_CALL_ERROR_CALL_ERROR_INSTANCE_IS_NULL,
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_variant_call_error
|
|
{
|
|
godot_variant_call_error_error error;
|
|
int argument;
|
|
Godot.Variant.Type expected;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Explicit)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_variant : IDisposable
|
|
{
|
|
[FieldOffset(0)] public Godot.Variant.Type _type;
|
|
|
|
// There's padding here
|
|
|
|
[FieldOffset(8)] internal godot_variant_data _data;
|
|
|
|
[StructLayout(LayoutKind.Explicit)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal unsafe 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 AABB* _aabb;
|
|
[FieldOffset(0)] public Basis* _basis;
|
|
[FieldOffset(0)] public Transform3D* _transform3d;
|
|
[FieldOffset(0)] private godot_variant_data_mem _mem;
|
|
|
|
// The following fields are not in the C++ union, but this is how they're stored in _mem.
|
|
[FieldOffset(0)] public godot_string_name _m_string_name;
|
|
[FieldOffset(0)] public godot_string _m_string;
|
|
[FieldOffset(0)] public Vector3 _m_vector3;
|
|
[FieldOffset(0)] public Vector3i _m_vector3i;
|
|
[FieldOffset(0)] public Vector2 _m_vector2;
|
|
[FieldOffset(0)] public Vector2i _m_vector2i;
|
|
[FieldOffset(0)] public Rect2 _m_rect2;
|
|
[FieldOffset(0)] public Rect2i _m_rect2i;
|
|
[FieldOffset(0)] public Plane _m_plane;
|
|
[FieldOffset(0)] public Quaternion _m_quaternion;
|
|
[FieldOffset(0)] public Color _m_color;
|
|
[FieldOffset(0)] public godot_node_path _m_node_path;
|
|
[FieldOffset(0)] public RID _m_rid;
|
|
[FieldOffset(0)] public godot_variant_obj_data _m_obj_data;
|
|
[FieldOffset(0)] public godot_callable _m_callable;
|
|
[FieldOffset(0)] public godot_signal _m_signal;
|
|
[FieldOffset(0)] public godot_dictionary _m_dictionary;
|
|
[FieldOffset(0)] public godot_array _m_array;
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_variant_obj_data
|
|
{
|
|
public UInt64 id;
|
|
public IntPtr obj;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
private struct godot_variant_data_mem
|
|
{
|
|
#pragma warning disable 169
|
|
private real_t _mem0;
|
|
private real_t _mem1;
|
|
private real_t _mem2;
|
|
private real_t _mem3;
|
|
#pragma warning restore 169
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
switch (_type)
|
|
{
|
|
case Variant.Type.Nil:
|
|
case Variant.Type.Bool:
|
|
case Variant.Type.Int:
|
|
case Variant.Type.Float:
|
|
case Variant.Type.Vector2:
|
|
case Variant.Type.Vector2i:
|
|
case Variant.Type.Rect2:
|
|
case Variant.Type.Rect2i:
|
|
case Variant.Type.Vector3:
|
|
case Variant.Type.Vector3i:
|
|
case Variant.Type.Plane:
|
|
case Variant.Type.Quaternion:
|
|
case Variant.Type.Color:
|
|
case Variant.Type.Rid:
|
|
return;
|
|
}
|
|
|
|
NativeFuncs.godotsharp_variant_destroy(ref this);
|
|
_type = Variant.Type.Nil;
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_string : IDisposable
|
|
{
|
|
internal IntPtr _ptr;
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_ptr == IntPtr.Zero)
|
|
return;
|
|
NativeFuncs.godotsharp_string_destroy(ref this);
|
|
_ptr = IntPtr.Zero;
|
|
}
|
|
|
|
// Size including the null termination character
|
|
public unsafe int Size => _ptr != IntPtr.Zero ? *((int*)_ptr - 1) : 0;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_string_name : IDisposable
|
|
{
|
|
internal IntPtr _data;
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_data == IntPtr.Zero)
|
|
return;
|
|
NativeFuncs.godotsharp_string_name_destroy(ref this);
|
|
_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) =>
|
|
// This is all that's needed to check if it's empty. Equivalent to `== StringName()` in C++.
|
|
name._data == IntPtr.Zero;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_node_path : IDisposable
|
|
{
|
|
internal IntPtr _data;
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_data == IntPtr.Zero)
|
|
return;
|
|
NativeFuncs.godotsharp_node_path_destroy(ref this);
|
|
_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) =>
|
|
// 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;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Explicit)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_signal : IDisposable
|
|
{
|
|
[FieldOffset(0)] public godot_string_name _name;
|
|
|
|
// There's padding here on 32-bit
|
|
|
|
[FieldOffset(8)] public UInt64 _objectId;
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_name._data == IntPtr.Zero)
|
|
return;
|
|
NativeFuncs.godotsharp_signal_destroy(ref this);
|
|
_name._data = IntPtr.Zero;
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Explicit)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_callable : IDisposable
|
|
{
|
|
[FieldOffset(0)] public godot_string_name _method;
|
|
|
|
// There's padding here on 32-bit
|
|
|
|
[FieldOffset(8)] public UInt64 _objectId;
|
|
[FieldOffset(8)] public IntPtr _custom;
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_method._data == IntPtr.Zero && _custom == IntPtr.Zero)
|
|
return;
|
|
NativeFuncs.godotsharp_callable_destroy(ref this);
|
|
_method._data = IntPtr.Zero;
|
|
_custom = IntPtr.Zero;
|
|
}
|
|
}
|
|
|
|
// A correctly constructed value needs to call the native default constructor to allocate `_p`.
|
|
// Don't pass a C# default constructed `godot_array` to native code, unless it's going to
|
|
// 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
|
|
internal struct godot_array : IDisposable
|
|
{
|
|
internal unsafe ArrayPrivate* _p;
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct ArrayPrivate
|
|
{
|
|
private uint _safeRefCount;
|
|
|
|
internal VariantVector _arrayVector;
|
|
// There's more here, but we don't care as we never store this in C#
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct VariantVector
|
|
{
|
|
internal IntPtr _writeProxy;
|
|
internal unsafe godot_variant* _ptr;
|
|
|
|
public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
|
|
}
|
|
|
|
public unsafe int Size => _p != null ? _p->_arrayVector.Size : 0;
|
|
|
|
public unsafe void Dispose()
|
|
{
|
|
if (_p == null)
|
|
return;
|
|
NativeFuncs.godotsharp_array_destroy(ref this);
|
|
_p = null;
|
|
}
|
|
}
|
|
|
|
// IMPORTANT:
|
|
// A correctly constructed value needs to call the native default constructor to allocate `_p`.
|
|
// Don't pass a C# default constructed `godot_dictionary` to native code, unless it's going to
|
|
// 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
|
|
internal struct godot_dictionary : IDisposable
|
|
{
|
|
internal IntPtr _p;
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_p == IntPtr.Zero)
|
|
return;
|
|
NativeFuncs.godotsharp_dictionary_destroy(ref this);
|
|
_p = IntPtr.Zero;
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_packed_byte_array : IDisposable
|
|
{
|
|
internal IntPtr _writeProxy;
|
|
internal unsafe byte* _ptr;
|
|
|
|
public unsafe void Dispose()
|
|
{
|
|
if (_ptr == null)
|
|
return;
|
|
NativeFuncs.godotsharp_packed_byte_array_destroy(ref this);
|
|
_ptr = null;
|
|
}
|
|
|
|
public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_packed_int32_array : IDisposable
|
|
{
|
|
internal IntPtr _writeProxy;
|
|
internal unsafe int* _ptr;
|
|
|
|
public unsafe void Dispose()
|
|
{
|
|
if (_ptr == null)
|
|
return;
|
|
NativeFuncs.godotsharp_packed_int32_array_destroy(ref this);
|
|
_ptr = null;
|
|
}
|
|
|
|
public unsafe int Size => _ptr != null ? *(_ptr - 1) : 0;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_packed_int64_array : IDisposable
|
|
{
|
|
internal IntPtr _writeProxy;
|
|
internal unsafe long* _ptr;
|
|
|
|
public unsafe void Dispose()
|
|
{
|
|
if (_ptr == null)
|
|
return;
|
|
NativeFuncs.godotsharp_packed_int64_array_destroy(ref this);
|
|
_ptr = null;
|
|
}
|
|
|
|
public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_packed_float32_array : IDisposable
|
|
{
|
|
internal IntPtr _writeProxy;
|
|
internal unsafe float* _ptr;
|
|
|
|
public unsafe void Dispose()
|
|
{
|
|
if (_ptr == null)
|
|
return;
|
|
NativeFuncs.godotsharp_packed_float32_array_destroy(ref this);
|
|
_ptr = null;
|
|
}
|
|
|
|
public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_packed_float64_array : IDisposable
|
|
{
|
|
internal IntPtr _writeProxy;
|
|
internal unsafe double* _ptr;
|
|
|
|
public unsafe void Dispose()
|
|
{
|
|
if (_ptr == null)
|
|
return;
|
|
NativeFuncs.godotsharp_packed_float64_array_destroy(ref this);
|
|
_ptr = null;
|
|
}
|
|
|
|
public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_packed_string_array : IDisposable
|
|
{
|
|
internal IntPtr _writeProxy;
|
|
internal unsafe godot_string* _ptr;
|
|
|
|
public unsafe void Dispose()
|
|
{
|
|
if (_ptr == null)
|
|
return;
|
|
NativeFuncs.godotsharp_packed_string_array_destroy(ref this);
|
|
_ptr = null;
|
|
}
|
|
|
|
public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_packed_vector2_array : IDisposable
|
|
{
|
|
internal IntPtr _writeProxy;
|
|
internal unsafe Vector2* _ptr;
|
|
|
|
public unsafe void Dispose()
|
|
{
|
|
if (_ptr == null)
|
|
return;
|
|
NativeFuncs.godotsharp_packed_vector2_array_destroy(ref this);
|
|
_ptr = null;
|
|
}
|
|
|
|
public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_packed_vector3_array : IDisposable
|
|
{
|
|
internal IntPtr _writeProxy;
|
|
internal unsafe Vector3* _ptr;
|
|
|
|
public unsafe void Dispose()
|
|
{
|
|
if (_ptr == null)
|
|
return;
|
|
NativeFuncs.godotsharp_packed_vector3_array_destroy(ref this);
|
|
_ptr = null;
|
|
}
|
|
|
|
public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
// ReSharper disable once InconsistentNaming
|
|
internal struct godot_packed_color_array : IDisposable
|
|
{
|
|
internal IntPtr _writeProxy;
|
|
internal unsafe Color* _ptr;
|
|
|
|
public unsafe void Dispose()
|
|
{
|
|
if (_ptr == null)
|
|
return;
|
|
NativeFuncs.godotsharp_packed_color_array_destroy(ref this);
|
|
_ptr = null;
|
|
}
|
|
|
|
public unsafe int Size => _ptr != null ? *((int*)_ptr - 1) : 0;
|
|
}
|
|
}
|