diff options
Diffstat (limited to 'modules/mono')
103 files changed, 6448 insertions, 3385 deletions
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index ca94917938..fe0f4aae81 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -60,6 +60,7 @@ #include "mono_gd/gd_mono_cache.h" #include "signal_awaiter_utils.h" #include "utils/macros.h" +#include "utils/naming_utils.h" #include "utils/string_utils.h" #define CACHED_STRING_NAME(m_var) (CSharpLanguage::get_singleton()->get_string_names().m_var) @@ -333,7 +334,7 @@ void CSharpLanguage::get_string_delimiters(List<String> *p_delimiters) const { } static String get_base_class_name(const String &p_base_class_name, const String p_class_name) { - String base_class = p_base_class_name; + String base_class = pascal_to_pascal_case(p_base_class_name); if (p_class_name == base_class) { base_class = "Godot." + base_class; } @@ -394,17 +395,22 @@ bool CSharpLanguage::supports_builtin_mode() const { } #ifdef TOOLS_ENABLED +struct VariantCsName { + Variant::Type variant_type; + const String cs_type; +}; + static String variant_type_to_managed_name(const String &p_var_type_name) { if (p_var_type_name.is_empty()) { return "Variant"; } if (ClassDB::class_exists(p_var_type_name)) { - return p_var_type_name; + return pascal_to_pascal_case(p_var_type_name); } if (p_var_type_name == Variant::get_type_name(Variant::OBJECT)) { - return "Godot.Object"; + return "GodotObject"; } if (p_var_type_name == Variant::get_type_name(Variant::INT)) { @@ -459,34 +465,34 @@ static String variant_type_to_managed_name(const String &p_var_type_name) { return "Signal"; } - Variant::Type var_types[] = { - Variant::BOOL, - Variant::INT, - Variant::VECTOR2, - Variant::VECTOR2I, - Variant::RECT2, - Variant::RECT2I, - Variant::VECTOR3, - Variant::VECTOR3I, - Variant::TRANSFORM2D, - Variant::VECTOR4, - Variant::VECTOR4I, - Variant::PLANE, - Variant::QUATERNION, - Variant::AABB, - Variant::BASIS, - Variant::TRANSFORM3D, - Variant::PROJECTION, - Variant::COLOR, - Variant::STRING_NAME, - Variant::NODE_PATH, - Variant::RID, - Variant::CALLABLE + const VariantCsName var_types[] = { + { Variant::BOOL, "bool" }, + { Variant::INT, "long" }, + { Variant::VECTOR2, "Vector2" }, + { Variant::VECTOR2I, "Vector2I" }, + { Variant::RECT2, "Rect2" }, + { Variant::RECT2I, "Rect2I" }, + { Variant::VECTOR3, "Vector3" }, + { Variant::VECTOR3I, "Vector3I" }, + { Variant::TRANSFORM2D, "Transform2D" }, + { Variant::VECTOR4, "Vector4" }, + { Variant::VECTOR4I, "Vector4I" }, + { Variant::PLANE, "Plane" }, + { Variant::QUATERNION, "Quaternion" }, + { Variant::AABB, "Aabb" }, + { Variant::BASIS, "Basis" }, + { Variant::TRANSFORM3D, "Transform3D" }, + { Variant::PROJECTION, "Projection" }, + { Variant::COLOR, "Color" }, + { Variant::STRING_NAME, "StringName" }, + { Variant::NODE_PATH, "NodePath" }, + { Variant::RID, "Rid" }, + { Variant::CALLABLE, "Callable" }, }; - for (unsigned int i = 0; i < sizeof(var_types) / sizeof(Variant::Type); i++) { - if (p_var_type_name == Variant::get_type_name(var_types[i])) { - return p_var_type_name; + for (unsigned int i = 0; i < sizeof(var_types) / sizeof(VariantCsName); i++) { + if (p_var_type_name == Variant::get_type_name(var_types[i].variant_type)) { + return var_types[i].cs_type; } } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs index 5eaebc4474..2d797e2f46 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs @@ -1,6 +1,6 @@ namespace Godot.SourceGenerators.Sample { - partial class Bar : Godot.Object + partial class Bar : GodotObject { } @@ -9,7 +9,7 @@ namespace Godot.SourceGenerators.Sample { } - partial class NotSameNameAsFile : Godot.Object + partial class NotSameNameAsFile : GodotObject { } } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/EventSignals.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/EventSignals.cs index 764ba8f121..ee6aa857fc 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/EventSignals.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/EventSignals.cs @@ -1,6 +1,6 @@ namespace Godot.SourceGenerators.Sample; -public partial class EventSignals : Godot.Object +public partial class EventSignals : GodotObject { [Signal] public delegate void MySignalEventHandler(string str, int num); diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs index ccaba4d727..31e66ac306 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs @@ -11,7 +11,7 @@ namespace Godot.SourceGenerators.Sample [SuppressMessage("ReSharper", "RedundantNameQualifier")] [SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeEvident")] [SuppressMessage("ReSharper", "InconsistentNaming")] - public partial class ExportedFields : Godot.Object + public partial class ExportedFields : GodotObject { [Export] private Boolean field_Boolean = true; [Export] private Char field_Char = 'f'; @@ -29,19 +29,19 @@ namespace Godot.SourceGenerators.Sample // Godot structs [Export] private Vector2 field_Vector2 = new(10f, 10f); - [Export] private Vector2i field_Vector2i = Vector2i.Up; + [Export] private Vector2I field_Vector2I = Vector2I.Up; [Export] private Rect2 field_Rect2 = new(new Vector2(10f, 10f), new Vector2(10f, 10f)); - [Export] private Rect2i field_Rect2i = new(new Vector2i(10, 10), new Vector2i(10, 10)); + [Export] private Rect2I field_Rect2I = new(new Vector2I(10, 10), new Vector2I(10, 10)); [Export] private Transform2D field_Transform2D = Transform2D.Identity; [Export] private Vector3 field_Vector3 = new(10f, 10f, 10f); - [Export] private Vector3i field_Vector3i = Vector3i.Back; + [Export] private Vector3I field_Vector3I = Vector3I.Back; [Export] private Basis field_Basis = new Basis(Quaternion.Identity); [Export] private Quaternion field_Quaternion = new Quaternion(Basis.Identity); [Export] private Transform3D field_Transform3D = Transform3D.Identity; [Export] private Vector4 field_Vector4 = new(10f, 10f, 10f, 10f); - [Export] private Vector4i field_Vector4i = Vector4i.One; + [Export] private Vector4I field_Vector4I = Vector4I.One; [Export] private Projection field_Projection = Projection.Identity; - [Export] private AABB field_AABB = new AABB(10f, 10f, 10f, new Vector3(1f, 1f, 1f)); + [Export] private Aabb field_Aabb = new Aabb(10f, 10f, 10f, new Vector3(1f, 1f, 1f)); [Export] private Color field_Color = Colors.Aquamarine; [Export] private Plane field_Plane = Plane.PlaneXZ; [Export] private Callable field_Callable = new Callable(Engine.GetMainLoop(), "_process"); @@ -80,10 +80,10 @@ namespace Godot.SourceGenerators.Sample [Export] private Vector2[] field_Vector2Array = { Vector2.Up, Vector2.Down, Vector2.Left, Vector2.Right }; [Export] private Vector3[] field_Vector3Array = { Vector3.Up, Vector3.Down, Vector3.Left, Vector3.Right }; [Export] private Color[] field_ColorArray = { Colors.Aqua, Colors.Aquamarine, Colors.Azure, Colors.Beige }; - [Export] private Godot.Object[] field_GodotObjectOrDerivedArray = { null }; + [Export] private GodotObject[] field_GodotObjectOrDerivedArray = { null }; [Export] private StringName[] field_StringNameArray = { "foo", "bar" }; [Export] private NodePath[] field_NodePathArray = { "foo", "bar" }; - [Export] private RID[] field_RIDArray = { default, default, default }; + [Export] private Rid[] field_RidArray = { default, default, default }; // Note we use Array and not System.Array. This tests the generated namespace qualification. [Export] private Int32[] field_empty_Int32Array = Array.Empty<Int32>(); // Note we use List and not System.Collections.Generic. @@ -93,11 +93,11 @@ namespace Godot.SourceGenerators.Sample [Export] private Variant field_Variant = "foo"; // Classes - [Export] private Godot.Object field_GodotObjectOrDerived; + [Export] private GodotObject field_GodotObjectOrDerived; [Export] private Godot.Texture field_GodotResourceTexture; [Export] private StringName field_StringName = new StringName("foo"); [Export] private NodePath field_NodePath = new NodePath("foo"); - [Export] private RID field_RID; + [Export] private Rid field_Rid; [Export] private Godot.Collections.Dictionary field_GodotDictionary = diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedProperties.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedProperties.cs index 5afaeb736f..aef2a8824e 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedProperties.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedProperties.cs @@ -10,7 +10,7 @@ namespace Godot.SourceGenerators.Sample [SuppressMessage("ReSharper", "RedundantNameQualifier")] [SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeEvident")] [SuppressMessage("ReSharper", "InconsistentNaming")] - public partial class ExportedProperties : Godot.Object + public partial class ExportedProperties : GodotObject { // Do not generate default value private String _notGenerate_Property_String = new string("not generate"); @@ -117,19 +117,19 @@ namespace Godot.SourceGenerators.Sample // Godot structs [Export] private Vector2 property_Vector2 { get; set; } = new(10f, 10f); - [Export] private Vector2i property_Vector2i { get; set; } = Vector2i.Up; + [Export] private Vector2I property_Vector2I { get; set; } = Vector2I.Up; [Export] private Rect2 property_Rect2 { get; set; } = new(new Vector2(10f, 10f), new Vector2(10f, 10f)); - [Export] private Rect2i property_Rect2i { get; set; } = new(new Vector2i(10, 10), new Vector2i(10, 10)); + [Export] private Rect2I property_Rect2I { get; set; } = new(new Vector2I(10, 10), new Vector2I(10, 10)); [Export] private Transform2D property_Transform2D { get; set; } = Transform2D.Identity; [Export] private Vector3 property_Vector3 { get; set; } = new(10f, 10f, 10f); - [Export] private Vector3i property_Vector3i { get; set; } = Vector3i.Back; + [Export] private Vector3I property_Vector3I { get; set; } = Vector3I.Back; [Export] private Basis property_Basis { get; set; } = new Basis(Quaternion.Identity); [Export] private Quaternion property_Quaternion { get; set; } = new Quaternion(Basis.Identity); [Export] private Transform3D property_Transform3D { get; set; } = Transform3D.Identity; [Export] private Vector4 property_Vector4 { get; set; } = new(10f, 10f, 10f, 10f); - [Export] private Vector4i property_Vector4i { get; set; } = Vector4i.One; + [Export] private Vector4I property_Vector4I { get; set; } = Vector4I.One; [Export] private Projection property_Projection { get; set; } = Projection.Identity; - [Export] private AABB property_AABB { get; set; } = new AABB(10f, 10f, 10f, new Vector3(1f, 1f, 1f)); + [Export] private Aabb property_Aabb { get; set; } = new Aabb(10f, 10f, 10f, new Vector3(1f, 1f, 1f)); [Export] private Color property_Color { get; set; } = Colors.Aquamarine; [Export] private Plane property_Plane { get; set; } = Plane.PlaneXZ; [Export] private Callable property_Callable { get; set; } = new Callable(Engine.GetMainLoop(), "_process"); @@ -168,20 +168,20 @@ namespace Godot.SourceGenerators.Sample [Export] private Vector2[] property_Vector2Array { get; set; } = { Vector2.Up, Vector2.Down, Vector2.Left, Vector2.Right }; [Export] private Vector3[] property_Vector3Array { get; set; } = { Vector3.Up, Vector3.Down, Vector3.Left, Vector3.Right }; [Export] private Color[] property_ColorArray { get; set; } = { Colors.Aqua, Colors.Aquamarine, Colors.Azure, Colors.Beige }; - [Export] private Godot.Object[] property_GodotObjectOrDerivedArray { get; set; } = { null }; + [Export] private GodotObject[] property_GodotObjectOrDerivedArray { get; set; } = { null }; [Export] private StringName[] field_StringNameArray { get; set; } = { "foo", "bar" }; [Export] private NodePath[] field_NodePathArray { get; set; } = { "foo", "bar" }; - [Export] private RID[] field_RIDArray { get; set; } = { default, default, default }; + [Export] private Rid[] field_RidArray { get; set; } = { default, default, default }; // Variant [Export] private Variant property_Variant { get; set; } = "foo"; // Classes - [Export] private Godot.Object property_GodotObjectOrDerived { get; set; } + [Export] private GodotObject property_GodotObjectOrDerived { get; set; } [Export] private Godot.Texture property_GodotResourceTexture { get; set; } [Export] private StringName property_StringName { get; set; } = new StringName("foo"); [Export] private NodePath property_NodePath { get; set; } = new NodePath("foo"); - [Export] private RID property_RID { get; set; } + [Export] private Rid property_Rid { get; set; } [Export] private Godot.Collections.Dictionary property_GodotDictionary { get; set; } = diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs index 21a5bfe560..9ef72d9e02 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs @@ -1,6 +1,6 @@ namespace Godot.SourceGenerators.Sample { - partial class Foo : Godot.Object + partial class Foo : GodotObject { } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Generic.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Generic.cs index b21b035b4d..2cd1a08c0e 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Generic.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Generic.cs @@ -2,19 +2,19 @@ namespace Godot.SourceGenerators.Sample { - partial class Generic<T> : Godot.Object + partial class Generic<T> : GodotObject { private int _field; } // Generic again but different generic parameters - partial class Generic<T, R> : Godot.Object + partial class Generic<T, R> : GodotObject { private int _field; } // Generic again but without generic parameters - partial class Generic : Godot.Object + partial class Generic : GodotObject { private int _field; } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Methods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Methods.cs index 618ba24abc..9aa6be3972 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Methods.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Methods.cs @@ -3,7 +3,7 @@ using System.Diagnostics.CodeAnalysis; namespace Godot.SourceGenerators.Sample; [SuppressMessage("ReSharper", "RedundantNameQualifier")] -public partial class Methods : Godot.Object +public partial class Methods : GodotObject { private void MethodWithOverload() { diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/MoreExportedFields.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/MoreExportedFields.cs index a6c8e52667..64088215e9 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/MoreExportedFields.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/MoreExportedFields.cs @@ -11,7 +11,7 @@ namespace Godot.SourceGenerators.Sample [SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeEvident")] [SuppressMessage("ReSharper", "InconsistentNaming")] // We split the definition of ExportedFields to verify properties work across multiple files. - public partial class ExportedFields : Godot.Object + public partial class ExportedFields : GodotObject { // Note we use Array and not System.Array. This tests the generated namespace qualification. [Export] private Int64[] field_empty_Int64Array = Array.Empty<Int64>(); diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs index 4eed2d7b7b..41bf89e6d8 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs @@ -14,9 +14,9 @@ namespace Godot.SourceGenerators { string message = "Missing partial modifier on declaration of type '" + - $"{symbol.FullQualifiedNameOmitGlobal()}' which is a subclass of '{GodotClasses.Object}'"; + $"{symbol.FullQualifiedNameOmitGlobal()}' which is a subclass of '{GodotClasses.GodotObject}'"; - string description = $"{message}. Subclasses of '{GodotClasses.Object}' " + + string description = $"{message}. Subclasses of '{GodotClasses.GodotObject}' " + "must be declared with the partial modifier."; context.ReportDiagnostic(Diagnostic.Create( @@ -46,9 +46,9 @@ namespace Godot.SourceGenerators string message = $"Missing partial modifier on declaration of type '{fullQualifiedName}', " + - $"which contains one or more subclasses of '{GodotClasses.Object}'"; + $"which contains one or more subclasses of '{GodotClasses.GodotObject}'"; - string description = $"{message}. Subclasses of '{GodotClasses.Object}' and their " + + string description = $"{message}. Subclasses of '{GodotClasses.GodotObject}' and their " + "containing types must be declared with the partial modifier."; context.ReportDiagnostic(Diagnostic.Create( diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs index 8852b7ebad..f0c9043fd5 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs @@ -85,7 +85,7 @@ namespace Godot.SourceGenerators var classTypeSymbol = sm.GetDeclaredSymbol(cds); if (classTypeSymbol?.BaseType == null - || !classTypeSymbol.BaseType.InheritsFrom("GodotSharp", GodotClasses.Object)) + || !classTypeSymbol.BaseType.InheritsFrom("GodotSharp", GodotClasses.GodotObject)) { symbol = null; return false; diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs index 1d8ddbabf2..b60148b34f 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs @@ -2,7 +2,7 @@ namespace Godot.SourceGenerators { public static class GodotClasses { - public const string Object = "Godot.Object"; + public const string GodotObject = "Godot.GodotObject"; public const string AssemblyHasScriptsAttr = "Godot.AssemblyHasScriptsAttribute"; public const string ExportAttr = "Godot.ExportAttribute"; public const string ExportCategoryAttr = "Godot.ExportCategoryAttribute"; @@ -10,7 +10,7 @@ namespace Godot.SourceGenerators public const string ExportSubgroupAttr = "Godot.ExportSubgroupAttribute"; public const string SignalAttr = "Godot.SignalAttribute"; public const string MustBeVariantAttr = "Godot.MustBeVariantAttribute"; - public const string GodotClassNameAttr = "Godot.GodotClassName"; + public const string GodotClassNameAttr = "Godot.GodotClassNameAttribute"; public const string SystemFlagsAttr = "System.FlagsAttribute"; } } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotEnums.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotEnums.cs index 22a21a1754..b30c8c240e 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotEnums.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotEnums.cs @@ -12,19 +12,19 @@ namespace Godot.SourceGenerators Float = 3, String = 4, Vector2 = 5, - Vector2i = 6, + Vector2I = 6, Rect2 = 7, - Rect2i = 8, + Rect2I = 8, Vector3 = 9, - Vector3i = 10, - Transform2d = 11, + Vector3I = 10, + Transform2D = 11, Vector4 = 12, - Vector4i = 13, + Vector4I = 13, Plane = 14, Quaternion = 15, Aabb = 16, Basis = 17, - Transform3d = 18, + Transform3D = 18, Projection = 19, Color = 20, StringName = 21, @@ -56,12 +56,12 @@ namespace Godot.SourceGenerators ExpEasing = 4, Link = 5, Flags = 6, - Layers2dRender = 7, - Layers2dPhysics = 8, - Layers2dNavigation = 9, - Layers3dRender = 10, - Layers3dPhysics = 11, - Layers3dNavigation = 12, + Layers2DRender = 7, + Layers2DPhysics = 8, + Layers2DNavigation = 9, + Layers3DRender = 10, + Layers3DPhysics = 11, + Layers3DNavigation = 12, File = 13, Dir = 14, GlobalFile = 15, diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs index 19fdd51dab..47a4516948 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs @@ -34,7 +34,7 @@ namespace GodotPlugins.Game { DllImportResolver dllImportResolver = new GodotDllImportResolver(godotDllHandle).OnResolveDllImport; - var coreApiAssembly = typeof(Godot.Object).Assembly; + var coreApiAssembly = typeof(global::Godot.GodotObject).Assembly; NativeLibrary.SetDllImportResolver(coreApiAssembly, dllImportResolver); @@ -42,13 +42,13 @@ namespace GodotPlugins.Game ManagedCallbacks.Create(outManagedCallbacks); - ScriptManagerBridge.LookupScriptsInAssembly(typeof(GodotPlugins.Game.Main).Assembly); + ScriptManagerBridge.LookupScriptsInAssembly(typeof(global::GodotPlugins.Game.Main).Assembly); return godot_bool.True; } catch (Exception e) { - Console.Error.WriteLine(e); + global::System.Console.Error.WriteLine(e); return false.ToGodotBool(); } } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalType.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalType.cs index ee1374d0b9..be6af117eb 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalType.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalType.cs @@ -21,19 +21,19 @@ namespace Godot.SourceGenerators // Godot structs Vector2, - Vector2i, + Vector2I, Rect2, - Rect2i, + Rect2I, Transform2D, Vector3, - Vector3i, + Vector3I, Basis, Quaternion, Transform3D, Vector4, - Vector4i, + Vector4I, Projection, - AABB, + Aabb, Color, Plane, Callable, @@ -55,7 +55,7 @@ namespace Godot.SourceGenerators GodotObjectOrDerivedArray, SystemArrayOfStringName, SystemArrayOfNodePath, - SystemArrayOfRID, + SystemArrayOfRid, // Variant Variant, @@ -64,7 +64,7 @@ namespace Godot.SourceGenerators GodotObjectOrDerived, StringName, NodePath, - RID, + Rid, GodotDictionary, GodotArray, GodotGenericDictionary, diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs index f0a6a72281..0258f53062 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs @@ -19,7 +19,7 @@ namespace Godot.SourceGenerators throw new InvalidOperationException($"Type not found: '{fullyQualifiedMetadataName}'."); } - GodotObjectType = GetTypeByMetadataNameOrThrow("Godot.Object"); + GodotObjectType = GetTypeByMetadataNameOrThrow(GodotClasses.GodotObject); } } @@ -40,19 +40,19 @@ namespace Godot.SourceGenerators MarshalType.Double => VariantType.Float, MarshalType.String => VariantType.String, MarshalType.Vector2 => VariantType.Vector2, - MarshalType.Vector2i => VariantType.Vector2i, + MarshalType.Vector2I => VariantType.Vector2I, MarshalType.Rect2 => VariantType.Rect2, - MarshalType.Rect2i => VariantType.Rect2i, - MarshalType.Transform2D => VariantType.Transform2d, + MarshalType.Rect2I => VariantType.Rect2I, + MarshalType.Transform2D => VariantType.Transform2D, MarshalType.Vector3 => VariantType.Vector3, - MarshalType.Vector3i => VariantType.Vector3i, + MarshalType.Vector3I => VariantType.Vector3I, MarshalType.Basis => VariantType.Basis, MarshalType.Quaternion => VariantType.Quaternion, - MarshalType.Transform3D => VariantType.Transform3d, + MarshalType.Transform3D => VariantType.Transform3D, MarshalType.Vector4 => VariantType.Vector4, - MarshalType.Vector4i => VariantType.Vector4i, + MarshalType.Vector4I => VariantType.Vector4I, MarshalType.Projection => VariantType.Projection, - MarshalType.AABB => VariantType.Aabb, + MarshalType.Aabb => VariantType.Aabb, MarshalType.Color => VariantType.Color, MarshalType.Plane => VariantType.Plane, MarshalType.Callable => VariantType.Callable, @@ -70,12 +70,12 @@ namespace Godot.SourceGenerators MarshalType.GodotObjectOrDerivedArray => VariantType.Array, MarshalType.SystemArrayOfStringName => VariantType.Array, MarshalType.SystemArrayOfNodePath => VariantType.Array, - MarshalType.SystemArrayOfRID => VariantType.Array, + MarshalType.SystemArrayOfRid => VariantType.Array, MarshalType.Variant => VariantType.Nil, MarshalType.GodotObjectOrDerived => VariantType.Object, MarshalType.StringName => VariantType.StringName, MarshalType.NodePath => VariantType.NodePath, - MarshalType.RID => VariantType.Rid, + MarshalType.Rid => VariantType.Rid, MarshalType.GodotDictionary => VariantType.Dictionary, MarshalType.GodotArray => VariantType.Array, MarshalType.GodotGenericDictionary => VariantType.Dictionary, @@ -130,22 +130,22 @@ namespace Godot.SourceGenerators return type switch { { Name: "Vector2" } => MarshalType.Vector2, - { Name: "Vector2i" } => MarshalType.Vector2i, + { Name: "Vector2I" } => MarshalType.Vector2I, { Name: "Rect2" } => MarshalType.Rect2, - { Name: "Rect2i" } => MarshalType.Rect2i, + { Name: "Rect2I" } => MarshalType.Rect2I, { Name: "Transform2D" } => MarshalType.Transform2D, { Name: "Vector3" } => MarshalType.Vector3, - { Name: "Vector3i" } => MarshalType.Vector3i, + { Name: "Vector3I" } => MarshalType.Vector3I, { Name: "Basis" } => MarshalType.Basis, { Name: "Quaternion" } => MarshalType.Quaternion, { Name: "Transform3D" } => MarshalType.Transform3D, { Name: "Vector4" } => MarshalType.Vector4, - { Name: "Vector4i" } => MarshalType.Vector4i, + { Name: "Vector4I" } => MarshalType.Vector4I, { Name: "Projection" } => MarshalType.Projection, - { Name: "AABB" } => MarshalType.AABB, + { Name: "Aabb" } => MarshalType.Aabb, { Name: "Color" } => MarshalType.Color, { Name: "Plane" } => MarshalType.Plane, - { Name: "RID" } => MarshalType.RID, + { Name: "Rid" } => MarshalType.Rid, { Name: "Callable" } => MarshalType.Callable, { Name: "Signal" } => MarshalType.Signal, { Name: "Variant" } => MarshalType.Variant, @@ -196,8 +196,8 @@ namespace Godot.SourceGenerators return MarshalType.SystemArrayOfStringName; case { Name: "NodePath" }: return MarshalType.SystemArrayOfNodePath; - case { Name: "RID" }: - return MarshalType.SystemArrayOfRID; + case { Name: "Rid" }: + return MarshalType.SystemArrayOfRid; } } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs index 98ca534c66..2a9758516c 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs @@ -26,6 +26,10 @@ namespace Godot.SourceGenerators private void AnalyzeNode(SyntaxNodeAnalysisContext context) { + // Ignore syntax inside comments + if (IsInsideDocumentation(context.Node)) + return; + var typeArgListSyntax = (TypeArgumentListSyntax)context.Node; // Method invocation or variable declaration that contained the type arguments @@ -74,6 +78,26 @@ namespace Godot.SourceGenerators } /// <summary> + /// Check if the syntax node is inside a documentation syntax. + /// </summary> + /// <param name="syntax">Syntax node to check.</param> + /// <returns><see langword="true"/> if the syntax node is inside a documentation syntax.</returns> + private bool IsInsideDocumentation(SyntaxNode? syntax) + { + while (syntax != null) + { + if (syntax is DocumentationCommentTriviaSyntax) + { + return true; + } + + syntax = syntax.Parent; + } + + return false; + } + + /// <summary> /// Check if the given type argument is being used in a type parameter that contains /// the <c>MustBeVariantAttribute</c>; otherwise, we ignore the attribute. /// </summary> diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs index b64b843b7c..b720fb93a3 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs @@ -328,15 +328,15 @@ namespace Godot.SourceGenerators private static void AppendGroupingPropertyInfo(StringBuilder source, PropertyInfo propertyInfo) { - source.Append(" properties.Add(new(type: (Godot.Variant.Type)") + source.Append(" properties.Add(new(type: (global::Godot.Variant.Type)") .Append((int)VariantType.Nil) .Append(", name: \"") .Append(propertyInfo.Name) - .Append("\", hint: (Godot.PropertyHint)") + .Append("\", hint: (global::Godot.PropertyHint)") .Append((int)PropertyHint.None) .Append(", hintString: \"") .Append(propertyInfo.HintString) - .Append("\", usage: (Godot.PropertyUsageFlags)") + .Append("\", usage: (global::Godot.PropertyUsageFlags)") .Append((int)propertyInfo.Usage) .Append(", exported: true));\n"); } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs index ba6c10aa31..d67cb5349d 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs @@ -272,6 +272,25 @@ namespace Godot.SourceGenerators source.Append(" }\n"); } + // Generate HasGodotClassSignal + + if (godotSignalDelegates.Count > 0) + { + source.Append( + " protected override bool HasGodotClassSignal(in godot_string_name signal)\n {\n"); + + bool isFirstEntry = true; + foreach (var signal in godotSignalDelegates) + { + GenerateHasSignalEntry(signal.Name, source, isFirstEntry); + isFirstEntry = false; + } + + source.Append(" return base.HasGodotClassSignal(signal);\n"); + + source.Append(" }\n"); + } + source.Append("}\n"); // partial class if (isInnerClass) @@ -397,6 +416,20 @@ namespace Godot.SourceGenerators PropertyHint.None, string.Empty, propUsage, exported: false); } + private static void GenerateHasSignalEntry( + string signalName, + StringBuilder source, + bool isFirstEntry + ) + { + source.Append(" "); + if (!isFirstEntry) + source.Append("else "); + source.Append("if (signal == SignalName."); + source.Append(signalName); + source.Append(") {\n return true;\n }\n"); + } + private static void GenerateSignalEventInvoker( GodotSignalDelegateData signal, StringBuilder source diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs index edbf53a389..1e4fd2f09a 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs @@ -22,8 +22,7 @@ namespace GodotTools.Build // TODO Use List once we have proper serialization public Godot.Collections.Array CustomProperties { get; private set; } = new(); - public string LogsDirPath => - Path.Combine(GodotSharpDirs.BuildLogsDirs, $"{Solution.MD5Text()}_{Configuration}"); + public string LogsDirPath => GodotSharpDirs.LogsDirPathFor(Solution, Configuration); public override bool Equals(object? obj) { diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs index 993c6d9217..349f9d0cb8 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs @@ -55,7 +55,7 @@ namespace GodotTools.Build private static void PrintVerbose(string text) { - if (OS.IsStdoutVerbose()) + if (OS.IsStdOutVerbose()) GD.Print(text); } diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs index e439822666..c083b9cc60 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs @@ -336,7 +336,7 @@ namespace GodotTools.Build _ = index; // Unused _issuesListContextMenu.Clear(); - _issuesListContextMenu.Size = new Vector2i(1, 1); + _issuesListContextMenu.Size = new Vector2I(1, 1); if (_issuesList.IsAnythingSelected()) { @@ -347,7 +347,7 @@ namespace GodotTools.Build if (_issuesListContextMenu.ItemCount > 0) { - _issuesListContextMenu.Position = (Vector2i)(_issuesList.GlobalPosition + atPosition); + _issuesListContextMenu.Position = (Vector2I)(_issuesList.GlobalPosition + atPosition); _issuesListContextMenu.Popup(); } } diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs index d0cd529d1f..d6549c1b70 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs @@ -7,6 +7,7 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using Godot; using GodotTools.BuildLogger; using GodotTools.Utils; @@ -22,19 +23,23 @@ namespace GodotTools.Build if (dotnetPath == null) throw new FileNotFoundException("Cannot find the dotnet executable."); + var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings(); + var startInfo = new ProcessStartInfo(dotnetPath); - BuildArguments(buildInfo, startInfo.ArgumentList); + BuildArguments(buildInfo, startInfo.ArgumentList, editorSettings); string launchMessage = startInfo.GetCommandLineDisplay(new StringBuilder("Running: ")).ToString(); stdOutHandler?.Invoke(launchMessage); - if (Godot.OS.IsStdoutVerbose()) + if (Godot.OS.IsStdOutVerbose()) Console.WriteLine(launchMessage); startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; startInfo.UseShellExecute = false; startInfo.CreateNoWindow = true; + startInfo.EnvironmentVariables["DOTNET_CLI_UI_LANGUAGE"] + = ((string)editorSettings.GetSetting("interface/editor/editor_language")).Replace('_', '-'); // Needed when running from Developer Command Prompt for VS RemovePlatformVariable(startInfo.EnvironmentVariables); @@ -83,18 +88,22 @@ namespace GodotTools.Build if (dotnetPath == null) throw new FileNotFoundException("Cannot find the dotnet executable."); + var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings(); + var startInfo = new ProcessStartInfo(dotnetPath); - BuildPublishArguments(buildInfo, startInfo.ArgumentList); + BuildPublishArguments(buildInfo, startInfo.ArgumentList, editorSettings); string launchMessage = startInfo.GetCommandLineDisplay(new StringBuilder("Running: ")).ToString(); stdOutHandler?.Invoke(launchMessage); - if (Godot.OS.IsStdoutVerbose()) + if (Godot.OS.IsStdOutVerbose()) Console.WriteLine(launchMessage); startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; startInfo.UseShellExecute = false; + startInfo.EnvironmentVariables["DOTNET_CLI_UI_LANGUAGE"] + = ((string)editorSettings.GetSetting("interface/editor/editor_language")).Replace('_', '-'); // Needed when running from Developer Command Prompt for VS RemovePlatformVariable(startInfo.EnvironmentVariables); @@ -124,7 +133,8 @@ namespace GodotTools.Build } } - private static void BuildArguments(BuildInfo buildInfo, Collection<string> arguments) + private static void BuildArguments(BuildInfo buildInfo, Collection<string> arguments, + EditorSettings editorSettings) { // `dotnet clean` / `dotnet build` commands arguments.Add(buildInfo.OnlyClean ? "clean" : "build"); @@ -150,12 +160,14 @@ namespace GodotTools.Build arguments.Add(buildInfo.Configuration); // Verbosity - arguments.Add("-v"); - arguments.Add("normal"); + AddVerbosityArguments(buildInfo, arguments, editorSettings); // Logger AddLoggerArgument(buildInfo, arguments); + // Binary log + AddBinaryLogArgument(buildInfo, arguments, editorSettings); + // Custom properties foreach (var customProperty in buildInfo.CustomProperties) { @@ -163,7 +175,8 @@ namespace GodotTools.Build } } - private static void BuildPublishArguments(BuildInfo buildInfo, Collection<string> arguments) + private static void BuildPublishArguments(BuildInfo buildInfo, Collection<string> arguments, + EditorSettings editorSettings) { arguments.Add("publish"); // `dotnet publish` command @@ -193,12 +206,14 @@ namespace GodotTools.Build arguments.Add("true"); // Verbosity - arguments.Add("-v"); - arguments.Add("normal"); + AddVerbosityArguments(buildInfo, arguments, editorSettings); // Logger AddLoggerArgument(buildInfo, arguments); + // Binary log + AddBinaryLogArgument(buildInfo, arguments, editorSettings); + // Custom properties foreach (var customProperty in buildInfo.CustomProperties) { @@ -213,6 +228,25 @@ namespace GodotTools.Build } } + private static void AddVerbosityArguments(BuildInfo buildInfo, Collection<string> arguments, + EditorSettings editorSettings) + { + var verbosityLevel = + editorSettings.GetSetting(GodotSharpEditor.Settings.VerbosityLevel).As<VerbosityLevelId>(); + arguments.Add("-v"); + arguments.Add(verbosityLevel switch + { + VerbosityLevelId.Quiet => "quiet", + VerbosityLevelId.Minimal => "minimal", + VerbosityLevelId.Detailed => "detailed", + VerbosityLevelId.Diagnostic => "diagnostic", + _ => "normal", + }); + + if ((bool)editorSettings.GetSetting(GodotSharpEditor.Settings.NoConsoleLogging)) + arguments.Add("-noconlog"); + } + private static void AddLoggerArgument(BuildInfo buildInfo, Collection<string> arguments) { string buildLoggerPath = Path.Combine(Internals.GodotSharpDirs.DataEditorToolsDir, @@ -222,6 +256,16 @@ namespace GodotTools.Build $"-l:{typeof(GodotBuildLogger).FullName},{buildLoggerPath};{buildInfo.LogsDirPath}"); } + private static void AddBinaryLogArgument(BuildInfo buildInfo, Collection<string> arguments, + EditorSettings editorSettings) + { + if (!(bool)editorSettings.GetSetting(GodotSharpEditor.Settings.CreateBinaryLog)) + return; + + arguments.Add($"-bl:{Path.Combine(buildInfo.LogsDirPath, "msbuild.binlog")}"); + arguments.Add("-ds:False"); // Honestly never understood why -bl also switches -ds on. + } + private static void RemovePlatformVariable(StringDictionary environmentVariables) { // EnvironmentVariables is case sensitive? Seriously? diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs index 2e438f3f8f..cf1b84e37f 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using Godot; using GodotTools.Internals; using static GodotTools.Internals.Globals; @@ -14,6 +15,7 @@ namespace GodotTools.Build private Button _errorsBtn; private Button _warningsBtn; private Button _viewLogBtn; + private Button _openLogsFolderBtn; private void WarningsToggled(bool pressed) { @@ -93,6 +95,10 @@ namespace GodotTools.Build private void ViewLogToggled(bool pressed) => BuildOutputView.LogVisible = pressed; + private void OpenLogsFolderPressed() => OS.ShellOpen( + $"file://{GodotSharpDirs.LogsDirPathFor("Debug")}" + ); + private void BuildMenuOptionPressed(long id) { switch ((BuildMenuOptions)id) @@ -122,7 +128,7 @@ namespace GodotTools.Build { base._Ready(); - CustomMinimumSize = new Vector2i(0, (int)(228 * EditorScale)); + CustomMinimumSize = new Vector2(0, 228 * EditorScale); SizeFlagsVertical = SizeFlags.ExpandFill; var toolBarHBox = new HBoxContainer { SizeFlagsHorizontal = SizeFlags.ExpandFill }; @@ -171,11 +177,27 @@ namespace GodotTools.Build _viewLogBtn.Toggled += ViewLogToggled; toolBarHBox.AddChild(_viewLogBtn); + // Horizontal spacer, push everything to the right. + toolBarHBox.AddChild(new Control + { + SizeFlagsHorizontal = SizeFlags.ExpandFill, + }); + + _openLogsFolderBtn = new Button + { + Text = "Show Logs in File Manager".TTR(), + Icon = GetThemeIcon("Filesystem", "EditorIcons"), + ExpandIcon = false, + FocusMode = FocusModeEnum.None, + }; + _openLogsFolderBtn.Pressed += OpenLogsFolderPressed; + toolBarHBox.AddChild(_openLogsFolderBtn); + BuildOutputView = new BuildOutputView(); AddChild(BuildOutputView); } - public override void _Notification(long what) + public override void _Notification(int what) { base._Notification(what); diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs index db96003baf..a284451a35 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs @@ -24,19 +24,7 @@ namespace GodotTools.Export public void RegisterExportSettings() { // TODO: These would be better as export preset options, but that doesn't seem to be supported yet - - GlobalDef("mono/export/include_scripts_content", false); - - GlobalDef("mono/export/aot/enabled", false); - GlobalDef("mono/export/aot/full_aot", false); - GlobalDef("mono/export/aot/use_interpreter", true); - - // --aot or --aot=opt1,opt2 (use 'mono --aot=help AuxAssembly.dll' to list AOT options) - GlobalDef("mono/export/aot/extra_aot_options", Array.Empty<string>()); - // --optimize/-O=opt1,opt2 (use 'mono --list-opt'' to list optimize options) - GlobalDef("mono/export/aot/extra_optimizer_options", Array.Empty<string>()); - - GlobalDef("mono/export/aot/android_toolchain_path", ""); + GlobalDef("dotnet/export/include_scripts_content", false); } private string _maybeLastExportError; @@ -56,7 +44,7 @@ namespace GodotTools.Export // TODO What if the source file is not part of the game's C# project - bool includeScriptsContent = (bool)ProjectSettings.GetSetting("mono/export/include_scripts_content"); + bool includeScriptsContent = (bool)ProjectSettings.GetSetting("dotnet/export/include_scripts_content"); if (!includeScriptsContent) { @@ -71,7 +59,7 @@ namespace GodotTools.Export } } - public override void _ExportBegin(string[] features, bool isDebug, string path, long flags) + public override void _ExportBegin(string[] features, bool isDebug, string path, uint flags) { base._ExportBegin(features, isDebug, path, flags); @@ -185,7 +173,9 @@ namespace GodotTools.Export foreach (string file in Directory.GetFiles(publishOutputTempDir, "*", SearchOption.AllDirectories)) { - AddSharedObject(file, tags: null, projectDataDirName); + AddSharedObject(file, tags: null, + Path.Join(projectDataDirName, + Path.GetRelativePath(publishOutputTempDir, Path.GetDirectoryName(file)))); } } } diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index 08147d9f6a..43ead4af69 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -22,6 +22,14 @@ namespace GodotTools { public partial class GodotSharpEditor : EditorPlugin, ISerializationListener { + public static class Settings + { + public const string ExternalEditor = "dotnet/editor/external_editor"; + public const string VerbosityLevel = "dotnet/build/verbosity_level"; + public const string NoConsoleLogging = "dotnet/build/no_console_logging"; + public const string CreateBinaryLog = "dotnet/build/create_binary_log"; + } + private EditorSettings _editorSettings; private PopupMenu _menuPopup; @@ -171,7 +179,7 @@ namespace GodotTools [UsedImplicitly] public Error OpenInExternalEditor(Script script, int line, int col) { - var editorId = (ExternalEditorId)(int)_editorSettings.GetSetting("mono/editor/external_editor"); + var editorId = _editorSettings.GetSetting(Settings.ExternalEditor).As<ExternalEditorId>(); switch (editorId) { @@ -192,7 +200,7 @@ namespace GodotTools try { - if (Godot.OS.IsStdoutVerbose()) + if (Godot.OS.IsStdOutVerbose()) Console.WriteLine( $"Running: \"{command}\" {string.Join(" ", args.Select(a => $"\"{a}\""))}"); @@ -323,8 +331,7 @@ namespace GodotTools [UsedImplicitly] public bool OverridesExternalEditor() { - return (ExternalEditorId)(int)_editorSettings.GetSetting("mono/editor/external_editor") != - ExternalEditorId.None; + return _editorSettings.GetSetting(Settings.ExternalEditor).As<ExternalEditorId>() != ExternalEditorId.None; } public override bool _Build() @@ -385,7 +392,7 @@ namespace GodotTools // correct version first (`RegisterDefaults` always picks the latest). if (DotNetFinder.TryFindDotNetSdk(dotNetSdkSearchVersion, out var sdkVersion, out string sdkPath)) { - if (Godot.OS.IsStdoutVerbose()) + if (Godot.OS.IsStdOutVerbose()) Console.WriteLine($"Found .NET Sdk version '{sdkVersion}': {sdkPath}"); ProjectUtils.MSBuildLocatorRegisterMSBuildPath(sdkPath); @@ -395,12 +402,12 @@ namespace GodotTools try { ProjectUtils.MSBuildLocatorRegisterDefaults(out sdkVersion, out sdkPath); - if (Godot.OS.IsStdoutVerbose()) + if (Godot.OS.IsStdOutVerbose()) Console.WriteLine($"Found .NET Sdk version '{sdkVersion}': {sdkPath}"); } catch (InvalidOperationException e) { - if (Godot.OS.IsStdoutVerbose()) + if (Godot.OS.IsStdOutVerbose()) GD.PrintErr(e.ToString()); GD.PushError($".NET Sdk not found. The required version is '{dotNetSdkSearchVersion}'."); } @@ -453,7 +460,10 @@ namespace GodotTools _menuPopup.IdPressed += _MenuOptionPressed; // External editor settings - EditorDef("mono/editor/external_editor", Variant.From(ExternalEditorId.None)); + EditorDef(Settings.ExternalEditor, Variant.From(ExternalEditorId.None)); + EditorDef(Settings.VerbosityLevel, Variant.From(VerbosityLevelId.Normal)); + EditorDef(Settings.NoConsoleLogging, false); + EditorDef(Settings.CreateBinaryLog, false); string settingsHintStr = "Disabled"; @@ -481,11 +491,23 @@ namespace GodotTools _editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary { ["type"] = (int)Variant.Type.Int, - ["name"] = "mono/editor/external_editor", + ["name"] = Settings.ExternalEditor, ["hint"] = (int)PropertyHint.Enum, ["hint_string"] = settingsHintStr }); + var verbosityLevels = Enum.GetValues<VerbosityLevelId>().Select(level => $"{Enum.GetName(level)}:{(int)level}"); + _editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary + { + ["type"] = (int)Variant.Type.Int, + ["name"] = Settings.VerbosityLevel, + ["hint"] = (int)PropertyHint.Enum, + ["hint_string"] = string.Join(",", verbosityLevels), + }); + + OnSettingsChanged(); + _editorSettings.SettingsChanged += OnSettingsChanged; + // Export plugin var exportPlugin = new ExportPlugin(); AddExportPlugin(exportPlugin); @@ -510,6 +532,24 @@ namespace GodotTools AddChild(GodotIdeManager); } + public override void _DisablePlugin() + { + base._DisablePlugin(); + + _editorSettings.SettingsChanged -= OnSettingsChanged; + } + + private void OnSettingsChanged() + { + // We want to force NoConsoleLogging to true when the VerbosityLevel is at Detailed or above. + // At that point, there's so much info logged that it doesn't make sense to display it in + // the tiny editor window, and it'd make the editor hang or crash anyway. + var verbosityLevel = _editorSettings.GetSetting(Settings.VerbosityLevel).As<VerbosityLevelId>(); + var hideConsoleLog = (bool)_editorSettings.GetSetting(Settings.NoConsoleLogging); + if (verbosityLevel >= VerbosityLevelId.Detailed && !hideConsoleLog) + _editorSettings.SetSetting(Settings.NoConsoleLogging, Variant.From(true)); + } + protected override void Dispose(bool disposing) { if (disposing) diff --git a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs index 89ac8058b9..eb42f01b3a 100644 --- a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs +++ b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs @@ -9,9 +9,9 @@ namespace GodotTools { private Timer _watchTimer; - public override void _Notification(long what) + public override void _Notification(int what) { - if (what == Node.NotificationWmWindowFocusIn) + if (what == Node.NotificationWMWindowFocusIn) { RestartTimer(); diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs index 9df90ac608..83621ce5af 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs @@ -21,7 +21,8 @@ namespace GodotTools.Ides return _messagingServer; _messagingServer?.Dispose(); - _messagingServer = new MessagingServer(OS.GetExecutablePath(), ProjectSettings.GlobalizePath(GodotSharpDirs.ResMetadataDir), new GodotLogger()); + _messagingServer = new MessagingServer(OS.GetExecutablePath(), + ProjectSettings.GlobalizePath(GodotSharpDirs.ResMetadataDir), new GodotLogger()); _ = _messagingServer.Listen(); @@ -76,8 +77,8 @@ namespace GodotTools.Ides public async Task<EditorPick?> LaunchIdeAsync(int millisecondsTimeout = 10000) { - var editorId = (ExternalEditorId)(int)GodotSharpEditor.Instance.GetEditorInterface() - .GetEditorSettings().GetSetting("mono/editor/external_editor"); + var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings(); + var editorId = editorSettings.GetSetting(GodotSharpEditor.Settings.ExternalEditor).As<ExternalEditorId>(); string editorIdentity = GetExternalEditorIdentity(editorId); var runningServer = GetRunningOrNewServer(); @@ -200,13 +201,13 @@ namespace GodotTools.Ides { public void LogDebug(string message) { - if (OS.IsStdoutVerbose()) + if (OS.IsStdOutVerbose()) Console.WriteLine(message); } public void LogInfo(string message) { - if (OS.IsStdoutVerbose()) + if (OS.IsStdOutVerbose()) Console.WriteLine(message); } diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs index 60602a5847..f55ca4c7d7 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs @@ -9,7 +9,7 @@ namespace GodotTools.Ides.Rider { public static class RiderPathManager { - public static readonly string EditorPathSettingName = "mono/editor/editor_path_optional"; + public static readonly string EditorPathSettingName = "dotnet/editor/editor_path_optional"; private static string GetRiderPathFromSettings() { @@ -22,7 +22,7 @@ namespace GodotTools.Ides.Rider public static void Initialize() { var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings(); - var editor = (ExternalEditorId)(int)editorSettings.GetSetting("mono/editor/external_editor"); + var editor = editorSettings.GetSetting(GodotSharpEditor.Settings.ExternalEditor).As<ExternalEditorId>(); if (editor == ExternalEditorId.Rider) { if (!editorSettings.HasSetting(EditorPathSettingName)) diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs index 7624989092..fb68fcbae6 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs @@ -115,5 +115,11 @@ namespace GodotTools.Internals return _projectCsProjPath; } } + + public static string LogsDirPathFor(string solution, string configuration) + => Path.Combine(BuildLogsDirs, $"{solution.Md5Text()}_{configuration}"); + + public static string LogsDirPathFor(string configuration) + => LogsDirPathFor(ProjectSlnPath, configuration); } } diff --git a/modules/mono/editor/GodotTools/GodotTools/VerbosityLevelId.cs b/modules/mono/editor/GodotTools/GodotTools/VerbosityLevelId.cs new file mode 100644 index 0000000000..0e1afe6bbf --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/VerbosityLevelId.cs @@ -0,0 +1,11 @@ +namespace GodotTools +{ + public enum VerbosityLevelId : long + { + Quiet, + Minimal, + Normal, + Detailed, + Diagnostic, + } +} diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 03cbfda1bd..ad6306bb41 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -38,10 +38,10 @@ #include "core/io/dir_access.h" #include "core/io/file_access.h" #include "core/os/os.h" -#include "core/string/ucaps.h" #include "main/main.h" #include "../godotsharp_defs.h" +#include "../utils/naming_utils.h" #include "../utils/path_utils.h" #include "../utils/string_utils.h" @@ -84,10 +84,12 @@ StringBuilder &operator<<(StringBuilder &r_sb, const char *p_cstring) { #define CS_PROPERTY_SINGLETON "Singleton" #define CS_METHOD_INVOKE_GODOT_CLASS_METHOD "InvokeGodotClassMethod" #define CS_METHOD_HAS_GODOT_CLASS_METHOD "HasGodotClassMethod" +#define CS_METHOD_HAS_GODOT_CLASS_SIGNAL "HasGodotClassSignal" #define CS_STATIC_FIELD_NATIVE_CTOR "NativeCtor" #define CS_STATIC_FIELD_METHOD_BIND_PREFIX "MethodBind" #define CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX "MethodProxyName_" +#define CS_STATIC_FIELD_SIGNAL_PROXY_NAME_PREFIX "SignalProxyName_" #define ICALL_PREFIX "godot_icall_" #define ICALL_CLASSDB_GET_METHOD "ClassDB_get_method" @@ -144,74 +146,6 @@ static String fix_doc_description(const String &p_bbcode) { .strip_edges(); } -static String snake_to_pascal_case(const String &p_identifier, bool p_input_is_upper = false) { - String ret; - Vector<String> parts = p_identifier.split("_", true); - - for (int i = 0; i < parts.size(); i++) { - String part = parts[i]; - - if (part.length()) { - part[0] = _find_upper(part[0]); - if (p_input_is_upper) { - for (int j = 1; j < part.length(); j++) { - part[j] = _find_lower(part[j]); - } - } - ret += part; - } else { - if (i == 0 || i == (parts.size() - 1)) { - // Preserve underscores at the beginning and end - ret += "_"; - } else { - // Preserve contiguous underscores - if (parts[i - 1].length()) { - ret += "__"; - } else { - ret += "_"; - } - } - } - } - - return ret; -} - -static String snake_to_camel_case(const String &p_identifier, bool p_input_is_upper = false) { - String ret; - Vector<String> parts = p_identifier.split("_", true); - - for (int i = 0; i < parts.size(); i++) { - String part = parts[i]; - - if (part.length()) { - if (i != 0) { - part[0] = _find_upper(part[0]); - } - if (p_input_is_upper) { - for (int j = i != 0 ? 1 : 0; j < part.length(); j++) { - part[j] = _find_lower(part[j]); - } - } - ret += part; - } else { - if (i == 0 || i == (parts.size() - 1)) { - // Preserve underscores at the beginning and end - ret += "_"; - } else { - // Preserve contiguous underscores - if (parts[i - 1].length()) { - ret += "__"; - } else { - ret += "_"; - } - } - } - } - - return ret; -} - String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterface *p_itype) { // Based on the version in EditorHelp @@ -229,6 +163,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf List<String> tag_stack; bool code_tag = false; + bool line_del = false; int pos = 0; while (pos < bbcode.length()) { @@ -239,20 +174,22 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf } if (brk_pos > pos) { - String text = bbcode.substr(pos, brk_pos - pos); - if (code_tag || tag_stack.size() > 0) { - xml_output.append(text.xml_escape()); - } else { - Vector<String> lines = text.split("\n"); - for (int i = 0; i < lines.size(); i++) { - if (i != 0) { - xml_output.append("<para>"); - } + if (!line_del) { + String text = bbcode.substr(pos, brk_pos - pos); + if (code_tag || tag_stack.size() > 0) { + xml_output.append(text.xml_escape()); + } else { + Vector<String> lines = text.split("\n"); + for (int i = 0; i < lines.size(); i++) { + if (i != 0) { + xml_output.append("<para>"); + } - xml_output.append(lines[i].xml_escape()); + xml_output.append(lines[i].xml_escape()); - if (i != lines.size() - 1) { - xml_output.append("</para>\n"); + if (i != lines.size() - 1) { + xml_output.append("</para>\n"); + } } } } @@ -265,20 +202,22 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf int brk_end = bbcode.find("]", brk_pos + 1); if (brk_end == -1) { - String text = bbcode.substr(brk_pos, bbcode.length() - brk_pos); - if (code_tag || tag_stack.size() > 0) { - xml_output.append(text.xml_escape()); - } else { - Vector<String> lines = text.split("\n"); - for (int i = 0; i < lines.size(); i++) { - if (i != 0) { - xml_output.append("<para>"); - } + if (!line_del) { + String text = bbcode.substr(brk_pos, bbcode.length() - brk_pos); + if (code_tag || tag_stack.size() > 0) { + xml_output.append(text.xml_escape()); + } else { + Vector<String> lines = text.split("\n"); + for (int i = 0; i < lines.size(); i++) { + if (i != 0) { + xml_output.append("<para>"); + } - xml_output.append(lines[i].xml_escape()); + xml_output.append(lines[i].xml_escape()); - if (i != lines.size() - 1) { - xml_output.append("</para>\n"); + if (i != lines.size() - 1) { + xml_output.append("</para>\n"); + } } } } @@ -292,7 +231,9 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1, tag.length()); if (!tag_ok) { - xml_output.append("["); + if (!line_del) { + xml_output.append("["); + } pos = brk_pos + 1; continue; } @@ -307,11 +248,20 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf xml_output.append("</c>"); } else if (tag == "/codeblock") { xml_output.append("</code>"); + } else if (tag == "/b") { + xml_output.append("</b>"); + } else if (tag == "/i") { + xml_output.append("</i>"); + } else if (tag == "/csharp") { + xml_output.append("</code>"); + line_del = true; + } else if (tag == "/codeblocks") { + line_del = false; } } else if (code_tag) { xml_output.append("["); pos = brk_pos + 1; - } else if (tag.begins_with("method ") || tag.begins_with("member ") || tag.begins_with("signal ") || tag.begins_with("enum ") || tag.begins_with("constant ") || tag.begins_with("theme_item ")) { + } else if (tag.begins_with("method ") || tag.begins_with("member ") || tag.begins_with("signal ") || tag.begins_with("enum ") || tag.begins_with("constant ") || tag.begins_with("theme_item ") || tag.begins_with("param ")) { const int tag_end = tag.find(" "); const String link_tag = tag.substr(0, tag_end); const String link_target = tag.substr(tag_end + 1, tag.length()).lstrip(" "); @@ -356,6 +306,8 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf } else if (link_tag == "theme_item") { // We do not declare theme_items in any way in C#, so there is nothing to reference _append_xml_undeclared(xml_output, link_target); + } else if (link_tag == "param") { + _append_xml_undeclared(xml_output, snake_to_camel_case(link_target, false)); } pos = brk_end + 1; @@ -377,8 +329,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf #endif "\"/>"); } else if (tag == "Variant") { - // We use System.Object for Variant, so there is no Variant type in C# - xml_output.append("<c>Variant</c>"); + xml_output.append("<see cref=\"Godot.Variant\"/>"); } else if (tag == "String") { xml_output.append("<see cref=\"string\"/>"); } else if (tag == "Nil") { @@ -428,11 +379,13 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf pos = brk_end + 1; } else if (tag == "b") { - // bold is not supported in xml comments + xml_output.append("<b>"); + pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "i") { - // italics is not supported in xml comments + xml_output.append("<i>"); + pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "code") { @@ -447,6 +400,17 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf code_tag = true; pos = brk_end + 1; tag_stack.push_front(tag); + } else if (tag == "codeblocks") { + line_del = true; + pos = brk_end + 1; + tag_stack.push_front(tag); + } else if (tag == "csharp") { + xml_output.append("<code>"); + + line_del = false; + code_tag = true; + pos = brk_end + 1; + tag_stack.push_front(tag); } else if (tag == "kbd") { // keyboard combinations are not supported in xml comments pos = brk_end + 1; @@ -459,7 +423,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf xml_output.append("\n"); // FIXME: Should use <para> instead. Luckily this tag isn't used for now. pos = brk_end + 1; } else if (tag == "u") { - // underline is not supported in xml comments + // underline is not supported in Rider xml comments pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "s") { @@ -510,7 +474,9 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf pos = brk_end + 1; tag_stack.push_front("font"); } else { - xml_output.append("["); // ignore + if (!line_del) { + xml_output.append("["); // ignore + } pos = brk_pos + 1; } } @@ -531,7 +497,7 @@ void BindingsGenerator::_append_xml_method(StringBuilder &p_xml_output, const Ty } else if (!p_target_itype || !p_target_itype->is_object_type) { if (OS::get_singleton()->is_stdout_verbose()) { if (p_target_itype) { - OS::get_singleton()->print("Cannot resolve method reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data()); + OS::get_singleton()->print("Cannot resolve method reference for non-GodotObject type in documentation: %s\n", p_link_target.utf8().get_data()); } else { OS::get_singleton()->print("Cannot resolve type from method reference in documentation: %s\n", p_link_target.utf8().get_data()); } @@ -571,7 +537,7 @@ void BindingsGenerator::_append_xml_member(StringBuilder &p_xml_output, const Ty } else if (!p_target_itype || !p_target_itype->is_object_type) { if (OS::get_singleton()->is_stdout_verbose()) { if (p_target_itype) { - OS::get_singleton()->print("Cannot resolve member reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data()); + OS::get_singleton()->print("Cannot resolve member reference for non-GodotObject type in documentation: %s\n", p_link_target.utf8().get_data()); } else { OS::get_singleton()->print("Cannot resolve type from member reference in documentation: %s\n", p_link_target.utf8().get_data()); } @@ -607,7 +573,7 @@ void BindingsGenerator::_append_xml_signal(StringBuilder &p_xml_output, const Ty if (!p_target_itype || !p_target_itype->is_object_type) { if (OS::get_singleton()->is_stdout_verbose()) { if (p_target_itype) { - OS::get_singleton()->print("Cannot resolve signal reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data()); + OS::get_singleton()->print("Cannot resolve signal reference for non-GodotObject type in documentation: %s\n", p_link_target.utf8().get_data()); } else { OS::get_singleton()->print("Cannot resolve type from signal reference in documentation: %s\n", p_link_target.utf8().get_data()); } @@ -664,7 +630,7 @@ void BindingsGenerator::_append_xml_constant(StringBuilder &p_xml_output, const if (OS::get_singleton()->is_stdout_verbose()) { if (p_target_itype) { - OS::get_singleton()->print("Cannot resolve constant reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data()); + OS::get_singleton()->print("Cannot resolve constant reference for non-GodotObject type in documentation: %s\n", p_link_target.utf8().get_data()); } else { OS::get_singleton()->print("Cannot resolve type from constant reference in documentation: %s\n", p_link_target.utf8().get_data()); } @@ -933,11 +899,11 @@ void BindingsGenerator::_generate_array_extensions(StringBuilder &p_output) { ARRAY_ALL(string); ARRAY_ALL(Color); ARRAY_ALL(Vector2); - ARRAY_ALL(Vector2i); + ARRAY_ALL(Vector2I); ARRAY_ALL(Vector3); - ARRAY_ALL(Vector3i); + ARRAY_ALL(Vector3I); ARRAY_ALL(Vector4); - ARRAY_ALL(Vector4i); + ARRAY_ALL(Vector4I); #undef ARRAY_ALL #undef ARRAY_IS_EMPTY @@ -1007,7 +973,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) { _log("Declaring global enum '%s' inside struct '%s'\n", enum_proxy_name.utf8().get_data(), enum_class_name.utf8().get_data()); p_output.append("\npublic partial struct "); - p_output.append(enum_class_name); + p_output.append(pascal_to_pascal_case(enum_class_name)); p_output.append("\n" OPEN_BLOCK); } @@ -1016,7 +982,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) { } p_output.append("\npublic enum "); - p_output.append(enum_proxy_name); + p_output.append(pascal_to_pascal_case(enum_proxy_name)); p_output.append(" : long"); p_output.append("\n" OPEN_BLOCK); @@ -1351,7 +1317,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str bool is_derived_type = itype.base_name != StringName(); if (!is_derived_type) { - // Some Godot.Object assertions + // Some GodotObject assertions CRASH_COND(itype.cname != name_cache.type_Object); CRASH_COND(!itype.is_instantiable); CRASH_COND(itype.api_type != ClassDB::API_CORE); @@ -1468,7 +1434,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str } output.append(MEMBER_BEGIN "public enum "); - output.append(ienum.cname.operator String()); + output.append(pascal_to_pascal_case(ienum.cname.operator String())); output.append(" : long"); output.append(MEMBER_BEGIN OPEN_BLOCK); @@ -1513,9 +1479,9 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str if (itype.is_singleton) { // Add the type name and the singleton pointer as static fields - output.append(MEMBER_BEGIN "private static Godot.Object singleton;\n"); + output.append(MEMBER_BEGIN "private static GodotObject singleton;\n"); - output << MEMBER_BEGIN "public static Godot.Object " CS_PROPERTY_SINGLETON "\n" INDENT1 "{\n" + output << MEMBER_BEGIN "public static GodotObject " CS_PROPERTY_SINGLETON "\n" INDENT1 "{\n" << INDENT2 "get\n" INDENT2 "{\n" INDENT3 "if (singleton == null)\n" << INDENT4 "singleton = " C_METHOD_ENGINE_GET_SINGLETON "(typeof(" << itype.proxy_name @@ -1525,8 +1491,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str output.append(itype.name); output.append("\";\n"); } else { - // IMPORTANT: We also generate the static fields for Godot.Object instead of declaring - // them manually in the `Object.base.cs` partial class declaration, because they're + // IMPORTANT: We also generate the static fields for GodotObject instead of declaring + // them manually in the `GodotObject.base.cs` partial class declaration, because they're // required by other static fields in this generated partial class declaration. // Static fields are initialized in order of declaration, but when they're in different // partial class declarations then it becomes harder to tell (Rider warns about this). @@ -1608,6 +1574,16 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str << " = \"" << imethod.proxy_name << "\";\n"; } + // Generate signal names cache fields + + for (const SignalInterface &isignal : itype.signals_) { + output << MEMBER_BEGIN "// ReSharper disable once InconsistentNaming\n" + << INDENT1 "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n" + << INDENT1 "private static readonly StringName " + << CS_STATIC_FIELD_SIGNAL_PROXY_NAME_PREFIX << isignal.name + << " = \"" << isignal.proxy_name << "\";\n"; + } + // TODO: Only generate HasGodotClassMethod and InvokeGodotClassMethod if there's any method // Generate InvokeGodotClassMethod @@ -1721,6 +1697,34 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str } output << INDENT1 "}\n"; + + // Generate HasGodotClassSignal + + output << MEMBER_BEGIN "protected internal " << (is_derived_type ? "override" : "virtual") + << " bool " CS_METHOD_HAS_GODOT_CLASS_SIGNAL "(in godot_string_name signal)\n" + << INDENT1 "{\n"; + + for (const SignalInterface &isignal : itype.signals_) { + // We check for native names (snake_case). If we detect one, we call HasGodotClassSignal + // again, but this time with the respective proxy name (PascalCase). It's the job of + // user derived classes to override the method and check for those. Our C# source + // generators take care of generating those override methods. + output << INDENT2 "if (signal == SignalName." << isignal.proxy_name + << ")\n" INDENT2 "{\n" + << INDENT3 "if (" CS_METHOD_HAS_GODOT_CLASS_SIGNAL "(" + << CS_STATIC_FIELD_SIGNAL_PROXY_NAME_PREFIX << isignal.name + << ".NativeValue.DangerousSelfRef))\n" INDENT3 "{\n" + << INDENT4 "return true;\n" + << INDENT3 "}\n" INDENT2 "}\n"; + } + + if (is_derived_type) { + output << INDENT2 "return base." CS_METHOD_HAS_GODOT_CLASS_SIGNAL "(signal);\n"; + } else { + output << INDENT2 "return false;\n"; + } + + output << INDENT1 "}\n"; } //Generate StringName for all class members @@ -2058,9 +2062,9 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf << INDENT1 "private static readonly IntPtr " << method_bind_field << " = "; if (p_itype.is_singleton) { - // Singletons are static classes. They don't derive Godot.Object, + // Singletons are static classes. They don't derive GodotObject, // so we need to specify the type to call the static method. - p_output << "Object."; + p_output << "GodotObject."; } p_output << ICALL_CLASSDB_GET_METHOD "(" BINDINGS_NATIVE_NAME_FIELD ", MethodName." @@ -2775,6 +2779,18 @@ bool BindingsGenerator::_arg_default_value_is_assignable_to_type(const Variant & return false; } +bool method_has_ptr_parameter(MethodInfo p_method_info) { + if (p_method_info.return_val.type == Variant::INT && p_method_info.return_val.hint == PROPERTY_HINT_INT_IS_POINTER) { + return true; + } + for (PropertyInfo arg : p_method_info.arguments) { + if (arg.type == Variant::INT && arg.hint == PROPERTY_HINT_INT_IS_POINTER) { + return true; + } + } + return false; +} + bool BindingsGenerator::_populate_object_type_interfaces() { obj_types.clear(); @@ -2812,7 +2828,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(type_cname); - TypeInterface itype = TypeInterface::create_object_type(type_cname, api_type); + TypeInterface itype = TypeInterface::create_object_type(type_cname, pascal_to_pascal_case(type_cname), api_type); itype.base_name = ClassDB::get_parent_class(type_cname); itype.is_singleton = Engine::get_singleton()->has_singleton(itype.proxy_name); @@ -2827,9 +2843,9 @@ bool BindingsGenerator::_populate_object_type_interfaces() { itype.cs_type = itype.proxy_name; if (itype.is_singleton) { - itype.cs_in_expr = "Object." CS_STATIC_METHOD_GETINSTANCE "(" CS_PROPERTY_SINGLETON ")"; + itype.cs_in_expr = "GodotObject." CS_STATIC_METHOD_GETINSTANCE "(" CS_PROPERTY_SINGLETON ")"; } else { - itype.cs_in_expr = "Object." CS_STATIC_METHOD_GETINSTANCE "(%0)"; + itype.cs_in_expr = "GodotObject." CS_STATIC_METHOD_GETINSTANCE "(%0)"; } itype.cs_out = "%5return (%2)%0(%1);"; @@ -2837,7 +2853,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { itype.c_arg_in = "(void*)%s"; itype.c_type = "IntPtr"; itype.c_type_in = itype.c_type; - itype.c_type_out = "Object"; + itype.c_type_out = "GodotObject"; // Populate properties @@ -2918,6 +2934,11 @@ bool BindingsGenerator::_populate_object_type_interfaces() { continue; } + if (method_has_ptr_parameter(method_info)) { + // Pointers are not supported. + continue; + } + MethodInterface imethod; imethod.name = method_info.name; imethod.cname = cname; @@ -2979,7 +3000,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { } else if (return_info.type == Variant::NIL) { imethod.return_type.cname = name_cache.type_void; } else { - imethod.return_type.cname = _get_type_name_from_meta(return_info.type, m ? m->get_argument_meta(-1) : GodotTypeInfo::METADATA_NONE); + imethod.return_type.cname = _get_type_name_from_meta(return_info.type, m ? m->get_argument_meta(-1) : (GodotTypeInfo::Metadata)method_info.return_val_metadata); } for (int i = 0; i < argc; i++) { @@ -3003,7 +3024,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { } else if (arginfo.type == Variant::NIL) { iarg.type.cname = name_cache.type_Variant; } else { - iarg.type.cname = _get_type_name_from_meta(arginfo.type, m ? m->get_argument_meta(i) : GodotTypeInfo::METADATA_NONE); + iarg.type.cname = _get_type_name_from_meta(arginfo.type, m ? m->get_argument_meta(i) : (GodotTypeInfo::Metadata)method_info.get_argument_meta(i)); } iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name)); @@ -3103,7 +3124,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { } else if (arginfo.type == Variant::NIL) { iarg.type.cname = name_cache.type_Variant; } else { - iarg.type.cname = _get_type_name_from_meta(arginfo.type, GodotTypeInfo::METADATA_NONE); + iarg.type.cname = _get_type_name_from_meta(arginfo.type, (GodotTypeInfo::Metadata)method_info.get_argument_meta(i)); } iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name)); @@ -3152,7 +3173,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { for (const KeyValue<StringName, ClassDB::ClassInfo::EnumInfo> &E : enum_map) { StringName enum_proxy_cname = E.key; - String enum_proxy_name = enum_proxy_cname.operator String(); + String enum_proxy_name = pascal_to_pascal_case(enum_proxy_cname.operator String()); if (itype.find_property_by_proxy_name(enum_proxy_name) || itype.find_method_by_proxy_name(enum_proxy_name) || itype.find_signal_by_proxy_name(enum_proxy_name)) { // In case the enum name conflicts with other PascalCase members, // we append 'Enum' to the enum name in those cases. @@ -3280,7 +3301,7 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar } break; case Variant::AABB: { AABB aabb = p_val.operator ::AABB(); - r_iarg.default_argument = "new AABB(new Vector3" + aabb.position.operator String() + ", new Vector3" + aabb.size.operator String() + ")"; + r_iarg.default_argument = "new Aabb(new Vector3" + aabb.position.operator String() + ", new Vector3" + aabb.size.operator String() + ")"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; case Variant::RECT2: { @@ -3290,7 +3311,7 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar } break; case Variant::RECT2I: { Rect2i rect = p_val.operator Rect2i(); - r_iarg.default_argument = "new Rect2i(new Vector2i" + rect.position.operator String() + ", new Vector2i" + rect.size.operator String() + ")"; + r_iarg.default_argument = "new Rect2I(new Vector2I" + rect.position.operator String() + ", new Vector2I" + rect.size.operator String() + ")"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; case Variant::COLOR: @@ -3424,32 +3445,30 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { TypeInterface itype; -#define INSERT_STRUCT_TYPE(m_type) \ - { \ - itype = TypeInterface::create_value_type(String(#m_type)); \ - itype.c_type_in = #m_type "*"; \ - itype.c_type_out = itype.cs_type; \ - itype.cs_in_expr = "&%0"; \ - itype.cs_in_expr_is_unsafe = true; \ - builtin_types.insert(itype.cname, itype); \ - } - - INSERT_STRUCT_TYPE(Vector2) - INSERT_STRUCT_TYPE(Vector2i) - INSERT_STRUCT_TYPE(Rect2) - INSERT_STRUCT_TYPE(Rect2i) - INSERT_STRUCT_TYPE(Transform2D) - INSERT_STRUCT_TYPE(Vector3) - INSERT_STRUCT_TYPE(Vector3i) - INSERT_STRUCT_TYPE(Basis) - INSERT_STRUCT_TYPE(Quaternion) - INSERT_STRUCT_TYPE(Transform3D) - INSERT_STRUCT_TYPE(AABB) - INSERT_STRUCT_TYPE(Color) - INSERT_STRUCT_TYPE(Plane) - INSERT_STRUCT_TYPE(Vector4) - INSERT_STRUCT_TYPE(Vector4i) - INSERT_STRUCT_TYPE(Projection) +#define INSERT_STRUCT_TYPE(m_type, m_proxy_name) \ + { \ + itype = TypeInterface::create_value_type(String(#m_type), String(#m_proxy_name)); \ + itype.cs_in_expr = "&%0"; \ + itype.cs_in_expr_is_unsafe = true; \ + builtin_types.insert(itype.cname, itype); \ + } + + INSERT_STRUCT_TYPE(Vector2, Vector2) + INSERT_STRUCT_TYPE(Vector2i, Vector2I) + INSERT_STRUCT_TYPE(Rect2, Rect2) + INSERT_STRUCT_TYPE(Rect2i, Rect2I) + INSERT_STRUCT_TYPE(Transform2D, Transform2D) + INSERT_STRUCT_TYPE(Vector3, Vector3) + INSERT_STRUCT_TYPE(Vector3i, Vector3I) + INSERT_STRUCT_TYPE(Basis, Basis) + INSERT_STRUCT_TYPE(Quaternion, Quaternion) + INSERT_STRUCT_TYPE(Transform3D, Transform3D) + INSERT_STRUCT_TYPE(AABB, Aabb) + INSERT_STRUCT_TYPE(Color, Color) + INSERT_STRUCT_TYPE(Plane, Plane) + INSERT_STRUCT_TYPE(Vector4, Vector4) + INSERT_STRUCT_TYPE(Vector4i, Vector4I) + INSERT_STRUCT_TYPE(Projection, Projection) #undef INSERT_STRUCT_TYPE @@ -3588,7 +3607,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype = TypeInterface(); itype.name = "RID"; itype.cname = itype.name; - itype.proxy_name = "RID"; + itype.proxy_name = "Rid"; itype.cs_type = itype.proxy_name; itype.c_arg_in = "&%s"; itype.c_type = itype.cs_type; @@ -3802,7 +3821,7 @@ void BindingsGenerator::_populate_global_constants() { enum_itype.is_enum = true; enum_itype.name = ienum.cname.operator String(); enum_itype.cname = ienum.cname; - enum_itype.proxy_name = enum_itype.name; + enum_itype.proxy_name = pascal_to_pascal_case(enum_itype.name); TypeInterface::postsetup_enum_type(enum_itype); enum_types.insert(enum_itype.cname, enum_itype); @@ -3824,9 +3843,9 @@ void BindingsGenerator::_populate_global_constants() { // HARDCODED List<StringName> hardcoded_enums; hardcoded_enums.push_back("Vector2.Axis"); - hardcoded_enums.push_back("Vector2i.Axis"); + hardcoded_enums.push_back("Vector2I.Axis"); hardcoded_enums.push_back("Vector3.Axis"); - hardcoded_enums.push_back("Vector3i.Axis"); + hardcoded_enums.push_back("Vector3I.Axis"); for (const StringName &enum_cname : hardcoded_enums) { // These enums are not generated and must be written manually (e.g.: Vector3.Axis) // Here, we assume core types do not begin with underscore @@ -3834,7 +3853,7 @@ void BindingsGenerator::_populate_global_constants() { enum_itype.is_enum = true; enum_itype.name = enum_cname.operator String(); enum_itype.cname = enum_cname; - enum_itype.proxy_name = enum_itype.name; + enum_itype.proxy_name = pascal_to_pascal_case(enum_itype.name); TypeInterface::postsetup_enum_type(enum_itype); enum_types.insert(enum_itype.cname, enum_itype); } diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index cef8246032..5c266ed31f 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -472,43 +472,88 @@ class BindingsGenerator { } private: + static DocData::ClassDoc *_get_type_doc(TypeInterface &itype) { + String doc_name = itype.name.begins_with("_") ? itype.name.substr(1) : itype.name; + return &EditorHelp::get_doc_data()->class_list[doc_name]; + } + static void _init_value_type(TypeInterface &itype) { - itype.proxy_name = itype.name; + if (itype.proxy_name.is_empty()) { + itype.proxy_name = itype.name; + } - itype.c_type = itype.name; itype.cs_type = itype.proxy_name; - itype.c_type_in = itype.proxy_name + "*"; - itype.c_type_out = itype.proxy_name; - itype.class_doc = &EditorHelp::get_doc_data()->class_list[itype.proxy_name]; + itype.c_type = itype.cs_type; + itype.c_type_in = itype.cs_type + "*"; + itype.c_type_out = itype.cs_type; + + itype.class_doc = _get_type_doc(itype); + } + + static void _init_object_type(TypeInterface &itype, ClassDB::APIType p_api_type) { + if (itype.proxy_name.is_empty()) { + itype.proxy_name = itype.name; + } + + if (itype.proxy_name.begins_with("_")) { + itype.proxy_name = itype.proxy_name.substr(1); + } + + itype.api_type = p_api_type; + itype.is_object_type = true; + + itype.class_doc = _get_type_doc(itype); } public: - static TypeInterface create_value_type(const String &p_name) { + static TypeInterface create_value_type(const String &p_name, const String &p_proxy_name) { TypeInterface itype; itype.name = p_name; - itype.cname = StringName(p_name); + itype.cname = p_name; + itype.proxy_name = p_proxy_name; _init_value_type(itype); return itype; } - static TypeInterface create_value_type(const StringName &p_name) { + static TypeInterface create_value_type(const StringName &p_cname, const String &p_proxy_name) { TypeInterface itype; - itype.name = p_name.operator String(); + itype.name = p_cname; + itype.cname = p_cname; + itype.proxy_name = p_proxy_name; + _init_value_type(itype); + return itype; + } + + static TypeInterface create_value_type(const String &p_name) { + TypeInterface itype; + itype.name = p_name; itype.cname = p_name; _init_value_type(itype); return itype; } - static TypeInterface create_object_type(const StringName &p_cname, ClassDB::APIType p_api_type) { + static TypeInterface create_value_type(const StringName &p_cname) { TypeInterface itype; + itype.name = p_cname; + itype.cname = p_cname; + _init_value_type(itype); + return itype; + } + static TypeInterface create_object_type(const StringName &p_cname, const String &p_proxy_name, ClassDB::APIType p_api_type) { + TypeInterface itype; itype.name = p_cname; itype.cname = p_cname; - itype.proxy_name = itype.name.begins_with("_") ? itype.name.substr(1, itype.name.length()) : itype.name; - itype.api_type = p_api_type; - itype.is_object_type = true; - itype.class_doc = &EditorHelp::get_doc_data()->class_list[itype.proxy_name]; + itype.proxy_name = p_proxy_name; + _init_object_type(itype, p_api_type); + return itype; + } + static TypeInterface create_object_type(const StringName &p_cname, ClassDB::APIType p_api_type) { + TypeInterface itype; + itype.name = p_cname; + itype.cname = p_cname; + _init_object_type(itype, p_api_type); return itype; } diff --git a/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs b/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs index fbad482cf6..87468fb433 100644 --- a/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs +++ b/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs @@ -17,22 +17,22 @@ public partial class _CLASS_ : _BASE_ // Add the gravity. if (!IsOnFloor()) - velocity.y += gravity * (float)delta; + velocity.Y += gravity * (float)delta; // Handle Jump. if (Input.IsActionJustPressed("ui_accept") && IsOnFloor()) - velocity.y = JumpVelocity; + velocity.Y = JumpVelocity; // Get the input direction and handle the movement/deceleration. // As good practice, you should replace UI actions with custom gameplay actions. Vector2 direction = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down"); if (direction != Vector2.Zero) { - velocity.x = direction.x * Speed; + velocity.X = direction.X * Speed; } else { - velocity.x = Mathf.MoveToward(Velocity.x, 0, Speed); + velocity.X = Mathf.MoveToward(Velocity.X, 0, Speed); } Velocity = velocity; diff --git a/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs b/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs index abed246a1e..ddeb9d7e00 100644 --- a/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs +++ b/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs @@ -17,25 +17,25 @@ public partial class _CLASS_ : _BASE_ // Add the gravity. if (!IsOnFloor()) - velocity.y -= gravity * (float)delta; + velocity.Y -= gravity * (float)delta; // Handle Jump. if (Input.IsActionJustPressed("ui_accept") && IsOnFloor()) - velocity.y = JumpVelocity; + velocity.Y = JumpVelocity; // Get the input direction and handle the movement/deceleration. // As good practice, you should replace UI actions with custom gameplay actions. Vector2 inputDir = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down"); - Vector3 direction = (Transform.basis * new Vector3(inputDir.x, 0, inputDir.y)).Normalized(); + Vector3 direction = (Transform.Basis * new Vector3(inputDir.X, 0, inputDir.Y)).Normalized(); if (direction != Vector3.Zero) { - velocity.x = direction.x * Speed; - velocity.z = direction.z * Speed; + velocity.X = direction.X * Speed; + velocity.Z = direction.Z * Speed; } else { - velocity.x = Mathf.MoveToward(Velocity.x, 0, Speed); - velocity.z = Mathf.MoveToward(Velocity.z, 0, Speed); + velocity.X = Mathf.MoveToward(Velocity.X, 0, Speed); + velocity.Z = Mathf.MoveToward(Velocity.Z, 0, Speed); } Velocity = velocity; diff --git a/modules/mono/editor/script_templates/EditorScenePostImport/basic_import_script.cs b/modules/mono/editor/script_templates/EditorScenePostImport/basic_import_script.cs index 9e1b7ef580..fa2ff30a09 100644 --- a/modules/mono/editor/script_templates/EditorScenePostImport/basic_import_script.cs +++ b/modules/mono/editor/script_templates/EditorScenePostImport/basic_import_script.cs @@ -7,7 +7,7 @@ using System; [Tool] public partial class _CLASS_ : _BASE_ { - public override Godot.Object _PostImport(Node scene) + public override GodotObject _PostImport(Node scene) { // Modify the contents of the scene upon import. return scene; // Return the modified root node when you're done. diff --git a/modules/mono/editor/script_templates/EditorScenePostImport/no_comments.cs b/modules/mono/editor/script_templates/EditorScenePostImport/no_comments.cs index bf2c9434e4..4365ba5a04 100644 --- a/modules/mono/editor/script_templates/EditorScenePostImport/no_comments.cs +++ b/modules/mono/editor/script_templates/EditorScenePostImport/no_comments.cs @@ -7,7 +7,7 @@ using System; [Tool] public partial class _CLASS_ : _BASE_ { - public override Godot.Object _PostImport(Node scene) + public override GodotObject _PostImport(Node scene) { return scene; } diff --git a/modules/mono/glue/GodotSharp/GodotPlugins/GodotPlugins.csproj b/modules/mono/glue/GodotSharp/GodotPlugins/GodotPlugins.csproj index e720d3878c..e58d730ee3 100644 --- a/modules/mono/glue/GodotSharp/GodotPlugins/GodotPlugins.csproj +++ b/modules/mono/glue/GodotSharp/GodotPlugins/GodotPlugins.csproj @@ -8,6 +8,7 @@ <!-- To generate the .runtimeconfig.json file--> <EnableDynamicLoading>true</EnableDynamicLoading> + <RollForward>LatestMajor</RollForward> </PropertyGroup> <ItemGroup> diff --git a/modules/mono/glue/GodotSharp/GodotPlugins/Main.cs b/modules/mono/glue/GodotSharp/GodotPlugins/Main.cs index 4ce02d221e..2a72b7c53e 100644 --- a/modules/mono/glue/GodotSharp/GodotPlugins/Main.cs +++ b/modules/mono/glue/GodotSharp/GodotPlugins/Main.cs @@ -65,7 +65,7 @@ namespace GodotPlugins } private static readonly List<AssemblyName> SharedAssemblies = new(); - private static readonly Assembly CoreApiAssembly = typeof(Godot.Object).Assembly; + private static readonly Assembly CoreApiAssembly = typeof(global::Godot.GodotObject).Assembly; private static Assembly? _editorApiAssembly; private static PluginLoadContextWrapper? _projectLoadContext; private static bool _editorHint = false; diff --git a/modules/mono/glue/GodotSharp/GodotPlugins/PluginLoadContext.cs b/modules/mono/glue/GodotSharp/GodotPlugins/PluginLoadContext.cs index 344b76a202..93baf4e51c 100644 --- a/modules/mono/glue/GodotSharp/GodotPlugins/PluginLoadContext.cs +++ b/modules/mono/glue/GodotSharp/GodotPlugins/PluginLoadContext.cs @@ -21,6 +21,26 @@ namespace GodotPlugins _resolver = new AssemblyDependencyResolver(pluginPath); _sharedAssemblies = sharedAssemblies; _mainLoadContext = mainLoadContext; + + if (string.IsNullOrEmpty(AppContext.BaseDirectory)) + { + // See https://github.com/dotnet/runtime/blob/v6.0.0/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs#L17-L35 + // but Assembly.Location is unavailable, because we load assemblies from memory. + string? baseDirectory = Path.GetDirectoryName(pluginPath); + if (baseDirectory != null) + { + if (!Path.EndsInDirectorySeparator(baseDirectory)) + baseDirectory += Path.DirectorySeparatorChar; + // This SetData call effectively sets AppContext.BaseDirectory + // See https://github.com/dotnet/runtime/blob/v6.0.0/src/libraries/System.Private.CoreLib/src/System/AppContext.cs#L21-L25 + AppDomain.CurrentDomain.SetData("APP_CONTEXT_BASE_DIRECTORY", baseDirectory); + } + else + { + // TODO: How to log from GodotPlugins? (delegate pointer?) + Console.Error.WriteLine("Failed to set AppContext.BaseDirectory. Dynamic loading of libraries may fail."); + } + } } protected override Assembly? Load(AssemblyName assemblyName) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Aabb.cs index 0e46b63b59..af83cc24bf 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Aabb.cs @@ -9,7 +9,7 @@ namespace Godot /// </summary> [Serializable] [StructLayout(LayoutKind.Sequential)] - public struct AABB : IEquatable<AABB> + public struct Aabb : IEquatable<Aabb> { private Vector3 _position; private Vector3 _size; @@ -50,19 +50,28 @@ namespace Godot } /// <summary> - /// Returns an <see cref="AABB"/> with equivalent position and size, modified so that + /// The volume of this <see cref="Aabb"/>. + /// See also <see cref="HasVolume"/>. + /// </summary> + public readonly real_t Volume + { + get { return _size.X * _size.Y * _size.Z; } + } + + /// <summary> + /// Returns an <see cref="Aabb"/> with equivalent position and size, modified so that /// the most-negative corner is the origin and the size is positive. /// </summary> - /// <returns>The modified <see cref="AABB"/>.</returns> - public readonly AABB Abs() + /// <returns>The modified <see cref="Aabb"/>.</returns> + public readonly Aabb Abs() { Vector3 end = End; - Vector3 topLeft = new Vector3(Mathf.Min(_position.x, end.x), Mathf.Min(_position.y, end.y), Mathf.Min(_position.z, end.z)); - return new AABB(topLeft, _size.Abs()); + Vector3 topLeft = new Vector3(Mathf.Min(_position.X, end.X), Mathf.Min(_position.Y, end.Y), Mathf.Min(_position.Z, end.Z)); + return new Aabb(topLeft, _size.Abs()); } /// <summary> - /// Returns the center of the <see cref="AABB"/>, which is equal + /// Returns the center of the <see cref="Aabb"/>, which is equal /// to <see cref="Position"/> + (<see cref="Size"/> / 2). /// </summary> /// <returns>The center.</returns> @@ -72,94 +81,94 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if this <see cref="AABB"/> completely encloses another one. + /// Returns <see langword="true"/> if this <see cref="Aabb"/> completely encloses another one. /// </summary> - /// <param name="with">The other <see cref="AABB"/> that may be enclosed.</param> + /// <param name="with">The other <see cref="Aabb"/> that may be enclosed.</param> /// <returns> - /// A <see langword="bool"/> for whether or not this <see cref="AABB"/> encloses <paramref name="with"/>. + /// A <see langword="bool"/> for whether or not this <see cref="Aabb"/> encloses <paramref name="with"/>. /// </returns> - public readonly bool Encloses(AABB with) + public readonly bool Encloses(Aabb with) { Vector3 srcMin = _position; Vector3 srcMax = _position + _size; Vector3 dstMin = with._position; Vector3 dstMax = with._position + with._size; - return srcMin.x <= dstMin.x && - srcMax.x > dstMax.x && - srcMin.y <= dstMin.y && - srcMax.y > dstMax.y && - srcMin.z <= dstMin.z && - srcMax.z > dstMax.z; + return srcMin.X <= dstMin.X && + srcMax.X > dstMax.X && + srcMin.Y <= dstMin.Y && + srcMax.Y > dstMax.Y && + srcMin.Z <= dstMin.Z && + srcMax.Z > dstMax.Z; } /// <summary> - /// Returns this <see cref="AABB"/> expanded to include a given point. + /// Returns this <see cref="Aabb"/> expanded to include a given point. /// </summary> /// <param name="point">The point to include.</param> - /// <returns>The expanded <see cref="AABB"/>.</returns> - public readonly AABB Expand(Vector3 point) + /// <returns>The expanded <see cref="Aabb"/>.</returns> + public readonly Aabb Expand(Vector3 point) { Vector3 begin = _position; Vector3 end = _position + _size; - if (point.x < begin.x) + if (point.X < begin.X) { - begin.x = point.x; + begin.X = point.X; } - if (point.y < begin.y) + if (point.Y < begin.Y) { - begin.y = point.y; + begin.Y = point.Y; } - if (point.z < begin.z) + if (point.Z < begin.Z) { - begin.z = point.z; + begin.Z = point.Z; } - if (point.x > end.x) + if (point.X > end.X) { - end.x = point.x; + end.X = point.X; } - if (point.y > end.y) + if (point.Y > end.Y) { - end.y = point.y; + end.Y = point.Y; } - if (point.z > end.z) + if (point.Z > end.Z) { - end.z = point.z; + end.Z = point.Z; } - return new AABB(begin, end - begin); + return new Aabb(begin, end - begin); } /// <summary> - /// Gets the position of one of the 8 endpoints of the <see cref="AABB"/>. + /// Gets the position of one of the 8 endpoints of the <see cref="Aabb"/>. /// </summary> /// <param name="idx">Which endpoint to get.</param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="idx"/> is less than 0 or greater than 7. /// </exception> - /// <returns>An endpoint of the <see cref="AABB"/>.</returns> + /// <returns>An endpoint of the <see cref="Aabb"/>.</returns> public readonly Vector3 GetEndpoint(int idx) { switch (idx) { case 0: - return new Vector3(_position.x, _position.y, _position.z); + return new Vector3(_position.X, _position.Y, _position.Z); case 1: - return new Vector3(_position.x, _position.y, _position.z + _size.z); + return new Vector3(_position.X, _position.Y, _position.Z + _size.Z); case 2: - return new Vector3(_position.x, _position.y + _size.y, _position.z); + return new Vector3(_position.X, _position.Y + _size.Y, _position.Z); case 3: - return new Vector3(_position.x, _position.y + _size.y, _position.z + _size.z); + return new Vector3(_position.X, _position.Y + _size.Y, _position.Z + _size.Z); case 4: - return new Vector3(_position.x + _size.x, _position.y, _position.z); + return new Vector3(_position.X + _size.X, _position.Y, _position.Z); case 5: - return new Vector3(_position.x + _size.x, _position.y, _position.z + _size.z); + return new Vector3(_position.X + _size.X, _position.Y, _position.Z + _size.Z); case 6: - return new Vector3(_position.x + _size.x, _position.y + _size.y, _position.z); + return new Vector3(_position.X + _size.X, _position.Y + _size.Y, _position.Z); case 7: - return new Vector3(_position.x + _size.x, _position.y + _size.y, _position.z + _size.z); + return new Vector3(_position.X + _size.X, _position.Y + _size.Y, _position.Z + _size.Z); default: { throw new ArgumentOutOfRangeException(nameof(idx), @@ -169,21 +178,21 @@ namespace Godot } /// <summary> - /// Returns the normalized longest axis of the <see cref="AABB"/>. + /// Returns the normalized longest axis of the <see cref="Aabb"/>. /// </summary> - /// <returns>A vector representing the normalized longest axis of the <see cref="AABB"/>.</returns> + /// <returns>A vector representing the normalized longest axis of the <see cref="Aabb"/>.</returns> public readonly Vector3 GetLongestAxis() { var axis = new Vector3(1f, 0f, 0f); - real_t maxSize = _size.x; + real_t maxSize = _size.X; - if (_size.y > maxSize) + if (_size.Y > maxSize) { axis = new Vector3(0f, 1f, 0f); - maxSize = _size.y; + maxSize = _size.Y; } - if (_size.z > maxSize) + if (_size.Z > maxSize) { axis = new Vector3(0f, 0f, 1f); } @@ -192,21 +201,21 @@ namespace Godot } /// <summary> - /// Returns the <see cref="Vector3.Axis"/> index of the longest axis of the <see cref="AABB"/>. + /// Returns the <see cref="Vector3.Axis"/> index of the longest axis of the <see cref="Aabb"/>. /// </summary> /// <returns>A <see cref="Vector3.Axis"/> index for which axis is longest.</returns> public readonly Vector3.Axis GetLongestAxisIndex() { var axis = Vector3.Axis.X; - real_t maxSize = _size.x; + real_t maxSize = _size.X; - if (_size.y > maxSize) + if (_size.Y > maxSize) { axis = Vector3.Axis.Y; - maxSize = _size.y; + maxSize = _size.Y; } - if (_size.z > maxSize) + if (_size.Z > maxSize) { axis = Vector3.Axis.Z; } @@ -215,38 +224,38 @@ namespace Godot } /// <summary> - /// Returns the scalar length of the longest axis of the <see cref="AABB"/>. + /// Returns the scalar length of the longest axis of the <see cref="Aabb"/>. /// </summary> - /// <returns>The scalar length of the longest axis of the <see cref="AABB"/>.</returns> + /// <returns>The scalar length of the longest axis of the <see cref="Aabb"/>.</returns> public readonly real_t GetLongestAxisSize() { - real_t maxSize = _size.x; + real_t maxSize = _size.X; - if (_size.y > maxSize) - maxSize = _size.y; + if (_size.Y > maxSize) + maxSize = _size.Y; - if (_size.z > maxSize) - maxSize = _size.z; + if (_size.Z > maxSize) + maxSize = _size.Z; return maxSize; } /// <summary> - /// Returns the normalized shortest axis of the <see cref="AABB"/>. + /// Returns the normalized shortest axis of the <see cref="Aabb"/>. /// </summary> - /// <returns>A vector representing the normalized shortest axis of the <see cref="AABB"/>.</returns> + /// <returns>A vector representing the normalized shortest axis of the <see cref="Aabb"/>.</returns> public readonly Vector3 GetShortestAxis() { var axis = new Vector3(1f, 0f, 0f); - real_t maxSize = _size.x; + real_t maxSize = _size.X; - if (_size.y < maxSize) + if (_size.Y < maxSize) { axis = new Vector3(0f, 1f, 0f); - maxSize = _size.y; + maxSize = _size.Y; } - if (_size.z < maxSize) + if (_size.Z < maxSize) { axis = new Vector3(0f, 0f, 1f); } @@ -255,21 +264,21 @@ namespace Godot } /// <summary> - /// Returns the <see cref="Vector3.Axis"/> index of the shortest axis of the <see cref="AABB"/>. + /// Returns the <see cref="Vector3.Axis"/> index of the shortest axis of the <see cref="Aabb"/>. /// </summary> /// <returns>A <see cref="Vector3.Axis"/> index for which axis is shortest.</returns> public readonly Vector3.Axis GetShortestAxisIndex() { var axis = Vector3.Axis.X; - real_t maxSize = _size.x; + real_t maxSize = _size.X; - if (_size.y < maxSize) + if (_size.Y < maxSize) { axis = Vector3.Axis.Y; - maxSize = _size.y; + maxSize = _size.Y; } - if (_size.z < maxSize) + if (_size.Z < maxSize) { axis = Vector3.Axis.Z; } @@ -278,18 +287,18 @@ namespace Godot } /// <summary> - /// Returns the scalar length of the shortest axis of the <see cref="AABB"/>. + /// Returns the scalar length of the shortest axis of the <see cref="Aabb"/>. /// </summary> - /// <returns>The scalar length of the shortest axis of the <see cref="AABB"/>.</returns> + /// <returns>The scalar length of the shortest axis of the <see cref="Aabb"/>.</returns> public readonly real_t GetShortestAxisSize() { - real_t maxSize = _size.x; + real_t maxSize = _size.X; - if (_size.y < maxSize) - maxSize = _size.y; + if (_size.Y < maxSize) + maxSize = _size.Y; - if (_size.z < maxSize) - maxSize = _size.z; + if (_size.Z < maxSize) + maxSize = _size.Z; return maxSize; } @@ -306,99 +315,90 @@ namespace Godot Vector3 ofs = _position + halfExtents; return ofs + new Vector3( - dir.x > 0f ? -halfExtents.x : halfExtents.x, - dir.y > 0f ? -halfExtents.y : halfExtents.y, - dir.z > 0f ? -halfExtents.z : halfExtents.z); - } - - /// <summary> - /// Returns the volume of the <see cref="AABB"/>. - /// </summary> - /// <returns>The volume.</returns> - public readonly real_t GetVolume() - { - return _size.x * _size.y * _size.z; + dir.X > 0f ? -halfExtents.X : halfExtents.X, + dir.Y > 0f ? -halfExtents.Y : halfExtents.Y, + dir.Z > 0f ? -halfExtents.Z : halfExtents.Z); } /// <summary> - /// Returns a copy of the <see cref="AABB"/> grown a given amount of units towards all the sides. + /// Returns a copy of the <see cref="Aabb"/> grown a given amount of units towards all the sides. /// </summary> /// <param name="by">The amount to grow by.</param> - /// <returns>The grown <see cref="AABB"/>.</returns> - public readonly AABB Grow(real_t by) + /// <returns>The grown <see cref="Aabb"/>.</returns> + public readonly Aabb Grow(real_t by) { - AABB res = this; + Aabb res = this; - res._position.x -= by; - res._position.y -= by; - res._position.z -= by; - res._size.x += 2.0f * by; - res._size.y += 2.0f * by; - res._size.z += 2.0f * by; + res._position.X -= by; + res._position.Y -= by; + res._position.Z -= by; + res._size.X += 2.0f * by; + res._size.Y += 2.0f * by; + res._size.Z += 2.0f * by; return res; } /// <summary> - /// Returns <see langword="true"/> if the <see cref="AABB"/> contains a point, + /// Returns <see langword="true"/> if the <see cref="Aabb"/> contains a point, /// or <see langword="false"/> otherwise. /// </summary> /// <param name="point">The point to check.</param> /// <returns> - /// A <see langword="bool"/> for whether or not the <see cref="AABB"/> contains <paramref name="point"/>. + /// A <see langword="bool"/> for whether or not the <see cref="Aabb"/> contains <paramref name="point"/>. /// </returns> public readonly bool HasPoint(Vector3 point) { - if (point.x < _position.x) + if (point.X < _position.X) return false; - if (point.y < _position.y) + if (point.Y < _position.Y) return false; - if (point.z < _position.z) + if (point.Z < _position.Z) return false; - if (point.x > _position.x + _size.x) + if (point.X > _position.X + _size.X) return false; - if (point.y > _position.y + _size.y) + if (point.Y > _position.Y + _size.Y) return false; - if (point.z > _position.z + _size.z) + if (point.Z > _position.Z + _size.Z) return false; return true; } /// <summary> - /// Returns <see langword="true"/> if the <see cref="AABB"/> + /// Returns <see langword="true"/> if the <see cref="Aabb"/> /// has a surface or a length, and <see langword="false"/> - /// if the <see cref="AABB"/> is empty (all components + /// if the <see cref="Aabb"/> is empty (all components /// of <see cref="Size"/> are zero or negative). /// </summary> /// <returns> - /// A <see langword="bool"/> for whether or not the <see cref="AABB"/> has surface. + /// A <see langword="bool"/> for whether or not the <see cref="Aabb"/> has surface. /// </returns> public readonly bool HasSurface() { - return _size.x > 0.0f || _size.y > 0.0f || _size.z > 0.0f; + return _size.X > 0.0f || _size.Y > 0.0f || _size.Z > 0.0f; } /// <summary> - /// Returns <see langword="true"/> if the <see cref="AABB"/> has - /// area, and <see langword="false"/> if the <see cref="AABB"/> + /// Returns <see langword="true"/> if the <see cref="Aabb"/> has + /// area, and <see langword="false"/> if the <see cref="Aabb"/> /// is linear, empty, or has a negative <see cref="Size"/>. - /// See also <see cref="GetVolume"/>. + /// See also <see cref="Volume"/>. /// </summary> /// <returns> - /// A <see langword="bool"/> for whether or not the <see cref="AABB"/> has volume. + /// A <see langword="bool"/> for whether or not the <see cref="Aabb"/> has volume. /// </returns> public readonly bool HasVolume() { - return _size.x > 0.0f && _size.y > 0.0f && _size.z > 0.0f; + return _size.X > 0.0f && _size.Y > 0.0f && _size.Z > 0.0f; } /// <summary> - /// Returns the intersection of this <see cref="AABB"/> and <paramref name="with"/>. + /// Returns the intersection of this <see cref="Aabb"/> and <paramref name="with"/>. /// </summary> - /// <param name="with">The other <see cref="AABB"/>.</param> - /// <returns>The clipped <see cref="AABB"/>.</returns> - public readonly AABB Intersection(AABB with) + /// <param name="with">The other <see cref="Aabb"/>.</param> + /// <returns>The clipped <see cref="Aabb"/>.</returns> + public readonly Aabb Intersection(Aabb with) { Vector3 srcMin = _position; Vector3 srcMax = _position + _size; @@ -407,78 +407,78 @@ namespace Godot Vector3 min, max; - if (srcMin.x > dstMax.x || srcMax.x < dstMin.x) + if (srcMin.X > dstMax.X || srcMax.X < dstMin.X) { - return new AABB(); + return new Aabb(); } - min.x = srcMin.x > dstMin.x ? srcMin.x : dstMin.x; - max.x = srcMax.x < dstMax.x ? srcMax.x : dstMax.x; + min.X = srcMin.X > dstMin.X ? srcMin.X : dstMin.X; + max.X = srcMax.X < dstMax.X ? srcMax.X : dstMax.X; - if (srcMin.y > dstMax.y || srcMax.y < dstMin.y) + if (srcMin.Y > dstMax.Y || srcMax.Y < dstMin.Y) { - return new AABB(); + return new Aabb(); } - min.y = srcMin.y > dstMin.y ? srcMin.y : dstMin.y; - max.y = srcMax.y < dstMax.y ? srcMax.y : dstMax.y; + min.Y = srcMin.Y > dstMin.Y ? srcMin.Y : dstMin.Y; + max.Y = srcMax.Y < dstMax.Y ? srcMax.Y : dstMax.Y; - if (srcMin.z > dstMax.z || srcMax.z < dstMin.z) + if (srcMin.Z > dstMax.Z || srcMax.Z < dstMin.Z) { - return new AABB(); + return new Aabb(); } - min.z = srcMin.z > dstMin.z ? srcMin.z : dstMin.z; - max.z = srcMax.z < dstMax.z ? srcMax.z : dstMax.z; + min.Z = srcMin.Z > dstMin.Z ? srcMin.Z : dstMin.Z; + max.Z = srcMax.Z < dstMax.Z ? srcMax.Z : dstMax.Z; - return new AABB(min, max - min); + return new Aabb(min, max - min); } /// <summary> - /// Returns <see langword="true"/> if the <see cref="AABB"/> overlaps with <paramref name="with"/> + /// Returns <see langword="true"/> if the <see cref="Aabb"/> overlaps with <paramref name="with"/> /// (i.e. they have at least one point in common). /// </summary> - /// <param name="with">The other <see cref="AABB"/> to check for intersections with.</param> + /// <param name="with">The other <see cref="Aabb"/> to check for intersections with.</param> /// <returns> /// A <see langword="bool"/> for whether or not they are intersecting. /// </returns> - public readonly bool Intersects(AABB with) + public readonly bool Intersects(Aabb with) { - if (_position.x >= with._position.x + with._size.x) + if (_position.X >= with._position.X + with._size.X) return false; - if (_position.x + _size.x <= with._position.x) + if (_position.X + _size.X <= with._position.X) return false; - if (_position.y >= with._position.y + with._size.y) + if (_position.Y >= with._position.Y + with._size.Y) return false; - if (_position.y + _size.y <= with._position.y) + if (_position.Y + _size.Y <= with._position.Y) return false; - if (_position.z >= with._position.z + with._size.z) + if (_position.Z >= with._position.Z + with._size.Z) return false; - if (_position.z + _size.z <= with._position.z) + if (_position.Z + _size.Z <= with._position.Z) return false; return true; } /// <summary> - /// Returns <see langword="true"/> if the <see cref="AABB"/> is on both sides of <paramref name="plane"/>. + /// Returns <see langword="true"/> if the <see cref="Aabb"/> is on both sides of <paramref name="plane"/>. /// </summary> /// <param name="plane">The <see cref="Plane"/> to check for intersection.</param> /// <returns> - /// A <see langword="bool"/> for whether or not the <see cref="AABB"/> intersects the <see cref="Plane"/>. + /// A <see langword="bool"/> for whether or not the <see cref="Aabb"/> intersects the <see cref="Plane"/>. /// </returns> public readonly bool IntersectsPlane(Plane plane) { Vector3[] points = { - new Vector3(_position.x, _position.y, _position.z), - new Vector3(_position.x, _position.y, _position.z + _size.z), - new Vector3(_position.x, _position.y + _size.y, _position.z), - new Vector3(_position.x, _position.y + _size.y, _position.z + _size.z), - new Vector3(_position.x + _size.x, _position.y, _position.z), - new Vector3(_position.x + _size.x, _position.y, _position.z + _size.z), - new Vector3(_position.x + _size.x, _position.y + _size.y, _position.z), - new Vector3(_position.x + _size.x, _position.y + _size.y, _position.z + _size.z) + new Vector3(_position.X, _position.Y, _position.Z), + new Vector3(_position.X, _position.Y, _position.Z + _size.Z), + new Vector3(_position.X, _position.Y + _size.Y, _position.Z), + new Vector3(_position.X, _position.Y + _size.Y, _position.Z + _size.Z), + new Vector3(_position.X + _size.X, _position.Y, _position.Z), + new Vector3(_position.X + _size.X, _position.Y, _position.Z + _size.Z), + new Vector3(_position.X + _size.X, _position.Y + _size.Y, _position.Z), + new Vector3(_position.X + _size.X, _position.Y + _size.Y, _position.Z + _size.Z) }; bool over = false; @@ -500,13 +500,13 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if the <see cref="AABB"/> intersects + /// Returns <see langword="true"/> if the <see cref="Aabb"/> intersects /// the line segment between <paramref name="from"/> and <paramref name="to"/>. /// </summary> /// <param name="from">The start of the line segment.</param> /// <param name="to">The end of the line segment.</param> /// <returns> - /// A <see langword="bool"/> for whether or not the <see cref="AABB"/> intersects the line segment. + /// A <see langword="bool"/> for whether or not the <see cref="Aabb"/> intersects the line segment. /// </returns> public readonly bool IntersectsSegment(Vector3 from, Vector3 to) { @@ -563,7 +563,7 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if this <see cref="AABB"/> is finite, by calling + /// Returns <see langword="true"/> if this <see cref="Aabb"/> is finite, by calling /// <see cref="Mathf.IsFinite"/> on each component. /// </summary> /// <returns>Whether this vector is finite or not.</returns> @@ -573,73 +573,73 @@ namespace Godot } /// <summary> - /// Returns a larger <see cref="AABB"/> that contains this <see cref="AABB"/> and <paramref name="with"/>. + /// Returns a larger <see cref="Aabb"/> that contains this <see cref="Aabb"/> and <paramref name="with"/>. /// </summary> - /// <param name="with">The other <see cref="AABB"/>.</param> - /// <returns>The merged <see cref="AABB"/>.</returns> - public readonly AABB Merge(AABB with) + /// <param name="with">The other <see cref="Aabb"/>.</param> + /// <returns>The merged <see cref="Aabb"/>.</returns> + public readonly Aabb Merge(Aabb with) { Vector3 beg1 = _position; Vector3 beg2 = with._position; - var end1 = new Vector3(_size.x, _size.y, _size.z) + beg1; - var end2 = new Vector3(with._size.x, with._size.y, with._size.z) + beg2; + var end1 = new Vector3(_size.X, _size.Y, _size.Z) + beg1; + var end2 = new Vector3(with._size.X, with._size.Y, with._size.Z) + beg2; var min = new Vector3( - beg1.x < beg2.x ? beg1.x : beg2.x, - beg1.y < beg2.y ? beg1.y : beg2.y, - beg1.z < beg2.z ? beg1.z : beg2.z + beg1.X < beg2.X ? beg1.X : beg2.X, + beg1.Y < beg2.Y ? beg1.Y : beg2.Y, + beg1.Z < beg2.Z ? beg1.Z : beg2.Z ); var max = new Vector3( - end1.x > end2.x ? end1.x : end2.x, - end1.y > end2.y ? end1.y : end2.y, - end1.z > end2.z ? end1.z : end2.z + end1.X > end2.X ? end1.X : end2.X, + end1.Y > end2.Y ? end1.Y : end2.Y, + end1.Z > end2.Z ? end1.Z : end2.Z ); - return new AABB(min, max - min); + return new Aabb(min, max - min); } /// <summary> - /// Constructs an <see cref="AABB"/> from a position and size. + /// Constructs an <see cref="Aabb"/> from a position and size. /// </summary> /// <param name="position">The position.</param> /// <param name="size">The size, typically positive.</param> - public AABB(Vector3 position, Vector3 size) + public Aabb(Vector3 position, Vector3 size) { _position = position; _size = size; } /// <summary> - /// Constructs an <see cref="AABB"/> from a <paramref name="position"/>, + /// Constructs an <see cref="Aabb"/> from a <paramref name="position"/>, /// <paramref name="width"/>, <paramref name="height"/>, and <paramref name="depth"/>. /// </summary> /// <param name="position">The position.</param> /// <param name="width">The width, typically positive.</param> /// <param name="height">The height, typically positive.</param> /// <param name="depth">The depth, typically positive.</param> - public AABB(Vector3 position, real_t width, real_t height, real_t depth) + public Aabb(Vector3 position, real_t width, real_t height, real_t depth) { _position = position; _size = new Vector3(width, height, depth); } /// <summary> - /// Constructs an <see cref="AABB"/> from <paramref name="x"/>, + /// Constructs an <see cref="Aabb"/> from <paramref name="x"/>, /// <paramref name="y"/>, <paramref name="z"/>, and <paramref name="size"/>. /// </summary> /// <param name="x">The position's X coordinate.</param> /// <param name="y">The position's Y coordinate.</param> /// <param name="z">The position's Z coordinate.</param> /// <param name="size">The size, typically positive.</param> - public AABB(real_t x, real_t y, real_t z, Vector3 size) + public Aabb(real_t x, real_t y, real_t z, Vector3 size) { _position = new Vector3(x, y, z); _size = size; } /// <summary> - /// Constructs an <see cref="AABB"/> from <paramref name="x"/>, + /// Constructs an <see cref="Aabb"/> from <paramref name="x"/>, /// <paramref name="y"/>, <paramref name="z"/>, <paramref name="width"/>, /// <paramref name="height"/>, and <paramref name="depth"/>. /// </summary> @@ -649,7 +649,7 @@ namespace Godot /// <param name="width">The width, typically positive.</param> /// <param name="height">The height, typically positive.</param> /// <param name="depth">The depth, typically positive.</param> - public AABB(real_t x, real_t y, real_t z, real_t width, real_t height, real_t depth) + public Aabb(real_t x, real_t y, real_t z, real_t width, real_t height, real_t depth) { _position = new Vector3(x, y, z); _size = new Vector3(width, height, depth); @@ -663,7 +663,7 @@ namespace Godot /// <param name="left">The left AABB.</param> /// <param name="right">The right AABB.</param> /// <returns>Whether or not the AABBs are exactly equal.</returns> - public static bool operator ==(AABB left, AABB right) + public static bool operator ==(Aabb left, Aabb right) { return left.Equals(right); } @@ -676,7 +676,7 @@ namespace Godot /// <param name="left">The left AABB.</param> /// <param name="right">The right AABB.</param> /// <returns>Whether or not the AABBs are not equal.</returns> - public static bool operator !=(AABB left, AABB right) + public static bool operator !=(Aabb left, Aabb right) { return !left.Equals(right); } @@ -691,7 +691,7 @@ namespace Godot /// <returns>Whether or not the AABB and the object are equal.</returns> public override readonly bool Equals(object obj) { - return obj is AABB other && Equals(other); + return obj is Aabb other && Equals(other); } /// <summary> @@ -701,7 +701,7 @@ namespace Godot /// </summary> /// <param name="other">The other AABB.</param> /// <returns>Whether or not the AABBs are exactly equal.</returns> - public readonly bool Equals(AABB other) + public readonly bool Equals(Aabb other) { return _position == other._position && _size == other._size; } @@ -712,13 +712,13 @@ namespace Godot /// </summary> /// <param name="other">The other AABB to compare.</param> /// <returns>Whether or not the AABBs structures are approximately equal.</returns> - public readonly bool IsEqualApprox(AABB other) + public readonly bool IsEqualApprox(Aabb other) { return _position.IsEqualApprox(other._position) && _size.IsEqualApprox(other._size); } /// <summary> - /// Serves as the hash function for <see cref="AABB"/>. + /// Serves as the hash function for <see cref="Aabb"/>. /// </summary> /// <returns>A hash code for this AABB.</returns> public override readonly int GetHashCode() @@ -727,7 +727,7 @@ namespace Godot } /// <summary> - /// Converts this <see cref="AABB"/> to a string. + /// Converts this <see cref="Aabb"/> to a string. /// </summary> /// <returns>A string representation of this AABB.</returns> public override readonly string ToString() @@ -736,7 +736,7 @@ namespace Godot } /// <summary> - /// Converts this <see cref="AABB"/> to a string with the given <paramref name="format"/>. + /// Converts this <see cref="Aabb"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this AABB.</returns> public readonly string ToString(string format) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs index df306e5244..8598c32760 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.Linq; using System.Runtime.CompilerServices; using Godot.NativeInterop; @@ -99,7 +100,7 @@ namespace Godot.Collections this[i] = array[i]; } - public Array(Span<RID> array) : this() + public Array(Span<Rid> array) : this() { if (array == null) throw new ArgumentNullException(nameof(array)); @@ -120,7 +121,7 @@ namespace Godot.Collections // fine as long as the array is not mutated. However, Span does this type checking at // instantiation, so it's not possible to use it even when not mutating anything. // ReSharper disable once RedundantNameQualifier - public Array(ReadOnlySpan<Godot.Object> array) : this() + public Array(ReadOnlySpan<GodotObject> array) : this() { if (array == null) throw new ArgumentNullException(nameof(array)); @@ -174,7 +175,15 @@ namespace Godot.Collections } /// <summary> - /// Duplicates this <see cref="Array"/>. + /// Returns a copy of the <see cref="Array"/>. + /// If <paramref name="deep"/> is <see langword="true"/>, a deep copy if performed: + /// all nested arrays and dictionaries are duplicated and will not be shared with + /// the original array. If <see langword="false"/>, a shallow copy is made and + /// references to the original nested arrays and dictionaries are kept, so that + /// modifying a sub-array or dictionary in the copy will also impact those + /// referenced in the source array. Note that any <see cref="GodotObject"/> derived + /// elements will be shallow copied regardless of the <paramref name="deep"/> + /// setting. /// </summary> /// <param name="deep">If <see langword="true"/>, performs a deep copy.</param> /// <returns>A new Godot Array.</returns> @@ -187,27 +196,247 @@ namespace Godot.Collections } /// <summary> - /// Resizes this <see cref="Array"/> to the given size. + /// Assigns the given value to all elements in the array. This can typically be + /// used together with <see cref="Resize(int)"/> to create an array with a given + /// size and initialized elements. + /// Note: If <paramref name="value"/> is of a reference type (<see cref="GodotObject"/> + /// derived, <see cref="Array"/> or <see cref="Dictionary"/>, etc.) then the array + /// is filled with the references to the same object, i.e. no duplicates are + /// created. /// </summary> + /// <example> + /// <code> + /// var array = new Godot.Collections.Array(); + /// array.Resize(10); + /// array.Fill(0); // Initialize the 10 elements to 0. + /// </code> + /// </example> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> + /// <param name="value">The value to fill the array with.</param> + public void Fill(Variant value) + { + ThrowIfReadOnly(); + + godot_variant variantValue = (godot_variant)value.NativeVar; + var self = (godot_array)NativeValue; + NativeFuncs.godotsharp_array_fill(ref self, variantValue); + } + + /// <summary> + /// Returns the maximum value contained in the array if all elements are of + /// comparable types. If the elements can't be compared, <see langword="null"/> + /// is returned. + /// </summary> + /// <returns>The maximum value contained in the array.</returns> + public Variant Max() + { + godot_variant resVariant; + var self = (godot_array)NativeValue; + NativeFuncs.godotsharp_array_max(ref self, out resVariant); + return Variant.CreateTakingOwnershipOfDisposableValue(resVariant); + } + + /// <summary> + /// Returns the minimum value contained in the array if all elements are of + /// comparable types. If the elements can't be compared, <see langword="null"/> + /// is returned. + /// </summary> + /// <returns>The minimum value contained in the array.</returns> + public Variant Min() + { + godot_variant resVariant; + var self = (godot_array)NativeValue; + NativeFuncs.godotsharp_array_min(ref self, out resVariant); + return Variant.CreateTakingOwnershipOfDisposableValue(resVariant); + } + + /// <summary> + /// Returns a random value from the target array. + /// </summary> + /// <example> + /// <code> + /// var array = new Godot.Collections.Array { 1, 2, 3, 4 }; + /// GD.Print(array.PickRandom()); // Prints either of the four numbers. + /// </code> + /// </example> + /// <returns>A random element from the array.</returns> + public Variant PickRandom() + { + godot_variant resVariant; + var self = (godot_array)NativeValue; + NativeFuncs.godotsharp_array_pick_random(ref self, out resVariant); + return Variant.CreateTakingOwnershipOfDisposableValue(resVariant); + } + + /// <summary> + /// Compares this <see cref="Array"/> against the <paramref name="other"/> + /// <see cref="Array"/> recursively. Returns <see langword="true"/> if the + /// sizes and contents of the arrays are equal, <see langword="false"/> + /// otherwise. + /// </summary> + /// <param name="other">The other array to compare against.</param> + /// <returns> + /// <see langword="true"/> if the sizes and contents of the arrays are equal, + /// <see langword="false"/> otherwise. + /// </returns> + public bool RecursiveEqual(Array other) + { + var self = (godot_array)NativeValue; + var otherVariant = (godot_array)other.NativeValue; + return NativeFuncs.godotsharp_array_recursive_equal(ref self, otherVariant).ToBool(); + } + + /// <summary> + /// Resizes the array to contain a different number of elements. If the array + /// size is smaller, elements are cleared, if bigger, new elements are + /// <see langword="null"/>. + /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> /// <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) { + ThrowIfReadOnly(); + 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. + /// Reverses the order of the elements in the array. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> + public void Reverse() + { + ThrowIfReadOnly(); + + var self = (godot_array)NativeValue; + NativeFuncs.godotsharp_array_reverse(ref self); + } + + /// <summary> + /// Shuffles the array such that the items will have a random order. + /// This method uses the global random number generator common to methods + /// such as <see cref="GD.Randi"/>. Call <see cref="GD.Randomize"/> to + /// ensure that a new seed will be used each time if you want + /// non-reproducible shuffling. + /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> public void Shuffle() { + ThrowIfReadOnly(); + var self = (godot_array)NativeValue; NativeFuncs.godotsharp_array_shuffle(ref self); } /// <summary> - /// Concatenates these two <see cref="Array"/>s. + /// Creates a shallow copy of a range of elements in the source <see cref="Array"/>. + /// </summary> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="start"/> is less than 0 or greater than the array's size. + /// </exception> + /// <param name="start">The zero-based index at which the range starts.</param> + /// <returns>A new array that contains the elements inside the slice range.</returns> + public Array Slice(int start) + { + if (start < 0 || start > Count) + throw new ArgumentOutOfRangeException(nameof(start)); + + return GetSliceRange(start, Count, step: 1, deep: false); + } + + /// <summary> + /// Creates a shallow copy of a range of elements in the source <see cref="Array"/>. + /// </summary> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="start"/> is less than 0 or greater than the array's size. + /// -or- + /// <paramref name="length"/> is less than 0 or greater than the array's size. + /// </exception> + /// <param name="start">The zero-based index at which the range starts.</param> + /// <param name="length">The length of the range.</param> + /// <returns>A new array that contains the elements inside the slice range.</returns> + // The Slice method must have this signature to get implicit Range support. + public Array Slice(int start, int length) + { + if (start < 0 || start > Count) + throw new ArgumentOutOfRangeException(nameof(start)); + + if (length < 0 || length > Count) + throw new ArgumentOutOfRangeException(nameof(start)); + + return GetSliceRange(start, start + length, step: 1, deep: false); + } + + /// <summary> + /// Returns the slice of the <see cref="Array"/>, from <paramref name="start"/> + /// (inclusive) to <paramref name="end"/> (exclusive), as a new <see cref="Array"/>. + /// The absolute value of <paramref name="start"/> and <paramref name="end"/> + /// will be clamped to the array size. + /// If either <paramref name="start"/> or <paramref name="end"/> are negative, they + /// will be relative to the end of the array (i.e. <c>arr.GetSliceRange(0, -2)</c> + /// is a shorthand for <c>arr.GetSliceRange(0, arr.Count - 2)</c>). + /// If specified, <paramref name="step"/> is the relative index between source + /// elements. It can be negative, then <paramref name="start"/> must be higher than + /// <paramref name="end"/>. For example, <c>[0, 1, 2, 3, 4, 5].GetSliceRange(5, 1, -2)</c> + /// returns <c>[5, 3]</c>. + /// If <paramref name="deep"/> is true, each element will be copied by value + /// rather than by reference. + /// </summary> + /// <param name="start">The zero-based index at which the range starts.</param> + /// <param name="end">The zero-based index at which the range ends.</param> + /// <param name="step">The relative index between source elements to take.</param> + /// <param name="deep">If <see langword="true"/>, performs a deep copy.</param> + /// <returns>A new array that contains the elements inside the slice range.</returns> + public Array GetSliceRange(int start, int end, int step = 1, bool deep = false) + { + godot_array newArray; + var self = (godot_array)NativeValue; + NativeFuncs.godotsharp_array_slice(ref self, start, end, step, deep.ToGodotBool(), out newArray); + return CreateTakingOwnershipOfDisposableValue(newArray); + } + + /// <summary> + /// Sorts the array. + /// Note: The sorting algorithm used is not stable. This means that values + /// considered equal may have their order changed when using <see cref="Sort"/>. + /// Note: Strings are sorted in alphabetical order (as opposed to natural order). + /// This may lead to unexpected behavior when sorting an array of strings ending + /// with a sequence of numbers. + /// To sort with a custom predicate use + /// <see cref="Enumerable.OrderBy{TSource, TKey}(IEnumerable{TSource}, Func{TSource, TKey})"/>. + /// </summary> + /// <example> + /// <code> + /// var strings = new Godot.Collections.Array { "string1", "string2", "string10", "string11" }; + /// strings.Sort(); + /// GD.Print(strings); // Prints [string1, string10, string11, string2] + /// </code> + /// </example> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> + public void Sort() + { + ThrowIfReadOnly(); + + var self = (godot_array)NativeValue; + NativeFuncs.godotsharp_array_sort(ref self); + } + + /// <summary> + /// Concatenates two <see cref="Array"/>s together, with the <paramref name="right"/> + /// being added to the end of the <see cref="Array"/> specified in <paramref name="left"/>. + /// For example, <c>[1, 2] + [3, 4]</c> results in <c>[1, 2, 3, 4]</c>. /// </summary> /// <param name="left">The first array.</param> /// <param name="right">The second array.</param> @@ -240,6 +469,12 @@ namespace Godot.Collections /// <summary> /// Returns the item at the given <paramref name="index"/>. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The property is assigned and the array is read-only. + /// </exception> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="index"/> is less than 0 or greater than the array's size. + /// </exception> /// <value>The <see cref="Variant"/> item at the given <paramref name="index"/>.</value> public unsafe Variant this[int index] { @@ -250,8 +485,11 @@ namespace Godot.Collections } set { + ThrowIfReadOnly(); + if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException(nameof(index)); + var self = (godot_array)NativeValue; godot_variant* ptrw = NativeFuncs.godotsharp_array_ptrw(ref self); godot_variant* itemPtr = &ptrw[index]; @@ -264,49 +502,271 @@ namespace Godot.Collections /// Adds an item to the end of this <see cref="Array"/>. /// This is the same as <c>append</c> or <c>push_back</c> in GDScript. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> /// <param name="item">The <see cref="Variant"/> item to add.</param> public void Add(Variant item) { + ThrowIfReadOnly(); + godot_variant variantValue = (godot_variant)item.NativeVar; var self = (godot_array)NativeValue; _ = NativeFuncs.godotsharp_array_add(ref self, variantValue); } /// <summary> - /// Checks if this <see cref="Array"/> contains the given item. + /// Adds the elements of the specified collection to the end of this <see cref="Array"/>. + /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> + /// <exception cref="ArgumentNullException"> + /// The <paramref name="collection"/> is <see langword="null"/>. + /// </exception> + /// <param name="collection">Collection of <see cref="Variant"/> items to add.</param> + public void AddRange<[MustBeVariant] T>(IEnumerable<T> collection) + { + ThrowIfReadOnly(); + + if (collection == null) + throw new ArgumentNullException(nameof(collection), "Value cannot be null."); + + // If the collection is another Godot Array, we can add the items + // with a single interop call. + if (collection is Array array) + { + var self = (godot_array)NativeValue; + var collectionNative = (godot_array)array.NativeValue; + _ = NativeFuncs.godotsharp_array_add_range(ref self, collectionNative); + return; + } + if (collection is Array<T> typedArray) + { + var self = (godot_array)NativeValue; + var collectionNative = (godot_array)typedArray.NativeValue; + _ = NativeFuncs.godotsharp_array_add_range(ref self, collectionNative); + return; + } + + // If we can retrieve the count of the collection without enumerating it + // (e.g.: the collections is a List<T>), use it to resize the array once + // instead of growing it as we add items. + if (collection.TryGetNonEnumeratedCount(out int count)) + { + Resize(Count + count); + + using var enumerator = collection.GetEnumerator(); + + for (int i = 0; i < count; i++) + { + enumerator.MoveNext(); + this[count + i] = Variant.From(enumerator.Current); + } + + return; + } + + foreach (var item in collection) + { + Add(Variant.From(item)); + } + } + + /// <summary> + /// Finds the index of an existing value using binary search. + /// If the value is not present in the array, it returns the bitwise + /// complement of the insertion index that maintains sorting order. + /// Note: Calling <see cref="BinarySearch(int, int, Variant)"/> on an + /// unsorted array results in unexpected behavior. /// </summary> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="index"/> is less than 0. + /// -or- + /// <paramref name="count"/> is less than 0. + /// </exception> + /// <exception cref="ArgumentException"> + /// <paramref name="index"/> and <paramref name="count"/> do not denote + /// a valid range in the <see cref="Array"/>. + /// </exception> + /// <param name="index">The starting index of the range to search.</param> + /// <param name="count">The length of the range to search.</param> + /// <param name="item">The object to locate.</param> + /// <returns> + /// The index of the item in the array, if <paramref name="item"/> is found; + /// otherwise, a negative number that is the bitwise complement of the index + /// of the next element that is larger than <paramref name="item"/> or, if + /// there is no larger element, the bitwise complement of <see cref="Count"/>. + /// </returns> + public int BinarySearch(int index, int count, Variant item) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index), "index cannot be negative."); + if (count < 0) + throw new ArgumentOutOfRangeException(nameof(count), "count cannot be negative."); + if (Count - index < count) + throw new ArgumentException("length is out of bounds or count is greater than the number of elements."); + + if (Count == 0) + { + // Special case for empty array to avoid an interop call. + return -1; + } + + godot_variant variantValue = (godot_variant)item.NativeVar; + var self = (godot_array)NativeValue; + return NativeFuncs.godotsharp_array_binary_search(ref self, index, count, variantValue); + } + + /// <summary> + /// Finds the index of an existing value using binary search. + /// If the value is not present in the array, it returns the bitwise + /// complement of the insertion index that maintains sorting order. + /// Note: Calling <see cref="BinarySearch(Variant)"/> on an unsorted + /// array results in unexpected behavior. + /// </summary> + /// <param name="item">The object to locate.</param> + /// <returns> + /// The index of the item in the array, if <paramref name="item"/> is found; + /// otherwise, a negative number that is the bitwise complement of the index + /// of the next element that is larger than <paramref name="item"/> or, if + /// there is no larger element, the bitwise complement of <see cref="Count"/>. + /// </returns> + public int BinarySearch(Variant item) + { + return BinarySearch(0, Count, item); + } + + /// <summary> + /// Returns <see langword="true"/> if the array contains the given value. + /// </summary> + /// <example> + /// <code> + /// var arr = new Godot.Collections.Array { "inside", 7 }; + /// GD.Print(arr.Contains("inside")); // True + /// GD.Print(arr.Contains("outside")); // False + /// GD.Print(arr.Contains(7)); // True + /// GD.Print(arr.Contains("7")); // False + /// </code> + /// </example> /// <param name="item">The <see cref="Variant"/> item to look for.</param> /// <returns>Whether or not this array contains the given item.</returns> public bool Contains(Variant item) => IndexOf(item) != -1; /// <summary> - /// Erases all items from this <see cref="Array"/>. + /// Clears the array. This is the equivalent to using <see cref="Resize(int)"/> + /// with a size of <c>0</c> /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> public void Clear() => Resize(0); /// <summary> - /// Searches this <see cref="Array"/> for an item - /// and returns its index or -1 if not found. + /// Searches the array for a value and returns its index or <c>-1</c> if not found. /// </summary> /// <param name="item">The <see cref="Variant"/> item to search for.</param> /// <returns>The index of the item, or -1 if not found.</returns> public int IndexOf(Variant item) { + if (Count == 0) + { + // Special case for empty array to avoid an interop call. + return -1; + } + godot_variant variantValue = (godot_variant)item.NativeVar; var self = (godot_array)NativeValue; return NativeFuncs.godotsharp_array_index_of(ref self, variantValue); } /// <summary> - /// Inserts a new item at a given position in the array. - /// The position must be a valid position of an existing item, - /// or the position at the end of the array. + /// Searches the array for a value and returns its index or <c>-1</c> if not found. + /// </summary> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="index"/> is less than 0 or greater than the array's size. + /// </exception> + /// <param name="item">The <see cref="Variant"/> item to search for.</param> + /// <param name="index">The initial search index to start from.</param> + /// <returns>The index of the item, or -1 if not found.</returns> + public int IndexOf(Variant item, int index) + { + if (index < 0 || index > Count) + throw new ArgumentOutOfRangeException(nameof(index)); + + if (Count == 0) + { + // Special case for empty array to avoid an interop call. + return -1; + } + + godot_variant variantValue = (godot_variant)item.NativeVar; + var self = (godot_array)NativeValue; + return NativeFuncs.godotsharp_array_index_of(ref self, variantValue, index); + } + + /// <summary> + /// Searches the array for a value in reverse order and returns its index + /// or <c>-1</c> if not found. + /// </summary> + /// <param name="item">The <see cref="Variant"/> item to search for.</param> + /// <returns>The index of the item, or -1 if not found.</returns> + public int LastIndexOf(Variant item) + { + if (Count == 0) + { + // Special case for empty array to avoid an interop call. + return -1; + } + + godot_variant variantValue = (godot_variant)item.NativeVar; + var self = (godot_array)NativeValue; + return NativeFuncs.godotsharp_array_last_index_of(ref self, variantValue, Count - 1); + } + + /// <summary> + /// Searches the array for a value in reverse order and returns its index + /// or <c>-1</c> if not found. + /// </summary> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="index"/> is less than 0 or greater than the array's size. + /// </exception> + /// <param name="item">The <see cref="Variant"/> item to search for.</param> + /// <param name="index">The initial search index to start from.</param> + /// <returns>The index of the item, or -1 if not found.</returns> + public int LastIndexOf(Variant item, int index) + { + if (index < 0 || index >= Count) + throw new ArgumentOutOfRangeException(nameof(index)); + + if (Count == 0) + { + // Special case for empty array to avoid an interop call. + return -1; + } + + godot_variant variantValue = (godot_variant)item.NativeVar; + var self = (godot_array)NativeValue; + return NativeFuncs.godotsharp_array_last_index_of(ref self, variantValue, index); + } + + /// <summary> + /// Inserts a new element at a given position in the array. The position + /// must be valid, or at the end of the array (<c>pos == Count - 1</c>). /// Existing items will be moved to the right. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="index"/> is less than 0 or greater than the array's size. + /// </exception> /// <param name="index">The index to insert at.</param> /// <param name="item">The <see cref="Variant"/> item to insert.</param> public void Insert(int index, Variant item) { + ThrowIfReadOnly(); + if (index < 0 || index > Count) throw new ArgumentOutOfRangeException(nameof(index)); @@ -319,9 +779,14 @@ namespace Godot.Collections /// Removes the first occurrence of the specified <paramref name="item"/> /// from this <see cref="Array"/>. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> /// <param name="item">The value to remove.</param> public bool Remove(Variant item) { + ThrowIfReadOnly(); + int index = IndexOf(item); if (index >= 0) { @@ -333,11 +798,21 @@ namespace Godot.Collections } /// <summary> - /// Removes an element from this <see cref="Array"/> by index. + /// Removes an element from the array by index. + /// To remove an element by searching for its value, use + /// <see cref="Remove(Variant)"/> instead. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="index"/> is less than 0 or greater than the array's size. + /// </exception> /// <param name="index">The index of the element to remove.</param> public void RemoveAt(int index) { + ThrowIfReadOnly(); + if (index < 0 || index > Count) throw new ArgumentOutOfRangeException(nameof(index)); @@ -358,12 +833,36 @@ namespace Godot.Collections object ICollection.SyncRoot => false; - bool ICollection<Variant>.IsReadOnly => false; + /// <summary> + /// Returns <see langword="true"/> if the array is read-only. + /// See <see cref="MakeReadOnly"/>. + /// </summary> + public bool IsReadOnly => NativeValue.DangerousSelfRef.IsReadOnly; + + /// <summary> + /// Makes the <see cref="Array"/> read-only, i.e. disabled modying of the + /// array's elements. Does not apply to nested content, e.g. content of + /// nested arrays. + /// </summary> + public void MakeReadOnly() + { + if (IsReadOnly) + { + // Avoid interop call when the array is already read-only. + return; + } + + var self = (godot_array)NativeValue; + NativeFuncs.godotsharp_array_make_read_only(ref self); + } /// <summary> /// Copies the elements of this <see cref="Array"/> to the given /// <see cref="Variant"/> C# array, starting at the given index. /// </summary> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="arrayIndex"/> is less than 0 or greater than the array's size. + /// </exception> /// <param name="array">The array to copy to.</param> /// <param name="arrayIndex">The index to start at.</param> public void CopyTo(Variant[] array, int arrayIndex) @@ -458,6 +957,9 @@ namespace Godot.Collections /// <summary> /// The variant returned via the <paramref name="elem"/> parameter is owned by the Array and must not be disposed. /// </summary> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="index"/> is less than 0 or greater than the array's size. + /// </exception> internal void GetVariantBorrowElementAt(int index, out godot_variant elem) { if (index < 0 || index >= Count) @@ -472,6 +974,14 @@ namespace Godot.Collections { elem = NativeValue.DangerousSelfRef.Elements[index]; } + + private void ThrowIfReadOnly() + { + if (IsReadOnly) + { + throw new InvalidOperationException("Array instance is read-only."); + } + } } internal interface IGenericGodotArray @@ -590,8 +1100,102 @@ namespace Godot.Collections } /// <summary> + /// Assigns the given value to all elements in the array. This can typically be + /// used together with <see cref="Resize(int)"/> to create an array with a given + /// size and initialized elements. + /// Note: If <paramref name="value"/> is of a reference type (<see cref="GodotObject"/> + /// derived, <see cref="Array"/> or <see cref="Dictionary"/>, etc.) then the array + /// is filled with the references to the same object, i.e. no duplicates are + /// created. + /// </summary> + /// <example> + /// <code> + /// var array = new Godot.Collections.Array<int>(); + /// array.Resize(10); + /// array.Fill(0); // Initialize the 10 elements to 0. + /// </code> + /// </example> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> + /// <param name="value">The value to fill the array with.</param> + public void Fill(T value) + { + ThrowIfReadOnly(); + + godot_variant variantValue = VariantUtils.CreateFrom(value); + var self = (godot_array)_underlyingArray.NativeValue; + NativeFuncs.godotsharp_array_fill(ref self, variantValue); + } + + /// <summary> + /// Returns the maximum value contained in the array if all elements are of + /// comparable types. If the elements can't be compared, <see langword="default"/> + /// is returned. + /// </summary> + /// <returns>The maximum value contained in the array.</returns> + public T Max() + { + godot_variant resVariant; + var self = (godot_array)_underlyingArray.NativeValue; + NativeFuncs.godotsharp_array_max(ref self, out resVariant); + return VariantUtils.ConvertTo<T>(resVariant); + } + + /// <summary> + /// Returns the minimum value contained in the array if all elements are of + /// comparable types. If the elements can't be compared, <see langword="default"/> + /// is returned. + /// </summary> + /// <returns>The minimum value contained in the array.</returns> + public T Min() + { + godot_variant resVariant; + var self = (godot_array)_underlyingArray.NativeValue; + NativeFuncs.godotsharp_array_min(ref self, out resVariant); + return VariantUtils.ConvertTo<T>(resVariant); + } + + /// <summary> + /// Returns a random value from the target array. + /// </summary> + /// <example> + /// <code> + /// var array = new Godot.Collections.Array<int> { 1, 2, 3, 4 }; + /// GD.Print(array.PickRandom()); // Prints either of the four numbers. + /// </code> + /// </example> + /// <returns>A random element from the array.</returns> + public T PickRandom() + { + godot_variant resVariant; + var self = (godot_array)_underlyingArray.NativeValue; + NativeFuncs.godotsharp_array_pick_random(ref self, out resVariant); + return VariantUtils.ConvertTo<T>(resVariant); + } + + /// <summary> + /// Compares this <see cref="Array{T}"/> against the <paramref name="other"/> + /// <see cref="Array{T}"/> recursively. Returns <see langword="true"/> if the + /// sizes and contents of the arrays are equal, <see langword="false"/> + /// otherwise. + /// </summary> + /// <param name="other">The other array to compare against.</param> + /// <returns> + /// <see langword="true"/> if the sizes and contents of the arrays are equal, + /// <see langword="false"/> otherwise. + /// </returns> + public bool RecursiveEqual(Array<T> other) + { + return _underlyingArray.RecursiveEqual(other._underlyingArray); + } + + /// <summary> /// Resizes this <see cref="Array{T}"/> to the given size. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> /// <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) @@ -600,15 +1204,115 @@ namespace Godot.Collections } /// <summary> - /// Shuffles the contents of this <see cref="Array{T}"/> into a random order. + /// Reverses the order of the elements in the array. + /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> + public void Reverse() + { + _underlyingArray.Reverse(); + } + + /// <summary> + /// Shuffles the array such that the items will have a random order. + /// This method uses the global random number generator common to methods + /// such as <see cref="GD.Randi"/>. Call <see cref="GD.Randomize"/> to + /// ensure that a new seed will be used each time if you want + /// non-reproducible shuffling. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> public void Shuffle() { _underlyingArray.Shuffle(); } /// <summary> - /// Concatenates these two <see cref="Array{T}"/>s. + /// Creates a shallow copy of a range of elements in the source <see cref="Array{T}"/>. + /// </summary> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="start"/> is less than 0 or greater than the array's size. + /// </exception> + /// <param name="start">The zero-based index at which the range starts.</param> + /// <returns>A new array that contains the elements inside the slice range.</returns> + public Array<T> Slice(int start) + { + return GetSliceRange(start, Count, step: 1, deep: false); + } + + /// <summary> + /// Creates a shallow copy of a range of elements in the source <see cref="Array{T}"/>. + /// </summary> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="start"/> is less than 0 or greater than the array's size. + /// -or- + /// <paramref name="length"/> is less than 0 or greater than the array's size. + /// </exception> + /// <param name="start">The zero-based index at which the range starts.</param> + /// <param name="length">The length of the range.</param> + /// <returns>A new array that contains the elements inside the slice range.</returns> + // The Slice method must have this signature to get implicit Range support. + public Array<T> Slice(int start, int length) + { + return GetSliceRange(start, start + length, step: 1, deep: false); + } + + /// <summary> + /// Returns the slice of the <see cref="Array{T}"/>, from <paramref name="start"/> + /// (inclusive) to <paramref name="end"/> (exclusive), as a new <see cref="Array{T}"/>. + /// The absolute value of <paramref name="start"/> and <paramref name="end"/> + /// will be clamped to the array size. + /// If either <paramref name="start"/> or <paramref name="end"/> are negative, they + /// will be relative to the end of the array (i.e. <c>arr.GetSliceRange(0, -2)</c> + /// is a shorthand for <c>arr.GetSliceRange(0, arr.Count - 2)</c>). + /// If specified, <paramref name="step"/> is the relative index between source + /// elements. It can be negative, then <paramref name="start"/> must be higher than + /// <paramref name="end"/>. For example, <c>[0, 1, 2, 3, 4, 5].GetSliceRange(5, 1, -2)</c> + /// returns <c>[5, 3]</c>. + /// If <paramref name="deep"/> is true, each element will be copied by value + /// rather than by reference. + /// </summary> + /// <param name="start">The zero-based index at which the range starts.</param> + /// <param name="end">The zero-based index at which the range ends.</param> + /// <param name="step">The relative index between source elements to take.</param> + /// <param name="deep">If <see langword="true"/>, performs a deep copy.</param> + /// <returns>A new array that contains the elements inside the slice range.</returns> + public Array<T> GetSliceRange(int start, int end, int step = 1, bool deep = false) + { + return new Array<T>(_underlyingArray.GetSliceRange(start, end, step, deep)); + } + + /// <summary> + /// Sorts the array. + /// Note: The sorting algorithm used is not stable. This means that values + /// considered equal may have their order changed when using <see cref="Sort"/>. + /// Note: Strings are sorted in alphabetical order (as opposed to natural order). + /// This may lead to unexpected behavior when sorting an array of strings ending + /// with a sequence of numbers. + /// To sort with a custom predicate use + /// <see cref="Enumerable.OrderBy{TSource, TKey}(IEnumerable{TSource}, Func{TSource, TKey})"/>. + /// </summary> + /// <example> + /// <code> + /// var strings = new Godot.Collections.Array<string> { "string1", "string2", "string10", "string11" }; + /// strings.Sort(); + /// GD.Print(strings); // Prints [string1, string10, string11, string2] + /// </code> + /// </example> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> + public void Sort() + { + _underlyingArray.Sort(); + } + + /// <summary> + /// Concatenates two <see cref="Array{T}"/>s together, with the <paramref name="right"/> + /// being added to the end of the <see cref="Array{T}"/> specified in <paramref name="left"/>. + /// For example, <c>[1, 2] + [3, 4]</c> results in <c>[1, 2, 3, 4]</c>. /// </summary> /// <param name="left">The first array.</param> /// <param name="right">The second array.</param> @@ -632,9 +1336,15 @@ namespace Godot.Collections // IList<T> /// <summary> - /// Returns the value at the given <paramref name="index"/>. + /// Returns the item at the given <paramref name="index"/>. /// </summary> - /// <value>The value at the given <paramref name="index"/>.</value> + /// <exception cref="InvalidOperationException"> + /// The property is assigned and the array is read-only. + /// </exception> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="index"/> is less than 0 or greater than the array's size. + /// </exception> + /// <value>The <see cref="Variant"/> item at the given <paramref name="index"/>.</value> public unsafe T this[int index] { get @@ -644,8 +1354,11 @@ namespace Godot.Collections } set { + ThrowIfReadOnly(); + if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException(nameof(index)); + var self = (godot_array)_underlyingArray.NativeValue; godot_variant* ptrw = NativeFuncs.godotsharp_array_ptrw(ref self); godot_variant* itemPtr = &ptrw[index]; @@ -655,28 +1368,110 @@ namespace Godot.Collections } /// <summary> - /// Searches this <see cref="Array{T}"/> for an item - /// and returns its index or -1 if not found. + /// Searches the array for a value and returns its index or <c>-1</c> if not found. /// </summary> - /// <param name="item">The item to search for.</param> + /// <param name="item">The <see cref="Variant"/> item to search for.</param> /// <returns>The index of the item, or -1 if not found.</returns> public int IndexOf(T item) { + if (Count == 0) + { + // Special case for empty array to avoid an interop call. + return -1; + } + using var variantValue = VariantUtils.CreateFrom(item); var self = (godot_array)_underlyingArray.NativeValue; return NativeFuncs.godotsharp_array_index_of(ref self, variantValue); } /// <summary> - /// Inserts a new item at a given position in the <see cref="Array{T}"/>. - /// The position must be a valid position of an existing item, - /// or the position at the end of the array. + /// Searches the array for a value and returns its index or <c>-1</c> if not found. + /// </summary> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="index"/> is less than 0 or greater than the array's size. + /// </exception> + /// <param name="item">The <see cref="Variant"/> item to search for.</param> + /// <param name="index">The initial search index to start from.</param> + /// <returns>The index of the item, or -1 if not found.</returns> + public int IndexOf(T item, int index) + { + if (index < 0 || index > Count) + throw new ArgumentOutOfRangeException(nameof(index)); + + if (Count == 0) + { + // Special case for empty array to avoid an interop call. + return -1; + } + + godot_variant variantValue = VariantUtils.CreateFrom(item); + var self = (godot_array)_underlyingArray.NativeValue; + return NativeFuncs.godotsharp_array_index_of(ref self, variantValue, index); + } + + /// <summary> + /// Searches the array for a value in reverse order and returns its index + /// or <c>-1</c> if not found. + /// </summary> + /// <param name="item">The <see cref="Variant"/> item to search for.</param> + /// <returns>The index of the item, or -1 if not found.</returns> + public int LastIndexOf(Variant item) + { + if (Count == 0) + { + // Special case for empty array to avoid an interop call. + return -1; + } + + godot_variant variantValue = VariantUtils.CreateFrom(item); + var self = (godot_array)_underlyingArray.NativeValue; + return NativeFuncs.godotsharp_array_last_index_of(ref self, variantValue, Count - 1); + } + + /// <summary> + /// Searches the array for a value in reverse order and returns its index + /// or <c>-1</c> if not found. + /// </summary> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="index"/> is less than 0 or greater than the array's size. + /// </exception> + /// <param name="item">The <see cref="Variant"/> item to search for.</param> + /// <param name="index">The initial search index to start from.</param> + /// <returns>The index of the item, or -1 if not found.</returns> + public int LastIndexOf(Variant item, int index) + { + if (index < 0 || index >= Count) + throw new ArgumentOutOfRangeException(nameof(index)); + + if (Count == 0) + { + // Special case for empty array to avoid an interop call. + return -1; + } + + godot_variant variantValue = VariantUtils.CreateFrom(item); + var self = (godot_array)_underlyingArray.NativeValue; + return NativeFuncs.godotsharp_array_last_index_of(ref self, variantValue, index); + } + + /// <summary> + /// Inserts a new element at a given position in the array. The position + /// must be valid, or at the end of the array (<c>pos == Count - 1</c>). /// Existing items will be moved to the right. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="index"/> is less than 0 or greater than the array's size. + /// </exception> /// <param name="index">The index to insert at.</param> - /// <param name="item">The item to insert.</param> + /// <param name="item">The <see cref="Variant"/> item to insert.</param> public void Insert(int index, T item) { + ThrowIfReadOnly(); + if (index < 0 || index > Count) throw new ArgumentOutOfRangeException(nameof(index)); @@ -686,8 +1481,16 @@ namespace Godot.Collections } /// <summary> - /// Removes an element from this <see cref="Array{T}"/> by index. + /// Removes an element from the array by index. + /// To remove an element by searching for its value, use + /// <see cref="Remove(T)"/> instead. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="index"/> is less than 0 or greater than the array's size. + /// </exception> /// <param name="index">The index of the element to remove.</param> public void RemoveAt(int index) { @@ -703,32 +1506,185 @@ namespace Godot.Collections /// <returns>The number of elements.</returns> public int Count => _underlyingArray.Count; - bool ICollection<T>.IsReadOnly => false; + /// <summary> + /// Returns <see langword="true"/> if the array is read-only. + /// See <see cref="MakeReadOnly"/>. + /// </summary> + public bool IsReadOnly => _underlyingArray.IsReadOnly; + + /// <summary> + /// Makes the <see cref="Array{T}"/> read-only, i.e. disabled modying of the + /// array's elements. Does not apply to nested content, e.g. content of + /// nested arrays. + /// </summary> + public void MakeReadOnly() + { + _underlyingArray.MakeReadOnly(); + } /// <summary> /// Adds an item to the end of this <see cref="Array{T}"/>. /// This is the same as <c>append</c> or <c>push_back</c> in GDScript. /// </summary> - /// <param name="item">The item to add.</param> - /// <returns>The new size after adding the item.</returns> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> + /// <param name="item">The <see cref="Variant"/> item to add.</param> public void Add(T item) { + ThrowIfReadOnly(); + using var variantValue = VariantUtils.CreateFrom(item); var self = (godot_array)_underlyingArray.NativeValue; _ = NativeFuncs.godotsharp_array_add(ref self, variantValue); } /// <summary> - /// Erases all items from this <see cref="Array{T}"/>. + /// Adds the elements of the specified collection to the end of this <see cref="Array{T}"/>. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> + /// <exception cref="ArgumentNullException"> + /// The <paramref name="collection"/> is <see langword="null"/>. + /// </exception> + /// <param name="collection">Collection of <see cref="Variant"/> items to add.</param> + public void AddRange(IEnumerable<T> collection) + { + ThrowIfReadOnly(); + + if (collection == null) + throw new ArgumentNullException(nameof(collection), "Value cannot be null."); + + // If the collection is another Godot Array, we can add the items + // with a single interop call. + if (collection is Array array) + { + var self = (godot_array)_underlyingArray.NativeValue; + var collectionNative = (godot_array)array.NativeValue; + _ = NativeFuncs.godotsharp_array_add_range(ref self, collectionNative); + return; + } + if (collection is Array<T> typedArray) + { + var self = (godot_array)_underlyingArray.NativeValue; + var collectionNative = (godot_array)typedArray._underlyingArray.NativeValue; + _ = NativeFuncs.godotsharp_array_add_range(ref self, collectionNative); + return; + } + + // If we can retrieve the count of the collection without enumerating it + // (e.g.: the collections is a List<T>), use it to resize the array once + // instead of growing it as we add items. + if (collection.TryGetNonEnumeratedCount(out int count)) + { + Resize(Count + count); + + using var enumerator = collection.GetEnumerator(); + + for (int i = 0; i < count; i++) + { + enumerator.MoveNext(); + this[count + i] = enumerator.Current; + } + + return; + } + + foreach (var item in collection) + { + Add(item); + } + } + + /// <summary> + /// Finds the index of an existing value using binary search. + /// If the value is not present in the array, it returns the bitwise + /// complement of the insertion index that maintains sorting order. + /// Note: Calling <see cref="BinarySearch(int, int, T)"/> on an unsorted + /// array results in unexpected behavior. + /// </summary> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="index"/> is less than 0. + /// -or- + /// <paramref name="count"/> is less than 0. + /// </exception> + /// <exception cref="ArgumentException"> + /// <paramref name="index"/> and <paramref name="count"/> do not denote + /// a valid range in the <see cref="Array{T}"/>. + /// </exception> + /// <param name="index">The starting index of the range to search.</param> + /// <param name="count">The length of the range to search.</param> + /// <param name="item">The object to locate.</param> + /// <returns> + /// The index of the item in the array, if <paramref name="item"/> is found; + /// otherwise, a negative number that is the bitwise complement of the index + /// of the next element that is larger than <paramref name="item"/> or, if + /// there is no larger element, the bitwise complement of <see cref="Count"/>. + /// </returns> + public int BinarySearch(int index, int count, T item) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index), "index cannot be negative."); + if (count < 0) + throw new ArgumentOutOfRangeException(nameof(count), "count cannot be negative."); + if (Count - index < count) + throw new ArgumentException("length is out of bounds or count is greater than the number of elements."); + + if (Count == 0) + { + // Special case for empty array to avoid an interop call. + return -1; + } + + using var variantValue = VariantUtils.CreateFrom(item); + var self = (godot_array)_underlyingArray.NativeValue; + return NativeFuncs.godotsharp_array_binary_search(ref self, index, count, variantValue); + } + + /// <summary> + /// Finds the index of an existing value using binary search. + /// If the value is not present in the array, it returns the bitwise + /// complement of the insertion index that maintains sorting order. + /// Note: Calling <see cref="BinarySearch(T)"/> on an unsorted + /// array results in unexpected behavior. + /// </summary> + /// <param name="item">The object to locate.</param> + /// <returns> + /// The index of the item in the array, if <paramref name="item"/> is found; + /// otherwise, a negative number that is the bitwise complement of the index + /// of the next element that is larger than <paramref name="item"/> or, if + /// there is no larger element, the bitwise complement of <see cref="Count"/>. + /// </returns> + public int BinarySearch(T item) + { + return BinarySearch(0, Count, item); + } + + /// <summary> + /// Clears the array. This is the equivalent to using <see cref="Resize(int)"/> + /// with a size of <c>0</c> + /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> public void Clear() { _underlyingArray.Clear(); } /// <summary> - /// Checks if this <see cref="Array{T}"/> contains the given item. + /// Returns <see langword="true"/> if the array contains the given value. /// </summary> + /// <example> + /// <code> + /// var arr = new Godot.Collections.Array<string> { "inside", "7" }; + /// GD.Print(arr.Contains("inside")); // True + /// GD.Print(arr.Contains("outside")); // False + /// GD.Print(arr.Contains(7)); // False + /// GD.Print(arr.Contains("7")); // True + /// </code> + /// </example> /// <param name="item">The item to look for.</param> /// <returns>Whether or not this array contains the given item.</returns> public bool Contains(T item) => IndexOf(item) != -1; @@ -737,6 +1693,9 @@ namespace Godot.Collections /// Copies the elements of this <see cref="Array{T}"/> to the given /// C# array, starting at the given index. /// </summary> + /// <exception cref="ArgumentOutOfRangeException"> + /// <paramref name="arrayIndex"/> is less than 0 or greater than the array's size. + /// </exception> /// <param name="array">The C# array to copy to.</param> /// <param name="arrayIndex">The index to start at.</param> public void CopyTo(T[] array, int arrayIndex) @@ -766,13 +1725,18 @@ namespace Godot.Collections } /// <summary> - /// Removes the first occurrence of the specified value + /// Removes the first occurrence of the specified <paramref name="item"/> /// from this <see cref="Array{T}"/>. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The array is read-only. + /// </exception> /// <param name="item">The value to remove.</param> /// <returns>A <see langword="bool"/> indicating success or failure.</returns> public bool Remove(T item) { + ThrowIfReadOnly(); + int index = IndexOf(item); if (index >= 0) { @@ -812,5 +1776,13 @@ namespace Godot.Collections [MethodImpl(MethodImplOptions.AggressiveInlining)] public static explicit operator Array<T>(Variant from) => from.AsGodotArray<T>(); + + private void ThrowIfReadOnly() + { + if (IsReadOnly) + { + throw new InvalidOperationException("Array instance is read-only."); + } + } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs index acdae83d2e..81659f74de 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs @@ -10,7 +10,7 @@ namespace Godot /// collection of types that implement scripts; otherwise, retrieving the types requires lookup. /// </summary> [AttributeUsage(AttributeTargets.Assembly)] - public class AssemblyHasScriptsAttribute : Attribute + public sealed class AssemblyHasScriptsAttribute : Attribute { /// <summary> /// If the Godot scripts contained in the assembly require lookup diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/GodotClassNameAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/GodotClassNameAttribute.cs new file mode 100644 index 0000000000..b19427f60d --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/GodotClassNameAttribute.cs @@ -0,0 +1,24 @@ +using System; + +namespace Godot +{ + /// <summary> + /// Attribute that specifies the engine class name when it's not the same + /// as the generated C# class name. This allows introspection code to find + /// the name associated with the class. If the attribute is not present, + /// the C# class name can be used instead. + /// </summary> + [AttributeUsage(AttributeTargets.Class)] + public class GodotClassNameAttribute : Attribute + { + /// <summary> + /// Original engine class name. + /// </summary> + public string Name { get; } + + public GodotClassNameAttribute(string name) + { + Name = name; + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs index 23088378d1..0070223c95 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs @@ -7,5 +7,5 @@ namespace Godot /// that can be marshaled from/to a <see cref="Variant"/>. /// </summary> [AttributeUsage(AttributeTargets.GenericParameter)] - public class MustBeVariantAttribute : Attribute { } + public sealed class MustBeVariantAttribute : Attribute { } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RpcAttribute.cs index afee926464..6a73d6f70c 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RpcAttribute.cs @@ -5,16 +5,16 @@ namespace Godot /// <summary> /// Attribute that changes the RPC mode for the annotated <c>method</c> to the given <see cref="Mode"/>, /// optionally specifying the <see cref="TransferMode"/> and <see cref="TransferChannel"/> (on supported peers). - /// See <see cref="MultiplayerAPI.RPCMode"/> and <see cref="MultiplayerPeer.TransferModeEnum"/>. + /// See <see cref="MultiplayerApi.RpcMode"/> and <see cref="MultiplayerPeer.TransferModeEnum"/>. /// By default, methods are not exposed to networking (and RPCs). /// </summary> [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] - public class RPCAttribute : Attribute + public sealed class RpcAttribute : Attribute { /// <summary> /// RPC mode for the annotated method. /// </summary> - public MultiplayerAPI.RPCMode Mode { get; } = MultiplayerAPI.RPCMode.Disabled; + public MultiplayerApi.RpcMode Mode { get; } = MultiplayerApi.RpcMode.Disabled; /// <summary> /// If the method will also be called locally; otherwise, it is only called remotely. @@ -32,10 +32,10 @@ namespace Godot public int TransferChannel { get; init; } = 0; /// <summary> - /// Constructs a <see cref="RPCAttribute"/> instance. + /// Constructs a <see cref="RpcAttribute"/> instance. /// </summary> /// <param name="mode">The RPC mode to use.</param> - public RPCAttribute(MultiplayerAPI.RPCMode mode = MultiplayerAPI.RPCMode.Authority) + public RpcAttribute(MultiplayerApi.RpcMode mode = MultiplayerApi.RpcMode.Authority) { Mode = mode; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs index f05bcdac38..d363e14c5d 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs @@ -6,7 +6,7 @@ namespace Godot /// An attribute that contains the path to the object's script. /// </summary> [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - public class ScriptPathAttribute : Attribute + public sealed class ScriptPathAttribute : Attribute { /// <summary> /// File path to the script. diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs index 38e68a89d5..0a08bb5df8 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs @@ -3,5 +3,5 @@ using System; namespace Godot { [AttributeUsage(AttributeTargets.Delegate)] - public class SignalAttribute : Attribute { } + public sealed class SignalAttribute : Attribute { } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ToolAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ToolAttribute.cs index d2344389f4..4c56201727 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ToolAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ToolAttribute.cs @@ -3,5 +3,5 @@ using System; namespace Godot { [AttributeUsage(AttributeTargets.Class)] - public class ToolAttribute : Attribute { } + public sealed class ToolAttribute : Attribute { } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs index b57317e1d0..ca963cbf4f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs @@ -27,7 +27,7 @@ namespace Godot /// The basis matrix's X vector (column 0). /// </summary> /// <value>Equivalent to <see cref="Column0"/> and array index <c>[0]</c>.</value> - public Vector3 x + public Vector3 X { readonly get => Column0; set => Column0 = value; @@ -37,7 +37,7 @@ namespace Godot /// The basis matrix's Y vector (column 1). /// </summary> /// <value>Equivalent to <see cref="Column1"/> and array index <c>[1]</c>.</value> - public Vector3 y + public Vector3 Y { readonly get => Column1; set => Column1 = value; @@ -47,7 +47,7 @@ namespace Godot /// The basis matrix's Z vector (column 2). /// </summary> /// <value>Equivalent to <see cref="Column2"/> and array index <c>[2]</c>.</value> - public Vector3 z + public Vector3 Z { readonly get => Column2; set => Column2 = value; @@ -77,45 +77,63 @@ namespace Godot /// <summary> /// Column 0 of the basis matrix (the X vector). /// </summary> - /// <value>Equivalent to <see cref="x"/> and array index <c>[0]</c>.</value> + /// <value>Equivalent to <see cref="X"/> and array index <c>[0]</c>.</value> public Vector3 Column0 { - readonly get => new Vector3(Row0.x, Row1.x, Row2.x); + readonly get => new Vector3(Row0.X, Row1.X, Row2.X); set { - Row0.x = value.x; - Row1.x = value.y; - Row2.x = value.z; + Row0.X = value.X; + Row1.X = value.Y; + Row2.X = value.Z; } } /// <summary> /// Column 1 of the basis matrix (the Y vector). /// </summary> - /// <value>Equivalent to <see cref="y"/> and array index <c>[1]</c>.</value> + /// <value>Equivalent to <see cref="Y"/> and array index <c>[1]</c>.</value> public Vector3 Column1 { - readonly get => new Vector3(Row0.y, Row1.y, Row2.y); + readonly get => new Vector3(Row0.Y, Row1.Y, Row2.Y); set { - Row0.y = value.x; - Row1.y = value.y; - Row2.y = value.z; + Row0.Y = value.X; + Row1.Y = value.Y; + Row2.Y = value.Z; } } /// <summary> /// Column 2 of the basis matrix (the Z vector). /// </summary> - /// <value>Equivalent to <see cref="z"/> and array index <c>[2]</c>.</value> + /// <value>Equivalent to <see cref="Z"/> and array index <c>[2]</c>.</value> public Vector3 Column2 { - readonly get => new Vector3(Row0.z, Row1.z, Row2.z); + readonly get => new Vector3(Row0.Z, Row1.Z, Row2.Z); set { - Row0.z = value.x; - Row1.z = value.y; - Row2.z = value.z; + Row0.Z = value.X; + Row1.Z = value.Y; + Row2.Z = value.Z; + } + } + + /// <summary> + /// Assuming that the matrix is the combination of a rotation and scaling, + /// return the absolute value of scaling factors along each axis. + /// </summary> + public readonly Vector3 Scale + { + get + { + real_t detSign = Mathf.Sign(Determinant()); + return detSign * new Vector3 + ( + Column0.Length(), + Column1.Length(), + Column2.Length() + ); } } @@ -195,9 +213,9 @@ namespace Godot private void SetDiagonal(Vector3 diagonal) { - Row0 = new Vector3(diagonal.x, 0, 0); - Row1 = new Vector3(0, diagonal.y, 0); - Row2 = new Vector3(0, 0, diagonal.z); + Row0 = new Vector3(diagonal.X, 0, 0); + Row1 = new Vector3(0, diagonal.Y, 0); + Row2 = new Vector3(0, 0, diagonal.Z); } /// <summary> @@ -252,29 +270,29 @@ namespace Godot if (Row1[0] == 0 && Row0[1] == 0 && Row1[2] == 0 && Row2[1] == 0 && Row1[1] == 1) { // return the simplest form (human friendlier in editor and scripts) - euler.x = 0; - euler.y = Mathf.Atan2(Row0[2], Row0[0]); - euler.z = 0; + euler.X = 0; + euler.Y = Mathf.Atan2(Row0[2], Row0[0]); + euler.Z = 0; } else { - euler.x = Mathf.Atan2(-Row1[2], Row2[2]); - euler.y = Mathf.Asin(sy); - euler.z = Mathf.Atan2(-Row0[1], Row0[0]); + euler.X = Mathf.Atan2(-Row1[2], Row2[2]); + euler.Y = Mathf.Asin(sy); + euler.Z = Mathf.Atan2(-Row0[1], Row0[0]); } } else { - euler.x = Mathf.Atan2(Row2[1], Row1[1]); - euler.y = -Mathf.Tau / 4.0f; - euler.z = 0.0f; + euler.X = Mathf.Atan2(Row2[1], Row1[1]); + euler.Y = -Mathf.Tau / 4.0f; + euler.Z = 0.0f; } } else { - euler.x = Mathf.Atan2(Row2[1], Row1[1]); - euler.y = Mathf.Tau / 4.0f; - euler.z = 0.0f; + euler.X = Mathf.Atan2(Row2[1], Row1[1]); + euler.Y = Mathf.Tau / 4.0f; + euler.Z = 0.0f; } return euler; } @@ -292,24 +310,24 @@ namespace Godot { if (sz > -(1.0f - Mathf.Epsilon)) { - euler.x = Mathf.Atan2(Row2[1], Row1[1]); - euler.y = Mathf.Atan2(Row0[2], Row0[0]); - euler.z = Mathf.Asin(-sz); + euler.X = Mathf.Atan2(Row2[1], Row1[1]); + euler.Y = Mathf.Atan2(Row0[2], Row0[0]); + euler.Z = Mathf.Asin(-sz); } else { // It's -1 - euler.x = -Mathf.Atan2(Row1[2], Row2[2]); - euler.y = 0.0f; - euler.z = Mathf.Tau / 4.0f; + euler.X = -Mathf.Atan2(Row1[2], Row2[2]); + euler.Y = 0.0f; + euler.Z = Mathf.Tau / 4.0f; } } else { // It's 1 - euler.x = -Mathf.Atan2(Row1[2], Row2[2]); - euler.y = 0.0f; - euler.z = -Mathf.Tau / 4.0f; + euler.X = -Mathf.Atan2(Row1[2], Row2[2]); + euler.Y = 0.0f; + euler.Z = -Mathf.Tau / 4.0f; } return euler; } @@ -331,29 +349,29 @@ namespace Godot if (Row1[0] == 0 && Row0[1] == 0 && Row0[2] == 0 && Row2[0] == 0 && Row0[0] == 1) { // return the simplest form (human friendlier in editor and scripts) - euler.x = Mathf.Atan2(-m12, Row1[1]); - euler.y = 0; - euler.z = 0; + euler.X = Mathf.Atan2(-m12, Row1[1]); + euler.Y = 0; + euler.Z = 0; } else { - euler.x = Mathf.Asin(-m12); - euler.y = Mathf.Atan2(Row0[2], Row2[2]); - euler.z = Mathf.Atan2(Row1[0], Row1[1]); + euler.X = Mathf.Asin(-m12); + euler.Y = Mathf.Atan2(Row0[2], Row2[2]); + euler.Z = Mathf.Atan2(Row1[0], Row1[1]); } } else { // m12 == -1 - euler.x = Mathf.Tau / 4.0f; - euler.y = Mathf.Atan2(Row0[1], Row0[0]); - euler.z = 0; + euler.X = Mathf.Tau / 4.0f; + euler.Y = Mathf.Atan2(Row0[1], Row0[0]); + euler.Z = 0; } } else { // m12 == 1 - euler.x = -Mathf.Tau / 4.0f; - euler.y = -Mathf.Atan2(Row0[1], Row0[0]); - euler.z = 0; + euler.X = -Mathf.Tau / 4.0f; + euler.Y = -Mathf.Atan2(Row0[1], Row0[0]); + euler.Z = 0; } return euler; @@ -372,24 +390,24 @@ namespace Godot { if (sz > -(1.0f - Mathf.Epsilon)) { - euler.x = Mathf.Atan2(-Row1[2], Row1[1]); - euler.y = Mathf.Atan2(-Row2[0], Row0[0]); - euler.z = Mathf.Asin(sz); + euler.X = Mathf.Atan2(-Row1[2], Row1[1]); + euler.Y = Mathf.Atan2(-Row2[0], Row0[0]); + euler.Z = Mathf.Asin(sz); } else { // It's -1 - euler.x = Mathf.Atan2(Row2[1], Row2[2]); - euler.y = 0.0f; - euler.z = -Mathf.Tau / 4.0f; + euler.X = Mathf.Atan2(Row2[1], Row2[2]); + euler.Y = 0.0f; + euler.Z = -Mathf.Tau / 4.0f; } } else { // It's 1 - euler.x = Mathf.Atan2(Row2[1], Row2[2]); - euler.y = 0.0f; - euler.z = Mathf.Tau / 4.0f; + euler.X = Mathf.Atan2(Row2[1], Row2[2]); + euler.Y = 0.0f; + euler.Z = Mathf.Tau / 4.0f; } return euler; } @@ -407,24 +425,24 @@ namespace Godot { if (sx > -(1.0f - Mathf.Epsilon)) { - euler.x = Mathf.Asin(sx); - euler.y = Mathf.Atan2(-Row2[0], Row2[2]); - euler.z = Mathf.Atan2(-Row0[1], Row1[1]); + euler.X = Mathf.Asin(sx); + euler.Y = Mathf.Atan2(-Row2[0], Row2[2]); + euler.Z = Mathf.Atan2(-Row0[1], Row1[1]); } else { // It's -1 - euler.x = -Mathf.Tau / 4.0f; - euler.y = Mathf.Atan2(Row0[2], Row0[0]); - euler.z = 0; + euler.X = -Mathf.Tau / 4.0f; + euler.Y = Mathf.Atan2(Row0[2], Row0[0]); + euler.Z = 0; } } else { // It's 1 - euler.x = Mathf.Tau / 4.0f; - euler.y = Mathf.Atan2(Row0[2], Row0[0]); - euler.z = 0; + euler.X = Mathf.Tau / 4.0f; + euler.Y = Mathf.Atan2(Row0[2], Row0[0]); + euler.Z = 0; } return euler; } @@ -442,24 +460,24 @@ namespace Godot { if (sy > -(1.0f - Mathf.Epsilon)) { - euler.x = Mathf.Atan2(Row2[1], Row2[2]); - euler.y = Mathf.Asin(-sy); - euler.z = Mathf.Atan2(Row1[0], Row0[0]); + euler.X = Mathf.Atan2(Row2[1], Row2[2]); + euler.Y = Mathf.Asin(-sy); + euler.Z = Mathf.Atan2(Row1[0], Row0[0]); } else { // It's -1 - euler.x = 0; - euler.y = Mathf.Tau / 4.0f; - euler.z = -Mathf.Atan2(Row0[1], Row1[1]); + euler.X = 0; + euler.Y = Mathf.Tau / 4.0f; + euler.Z = -Mathf.Atan2(Row0[1], Row1[1]); } } else { // It's 1 - euler.x = 0; - euler.y = -Mathf.Tau / 4.0f; - euler.z = -Mathf.Atan2(Row0[1], Row1[1]); + euler.X = 0; + euler.Y = -Mathf.Tau / 4.0f; + euler.Z = -Mathf.Atan2(Row0[1], Row1[1]); } return euler; } @@ -542,21 +560,6 @@ namespace Godot } /// <summary> - /// Assuming that the matrix is the combination of a rotation and scaling, - /// return the absolute value of scaling factors along each axis. - /// </summary> - public readonly Vector3 GetScale() - { - real_t detSign = Mathf.Sign(Determinant()); - return detSign * new Vector3 - ( - Column0.Length(), - Column1.Length(), - Column2.Length() - ); - } - - /// <summary> /// Returns the inverse of the matrix. /// </summary> /// <returns>The inverse matrix.</returns> @@ -650,9 +653,9 @@ namespace Godot public readonly Basis Scaled(Vector3 scale) { Basis b = this; - b.Row0 *= scale.x; - b.Row1 *= scale.y; - b.Row2 *= scale.z; + b.Row0 *= scale.X; + b.Row1 *= scale.Y; + b.Row2 *= scale.Z; return b; } @@ -789,18 +792,18 @@ namespace Godot { real_t s = 2.0f / quaternion.LengthSquared(); - real_t xs = quaternion.x * s; - real_t ys = quaternion.y * s; - real_t zs = quaternion.z * s; - real_t wx = quaternion.w * xs; - real_t wy = quaternion.w * ys; - real_t wz = quaternion.w * zs; - real_t xx = quaternion.x * xs; - real_t xy = quaternion.x * ys; - real_t xz = quaternion.x * zs; - real_t yy = quaternion.y * ys; - real_t yz = quaternion.y * zs; - real_t zz = quaternion.z * zs; + real_t xs = quaternion.X * s; + real_t ys = quaternion.Y * s; + real_t zs = quaternion.Z * s; + real_t wx = quaternion.W * xs; + real_t wy = quaternion.W * ys; + real_t wz = quaternion.W * zs; + real_t xx = quaternion.X * xs; + real_t xy = quaternion.X * ys; + real_t xz = quaternion.X * zs; + real_t yy = quaternion.Y * ys; + real_t yz = quaternion.Y * zs; + real_t zz = quaternion.Z * zs; Row0 = new Vector3(1.0f - (yy + zz), xy - wz, xz + wy); Row1 = new Vector3(xy + wz, 1.0f - (xx + zz), yz - wx); @@ -815,29 +818,29 @@ namespace Godot /// <param name="angle">The angle to rotate, in radians.</param> public Basis(Vector3 axis, real_t angle) { - Vector3 axisSq = new Vector3(axis.x * axis.x, axis.y * axis.y, axis.z * axis.z); + Vector3 axisSq = new Vector3(axis.X * axis.X, axis.Y * axis.Y, axis.Z * axis.Z); (real_t sin, real_t cos) = Mathf.SinCos(angle); - Row0.x = axisSq.x + cos * (1.0f - axisSq.x); - Row1.y = axisSq.y + cos * (1.0f - axisSq.y); - Row2.z = axisSq.z + cos * (1.0f - axisSq.z); + Row0.X = axisSq.X + cos * (1.0f - axisSq.X); + Row1.Y = axisSq.Y + cos * (1.0f - axisSq.Y); + Row2.Z = axisSq.Z + cos * (1.0f - axisSq.Z); real_t t = 1.0f - cos; - real_t xyzt = axis.x * axis.y * t; - real_t zyxs = axis.z * sin; - Row0.y = xyzt - zyxs; - Row1.x = xyzt + zyxs; + real_t xyzt = axis.X * axis.Y * t; + real_t zyxs = axis.Z * sin; + Row0.Y = xyzt - zyxs; + Row1.X = xyzt + zyxs; - xyzt = axis.x * axis.z * t; - zyxs = axis.y * sin; - Row0.z = xyzt + zyxs; - Row2.x = xyzt - zyxs; + xyzt = axis.X * axis.Z * t; + zyxs = axis.Y * sin; + Row0.Z = xyzt + zyxs; + Row2.X = xyzt - zyxs; - xyzt = axis.y * axis.z * t; - zyxs = axis.x * sin; - Row1.z = xyzt - zyxs; - Row2.y = xyzt + zyxs; + xyzt = axis.Y * axis.Z * t; + zyxs = axis.X * sin; + Row1.Z = xyzt - zyxs; + Row2.Y = xyzt + zyxs; } /// <summary> @@ -848,9 +851,9 @@ namespace Godot /// <param name="column2">The Z vector, or Column2.</param> public Basis(Vector3 column0, Vector3 column1, Vector3 column2) { - Row0 = new Vector3(column0.x, column1.x, column2.x); - Row1 = new Vector3(column0.y, column1.y, column2.y); - Row2 = new Vector3(column0.z, column1.z, column2.z); + Row0 = new Vector3(column0.X, column1.X, column2.X); + Row1 = new Vector3(column0.Y, column1.Y, column2.Y); + Row2 = new Vector3(column0.Z, column1.Z, column2.Z); // Same as: // Column0 = column0; // Column1 = column1; @@ -860,17 +863,17 @@ namespace Godot /// <summary> /// Constructs a transformation matrix from the given components. - /// Arguments are named such that xy is equal to calling <c>x.y</c>. + /// Arguments are named such that xy is equal to calling <c>X.Y</c>. /// </summary> - /// <param name="xx">The X component of the X column vector, accessed via <c>b.x.x</c> or <c>[0][0]</c>.</param> - /// <param name="yx">The X component of the Y column vector, accessed via <c>b.y.x</c> or <c>[1][0]</c>.</param> - /// <param name="zx">The X component of the Z column vector, accessed via <c>b.z.x</c> or <c>[2][0]</c>.</param> - /// <param name="xy">The Y component of the X column vector, accessed via <c>b.x.y</c> or <c>[0][1]</c>.</param> - /// <param name="yy">The Y component of the Y column vector, accessed via <c>b.y.y</c> or <c>[1][1]</c>.</param> - /// <param name="zy">The Y component of the Z column vector, accessed via <c>b.y.y</c> or <c>[2][1]</c>.</param> - /// <param name="xz">The Z component of the X column vector, accessed via <c>b.x.y</c> or <c>[0][2]</c>.</param> - /// <param name="yz">The Z component of the Y column vector, accessed via <c>b.y.y</c> or <c>[1][2]</c>.</param> - /// <param name="zz">The Z component of the Z column vector, accessed via <c>b.y.y</c> or <c>[2][2]</c>.</param> + /// <param name="xx">The X component of the X column vector, accessed via <c>b.X.X</c> or <c>[0][0]</c>.</param> + /// <param name="yx">The X component of the Y column vector, accessed via <c>b.Y.X</c> or <c>[1][0]</c>.</param> + /// <param name="zx">The X component of the Z column vector, accessed via <c>b.Z.X</c> or <c>[2][0]</c>.</param> + /// <param name="xy">The Y component of the X column vector, accessed via <c>b.X.Y</c> or <c>[0][1]</c>.</param> + /// <param name="yy">The Y component of the Y column vector, accessed via <c>b.Y.Y</c> or <c>[1][1]</c>.</param> + /// <param name="zy">The Y component of the Z column vector, accessed via <c>b.Y.Y</c> or <c>[2][1]</c>.</param> + /// <param name="xz">The Z component of the X column vector, accessed via <c>b.X.Y</c> or <c>[0][2]</c>.</param> + /// <param name="yz">The Z component of the Y column vector, accessed via <c>b.Y.Y</c> or <c>[1][2]</c>.</param> + /// <param name="zz">The Z component of the Z column vector, accessed via <c>b.Y.Y</c> or <c>[2][2]</c>.</param> public Basis(real_t xx, real_t yx, real_t zx, real_t xy, real_t yy, real_t zy, real_t xz, real_t yz, real_t zz) { Row0 = new Vector3(xx, yx, zx); @@ -885,7 +888,7 @@ namespace Godot /// <param name="order">The order to compose the Euler angles.</param> public static Basis FromEuler(Vector3 euler, EulerOrder order = EulerOrder.Yxz) { - (real_t sin, real_t cos) = Mathf.SinCos(euler.x); + (real_t sin, real_t cos) = Mathf.SinCos(euler.X); Basis xmat = new Basis ( new Vector3(1, 0, 0), @@ -893,7 +896,7 @@ namespace Godot new Vector3(0, -sin, cos) ); - (sin, cos) = Mathf.SinCos(euler.y); + (sin, cos) = Mathf.SinCos(euler.Y); Basis ymat = new Basis ( new Vector3(cos, 0, -sin), @@ -901,7 +904,7 @@ namespace Godot new Vector3(sin, 0, cos) ); - (sin, cos) = Mathf.SinCos(euler.z); + (sin, cos) = Mathf.SinCos(euler.Z); Basis zmat = new Basis ( new Vector3(cos, sin, 0), @@ -938,9 +941,9 @@ namespace Godot public static Basis FromScale(Vector3 scale) { return new Basis( - scale.x, 0, 0, - 0, scale.y, 0, - 0, 0, scale.z + scale.X, 0, 0, + 0, scale.Y, 0, + 0, 0, scale.Z ); } @@ -991,9 +994,9 @@ namespace Godot { return new Vector3 ( - basis.Row0[0] * vector.x + basis.Row1[0] * vector.y + basis.Row2[0] * vector.z, - basis.Row0[1] * vector.x + basis.Row1[1] * vector.y + basis.Row2[1] * vector.z, - basis.Row0[2] * vector.x + basis.Row1[2] * vector.y + basis.Row2[2] * vector.z + basis.Row0[0] * vector.X + basis.Row1[0] * vector.Y + basis.Row2[0] * vector.Z, + basis.Row0[1] * vector.X + basis.Row1[1] * vector.Y + basis.Row2[1] * vector.Z, + basis.Row0[2] * vector.X + basis.Row1[2] * vector.Y + basis.Row2[2] * vector.Z ); } @@ -1074,7 +1077,7 @@ namespace Godot /// <returns>A string representation of this basis.</returns> public override readonly string ToString() { - return $"[X: {x}, Y: {y}, Z: {z}]"; + return $"[X: {X}, Y: {Y}, Z: {Z}]"; } /// <summary> @@ -1083,7 +1086,7 @@ namespace Godot /// <returns>A string representation of this basis.</returns> public readonly string ToString(string format) { - return $"[X: {x.ToString(format)}, Y: {y.ToString(format)}, Z: {z.ToString(format)}]"; + return $"[X: {X.ToString(format)}, Y: {Y.ToString(format)}, Z: {Z.ToString(format)}]"; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs index 354212da1b..16be494d99 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs @@ -12,7 +12,7 @@ namespace Godot.Bridge { try { - var godotObject = (Object)GCHandle.FromIntPtr(godotObjectGCHandle).Target; + var godotObject = (GodotObject)GCHandle.FromIntPtr(godotObjectGCHandle).Target; if (godotObject == null) { @@ -49,7 +49,7 @@ namespace Godot.Bridge { try { - var godotObject = (Object)GCHandle.FromIntPtr(godotObjectGCHandle).Target; + var godotObject = (GodotObject)GCHandle.FromIntPtr(godotObjectGCHandle).Target; if (godotObject == null) throw new InvalidOperationException(); @@ -79,17 +79,34 @@ namespace Godot.Bridge { try { - var godotObject = (Object)GCHandle.FromIntPtr(godotObjectGCHandle).Target; + var godotObject = (GodotObject)GCHandle.FromIntPtr(godotObjectGCHandle).Target; if (godotObject == null) throw new InvalidOperationException(); + // Properties if (godotObject.GetGodotClassPropertyValue(CustomUnsafe.AsRef(name), out godot_variant outRetValue)) { *outRet = outRetValue; return godot_bool.True; } + // Signals + if (godotObject.HasGodotClassSignal(CustomUnsafe.AsRef(name))) + { + godot_signal signal = new godot_signal(*name, godotObject.GetInstanceId()); + *outRet = VariantUtils.CreateFromSignalTakingOwnershipOfDisposableValue(signal); + return godot_bool.True; + } + + // Methods + if (godotObject.HasGodotClassMethod(CustomUnsafe.AsRef(name))) + { + godot_callable method = new godot_callable(*name, godotObject.GetInstanceId()); + *outRet = VariantUtils.CreateFromCallableTakingOwnershipOfDisposableValue(method); + return godot_bool.True; + } + var nameManaged = StringName.CreateTakingOwnershipOfDisposableValue( NativeFuncs.godotsharp_string_name_new_copy(CustomUnsafe.AsRef(name))); @@ -117,7 +134,7 @@ namespace Godot.Bridge { try { - var godotObject = (Object)GCHandle.FromIntPtr(godotObjectGCHandle).Target; + var godotObject = (GodotObject)GCHandle.FromIntPtr(godotObjectGCHandle).Target; if (okIfNull.ToBool()) godotObject?.Dispose(); @@ -135,7 +152,7 @@ namespace Godot.Bridge { try { - var self = (Object)GCHandle.FromIntPtr(godotObjectGCHandle).Target; + var self = (GodotObject)GCHandle.FromIntPtr(godotObjectGCHandle).Target; if (self == null) { @@ -169,7 +186,7 @@ namespace Godot.Bridge { try { - var godotObject = (Object)GCHandle.FromIntPtr(godotObjectGCHandle).Target; + var godotObject = (GodotObject)GCHandle.FromIntPtr(godotObjectGCHandle).Target; if (godotObject == null) return godot_bool.False; @@ -192,7 +209,7 @@ namespace Godot.Bridge { try { - var godotObject = (Object)GCHandle.FromIntPtr(godotObjectGCHandle).Target; + var godotObject = (GodotObject)GCHandle.FromIntPtr(godotObjectGCHandle).Target; if (godotObject == null) return; @@ -225,7 +242,7 @@ namespace Godot.Bridge { try { - var godotObject = (Object)GCHandle.FromIntPtr(godotObjectGCHandle).Target; + var godotObject = (GodotObject)GCHandle.FromIntPtr(godotObjectGCHandle).Target; if (godotObject == null) return; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/GodotSerializationInfo.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/GodotSerializationInfo.cs index 6d20f95007..47feb1902f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/GodotSerializationInfo.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/GodotSerializationInfo.cs @@ -48,7 +48,7 @@ public sealed class GodotSerializationInfo : IDisposable { _signalEvents[name] = serializedData; } - else if (OS.IsStdoutVerbose()) + else if (OS.IsStdOutVerbose()) { Console.WriteLine($"Failed to serialize event signal delegate: {name}"); } @@ -72,7 +72,7 @@ public sealed class GodotSerializationInfo : IDisposable return true; } - else if (OS.IsStdoutVerbose()) + else if (OS.IsStdOutVerbose()) { Console.WriteLine($"Failed to deserialize event signal delegate: {name}"); } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs index dafa83431b..ec2728140e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs @@ -100,7 +100,7 @@ namespace Godot.Bridge Type nativeType = TypeGetProxyClass(nativeTypeNameStr) ?? throw new InvalidOperationException( "Wrapper class not found for type: " + nativeTypeNameStr); - var obj = (Object)FormatterServices.GetUninitializedObject(nativeType); + var obj = (GodotObject)FormatterServices.GetUninitializedObject(nativeType); var ctor = nativeType.GetConstructor( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, @@ -150,7 +150,7 @@ namespace Godot.Bridge } } - var obj = (Object)FormatterServices.GetUninitializedObject(scriptType); + var obj = (GodotObject)FormatterServices.GetUninitializedObject(scriptType); var parameters = ctor.GetParameters(); int paramCount = parameters.Length; @@ -189,7 +189,7 @@ namespace Godot.Bridge return; } - var native = Object.InternalGetClassNativeBase(scriptType); + var native = GodotObject.InternalGetClassNativeBase(scriptType); var field = native?.GetField("NativeName", BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); @@ -222,7 +222,7 @@ namespace Godot.Bridge { try { - var target = (Object?)GCHandle.FromIntPtr(gcHandlePtr).Target; + var target = (GodotObject?)GCHandle.FromIntPtr(gcHandlePtr).Target; if (target != null) target.NativePtr = newPtr; } @@ -239,21 +239,45 @@ namespace Godot.Bridge if (nativeTypeNameStr[0] == '_') nativeTypeNameStr = nativeTypeNameStr.Substring(1); - Type? wrapperType = typeof(Object).Assembly.GetType("Godot." + nativeTypeNameStr); + Type? wrapperType = typeof(GodotObject).Assembly.GetType("Godot." + nativeTypeNameStr); if (wrapperType == null) { - wrapperType = AppDomain.CurrentDomain.GetAssemblies() - .FirstOrDefault(a => a.GetName().Name == "GodotSharpEditor")? - .GetType("Godot." + nativeTypeNameStr); + wrapperType = GetTypeByGodotClassAttr(typeof(GodotObject).Assembly, nativeTypeNameStr); + } + + if (wrapperType == null) + { + var editorAssembly = AppDomain.CurrentDomain.GetAssemblies() + .FirstOrDefault(a => a.GetName().Name == "GodotSharpEditor"); + wrapperType = editorAssembly?.GetType("Godot." + nativeTypeNameStr); + + if (wrapperType == null) + { + wrapperType = GetTypeByGodotClassAttr(editorAssembly, nativeTypeNameStr); + } + } + + static Type? GetTypeByGodotClassAttr(Assembly assembly, string nativeTypeNameStr) + { + var types = assembly.GetTypes(); + foreach (var type in types) + { + var attr = type.GetCustomAttribute<GodotClassNameAttribute>(); + if (attr?.Name == nativeTypeNameStr) + { + return type; + } + } + return null; } static bool IsStatic(Type type) => type.IsAbstract && type.IsSealed; if (wrapperType != null && IsStatic(wrapperType)) { - // A static class means this is a Godot singleton class. If an instance is needed we use Godot.Object. - return typeof(Object); + // A static class means this is a Godot singleton class. If an instance is needed we use GodotObject. + return typeof(GodotObject); } return wrapperType; @@ -293,7 +317,7 @@ namespace Godot.Bridge // such as when disabling C# source generators (for whatever reason) or when using a // language other than C# that has nothing similar to source generators to automate it. - var typeOfGodotObject = typeof(Object); + var typeOfGodotObject = typeof(GodotObject); foreach (var type in assembly.GetTypes()) { @@ -331,7 +355,7 @@ namespace Godot.Bridge { try { - var owner = (Object?)GCHandle.FromIntPtr(ownerGCHandlePtr).Target; + var owner = (GodotObject?)GCHandle.FromIntPtr(ownerGCHandlePtr).Target; if (owner == null) { @@ -539,9 +563,9 @@ namespace Godot.Bridge } // ReSharper disable once RedundantNameQualifier - if (!typeof(Godot.Object).IsAssignableFrom(scriptType)) + if (!typeof(GodotObject).IsAssignableFrom(scriptType)) { - // The class no longer inherits Godot.Object, can't reload + // The class no longer inherits GodotObject, can't reload return godot_bool.False; } @@ -589,7 +613,7 @@ namespace Godot.Bridge using var methods = new Collections.Array(); Type? top = scriptType; - Type native = Object.InternalGetClassNativeBase(top); + Type native = GodotObject.InternalGetClassNativeBase(top); while (top != null && top != native) { @@ -650,7 +674,7 @@ namespace Godot.Bridge continue; var rpcAttr = method.GetCustomAttributes(inherit: false) - .OfType<RPCAttribute>().FirstOrDefault(); + .OfType<RpcAttribute>().FirstOrDefault(); if (rpcAttr == null) continue; @@ -899,7 +923,7 @@ namespace Godot.Bridge try { Type? top = _scriptTypeBiMap.GetScriptType(scriptPtr); - Type native = Object.InternalGetClassNativeBase(top); + Type native = GodotObject.InternalGetClassNativeBase(top); while (top != null && top != native) { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs index 23b0aa9204..219a9a8c15 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs @@ -28,7 +28,7 @@ namespace Godot /// </example> public readonly partial struct Callable { - private readonly Object _target; + private readonly GodotObject _target; private readonly StringName _method; private readonly Delegate _delegate; private readonly unsafe delegate* managed<object, NativeVariantPtrArgs, out godot_variant, void> _trampoline; @@ -36,7 +36,7 @@ namespace Godot /// <summary> /// Object that contains the method. /// </summary> - public Object Target => _target; + public GodotObject Target => _target; /// <summary> /// Name of the method that will be called. @@ -60,7 +60,7 @@ namespace Godot /// </summary> /// <param name="target">Object that contains the method.</param> /// <param name="method">Name of the method that will be called.</param> - public unsafe Callable(Object target, StringName method) + public unsafe Callable(GodotObject target, StringName method) { _target = target; _method = method; @@ -71,7 +71,7 @@ namespace Godot private unsafe Callable(Delegate @delegate, delegate* managed<object, NativeVariantPtrArgs, out godot_variant, void> trampoline) { - _target = @delegate?.Target as Object; + _target = @delegate?.Target as GodotObject; _method = null; _delegate = @delegate; _trampoline = trampoline; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.generics.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.generics.cs index ff385da1c9..3005582bea 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.generics.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.generics.cs @@ -45,7 +45,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From(Action)"/> - public static unsafe Callable From<T0>( + public static unsafe Callable From<[MustBeVariant] T0>( Action<T0> action ) { @@ -64,7 +64,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From(Action)"/> - public static unsafe Callable From<T0, T1>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1>( Action<T0, T1> action ) { @@ -84,7 +84,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From(Action)"/> - public static unsafe Callable From<T0, T1, T2>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2>( Action<T0, T1, T2> action ) { @@ -105,7 +105,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From(Action)"/> - public static unsafe Callable From<T0, T1, T2, T3>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3>( Action<T0, T1, T2, T3> action ) { @@ -127,7 +127,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From(Action)"/> - public static unsafe Callable From<T0, T1, T2, T3, T4>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4>( Action<T0, T1, T2, T3, T4> action ) { @@ -150,7 +150,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From(Action)"/> - public static unsafe Callable From<T0, T1, T2, T3, T4, T5>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5>( Action<T0, T1, T2, T3, T4, T5> action ) { @@ -174,7 +174,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From(Action)"/> - public static unsafe Callable From<T0, T1, T2, T3, T4, T5, T6>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5, [MustBeVariant] T6>( Action<T0, T1, T2, T3, T4, T5, T6> action ) { @@ -199,7 +199,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From(Action)"/> - public static unsafe Callable From<T0, T1, T2, T3, T4, T5, T6, T7>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5, [MustBeVariant] T6, [MustBeVariant] T7>( Action<T0, T1, T2, T3, T4, T5, T6, T7> action ) { @@ -225,7 +225,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From(Action)"/> - public static unsafe Callable From<T0, T1, T2, T3, T4, T5, T6, T7, T8>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5, [MustBeVariant] T6, [MustBeVariant] T7, [MustBeVariant] T8>( Action<T0, T1, T2, T3, T4, T5, T6, T7, T8> action ) { @@ -255,7 +255,7 @@ public readonly partial struct Callable /// Constructs a new <see cref="Callable"/> for the given <paramref name="func"/>. /// </summary> /// <param name="func">Action method that will be called.</param> - public static unsafe Callable From<TResult>( + public static unsafe Callable From<[MustBeVariant] TResult>( Func<TResult> func ) { @@ -272,7 +272,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From{TResult}(Func{TResult})"/> - public static unsafe Callable From<T0, TResult>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] TResult>( Func<T0, TResult> func ) { @@ -291,7 +291,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From{TResult}(Func{TResult})"/> - public static unsafe Callable From<T0, T1, TResult>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] TResult>( Func<T0, T1, TResult> func ) { @@ -311,7 +311,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From{TResult}(Func{TResult})"/> - public static unsafe Callable From<T0, T1, T2, TResult>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] TResult>( Func<T0, T1, T2, TResult> func ) { @@ -332,7 +332,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From{TResult}(Func{TResult})"/> - public static unsafe Callable From<T0, T1, T2, T3, TResult>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] TResult>( Func<T0, T1, T2, T3, TResult> func ) { @@ -354,7 +354,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From{TResult}(Func{TResult})"/> - public static unsafe Callable From<T0, T1, T2, T3, T4, TResult>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] TResult>( Func<T0, T1, T2, T3, T4, TResult> func ) { @@ -377,7 +377,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From{TResult}(Func{TResult})"/> - public static unsafe Callable From<T0, T1, T2, T3, T4, T5, TResult>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5, [MustBeVariant] TResult>( Func<T0, T1, T2, T3, T4, T5, TResult> func ) { @@ -401,7 +401,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From{TResult}(Func{TResult})"/> - public static unsafe Callable From<T0, T1, T2, T3, T4, T5, T6, TResult>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5, [MustBeVariant] T6, [MustBeVariant] TResult>( Func<T0, T1, T2, T3, T4, T5, T6, TResult> func ) { @@ -426,7 +426,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From{TResult}(Func{TResult})"/> - public static unsafe Callable From<T0, T1, T2, T3, T4, T5, T6, T7, TResult>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5, [MustBeVariant] T6, [MustBeVariant] T7, [MustBeVariant] TResult>( Func<T0, T1, T2, T3, T4, T5, T6, T7, TResult> func ) { @@ -452,7 +452,7 @@ public readonly partial struct Callable } /// <inheritdoc cref="From{TResult}(Func{TResult})"/> - public static unsafe Callable From<T0, T1, T2, T3, T4, T5, T6, T7, T8, TResult>( + public static unsafe Callable From<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3, [MustBeVariant] T4, [MustBeVariant] T5, [MustBeVariant] T6, [MustBeVariant] T7, [MustBeVariant] T8, [MustBeVariant] TResult>( Func<T0, T1, T2, T3, T4, T5, T6, T7, T8, TResult> func ) { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs index 6a7863112a..555811bab2 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs @@ -21,97 +21,97 @@ namespace Godot /// <summary> /// The color's red component, typically on the range of 0 to 1. /// </summary> - public float r; + public float R; /// <summary> /// The color's green component, typically on the range of 0 to 1. /// </summary> - public float g; + public float G; /// <summary> /// The color's blue component, typically on the range of 0 to 1. /// </summary> - public float b; + public float B; /// <summary> /// The color's alpha (transparency) component, typically on the range of 0 to 1. /// </summary> - public float a; + public float A; /// <summary> - /// Wrapper for <see cref="r"/> that uses the range 0 to 255 instead of 0 to 1. + /// Wrapper for <see cref="R"/> that uses the range 0 to 255 instead of 0 to 1. /// </summary> /// <value>Getting is equivalent to multiplying by 255 and rounding. Setting is equivalent to dividing by 255.</value> - public int r8 + public int R8 { readonly get { - return (int)Math.Round(r * 255.0f); + return (int)Math.Round(R * 255.0f); } set { - r = value / 255.0f; + R = value / 255.0f; } } /// <summary> - /// Wrapper for <see cref="g"/> that uses the range 0 to 255 instead of 0 to 1. + /// Wrapper for <see cref="G"/> that uses the range 0 to 255 instead of 0 to 1. /// </summary> /// <value>Getting is equivalent to multiplying by 255 and rounding. Setting is equivalent to dividing by 255.</value> - public int g8 + public int G8 { readonly get { - return (int)Math.Round(g * 255.0f); + return (int)Math.Round(G * 255.0f); } set { - g = value / 255.0f; + G = value / 255.0f; } } /// <summary> - /// Wrapper for <see cref="b"/> that uses the range 0 to 255 instead of 0 to 1. + /// Wrapper for <see cref="B"/> that uses the range 0 to 255 instead of 0 to 1. /// </summary> /// <value>Getting is equivalent to multiplying by 255 and rounding. Setting is equivalent to dividing by 255.</value> - public int b8 + public int B8 { readonly get { - return (int)Math.Round(b * 255.0f); + return (int)Math.Round(B * 255.0f); } set { - b = value / 255.0f; + B = value / 255.0f; } } /// <summary> - /// Wrapper for <see cref="a"/> that uses the range 0 to 255 instead of 0 to 1. + /// Wrapper for <see cref="A"/> that uses the range 0 to 255 instead of 0 to 1. /// </summary> /// <value>Getting is equivalent to multiplying by 255 and rounding. Setting is equivalent to dividing by 255.</value> - public int a8 + public int A8 { readonly get { - return (int)Math.Round(a * 255.0f); + return (int)Math.Round(A * 255.0f); } set { - a = value / 255.0f; + A = value / 255.0f; } } /// <summary> /// The HSV hue of this color, on the range 0 to 1. /// </summary> - /// <value>Getting is a long process, refer to the source code for details. Setting uses <see cref="FromHSV"/>.</value> - public float h + /// <value>Getting is a long process, refer to the source code for details. Setting uses <see cref="FromHsv"/>.</value> + public float H { readonly get { - float max = Math.Max(r, Math.Max(g, b)); - float min = Math.Min(r, Math.Min(g, b)); + float max = Math.Max(R, Math.Max(G, B)); + float min = Math.Min(R, Math.Min(G, B)); float delta = max - min; @@ -122,17 +122,17 @@ namespace Godot float h; - if (r == max) + if (R == max) { - h = (g - b) / delta; // Between yellow & magenta + h = (G - B) / delta; // Between yellow & magenta } - else if (g == max) + else if (G == max) { - h = 2 + ((b - r) / delta); // Between cyan & yellow + h = 2 + ((B - R) / delta); // Between cyan & yellow } else { - h = 4 + ((r - g) / delta); // Between magenta & cyan + h = 4 + ((R - G) / delta); // Between magenta & cyan } h /= 6.0f; @@ -146,20 +146,20 @@ namespace Godot } set { - this = FromHSV(value, s, v, a); + this = FromHsv(value, S, V, A); } } /// <summary> /// The HSV saturation of this color, on the range 0 to 1. /// </summary> - /// <value>Getting is equivalent to the ratio between the min and max RGB value. Setting uses <see cref="FromHSV"/>.</value> - public float s + /// <value>Getting is equivalent to the ratio between the min and max RGB value. Setting uses <see cref="FromHsv"/>.</value> + public float S { readonly get { - float max = Math.Max(r, Math.Max(g, b)); - float min = Math.Min(r, Math.Min(g, b)); + float max = Math.Max(R, Math.Max(G, B)); + float min = Math.Min(R, Math.Min(G, B)); float delta = max - min; @@ -167,23 +167,23 @@ namespace Godot } set { - this = FromHSV(h, value, v, a); + this = FromHsv(H, value, V, A); } } /// <summary> /// The HSV value (brightness) of this color, on the range 0 to 1. /// </summary> - /// <value>Getting is equivalent to using <see cref="Math.Max(float, float)"/> on the RGB components. Setting uses <see cref="FromHSV"/>.</value> - public float v + /// <value>Getting is equivalent to using <see cref="Math.Max(float, float)"/> on the RGB components. Setting uses <see cref="FromHsv"/>.</value> + public float V { readonly get { - return Math.Max(r, Math.Max(g, b)); + return Math.Max(R, Math.Max(G, B)); } set { - this = FromHSV(h, s, value, a); + this = FromHsv(H, S, value, A); } } @@ -197,17 +197,17 @@ namespace Godot /// </summary> public readonly float Luminance { - get { return 0.2126f * r + 0.7152f * g + 0.0722f * b; } + get { return 0.2126f * R + 0.7152f * G + 0.0722f * B; } } /// <summary> /// Access color components using their index. /// </summary> /// <value> - /// <c>[0]</c> is equivalent to <see cref="r"/>, - /// <c>[1]</c> is equivalent to <see cref="g"/>, - /// <c>[2]</c> is equivalent to <see cref="b"/>, - /// <c>[3]</c> is equivalent to <see cref="a"/>. + /// <c>[0]</c> is equivalent to <see cref="R"/>, + /// <c>[1]</c> is equivalent to <see cref="G"/>, + /// <c>[2]</c> is equivalent to <see cref="B"/>, + /// <c>[3]</c> is equivalent to <see cref="A"/>. /// </value> public float this[int index] { @@ -216,13 +216,13 @@ namespace Godot switch (index) { case 0: - return r; + return R; case 1: - return g; + return G; case 2: - return b; + return B; case 3: - return a; + return A; default: throw new ArgumentOutOfRangeException(nameof(index)); } @@ -232,16 +232,16 @@ namespace Godot switch (index) { case 0: - r = value; + R = value; return; case 1: - g = value; + G = value; return; case 2: - b = value; + B = value; return; case 3: - a = value; + A = value; return; default: throw new ArgumentOutOfRangeException(nameof(index)); @@ -260,17 +260,17 @@ namespace Godot { Color res; - float sa = 1.0f - over.a; - res.a = (a * sa) + over.a; + float sa = 1.0f - over.A; + res.A = (A * sa) + over.A; - if (res.a == 0) + if (res.A == 0) { return new Color(0, 0, 0, 0); } - res.r = ((r * a * sa) + (over.r * over.a)) / res.a; - res.g = ((g * a * sa) + (over.g * over.a)) / res.a; - res.b = ((b * a * sa) + (over.b * over.a)) / res.a; + res.R = ((R * A * sa) + (over.R * over.A)) / res.A; + res.G = ((G * A * sa) + (over.G * over.A)) / res.A; + res.B = ((B * A * sa) + (over.B * over.A)) / res.A; return res; } @@ -289,10 +289,10 @@ namespace Godot Color maximum = max ?? new Color(1, 1, 1, 1); return new Color ( - (float)Mathf.Clamp(r, minimum.r, maximum.r), - (float)Mathf.Clamp(g, minimum.g, maximum.g), - (float)Mathf.Clamp(b, minimum.b, maximum.b), - (float)Mathf.Clamp(a, minimum.a, maximum.a) + (float)Mathf.Clamp(R, minimum.R, maximum.R), + (float)Mathf.Clamp(G, minimum.G, maximum.G), + (float)Mathf.Clamp(B, minimum.B, maximum.B), + (float)Mathf.Clamp(A, minimum.A, maximum.A) ); } @@ -305,9 +305,9 @@ namespace Godot public readonly Color Darkened(float amount) { Color res = this; - res.r *= 1.0f - amount; - res.g *= 1.0f - amount; - res.b *= 1.0f - amount; + res.R *= 1.0f - amount; + res.G *= 1.0f - amount; + res.B *= 1.0f - amount; return res; } @@ -318,10 +318,10 @@ namespace Godot public readonly Color Inverted() { return new Color( - 1.0f - r, - 1.0f - g, - 1.0f - b, - a + 1.0f - R, + 1.0f - G, + 1.0f - B, + A ); } @@ -334,9 +334,9 @@ namespace Godot public readonly Color Lightened(float amount) { Color res = this; - res.r += (1.0f - res.r) * amount; - res.g += (1.0f - res.g) * amount; - res.b += (1.0f - res.b) * amount; + res.R += (1.0f - res.R) * amount; + res.G += (1.0f - res.G) * amount; + res.B += (1.0f - res.B) * amount; return res; } @@ -351,10 +351,10 @@ namespace Godot { return new Color ( - (float)Mathf.Lerp(r, to.r, weight), - (float)Mathf.Lerp(g, to.g, weight), - (float)Mathf.Lerp(b, to.b, weight), - (float)Mathf.Lerp(a, to.a, weight) + (float)Mathf.Lerp(R, to.R, weight), + (float)Mathf.Lerp(G, to.G, weight), + (float)Mathf.Lerp(B, to.B, weight), + (float)Mathf.Lerp(A, to.A, weight) ); } @@ -367,9 +367,9 @@ namespace Godot public readonly Color LinearToSrgb() { return new Color( - r < 0.0031308f ? 12.92f * r : (1.0f + 0.055f) * (float)Mathf.Pow(r, 1.0f / 2.4f) - 0.055f, - g < 0.0031308f ? 12.92f * g : (1.0f + 0.055f) * (float)Mathf.Pow(g, 1.0f / 2.4f) - 0.055f, - b < 0.0031308f ? 12.92f * b : (1.0f + 0.055f) * (float)Mathf.Pow(b, 1.0f / 2.4f) - 0.055f, a); + R < 0.0031308f ? 12.92f * R : (1.0f + 0.055f) * (float)Mathf.Pow(R, 1.0f / 2.4f) - 0.055f, + G < 0.0031308f ? 12.92f * G : (1.0f + 0.055f) * (float)Mathf.Pow(G, 1.0f / 2.4f) - 0.055f, + B < 0.0031308f ? 12.92f * B : (1.0f + 0.055f) * (float)Mathf.Pow(B, 1.0f / 2.4f) - 0.055f, A); } /// <summary> @@ -381,10 +381,10 @@ namespace Godot public readonly Color SrgbToLinear() { return new Color( - r < 0.04045f ? r * (1.0f / 12.92f) : (float)Mathf.Pow((r + 0.055f) * (float)(1.0 / (1.0 + 0.055)), 2.4f), - g < 0.04045f ? g * (1.0f / 12.92f) : (float)Mathf.Pow((g + 0.055f) * (float)(1.0 / (1.0 + 0.055)), 2.4f), - b < 0.04045f ? b * (1.0f / 12.92f) : (float)Mathf.Pow((b + 0.055f) * (float)(1.0 / (1.0 + 0.055)), 2.4f), - a); + R < 0.04045f ? R * (1.0f / 12.92f) : (float)Mathf.Pow((R + 0.055f) * (float)(1.0 / (1.0 + 0.055)), 2.4f), + G < 0.04045f ? G * (1.0f / 12.92f) : (float)Mathf.Pow((G + 0.055f) * (float)(1.0 / (1.0 + 0.055)), 2.4f), + B < 0.04045f ? B * (1.0f / 12.92f) : (float)Mathf.Pow((B + 0.055f) * (float)(1.0 / (1.0 + 0.055)), 2.4f), + A); } /// <summary> @@ -395,13 +395,13 @@ namespace Godot /// <returns>A <see langword="uint"/> representing this color in ABGR32 format.</returns> public readonly uint ToAbgr32() { - uint c = (byte)Math.Round(a * 255); + uint c = (byte)Math.Round(A * 255); c <<= 8; - c |= (byte)Math.Round(b * 255); + c |= (byte)Math.Round(B * 255); c <<= 8; - c |= (byte)Math.Round(g * 255); + c |= (byte)Math.Round(G * 255); c <<= 8; - c |= (byte)Math.Round(r * 255); + c |= (byte)Math.Round(R * 255); return c; } @@ -414,13 +414,13 @@ namespace Godot /// <returns>A <see langword="ulong"/> representing this color in ABGR64 format.</returns> public readonly ulong ToAbgr64() { - ulong c = (ushort)Math.Round(a * 65535); + ulong c = (ushort)Math.Round(A * 65535); c <<= 16; - c |= (ushort)Math.Round(b * 65535); + c |= (ushort)Math.Round(B * 65535); c <<= 16; - c |= (ushort)Math.Round(g * 65535); + c |= (ushort)Math.Round(G * 65535); c <<= 16; - c |= (ushort)Math.Round(r * 65535); + c |= (ushort)Math.Round(R * 65535); return c; } @@ -433,13 +433,13 @@ namespace Godot /// <returns>A <see langword="uint"/> representing this color in ARGB32 format.</returns> public readonly uint ToArgb32() { - uint c = (byte)Math.Round(a * 255); + uint c = (byte)Math.Round(A * 255); c <<= 8; - c |= (byte)Math.Round(r * 255); + c |= (byte)Math.Round(R * 255); c <<= 8; - c |= (byte)Math.Round(g * 255); + c |= (byte)Math.Round(G * 255); c <<= 8; - c |= (byte)Math.Round(b * 255); + c |= (byte)Math.Round(B * 255); return c; } @@ -452,13 +452,13 @@ namespace Godot /// <returns>A <see langword="ulong"/> representing this color in ARGB64 format.</returns> public readonly ulong ToArgb64() { - ulong c = (ushort)Math.Round(a * 65535); + ulong c = (ushort)Math.Round(A * 65535); c <<= 16; - c |= (ushort)Math.Round(r * 65535); + c |= (ushort)Math.Round(R * 65535); c <<= 16; - c |= (ushort)Math.Round(g * 65535); + c |= (ushort)Math.Round(G * 65535); c <<= 16; - c |= (ushort)Math.Round(b * 65535); + c |= (ushort)Math.Round(B * 65535); return c; } @@ -471,13 +471,13 @@ namespace Godot /// <returns>A <see langword="uint"/> representing this color in RGBA32 format.</returns> public readonly uint ToRgba32() { - uint c = (byte)Math.Round(r * 255); + uint c = (byte)Math.Round(R * 255); c <<= 8; - c |= (byte)Math.Round(g * 255); + c |= (byte)Math.Round(G * 255); c <<= 8; - c |= (byte)Math.Round(b * 255); + c |= (byte)Math.Round(B * 255); c <<= 8; - c |= (byte)Math.Round(a * 255); + c |= (byte)Math.Round(A * 255); return c; } @@ -490,13 +490,13 @@ namespace Godot /// <returns>A <see langword="ulong"/> representing this color in RGBA64 format.</returns> public readonly ulong ToRgba64() { - ulong c = (ushort)Math.Round(r * 65535); + ulong c = (ushort)Math.Round(R * 65535); c <<= 16; - c |= (ushort)Math.Round(g * 65535); + c |= (ushort)Math.Round(G * 65535); c <<= 16; - c |= (ushort)Math.Round(b * 65535); + c |= (ushort)Math.Round(B * 65535); c <<= 16; - c |= (ushort)Math.Round(a * 65535); + c |= (ushort)Math.Round(A * 65535); return c; } @@ -508,17 +508,17 @@ namespace Godot /// Whether or not to include alpha. If <see langword="false"/>, the color is RGB instead of RGBA. /// </param> /// <returns>A string for the HTML hexadecimal representation of this color.</returns> - public readonly string ToHTML(bool includeAlpha = true) + public readonly string ToHtml(bool includeAlpha = true) { string txt = string.Empty; - txt += ToHex32(r); - txt += ToHex32(g); - txt += ToHex32(b); + txt += ToHex32(R); + txt += ToHex32(G); + txt += ToHex32(B); if (includeAlpha) { - txt += ToHex32(a); + txt += ToHex32(A); } return txt; @@ -533,10 +533,10 @@ namespace Godot /// <param name="a">The color's alpha (transparency) value, typically on the range of 0 to 1. Default: 1.</param> public Color(float r, float g, float b, float a = 1.0f) { - this.r = r; - this.g = g; - this.b = b; - this.a = a; + R = r; + G = g; + B = b; + A = a; } /// <summary> @@ -546,10 +546,10 @@ namespace Godot /// <param name="a">The color's alpha (transparency) value, typically on the range of 0 to 1. Default: 1.</param> public Color(Color c, float a = 1.0f) { - r = c.r; - g = c.g; - b = c.b; - this.a = a; + R = c.R; + G = c.G; + B = c.B; + A = a; } /// <summary> @@ -559,13 +559,13 @@ namespace Godot /// <param name="rgba">The <see langword="uint"/> representing the color.</param> public Color(uint rgba) { - a = (rgba & 0xFF) / 255.0f; + A = (rgba & 0xFF) / 255.0f; rgba >>= 8; - b = (rgba & 0xFF) / 255.0f; + B = (rgba & 0xFF) / 255.0f; rgba >>= 8; - g = (rgba & 0xFF) / 255.0f; + G = (rgba & 0xFF) / 255.0f; rgba >>= 8; - r = (rgba & 0xFF) / 255.0f; + R = (rgba & 0xFF) / 255.0f; } /// <summary> @@ -575,13 +575,13 @@ namespace Godot /// <param name="rgba">The <see langword="ulong"/> representing the color.</param> public Color(ulong rgba) { - a = (rgba & 0xFFFF) / 65535.0f; + A = (rgba & 0xFFFF) / 65535.0f; rgba >>= 16; - b = (rgba & 0xFFFF) / 65535.0f; + B = (rgba & 0xFFFF) / 65535.0f; rgba >>= 16; - g = (rgba & 0xFFFF) / 65535.0f; + G = (rgba & 0xFFFF) / 65535.0f; rgba >>= 16; - r = (rgba & 0xFFFF) / 65535.0f; + R = (rgba & 0xFFFF) / 65535.0f; } /// <summary> @@ -598,7 +598,7 @@ namespace Godot { if (HtmlIsValid(code)) { - this = FromHTML(code); + this = FromHtml(code); } else { @@ -616,7 +616,7 @@ namespace Godot public Color(string code, float alpha) { this = new Color(code); - a = alpha; + A = alpha; } /// <summary> @@ -626,15 +626,15 @@ namespace Godot /// <exception name="ArgumentOutOfRangeException"> /// <paramref name="rgba"/> color code is invalid. /// </exception> - public static Color FromHTML(ReadOnlySpan<char> rgba) + public static Color FromHtml(ReadOnlySpan<char> rgba) { Color c; if (rgba.Length == 0) { - c.r = 0f; - c.g = 0f; - c.b = 0f; - c.a = 1.0f; + c.R = 0f; + c.G = 0f; + c.B = 0f; + c.A = 1.0f; return c; } @@ -670,44 +670,44 @@ namespace Godot $"Invalid color code. Length is {rgba.Length}, but a length of 6 or 8 is expected: {rgba}"); } - c.a = 1.0f; + c.A = 1.0f; if (isShorthand) { - c.r = ParseCol4(rgba, 0) / 15f; - c.g = ParseCol4(rgba, 1) / 15f; - c.b = ParseCol4(rgba, 2) / 15f; + c.R = ParseCol4(rgba, 0) / 15f; + c.G = ParseCol4(rgba, 1) / 15f; + c.B = ParseCol4(rgba, 2) / 15f; if (alpha) { - c.a = ParseCol4(rgba, 3) / 15f; + c.A = ParseCol4(rgba, 3) / 15f; } } else { - c.r = ParseCol8(rgba, 0) / 255f; - c.g = ParseCol8(rgba, 2) / 255f; - c.b = ParseCol8(rgba, 4) / 255f; + c.R = ParseCol8(rgba, 0) / 255f; + c.G = ParseCol8(rgba, 2) / 255f; + c.B = ParseCol8(rgba, 4) / 255f; if (alpha) { - c.a = ParseCol8(rgba, 6) / 255f; + c.A = ParseCol8(rgba, 6) / 255f; } } - if (c.r < 0) + if (c.R < 0) { throw new ArgumentOutOfRangeException($"Invalid color code. Red part is not valid hexadecimal: {rgba}"); } - if (c.g < 0) + if (c.G < 0) { throw new ArgumentOutOfRangeException($"Invalid color code. Green part is not valid hexadecimal: {rgba}"); } - if (c.b < 0) + if (c.B < 0) { throw new ArgumentOutOfRangeException($"Invalid color code. Blue part is not valid hexadecimal: {rgba}"); } - if (c.a < 0) + if (c.A < 0) { throw new ArgumentOutOfRangeException($"Invalid color code. Alpha part is not valid hexadecimal: {rgba}"); } @@ -793,7 +793,7 @@ namespace Godot /// <param name="value">The HSV value (brightness), typically on the range of 0 to 1.</param> /// <param name="alpha">The alpha (transparency) value, typically on the range of 0 to 1.</param> /// <returns>The constructed color.</returns> - public static Color FromHSV(float hue, float saturation, float value, float alpha = 1.0f) + public static Color FromHsv(float hue, float saturation, float value, float alpha = 1.0f) { if (saturation == 0) { @@ -837,10 +837,10 @@ namespace Godot /// <param name="hue">Output parameter for the HSV hue.</param> /// <param name="saturation">Output parameter for the HSV saturation.</param> /// <param name="value">Output parameter for the HSV value.</param> - public readonly void ToHSV(out float hue, out float saturation, out float value) + public readonly void ToHsv(out float hue, out float saturation, out float value) { - float max = (float)Mathf.Max(r, Mathf.Max(g, b)); - float min = (float)Mathf.Min(r, Mathf.Min(g, b)); + float max = (float)Mathf.Max(R, Mathf.Max(G, B)); + float min = (float)Mathf.Min(R, Mathf.Min(G, B)); float delta = max - min; @@ -850,17 +850,17 @@ namespace Godot } else { - if (r == max) + if (R == max) { - hue = (g - b) / delta; // Between yellow & magenta + hue = (G - B) / delta; // Between yellow & magenta } - else if (g == max) + else if (G == max) { - hue = 2 + ((b - r) / delta); // Between cyan & yellow + hue = 2 + ((B - R) / delta); // Between cyan & yellow } else { - hue = 4 + ((r - g) / delta); // Between magenta & cyan + hue = 4 + ((R - G) / delta); // Between magenta & cyan } hue /= 6.0f; @@ -950,7 +950,7 @@ namespace Godot { if (HtmlIsValid(str)) { - return FromHTML(str); + return FromHtml(str); } else { @@ -1012,10 +1012,10 @@ namespace Godot /// <returns>The added color.</returns> public static Color operator +(Color left, Color right) { - left.r += right.r; - left.g += right.g; - left.b += right.b; - left.a += right.a; + left.R += right.R; + left.G += right.G; + left.B += right.B; + left.A += right.A; return left; } @@ -1028,17 +1028,17 @@ namespace Godot /// <returns>The subtracted color.</returns> public static Color operator -(Color left, Color right) { - left.r -= right.r; - left.g -= right.g; - left.b -= right.b; - left.a -= right.a; + left.R -= right.R; + left.G -= right.G; + left.B -= right.B; + left.A -= right.A; return left; } /// <summary> /// Inverts the given color. This is equivalent to /// <c>Colors.White - c</c> or - /// <c>new Color(1 - c.r, 1 - c.g, 1 - c.b, 1 - c.a)</c>. + /// <c>new Color(1 - c.R, 1 - c.G, 1 - c.B, 1 - c.A)</c>. /// </summary> /// <param name="color">The color to invert.</param> /// <returns>The inverted color.</returns> @@ -1056,10 +1056,10 @@ namespace Godot /// <returns>The multiplied color.</returns> public static Color operator *(Color color, float scale) { - color.r *= scale; - color.g *= scale; - color.b *= scale; - color.a *= scale; + color.R *= scale; + color.G *= scale; + color.B *= scale; + color.A *= scale; return color; } @@ -1072,10 +1072,10 @@ namespace Godot /// <returns>The multiplied color.</returns> public static Color operator *(float scale, Color color) { - color.r *= scale; - color.g *= scale; - color.b *= scale; - color.a *= scale; + color.R *= scale; + color.G *= scale; + color.B *= scale; + color.A *= scale; return color; } @@ -1088,10 +1088,10 @@ namespace Godot /// <returns>The multiplied color.</returns> public static Color operator *(Color left, Color right) { - left.r *= right.r; - left.g *= right.g; - left.b *= right.b; - left.a *= right.a; + left.R *= right.R; + left.G *= right.G; + left.B *= right.B; + left.A *= right.A; return left; } @@ -1104,10 +1104,10 @@ namespace Godot /// <returns>The divided color.</returns> public static Color operator /(Color color, float scale) { - color.r /= scale; - color.g /= scale; - color.b /= scale; - color.a /= scale; + color.R /= scale; + color.G /= scale; + color.B /= scale; + color.A /= scale; return color; } @@ -1120,10 +1120,10 @@ namespace Godot /// <returns>The divided color.</returns> public static Color operator /(Color left, Color right) { - left.r /= right.r; - left.g /= right.g; - left.b /= right.b; - left.a /= right.a; + left.R /= right.R; + left.G /= right.G; + left.B /= right.B; + left.A /= right.A; return left; } @@ -1167,19 +1167,19 @@ namespace Godot /// <returns>Whether or not the left is less than the right.</returns> public static bool operator <(Color left, Color right) { - if (left.r == right.r) + if (left.R == right.R) { - if (left.g == right.g) + if (left.G == right.G) { - if (left.b == right.b) + if (left.B == right.B) { - return left.a < right.a; + return left.A < right.A; } - return left.b < right.b; + return left.B < right.B; } - return left.g < right.g; + return left.G < right.G; } - return left.r < right.r; + return left.R < right.R; } /// <summary> @@ -1196,19 +1196,19 @@ namespace Godot /// <returns>Whether or not the left is greater than the right.</returns> public static bool operator >(Color left, Color right) { - if (left.r == right.r) + if (left.R == right.R) { - if (left.g == right.g) + if (left.G == right.G) { - if (left.b == right.b) + if (left.B == right.B) { - return left.a > right.a; + return left.A > right.A; } - return left.b > right.b; + return left.B > right.B; } - return left.g > right.g; + return left.G > right.G; } - return left.r > right.r; + return left.R > right.R; } /// <summary> @@ -1225,19 +1225,19 @@ namespace Godot /// <returns>Whether or not the left is less than or equal to the right.</returns> public static bool operator <=(Color left, Color right) { - if (left.r == right.r) + if (left.R == right.R) { - if (left.g == right.g) + if (left.G == right.G) { - if (left.b == right.b) + if (left.B == right.B) { - return left.a <= right.a; + return left.A <= right.A; } - return left.b < right.b; + return left.B < right.B; } - return left.g < right.g; + return left.G < right.G; } - return left.r < right.r; + return left.R < right.R; } /// <summary> @@ -1254,19 +1254,19 @@ namespace Godot /// <returns>Whether or not the left is greater than or equal to the right.</returns> public static bool operator >=(Color left, Color right) { - if (left.r == right.r) + if (left.R == right.R) { - if (left.g == right.g) + if (left.G == right.G) { - if (left.b == right.b) + if (left.B == right.B) { - return left.a >= right.a; + return left.A >= right.A; } - return left.b > right.b; + return left.B > right.B; } - return left.g > right.g; + return left.G > right.G; } - return left.r > right.r; + return left.R > right.R; } /// <summary> @@ -1288,7 +1288,7 @@ namespace Godot /// <returns>Whether or not the colors are equal.</returns> public readonly bool Equals(Color other) { - return r == other.r && g == other.g && b == other.b && a == other.a; + return R == other.R && G == other.G && B == other.B && A == other.A; } /// <summary> @@ -1299,7 +1299,7 @@ namespace Godot /// <returns>Whether or not the colors are approximately equal.</returns> public readonly bool IsEqualApprox(Color other) { - return Mathf.IsEqualApprox(r, other.r) && Mathf.IsEqualApprox(g, other.g) && Mathf.IsEqualApprox(b, other.b) && Mathf.IsEqualApprox(a, other.a); + return Mathf.IsEqualApprox(R, other.R) && Mathf.IsEqualApprox(G, other.G) && Mathf.IsEqualApprox(B, other.B) && Mathf.IsEqualApprox(A, other.A); } /// <summary> @@ -1308,7 +1308,7 @@ namespace Godot /// <returns>A hash code for this color.</returns> public override readonly int GetHashCode() { - return r.GetHashCode() ^ g.GetHashCode() ^ b.GetHashCode() ^ a.GetHashCode(); + return R.GetHashCode() ^ G.GetHashCode() ^ B.GetHashCode() ^ A.GetHashCode(); } /// <summary> @@ -1317,7 +1317,7 @@ namespace Godot /// <returns>A string representation of this color.</returns> public override readonly string ToString() { - return $"({r}, {g}, {b}, {a})"; + return $"({R}, {G}, {B}, {A})"; } /// <summary> @@ -1326,7 +1326,7 @@ namespace Godot /// <returns>A string representation of this color.</returns> public readonly string ToString(string format) { - return $"({r.ToString(format)}, {g.ToString(format)}, {b.ToString(format)}, {a.ToString(format)})"; + return $"({R.ToString(format)}, {G.ToString(format)}, {B.ToString(format)}, {A.ToString(format)})"; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs index d94fbff331..4a54f67cc9 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs @@ -126,7 +126,7 @@ namespace Godot } } // ReSharper disable once RedundantNameQualifier - case Godot.Object godotObject: + case GodotObject godotObject: { using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) @@ -399,7 +399,7 @@ namespace Godot { ulong objectId = reader.ReadUInt64(); // ReSharper disable once RedundantNameQualifier - Godot.Object godotObject = GD.InstanceFromId(objectId); + GodotObject godotObject = GodotObject.InstanceFromId(objectId); if (godotObject == null) return false; @@ -581,31 +581,31 @@ namespace Godot return VariantUtils.CreateFrom(@double); case Vector2 vector2: return VariantUtils.CreateFrom(vector2); - case Vector2i vector2I: + case Vector2I vector2I: return VariantUtils.CreateFrom(vector2I); case Rect2 rect2: return VariantUtils.CreateFrom(rect2); - case Rect2i rect2I: + case Rect2I rect2I: return VariantUtils.CreateFrom(rect2I); case Transform2D transform2D: return VariantUtils.CreateFrom(transform2D); case Vector3 vector3: return VariantUtils.CreateFrom(vector3); - case Vector3i vector3I: + case Vector3I vector3I: return VariantUtils.CreateFrom(vector3I); case Vector4 vector4: return VariantUtils.CreateFrom(vector4); - case Vector4i vector4I: + case Vector4I vector4I: return VariantUtils.CreateFrom(vector4I); case Basis basis: return VariantUtils.CreateFrom(basis); case Quaternion quaternion: return VariantUtils.CreateFrom(quaternion); - case Transform3D transform3d: - return VariantUtils.CreateFrom(transform3d); + case Transform3D transform3D: + return VariantUtils.CreateFrom(transform3D); case Projection projection: return VariantUtils.CreateFrom(projection); - case AABB aabb: + case Aabb aabb: return VariantUtils.CreateFrom(aabb); case Color color: return VariantUtils.CreateFrom(color); @@ -639,15 +639,15 @@ namespace Godot return VariantUtils.CreateFrom(stringNameArray); case NodePath[] nodePathArray: return VariantUtils.CreateFrom(nodePathArray); - case RID[] ridArray: + case Rid[] ridArray: return VariantUtils.CreateFrom(ridArray); - case Godot.Object[] godotObjectArray: + case GodotObject[] godotObjectArray: return VariantUtils.CreateFrom(godotObjectArray); case StringName stringName: return VariantUtils.CreateFrom(stringName); case NodePath nodePath: return VariantUtils.CreateFrom(nodePath); - case RID rid: + case Rid rid: return VariantUtils.CreateFrom(rid); case Collections.Dictionary godotDictionary: return VariantUtils.CreateFrom(godotDictionary); @@ -655,7 +655,7 @@ namespace Godot return VariantUtils.CreateFrom(godotArray); case Variant variant: return VariantUtils.CreateFrom(variant); - case Godot.Object godotObject: + case GodotObject godotObject: return VariantUtils.CreateFrom(godotObject); case Enum @enum: return VariantUtils.CreateFrom(Convert.ToInt64(@enum)); @@ -690,18 +690,18 @@ namespace Godot [typeof(float)] = (in godot_variant variant) => VariantUtils.ConvertTo<float>(variant), [typeof(double)] = (in godot_variant variant) => VariantUtils.ConvertTo<double>(variant), [typeof(Vector2)] = (in godot_variant variant) => VariantUtils.ConvertTo<Vector2>(variant), - [typeof(Vector2i)] = (in godot_variant variant) => VariantUtils.ConvertTo<Vector2i>(variant), + [typeof(Vector2I)] = (in godot_variant variant) => VariantUtils.ConvertTo<Vector2I>(variant), [typeof(Rect2)] = (in godot_variant variant) => VariantUtils.ConvertTo<Rect2>(variant), - [typeof(Rect2i)] = (in godot_variant variant) => VariantUtils.ConvertTo<Rect2i>(variant), + [typeof(Rect2I)] = (in godot_variant variant) => VariantUtils.ConvertTo<Rect2I>(variant), [typeof(Transform2D)] = (in godot_variant variant) => VariantUtils.ConvertTo<Transform2D>(variant), [typeof(Vector3)] = (in godot_variant variant) => VariantUtils.ConvertTo<Vector3>(variant), - [typeof(Vector3i)] = (in godot_variant variant) => VariantUtils.ConvertTo<Vector3i>(variant), + [typeof(Vector3I)] = (in godot_variant variant) => VariantUtils.ConvertTo<Vector3I>(variant), [typeof(Basis)] = (in godot_variant variant) => VariantUtils.ConvertTo<Basis>(variant), [typeof(Quaternion)] = (in godot_variant variant) => VariantUtils.ConvertTo<Quaternion>(variant), [typeof(Transform3D)] = (in godot_variant variant) => VariantUtils.ConvertTo<Transform3D>(variant), [typeof(Vector4)] = (in godot_variant variant) => VariantUtils.ConvertTo<Vector4>(variant), - [typeof(Vector4i)] = (in godot_variant variant) => VariantUtils.ConvertTo<Vector4i>(variant), - [typeof(AABB)] = (in godot_variant variant) => VariantUtils.ConvertTo<AABB>(variant), + [typeof(Vector4I)] = (in godot_variant variant) => VariantUtils.ConvertTo<Vector4I>(variant), + [typeof(Aabb)] = (in godot_variant variant) => VariantUtils.ConvertTo<Aabb>(variant), [typeof(Color)] = (in godot_variant variant) => VariantUtils.ConvertTo<Color>(variant), [typeof(Plane)] = (in godot_variant variant) => VariantUtils.ConvertTo<Plane>(variant), [typeof(Callable)] = (in godot_variant variant) => VariantUtils.ConvertTo<Callable>(variant), @@ -719,10 +719,10 @@ namespace Godot [typeof(StringName[])] = (in godot_variant variant) => VariantUtils.ConvertTo<StringName[]>(variant), [typeof(NodePath[])] = (in godot_variant variant) => VariantUtils.ConvertTo<NodePath[]>(variant), - [typeof(RID[])] = (in godot_variant variant) => VariantUtils.ConvertTo<RID[]>(variant), + [typeof(Rid[])] = (in godot_variant variant) => VariantUtils.ConvertTo<Rid[]>(variant), [typeof(StringName)] = (in godot_variant variant) => VariantUtils.ConvertTo<StringName>(variant), [typeof(NodePath)] = (in godot_variant variant) => VariantUtils.ConvertTo<NodePath>(variant), - [typeof(RID)] = (in godot_variant variant) => VariantUtils.ConvertTo<RID>(variant), + [typeof(Rid)] = (in godot_variant variant) => VariantUtils.ConvertTo<Rid>(variant), [typeof(Godot.Collections.Dictionary)] = (in godot_variant variant) => VariantUtils.ConvertTo<Godot.Collections.Dictionary>(variant), [typeof(Godot.Collections.Array)] = @@ -736,18 +736,18 @@ namespace Godot if (ToSystemObjectFuncByType.TryGetValue(type, out var func)) return func(variant); - if (typeof(Godot.Object).IsAssignableFrom(type)) - return Convert.ChangeType(VariantUtils.ConvertTo<Godot.Object>(variant), type); + if (typeof(GodotObject).IsAssignableFrom(type)) + return Convert.ChangeType(VariantUtils.ConvertTo<GodotObject>(variant), type); - if (typeof(Godot.Object[]).IsAssignableFrom(type)) + if (typeof(GodotObject[]).IsAssignableFrom(type)) { - static Godot.Object[] ConvertToSystemArrayOfGodotObject(in godot_array nativeArray, Type type) + static GodotObject[] ConvertToSystemArrayOfGodotObject(in godot_array nativeArray, Type type) { var array = Collections.Array.CreateTakingOwnershipOfDisposableValue( NativeFuncs.godotsharp_array_new_copy(nativeArray)); int length = array.Count; - var ret = (Godot.Object[])Activator.CreateInstance(type, length)!; + var ret = (GodotObject[])Activator.CreateInstance(type, length)!; for (int i = 0; i < length; i++) ret[i] = array[i].AsGodotObject(); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs index b5a8742d3d..923b2adafd 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs @@ -68,7 +68,15 @@ namespace Godot.Collections } /// <summary> - /// Duplicates this <see cref="Dictionary"/>. + /// Returns a copy of the <see cref="Dictionary"/>. + /// If <paramref name="deep"/> is <see langword="true"/>, a deep copy is performed: + /// all nested arrays and dictionaries are duplicated and will not be shared with + /// the original dictionary. If <see langword="false"/>, a shallow copy is made and + /// references to the original nested arrays and dictionaries are kept, so that + /// modifying a sub-array or dictionary in the copy will also impact those + /// referenced in the source dictionary. Note that any <see cref="GodotObject"/> derived + /// elements will be shallow copied regardless of the <paramref name="deep"/> + /// setting. /// </summary> /// <param name="deep">If <see langword="true"/>, performs a deep copy.</param> /// <returns>A new Godot Dictionary.</returns> @@ -80,6 +88,44 @@ namespace Godot.Collections return CreateTakingOwnershipOfDisposableValue(newDictionary); } + /// <summary> + /// Adds entries from <paramref name="dictionary"/> to this dictionary. + /// By default, duplicate keys are not copied over, unless <paramref name="overwrite"/> + /// is <see langword="true"/>. + /// </summary> + /// <exception cref="InvalidOperationException"> + /// The dictionary is read-only. + /// </exception> + /// <param name="dictionary">Dictionary to copy entries from.</param> + /// <param name="overwrite">If duplicate keys should be copied over as well.</param> + public void Merge(Dictionary dictionary, bool overwrite = false) + { + ThrowIfReadOnly(); + + var self = (godot_dictionary)NativeValue; + var other = (godot_dictionary)dictionary.NativeValue; + NativeFuncs.godotsharp_dictionary_merge(ref self, in other, overwrite.ToGodotBool()); + } + + /// <summary> + /// Compares this <see cref="Dictionary"/> against the <paramref name="other"/> + /// <see cref="Dictionary"/> recursively. Returns <see langword="true"/> if the + /// two dictionaries contain the same keys and values. The order of the entries + /// does not matter. + /// otherwise. + /// </summary> + /// <param name="other">The other dictionary to compare against.</param> + /// <returns> + /// <see langword="true"/> if the dictionaries contain the same keys and values, + /// <see langword="false"/> otherwise. + /// </returns> + public bool RecursiveEqual(Dictionary other) + { + var self = (godot_dictionary)NativeValue; + var otherVariant = (godot_dictionary)other.NativeValue; + return NativeFuncs.godotsharp_dictionary_recursive_equal(ref self, otherVariant).ToBool(); + } + // IDictionary /// <summary> @@ -134,6 +180,13 @@ namespace Godot.Collections /// <summary> /// Returns the value at the given <paramref name="key"/>. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The property is assigned and the dictionary is read-only. + /// </exception> + /// <exception cref="KeyNotFoundException"> + /// The property is retrieved and an entry for <paramref name="key"/> + /// does not exist in the dictionary. + /// </exception> /// <value>The value at the given <paramref name="key"/>.</value> public Variant this[Variant key] { @@ -153,6 +206,8 @@ namespace Godot.Collections } set { + ThrowIfReadOnly(); + var self = (godot_dictionary)NativeValue; NativeFuncs.godotsharp_dictionary_set_value(ref self, (godot_variant)key.NativeVar, (godot_variant)value.NativeVar); @@ -163,10 +218,18 @@ namespace Godot.Collections /// Adds an value <paramref name="value"/> at key <paramref name="key"/> /// to this <see cref="Dictionary"/>. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The dictionary is read-only. + /// </exception> + /// <exception cref="ArgumentException"> + /// An entry for <paramref name="key"/> already exists in the dictionary. + /// </exception> /// <param name="key">The key at which to add the value.</param> /// <param name="value">The value to add.</param> public void Add(Variant key, Variant value) { + ThrowIfReadOnly(); + var variantKey = (godot_variant)key.NativeVar; var self = (godot_dictionary)NativeValue; @@ -181,10 +244,15 @@ namespace Godot.Collections => Add(item.Key, item.Value); /// <summary> - /// Erases all items from this <see cref="Dictionary"/>. + /// Clears the dictionary, removing all entries from it. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The dictionary is read-only. + /// </exception> public void Clear() { + ThrowIfReadOnly(); + var self = (godot_dictionary)NativeValue; NativeFuncs.godotsharp_dictionary_clear(ref self); } @@ -200,7 +268,7 @@ namespace Godot.Collections return NativeFuncs.godotsharp_dictionary_contains_key(ref self, (godot_variant)key.NativeVar).ToBool(); } - public bool Contains(KeyValuePair<Variant, Variant> item) + bool ICollection<KeyValuePair<Variant, Variant>>.Contains(KeyValuePair<Variant, Variant> item) { godot_variant variantKey = (godot_variant)item.Key.NativeVar; var self = (godot_dictionary)NativeValue; @@ -220,15 +288,22 @@ namespace Godot.Collections /// <summary> /// Removes an element from this <see cref="Dictionary"/> by key. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The dictionary is read-only. + /// </exception> /// <param name="key">The key of the element to remove.</param> public bool Remove(Variant key) { + ThrowIfReadOnly(); + var self = (godot_dictionary)NativeValue; return NativeFuncs.godotsharp_dictionary_remove_key(ref self, (godot_variant)key.NativeVar).ToBool(); } - public bool Remove(KeyValuePair<Variant, Variant> item) + bool ICollection<KeyValuePair<Variant, Variant>>.Remove(KeyValuePair<Variant, Variant> item) { + ThrowIfReadOnly(); + godot_variant variantKey = (godot_variant)item.Key.NativeVar; var self = (godot_dictionary)NativeValue; bool found = NativeFuncs.godotsharp_dictionary_try_get_value(ref self, @@ -264,8 +339,37 @@ namespace Godot.Collections } } - bool ICollection<KeyValuePair<Variant, Variant>>.IsReadOnly => false; + /// <summary> + /// Returns <see langword="true"/> if the dictionary is read-only. + /// See <see cref="MakeReadOnly"/>. + /// </summary> + public bool IsReadOnly => NativeValue.DangerousSelfRef.IsReadOnly; + + /// <summary> + /// Makes the <see cref="Dictionary"/> read-only, i.e. disabled modying of the + /// dictionary's elements. Does not apply to nested content, e.g. content of + /// nested dictionaries. + /// </summary> + public void MakeReadOnly() + { + if (IsReadOnly) + { + // Avoid interop call when the dictionary is already read-only. + return; + } + + var self = (godot_dictionary)NativeValue; + NativeFuncs.godotsharp_dictionary_make_read_only(ref self); + } + /// <summary> + /// Gets the value for the given <paramref name="key"/> in the dictionary. + /// Returns <see langword="true"/> if an entry for the given key exists in + /// the dictionary; otherwise, returns <see langword="false"/>. + /// </summary> + /// <param name="key">The key of the element to get.</param> + /// <param name="value">The value at the given <paramref name="key"/>.</param> + /// <returns>If an entry was found for the given <paramref name="key"/>.</returns> public bool TryGetValue(Variant key, out Variant value) { var self = (godot_dictionary)NativeValue; @@ -283,7 +387,7 @@ namespace Godot.Collections /// </summary> /// <param name="array">The array to copy to.</param> /// <param name="arrayIndex">The index to start at.</param> - public void CopyTo(KeyValuePair<Variant, Variant>[] array, int arrayIndex) + void ICollection<KeyValuePair<Variant, Variant>>.CopyTo(KeyValuePair<Variant, Variant>[] array, int arrayIndex) { if (array == null) throw new ArgumentNullException(nameof(array), "Value cannot be null."); @@ -342,6 +446,14 @@ namespace Godot.Collections using (str) return Marshaling.ConvertStringToManaged(str); } + + private void ThrowIfReadOnly() + { + if (IsReadOnly) + { + throw new InvalidOperationException("Dictionary instance is read-only."); + } + } } internal interface IGenericGodotDictionary @@ -433,20 +545,64 @@ namespace Godot.Collections } /// <summary> - /// Duplicates this <see cref="Dictionary{TKey, TValue}"/>. + /// Returns a copy of the <see cref="Dictionary{TKey, TValue}"/>. + /// If <paramref name="deep"/> is <see langword="true"/>, a deep copy is performed: + /// all nested arrays and dictionaries are duplicated and will not be shared with + /// the original dictionary. If <see langword="false"/>, a shallow copy is made and + /// references to the original nested arrays and dictionaries are kept, so that + /// modifying a sub-array or dictionary in the copy will also impact those + /// referenced in the source dictionary. Note that any <see cref="GodotObject"/> derived + /// elements will be shallow copied regardless of the <paramref name="deep"/> + /// setting. /// </summary> - /// <param name="deep">If <see langword="true"/>, performs a deep copy.</param> - /// <returns>A new Godot Dictionary.</returns> public Dictionary<TKey, TValue> Duplicate(bool deep = false) { return new Dictionary<TKey, TValue>(_underlyingDict.Duplicate(deep)); } + /// <summary> + /// Adds entries from <paramref name="dictionary"/> to this dictionary. + /// By default, duplicate keys are not copied over, unless <paramref name="overwrite"/> + /// is <see langword="true"/>. + /// </summary> + /// <exception cref="InvalidOperationException"> + /// The dictionary is read-only. + /// </exception> + /// <param name="dictionary">Dictionary to copy entries from.</param> + /// <param name="overwrite">If duplicate keys should be copied over as well.</param> + public void Merge(Dictionary<TKey, TValue> dictionary, bool overwrite = false) + { + _underlyingDict.Merge(dictionary._underlyingDict, overwrite); + } + + /// <summary> + /// Compares this <see cref="Dictionary{TKey, TValue}"/> against the <paramref name="other"/> + /// <see cref="Dictionary{TKey, TValue}"/> recursively. Returns <see langword="true"/> if the + /// two dictionaries contain the same keys and values. The order of the entries does not matter. + /// otherwise. + /// </summary> + /// <param name="other">The other dictionary to compare against.</param> + /// <returns> + /// <see langword="true"/> if the dictionaries contain the same keys and values, + /// <see langword="false"/> otherwise. + /// </returns> + public bool RecursiveEqual(Dictionary<TKey, TValue> other) + { + return _underlyingDict.RecursiveEqual(other._underlyingDict); + } + // IDictionary<TKey, TValue> /// <summary> /// Returns the value at the given <paramref name="key"/>. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The property is assigned and the dictionary is read-only. + /// </exception> + /// <exception cref="KeyNotFoundException"> + /// The property is retrieved and an entry for <paramref name="key"/> + /// does not exist in the dictionary. + /// </exception> /// <value>The value at the given <paramref name="key"/>.</value> public TValue this[TKey key] { @@ -468,6 +624,8 @@ namespace Godot.Collections } set { + ThrowIfReadOnly(); + using var variantKey = VariantUtils.CreateFrom(key); using var variantValue = VariantUtils.CreateFrom(value); var self = (godot_dictionary)_underlyingDict.NativeValue; @@ -527,10 +685,15 @@ namespace Godot.Collections /// Adds an object <paramref name="value"/> at key <paramref name="key"/> /// to this <see cref="Dictionary{TKey, TValue}"/>. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The dictionary is read-only. + /// </exception> /// <param name="key">The key at which to add the object.</param> /// <param name="value">The object to add.</param> public void Add(TKey key, TValue value) { + ThrowIfReadOnly(); + using var variantKey = VariantUtils.CreateFrom(key); var self = (godot_dictionary)_underlyingDict.NativeValue; @@ -556,20 +719,27 @@ namespace Godot.Collections /// <summary> /// Removes an element from this <see cref="Dictionary{TKey, TValue}"/> by key. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The dictionary is read-only. + /// </exception> /// <param name="key">The key of the element to remove.</param> public bool Remove(TKey key) { + ThrowIfReadOnly(); + using var variantKey = VariantUtils.CreateFrom(key); var self = (godot_dictionary)_underlyingDict.NativeValue; return NativeFuncs.godotsharp_dictionary_remove_key(ref self, variantKey).ToBool(); } /// <summary> - /// Gets the object at the given <paramref name="key"/>. + /// Gets the value for the given <paramref name="key"/> in the dictionary. + /// Returns <see langword="true"/> if an entry for the given key exists in + /// the dictionary; otherwise, returns <see langword="false"/>. /// </summary> /// <param name="key">The key of the element to get.</param> /// <param name="value">The value at the given <paramref name="key"/>.</param> - /// <returns>If an object was found for the given <paramref name="key"/>.</returns> + /// <returns>If an entry was found for the given <paramref name="key"/>.</returns> public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) { using var variantKey = VariantUtils.CreateFrom(key); @@ -592,14 +762,31 @@ namespace Godot.Collections /// <returns>The number of elements.</returns> public int Count => _underlyingDict.Count; - bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly => false; + /// <summary> + /// Returns <see langword="true"/> if the dictionary is read-only. + /// See <see cref="MakeReadOnly"/>. + /// </summary> + public bool IsReadOnly => _underlyingDict.IsReadOnly; + + /// <summary> + /// Makes the <see cref="Dictionary{TKey, TValue}"/> read-only, i.e. disabled + /// modying of the dictionary's elements. Does not apply to nested content, + /// e.g. content of nested dictionaries. + /// </summary> + public void MakeReadOnly() + { + _underlyingDict.MakeReadOnly(); + } void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item) => Add(item.Key, item.Value); /// <summary> - /// Erases all the items from this <see cref="Dictionary{TKey, TValue}"/>. + /// Clears the dictionary, removing all entries from it. /// </summary> + /// <exception cref="InvalidOperationException"> + /// The dictionary is read-only. + /// </exception> public void Clear() => _underlyingDict.Clear(); bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item) @@ -625,7 +812,7 @@ namespace Godot.Collections /// </summary> /// <param name="array">The array to copy to.</param> /// <param name="arrayIndex">The index to start at.</param> - public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) + void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) { if (array == null) throw new ArgumentNullException(nameof(array), "Value cannot be null."); @@ -649,6 +836,8 @@ namespace Godot.Collections bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item) { + ThrowIfReadOnly(); + using var variantKey = VariantUtils.CreateFrom(item.Key); var self = (godot_dictionary)_underlyingDict.NativeValue; bool found = NativeFuncs.godotsharp_dictionary_try_get_value(ref self, @@ -698,5 +887,13 @@ namespace Godot.Collections [MethodImpl(MethodImplOptions.AggressiveInlining)] public static explicit operator Dictionary<TKey, TValue>(Variant from) => from.AsGodotDictionary<TKey, TValue>(); + + private void ThrowIfReadOnly() + { + if (IsReadOnly) + { + throw new InvalidOperationException("Dictionary instance is read-only."); + } + } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dispatcher.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dispatcher.cs index e6cb4171a7..e7370b2b05 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dispatcher.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dispatcher.cs @@ -9,7 +9,10 @@ namespace Godot internal static GodotTaskScheduler DefaultGodotTaskScheduler; internal static void InitializeDefaultGodotTaskScheduler() - => DefaultGodotTaskScheduler = new GodotTaskScheduler(); + { + DefaultGodotTaskScheduler?.Dispose(); + DefaultGodotTaskScheduler = new GodotTaskScheduler(); + } public static GodotSynchronizationContext SynchronizationContext => DefaultGodotTaskScheduler.Context; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DisposablesTracker.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DisposablesTracker.cs index 421b588560..53292e10cf 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DisposablesTracker.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DisposablesTracker.cs @@ -28,7 +28,7 @@ namespace Godot try { - isStdoutVerbose = OS.IsStdoutVerbose(); + isStdoutVerbose = OS.IsStdOutVerbose(); } catch (ObjectDisposedException) { @@ -43,9 +43,9 @@ namespace Godot // like StringName, NodePath, Godot.Collections.Array/Dictionary, etc. // The Godot Object Dispose() method may need any of the later instances. - foreach (WeakReference<Object> item in GodotObjectInstances.Keys) + foreach (WeakReference<GodotObject> item in GodotObjectInstances.Keys) { - if (item.TryGetTarget(out Object? self)) + if (item.TryGetTarget(out GodotObject? self)) self.Dispose(); } @@ -60,15 +60,15 @@ namespace Godot } // ReSharper disable once RedundantNameQualifier - private static ConcurrentDictionary<WeakReference<Godot.Object>, byte> GodotObjectInstances { get; } = + private static ConcurrentDictionary<WeakReference<GodotObject>, byte> GodotObjectInstances { get; } = new(); private static ConcurrentDictionary<WeakReference<IDisposable>, byte> OtherInstances { get; } = new(); - public static WeakReference<Object> RegisterGodotObject(Object godotObject) + public static WeakReference<GodotObject> RegisterGodotObject(GodotObject godotObject) { - var weakReferenceToSelf = new WeakReference<Object>(godotObject); + var weakReferenceToSelf = new WeakReference<GodotObject>(godotObject); GodotObjectInstances.TryAdd(weakReferenceToSelf, 0); return weakReferenceToSelf; } @@ -80,7 +80,7 @@ namespace Godot return weakReferenceToSelf; } - public static void UnregisterGodotObject(Object godotObject, WeakReference<Object> weakReferenceToSelf) + public static void UnregisterGodotObject(GodotObject godotObject, WeakReference<GodotObject> weakReferenceToSelf) { if (!GodotObjectInstances.TryRemove(weakReferenceToSelf, out _)) throw new ArgumentException("Godot Object not registered.", nameof(weakReferenceToSelf)); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/GodotObjectExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/GodotObjectExtensions.cs new file mode 100644 index 0000000000..6c90c17078 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/GodotObjectExtensions.cs @@ -0,0 +1,86 @@ +using System; +using Godot.NativeInterop; + +namespace Godot +{ + public partial class GodotObject + { + /// <summary> + /// Returns the <see cref="GodotObject"/> that corresponds to <paramref name="instanceId"/>. + /// All Objects have a unique instance ID. See also <see cref="GetInstanceId"/>. + /// </summary> + /// <example> + /// <code> + /// public partial class MyNode : Node + /// { + /// public string Foo { get; set; } = "bar"; + /// + /// public override void _Ready() + /// { + /// ulong id = GetInstanceId(); + /// var inst = (MyNode)InstanceFromId(Id); + /// GD.Print(inst.Foo); // Prints bar + /// } + /// } + /// </code> + /// </example> + /// <param name="instanceId">Instance ID of the Object to retrieve.</param> + /// <returns>The <see cref="GodotObject"/> instance.</returns> + public static GodotObject InstanceFromId(ulong instanceId) + { + return InteropUtils.UnmanagedGetManaged(NativeFuncs.godotsharp_instance_from_id(instanceId)); + } + + /// <summary> + /// Returns <see langword="true"/> if the <see cref="GodotObject"/> that corresponds + /// to <paramref name="id"/> is a valid object (e.g. has not been deleted from + /// memory). All Objects have a unique instance ID. + /// </summary> + /// <param name="id">The Object ID to check.</param> + /// <returns>If the instance with the given ID is a valid object.</returns> + public static bool IsInstanceIdValid(ulong id) + { + return IsInstanceValid(InstanceFromId(id)); + } + + /// <summary> + /// Returns <see langword="true"/> if <paramref name="instance"/> is a + /// valid <see cref="GodotObject"/> (e.g. has not been deleted from memory). + /// </summary> + /// <param name="instance">The instance to check.</param> + /// <returns>If the instance is a valid object.</returns> + public static bool IsInstanceValid(GodotObject instance) + { + return instance != null && instance.NativeInstance != IntPtr.Zero; + } + + /// <summary> + /// Returns a weak reference to an object, or <see langword="null"/> + /// if the argument is invalid. + /// A weak reference to an object is not enough to keep the object alive: + /// when the only remaining references to a referent are weak references, + /// garbage collection is free to destroy the referent and reuse its memory + /// for something else. However, until the object is actually destroyed the + /// weak reference may return the object even if there are no strong references + /// to it. + /// </summary> + /// <param name="obj">The object.</param> + /// <returns> + /// The <see cref="WeakRef"/> reference to the object or <see langword="null"/>. + /// </returns> + public static WeakRef WeakRef(GodotObject obj) + { + if (!IsInstanceValid(obj)) + return null; + + NativeFuncs.godotsharp_weakref(GetPtr(obj), out godot_ref weakRef); + using (weakRef) + { + if (weakRef.IsNull) + return null; + + return (WeakRef)InteropUtils.UnmanagedGetManaged(weakRef.Reference); + } + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs deleted file mode 100644 index 4094ceeb22..0000000000 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using Godot.NativeInterop; - -namespace Godot -{ - public partial class Object - { - /// <summary> - /// Returns whether <paramref name="instance"/> is a valid object - /// (e.g. has not been deleted from memory). - /// </summary> - /// <param name="instance">The instance to check.</param> - /// <returns>If the instance is a valid object.</returns> - public static bool IsInstanceValid(Object instance) - { - return instance != null && instance.NativeInstance != IntPtr.Zero; - } - - /// <summary> - /// Returns a weak reference to an object, or <see langword="null"/> - /// if the argument is invalid. - /// A weak reference to an object is not enough to keep the object alive: - /// when the only remaining references to a referent are weak references, - /// garbage collection is free to destroy the referent and reuse its memory - /// for something else. However, until the object is actually destroyed the - /// weak reference may return the object even if there are no strong references - /// to it. - /// </summary> - /// <param name="obj">The object.</param> - /// <returns> - /// The <see cref="WeakRef"/> reference to the object or <see langword="null"/>. - /// </returns> - public static WeakRef WeakRef(Object obj) - { - if (!IsInstanceValid(obj)) - return null; - - NativeFuncs.godotsharp_weakref(GetPtr(obj), out godot_ref weakRef); - using (weakRef) - { - if (weakRef.IsNull) - return null; - - return (WeakRef)InteropUtils.UnmanagedGetManaged(weakRef.Reference); - } - } - } -} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs index 8463403096..4610761bdb 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs @@ -7,7 +7,7 @@ namespace Godot /// <summary> /// Instantiates the scene's node hierarchy, erroring on failure. /// Triggers child scene instantiation(s). Triggers a - /// <see cref="Node.NotificationInstanced"/> notification on the root node. + /// <see cref="Node.NotificationSceneInstantiated"/> notification on the root node. /// </summary> /// <seealso cref="InstantiateOrNull{T}(GenEditState)"/> /// <exception cref="InvalidCastException"> @@ -23,7 +23,7 @@ namespace Godot /// <summary> /// Instantiates the scene's node hierarchy, returning <see langword="null"/> on failure. /// Triggers child scene instantiation(s). Triggers a - /// <see cref="Node.NotificationInstanced"/> notification on the root node. + /// <see cref="Node.NotificationSceneInstantiated"/> notification on the root node. /// </summary> /// <seealso cref="Instantiate{T}(GenEditState)"/> /// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs index f3f124d5ad..9425b7424c 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Text; using Godot.NativeInterop; namespace Godot @@ -10,36 +11,45 @@ namespace Godot public static partial class GD { /// <summary> - /// Decodes a byte array back to a <c>Variant</c> value. - /// If <paramref name="allowObjects"/> is <see langword="true"/> decoding objects is allowed. - /// - /// WARNING: Deserialized object can contain code which gets executed. - /// Do not set <paramref name="allowObjects"/> to <see langword="true"/> - /// if the serialized object comes from untrusted sources to avoid - /// potential security threats (remote code execution). + /// Decodes a byte array back to a <see cref="Variant"/> value, without decoding objects. + /// Note: If you need object deserialization, see <see cref="BytesToVarWithObjects"/>. /// </summary> - /// <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 Variant BytesToVar(Span<byte> bytes, bool allowObjects = false) + /// <param name="bytes">Byte array that will be decoded to a <see cref="Variant"/>.</param> + /// <returns>The decoded <see cref="Variant"/>.</returns> + public static Variant BytesToVar(Span<byte> bytes) + { + using var varBytes = Marshaling.ConvertSystemArrayToNativePackedByteArray(bytes); + NativeFuncs.godotsharp_bytes_to_var(varBytes, godot_bool.False, out godot_variant ret); + return Variant.CreateTakingOwnershipOfDisposableValue(ret); + } + + /// <summary> + /// Decodes a byte array back to a <see cref="Variant"/> value. Decoding objects is allowed. + /// Warning: Deserialized object can contain code which gets executed. Do not use this + /// option if the serialized object comes from untrusted sources to avoid potential security + /// threats (remote code execution). + /// </summary> + /// <param name="bytes">Byte array that will be decoded to a <see cref="Variant"/>.</param> + /// <returns>The decoded <see cref="Variant"/>.</returns> + public static Variant BytesToVarWithObjects(Span<byte> bytes) { using var varBytes = Marshaling.ConvertSystemArrayToNativePackedByteArray(bytes); - NativeFuncs.godotsharp_bytes_to_var(varBytes, allowObjects.ToGodotBool(), out godot_variant ret); + NativeFuncs.godotsharp_bytes_to_var(varBytes, godot_bool.True, out godot_variant ret); return Variant.CreateTakingOwnershipOfDisposableValue(ret); } /// <summary> - /// Converts from a <c>Variant</c> type to another in the best way possible. + /// Converts <paramref name="what"/> to <paramref name="type"/> in the best way possible. /// The <paramref name="type"/> parameter uses the <see cref="Variant.Type"/> values. /// </summary> /// <example> /// <code> - /// var a = new Vector2(1, 0); - /// // Prints 1 - /// GD.Print(a.Length()); - /// var b = GD.Convert(a, Variant.Type.String) - /// // Prints 6 as "(1, 0)" is 6 characters - /// GD.Print(b.Length); + /// Variant a = new Godot.Collections.Array { 4, 2.5, 1.2 }; + /// GD.Print(a.VariantType == Variant.Type.Array); // Prints true + /// + /// var b = GD.Convert(a, Variant.Type.PackedByteArray); + /// GD.Print(b); // Prints [4, 2, 1] + /// GD.Print(b.VariantType == Variant.Type.Array); // Prints false /// </code> /// </example> /// <returns>The <c>Variant</c> converted to the given <paramref name="type"/>.</returns> @@ -49,18 +59,8 @@ namespace Godot return Variant.CreateTakingOwnershipOfDisposableValue(ret); } - private static string[] GetPrintParams(object[] parameters) - { - if (parameters == null) - { - return new[] { "null" }; - } - - return Array.ConvertAll(parameters, x => x?.ToString() ?? "null"); - } - /// <summary> - /// Returns the integer hash of the variable passed. + /// Returns the integer hash of the passed <paramref name="var"/>. /// </summary> /// <example> /// <code> @@ -75,32 +75,6 @@ namespace Godot } /// <summary> - /// Returns the <see cref="Object"/> that corresponds to <paramref name="instanceId"/>. - /// All Objects have a unique instance ID. - /// </summary> - /// <example> - /// <code> - /// public class MyNode : Node - /// { - /// public string foo = "bar"; - /// - /// public override void _Ready() - /// { - /// ulong id = GetInstanceId(); - /// var inst = (MyNode)GD.InstanceFromId(Id); - /// GD.Print(inst.foo); // Prints bar - /// } - /// } - /// </code> - /// </example> - /// <param name="instanceId">Instance ID of the Object to retrieve.</param> - /// <returns>The <see cref="Object"/> instance.</returns> - public static Object InstanceFromId(ulong instanceId) - { - return InteropUtils.UnmanagedGetManaged(NativeFuncs.godotsharp_instance_from_id(instanceId)); - } - - /// <summary> /// Loads a resource from the filesystem located at <paramref name="path"/>. /// The resource is loaded on the method call (unless it's referenced already /// elsewhere, e.g. in another script or in the scene), which might cause slight delay, @@ -154,57 +128,96 @@ namespace Godot return ResourceLoader.Load<T>(path); } - /// <summary> - /// Pushes an error message to Godot's built-in debugger and to the OS terminal. - /// - /// Note: Errors printed this way will not pause project execution. - /// </summary> - /// <example> - /// <code> - /// GD.PushError("test_error"); // Prints "test error" to debugger and terminal as error call - /// </code> - /// </example> - /// <param name="message">Error message.</param> - public static void PushError(string message) + private static string AppendPrintParams(object[] parameters) { - using var godotStr = Marshaling.ConvertStringToNative(message); - NativeFuncs.godotsharp_pusherror(godotStr); + if (parameters == null) + { + return "null"; + } + + var sb = new StringBuilder(); + for (int i = 0; i < parameters.Length; i++) + { + sb.Append(parameters[i]?.ToString() ?? "null"); + } + return sb.ToString(); + } + + private static string AppendPrintParams(char separator, object[] parameters) + { + if (parameters == null) + { + return "null"; + } + + var sb = new StringBuilder(); + for (int i = 0; i < parameters.Length; i++) + { + if (i != 0) + sb.Append(separator); + sb.Append(parameters[i]?.ToString() ?? "null"); + } + return sb.ToString(); } /// <summary> - /// Pushes a warning message to Godot's built-in debugger and to the OS terminal. + /// Prints a message to the console. + /// + /// Note: Consider using <see cref="PushError(string)"/> and <see cref="PushWarning(string)"/> + /// to print error and warning messages instead of <see cref="Print(string)"/>. + /// This distinguishes them from print messages used for debugging purposes, + /// while also displaying a stack trace when an error or warning is printed. /// </summary> - /// <example> - /// GD.PushWarning("test warning"); // Prints "test warning" to debugger and terminal as warning call - /// </example> - /// <param name="message">Warning message.</param> - public static void PushWarning(string message) + /// <param name="what">Message that will be printed.</param> + public static void Print(string what) { - using var godotStr = Marshaling.ConvertStringToNative(message); - NativeFuncs.godotsharp_pushwarning(godotStr); + using var godotStr = Marshaling.ConvertStringToNative(what); + NativeFuncs.godotsharp_print(godotStr); } /// <summary> /// Converts one or more arguments of any type to string in the best way possible /// and prints them to the console. /// - /// Note: Consider using <see cref="PushError(string)"/> and <see cref="PushWarning(string)"/> + /// Note: Consider using <see cref="PushError(object[])"/> and <see cref="PushWarning(object[])"/> /// to print error and warning messages instead of <see cref="Print(object[])"/>. /// This distinguishes them from print messages used for debugging purposes, /// while also displaying a stack trace when an error or warning is printed. /// </summary> /// <example> /// <code> - /// var a = new int[] { 1, 2, 3 }; + /// var a = new Godot.Collections.Array { 1, 2, 3 }; /// GD.Print("a", "b", a); // Prints ab[1, 2, 3] /// </code> /// </example> /// <param name="what">Arguments that will be printed.</param> public static void Print(params object[] what) { - string str = string.Concat(GetPrintParams(what)); - using var godotStr = Marshaling.ConvertStringToNative(str); - NativeFuncs.godotsharp_print(godotStr); + Print(AppendPrintParams(what)); + } + + /// <summary> + /// Prints a message to the console. + /// The following BBCode tags are supported: b, i, u, s, indent, code, url, center, + /// right, color, bgcolor, fgcolor. + /// Color tags only support named colors such as <c>red</c>, not hexadecimal color codes. + /// Unsupported tags will be left as-is in standard output. + /// When printing to standard output, the supported subset of BBCode is converted to + /// ANSI escape codes for the terminal emulator to display. Displaying ANSI escape codes + /// is currently only supported on Linux and macOS. Support for ANSI escape codes may vary + /// across terminal emulators, especially for italic and strikethrough. + /// + /// Note: Consider using <see cref="PushError(string)"/> and <see cref="PushWarning(string)"/> + /// to print error and warning messages instead of <see cref="Print(string)"/> or + /// <see cref="PrintRich(string)"/>. + /// This distinguishes them from print messages used for debugging purposes, + /// while also displaying a stack trace when an error or warning is printed. + /// </summary> + /// <param name="what">Message that will be printed.</param> + public static void PrintRich(string what) + { + using var godotStr = Marshaling.ConvertStringToNative(what); + NativeFuncs.godotsharp_print_rich(godotStr); } /// <summary> @@ -219,7 +232,7 @@ namespace Godot /// is currently only supported on Linux and macOS. Support for ANSI escape codes may vary /// across terminal emulators, especially for italic and strikethrough. /// - /// Note: Consider using <see cref="PushError(string)"/> and <see cref="PushWarning(string)"/> + /// Note: Consider using <see cref="PushError(object[])"/> and <see cref="PushWarning(object[])"/> /// to print error and warning messages instead of <see cref="Print(object[])"/> or /// <see cref="PrintRich(object[])"/>. /// This distinguishes them from print messages used for debugging purposes, @@ -227,23 +240,23 @@ namespace Godot /// </summary> /// <example> /// <code> - /// GD.PrintRich("[b]Hello world![/b]"); // Prints out "Hello world!" in bold. + /// GD.PrintRich("[code][b]Hello world![/b][/code]"); // Prints out: [b]Hello world![/b] /// </code> /// </example> /// <param name="what">Arguments that will be printed.</param> public static void PrintRich(params object[] what) { - string str = string.Concat(GetPrintParams(what)); - using var godotStr = Marshaling.ConvertStringToNative(str); - NativeFuncs.godotsharp_print_rich(godotStr); + PrintRich(AppendPrintParams(what)); } /// <summary> - /// Prints the current stack trace information to the console. + /// Prints a message to standard error line. /// </summary> - public static void PrintStack() + /// <param name="what">Message that will be printed.</param> + public static void PrintErr(string what) { - Print(System.Environment.StackTrace); + using var godotStr = Marshaling.ConvertStringToNative(what); + NativeFuncs.godotsharp_printerr(godotStr); } /// <summary> @@ -257,31 +270,36 @@ namespace Godot /// <param name="what">Arguments that will be printed.</param> public static void PrintErr(params object[] what) { - string str = string.Concat(GetPrintParams(what)); - using var godotStr = Marshaling.ConvertStringToNative(str); - NativeFuncs.godotsharp_printerr(godotStr); + PrintErr(AppendPrintParams(what)); } /// <summary> - /// Prints one or more arguments to strings in the best way possible to console. - /// No newline is added at the end. - /// - /// Note: Due to limitations with Godot's built-in console, this only prints to the terminal. - /// If you need to print in the editor, use another method, such as <see cref="Print(object[])"/>. + /// Prints a message to the OS terminal. + /// Unlike <see cref="Print(string)"/>, no newline is added at the end. + /// </summary> + /// <param name="what">Message that will be printed.</param> + public static void PrintRaw(string what) + { + using var godotStr = Marshaling.ConvertStringToNative(what); + NativeFuncs.godotsharp_printraw(godotStr); + } + + /// <summary> + /// Prints one or more arguments to strings in the best way possible to the OS terminal. + /// Unlike <see cref="Print(object[])"/>, no newline is added at the end. /// </summary> /// <example> /// <code> /// GD.PrintRaw("A"); /// GD.PrintRaw("B"); - /// // Prints AB + /// GD.PrintRaw("C"); + /// // Prints ABC to terminal /// </code> /// </example> /// <param name="what">Arguments that will be printed.</param> public static void PrintRaw(params object[] what) { - string str = string.Concat(GetPrintParams(what)); - using var godotStr = Marshaling.ConvertStringToNative(str); - NativeFuncs.godotsharp_printraw(godotStr); + PrintRaw(AppendPrintParams(what)); } /// <summary> @@ -295,8 +313,8 @@ namespace Godot /// <param name="what">Arguments that will be printed.</param> public static void PrintS(params object[] what) { - string str = string.Join(' ', GetPrintParams(what)); - using var godotStr = Marshaling.ConvertStringToNative(str); + string message = AppendPrintParams(' ', what); + using var godotStr = Marshaling.ConvertStringToNative(message); NativeFuncs.godotsharp_prints(godotStr); } @@ -311,12 +329,74 @@ namespace Godot /// <param name="what">Arguments that will be printed.</param> public static void PrintT(params object[] what) { - string str = string.Join('\t', GetPrintParams(what)); - using var godotStr = Marshaling.ConvertStringToNative(str); + string message = AppendPrintParams('\t', what); + using var godotStr = Marshaling.ConvertStringToNative(message); NativeFuncs.godotsharp_printt(godotStr); } /// <summary> + /// Pushes an error message to Godot's built-in debugger and to the OS terminal. + /// + /// Note: Errors printed this way will not pause project execution. + /// </summary> + /// <example> + /// <code> + /// GD.PushError("test error"); // Prints "test error" to debugger and terminal as error call + /// </code> + /// </example> + /// <param name="message">Error message.</param> + public static void PushError(string message) + { + using var godotStr = Marshaling.ConvertStringToNative(message); + NativeFuncs.godotsharp_pusherror(godotStr); + } + + /// <summary> + /// Pushes an error message to Godot's built-in debugger and to the OS terminal. + /// + /// Note: Errors printed this way will not pause project execution. + /// </summary> + /// <example> + /// <code> + /// GD.PushError("test_error"); // Prints "test error" to debugger and terminal as error call + /// </code> + /// </example> + /// <param name="what">Arguments that form the error message.</param> + public static void PushError(params object[] what) + { + PushError(AppendPrintParams(what)); + } + + /// <summary> + /// Pushes a warning message to Godot's built-in debugger and to the OS terminal. + /// </summary> + /// <example> + /// <code> + /// GD.PushWarning("test warning"); // Prints "test warning" to debugger and terminal as warning call + /// </code> + /// </example> + /// <param name="message">Warning message.</param> + public static void PushWarning(string message) + { + using var godotStr = Marshaling.ConvertStringToNative(message); + NativeFuncs.godotsharp_pushwarning(godotStr); + } + + /// <summary> + /// Pushes a warning message to Godot's built-in debugger and to the OS terminal. + /// </summary> + /// <example> + /// <code> + /// GD.PushWarning("test warning"); // Prints "test warning" to debugger and terminal as warning call + /// </code> + /// </example> + /// <param name="what">Arguments that form the warning message.</param> + public static void PushWarning(params object[] what) + { + PushWarning(AppendPrintParams(what)); + } + + /// <summary> /// Returns a random floating point value between <c>0.0</c> and <c>1.0</c> (inclusive). /// </summary> /// <example> @@ -331,7 +411,9 @@ namespace Godot } /// <summary> - /// Returns a normally-distributed pseudo-random number, using Box-Muller transform with the specified <c>mean</c> and a standard <c>deviation</c>. + /// Returns a normally-distributed pseudo-random floating point value + /// using Box-Muller transform with the specified <pararmref name="mean"/> + /// and a standard <paramref name="deviation"/>. /// This is also called Gaussian distribution. /// </summary> /// <returns>A random normally-distributed <see langword="float"/> number.</returns> @@ -342,7 +424,8 @@ namespace Godot /// <summary> /// Returns a random unsigned 32-bit integer. - /// Use remainder to obtain a random value in the interval <c>[0, N - 1]</c> (where N is smaller than 2^32). + /// Use remainder to obtain a random value in the interval <c>[0, N - 1]</c> + /// (where N is smaller than 2^32). /// </summary> /// <example> /// <code> @@ -360,11 +443,11 @@ namespace Godot /// <summary> /// Randomizes the seed (or the internal state) of the random number generator. - /// Current implementation reseeds using a number based on time. + /// The current implementation uses a number based on the device's time. /// /// Note: This method is called automatically when the project is run. - /// If you need to fix the seed to have reproducible results, use <see cref="Seed(ulong)"/> - /// to initialize the random number generator. + /// If you need to fix the seed to have consistent, reproducible results, + /// use <see cref="Seed(ulong)"/> to initialize the random number generator. /// </summary> public static void Randomize() { @@ -372,12 +455,13 @@ namespace Godot } /// <summary> - /// Returns a random floating point value on the interval between <paramref name="from"/> + /// Returns a random floating point value between <paramref name="from"/> /// and <paramref name="to"/> (inclusive). /// </summary> /// <example> /// <code> - /// GD.PrintS(GD.RandRange(-10.0, 10.0), GD.RandRange(-10.0, 10.0)); // Prints e.g. -3.844535 7.45315 + /// GD.RandRange(0.0, 20.5); // Returns e.g. 7.45315 + /// GD.RandRange(-10.0, 10.0); // Returns e.g. -3.844535 /// </code> /// </example> /// <returns>A random <see langword="double"/> number inside the given range.</returns> @@ -393,8 +477,8 @@ namespace Godot /// </summary> /// <example> /// <code> - /// GD.Print(GD.RandRange(0, 1)); // Prints 0 or 1 - /// GD.Print(GD.RandRange(-10, 1000)); // Prints any number from -10 to 1000 + /// GD.RandRange(0, 1); // Returns either 0 or 1 + /// GD.RandRange(-10, 1000); // Returns random integer between -10 and 1000 /// </code> /// </example> /// <returns>A random <see langword="int"/> number inside the given range.</returns> @@ -404,8 +488,18 @@ namespace Godot } /// <summary> - /// Returns a random unsigned 32-bit integer, using the given <paramref name="seed"/>. + /// Given a <paramref name="seed"/>, returns a randomized <see langword="uint"/> + /// value. The <paramref name="seed"/> may be modified. + /// Passing the same <paramref name="seed"/> consistently returns the same value. + /// + /// Note: "Seed" here refers to the internal state of the pseudo random number + /// generator, currently implemented as a 64 bit integer. /// </summary> + /// <example> + /// <code> + /// var a = GD.RandFromSeed(4); + /// </code> + /// </example> /// <param name="seed"> /// Seed to use to generate the random number. /// If a different seed is used, its value will be modified. @@ -418,7 +512,8 @@ namespace Godot /// <summary> /// Returns a <see cref="IEnumerable{T}"/> that iterates from - /// <c>0</c> to <paramref name="end"/> in steps of <c>1</c>. + /// <c>0</c> (inclusive) to <paramref name="end"/> (exclusive) + /// in steps of <c>1</c>. /// </summary> /// <param name="end">The last index.</param> public static IEnumerable<int> Range(int end) @@ -428,7 +523,8 @@ namespace Godot /// <summary> /// Returns a <see cref="IEnumerable{T}"/> that iterates from - /// <paramref name="start"/> to <paramref name="end"/> in steps of <c>1</c>. + /// <paramref name="start"/> (inclusive) to <paramref name="end"/> (exclusive) + /// in steps of <c>1</c>. /// </summary> /// <param name="start">The first index.</param> /// <param name="end">The last index.</param> @@ -439,13 +535,21 @@ namespace Godot /// <summary> /// Returns a <see cref="IEnumerable{T}"/> that iterates from - /// <paramref name="start"/> to <paramref name="end"/> in steps of <paramref name="step"/>. + /// <paramref name="start"/> (inclusive) to <paramref name="end"/> (exclusive) + /// in steps of <paramref name="step"/>. + /// The argument <paramref name="step"/> can be negative, but not <c>0</c>. /// </summary> + /// <exception cref="ArgumentException"> + /// <paramref name="step"/> is 0. + /// </exception> /// <param name="start">The first index.</param> /// <param name="end">The last index.</param> /// <param name="step">The amount by which to increment the index on each iteration.</param> public static IEnumerable<int> Range(int start, int end, int step) { + if (step == 0) + throw new ArgumentException("step cannot be 0.", nameof(step)); + if (end < start && step > 0) yield break; @@ -465,8 +569,20 @@ namespace Godot } /// <summary> - /// Sets seed for the random number generator. + /// Sets seed for the random number generator to <paramref name="seed"/>. + /// Setting the seed manually can ensure consistent, repeatable results for + /// most random functions. /// </summary> + /// <example> + /// <code> + /// ulong mySeed = (ulong)GD.Hash("Godot Rocks"); + /// GD.Seed(mySeed); + /// var a = GD.Randf() + GD.Randi(); + /// GD.Seed(mySeed); + /// var b = GD.Randf() + GD.Randi(); + /// // a and b are now identical + /// </code> + /// </example> /// <param name="seed">Seed that will be used.</param> public static void Seed(ulong seed) { @@ -474,26 +590,14 @@ namespace Godot } /// <summary> - /// Converts one or more arguments of any type to string in the best way possible. - /// </summary> - /// <param name="what">Arguments that will converted to string.</param> - /// <returns>The string formed by the given arguments.</returns> - public static string Str(params Variant[] what) - { - using var whatGodot = new Godot.Collections.Array(what); - NativeFuncs.godotsharp_str((godot_array)whatGodot.NativeValue, out godot_string ret); - using (ret) - return Marshaling.ConvertStringToManaged(ret); - } - - /// <summary> - /// Converts a formatted string that was returned by <see cref="VarToStr(Variant)"/> to the original value. + /// Converts a formatted string that was returned by <see cref="VarToStr(Variant)"/> + /// to the original value. /// </summary> /// <example> /// <code> - /// string a = "{\"a\": 1, \"b\": 2 }"; - /// var b = (Godot.Collections.Dictionary)GD.StrToVar(a); - /// GD.Print(b["a"]); // Prints 1 + /// string a = "{ \"a\": 1, \"b\": 2 }"; // a is a string + /// var b = GD.StrToVar(a).AsGodotDictionary(); // b is a Dictionary + /// GD.Print(b["a"]); // Prints 1 /// </code> /// </example> /// <param name="str">String that will be converted to Variant.</param> @@ -506,38 +610,49 @@ namespace Godot } /// <summary> - /// Encodes a <c>Variant</c> value to a byte array. - /// If <paramref name="fullObjects"/> is <see langword="true"/> encoding objects is allowed - /// (and can potentially include code). - /// Deserialization can be done with <see cref="BytesToVar(Span{byte}, bool)"/>. + /// Encodes a <see cref="Variant"/> value to a byte array, without encoding objects. + /// Deserialization can be done with <see cref="BytesToVar"/>. + /// Note: If you need object serialization, see <see cref="VarToBytesWithObjects"/>. + /// </summary> + /// <param name="var"><see cref="Variant"/> that will be encoded.</param> + /// <returns>The <see cref="Variant"/> encoded as an array of bytes.</returns> + public static byte[] VarToBytes(Variant var) + { + NativeFuncs.godotsharp_var_to_bytes((godot_variant)var.NativeVar, godot_bool.False, out var varBytes); + using (varBytes) + return Marshaling.ConvertNativePackedByteArrayToSystemArray(varBytes); + } + + /// <summary> + /// Encodes a <see cref="Variant"/>. Encoding objects is allowed (and can potentially + /// include executable code). Deserialization can be done with <see cref="BytesToVarWithObjects"/>. /// </summary> - /// <param name="var">Variant that will be encoded.</param> - /// <param name="fullObjects">If objects should be serialized.</param> - /// <returns>The <c>Variant</c> encoded as an array of bytes.</returns> - public static byte[] VarToBytes(Variant var, bool fullObjects = false) + /// <param name="var"><see cref="Variant"/> that will be encoded.</param> + /// <returns>The <see cref="Variant"/> encoded as an array of bytes.</returns> + public static byte[] VarToBytesWithObjects(Variant var) { - NativeFuncs.godotsharp_var_to_bytes((godot_variant)var.NativeVar, fullObjects.ToGodotBool(), out var varBytes); + NativeFuncs.godotsharp_var_to_bytes((godot_variant)var.NativeVar, godot_bool.True, out var varBytes); using (varBytes) return Marshaling.ConvertNativePackedByteArrayToSystemArray(varBytes); } /// <summary> - /// Converts a <c>Variant</c> <paramref name="var"/> to a formatted string that + /// Converts a <see cref="Variant"/> <paramref name="var"/> to a formatted string that /// can later be parsed using <see cref="StrToVar(string)"/>. /// </summary> /// <example> /// <code> /// var a = new Godot.Collections.Dictionary { ["a"] = 1, ["b"] = 2 }; /// GD.Print(GD.VarToStr(a)); - /// // Prints + /// // Prints: /// // { - /// // "a": 1, - /// // "b": 2 + /// // "a": 1, + /// // "b": 2 /// // } /// </code> /// </example> /// <param name="var">Variant that will be converted to string.</param> - /// <returns>The <c>Variant</c> encoded as a string.</returns> + /// <returns>The <see cref="Variant"/> encoded as a string.</returns> public static string VarToStr(Variant var) { NativeFuncs.godotsharp_var_to_str((godot_variant)var.NativeVar, out godot_string ret); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.base.cs index 60ee6eb6f4..b9a5ac82d1 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.base.cs @@ -5,20 +5,20 @@ using Godot.NativeInterop; namespace Godot { - public partial class Object : IDisposable + public partial class GodotObject : IDisposable { private bool _disposed = false; - private static readonly Type CachedType = typeof(Object); + private static readonly Type CachedType = typeof(GodotObject); internal IntPtr NativePtr; private bool _memoryOwn; - private WeakReference<Object> _weakReferenceToSelf; + private WeakReference<GodotObject> _weakReferenceToSelf; /// <summary> - /// Constructs a new <see cref="Object"/>. + /// Constructs a new <see cref="GodotObject"/>. /// </summary> - public Object() : this(false) + public GodotObject() : this(false) { unsafe { @@ -49,17 +49,17 @@ namespace Godot _weakReferenceToSelf = DisposablesTracker.RegisterGodotObject(this); } - internal Object(bool memoryOwn) + internal GodotObject(bool memoryOwn) { _memoryOwn = memoryOwn; } /// <summary> - /// The pointer to the native instance of this <see cref="Object"/>. + /// The pointer to the native instance of this <see cref="GodotObject"/>. /// </summary> public IntPtr NativeInstance => NativePtr; - internal static IntPtr GetPtr(Object instance) + internal static IntPtr GetPtr(GodotObject instance) { if (instance == null) return IntPtr.Zero; @@ -75,13 +75,13 @@ namespace Godot return instance.NativePtr; } - ~Object() + ~GodotObject() { Dispose(false); } /// <summary> - /// Disposes of this <see cref="Object"/>. + /// Disposes of this <see cref="GodotObject"/>. /// </summary> public void Dispose() { @@ -90,7 +90,7 @@ namespace Godot } /// <summary> - /// Disposes implementation of this <see cref="Object"/>. + /// Disposes implementation of this <see cref="GodotObject"/>. /// </summary> protected virtual void Dispose(bool disposing) { @@ -129,7 +129,7 @@ namespace Godot } /// <summary> - /// Converts this <see cref="Object"/> to a string. + /// Converts this <see cref="GodotObject"/> to a string. /// </summary> /// <returns>A string representation of this object.</returns> public override string ToString() @@ -166,7 +166,7 @@ namespace Godot /// A <see cref="SignalAwaiter"/> that completes when /// <paramref name="source"/> emits the <paramref name="signal"/>. /// </returns> - public SignalAwaiter ToSignal(Object source, StringName signal) + public SignalAwaiter ToSignal(GodotObject source, StringName signal) { return new SignalAwaiter(source, signal, this); } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.exceptions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.exceptions.cs index 0fcc4ee01b..a7640043ce 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.exceptions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.exceptions.cs @@ -5,7 +5,7 @@ using System.Text; namespace Godot { - public partial class Object + public partial class GodotObject { public class NativeMemberNotFoundException : Exception { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs index 1b599beab5..027eab30fc 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs @@ -1,13 +1,13 @@ +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading; namespace Godot { - public class GodotSynchronizationContext : SynchronizationContext + public sealed class GodotSynchronizationContext : SynchronizationContext, IDisposable { - private readonly BlockingCollection<KeyValuePair<SendOrPostCallback, object>> _queue = - new BlockingCollection<KeyValuePair<SendOrPostCallback, object>>(); + private readonly BlockingCollection<KeyValuePair<SendOrPostCallback, object>> _queue = new(); public override void Post(SendOrPostCallback d, object state) { @@ -24,5 +24,10 @@ namespace Godot workItem.Key(workItem.Value); } } + + public void Dispose() + { + _queue.Dispose(); + } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTaskScheduler.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTaskScheduler.cs index 408bed71b2..f6c36455b2 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTaskScheduler.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTaskScheduler.cs @@ -10,7 +10,7 @@ namespace Godot /// GodotTaskScheduler contains a linked list of tasks to perform as a queue. Methods /// within the class are used to control the queue and perform the contained tasks. /// </summary> - public class GodotTaskScheduler : TaskScheduler + public sealed class GodotTaskScheduler : TaskScheduler, IDisposable { /// <summary> /// The current synchronization context. @@ -108,5 +108,10 @@ namespace Godot } } } + + public void Dispose() + { + Context.Dispose(); + } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs index 137a42a6de..ca0032df73 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; namespace Godot { @@ -35,15 +36,18 @@ namespace Godot public const real_t NaN = real_t.NaN; // 0.0174532924f and 0.0174532925199433 - private const real_t _degToRadConst = (real_t)0.0174532925199432957692369077M; + private const float _degToRadConstF = (float)0.0174532925199432957692369077M; + private const double _degToRadConstD = (double)0.0174532925199432957692369077M; // 57.29578f and 57.2957795130823 - private const real_t _radToDegConst = (real_t)57.295779513082320876798154814M; + private const float _radToDegConstF = (float)57.295779513082320876798154814M; + private const double _radToDegConstD = (double)57.295779513082320876798154814M; /// <summary> /// Returns the absolute value of <paramref name="s"/> (i.e. positive value). /// </summary> /// <param name="s">The input number.</param> /// <returns>The absolute value of <paramref name="s"/>.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Abs(int s) { return Math.Abs(s); @@ -54,7 +58,19 @@ namespace Godot /// </summary> /// <param name="s">The input number.</param> /// <returns>The absolute value of <paramref name="s"/>.</returns> - public static real_t Abs(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Abs(float s) + { + return Math.Abs(s); + } + + /// <summary> + /// Returns the absolute value of <paramref name="s"/> (i.e. positive value). + /// </summary> + /// <param name="s">The input number.</param> + /// <returns>The absolute value of <paramref name="s"/>.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Abs(double s) { return Math.Abs(s); } @@ -67,9 +83,38 @@ namespace Godot /// <returns> /// An angle that would result in the given cosine value. On the range <c>0</c> to <c>Tau/2</c>. /// </returns> - public static real_t Acos(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Acos(float s) { - return (real_t)Math.Acos(s); + return MathF.Acos(s); + } + + /// <summary> + /// Returns the arc cosine of <paramref name="s"/> in radians. + /// Use to get the angle of cosine <paramref name="s"/>. + /// </summary> + /// <param name="s">The input cosine value. Must be on the range of -1.0 to 1.0.</param> + /// <returns> + /// An angle that would result in the given cosine value. On the range <c>0</c> to <c>Tau/2</c>. + /// </returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Acos(double s) + { + return Math.Acos(s); + } + + /// <summary> + /// Returns the arc sine of <paramref name="s"/> in radians. + /// Use to get the angle of sine <paramref name="s"/>. + /// </summary> + /// <param name="s">The input sine value. Must be on the range of -1.0 to 1.0.</param> + /// <returns> + /// An angle that would result in the given sine value. On the range <c>-Tau/4</c> to <c>Tau/4</c>. + /// </returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Asin(float s) + { + return MathF.Asin(s); } /// <summary> @@ -80,9 +125,10 @@ namespace Godot /// <returns> /// An angle that would result in the given sine value. On the range <c>-Tau/4</c> to <c>Tau/4</c>. /// </returns> - public static real_t Asin(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Asin(double s) { - return (real_t)Math.Asin(s); + return Math.Asin(s); } /// <summary> @@ -90,15 +136,51 @@ namespace Godot /// Use to get the angle of tangent <paramref name="s"/>. /// /// The method cannot know in which quadrant the angle should fall. - /// See <see cref="Atan2(real_t, real_t)"/> if you have both <c>y</c> and <c>x</c>. + /// See <see cref="Atan2(float, float)"/> if you have both <c>y</c> and <c>x</c>. /// </summary> /// <param name="s">The input tangent value.</param> /// <returns> /// An angle that would result in the given tangent value. On the range <c>-Tau/4</c> to <c>Tau/4</c>. /// </returns> - public static real_t Atan(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Atan(float s) { - return (real_t)Math.Atan(s); + return MathF.Atan(s); + } + + /// <summary> + /// Returns the arc tangent of <paramref name="s"/> in radians. + /// Use to get the angle of tangent <paramref name="s"/>. + /// + /// The method cannot know in which quadrant the angle should fall. + /// See <see cref="Atan2(double, double)"/> if you have both <c>y</c> and <c>x</c>. + /// </summary> + /// <param name="s">The input tangent value.</param> + /// <returns> + /// An angle that would result in the given tangent value. On the range <c>-Tau/4</c> to <c>Tau/4</c>. + /// </returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Atan(double s) + { + return Math.Atan(s); + } + + /// <summary> + /// Returns the arc tangent of <paramref name="y"/> and <paramref name="x"/> in radians. + /// Use to get the angle of the tangent of <c>y/x</c>. To compute the value, the method takes into + /// account the sign of both arguments in order to determine the quadrant. + /// + /// Important note: The Y coordinate comes first, by convention. + /// </summary> + /// <param name="y">The Y coordinate of the point to find the angle to.</param> + /// <param name="x">The X coordinate of the point to find the angle to.</param> + /// <returns> + /// An angle that would result in the given tangent value. On the range <c>-Tau/2</c> to <c>Tau/2</c>. + /// </returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Atan2(float y, float x) + { + return MathF.Atan2(y, x); } /// <summary> @@ -113,9 +195,21 @@ namespace Godot /// <returns> /// An angle that would result in the given tangent value. On the range <c>-Tau/2</c> to <c>Tau/2</c>. /// </returns> - public static real_t Atan2(real_t y, real_t x) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Atan2(double y, double x) + { + return Math.Atan2(y, x); + } + + /// <summary> + /// Rounds <paramref name="s"/> upward (towards positive infinity). + /// </summary> + /// <param name="s">The number to ceil.</param> + /// <returns>The smallest whole number that is not less than <paramref name="s"/>.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Ceil(float s) { - return (real_t)Math.Atan2(y, x); + return MathF.Ceiling(s); } /// <summary> @@ -123,9 +217,10 @@ namespace Godot /// </summary> /// <param name="s">The number to ceil.</param> /// <returns>The smallest whole number that is not less than <paramref name="s"/>.</returns> - public static real_t Ceil(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Ceil(double s) { - return (real_t)Math.Ceiling(s); + return Math.Ceiling(s); } /// <summary> @@ -136,9 +231,24 @@ namespace Godot /// <param name="min">The minimum allowed value.</param> /// <param name="max">The maximum allowed value.</param> /// <returns>The clamped value.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Clamp(int value, int min, int max) { - return value < min ? min : value > max ? max : value; + return Math.Clamp(value, min, max); + } + + /// <summary> + /// Clamps a <paramref name="value"/> so that it is not less than <paramref name="min"/> + /// and not more than <paramref name="max"/>. + /// </summary> + /// <param name="value">The value to clamp.</param> + /// <param name="min">The minimum allowed value.</param> + /// <param name="max">The maximum allowed value.</param> + /// <returns>The clamped value.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Clamp(float value, float min, float max) + { + return Math.Clamp(value, min, max); } /// <summary> @@ -149,9 +259,10 @@ namespace Godot /// <param name="min">The minimum allowed value.</param> /// <param name="max">The maximum allowed value.</param> /// <returns>The clamped value.</returns> - public static real_t Clamp(real_t value, real_t min, real_t max) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Clamp(double value, double min, double max) { - return value < min ? min : value > max ? max : value; + return Math.Clamp(value, min, max); } /// <summary> @@ -159,9 +270,21 @@ namespace Godot /// </summary> /// <param name="s">The angle in radians.</param> /// <returns>The cosine of that angle.</returns> - public static real_t Cos(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Cos(float s) { - return (real_t)Math.Cos(s); + return MathF.Cos(s); + } + + /// <summary> + /// Returns the cosine of angle <paramref name="s"/> in radians. + /// </summary> + /// <param name="s">The angle in radians.</param> + /// <returns>The cosine of that angle.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Cos(double s) + { + return Math.Cos(s); } /// <summary> @@ -169,9 +292,21 @@ namespace Godot /// </summary> /// <param name="s">The angle in radians.</param> /// <returns>The hyperbolic cosine of that angle.</returns> - public static real_t Cosh(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Cosh(float s) { - return (real_t)Math.Cosh(s); + return MathF.Cosh(s); + } + + /// <summary> + /// Returns the hyperbolic cosine of angle <paramref name="s"/> in radians. + /// </summary> + /// <param name="s">The angle in radians.</param> + /// <returns>The hyperbolic cosine of that angle.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Cosh(double s) + { + return Math.Cosh(s); } /// <summary> @@ -184,7 +319,7 @@ namespace Godot /// <param name="post">The value which after "to" value for interpolation.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> /// <returns>The resulting value of the interpolation.</returns> - public static real_t CubicInterpolate(real_t from, real_t to, real_t pre, real_t post, real_t weight) + public static float CubicInterpolate(float from, float to, float pre, float post, float weight) { return 0.5f * ((from * 2.0f) + @@ -194,9 +329,28 @@ namespace Godot } /// <summary> + /// Cubic interpolates between two values by the factor defined in <paramref name="weight"/> + /// with pre and post values. + /// </summary> + /// <param name="from">The start value for interpolation.</param> + /// <param name="to">The destination value for interpolation.</param> + /// <param name="pre">The value which before "from" value for interpolation.</param> + /// <param name="post">The value which after "to" value for interpolation.</param> + /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> + /// <returns>The resulting value of the interpolation.</returns> + public static double CubicInterpolate(double from, double to, double pre, double post, double weight) + { + return 0.5 * + ((from * 2.0) + + (-pre + to) * weight + + (2.0 * pre - 5.0 * from + 4.0 * to - post) * (weight * weight) + + (-pre + 3.0 * from - 3.0 * to + post) * (weight * weight * weight)); + } + + /// <summary> /// Cubic interpolates between two rotation values with shortest path /// by the factor defined in <paramref name="weight"/> with pre and post values. - /// See also <see cref="LerpAngle"/>. + /// See also <see cref="LerpAngle(float, float, float)"/>. /// </summary> /// <param name="from">The start value for interpolation.</param> /// <param name="to">The destination value for interpolation.</param> @@ -204,18 +358,45 @@ namespace Godot /// <param name="post">The value which after "to" value for interpolation.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> /// <returns>The resulting value of the interpolation.</returns> - public static real_t CubicInterpolateAngle(real_t from, real_t to, real_t pre, real_t post, real_t weight) + public static float CubicInterpolateAngle(float from, float to, float pre, float post, float weight) { - real_t fromRot = from % Mathf.Tau; + float fromRot = from % MathF.Tau; - real_t preDiff = (pre - fromRot) % Mathf.Tau; - real_t preRot = fromRot + (2.0f * preDiff) % Mathf.Tau - preDiff; + float preDiff = (pre - fromRot) % MathF.Tau; + float preRot = fromRot + (2.0f * preDiff) % MathF.Tau - preDiff; - real_t toDiff = (to - fromRot) % Mathf.Tau; - real_t toRot = fromRot + (2.0f * toDiff) % Mathf.Tau - toDiff; + float toDiff = (to - fromRot) % MathF.Tau; + float toRot = fromRot + (2.0f * toDiff) % MathF.Tau - toDiff; - real_t postDiff = (post - toRot) % Mathf.Tau; - real_t postRot = toRot + (2.0f * postDiff) % Mathf.Tau - postDiff; + float postDiff = (post - toRot) % MathF.Tau; + float postRot = toRot + (2.0f * postDiff) % MathF.Tau - postDiff; + + return CubicInterpolate(fromRot, toRot, preRot, postRot, weight); + } + + /// <summary> + /// Cubic interpolates between two rotation values with shortest path + /// by the factor defined in <paramref name="weight"/> with pre and post values. + /// See also <see cref="LerpAngle(double, double, double)"/>. + /// </summary> + /// <param name="from">The start value for interpolation.</param> + /// <param name="to">The destination value for interpolation.</param> + /// <param name="pre">The value which before "from" value for interpolation.</param> + /// <param name="post">The value which after "to" value for interpolation.</param> + /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> + /// <returns>The resulting value of the interpolation.</returns> + public static double CubicInterpolateAngle(double from, double to, double pre, double post, double weight) + { + double fromRot = from % Math.Tau; + + double preDiff = (pre - fromRot) % Math.Tau; + double preRot = fromRot + (2.0 * preDiff) % Math.Tau - preDiff; + + double toDiff = (to - fromRot) % Math.Tau; + double toRot = fromRot + (2.0 * toDiff) % Math.Tau - toDiff; + + double postDiff = (post - toRot) % Math.Tau; + double postRot = toRot + (2.0 * postDiff) % Math.Tau - postDiff; return CubicInterpolate(fromRot, toRot, preRot, postRot, weight); } @@ -223,7 +404,8 @@ namespace Godot /// <summary> /// Cubic interpolates between two values by the factor defined in <paramref name="weight"/> /// with pre and post values. - /// It can perform smoother interpolation than <see cref="CubicInterpolate"/> + /// It can perform smoother interpolation than + /// <see cref="CubicInterpolate(float, float, float, float, float)"/> /// by the time values. /// </summary> /// <param name="from">The start value for interpolation.</param> @@ -235,23 +417,52 @@ namespace Godot /// <param name="preT"></param> /// <param name="postT"></param> /// <returns>The resulting value of the interpolation.</returns> - public static real_t CubicInterpolateInTime(real_t from, real_t to, real_t pre, real_t post, real_t weight, real_t toT, real_t preT, real_t postT) + public static float CubicInterpolateInTime(float from, float to, float pre, float post, float weight, float toT, float preT, float postT) { /* Barry-Goldman method */ - real_t t = Lerp(0.0f, toT, weight); - real_t a1 = Lerp(pre, from, preT == 0 ? 0.0f : (t - preT) / -preT); - real_t a2 = Lerp(from, to, toT == 0 ? 0.5f : t / toT); - real_t a3 = Lerp(to, post, postT - toT == 0 ? 1.0f : (t - toT) / (postT - toT)); - real_t b1 = Lerp(a1, a2, toT - preT == 0 ? 0.0f : (t - preT) / (toT - preT)); - real_t b2 = Lerp(a2, a3, postT == 0 ? 1.0f : t / postT); + float t = Lerp(0.0f, toT, weight); + float a1 = Lerp(pre, from, preT == 0 ? 0.0f : (t - preT) / -preT); + float a2 = Lerp(from, to, toT == 0 ? 0.5f : t / toT); + float a3 = Lerp(to, post, postT - toT == 0 ? 1.0f : (t - toT) / (postT - toT)); + float b1 = Lerp(a1, a2, toT - preT == 0 ? 0.0f : (t - preT) / (toT - preT)); + float b2 = Lerp(a2, a3, postT == 0 ? 1.0f : t / postT); return Lerp(b1, b2, toT == 0 ? 0.5f : t / toT); } /// <summary> + /// Cubic interpolates between two values by the factor defined in <paramref name="weight"/> + /// with pre and post values. + /// It can perform smoother interpolation than + /// <see cref="CubicInterpolate(double, double, double, double, double)"/> + /// by the time values. + /// </summary> + /// <param name="from">The start value for interpolation.</param> + /// <param name="to">The destination value for interpolation.</param> + /// <param name="pre">The value which before "from" value for interpolation.</param> + /// <param name="post">The value which after "to" value for interpolation.</param> + /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> + /// <param name="toT"></param> + /// <param name="preT"></param> + /// <param name="postT"></param> + /// <returns>The resulting value of the interpolation.</returns> + public static double CubicInterpolateInTime(double from, double to, double pre, double post, double weight, double toT, double preT, double postT) + { + /* Barry-Goldman method */ + double t = Lerp(0.0, toT, weight); + double a1 = Lerp(pre, from, preT == 0 ? 0.0 : (t - preT) / -preT); + double a2 = Lerp(from, to, toT == 0 ? 0.5 : t / toT); + double a3 = Lerp(to, post, postT - toT == 0 ? 1.0 : (t - toT) / (postT - toT)); + double b1 = Lerp(a1, a2, toT - preT == 0 ? 0.0 : (t - preT) / (toT - preT)); + double b2 = Lerp(a2, a3, postT == 0 ? 1.0 : t / postT); + return Lerp(b1, b2, toT == 0 ? 0.5 : t / toT); + } + + /// <summary> /// Cubic interpolates between two rotation values with shortest path /// by the factor defined in <paramref name="weight"/> with pre and post values. - /// See also <see cref="LerpAngle"/>. - /// It can perform smoother interpolation than <see cref="CubicInterpolateAngle"/> + /// See also <see cref="LerpAngle(float, float, float)"/>. + /// It can perform smoother interpolation than + /// <see cref="CubicInterpolateAngle(float, float, float, float, float)"/> /// by the time values. /// </summary> /// <param name="from">The start value for interpolation.</param> @@ -263,24 +474,78 @@ namespace Godot /// <param name="preT"></param> /// <param name="postT"></param> /// <returns>The resulting value of the interpolation.</returns> - public static real_t CubicInterpolateAngleInTime(real_t from, real_t to, real_t pre, real_t post, real_t weight, - real_t toT, real_t preT, real_t postT) + public static float CubicInterpolateAngleInTime(float from, float to, float pre, float post, float weight, float toT, float preT, float postT) { - real_t fromRot = from % Mathf.Tau; + float fromRot = from % MathF.Tau; - real_t preDiff = (pre - fromRot) % Mathf.Tau; - real_t preRot = fromRot + (2.0f * preDiff) % Mathf.Tau - preDiff; + float preDiff = (pre - fromRot) % MathF.Tau; + float preRot = fromRot + (2.0f * preDiff) % MathF.Tau - preDiff; - real_t toDiff = (to - fromRot) % Mathf.Tau; - real_t toRot = fromRot + (2.0f * toDiff) % Mathf.Tau - toDiff; + float toDiff = (to - fromRot) % MathF.Tau; + float toRot = fromRot + (2.0f * toDiff) % MathF.Tau - toDiff; - real_t postDiff = (post - toRot) % Mathf.Tau; - real_t postRot = toRot + (2.0f * postDiff) % Mathf.Tau - postDiff; + float postDiff = (post - toRot) % MathF.Tau; + float postRot = toRot + (2.0f * postDiff) % MathF.Tau - postDiff; return CubicInterpolateInTime(fromRot, toRot, preRot, postRot, weight, toT, preT, postT); } /// <summary> + /// Cubic interpolates between two rotation values with shortest path + /// by the factor defined in <paramref name="weight"/> with pre and post values. + /// See also <see cref="LerpAngle(double, double, double)"/>. + /// It can perform smoother interpolation than + /// <see cref="CubicInterpolateAngle(double, double, double, double, double)"/> + /// by the time values. + /// </summary> + /// <param name="from">The start value for interpolation.</param> + /// <param name="to">The destination value for interpolation.</param> + /// <param name="pre">The value which before "from" value for interpolation.</param> + /// <param name="post">The value which after "to" value for interpolation.</param> + /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> + /// <param name="toT"></param> + /// <param name="preT"></param> + /// <param name="postT"></param> + /// <returns>The resulting value of the interpolation.</returns> + public static double CubicInterpolateAngleInTime(double from, double to, double pre, double post, double weight, double toT, double preT, double postT) + { + double fromRot = from % Math.Tau; + + double preDiff = (pre - fromRot) % Math.Tau; + double preRot = fromRot + (2.0 * preDiff) % Math.Tau - preDiff; + + double toDiff = (to - fromRot) % Math.Tau; + double toRot = fromRot + (2.0 * toDiff) % Math.Tau - toDiff; + + double postDiff = (post - toRot) % Math.Tau; + double postRot = toRot + (2.0 * postDiff) % Math.Tau - postDiff; + + return CubicInterpolateInTime(fromRot, toRot, preRot, postRot, weight, toT, preT, postT); + } + + /// <summary> + /// Returns the point at the given <paramref name="t"/> on a one-dimensional Bezier curve defined by + /// the given <paramref name="control1"/>, <paramref name="control2"/>, and <paramref name="end"/> points. + /// </summary> + /// <param name="start">The start value for the interpolation.</param> + /// <param name="control1">Control point that defines the bezier curve.</param> + /// <param name="control2">Control point that defines the bezier curve.</param> + /// <param name="end">The destination value for the interpolation.</param> + /// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> + /// <returns>The resulting value of the interpolation.</returns> + public static float BezierInterpolate(float start, float control1, float control2, float end, float t) + { + // Formula from Wikipedia article on Bezier curves + float omt = 1.0f - t; + float omt2 = omt * omt; + float omt3 = omt2 * omt; + float t2 = t * t; + float t3 = t2 * t; + + return start * omt3 + control1 * omt2 * t * 3.0f + control2 * omt * t2 * 3.0f + end * t3; + } + + /// <summary> /// Returns the point at the given <paramref name="t"/> on a one-dimensional Bezier curve defined by /// the given <paramref name="control1"/>, <paramref name="control2"/>, and <paramref name="end"/> points. /// </summary> @@ -290,16 +555,16 @@ namespace Godot /// <param name="end">The destination value for the interpolation.</param> /// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> /// <returns>The resulting value of the interpolation.</returns> - public static real_t BezierInterpolate(real_t start, real_t control1, real_t control2, real_t end, real_t t) + public static double BezierInterpolate(double start, double control1, double control2, double end, double t) { // Formula from Wikipedia article on Bezier curves - real_t omt = 1 - t; - real_t omt2 = omt * omt; - real_t omt3 = omt2 * omt; - real_t t2 = t * t; - real_t t3 = t2 * t; + double omt = 1.0 - t; + double omt2 = omt * omt; + double omt3 = omt2 * omt; + double t2 = t * t; + double t3 = t2 * t; - return start * omt3 + control1 * omt2 * t * 3 + control2 * omt * t2 * 3 + end * t3; + return start * omt3 + control1 * omt2 * t * 3.0 + control2 * omt * t2 * 3.0 + end * t3; } /// <summary> @@ -312,26 +577,68 @@ namespace Godot /// <param name="end">The destination value for the interpolation.</param> /// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> /// <returns>The resulting value of the interpolation.</returns> - public static real_t BezierDerivative(real_t start, real_t control1, real_t control2, real_t end, real_t t) + public static float BezierDerivative(float start, float control1, float control2, float end, float t) { // Formula from Wikipedia article on Bezier curves - real_t omt = 1 - t; - real_t omt2 = omt * omt; - real_t t2 = t * t; + float omt = 1.0f - t; + float omt2 = omt * omt; + float t2 = t * t; - real_t d = (control1 - start) * 3 * omt2 + (control2 - control1) * 6 * omt * t + (end - control2) * 3 * t2; + float d = (control1 - start) * 3.0f * omt2 + (control2 - control1) * 6.0f * omt * t + (end - control2) * 3.0f * t2; return d; } /// <summary> + /// Returns the derivative at the given <paramref name="t"/> on a one dimensional Bezier curve defined by + /// the given <paramref name="control1"/>, <paramref name="control2"/>, and <paramref name="end"/> points. + /// </summary> + /// <param name="start">The start value for the interpolation.</param> + /// <param name="control1">Control point that defines the bezier curve.</param> + /// <param name="control2">Control point that defines the bezier curve.</param> + /// <param name="end">The destination value for the interpolation.</param> + /// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> + /// <returns>The resulting value of the interpolation.</returns> + public static double BezierDerivative(double start, double control1, double control2, double end, double t) + { + // Formula from Wikipedia article on Bezier curves + double omt = 1.0 - t; + double omt2 = omt * omt; + double t2 = t * t; + + double d = (control1 - start) * 3.0 * omt2 + (control2 - control1) * 6.0 * omt * t + (end - control2) * 3.0 * t2; + return d; + } + + /// <summary> + /// Converts from decibels to linear energy (audio). + /// </summary> + /// <seealso cref="LinearToDb(float)"/> + /// <param name="db">Decibels to convert.</param> + /// <returns>Audio volume as linear energy.</returns> + public static float DbToLinear(float db) + { + return MathF.Exp(db * 0.11512925464970228420089957273422f); + } + + /// <summary> /// Converts from decibels to linear energy (audio). /// </summary> - /// <seealso cref="LinearToDb(real_t)"/> + /// <seealso cref="LinearToDb(double)"/> /// <param name="db">Decibels to convert.</param> /// <returns>Audio volume as linear energy.</returns> - public static real_t DbToLinear(real_t db) + public static double DbToLinear(double db) + { + return Math.Exp(db * 0.11512925464970228420089957273422); + } + + /// <summary> + /// Converts an angle expressed in degrees to radians. + /// </summary> + /// <param name="deg">An angle expressed in degrees.</param> + /// <returns>The same angle expressed in radians.</returns> + public static float DegToRad(float deg) { - return (real_t)Math.Exp(db * 0.11512925464970228420089957273422); + return deg * _degToRadConstF; } /// <summary> @@ -339,9 +646,9 @@ namespace Godot /// </summary> /// <param name="deg">An angle expressed in degrees.</param> /// <returns>The same angle expressed in radians.</returns> - public static real_t DegToRad(real_t deg) + public static double DegToRad(double deg) { - return deg * _degToRadConst; + return deg * _degToRadConstD; } /// <summary> @@ -354,38 +661,94 @@ namespace Godot /// <c>0</c> is constant, <c>1</c> is linear, <c>0</c> to <c>1</c> is ease-in, <c>1</c> or more is ease-out. /// </param> /// <returns>The eased value.</returns> - public static real_t Ease(real_t s, real_t curve) + public static float Ease(float s, float curve) { - if (s < 0f) + if (s < 0.0f) { - s = 0f; + s = 0.0f; } else if (s > 1.0f) { s = 1.0f; } - if (curve > 0f) + if (curve > 0.0f) { if (curve < 1.0f) { - return 1.0f - Pow(1.0f - s, 1.0f / curve); + return 1.0f - MathF.Pow(1.0f - s, 1.0f / curve); } - return Pow(s, curve); + return MathF.Pow(s, curve); } - if (curve < 0f) + if (curve < 0.0f) { if (s < 0.5f) { - return Pow(s * 2.0f, -curve) * 0.5f; + return MathF.Pow(s * 2.0f, -curve) * 0.5f; } - return ((1.0f - Pow(1.0f - ((s - 0.5f) * 2.0f), -curve)) * 0.5f) + 0.5f; + return ((1.0f - MathF.Pow(1.0f - ((s - 0.5f) * 2.0f), -curve)) * 0.5f) + 0.5f; } - return 0f; + return 0.0f; + } + + /// <summary> + /// Easing function, based on exponent. The <paramref name="curve"/> values are: + /// <c>0</c> is constant, <c>1</c> is linear, <c>0</c> to <c>1</c> is ease-in, <c>1</c> or more is ease-out. + /// Negative values are in-out/out-in. + /// </summary> + /// <param name="s">The value to ease.</param> + /// <param name="curve"> + /// <c>0</c> is constant, <c>1</c> is linear, <c>0</c> to <c>1</c> is ease-in, <c>1</c> or more is ease-out. + /// </param> + /// <returns>The eased value.</returns> + public static double Ease(double s, double curve) + { + if (s < 0.0) + { + s = 0.0; + } + else if (s > 1.0) + { + s = 1.0; + } + + if (curve > 0) + { + if (curve < 1.0) + { + return 1.0 - Math.Pow(1.0 - s, 1.0 / curve); + } + + return Math.Pow(s, curve); + } + + if (curve < 0.0) + { + if (s < 0.5) + { + return Math.Pow(s * 2.0, -curve) * 0.5; + } + + return ((1.0 - Math.Pow(1.0 - ((s - 0.5) * 2.0), -curve)) * 0.5) + 0.5; + } + + return 0.0; + } + + /// <summary> + /// The natural exponential function. It raises the mathematical + /// constant <c>e</c> to the power of <paramref name="s"/> and returns it. + /// </summary> + /// <param name="s">The exponent to raise <c>e</c> to.</param> + /// <returns><c>e</c> raised to the power of <paramref name="s"/>.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Exp(float s) + { + return MathF.Exp(s); } /// <summary> @@ -394,9 +757,21 @@ namespace Godot /// </summary> /// <param name="s">The exponent to raise <c>e</c> to.</param> /// <returns><c>e</c> raised to the power of <paramref name="s"/>.</returns> - public static real_t Exp(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Exp(double s) + { + return Math.Exp(s); + } + + /// <summary> + /// Rounds <paramref name="s"/> downward (towards negative infinity). + /// </summary> + /// <param name="s">The number to floor.</param> + /// <returns>The largest whole number that is not more than <paramref name="s"/>.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Floor(float s) { - return (real_t)Math.Exp(s); + return MathF.Floor(s); } /// <summary> @@ -404,14 +779,32 @@ namespace Godot /// </summary> /// <param name="s">The number to floor.</param> /// <returns>The largest whole number that is not more than <paramref name="s"/>.</returns> - public static real_t Floor(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Floor(double s) + { + return Math.Floor(s); + } + + /// <summary> + /// Returns a normalized value considering the given range. + /// This is the opposite of <see cref="Lerp(float, float, float)"/>. + /// </summary> + /// <param name="from">The start value for interpolation.</param> + /// <param name="to">The destination value for interpolation.</param> + /// <param name="weight">The interpolated value.</param> + /// <returns> + /// The resulting value of the inverse interpolation. + /// The returned value will be between 0.0 and 1.0 if <paramref name="weight"/> is + /// between <paramref name="from"/> and <paramref name="to"/> (inclusive). + /// </returns> + public static float InverseLerp(float from, float to, float weight) { - return (real_t)Math.Floor(s); + return (weight - from) / (to - from); } /// <summary> /// Returns a normalized value considering the given range. - /// This is the opposite of <see cref="Lerp(real_t, real_t, real_t)"/>. + /// This is the opposite of <see cref="Lerp(double, double, double)"/>. /// </summary> /// <param name="from">The start value for interpolation.</param> /// <param name="to">The destination value for interpolation.</param> @@ -421,7 +814,7 @@ namespace Godot /// The returned value will be between 0.0 and 1.0 if <paramref name="weight"/> is /// between <paramref name="from"/> and <paramref name="to"/> (inclusive). /// </returns> - public static real_t InverseLerp(real_t from, real_t to, real_t weight) + public static double InverseLerp(double from, double to, double weight) { return (weight - from) / (to - from); } @@ -434,7 +827,7 @@ namespace Godot /// <param name="a">One of the values.</param> /// <param name="b">The other value.</param> /// <returns>A <see langword="bool"/> for whether or not the two values are approximately equal.</returns> - public static bool IsEqualApprox(real_t a, real_t b) + public static bool IsEqualApprox(float a, float b) { // Check for exact equality first, required to handle "infinity" values. if (a == b) @@ -442,12 +835,36 @@ namespace Godot return true; } // Then check for approximate equality. - real_t tolerance = Epsilon * Abs(a); - if (tolerance < Epsilon) + float tolerance = _epsilonF * Math.Abs(a); + if (tolerance < _epsilonF) { - tolerance = Epsilon; + tolerance = _epsilonF; } - return Abs(a - b) < tolerance; + return Math.Abs(a - b) < tolerance; + } + + /// <summary> + /// Returns <see langword="true"/> if <paramref name="a"/> and <paramref name="b"/> are approximately equal + /// to each other. + /// The comparison is done using a tolerance calculation with <see cref="Epsilon"/>. + /// </summary> + /// <param name="a">One of the values.</param> + /// <param name="b">The other value.</param> + /// <returns>A <see langword="bool"/> for whether or not the two values are approximately equal.</returns> + public static bool IsEqualApprox(double a, double b) + { + // Check for exact equality first, required to handle "infinity" values. + if (a == b) + { + return true; + } + // Then check for approximate equality. + double tolerance = _epsilonD * Math.Abs(a); + if (tolerance < _epsilonD) + { + tolerance = _epsilonD; + } + return Math.Abs(a - b) < tolerance; } /// <summary> @@ -456,9 +873,22 @@ namespace Godot /// </summary> /// <param name="s">The value to check.</param> /// <returns>A <see langword="bool"/> for whether or not the value is a finite value.</returns> - public static bool IsFinite(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsFinite(float s) { - return real_t.IsFinite(s); + return float.IsFinite(s); + } + + /// <summary> + /// Returns whether <paramref name="s"/> is a finite value, i.e. it is not + /// <see cref="NaN"/>, positive infinite, or negative infinity. + /// </summary> + /// <param name="s">The value to check.</param> + /// <returns>A <see langword="bool"/> for whether or not the value is a finite value.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsFinite(double s) + { + return double.IsFinite(s); } /// <summary> @@ -466,9 +896,32 @@ namespace Godot /// </summary> /// <param name="s">The value to check.</param> /// <returns>A <see langword="bool"/> for whether or not the value is an infinity value.</returns> - public static bool IsInf(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsInf(float s) { - return real_t.IsInfinity(s); + return float.IsInfinity(s); + } + + /// <summary> + /// Returns whether <paramref name="s"/> is an infinity value (either positive infinity or negative infinity). + /// </summary> + /// <param name="s">The value to check.</param> + /// <returns>A <see langword="bool"/> for whether or not the value is an infinity value.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsInf(double s) + { + return double.IsInfinity(s); + } + + /// <summary> + /// Returns whether <paramref name="s"/> is a <c>NaN</c> ("Not a Number" or invalid) value. + /// </summary> + /// <param name="s">The value to check.</param> + /// <returns>A <see langword="bool"/> for whether or not the value is a <c>NaN</c> value.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNaN(float s) + { + return float.IsNaN(s); } /// <summary> @@ -476,34 +929,64 @@ namespace Godot /// </summary> /// <param name="s">The value to check.</param> /// <returns>A <see langword="bool"/> for whether or not the value is a <c>NaN</c> value.</returns> - public static bool IsNaN(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNaN(double s) { - return real_t.IsNaN(s); + return double.IsNaN(s); } /// <summary> /// Returns <see langword="true"/> if <paramref name="s"/> is zero or almost zero. /// The comparison is done using a tolerance calculation with <see cref="Epsilon"/>. /// - /// This method is faster than using <see cref="IsEqualApprox(real_t, real_t)"/> with + /// This method is faster than using <see cref="IsEqualApprox(float, float)"/> with /// one value as zero. /// </summary> /// <param name="s">The value to check.</param> /// <returns>A <see langword="bool"/> for whether or not the value is nearly zero.</returns> - public static bool IsZeroApprox(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsZeroApprox(float s) { - return Abs(s) < Epsilon; + return Math.Abs(s) < _epsilonF; + } + + /// <summary> + /// Returns <see langword="true"/> if <paramref name="s"/> is zero or almost zero. + /// The comparison is done using a tolerance calculation with <see cref="Epsilon"/>. + /// + /// This method is faster than using <see cref="IsEqualApprox(double, double)"/> with + /// one value as zero. + /// </summary> + /// <param name="s">The value to check.</param> + /// <returns>A <see langword="bool"/> for whether or not the value is nearly zero.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsZeroApprox(double s) + { + return Math.Abs(s) < _epsilonD; + } + + /// <summary> + /// Linearly interpolates between two values by a normalized value. + /// This is the opposite <see cref="InverseLerp(float, float, float)"/>. + /// </summary> + /// <param name="from">The start value for interpolation.</param> + /// <param name="to">The destination value for interpolation.</param> + /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> + /// <returns>The resulting value of the interpolation.</returns> + public static float Lerp(float from, float to, float weight) + { + return from + ((to - from) * weight); } /// <summary> /// Linearly interpolates between two values by a normalized value. - /// This is the opposite <see cref="InverseLerp(real_t, real_t, real_t)"/>. + /// This is the opposite <see cref="InverseLerp(double, double, double)"/>. /// </summary> /// <param name="from">The start value for interpolation.</param> /// <param name="to">The destination value for interpolation.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> /// <returns>The resulting value of the interpolation.</returns> - public static real_t Lerp(real_t from, real_t to, real_t weight) + public static double Lerp(double from, double to, double weight) { return from + ((to - from) * weight); } @@ -511,17 +994,34 @@ namespace Godot /// <summary> /// Linearly interpolates between two angles (in radians) by a normalized value. /// - /// Similar to <see cref="Lerp(real_t, real_t, real_t)"/>, + /// Similar to <see cref="Lerp(float, float, float)"/>, + /// but interpolates correctly when the angles wrap around <see cref="Tau"/>. + /// </summary> + /// <param name="from">The start angle for interpolation.</param> + /// <param name="to">The destination angle for interpolation.</param> + /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> + /// <returns>The resulting angle of the interpolation.</returns> + public static float LerpAngle(float from, float to, float weight) + { + float difference = (to - from) % MathF.Tau; + float distance = ((2 * difference) % MathF.Tau) - difference; + return from + (distance * weight); + } + + /// <summary> + /// Linearly interpolates between two angles (in radians) by a normalized value. + /// + /// Similar to <see cref="Lerp(double, double, double)"/>, /// but interpolates correctly when the angles wrap around <see cref="Tau"/>. /// </summary> /// <param name="from">The start angle for interpolation.</param> /// <param name="to">The destination angle for interpolation.</param> /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param> /// <returns>The resulting angle of the interpolation.</returns> - public static real_t LerpAngle(real_t from, real_t to, real_t weight) + public static double LerpAngle(double from, double to, double weight) { - real_t difference = (to - from) % Mathf.Tau; - real_t distance = ((2 * difference) % Mathf.Tau) - difference; + double difference = (to - from) % Math.Tau; + double distance = ((2 * difference) % Math.Tau) - difference; return from + (distance * weight); } @@ -529,7 +1029,7 @@ namespace Godot /// Converts from linear energy to decibels (audio). /// This can be used to implement volume sliders that behave as expected (since volume isn't linear). /// </summary> - /// <seealso cref="DbToLinear(real_t)"/> + /// <seealso cref="DbToLinear(float)"/> /// <example> /// <code> /// // "slider" refers to a node that inherits Range such as HSlider or VSlider. @@ -540,9 +1040,42 @@ namespace Godot /// </example> /// <param name="linear">The linear energy to convert.</param> /// <returns>Audio as decibels.</returns> - public static real_t LinearToDb(real_t linear) + public static float LinearToDb(float linear) { - return (real_t)(Math.Log(linear) * 8.6858896380650365530225783783321); + return MathF.Log(linear) * 8.6858896380650365530225783783321f; + } + + /// <summary> + /// Converts from linear energy to decibels (audio). + /// This can be used to implement volume sliders that behave as expected (since volume isn't linear). + /// </summary> + /// <seealso cref="DbToLinear(double)"/> + /// <example> + /// <code> + /// // "slider" refers to a node that inherits Range such as HSlider or VSlider. + /// // Its range must be configured to go from 0 to 1. + /// // Change the bus name if you'd like to change the volume of a specific bus only. + /// AudioServer.SetBusVolumeDb(AudioServer.GetBusIndex("Master"), GD.LinearToDb(slider.value)); + /// </code> + /// </example> + /// <param name="linear">The linear energy to convert.</param> + /// <returns>Audio as decibels.</returns> + public static double LinearToDb(double linear) + { + return Math.Log(linear) * 8.6858896380650365530225783783321; + } + + /// <summary> + /// Natural logarithm. The amount of time needed to reach a certain level of continuous growth. + /// + /// Note: This is not the same as the "log" function on most calculators, which uses a base 10 logarithm. + /// </summary> + /// <param name="s">The input value.</param> + /// <returns>The natural log of <paramref name="s"/>.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Log(float s) + { + return MathF.Log(s); } /// <summary> @@ -552,9 +1085,10 @@ namespace Godot /// </summary> /// <param name="s">The input value.</param> /// <returns>The natural log of <paramref name="s"/>.</returns> - public static real_t Log(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Log(double s) { - return (real_t)Math.Log(s); + return Math.Log(s); } /// <summary> @@ -563,9 +1097,22 @@ namespace Godot /// <param name="a">One of the values.</param> /// <param name="b">The other value.</param> /// <returns>Whichever of the two values is higher.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Max(int a, int b) { - return a > b ? a : b; + return Math.Max(a, b); + } + + /// <summary> + /// Returns the maximum of two values. + /// </summary> + /// <param name="a">One of the values.</param> + /// <param name="b">The other value.</param> + /// <returns>Whichever of the two values is higher.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Max(float a, float b) + { + return Math.Max(a, b); } /// <summary> @@ -574,9 +1121,10 @@ namespace Godot /// <param name="a">One of the values.</param> /// <param name="b">The other value.</param> /// <returns>Whichever of the two values is higher.</returns> - public static real_t Max(real_t a, real_t b) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Max(double a, double b) { - return a > b ? a : b; + return Math.Max(a, b); } /// <summary> @@ -585,9 +1133,22 @@ namespace Godot /// <param name="a">One of the values.</param> /// <param name="b">The other value.</param> /// <returns>Whichever of the two values is lower.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Min(int a, int b) { - return a < b ? a : b; + return Math.Min(a, b); + } + + /// <summary> + /// Returns the minimum of two values. + /// </summary> + /// <param name="a">One of the values.</param> + /// <param name="b">The other value.</param> + /// <returns>Whichever of the two values is lower.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Min(float a, float b) + { + return Math.Min(a, b); } /// <summary> @@ -596,9 +1157,27 @@ namespace Godot /// <param name="a">One of the values.</param> /// <param name="b">The other value.</param> /// <returns>Whichever of the two values is lower.</returns> - public static real_t Min(real_t a, real_t b) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Min(double a, double b) + { + return Math.Min(a, b); + } + + /// <summary> + /// Moves <paramref name="from"/> toward <paramref name="to"/> by the <paramref name="delta"/> value. + /// + /// Use a negative <paramref name="delta"/> value to move away. + /// </summary> + /// <param name="from">The start value.</param> + /// <param name="to">The value to move towards.</param> + /// <param name="delta">The amount to move by.</param> + /// <returns>The value after moving.</returns> + public static float MoveToward(float from, float to, float delta) { - return a < b ? a : b; + if (Math.Abs(to - from) <= delta) + return to; + + return from + (Math.Sign(to - from) * delta); } /// <summary> @@ -610,12 +1189,12 @@ namespace Godot /// <param name="to">The value to move towards.</param> /// <param name="delta">The amount to move by.</param> /// <returns>The value after moving.</returns> - public static real_t MoveToward(real_t from, real_t to, real_t delta) + public static double MoveToward(double from, double to, double delta) { - if (Abs(to - from) <= delta) + if (Math.Abs(to - from) <= delta) return to; - return from + (Sign(to - from) * delta); + return from + (Math.Sign(to - from) * delta); } /// <summary> @@ -657,9 +1236,25 @@ namespace Godot /// <param name="a">The dividend, the primary input.</param> /// <param name="b">The divisor. The output is on the range [0, <paramref name="b"/>).</param> /// <returns>The resulting output.</returns> - public static real_t PosMod(real_t a, real_t b) + public static float PosMod(float a, float b) + { + float c = a % b; + if ((c < 0 && b > 0) || (c > 0 && b < 0)) + { + c += b; + } + return c; + } + + /// <summary> + /// Performs a canonical Modulus operation, where the output is on the range [0, <paramref name="b"/>). + /// </summary> + /// <param name="a">The dividend, the primary input.</param> + /// <param name="b">The divisor. The output is on the range [0, <paramref name="b"/>).</param> + /// <returns>The resulting output.</returns> + public static double PosMod(double a, double b) { - real_t c = a % b; + double c = a % b; if ((c < 0 && b > 0) || (c > 0 && b < 0)) { c += b; @@ -673,9 +1268,22 @@ namespace Godot /// <param name="x">The base.</param> /// <param name="y">The exponent.</param> /// <returns><paramref name="x"/> raised to the power of <paramref name="y"/>.</returns> - public static real_t Pow(real_t x, real_t y) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Pow(float x, float y) + { + return MathF.Pow(x, y); + } + + /// <summary> + /// Returns the result of <paramref name="x"/> raised to the power of <paramref name="y"/>. + /// </summary> + /// <param name="x">The base.</param> + /// <param name="y">The exponent.</param> + /// <returns><paramref name="x"/> raised to the power of <paramref name="y"/>.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Pow(double x, double y) { - return (real_t)Math.Pow(x, y); + return Math.Pow(x, y); } /// <summary> @@ -683,9 +1291,21 @@ namespace Godot /// </summary> /// <param name="rad">An angle expressed in radians.</param> /// <returns>The same angle expressed in degrees.</returns> - public static real_t RadToDeg(real_t rad) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float RadToDeg(float rad) { - return rad * _radToDegConst; + return rad * _radToDegConstF; + } + + /// <summary> + /// Converts an angle expressed in radians to degrees. + /// </summary> + /// <param name="rad">An angle expressed in radians.</param> + /// <returns>The same angle expressed in degrees.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double RadToDeg(double rad) + { + return rad * _radToDegConstD; } /// <summary> @@ -698,20 +1318,48 @@ namespace Godot /// <param name="outFrom">The start value for the output interpolation.</param> /// <param name="outTo">The destination value for the output interpolation.</param> /// <returns>The resulting mapped value mapped.</returns> - public static real_t Remap(real_t value, real_t inFrom, real_t inTo, real_t outFrom, real_t outTo) + public static float Remap(float value, float inFrom, float inTo, float outFrom, float outTo) { return Lerp(outFrom, outTo, InverseLerp(inFrom, inTo, value)); } /// <summary> + /// Maps a <paramref name="value"/> from [<paramref name="inFrom"/>, <paramref name="inTo"/>] + /// to [<paramref name="outFrom"/>, <paramref name="outTo"/>]. + /// </summary> + /// <param name="value">The value to map.</param> + /// <param name="inFrom">The start value for the input interpolation.</param> + /// <param name="inTo">The destination value for the input interpolation.</param> + /// <param name="outFrom">The start value for the output interpolation.</param> + /// <param name="outTo">The destination value for the output interpolation.</param> + /// <returns>The resulting mapped value mapped.</returns> + public static double Remap(double value, double inFrom, double inTo, double outFrom, double outTo) + { + return Lerp(outFrom, outTo, InverseLerp(inFrom, inTo, value)); + } + + /// <summary> + /// Rounds <paramref name="s"/> to the nearest whole number, + /// with halfway cases rounded towards the nearest multiple of two. + /// </summary> + /// <param name="s">The number to round.</param> + /// <returns>The rounded number.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Round(float s) + { + return MathF.Round(s); + } + + /// <summary> /// Rounds <paramref name="s"/> to the nearest whole number, /// with halfway cases rounded towards the nearest multiple of two. /// </summary> /// <param name="s">The number to round.</param> /// <returns>The rounded number.</returns> - public static real_t Round(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Round(double s) { - return (real_t)Math.Round(s); + return Math.Round(s); } /// <summary> @@ -720,11 +1368,10 @@ namespace Godot /// </summary> /// <param name="s">The input number.</param> /// <returns>One of three possible values: <c>1</c>, <c>-1</c>, or <c>0</c>.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Sign(int s) { - if (s == 0) - return 0; - return s < 0 ? -1 : 1; + return Math.Sign(s); } /// <summary> @@ -733,11 +1380,33 @@ namespace Godot /// </summary> /// <param name="s">The input number.</param> /// <returns>One of three possible values: <c>1</c>, <c>-1</c>, or <c>0</c>.</returns> - public static int Sign(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Sign(float s) { - if (s == 0) - return 0; - return s < 0 ? -1 : 1; + return Math.Sign(s); + } + + /// <summary> + /// Returns the sign of <paramref name="s"/>: <c>-1</c> or <c>1</c>. + /// Returns <c>0</c> if <paramref name="s"/> is <c>0</c>. + /// </summary> + /// <param name="s">The input number.</param> + /// <returns>One of three possible values: <c>1</c>, <c>-1</c>, or <c>0</c>.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Sign(double s) + { + return Math.Sign(s); + } + + /// <summary> + /// Returns the sine of angle <paramref name="s"/> in radians. + /// </summary> + /// <param name="s">The angle in radians.</param> + /// <returns>The sine of that angle.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Sin(float s) + { + return MathF.Sin(s); } /// <summary> @@ -745,9 +1414,21 @@ namespace Godot /// </summary> /// <param name="s">The angle in radians.</param> /// <returns>The sine of that angle.</returns> - public static real_t Sin(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Sin(double s) + { + return Math.Sin(s); + } + + /// <summary> + /// Returns the hyperbolic sine of angle <paramref name="s"/> in radians. + /// </summary> + /// <param name="s">The angle in radians.</param> + /// <returns>The hyperbolic sine of that angle.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Sinh(float s) { - return (real_t)Math.Sin(s); + return MathF.Sinh(s); } /// <summary> @@ -755,27 +1436,47 @@ namespace Godot /// </summary> /// <param name="s">The angle in radians.</param> /// <returns>The hyperbolic sine of that angle.</returns> - public static real_t Sinh(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Sinh(double s) + { + return Math.Sinh(s); + } + + /// <summary> + /// Returns a number smoothly interpolated between <paramref name="from"/> and <paramref name="to"/>, + /// based on the <paramref name="weight"/>. Similar to <see cref="Lerp(float, float, float)"/>, + /// but interpolates faster at the beginning and slower at the end. + /// </summary> + /// <param name="from">The start value for interpolation.</param> + /// <param name="to">The destination value for interpolation.</param> + /// <param name="weight">A value representing the amount of interpolation.</param> + /// <returns>The resulting value of the interpolation.</returns> + public static float SmoothStep(float from, float to, float weight) { - return (real_t)Math.Sinh(s); + if (IsEqualApprox(from, to)) + { + return from; + } + float x = Math.Clamp((weight - from) / (to - from), 0.0f, 1.0f); + return x * x * (3 - (2 * x)); } /// <summary> /// Returns a number smoothly interpolated between <paramref name="from"/> and <paramref name="to"/>, - /// based on the <paramref name="weight"/>. Similar to <see cref="Lerp(real_t, real_t, real_t)"/>, + /// based on the <paramref name="weight"/>. Similar to <see cref="Lerp(double, double, double)"/>, /// but interpolates faster at the beginning and slower at the end. /// </summary> /// <param name="from">The start value for interpolation.</param> /// <param name="to">The destination value for interpolation.</param> /// <param name="weight">A value representing the amount of interpolation.</param> /// <returns>The resulting value of the interpolation.</returns> - public static real_t SmoothStep(real_t from, real_t to, real_t weight) + public static double SmoothStep(double from, double to, double weight) { if (IsEqualApprox(from, to)) { return from; } - real_t x = Clamp((weight - from) / (to - from), (real_t)0.0, (real_t)1.0); + double x = Math.Clamp((weight - from) / (to - from), 0.0, 1.0); return x * x * (3 - (2 * x)); } @@ -786,9 +1487,23 @@ namespace Godot /// </summary> /// <param name="s">The input number. Must not be negative.</param> /// <returns>The square root of <paramref name="s"/>.</returns> - public static real_t Sqrt(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Sqrt(float s) { - return (real_t)Math.Sqrt(s); + return MathF.Sqrt(s); + } + + /// <summary> + /// Returns the square root of <paramref name="s"/>, where <paramref name="s"/> is a non-negative number. + /// + /// If you need negative inputs, use <see cref="System.Numerics.Complex"/>. + /// </summary> + /// <param name="s">The input number. Must not be negative.</param> + /// <returns>The square root of <paramref name="s"/>.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Sqrt(double s) + { + return Math.Sqrt(s); } /// <summary> @@ -798,7 +1513,7 @@ namespace Godot /// </summary> /// <param name="step">The input value.</param> /// <returns>The position of the first non-zero digit.</returns> - public static int StepDecimals(real_t step) + public static int StepDecimals(double step) { double[] sd = new double[] { @@ -812,7 +1527,7 @@ namespace Godot 0.00000009999, 0.000000009999, }; - double abs = Abs(step); + double abs = Math.Abs(step); double decs = abs - (int)abs; // Strip away integer part for (int i = 0; i < sd.Length; i++) { @@ -831,11 +1546,28 @@ namespace Godot /// <param name="s">The value to snap.</param> /// <param name="step">The step size to snap to.</param> /// <returns>The snapped value.</returns> - public static real_t Snapped(real_t s, real_t step) + public static float Snapped(float s, float step) + { + if (step != 0f) + { + return MathF.Floor((s / step) + 0.5f) * step; + } + + return s; + } + + /// <summary> + /// Snaps float value <paramref name="s"/> to a given <paramref name="step"/>. + /// This can also be used to round a floating point number to an arbitrary number of decimals. + /// </summary> + /// <param name="s">The value to snap.</param> + /// <param name="step">The step size to snap to.</param> + /// <returns>The snapped value.</returns> + public static double Snapped(double s, double step) { if (step != 0f) { - return Floor((s / step) + 0.5f) * step; + return Math.Floor((s / step) + 0.5f) * step; } return s; @@ -846,9 +1578,32 @@ namespace Godot /// </summary> /// <param name="s">The angle in radians.</param> /// <returns>The tangent of that angle.</returns> - public static real_t Tan(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Tan(float s) + { + return MathF.Tan(s); + } + + /// <summary> + /// Returns the tangent of angle <paramref name="s"/> in radians. + /// </summary> + /// <param name="s">The angle in radians.</param> + /// <returns>The tangent of that angle.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Tan(double s) + { + return Math.Tan(s); + } + + /// <summary> + /// Returns the hyperbolic tangent of angle <paramref name="s"/> in radians. + /// </summary> + /// <param name="s">The angle in radians.</param> + /// <returns>The hyperbolic tangent of that angle.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Tanh(float s) { - return (real_t)Math.Tan(s); + return MathF.Tanh(s); } /// <summary> @@ -856,9 +1611,10 @@ namespace Godot /// </summary> /// <param name="s">The angle in radians.</param> /// <returns>The hyperbolic tangent of that angle.</returns> - public static real_t Tanh(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Tanh(double s) { - return (real_t)Math.Tanh(s); + return Math.Tanh(s); } /// <summary> @@ -884,15 +1640,35 @@ namespace Godot /// Wraps <paramref name="value"/> between <paramref name="min"/> and <paramref name="max"/>. /// Usable for creating loop-alike behavior or infinite surfaces. /// If <paramref name="min"/> is <c>0</c>, this is equivalent - /// to <see cref="PosMod(real_t, real_t)"/>, so prefer using that instead. + /// to <see cref="PosMod(float, float)"/>, so prefer using that instead. + /// </summary> + /// <param name="value">The value to wrap.</param> + /// <param name="min">The minimum allowed value and lower bound of the range.</param> + /// <param name="max">The maximum allowed value and upper bound of the range.</param> + /// <returns>The wrapped value.</returns> + public static float Wrap(float value, float min, float max) + { + float range = max - min; + if (IsZeroApprox(range)) + { + return min; + } + return min + ((((value - min) % range) + range) % range); + } + + /// <summary> + /// Wraps <paramref name="value"/> between <paramref name="min"/> and <paramref name="max"/>. + /// Usable for creating loop-alike behavior or infinite surfaces. + /// If <paramref name="min"/> is <c>0</c>, this is equivalent + /// to <see cref="PosMod(double, double)"/>, so prefer using that instead. /// </summary> /// <param name="value">The value to wrap.</param> /// <param name="min">The minimum allowed value and lower bound of the range.</param> /// <param name="max">The maximum allowed value and upper bound of the range.</param> /// <returns>The wrapped value.</returns> - public static real_t Wrap(real_t value, real_t min, real_t max) + public static double Wrap(double value, double min, double max) { - real_t range = max - min; + double range = max - min; if (IsZeroApprox(range)) { return min; @@ -900,9 +1676,23 @@ namespace Godot return min + ((((value - min) % range) + range) % range); } - private static real_t Fract(real_t value) + /// <summary> + /// Returns the <paramref name="value"/> wrapped between <c>0</c> and the <paramref name="length"/>. + /// If the limit is reached, the next value the function returned is decreased to the <c>0</c> side + /// or increased to the <paramref name="length"/> side (like a triangle wave). + /// If <paramref name="length"/> is less than zero, it becomes positive. + /// </summary> + /// <param name="value">The value to pingpong.</param> + /// <param name="length">The maximum value of the function.</param> + /// <returns>The ping-ponged value.</returns> + public static float PingPong(float value, float length) { - return value - (real_t)Math.Floor(value); + return (length != 0.0f) ? Math.Abs(Fract((value - length) / (length * 2.0f)) * length * 2.0f - length) : 0.0f; + + static float Fract(float value) + { + return value - MathF.Floor(value); + } } /// <summary> @@ -914,9 +1704,14 @@ namespace Godot /// <param name="value">The value to pingpong.</param> /// <param name="length">The maximum value of the function.</param> /// <returns>The ping-ponged value.</returns> - public static real_t PingPong(real_t value, real_t length) + public static double PingPong(double value, double length) { - return (length != (real_t)0.0) ? Abs(Fract((value - length) / (length * (real_t)2.0)) * length * (real_t)2.0 - length) : (real_t)0.0; + return (length != 0.0) ? Math.Abs(Fract((value - length) / (length * 2.0)) * length * 2.0 - length) : 0.0; + + static double Fract(double value) + { + return value - Math.Floor(value); + } } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs index 72a1868964..cc2d61f58d 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MathfEx.cs @@ -1,4 +1,8 @@ using System; +using System.Runtime.CompilerServices; + +// This file contains extra members for the Mathf class that aren't part of Godot's Core API. +// Math API that is also part of Core should go into Mathf.cs. namespace Godot { @@ -16,14 +20,18 @@ namespace Godot /// </summary> public const real_t Sqrt2 = (real_t)1.4142135623730950488016887242M; // 1.4142136f and 1.414213562373095 + // Epsilon size should depend on the precision used. + private const float _epsilonF = 1e-06f; + private const double _epsilonD = 1e-14; + /// <summary> /// A very small number used for float comparison with error tolerance. /// 1e-06 with single-precision floats, but 1e-14 if <c>REAL_T_IS_DOUBLE</c>. /// </summary> #if REAL_T_IS_DOUBLE - public const real_t Epsilon = 1e-14; // Epsilon size should depend on the precision used. + public const real_t Epsilon = _epsilonD; #else - public const real_t Epsilon = 1e-06f; + public const real_t Epsilon = _epsilonF; #endif /// <summary> @@ -31,7 +39,8 @@ namespace Godot /// </summary> /// <param name="s">The input value.</param> /// <returns>The amount of digits.</returns> - public static int DecimalCount(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int DecimalCount(double s) { return DecimalCount((decimal)s); } @@ -41,6 +50,7 @@ namespace Godot /// </summary> /// <param name="s">The input <see langword="decimal"/> value.</param> /// <returns>The amount of digits.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int DecimalCount(decimal s) { return BitConverter.GetBytes(decimal.GetBits(s)[3])[2]; @@ -49,11 +59,25 @@ namespace Godot /// <summary> /// Rounds <paramref name="s"/> upward (towards positive infinity). /// - /// This is the same as <see cref="Ceil(real_t)"/>, but returns an <see langword="int"/>. + /// This is the same as <see cref="Ceil(float)"/>, but returns an <see langword="int"/>. + /// </summary> + /// <param name="s">The number to ceil.</param> + /// <returns>The smallest whole number that is not less than <paramref name="s"/>.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CeilToInt(float s) + { + return (int)MathF.Ceiling(s); + } + + /// <summary> + /// Rounds <paramref name="s"/> upward (towards positive infinity). + /// + /// This is the same as <see cref="Ceil(double)"/>, but returns an <see langword="int"/>. /// </summary> /// <param name="s">The number to ceil.</param> /// <returns>The smallest whole number that is not less than <paramref name="s"/>.</returns> - public static int CeilToInt(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CeilToInt(double s) { return (int)Math.Ceiling(s); } @@ -61,11 +85,25 @@ namespace Godot /// <summary> /// Rounds <paramref name="s"/> downward (towards negative infinity). /// - /// This is the same as <see cref="Floor(real_t)"/>, but returns an <see langword="int"/>. + /// This is the same as <see cref="Floor(float)"/>, but returns an <see langword="int"/>. + /// </summary> + /// <param name="s">The number to floor.</param> + /// <returns>The largest whole number that is not more than <paramref name="s"/>.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int FloorToInt(float s) + { + return (int)MathF.Floor(s); + } + + /// <summary> + /// Rounds <paramref name="s"/> downward (towards negative infinity). + /// + /// This is the same as <see cref="Floor(double)"/>, but returns an <see langword="int"/>. /// </summary> /// <param name="s">The number to floor.</param> /// <returns>The largest whole number that is not more than <paramref name="s"/>.</returns> - public static int FloorToInt(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int FloorToInt(double s) { return (int)Math.Floor(s); } @@ -73,11 +111,25 @@ namespace Godot /// <summary> /// Rounds <paramref name="s"/> to the nearest whole number. /// - /// This is the same as <see cref="Round(real_t)"/>, but returns an <see langword="int"/>. + /// This is the same as <see cref="Round(float)"/>, but returns an <see langword="int"/>. /// </summary> /// <param name="s">The number to round.</param> /// <returns>The rounded number.</returns> - public static int RoundToInt(real_t s) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int RoundToInt(float s) + { + return (int)MathF.Round(s); + } + + /// <summary> + /// Rounds <paramref name="s"/> to the nearest whole number. + /// + /// This is the same as <see cref="Round(double)"/>, but returns an <see langword="int"/>. + /// </summary> + /// <param name="s">The number to round.</param> + /// <returns>The rounded number.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int RoundToInt(double s) { return (int)Math.Round(s); } @@ -87,23 +139,53 @@ namespace Godot /// </summary> /// <param name="s">The angle in radians.</param> /// <returns>The sine and cosine of that angle.</returns> - public static (real_t Sin, real_t Cos) SinCos(real_t s) + public static (float Sin, float Cos) SinCos(float s) + { + return MathF.SinCos(s); + } + + /// <summary> + /// Returns the sine and cosine of angle <paramref name="s"/> in radians. + /// </summary> + /// <param name="s">The angle in radians.</param> + /// <returns>The sine and cosine of that angle.</returns> + public static (double Sin, double Cos) SinCos(double s) { - (double sin, double cos) = Math.SinCos(s); - return ((real_t)sin, (real_t)cos); + return Math.SinCos(s); + } + + /// <summary> + /// Returns <see langword="true"/> if <paramref name="a"/> and <paramref name="b"/> are approximately + /// equal to each other. + /// The comparison is done using the provided tolerance value. + /// If you want the tolerance to be calculated for you, use <see cref="IsEqualApprox(float, float)"/>. + /// </summary> + /// <param name="a">One of the values.</param> + /// <param name="b">The other value.</param> + /// <param name="tolerance">The pre-calculated tolerance value.</param> + /// <returns>A <see langword="bool"/> for whether or not the two values are equal.</returns> + public static bool IsEqualApprox(float a, float b, float tolerance) + { + // Check for exact equality first, required to handle "infinity" values. + if (a == b) + { + return true; + } + // Then check for approximate equality. + return Math.Abs(a - b) < tolerance; } /// <summary> /// Returns <see langword="true"/> if <paramref name="a"/> and <paramref name="b"/> are approximately /// equal to each other. /// The comparison is done using the provided tolerance value. - /// If you want the tolerance to be calculated for you, use <see cref="IsEqualApprox(real_t, real_t)"/>. + /// If you want the tolerance to be calculated for you, use <see cref="IsEqualApprox(double, double)"/>. /// </summary> /// <param name="a">One of the values.</param> /// <param name="b">The other value.</param> /// <param name="tolerance">The pre-calculated tolerance value.</param> /// <returns>A <see langword="bool"/> for whether or not the two values are equal.</returns> - public static bool IsEqualApprox(real_t a, real_t b, real_t tolerance) + public static bool IsEqualApprox(double a, double b, double tolerance) { // Check for exact equality first, required to handle "infinity" values. if (a == b) @@ -111,7 +193,7 @@ namespace Godot return true; } // Then check for approximate equality. - return Abs(a - b) < tolerance; + return Math.Abs(a - b) < tolerance; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/ExceptionUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/ExceptionUtils.cs index 5a0ea2ba13..71a2adadcb 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/ExceptionUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/ExceptionUtils.cs @@ -68,7 +68,7 @@ namespace Godot.NativeInterop string file = globalFrames.Count > 0 ? globalFrames[0].File ?? "" : ""; string func = globalFrames.Count > 0 ? globalFrames[0].Func : ""; int line = globalFrames.Count > 0 ? globalFrames[0].Line : 0; - string errorMsg = "Exception"; + string errorMsg = e.GetType().FullName ?? ""; using godot_string nFile = Marshaling.ConvertStringToNative(file); using godot_string nFunc = Marshaling.ConvertStringToNative(func); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropStructs.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropStructs.cs index fa79c2efbc..43e7c7eb9a 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropStructs.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropStructs.cs @@ -104,7 +104,7 @@ namespace Godot.NativeInterop } } - [StructLayout(LayoutKind.Explicit)] + [StructLayout(LayoutKind.Sequential, Pack = 8)] // ReSharper disable once InconsistentNaming public ref struct godot_variant { @@ -113,11 +113,11 @@ namespace Godot.NativeInterop => (godot_variant*)Unsafe.AsPointer(ref Unsafe.AsRef(in _typeField)); // 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; + private int _typeField; // There's padding here - [FieldOffset(8)] private godot_variant_data _data; + private godot_variant_data _data; [StructLayout(LayoutKind.Explicit)] // ReSharper disable once InconsistentNaming @@ -126,10 +126,10 @@ namespace Godot.NativeInterop [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 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 Projection* _projection; [FieldOffset(0)] private godot_variant_data_mem _mem; @@ -137,18 +137,18 @@ namespace Godot.NativeInterop [FieldOffset(0)] public godot_string_name _m_string_name; [FieldOffset(0)] public godot_string _m_string; [FieldOffset(0)] public Vector4 _m_vector4; - [FieldOffset(0)] public Vector4i _m_vector4i; + [FieldOffset(0)] public Vector4I _m_vector4i; [FieldOffset(0)] public Vector3 _m_vector3; - [FieldOffset(0)] public Vector3i _m_vector3i; + [FieldOffset(0)] public Vector3I _m_vector3i; [FieldOffset(0)] public Vector2 _m_vector2; - [FieldOffset(0)] public Vector2i _m_vector2i; + [FieldOffset(0)] public Vector2I _m_vector2i; [FieldOffset(0)] public Rect2 _m_rect2; - [FieldOffset(0)] public Rect2i _m_rect2i; + [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 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; @@ -211,10 +211,10 @@ namespace Godot.NativeInterop public readonly unsafe Transform2D* Transform2D { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _data._transform2D; + get => _data._transform2d; } - public readonly unsafe AABB* AABB + public readonly unsafe Aabb* Aabb { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _data._aabb; @@ -229,7 +229,7 @@ namespace Godot.NativeInterop public readonly unsafe Transform3D* Transform3D { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _data._transform3D; + get => _data._transform3d; } public readonly unsafe Projection* Projection @@ -262,7 +262,7 @@ namespace Godot.NativeInterop set => _data._m_vector4 = value; } - public Vector4i Vector4i + public Vector4I Vector4I { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get => _data._m_vector4i; @@ -278,7 +278,7 @@ namespace Godot.NativeInterop set => _data._m_vector3 = value; } - public Vector3i Vector3i + public Vector3I Vector3I { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get => _data._m_vector3i; @@ -294,7 +294,7 @@ namespace Godot.NativeInterop set => _data._m_vector2 = value; } - public Vector2i Vector2i + public Vector2I Vector2I { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get => _data._m_vector2i; @@ -310,7 +310,7 @@ namespace Godot.NativeInterop set => _data._m_rect2 = value; } - public Rect2i Rect2i + public Rect2I Rect2I { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get => _data._m_rect2i; @@ -350,7 +350,7 @@ namespace Godot.NativeInterop set => _data._m_node_path = value; } - public RID RID + public Rid Rid { [MethodImpl(MethodImplOptions.AggressiveInlining)] readonly get => _data._m_rid; @@ -405,13 +405,13 @@ namespace Godot.NativeInterop case Variant.Type.Int: case Variant.Type.Float: case Variant.Type.Vector2: - case Variant.Type.Vector2i: + case Variant.Type.Vector2I: case Variant.Type.Rect2: - case Variant.Type.Rect2i: + case Variant.Type.Rect2I: case Variant.Type.Vector3: - case Variant.Type.Vector3i: + case Variant.Type.Vector3I: case Variant.Type.Vector4: - case Variant.Type.Vector4i: + case Variant.Type.Vector4I: case Variant.Type.Plane: case Variant.Type.Quaternion: case Variant.Type.Color: @@ -697,6 +697,9 @@ namespace Godot.NativeInterop private uint _safeRefCount; public VariantVector _arrayVector; + + private unsafe godot_variant* _readOnly; + // There are more fields here, but we don't care as we never store this in C# public readonly int Size @@ -704,6 +707,12 @@ namespace Godot.NativeInterop [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _arrayVector.Size; } + + public readonly unsafe bool IsReadOnly + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _readOnly != null; + } } [StructLayout(LayoutKind.Sequential)] @@ -737,6 +746,12 @@ namespace Godot.NativeInterop get => _p != null ? _p->Size : 0; } + public readonly unsafe bool IsReadOnly + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _p != null && _p->IsReadOnly; + } + public unsafe void Dispose() { if (_p == null) @@ -766,35 +781,59 @@ namespace Godot.NativeInterop // 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)] + [StructLayout(LayoutKind.Explicit)] // ReSharper disable once InconsistentNaming public ref struct godot_dictionary { [MethodImpl(MethodImplOptions.AggressiveInlining)] internal readonly unsafe godot_dictionary* GetUnsafeAddress() - => (godot_dictionary*)Unsafe.AsPointer(ref Unsafe.AsRef(in _p)); + => (godot_dictionary*)Unsafe.AsPointer(ref Unsafe.AsRef(in _getUnsafeAddressHelper)); - private IntPtr _p; + [FieldOffset(0)] private byte _getUnsafeAddressHelper; - public readonly bool IsAllocated + [FieldOffset(0)] private unsafe DictionaryPrivate* _p; + + [StructLayout(LayoutKind.Sequential)] + private struct DictionaryPrivate + { + private uint _safeRefCount; + + private unsafe godot_variant* _readOnly; + + // There are more fields here, but we don't care as we never store this in C# + + public readonly unsafe bool IsReadOnly + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _readOnly != null; + } + } + + public readonly unsafe bool IsAllocated { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _p != IntPtr.Zero; + get => _p != null; } - public void Dispose() + public readonly unsafe bool IsReadOnly { - if (_p == IntPtr.Zero) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _p != null && _p->IsReadOnly; + } + + public unsafe void Dispose() + { + if (_p == null) return; NativeFuncs.godotsharp_dictionary_destroy(ref this); - _p = IntPtr.Zero; + _p = null; } [StructLayout(LayoutKind.Sequential)] // ReSharper disable once InconsistentNaming internal struct movable { - private IntPtr _p; + private unsafe DictionaryPrivate* _p; public static unsafe explicit operator movable(in godot_dictionary value) => *(movable*)CustomUnsafe.AsPointer(ref CustomUnsafe.AsRef(value)); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropUtils.cs index 82f1c04d40..cc308bfdb3 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropUtils.cs @@ -8,7 +8,7 @@ namespace Godot.NativeInterop { internal static class InteropUtils { - public static Object UnmanagedGetManaged(IntPtr unmanaged) + public static GodotObject UnmanagedGetManaged(IntPtr unmanaged) { // The native pointer may be null if (unmanaged == IntPtr.Zero) @@ -23,7 +23,7 @@ namespace Godot.NativeInterop unmanaged, out hasCsScriptInstance); if (gcHandlePtr != IntPtr.Zero) - return (Object)GCHandle.FromIntPtr(gcHandlePtr).Target; + return (GodotObject)GCHandle.FromIntPtr(gcHandlePtr).Target; // Otherwise, if the object has a CSharpInstance script instance, return null @@ -37,17 +37,17 @@ namespace Godot.NativeInterop object target = gcHandlePtr != IntPtr.Zero ? GCHandle.FromIntPtr(gcHandlePtr).Target : null; if (target != null) - return (Object)target; + return (GodotObject)target; // If the native instance binding GC handle target was collected, create a new one gcHandlePtr = NativeFuncs.godotsharp_internal_unmanaged_instance_binding_create_managed( unmanaged, gcHandlePtr); - return gcHandlePtr != IntPtr.Zero ? (Object)GCHandle.FromIntPtr(gcHandlePtr).Target : null; + return gcHandlePtr != IntPtr.Zero ? (GodotObject)GCHandle.FromIntPtr(gcHandlePtr).Target : null; } - public static void TieManagedToUnmanaged(Object managed, IntPtr unmanaged, + public static void TieManagedToUnmanaged(GodotObject managed, IntPtr unmanaged, StringName nativeName, bool refCounted, Type type, Type nativeType) { var gcHandle = refCounted ? @@ -76,7 +76,7 @@ namespace Godot.NativeInterop } } - public static void TieManagedToUnmanagedWithPreSetup(Object managed, IntPtr unmanaged, + public static void TieManagedToUnmanagedWithPreSetup(GodotObject managed, IntPtr unmanaged, Type type, Type nativeType) { if (type == nativeType) @@ -87,7 +87,7 @@ namespace Godot.NativeInterop GCHandle.ToIntPtr(strongGCHandle), unmanaged); } - public static Object EngineGetSingleton(string name) + public static GodotObject EngineGetSingleton(string name) { 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 0d9a698af0..93a83b701b 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs @@ -51,29 +51,29 @@ namespace Godot.NativeInterop if (type == typeof(Vector2)) return Variant.Type.Vector2; - if (type == typeof(Vector2i)) - return Variant.Type.Vector2i; + if (type == typeof(Vector2I)) + return Variant.Type.Vector2I; if (type == typeof(Rect2)) return Variant.Type.Rect2; - if (type == typeof(Rect2i)) - return Variant.Type.Rect2i; + if (type == typeof(Rect2I)) + return Variant.Type.Rect2I; if (type == typeof(Transform2D)) - return Variant.Type.Transform2d; + return Variant.Type.Transform2D; if (type == typeof(Vector3)) return Variant.Type.Vector3; - if (type == typeof(Vector3i)) - return Variant.Type.Vector3i; + if (type == typeof(Vector3I)) + return Variant.Type.Vector3I; if (type == typeof(Vector4)) return Variant.Type.Vector4; - if (type == typeof(Vector4i)) - return Variant.Type.Vector4i; + if (type == typeof(Vector4I)) + return Variant.Type.Vector4I; if (type == typeof(Basis)) return Variant.Type.Basis; @@ -82,12 +82,12 @@ namespace Godot.NativeInterop return Variant.Type.Quaternion; if (type == typeof(Transform3D)) - return Variant.Type.Transform3d; + return Variant.Type.Transform3D; if (type == typeof(Projection)) return Variant.Type.Projection; - if (type == typeof(AABB)) + if (type == typeof(Aabb)) return Variant.Type.Aabb; if (type == typeof(Color)) @@ -140,15 +140,15 @@ namespace Godot.NativeInterop if (type == typeof(NodePath[])) return Variant.Type.Array; - if (type == typeof(RID[])) + if (type == typeof(Rid[])) return Variant.Type.Array; - if (typeof(Godot.Object[]).IsAssignableFrom(type)) + if (typeof(GodotObject[]).IsAssignableFrom(type)) return Variant.Type.Array; } else if (type.IsGenericType) { - if (typeof(Godot.Object).IsAssignableFrom(type)) + if (typeof(GodotObject).IsAssignableFrom(type)) return Variant.Type.Object; // We use `IsAssignableFrom` with our helper interfaces to detect generic Godot collections @@ -167,7 +167,7 @@ namespace Godot.NativeInterop } else { - if (typeof(Godot.Object).IsAssignableFrom(type)) + if (typeof(GodotObject).IsAssignableFrom(type)) return Variant.Type.Object; if (typeof(StringName) == type) @@ -176,7 +176,7 @@ namespace Godot.NativeInterop if (typeof(NodePath) == type) return Variant.Type.NodePath; - if (typeof(RID) == type) + if (typeof(Rid) == type) return Variant.Type.Rid; if (typeof(Collections.Dictionary) == type) @@ -232,7 +232,7 @@ namespace Godot.NativeInterop var gcHandle = CustomGCHandle.AllocStrong(p_managed_callable.Delegate); IntPtr objectPtr = p_managed_callable.Target != null ? - Object.GetPtr(p_managed_callable.Target) : + GodotObject.GetPtr(p_managed_callable.Target) : IntPtr.Zero; unsafe @@ -310,7 +310,7 @@ namespace Godot.NativeInterop public static Signal ConvertSignalToManaged(in godot_signal p_signal) { - var owner = GD.InstanceFromId(p_signal.ObjectId); + var owner = GodotObject.InstanceFromId(p_signal.ObjectId); var name = StringName.CreateTakingOwnershipOfDisposableValue( NativeFuncs.godotsharp_string_name_new_copy(p_signal.Name)); return new Signal(owner, name); @@ -319,7 +319,7 @@ namespace Godot.NativeInterop // Array internal static T[] ConvertNativeGodotArrayToSystemArrayOfGodotObjectType<T>(in godot_array p_array) - where T : Godot.Object + where T : GodotObject { var array = Collections.Array.CreateTakingOwnershipOfDisposableValue( NativeFuncs.godotsharp_array_new_copy(p_array)); @@ -361,16 +361,16 @@ namespace Godot.NativeInterop return ret; } - internal static RID[] ConvertNativeGodotArrayToSystemArrayOfRID(in godot_array p_array) + internal static Rid[] ConvertNativeGodotArrayToSystemArrayOfRid(in godot_array p_array) { var array = Collections.Array.CreateTakingOwnershipOfDisposableValue( NativeFuncs.godotsharp_array_new_copy(p_array)); int length = array.Count; - var ret = new RID[length]; + var ret = new Rid[length]; for (int i = 0; i < length; i++) - ret[i] = array[i].AsRID(); + ret[i] = array[i].AsRid(); return ret; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs index 57488bd586..3d72ee0036 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs @@ -184,7 +184,7 @@ namespace Godot.NativeInterop public static partial void godotsharp_variant_new_projection(out godot_variant r_dest, in Projection p_proj); - public static partial void godotsharp_variant_new_aabb(out godot_variant r_dest, in AABB p_aabb); + public static partial void godotsharp_variant_new_aabb(out godot_variant r_dest, in Aabb p_aabb); public static partial void godotsharp_variant_new_dictionary(out godot_variant r_dest, in godot_dictionary p_dict); @@ -228,27 +228,27 @@ namespace Godot.NativeInterop public static partial Vector2 godotsharp_variant_as_vector2(in godot_variant p_self); - public static partial Vector2i godotsharp_variant_as_vector2i(in godot_variant p_self); + public static partial Vector2I godotsharp_variant_as_vector2i(in godot_variant p_self); public static partial Rect2 godotsharp_variant_as_rect2(in godot_variant p_self); - public static partial Rect2i godotsharp_variant_as_rect2i(in godot_variant p_self); + public static partial Rect2I godotsharp_variant_as_rect2i(in godot_variant p_self); public static partial Vector3 godotsharp_variant_as_vector3(in godot_variant p_self); - public static partial Vector3i godotsharp_variant_as_vector3i(in godot_variant p_self); + public static partial Vector3I godotsharp_variant_as_vector3i(in godot_variant p_self); public static partial Transform2D godotsharp_variant_as_transform2d(in godot_variant p_self); public static partial Vector4 godotsharp_variant_as_vector4(in godot_variant p_self); - public static partial Vector4i godotsharp_variant_as_vector4i(in godot_variant p_self); + public static partial Vector4I godotsharp_variant_as_vector4i(in godot_variant p_self); public static partial Plane godotsharp_variant_as_plane(in godot_variant p_self); public static partial Quaternion godotsharp_variant_as_quaternion(in godot_variant p_self); - public static partial AABB godotsharp_variant_as_aabb(in godot_variant p_self); + public static partial Aabb godotsharp_variant_as_aabb(in godot_variant p_self); public static partial Basis godotsharp_variant_as_basis(in godot_variant p_self); @@ -262,7 +262,7 @@ namespace Godot.NativeInterop public static partial godot_node_path godotsharp_variant_as_node_path(in godot_variant p_self); - public static partial RID godotsharp_variant_as_rid(in godot_variant p_self); + public static partial Rid godotsharp_variant_as_rid(in godot_variant p_self); public static partial godot_callable godotsharp_variant_as_callable(in godot_variant p_self); @@ -365,19 +365,44 @@ namespace Godot.NativeInterop public static partial int godotsharp_array_add(ref godot_array p_self, in godot_variant p_item); + public static partial int godotsharp_array_add_range(ref godot_array p_self, in godot_array p_collection); + + public static partial int godotsharp_array_binary_search(ref godot_array p_self, int p_index, int p_count, in godot_variant p_value); + public static partial void godotsharp_array_duplicate(ref godot_array p_self, godot_bool p_deep, out godot_array r_dest); - public static partial int godotsharp_array_index_of(ref godot_array p_self, in godot_variant p_item); + public static partial void godotsharp_array_fill(ref godot_array p_self, in godot_variant p_value); + + public static partial int godotsharp_array_index_of(ref godot_array p_self, in godot_variant p_item, int p_index = 0); public static partial void godotsharp_array_insert(ref godot_array p_self, int p_index, in godot_variant p_item); + public static partial int godotsharp_array_last_index_of(ref godot_array p_self, in godot_variant p_item, int p_index); + + public static partial void godotsharp_array_make_read_only(ref godot_array p_self); + + public static partial void godotsharp_array_max(ref godot_array p_self, out godot_variant r_value); + + public static partial void godotsharp_array_min(ref godot_array p_self, out godot_variant r_value); + + public static partial void godotsharp_array_pick_random(ref godot_array p_self, out godot_variant r_value); + + public static partial godot_bool godotsharp_array_recursive_equal(ref godot_array p_self, in godot_array p_other); + public static partial void godotsharp_array_remove_at(ref godot_array p_self, int p_index); public static partial Error godotsharp_array_resize(ref godot_array p_self, int p_new_size); + public static partial void godotsharp_array_reverse(ref godot_array p_self); + public static partial void godotsharp_array_shuffle(ref godot_array p_self); + public static partial void godotsharp_array_slice(ref godot_array p_self, int p_start, int p_end, + int p_step, godot_bool p_deep, out godot_array r_dest); + + public static partial void godotsharp_array_sort(ref godot_array p_self); + public static partial void godotsharp_array_to_string(ref godot_array p_self, out godot_string r_str); // Dictionary @@ -409,9 +434,15 @@ namespace Godot.NativeInterop public static partial void godotsharp_dictionary_duplicate(ref godot_dictionary p_self, godot_bool p_deep, out godot_dictionary r_dest); + public static partial void godotsharp_dictionary_merge(ref godot_dictionary p_self, in godot_dictionary p_dictionary, godot_bool p_overwrite); + + public static partial godot_bool godotsharp_dictionary_recursive_equal(ref godot_dictionary p_self, in godot_dictionary p_other); + public static partial godot_bool godotsharp_dictionary_remove_key(ref godot_dictionary p_self, in godot_variant p_key); + public static partial void godotsharp_dictionary_make_read_only(ref godot_dictionary p_self); + public static partial void godotsharp_dictionary_to_string(ref godot_dictionary p_self, out godot_string r_str); // StringExtensions @@ -451,6 +482,10 @@ namespace Godot.NativeInterop public static partial godot_bool godotsharp_node_path_is_absolute(in godot_node_path p_self); + public static partial godot_bool godotsharp_node_path_equals(in godot_node_path p_self, in godot_node_path p_other); + + public static partial int godotsharp_node_path_hash(in godot_node_path p_self); + // GD, etc internal static partial void godotsharp_bytes_to_var(in godot_packed_byte_array p_bytes, @@ -494,8 +529,6 @@ namespace Godot.NativeInterop internal static partial void godotsharp_weakref(IntPtr p_obj, out godot_ref r_weak_ref); - internal static partial void godotsharp_str(in godot_array p_what, out godot_string r_ret); - internal static partial void godotsharp_str_to_var(in godot_string p_str, out godot_variant r_ret); internal static partial void godotsharp_var_to_bytes(in godot_variant p_what, godot_bool p_full_objects, 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 9f0b55431b..44ec16dca9 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.extended.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.extended.cs @@ -18,20 +18,20 @@ namespace Godot.NativeInterop return new godot_variant() { Float = src.Float, Type = Variant.Type.Float }; case Variant.Type.Vector2: return new godot_variant() { Vector2 = src.Vector2, Type = Variant.Type.Vector2 }; - case Variant.Type.Vector2i: - return new godot_variant() { Vector2i = src.Vector2i, Type = Variant.Type.Vector2i }; + case Variant.Type.Vector2I: + return new godot_variant() { Vector2I = src.Vector2I, Type = Variant.Type.Vector2I }; case Variant.Type.Rect2: return new godot_variant() { Rect2 = src.Rect2, Type = Variant.Type.Rect2 }; - case Variant.Type.Rect2i: - return new godot_variant() { Rect2i = src.Rect2i, Type = Variant.Type.Rect2i }; + case Variant.Type.Rect2I: + return new godot_variant() { Rect2I = src.Rect2I, Type = Variant.Type.Rect2I }; case Variant.Type.Vector3: return new godot_variant() { Vector3 = src.Vector3, Type = Variant.Type.Vector3 }; - case Variant.Type.Vector3i: - return new godot_variant() { Vector3i = src.Vector3i, Type = Variant.Type.Vector3i }; + case Variant.Type.Vector3I: + return new godot_variant() { Vector3I = src.Vector3I, Type = Variant.Type.Vector3I }; case Variant.Type.Vector4: return new godot_variant() { Vector4 = src.Vector4, Type = Variant.Type.Vector4 }; - case Variant.Type.Vector4i: - return new godot_variant() { Vector4i = src.Vector4i, Type = Variant.Type.Vector4i }; + case Variant.Type.Vector4I: + return new godot_variant() { Vector4I = src.Vector4I, Type = Variant.Type.Vector4I }; case Variant.Type.Plane: return new godot_variant() { Plane = src.Plane, Type = Variant.Type.Plane }; case Variant.Type.Quaternion: @@ -39,7 +39,7 @@ namespace Godot.NativeInterop case Variant.Type.Color: return new godot_variant() { Color = src.Color, Type = Variant.Type.Color }; case Variant.Type.Rid: - return new godot_variant() { RID = src.RID, Type = Variant.Type.Rid }; + return new godot_variant() { Rid = src.Rid, Type = Variant.Type.Rid }; } godotsharp_variant_new_copy(out godot_variant ret, src); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs index 9c9258dd9e..e6bcd9393d 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs @@ -10,8 +10,8 @@ namespace Godot.NativeInterop { public static partial class VariantUtils { - public static godot_variant CreateFromRID(RID from) - => new() { Type = Variant.Type.Rid, RID = from }; + public static godot_variant CreateFromRid(Rid from) + => new() { Type = Variant.Type.Rid, Rid = from }; public static godot_variant CreateFromBool(bool from) => new() { Type = Variant.Type.Bool, Bool = from.ToGodotBool() }; @@ -28,26 +28,26 @@ namespace Godot.NativeInterop public static godot_variant CreateFromVector2(Vector2 from) => new() { Type = Variant.Type.Vector2, Vector2 = from }; - public static godot_variant CreateFromVector2i(Vector2i from) - => new() { Type = Variant.Type.Vector2i, Vector2i = from }; + public static godot_variant CreateFromVector2I(Vector2I from) + => new() { Type = Variant.Type.Vector2I, Vector2I = from }; public static godot_variant CreateFromVector3(Vector3 from) => new() { Type = Variant.Type.Vector3, Vector3 = from }; - public static godot_variant CreateFromVector3i(Vector3i from) - => new() { Type = Variant.Type.Vector3i, Vector3i = from }; + public static godot_variant CreateFromVector3I(Vector3I from) + => new() { Type = Variant.Type.Vector3I, Vector3I = from }; public static godot_variant CreateFromVector4(Vector4 from) => new() { Type = Variant.Type.Vector4, Vector4 = from }; - public static godot_variant CreateFromVector4i(Vector4i from) - => new() { Type = Variant.Type.Vector4i, Vector4i = from }; + public static godot_variant CreateFromVector4I(Vector4I from) + => new() { Type = Variant.Type.Vector4I, Vector4I = from }; public static godot_variant CreateFromRect2(Rect2 from) => new() { Type = Variant.Type.Rect2, Rect2 = from }; - public static godot_variant CreateFromRect2i(Rect2i from) - => new() { Type = Variant.Type.Rect2i, Rect2i = from }; + public static godot_variant CreateFromRect2I(Rect2I from) + => new() { Type = Variant.Type.Rect2I, Rect2I = from }; public static godot_variant CreateFromQuaternion(Quaternion from) => new() { Type = Variant.Type.Quaternion, Quaternion = from }; @@ -82,7 +82,7 @@ namespace Godot.NativeInterop return ret; } - public static godot_variant CreateFromAABB(AABB from) + public static godot_variant CreateFromAabb(Aabb from) { NativeFuncs.godotsharp_variant_new_aabb(out godot_variant ret, from); return ret; @@ -237,11 +237,11 @@ namespace Godot.NativeInterop public static godot_variant CreateFromSystemArrayOfNodePath(Span<NodePath> from) => CreateFromArray(new Collections.Array(from)); - public static godot_variant CreateFromSystemArrayOfRID(Span<RID> from) + public static godot_variant CreateFromSystemArrayOfRid(Span<Rid> from) => CreateFromArray(new Collections.Array(from)); // ReSharper disable once RedundantNameQualifier - public static godot_variant CreateFromSystemArrayOfGodotObject(Godot.Object[]? from) + public static godot_variant CreateFromSystemArrayOfGodotObject(GodotObject[]? from) { if (from == null) return default; // Nil @@ -260,7 +260,7 @@ namespace Godot.NativeInterop => from != null ? CreateFromArray((godot_array)from.NativeValue) : default; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static godot_variant CreateFromArray<T>(Array<T>? from) + public static godot_variant CreateFromArray<[MustBeVariant] T>(Array<T>? from) => from != null ? CreateFromArray((godot_array)((Collections.Array)from).NativeValue) : default; public static godot_variant CreateFromDictionary(godot_dictionary from) @@ -274,7 +274,7 @@ namespace Godot.NativeInterop => from != null ? CreateFromDictionary((godot_dictionary)from.NativeValue) : default; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static godot_variant CreateFromDictionary<TKey, TValue>(Dictionary<TKey, TValue>? from) + public static godot_variant CreateFromDictionary<[MustBeVariant] TKey, [MustBeVariant] TValue>(Dictionary<TKey, TValue>? from) => from != null ? CreateFromDictionary((godot_dictionary)((Dictionary)from).NativeValue) : default; public static godot_variant CreateFromStringName(godot_string_name from) @@ -307,8 +307,8 @@ namespace Godot.NativeInterop [MethodImpl(MethodImplOptions.AggressiveInlining)] // ReSharper disable once RedundantNameQualifier - public static godot_variant CreateFromGodotObject(Godot.Object? from) - => from != null ? CreateFromGodotObjectPtr(Object.GetPtr(from)) : default; + public static godot_variant CreateFromGodotObject(GodotObject? from) + => from != null ? CreateFromGodotObjectPtr(GodotObject.GetPtr(from)) : default; // We avoid the internal call if the stored type is the same we want. @@ -375,9 +375,9 @@ namespace Godot.NativeInterop p_var.Vector2 : NativeFuncs.godotsharp_variant_as_vector2(p_var); - public static Vector2i ConvertToVector2i(in godot_variant p_var) - => p_var.Type == Variant.Type.Vector2i ? - p_var.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 Rect2 ConvertToRect2(in godot_variant p_var) @@ -385,13 +385,13 @@ namespace Godot.NativeInterop p_var.Rect2 : NativeFuncs.godotsharp_variant_as_rect2(p_var); - public static Rect2i ConvertToRect2i(in godot_variant p_var) - => p_var.Type == Variant.Type.Rect2i ? - p_var.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(in godot_variant p_var) - => p_var.Type == Variant.Type.Transform2d ? + => p_var.Type == Variant.Type.Transform2D ? *p_var.Transform2D : NativeFuncs.godotsharp_variant_as_transform2d(p_var); @@ -400,9 +400,9 @@ namespace Godot.NativeInterop p_var.Vector3 : NativeFuncs.godotsharp_variant_as_vector3(p_var); - public static Vector3i ConvertToVector3i(in godot_variant p_var) - => p_var.Type == Variant.Type.Vector3i ? - p_var.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(in godot_variant p_var) @@ -410,9 +410,9 @@ namespace Godot.NativeInterop p_var.Vector4 : NativeFuncs.godotsharp_variant_as_vector4(p_var); - public static unsafe Vector4i ConvertToVector4i(in godot_variant p_var) - => p_var.Type == Variant.Type.Vector4i ? - p_var.Vector4i : + 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(in godot_variant p_var) @@ -426,7 +426,7 @@ namespace Godot.NativeInterop NativeFuncs.godotsharp_variant_as_quaternion(p_var); public static unsafe Transform3D ConvertToTransform3D(in godot_variant p_var) - => p_var.Type == Variant.Type.Transform3d ? + => p_var.Type == Variant.Type.Transform3D ? *p_var.Transform3D : NativeFuncs.godotsharp_variant_as_transform3d(p_var); @@ -435,9 +435,9 @@ namespace Godot.NativeInterop *p_var.Projection : NativeFuncs.godotsharp_variant_as_projection(p_var); - public static unsafe AABB ConvertToAABB(in godot_variant p_var) + public static unsafe Aabb ConvertToAabb(in godot_variant p_var) => p_var.Type == Variant.Type.Aabb ? - *p_var.AABB : + *p_var.Aabb : NativeFuncs.godotsharp_variant_as_aabb(p_var); public static Color ConvertToColor(in godot_variant p_var) @@ -450,9 +450,9 @@ namespace Godot.NativeInterop p_var.Plane : NativeFuncs.godotsharp_variant_as_plane(p_var); - public static RID ConvertToRID(in godot_variant p_var) + public static Rid ConvertToRid(in godot_variant p_var) => p_var.Type == Variant.Type.Rid ? - p_var.RID : + p_var.Rid : NativeFuncs.godotsharp_variant_as_rid(p_var); public static IntPtr ConvertToGodotObjectPtr(in godot_variant p_var) @@ -460,7 +460,7 @@ namespace Godot.NativeInterop [MethodImpl(MethodImplOptions.AggressiveInlining)] // ReSharper disable once RedundantNameQualifier - public static Godot.Object ConvertToGodotObject(in godot_variant p_var) + public static GodotObject ConvertToGodotObject(in godot_variant p_var) => InteropUtils.UnmanagedGetManaged(ConvertToGodotObjectPtr(p_var)); public static string ConvertToString(in godot_variant p_var) @@ -526,7 +526,7 @@ namespace Godot.NativeInterop => Collections.Array.CreateTakingOwnershipOfDisposableValue(ConvertToNativeArray(p_var)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Array<T> ConvertToArray<T>(in godot_variant p_var) + public static Array<T> ConvertToArray<[MustBeVariant] T>(in godot_variant p_var) => Array<T>.CreateTakingOwnershipOfDisposableValue(ConvertToNativeArray(p_var)); public static godot_dictionary ConvertToNativeDictionary(in godot_variant p_var) @@ -539,7 +539,7 @@ namespace Godot.NativeInterop => Dictionary.CreateTakingOwnershipOfDisposableValue(ConvertToNativeDictionary(p_var)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Dictionary<TKey, TValue> ConvertToDictionary<TKey, TValue>(in godot_variant p_var) + public static Dictionary<TKey, TValue> ConvertToDictionary<[MustBeVariant] TKey, [MustBeVariant] TValue>(in godot_variant p_var) => Dictionary<TKey, TValue>.CreateTakingOwnershipOfDisposableValue(ConvertToNativeDictionary(p_var)); public static byte[] ConvertAsPackedByteArrayToSystemArray(in godot_variant p_var) @@ -608,15 +608,15 @@ namespace Godot.NativeInterop return Marshaling.ConvertNativeGodotArrayToSystemArrayOfNodePath(godotArray); } - public static RID[] ConvertToSystemArrayOfRID(in godot_variant p_var) + public static Rid[] ConvertToSystemArrayOfRid(in godot_variant p_var) { using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var); - return Marshaling.ConvertNativeGodotArrayToSystemArrayOfRID(godotArray); + return Marshaling.ConvertNativeGodotArrayToSystemArrayOfRid(godotArray); } public static T[] ConvertToSystemArrayOfGodotObject<T>(in godot_variant p_var) // ReSharper disable once RedundantNameQualifier - where T : Godot.Object + where T : GodotObject { using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var); return Marshaling.ConvertNativeGodotArrayToSystemArrayOfGodotObjectType<T>(godotArray); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.generic.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.generic.cs index 3d64533269..12b0a47079 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.generic.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.generic.cs @@ -80,14 +80,14 @@ public partial class VariantUtils if (typeof(T) == typeof(Vector2)) return CreateFromVector2(UnsafeAs<Vector2>(from)); - if (typeof(T) == typeof(Vector2i)) - return CreateFromVector2i(UnsafeAs<Vector2i>(from)); + if (typeof(T) == typeof(Vector2I)) + return CreateFromVector2I(UnsafeAs<Vector2I>(from)); if (typeof(T) == typeof(Rect2)) return CreateFromRect2(UnsafeAs<Rect2>(from)); - if (typeof(T) == typeof(Rect2i)) - return CreateFromRect2i(UnsafeAs<Rect2i>(from)); + if (typeof(T) == typeof(Rect2I)) + return CreateFromRect2I(UnsafeAs<Rect2I>(from)); if (typeof(T) == typeof(Transform2D)) return CreateFromTransform2D(UnsafeAs<Transform2D>(from)); @@ -98,8 +98,8 @@ public partial class VariantUtils if (typeof(T) == typeof(Vector3)) return CreateFromVector3(UnsafeAs<Vector3>(from)); - if (typeof(T) == typeof(Vector3i)) - return CreateFromVector3i(UnsafeAs<Vector3i>(from)); + if (typeof(T) == typeof(Vector3I)) + return CreateFromVector3I(UnsafeAs<Vector3I>(from)); if (typeof(T) == typeof(Basis)) return CreateFromBasis(UnsafeAs<Basis>(from)); @@ -113,11 +113,11 @@ public partial class VariantUtils if (typeof(T) == typeof(Vector4)) return CreateFromVector4(UnsafeAs<Vector4>(from)); - if (typeof(T) == typeof(Vector4i)) - return CreateFromVector4i(UnsafeAs<Vector4i>(from)); + if (typeof(T) == typeof(Vector4I)) + return CreateFromVector4I(UnsafeAs<Vector4I>(from)); - if (typeof(T) == typeof(AABB)) - return CreateFromAABB(UnsafeAs<AABB>(from)); + if (typeof(T) == typeof(Aabb)) + return CreateFromAabb(UnsafeAs<Aabb>(from)); if (typeof(T) == typeof(Color)) return CreateFromColor(UnsafeAs<Color>(from)); @@ -167,8 +167,8 @@ public partial class VariantUtils if (typeof(T) == typeof(NodePath[])) return CreateFromSystemArrayOfNodePath(UnsafeAs<NodePath[]>(from)); - if (typeof(T) == typeof(RID[])) - return CreateFromSystemArrayOfRID(UnsafeAs<RID[]>(from)); + if (typeof(T) == typeof(Rid[])) + return CreateFromSystemArrayOfRid(UnsafeAs<Rid[]>(from)); if (typeof(T) == typeof(StringName)) return CreateFromStringName(UnsafeAs<StringName>(from)); @@ -176,8 +176,8 @@ public partial class VariantUtils if (typeof(T) == typeof(NodePath)) return CreateFromNodePath(UnsafeAs<NodePath>(from)); - if (typeof(T) == typeof(RID)) - return CreateFromRID(UnsafeAs<RID>(from)); + if (typeof(T) == typeof(Rid)) + return CreateFromRid(UnsafeAs<Rid>(from)); if (typeof(T) == typeof(Godot.Collections.Dictionary)) return CreateFromDictionary(UnsafeAs<Godot.Collections.Dictionary>(from)); @@ -192,8 +192,8 @@ public partial class VariantUtils // `typeof(X).IsAssignableFrom(typeof(T))` is optimized away - if (typeof(Godot.Object).IsAssignableFrom(typeof(T))) - return CreateFromGodotObject(UnsafeAs<Godot.Object>(from)); + if (typeof(GodotObject).IsAssignableFrom(typeof(T))) + return CreateFromGodotObject(UnsafeAs<GodotObject>(from)); // `typeof(T).IsValueType` is optimized away // `typeof(T).IsEnum` is NOT optimized away: https://github.com/dotnet/runtime/issues/67113 @@ -269,14 +269,14 @@ public partial class VariantUtils if (typeof(T) == typeof(Vector2)) return UnsafeAsT(ConvertToVector2(variant)); - if (typeof(T) == typeof(Vector2i)) - return UnsafeAsT(ConvertToVector2i(variant)); + if (typeof(T) == typeof(Vector2I)) + return UnsafeAsT(ConvertToVector2I(variant)); if (typeof(T) == typeof(Rect2)) return UnsafeAsT(ConvertToRect2(variant)); - if (typeof(T) == typeof(Rect2i)) - return UnsafeAsT(ConvertToRect2i(variant)); + if (typeof(T) == typeof(Rect2I)) + return UnsafeAsT(ConvertToRect2I(variant)); if (typeof(T) == typeof(Transform2D)) return UnsafeAsT(ConvertToTransform2D(variant)); @@ -284,8 +284,8 @@ public partial class VariantUtils if (typeof(T) == typeof(Vector3)) return UnsafeAsT(ConvertToVector3(variant)); - if (typeof(T) == typeof(Vector3i)) - return UnsafeAsT(ConvertToVector3i(variant)); + if (typeof(T) == typeof(Vector3I)) + return UnsafeAsT(ConvertToVector3I(variant)); if (typeof(T) == typeof(Basis)) return UnsafeAsT(ConvertToBasis(variant)); @@ -302,11 +302,11 @@ public partial class VariantUtils if (typeof(T) == typeof(Vector4)) return UnsafeAsT(ConvertToVector4(variant)); - if (typeof(T) == typeof(Vector4i)) - return UnsafeAsT(ConvertToVector4i(variant)); + if (typeof(T) == typeof(Vector4I)) + return UnsafeAsT(ConvertToVector4I(variant)); - if (typeof(T) == typeof(AABB)) - return UnsafeAsT(ConvertToAABB(variant)); + if (typeof(T) == typeof(Aabb)) + return UnsafeAsT(ConvertToAabb(variant)); if (typeof(T) == typeof(Color)) return UnsafeAsT(ConvertToColor(variant)); @@ -356,8 +356,8 @@ public partial class VariantUtils if (typeof(T) == typeof(NodePath[])) return UnsafeAsT(ConvertToSystemArrayOfNodePath(variant)); - if (typeof(T) == typeof(RID[])) - return UnsafeAsT(ConvertToSystemArrayOfRID(variant)); + if (typeof(T) == typeof(Rid[])) + return UnsafeAsT(ConvertToSystemArrayOfRid(variant)); if (typeof(T) == typeof(StringName)) return UnsafeAsT(ConvertToStringName(variant)); @@ -365,8 +365,8 @@ public partial class VariantUtils if (typeof(T) == typeof(NodePath)) return UnsafeAsT(ConvertToNodePath(variant)); - if (typeof(T) == typeof(RID)) - return UnsafeAsT(ConvertToRID(variant)); + if (typeof(T) == typeof(Rid)) + return UnsafeAsT(ConvertToRid(variant)); if (typeof(T) == typeof(Godot.Collections.Dictionary)) return UnsafeAsT(ConvertToDictionary(variant)); @@ -381,7 +381,7 @@ public partial class VariantUtils // `typeof(X).IsAssignableFrom(typeof(T))` is optimized away - if (typeof(Godot.Object).IsAssignableFrom(typeof(T))) + if (typeof(GodotObject).IsAssignableFrom(typeof(T))) return (T)(object)ConvertToGodotObject(variant); // `typeof(T).IsValueType` is optimized away diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs index b02bd167a1..f216fb7ea3 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs @@ -39,7 +39,7 @@ namespace Godot /// new NodePath("/root/MyAutoload"); // If you have an autoloaded node or scene. /// </code> /// </example> - public sealed class NodePath : IDisposable + public sealed class NodePath : IDisposable, IEquatable<NodePath> { internal godot_node_path.movable NativeValue; @@ -288,5 +288,37 @@ namespace Godot /// </summary> /// <returns>If the <see cref="NodePath"/> is empty.</returns> public bool IsEmpty => NativeValue.DangerousSelfRef.IsEmpty; + + public static bool operator ==(NodePath left, NodePath right) + { + if (left is null) + return right is null; + return left.Equals(right); + } + + public static bool operator !=(NodePath left, NodePath right) + { + return !(left == right); + } + + public bool Equals(NodePath other) + { + if (other is null) + return false; + var self = (godot_node_path)NativeValue; + var otherNative = (godot_node_path)other.NativeValue; + return NativeFuncs.godotsharp_node_path_equals(self, otherNative).ToBool(); + } + + public override bool Equals(object obj) + { + return ReferenceEquals(this, obj) || (obj is NodePath other && Equals(other)); + } + + public override int GetHashCode() + { + var self = (godot_node_path)NativeValue; + return NativeFuncs.godotsharp_node_path_hash(self); + } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs index 8a125e3c73..55b7a83fc2 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs @@ -13,13 +13,14 @@ namespace Godot public struct Plane : IEquatable<Plane> { private Vector3 _normal; + private real_t _d; /// <summary> /// The normal of the plane, which must be a unit vector. /// In the scalar equation of the plane <c>ax + by + cz = d</c>, this is /// the vector <c>(a, b, c)</c>, where <c>d</c> is the <see cref="D"/> property. /// </summary> - /// <value>Equivalent to <see cref="x"/>, <see cref="y"/>, and <see cref="z"/>.</value> + /// <value>Equivalent to <see cref="X"/>, <see cref="Y"/>, and <see cref="Z"/>.</value> public Vector3 Normal { readonly get { return _normal; } @@ -27,18 +28,32 @@ namespace Godot } /// <summary> + /// The distance from the origin to the plane (in the direction of + /// <see cref="Normal"/>). This value is typically non-negative. + /// In the scalar equation of the plane <c>ax + by + cz = d</c>, + /// this is <c>d</c>, while the <c>(a, b, c)</c> coordinates are represented + /// by the <see cref="Normal"/> property. + /// </summary> + /// <value>The plane's distance from the origin.</value> + public real_t D + { + readonly get { return _d; } + set { _d = value; } + } + + /// <summary> /// The X component of the plane's normal vector. /// </summary> /// <value>Equivalent to <see cref="Normal"/>'s X value.</value> - public real_t x + public real_t X { readonly get { - return _normal.x; + return _normal.X; } set { - _normal.x = value; + _normal.X = value; } } @@ -46,15 +61,15 @@ namespace Godot /// The Y component of the plane's normal vector. /// </summary> /// <value>Equivalent to <see cref="Normal"/>'s Y value.</value> - public real_t y + public real_t Y { readonly get { - return _normal.y; + return _normal.Y; } set { - _normal.y = value; + _normal.Y = value; } } @@ -62,36 +77,26 @@ namespace Godot /// The Z component of the plane's normal vector. /// </summary> /// <value>Equivalent to <see cref="Normal"/>'s Z value.</value> - public real_t z + public real_t Z { readonly get { - return _normal.z; + return _normal.Z; } set { - _normal.z = value; + _normal.Z = value; } } /// <summary> - /// The distance from the origin to the plane (in the direction of - /// <see cref="Normal"/>). This value is typically non-negative. - /// In the scalar equation of the plane <c>ax + by + cz = d</c>, - /// this is <c>d</c>, while the <c>(a, b, c)</c> coordinates are represented - /// by the <see cref="Normal"/> property. - /// </summary> - /// <value>The plane's distance from the origin.</value> - public real_t D { get; set; } - - /// <summary> /// Returns the shortest distance from this plane to the position <paramref name="point"/>. /// </summary> /// <param name="point">The position to use for the calculation.</param> /// <returns>The shortest distance.</returns> public readonly real_t DistanceTo(Vector3 point) { - return _normal.Dot(point) - D; + return _normal.Dot(point) - _d; } /// <summary> @@ -101,7 +106,7 @@ namespace Godot /// <value>Equivalent to <see cref="Normal"/> multiplied by <see cref="D"/>.</value> public readonly Vector3 GetCenter() { - return _normal * D; + return _normal * _d; } /// <summary> @@ -113,7 +118,7 @@ namespace Godot /// <returns>A <see langword="bool"/> for whether or not the plane has the point.</returns> public readonly bool HasPoint(Vector3 point, real_t tolerance = Mathf.Epsilon) { - real_t dist = _normal.Dot(point) - D; + real_t dist = _normal.Dot(point) - _d; return Mathf.Abs(dist) <= tolerance; } @@ -133,9 +138,9 @@ namespace Godot return null; } - Vector3 result = (b._normal.Cross(c._normal) * D) + - (c._normal.Cross(_normal) * b.D) + - (_normal.Cross(b._normal) * c.D); + Vector3 result = (b._normal.Cross(c._normal) * _d) + + (c._normal.Cross(_normal) * b._d) + + (_normal.Cross(b._normal) * c._d); return result / denom; } @@ -157,7 +162,7 @@ namespace Godot return null; } - real_t dist = (_normal.Dot(from) - D) / den; + real_t dist = (_normal.Dot(from) - _d) / den; // This is a ray, before the emitting pos (from) does not exist if (dist > Mathf.Epsilon) @@ -186,7 +191,7 @@ namespace Godot return null; } - real_t dist = (_normal.Dot(begin) - D) / den; + real_t dist = (_normal.Dot(begin) - _d) / den; // Only allow dist to be in the range of 0 to 1, with tolerance. if (dist < -Mathf.Epsilon || dist > 1.0f + Mathf.Epsilon) @@ -214,7 +219,7 @@ namespace Godot /// <returns>A <see langword="bool"/> for whether or not the point is above the plane.</returns> public readonly bool IsPointOver(Vector3 point) { - return _normal.Dot(point) > D; + return _normal.Dot(point) > _d; } /// <summary> @@ -230,7 +235,7 @@ namespace Godot return new Plane(0, 0, 0, 0); } - return new Plane(_normal / len, D / len); + return new Plane(_normal / len, _d / len); } /// <summary> @@ -279,7 +284,7 @@ namespace Godot public Plane(real_t a, real_t b, real_t c, real_t d) { _normal = new Vector3(a, b, c); - D = d; + _d = d; } /// <summary> @@ -290,7 +295,7 @@ namespace Godot public Plane(Vector3 normal) { _normal = normal; - D = 0; + _d = 0; } /// <summary> @@ -302,7 +307,7 @@ namespace Godot public Plane(Vector3 normal, real_t d) { _normal = normal; - D = d; + _d = d; } /// <summary> @@ -314,7 +319,7 @@ namespace Godot public Plane(Vector3 normal, Vector3 point) { _normal = normal; - D = _normal.Dot(point); + _d = _normal.Dot(point); } /// <summary> @@ -327,7 +332,7 @@ namespace Godot { _normal = (v1 - v3).Cross(v1 - v2); _normal.Normalize(); - D = _normal.Dot(v1); + _d = _normal.Dot(v1); } /// <summary> @@ -341,7 +346,7 @@ namespace Godot /// <returns>The negated/flipped plane.</returns> public static Plane operator -(Plane plane) { - return new Plane(-plane._normal, -plane.D); + return new Plane(-plane._normal, -plane._d); } /// <summary> @@ -389,7 +394,7 @@ namespace Godot /// <returns>Whether or not the planes are exactly equal.</returns> public readonly bool Equals(Plane other) { - return _normal == other._normal && D == other.D; + return _normal == other._normal && _d == other._d; } /// <summary> @@ -400,7 +405,7 @@ namespace Godot /// <returns>Whether or not the planes are approximately equal.</returns> public readonly bool IsEqualApprox(Plane other) { - return _normal.IsEqualApprox(other._normal) && Mathf.IsEqualApprox(D, other.D); + return _normal.IsEqualApprox(other._normal) && Mathf.IsEqualApprox(_d, other._d); } /// <summary> @@ -409,7 +414,7 @@ namespace Godot /// <returns>A hash code for this plane.</returns> public override readonly int GetHashCode() { - return _normal.GetHashCode() ^ D.GetHashCode(); + return _normal.GetHashCode() ^ _d.GetHashCode(); } /// <summary> @@ -418,7 +423,7 @@ namespace Godot /// <returns>A string representation of this plane.</returns> public override readonly string ToString() { - return $"{_normal}, {D}"; + return $"{_normal}, {_d}"; } /// <summary> @@ -427,7 +432,7 @@ namespace Godot /// <returns>A string representation of this plane.</returns> public readonly string ToString(string format) { - return $"{_normal.ToString(format)}, {D.ToString(format)}"; + return $"{_normal.ToString(format)}, {_d.ToString(format)}"; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs index f11b3c553a..84fc73b87a 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs @@ -49,22 +49,22 @@ namespace Godot /// <summary> /// The projection's X column. Also accessible by using the index position <c>[0]</c>. /// </summary> - public Vector4 x; + public Vector4 X; /// <summary> /// The projection's Y column. Also accessible by using the index position <c>[1]</c>. /// </summary> - public Vector4 y; + public Vector4 Y; /// <summary> /// The projection's Z column. Also accessible by using the index position <c>[2]</c>. /// </summary> - public Vector4 z; + public Vector4 Z; /// <summary> /// The projection's W column. Also accessible by using the index position <c>[3]</c>. /// </summary> - public Vector4 w; + public Vector4 W; /// <summary> /// Access whole columns in the form of <see cref="Vector4"/>. @@ -80,13 +80,13 @@ namespace Godot switch (column) { case 0: - return x; + return X; case 1: - return y; + return Y; case 2: - return z; + return Z; case 3: - return w; + return W; default: throw new ArgumentOutOfRangeException(nameof(column)); } @@ -96,16 +96,16 @@ namespace Godot switch (column) { case 0: - x = value; + X = value; return; case 1: - y = value; + Y = value; return; case 2: - z = value; + Z = value; return; case 3: - w = value; + W = value; return; default: throw new ArgumentOutOfRangeException(nameof(column)); @@ -128,13 +128,13 @@ namespace Godot switch (column) { case 0: - return x[row]; + return X[row]; case 1: - return y[row]; + return Y[row]; case 2: - return z[row]; + return Z[row]; case 3: - return w[row]; + return W[row]; default: throw new ArgumentOutOfRangeException(nameof(column)); } @@ -144,16 +144,16 @@ namespace Godot switch (column) { case 0: - x[row] = value; + X[row] = value; return; case 1: - y[row] = value; + Y[row] = value; return; case 2: - z[row] = value; + Z[row] = value; return; case 3: - w[row] = value; + W[row] = value; return; default: throw new ArgumentOutOfRangeException(nameof(column)); @@ -180,20 +180,20 @@ namespace Godot /// <summary> /// Creates a new <see cref="Projection"/> that scales a given projection to fit around - /// a given <see cref="AABB"/> in projection space. + /// a given <see cref="Aabb"/> in projection space. /// </summary> - /// <param name="aabb">The AABB to fit the projection around.</param> + /// <param name="aabb">The Aabb to fit the projection around.</param> /// <returns>The created projection.</returns> - public static Projection CreateFitAabb(AABB aabb) + public static Projection CreateFitAabb(Aabb aabb) { Vector3 min = aabb.Position; Vector3 max = aabb.Position + aabb.Size; return new Projection( - new Vector4(2 / (max.x - min.x), 0, 0, 0), - new Vector4(0, 2 / (max.y - min.y), 0, 0), - new Vector4(0, 0, 2 / (max.z - min.z), 0), - new Vector4(-(max.x + min.x) / (max.x - min.x), -(max.y + min.y) / (max.y - min.y), -(max.z + min.z) / (max.z - min.z), 1) + new Vector4(2 / (max.X - min.X), 0, 0, 0), + new Vector4(0, 2 / (max.Y - min.Y), 0, 0), + new Vector4(0, 0, 2 / (max.Z - min.Z), 0), + new Vector4(-(max.X + min.X) / (max.X - min.X), -(max.Y + min.Y) / (max.Y - min.Y), -(max.Z + min.Z) / (max.Z - min.Z), 1) ); } @@ -300,7 +300,7 @@ namespace Godot { size *= aspect; } - return CreateFrustum(-size / 2 + offset.x, +size / 2 + offset.x, -size / aspect / 2 + offset.y, +size / aspect / 2 + offset.y, near, far); + return CreateFrustum(-size / 2 + offset.X, +size / 2 + offset.X, -size / aspect / 2 + offset.Y, +size / aspect / 2 + offset.Y, near, far); } /// <summary> @@ -311,10 +311,10 @@ namespace Godot public static Projection CreateLightAtlasRect(Rect2 rect) { return new Projection( - new Vector4(rect.Size.x, 0, 0, 0), - new Vector4(0, rect.Size.y, 0, 0), + new Vector4(rect.Size.X, 0, 0, 0), + new Vector4(0, rect.Size.Y, 0, 0), new Vector4(0, 0, 1, 0), - new Vector4(rect.Position.x, rect.Position.y, 0, 1) + new Vector4(rect.Position.X, rect.Position.Y, 0, 1) ); } @@ -332,13 +332,13 @@ namespace Godot public static Projection CreateOrthogonal(real_t left, real_t right, real_t bottom, real_t top, real_t zNear, real_t zFar) { Projection proj = Projection.Identity; - proj.x.x = (real_t)2.0 / (right - left); - proj.w.x = -((right + left) / (right - left)); - proj.y.y = (real_t)2.0 / (top - bottom); - proj.w.y = -((top + bottom) / (top - bottom)); - proj.z.z = (real_t)(-2.0) / (zFar - zNear); - proj.w.z = -((zFar + zNear) / (zFar - zNear)); - proj.w.w = (real_t)1.0; + proj.X.X = (real_t)2.0 / (right - left); + proj.W.X = -((right + left) / (right - left)); + proj.Y.Y = (real_t)2.0 / (top - bottom); + proj.W.Y = -((top + bottom) / (top - bottom)); + proj.Z.Z = (real_t)(-2.0) / (zFar - zNear); + proj.W.Z = -((zFar + zNear) / (zFar - zNear)); + proj.W.W = (real_t)1.0; return proj; } @@ -392,12 +392,12 @@ namespace Godot Projection proj = Projection.Identity; - proj.x.x = cotangent / aspect; - proj.y.y = cotangent; - proj.z.z = -(zFar + zNear) / deltaZ; - proj.z.w = -1; - proj.w.z = -2 * zNear * zFar / deltaZ; - proj.w.w = 0; + proj.X.X = cotangent / aspect; + proj.Y.Y = cotangent; + proj.Z.Z = -(zFar + zNear) / deltaZ; + proj.Z.W = -1; + proj.W.Z = -2 * zNear * zFar / deltaZ; + proj.W.W = 0; return proj; } @@ -456,7 +456,7 @@ namespace Godot } Projection proj = CreateFrustum(left, right, -ymax, ymax, zNear, zFar); Projection cm = Projection.Identity; - cm.w.x = modeltranslation; + cm.W.X = modeltranslation; return proj * cm; } @@ -469,18 +469,18 @@ namespace Godot /// <returns>The determinant calculated from this projection.</returns> public readonly real_t Determinant() { - return x.w * y.z * z.y * w.x - x.z * y.w * z.y * w.x - - x.w * y.y * z.z * w.x + x.y * y.w * z.z * w.x + - x.z * y.y * z.w * w.x - x.y * y.z * z.w * w.x - - x.w * y.z * z.x * w.y + x.z * y.w * z.x * w.y + - x.w * y.x * z.z * w.y - x.x * y.w * z.z * w.y - - x.z * y.x * z.w * w.y + x.x * y.z * z.w * w.y + - x.w * y.y * z.x * w.z - x.y * y.w * z.x * w.z - - x.w * y.x * z.y * w.z + x.x * y.w * z.y * w.z + - x.y * y.x * z.w * w.z - x.x * y.y * z.w * w.z - - x.z * y.y * z.x * w.w + x.y * y.z * z.x * w.w + - x.z * y.x * z.y * w.w - x.x * y.z * z.y * w.w - - x.y * y.x * z.z * w.w + x.x * y.y * z.z * w.w; + return X.W * Y.Z * Z.Y * W.X - X.Z * Y.W * Z.Y * W.X - + X.W * Y.Y * Z.Z * W.X + X.Y * Y.W * Z.Z * W.X + + X.Z * Y.Y * Z.W * W.X - X.Y * Y.Z * Z.W * W.X - + X.W * Y.Z * Z.X * W.Y + X.Z * Y.W * Z.X * W.Y + + X.W * Y.X * Z.Z * W.Y - X.X * Y.W * Z.Z * W.Y - + X.Z * Y.X * Z.W * W.Y + X.X * Y.Z * Z.W * W.Y + + X.W * Y.Y * Z.X * W.Z - X.Y * Y.W * Z.X * W.Z - + X.W * Y.X * Z.Y * W.Z + X.X * Y.W * Z.Y * W.Z + + X.Y * Y.X * Z.W * W.Z - X.X * Y.Y * Z.W * W.Z - + X.Z * Y.Y * Z.X * W.W + X.Y * Y.Z * Z.X * W.W + + X.Z * Y.X * Z.Y * W.W - X.X * Y.Z * Z.Y * W.W - + X.Y * Y.X * Z.Z * W.W + X.X * Y.Y * Z.Z * W.W; } /// <summary> @@ -490,7 +490,7 @@ namespace Godot public readonly real_t GetAspect() { Vector2 vpHe = GetViewportHalfExtents(); - return vpHe.x / vpHe.y; + return vpHe.X / vpHe.Y; } /// <summary> @@ -499,15 +499,15 @@ namespace Godot /// <returns>The horizontal field of view of this projection.</returns> public readonly real_t GetFov() { - Plane rightPlane = new Plane(x.w - x.x, y.w - y.x, z.w - z.x, -w.w + w.x).Normalized(); - if (z.x == 0 && z.y == 0) + Plane rightPlane = new Plane(X.W - X.X, Y.W - Y.X, Z.W - Z.X, -W.W + W.X).Normalized(); + if (Z.X == 0 && Z.Y == 0) { - return Mathf.RadToDeg(Mathf.Acos(Mathf.Abs(rightPlane.Normal.x))) * (real_t)2.0; + return Mathf.RadToDeg(Mathf.Acos(Mathf.Abs(rightPlane.Normal.X))) * (real_t)2.0; } else { - Plane leftPlane = new Plane(x.w + x.x, y.w + y.x, z.w + z.x, w.w + w.x).Normalized(); - return Mathf.RadToDeg(Mathf.Acos(Mathf.Abs(leftPlane.Normal.x))) + Mathf.RadToDeg(Mathf.Acos(Mathf.Abs(rightPlane.Normal.x))); + Plane leftPlane = new Plane(X.W + X.X, Y.W + Y.X, Z.W + Z.X, W.W + W.X).Normalized(); + return Mathf.RadToDeg(Mathf.Acos(Mathf.Abs(leftPlane.Normal.X))) + Mathf.RadToDeg(Mathf.Acos(Mathf.Abs(rightPlane.Normal.X))); } } @@ -531,12 +531,12 @@ namespace Godot { if (IsOrthogonal()) { - return GetViewportHalfExtents().x; + return GetViewportHalfExtents().X; } else { real_t zn = GetZNear(); - real_t width = GetViewportHalfExtents().x * (real_t)2.0; + real_t width = GetViewportHalfExtents().X * (real_t)2.0; return (real_t)1.0 / (zn / width); } } @@ -551,7 +551,7 @@ namespace Godot { Vector3 result = this * new Vector3(1, 0, -1); - return (int)((result.x * (real_t)0.5 + (real_t)0.5) * forPixelWidth); + return (int)((result.X * (real_t)0.5 + (real_t)0.5) * forPixelWidth); } /// <summary> @@ -567,12 +567,12 @@ namespace Godot { Plane newPlane = plane switch { - Planes.Near => new Plane(x.w + x.z, y.w + y.z, z.w + z.z, w.w + w.z), - Planes.Far => new Plane(x.w - x.z, y.w - y.z, z.w - z.z, w.w - w.z), - Planes.Left => new Plane(x.w + x.x, y.w + y.x, z.w + z.x, w.w + w.x), - Planes.Top => new Plane(x.w - x.y, y.w - y.y, z.w - z.y, w.w - w.y), - Planes.Right => new Plane(x.w - x.x, y.w - y.x, z.w - z.x, w.w - w.x), - Planes.Bottom => new Plane(x.w + x.y, y.w + y.y, z.w + z.y, w.w + w.y), + Planes.Near => new Plane(X.W + X.Z, Y.W + Y.Z, Z.W + Z.Z, W.W + W.Z), + Planes.Far => new Plane(X.W - X.Z, Y.W - Y.Z, Z.W - Z.Z, W.W - W.Z), + Planes.Left => new Plane(X.W + X.X, Y.W + Y.X, Z.W + Z.X, W.W + W.X), + Planes.Top => new Plane(X.W - X.Y, Y.W - Y.Y, Z.W - Z.Y, W.W - W.Y), + Planes.Right => new Plane(X.W - X.X, Y.W - Y.X, Z.W - Z.X, W.W - W.X), + Planes.Bottom => new Plane(X.W + X.Y, Y.W + Y.Y, Z.W + Z.Y, W.W + W.Y), _ => new Plane(), }; newPlane.Normal = -newPlane.Normal; @@ -586,7 +586,7 @@ namespace Godot public readonly Vector2 GetFarPlaneHalfExtents() { var res = GetProjectionPlane(Planes.Far).Intersect3(GetProjectionPlane(Planes.Right), GetProjectionPlane(Planes.Top)); - return new Vector2(res.Value.x, res.Value.y); + return new Vector2(res.Value.X, res.Value.Y); } /// <summary> @@ -597,7 +597,7 @@ namespace Godot public readonly Vector2 GetViewportHalfExtents() { var res = GetProjectionPlane(Planes.Near).Intersect3(GetProjectionPlane(Planes.Right), GetProjectionPlane(Planes.Top)); - return new Vector2(res.Value.x, res.Value.y); + return new Vector2(res.Value.X, res.Value.Y); } /// <summary> @@ -625,7 +625,7 @@ namespace Godot public readonly Projection FlippedY() { Projection proj = this; - proj.y = -proj.y; + proj.Y = -proj.Y; return proj; } @@ -642,8 +642,8 @@ namespace Godot real_t zFar = GetZFar(); real_t zNear = newZNear; real_t deltaZ = zFar - zNear; - proj.z.z = -(zFar + zNear) / deltaZ; - proj.w.z = -2 * zNear * zFar / deltaZ; + proj.Z.Z = -(zFar + zNear) / deltaZ; + proj.W.Z = -2 * zNear * zFar / deltaZ; return proj; } @@ -656,8 +656,8 @@ namespace Godot public readonly Projection JitterOffseted(Vector2 offset) { Projection proj = this; - proj.w.x += offset.x; - proj.w.y += offset.y; + proj.W.X += offset.X; + proj.W.Y += offset.Y; return proj; } @@ -795,7 +795,7 @@ namespace Godot /// <returns>If the projection performs an orthogonal projection.</returns> public readonly bool IsOrthogonal() { - return w.w == (real_t)1.0; + return W.W == (real_t)1.0; } // Constants @@ -835,10 +835,10 @@ namespace Godot /// <param name="w">The W column, or column index 3.</param> public Projection(Vector4 x, Vector4 y, Vector4 z, Vector4 w) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; + X = x; + Y = y; + Z = z; + W = w; } /// <summary> @@ -847,10 +847,10 @@ namespace Godot /// <param name="transform">The <see cref="Transform3D"/>.</param> public Projection(Transform3D transform) { - x = new Vector4(transform.basis.Row0.x, transform.basis.Row1.x, transform.basis.Row2.x, 0); - y = new Vector4(transform.basis.Row0.y, transform.basis.Row1.y, transform.basis.Row2.y, 0); - z = new Vector4(transform.basis.Row0.z, transform.basis.Row1.z, transform.basis.Row2.z, 0); - w = new Vector4(transform.origin.x, transform.origin.y, transform.origin.z, 1); + X = new Vector4(transform.Basis.Row0.X, transform.Basis.Row1.X, transform.Basis.Row2.X, 0); + Y = new Vector4(transform.Basis.Row0.Y, transform.Basis.Row1.Y, transform.Basis.Row2.Y, 0); + Z = new Vector4(transform.Basis.Row0.Z, transform.Basis.Row1.Z, transform.Basis.Row2.Z, 0); + W = new Vector4(transform.Origin.X, transform.Origin.Y, transform.Origin.Z, 1); } /// <summary> @@ -865,25 +865,25 @@ namespace Godot { return new Projection( new Vector4( - left.x.x * right.x.x + left.y.x * right.x.y + left.z.x * right.x.z + left.w.x * right.x.w, - left.x.y * right.x.x + left.y.y * right.x.y + left.z.y * right.x.z + left.w.y * right.x.w, - left.x.z * right.x.x + left.y.z * right.x.y + left.z.z * right.x.z + left.w.z * right.x.w, - left.x.w * right.x.x + left.y.w * right.x.y + left.z.w * right.x.z + left.w.w * right.x.w + left.X.X * right.X.X + left.Y.X * right.X.Y + left.Z.X * right.X.Z + left.W.X * right.X.W, + left.X.Y * right.X.X + left.Y.Y * right.X.Y + left.Z.Y * right.X.Z + left.W.Y * right.X.W, + left.X.Z * right.X.X + left.Y.Z * right.X.Y + left.Z.Z * right.X.Z + left.W.Z * right.X.W, + left.X.W * right.X.X + left.Y.W * right.X.Y + left.Z.W * right.X.Z + left.W.W * right.X.W ), new Vector4( - left.x.x * right.y.x + left.y.x * right.y.y + left.z.x * right.y.z + left.w.x * right.y.w, - left.x.y * right.y.x + left.y.y * right.y.y + left.z.y * right.y.z + left.w.y * right.y.w, - left.x.z * right.y.x + left.y.z * right.y.y + left.z.z * right.y.z + left.w.z * right.y.w, - left.x.w * right.y.x + left.y.w * right.y.y + left.z.w * right.y.z + left.w.w * right.y.w + left.X.X * right.Y.X + left.Y.X * right.Y.Y + left.Z.X * right.Y.Z + left.W.X * right.Y.W, + left.X.Y * right.Y.X + left.Y.Y * right.Y.Y + left.Z.Y * right.Y.Z + left.W.Y * right.Y.W, + left.X.Z * right.Y.X + left.Y.Z * right.Y.Y + left.Z.Z * right.Y.Z + left.W.Z * right.Y.W, + left.X.W * right.Y.X + left.Y.W * right.Y.Y + left.Z.W * right.Y.Z + left.W.W * right.Y.W ), new Vector4( - left.x.x * right.z.x + left.y.x * right.z.y + left.z.x * right.z.z + left.w.x * right.z.w, - left.x.y * right.z.x + left.y.y * right.z.y + left.z.y * right.z.z + left.w.y * right.z.w, - left.x.z * right.z.x + left.y.z * right.z.y + left.z.z * right.z.z + left.w.z * right.z.w, - left.x.w * right.z.x + left.y.w * right.z.y + left.z.w * right.z.z + left.w.w * right.z.w + left.X.X * right.Z.X + left.Y.X * right.Z.Y + left.Z.X * right.Z.Z + left.W.X * right.Z.W, + left.X.Y * right.Z.X + left.Y.Y * right.Z.Y + left.Z.Y * right.Z.Z + left.W.Y * right.Z.W, + left.X.Z * right.Z.X + left.Y.Z * right.Z.Y + left.Z.Z * right.Z.Z + left.W.Z * right.Z.W, + left.X.W * right.Z.X + left.Y.W * right.Z.Y + left.Z.W * right.Z.Z + left.W.W * right.Z.W ), new Vector4( - left.x.x * right.w.x + left.y.x * right.w.y + left.z.x * right.w.z + left.w.x * right.w.w, - left.x.y * right.w.x + left.y.y * right.w.y + left.z.y * right.w.z + left.w.y * right.w.w, - left.x.z * right.w.x + left.y.z * right.w.y + left.z.z * right.w.z + left.w.z * right.w.w, - left.x.w * right.w.x + left.y.w * right.w.y + left.z.w * right.w.z + left.w.w * right.w.w + left.X.X * right.W.X + left.Y.X * right.W.Y + left.Z.X * right.W.Z + left.W.X * right.W.W, + left.X.Y * right.W.X + left.Y.Y * right.W.Y + left.Z.Y * right.W.Z + left.W.Y * right.W.W, + left.X.Z * right.W.X + left.Y.Z * right.W.Y + left.Z.Z * right.W.Z + left.W.Z * right.W.W, + left.X.W * right.W.X + left.Y.W * right.W.Y + left.Z.W * right.W.Z + left.W.W * right.W.W ) ); } @@ -897,10 +897,10 @@ namespace Godot public static Vector4 operator *(Projection proj, Vector4 vector) { return new Vector4( - proj.x.x * vector.x + proj.y.x * vector.y + proj.z.x * vector.z + proj.w.x * vector.w, - proj.x.y * vector.x + proj.y.y * vector.y + proj.z.y * vector.z + proj.w.y * vector.w, - proj.x.z * vector.x + proj.y.z * vector.y + proj.z.z * vector.z + proj.w.z * vector.w, - proj.x.w * vector.x + proj.y.w * vector.y + proj.z.w * vector.z + proj.w.w * vector.w + proj.X.X * vector.X + proj.Y.X * vector.Y + proj.Z.X * vector.Z + proj.W.X * vector.W, + proj.X.Y * vector.X + proj.Y.Y * vector.Y + proj.Z.Y * vector.Z + proj.W.Y * vector.W, + proj.X.Z * vector.X + proj.Y.Z * vector.Y + proj.Z.Z * vector.Z + proj.W.Z * vector.W, + proj.X.W * vector.X + proj.Y.W * vector.Y + proj.Z.W * vector.Z + proj.W.W * vector.W ); } @@ -913,10 +913,10 @@ namespace Godot public static Vector4 operator *(Vector4 vector, Projection proj) { return new Vector4( - proj.x.x * vector.x + proj.x.y * vector.y + proj.x.z * vector.z + proj.x.w * vector.w, - proj.y.x * vector.x + proj.y.y * vector.y + proj.y.z * vector.z + proj.y.w * vector.w, - proj.z.x * vector.x + proj.z.y * vector.y + proj.z.z * vector.z + proj.z.w * vector.w, - proj.w.x * vector.x + proj.w.y * vector.y + proj.w.z * vector.z + proj.w.w * vector.w + proj.X.X * vector.X + proj.X.Y * vector.Y + proj.X.Z * vector.Z + proj.X.W * vector.W, + proj.Y.X * vector.X + proj.Y.Y * vector.Y + proj.Y.Z * vector.Z + proj.Y.W * vector.W, + proj.Z.X * vector.X + proj.Z.Y * vector.Y + proj.Z.Z * vector.Z + proj.Z.W * vector.W, + proj.W.X * vector.X + proj.W.Y * vector.Y + proj.W.Z * vector.Z + proj.W.W * vector.W ); } @@ -929,11 +929,11 @@ namespace Godot public static Vector3 operator *(Projection proj, Vector3 vector) { Vector3 ret = new Vector3( - proj.x.x * vector.x + proj.y.x * vector.y + proj.z.x * vector.z + proj.w.x, - proj.x.y * vector.x + proj.y.y * vector.y + proj.z.y * vector.z + proj.w.y, - proj.x.z * vector.x + proj.y.z * vector.y + proj.z.z * vector.z + proj.w.z + proj.X.X * vector.X + proj.Y.X * vector.Y + proj.Z.X * vector.Z + proj.W.X, + proj.X.Y * vector.X + proj.Y.Y * vector.Y + proj.Z.Y * vector.Z + proj.W.Y, + proj.X.Z * vector.X + proj.Y.Z * vector.Y + proj.Z.Z * vector.Z + proj.W.Z ); - return ret / (proj.x.w * vector.x + proj.y.w * vector.y + proj.z.w * vector.z + proj.w.w); + return ret / (proj.X.W * vector.X + proj.Y.W * vector.Y + proj.Z.W * vector.Z + proj.W.W); } /// <summary> @@ -966,11 +966,11 @@ namespace Godot { return new Transform3D( new Basis( - new Vector3(proj.x.x, proj.x.y, proj.x.z), - new Vector3(proj.y.x, proj.y.y, proj.y.z), - new Vector3(proj.z.x, proj.z.y, proj.z.z) + new Vector3(proj.X.X, proj.X.Y, proj.X.Z), + new Vector3(proj.Y.X, proj.Y.Y, proj.Y.Z), + new Vector3(proj.Z.X, proj.Z.Y, proj.Z.Z) ), - new Vector3(proj.w.x, proj.w.y, proj.w.z) + new Vector3(proj.W.X, proj.W.Y, proj.W.Z) ); } @@ -992,7 +992,7 @@ namespace Godot /// <returns>Whether or not the projections are exactly equal.</returns> public readonly bool Equals(Projection other) { - return x == other.x && y == other.y && z == other.z && w == other.w; + return X == other.X && Y == other.Y && Z == other.Z && W == other.W; } /// <summary> @@ -1001,7 +1001,7 @@ namespace Godot /// <returns>A hash code for this projection.</returns> public override readonly int GetHashCode() { - return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode(); + return Y.GetHashCode() ^ X.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode(); } /// <summary> @@ -1010,7 +1010,7 @@ namespace Godot /// <returns>A string representation of this projection.</returns> public override readonly string ToString() { - return $"{x.x}, {x.y}, {x.z}, {x.w}\n{y.x}, {y.y}, {y.z}, {y.w}\n{z.x}, {z.y}, {z.z}, {z.w}\n{w.x}, {w.y}, {w.z}, {w.w}\n"; + return $"{X.X}, {X.Y}, {X.Z}, {X.W}\n{Y.X}, {Y.Y}, {Y.Z}, {Y.W}\n{Z.X}, {Z.Y}, {Z.Z}, {Z.W}\n{W.X}, {W.Y}, {W.Z}, {W.W}\n"; } /// <summary> @@ -1019,10 +1019,10 @@ namespace Godot /// <returns>A string representation of this projection.</returns> public readonly string ToString(string format) { - return $"{x.x.ToString(format)}, {x.y.ToString(format)}, {x.z.ToString(format)}, {x.w.ToString(format)}\n" + - $"{y.x.ToString(format)}, {y.y.ToString(format)}, {y.z.ToString(format)}, {y.w.ToString(format)}\n" + - $"{z.x.ToString(format)}, {z.y.ToString(format)}, {z.z.ToString(format)}, {z.w.ToString(format)}\n" + - $"{w.x.ToString(format)}, {w.y.ToString(format)}, {w.z.ToString(format)}, {w.w.ToString(format)}\n"; + return $"{X.X.ToString(format)}, {X.Y.ToString(format)}, {X.Z.ToString(format)}, {X.W.ToString(format)}\n" + + $"{Y.X.ToString(format)}, {Y.Y.ToString(format)}, {Y.Z.ToString(format)}, {Y.W.ToString(format)}\n" + + $"{Z.X.ToString(format)}, {Z.Y.ToString(format)}, {Z.Z.ToString(format)}, {Z.W.ToString(format)}\n" + + $"{W.X.ToString(format)}, {W.Y.ToString(format)}, {W.Z.ToString(format)}, {W.W.ToString(format)}\n"; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs index 8e4f9178f7..9c2a6fc654 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs @@ -24,25 +24,25 @@ namespace Godot /// X component of the quaternion (imaginary <c>i</c> axis part). /// Quaternion components should usually not be manipulated directly. /// </summary> - public real_t x; + public real_t X; /// <summary> /// Y component of the quaternion (imaginary <c>j</c> axis part). /// Quaternion components should usually not be manipulated directly. /// </summary> - public real_t y; + public real_t Y; /// <summary> /// Z component of the quaternion (imaginary <c>k</c> axis part). /// Quaternion components should usually not be manipulated directly. /// </summary> - public real_t z; + public real_t Z; /// <summary> /// W component of the quaternion (real part). /// Quaternion components should usually not be manipulated directly. /// </summary> - public real_t w; + public real_t W; /// <summary> /// Access quaternion components using their index. @@ -51,10 +51,10 @@ namespace Godot /// <paramref name="index"/> is not 0, 1, 2 or 3. /// </exception> /// <value> - /// <c>[0]</c> is equivalent to <see cref="x"/>, - /// <c>[1]</c> is equivalent to <see cref="y"/>, - /// <c>[2]</c> is equivalent to <see cref="z"/>, - /// <c>[3]</c> is equivalent to <see cref="w"/>. + /// <c>[0]</c> is equivalent to <see cref="X"/>, + /// <c>[1]</c> is equivalent to <see cref="Y"/>, + /// <c>[2]</c> is equivalent to <see cref="Z"/>, + /// <c>[3]</c> is equivalent to <see cref="W"/>. /// </value> public real_t this[int index] { @@ -63,13 +63,13 @@ namespace Godot switch (index) { case 0: - return x; + return X; case 1: - return y; + return Y; case 2: - return z; + return Z; case 3: - return w; + return W; default: throw new ArgumentOutOfRangeException(nameof(index)); } @@ -79,16 +79,16 @@ namespace Godot switch (index) { case 0: - x = value; + X = value; break; case 1: - y = value; + Y = value; break; case 2: - z = value; + Z = value; break; case 3: - w = value; + W = value; break; default: throw new ArgumentOutOfRangeException(nameof(index)); @@ -155,9 +155,9 @@ namespace Godot Quaternion lnPre = (fromQ.Inverse() * preQ).Log(); Quaternion lnPost = (fromQ.Inverse() * postQ).Log(); Quaternion ln = new Quaternion( - Mathf.CubicInterpolate(lnFrom.x, lnTo.x, lnPre.x, lnPost.x, weight), - Mathf.CubicInterpolate(lnFrom.y, lnTo.y, lnPre.y, lnPost.y, weight), - Mathf.CubicInterpolate(lnFrom.z, lnTo.z, lnPre.z, lnPost.z, weight), + Mathf.CubicInterpolate(lnFrom.X, lnTo.X, lnPre.X, lnPost.X, weight), + Mathf.CubicInterpolate(lnFrom.Y, lnTo.Y, lnPre.Y, lnPost.Y, weight), + Mathf.CubicInterpolate(lnFrom.Z, lnTo.Z, lnPre.Z, lnPost.Z, weight), 0); Quaternion q1 = fromQ * ln.Exp(); @@ -167,9 +167,9 @@ namespace Godot lnPre = (toQ.Inverse() * preQ).Log(); lnPost = (toQ.Inverse() * postQ).Log(); ln = new Quaternion( - Mathf.CubicInterpolate(lnFrom.x, lnTo.x, lnPre.x, lnPost.x, weight), - Mathf.CubicInterpolate(lnFrom.y, lnTo.y, lnPre.y, lnPost.y, weight), - Mathf.CubicInterpolate(lnFrom.z, lnTo.z, lnPre.z, lnPost.z, weight), + Mathf.CubicInterpolate(lnFrom.X, lnTo.X, lnPre.X, lnPost.X, weight), + Mathf.CubicInterpolate(lnFrom.Y, lnTo.Y, lnPre.Y, lnPost.Y, weight), + Mathf.CubicInterpolate(lnFrom.Z, lnTo.Z, lnPre.Z, lnPost.Z, weight), 0); Quaternion q2 = toQ * ln.Exp(); @@ -224,9 +224,9 @@ namespace Godot Quaternion lnPre = (fromQ.Inverse() * preQ).Log(); Quaternion lnPost = (fromQ.Inverse() * postQ).Log(); Quaternion ln = new Quaternion( - Mathf.CubicInterpolateInTime(lnFrom.x, lnTo.x, lnPre.x, lnPost.x, weight, bT, preAT, postBT), - Mathf.CubicInterpolateInTime(lnFrom.y, lnTo.y, lnPre.y, lnPost.y, weight, bT, preAT, postBT), - Mathf.CubicInterpolateInTime(lnFrom.z, lnTo.z, lnPre.z, lnPost.z, weight, bT, preAT, postBT), + Mathf.CubicInterpolateInTime(lnFrom.X, lnTo.X, lnPre.X, lnPost.X, weight, bT, preAT, postBT), + Mathf.CubicInterpolateInTime(lnFrom.Y, lnTo.Y, lnPre.Y, lnPost.Y, weight, bT, preAT, postBT), + Mathf.CubicInterpolateInTime(lnFrom.Z, lnTo.Z, lnPre.Z, lnPost.Z, weight, bT, preAT, postBT), 0); Quaternion q1 = fromQ * ln.Exp(); @@ -236,9 +236,9 @@ namespace Godot lnPre = (toQ.Inverse() * preQ).Log(); lnPost = (toQ.Inverse() * postQ).Log(); ln = new Quaternion( - Mathf.CubicInterpolateInTime(lnFrom.x, lnTo.x, lnPre.x, lnPost.x, weight, bT, preAT, postBT), - Mathf.CubicInterpolateInTime(lnFrom.y, lnTo.y, lnPre.y, lnPost.y, weight, bT, preAT, postBT), - Mathf.CubicInterpolateInTime(lnFrom.z, lnTo.z, lnPre.z, lnPost.z, weight, bT, preAT, postBT), + Mathf.CubicInterpolateInTime(lnFrom.X, lnTo.X, lnPre.X, lnPost.X, weight, bT, preAT, postBT), + Mathf.CubicInterpolateInTime(lnFrom.Y, lnTo.Y, lnPre.Y, lnPost.Y, weight, bT, preAT, postBT), + Mathf.CubicInterpolateInTime(lnFrom.Z, lnTo.Z, lnPre.Z, lnPost.Z, weight, bT, preAT, postBT), 0); Quaternion q2 = toQ * ln.Exp(); @@ -253,12 +253,12 @@ namespace Godot /// <returns>The dot product.</returns> public readonly real_t Dot(Quaternion b) { - return (x * b.x) + (y * b.y) + (z * b.z) + (w * b.w); + return (X * b.X) + (Y * b.Y) + (Z * b.Z) + (W * b.W); } public readonly Quaternion Exp() { - Vector3 v = new Vector3(x, y, z); + Vector3 v = new Vector3(X, Y, Z); real_t theta = v.Length(); v = v.Normalized(); if (theta < Mathf.Epsilon || !v.IsNormalized()) @@ -270,18 +270,18 @@ namespace Godot public readonly real_t GetAngle() { - return 2 * Mathf.Acos(w); + return 2 * Mathf.Acos(W); } public readonly Vector3 GetAxis() { - if (Mathf.Abs(w) > 1 - Mathf.Epsilon) + if (Mathf.Abs(W) > 1 - Mathf.Epsilon) { - return new Vector3(x, y, z); + return new Vector3(X, Y, Z); } - real_t r = 1 / Mathf.Sqrt(1 - w * w); - return new Vector3(x * r, y * r, z * r); + real_t r = 1 / Mathf.Sqrt(1 - W * W); + return new Vector3(X * r, Y * r, Z * r); } /// <summary> @@ -315,7 +315,7 @@ namespace Godot throw new InvalidOperationException("Quaternion is not normalized."); } #endif - return new Quaternion(-x, -y, -z, w); + return new Quaternion(-X, -Y, -Z, W); } /// <summary> @@ -325,7 +325,7 @@ namespace Godot /// <returns>Whether this vector is finite or not.</returns> public readonly bool IsFinite() { - return Mathf.IsFinite(x) && Mathf.IsFinite(y) && Mathf.IsFinite(z) && Mathf.IsFinite(w); + return Mathf.IsFinite(X) && Mathf.IsFinite(Y) && Mathf.IsFinite(Z) && Mathf.IsFinite(W); } /// <summary> @@ -340,7 +340,7 @@ namespace Godot public readonly Quaternion Log() { Vector3 v = GetAxis() * GetAngle(); - return new Quaternion(v.x, v.y, v.z, 0); + return new Quaternion(v.X, v.Y, v.Z, 0); } /// <summary> @@ -432,10 +432,10 @@ namespace Godot // Calculate final values. return new Quaternion ( - (scale0 * x) + (scale1 * to1.x), - (scale0 * y) + (scale1 * to1.y), - (scale0 * z) + (scale1 * to1.z), - (scale0 * w) + (scale1 * to1.w) + (scale0 * X) + (scale1 * to1.X), + (scale0 * Y) + (scale1 * to1.Y), + (scale0 * Z) + (scale1 * to1.Z), + (scale0 * W) + (scale1 * to1.W) ); } @@ -474,10 +474,10 @@ namespace Godot return new Quaternion ( - (invFactor * x) + (newFactor * to.x), - (invFactor * y) + (newFactor * to.y), - (invFactor * z) + (newFactor * to.z), - (invFactor * w) + (newFactor * to.w) + (invFactor * X) + (newFactor * to.X), + (invFactor * Y) + (newFactor * to.Y), + (invFactor * Z) + (newFactor * to.Z), + (invFactor * W) + (newFactor * to.W) ); } @@ -501,10 +501,10 @@ namespace Godot /// <param name="w">W component of the quaternion (real part).</param> public Quaternion(real_t x, real_t y, real_t z, real_t w) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; + X = x; + Y = y; + Z = z; + W = w; } /// <summary> @@ -535,20 +535,20 @@ namespace Godot if (d == 0f) { - x = 0f; - y = 0f; - z = 0f; - w = 0f; + X = 0f; + Y = 0f; + Z = 0f; + W = 0f; } else { (real_t sin, real_t cos) = Mathf.SinCos(angle * 0.5f); real_t s = sin / d; - x = axis.x * s; - y = axis.y * s; - z = axis.z * s; - w = cos; + X = axis.X * s; + Y = axis.Y * s; + Z = axis.Z * s; + W = cos; } } @@ -559,20 +559,20 @@ namespace Godot if (d < -1.0f + Mathf.Epsilon) { - x = 0f; - y = 1f; - z = 0f; - w = 0f; + X = 0f; + Y = 1f; + Z = 0f; + W = 0f; } else { real_t s = Mathf.Sqrt((1.0f + d) * 2.0f); real_t rs = 1.0f / s; - x = c.x * rs; - y = c.y * rs; - z = c.z * rs; - w = s * 0.5f; + X = c.X * rs; + Y = c.Y * rs; + Z = c.Z * rs; + W = s * 0.5f; } } @@ -584,9 +584,9 @@ namespace Godot /// <param name="eulerYXZ">Euler angles that the quaternion will be rotated by.</param> public static Quaternion FromEuler(Vector3 eulerYXZ) { - real_t halfA1 = eulerYXZ.y * 0.5f; - real_t halfA2 = eulerYXZ.x * 0.5f; - real_t halfA3 = eulerYXZ.z * 0.5f; + real_t halfA1 = eulerYXZ.Y * 0.5f; + real_t halfA2 = eulerYXZ.X * 0.5f; + real_t halfA3 = eulerYXZ.Z * 0.5f; // R = Y(a1).X(a2).Z(a3) convention for Euler angles. // Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6) @@ -616,10 +616,10 @@ namespace Godot { return new Quaternion ( - (left.w * right.x) + (left.x * right.w) + (left.y * right.z) - (left.z * right.y), - (left.w * right.y) + (left.y * right.w) + (left.z * right.x) - (left.x * right.z), - (left.w * right.z) + (left.z * right.w) + (left.x * right.y) - (left.y * right.x), - (left.w * right.w) - (left.x * right.x) - (left.y * right.y) - (left.z * right.z) + (left.W * right.X) + (left.X * right.W) + (left.Y * right.Z) - (left.Z * right.Y), + (left.W * right.Y) + (left.Y * right.W) + (left.Z * right.X) - (left.X * right.Z), + (left.W * right.Z) + (left.Z * right.W) + (left.X * right.Y) - (left.Y * right.X), + (left.W * right.W) - (left.X * right.X) - (left.Y * right.Y) - (left.Z * right.Z) ); } @@ -637,9 +637,9 @@ namespace Godot throw new InvalidOperationException("Quaternion is not normalized."); } #endif - var u = new Vector3(quaternion.x, quaternion.y, quaternion.z); + var u = new Vector3(quaternion.X, quaternion.Y, quaternion.Z); Vector3 uv = u.Cross(vector); - return vector + (((uv * quaternion.w) + u.Cross(uv)) * 2); + return vector + (((uv * quaternion.W) + u.Cross(uv)) * 2); } /// <summary> @@ -665,7 +665,7 @@ namespace Godot /// <returns>The added quaternion.</returns> public static Quaternion operator +(Quaternion left, Quaternion right) { - return new Quaternion(left.x + right.x, left.y + right.y, left.z + right.z, left.w + right.w); + return new Quaternion(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W); } /// <summary> @@ -679,20 +679,20 @@ namespace Godot /// <returns>The subtracted quaternion.</returns> public static Quaternion operator -(Quaternion left, Quaternion right) { - return new Quaternion(left.x - right.x, left.y - right.y, left.z - right.z, left.w - right.w); + return new Quaternion(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W); } /// <summary> /// Returns the negative value of the <see cref="Quaternion"/>. /// This is the same as writing - /// <c>new Quaternion(-q.x, -q.y, -q.z, -q.w)</c>. This operation + /// <c>new Quaternion(-q.X, -q.Y, -q.Z, -q.W)</c>. This operation /// results in a quaternion that represents the same rotation. /// </summary> /// <param name="quat">The quaternion to negate.</param> /// <returns>The negated quaternion.</returns> public static Quaternion operator -(Quaternion quat) { - return new Quaternion(-quat.x, -quat.y, -quat.z, -quat.w); + return new Quaternion(-quat.X, -quat.Y, -quat.Z, -quat.W); } /// <summary> @@ -706,7 +706,7 @@ namespace Godot /// <returns>The multiplied quaternion.</returns> public static Quaternion operator *(Quaternion left, real_t right) { - return new Quaternion(left.x * right, left.y * right, left.z * right, left.w * right); + return new Quaternion(left.X * right, left.Y * right, left.Z * right, left.W * right); } /// <summary> @@ -720,7 +720,7 @@ namespace Godot /// <returns>The multiplied quaternion.</returns> public static Quaternion operator *(real_t left, Quaternion right) { - return new Quaternion(right.x * left, right.y * left, right.z * left, right.w * left); + return new Quaternion(right.X * left, right.Y * left, right.Z * left, right.W * left); } /// <summary> @@ -780,7 +780,7 @@ namespace Godot /// <returns>Whether or not the quaternions are exactly equal.</returns> public readonly bool Equals(Quaternion other) { - return x == other.x && y == other.y && z == other.z && w == other.w; + return X == other.X && Y == other.Y && Z == other.Z && W == other.W; } /// <summary> @@ -791,7 +791,7 @@ namespace Godot /// <returns>Whether or not the quaternions are approximately equal.</returns> public readonly bool IsEqualApprox(Quaternion other) { - return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y) && Mathf.IsEqualApprox(z, other.z) && Mathf.IsEqualApprox(w, other.w); + return Mathf.IsEqualApprox(X, other.X) && Mathf.IsEqualApprox(Y, other.Y) && Mathf.IsEqualApprox(Z, other.Z) && Mathf.IsEqualApprox(W, other.W); } /// <summary> @@ -800,7 +800,7 @@ namespace Godot /// <returns>A hash code for this quaternion.</returns> public override readonly int GetHashCode() { - return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode(); + return Y.GetHashCode() ^ X.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode(); } /// <summary> @@ -809,7 +809,7 @@ namespace Godot /// <returns>A string representation of this quaternion.</returns> public override readonly string ToString() { - return $"({x}, {y}, {z}, {w})"; + return $"({X}, {Y}, {Z}, {W})"; } /// <summary> @@ -818,7 +818,7 @@ namespace Godot /// <returns>A string representation of this quaternion.</returns> public readonly string ToString(string format) { - return $"({x.ToString(format)}, {y.ToString(format)}, {z.ToString(format)}, {w.ToString(format)})"; + return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)}, {W.ToString(format)})"; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/RID.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/RID.cs deleted file mode 100644 index 59b9faf16c..0000000000 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/RID.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Godot.NativeInterop; - -namespace Godot -{ - /// <summary> - /// The RID type is used to access the unique integer ID of a resource. - /// They are opaque, which means they do not grant access to the associated - /// resource by themselves. They are used by and with the low-level Server - /// classes such as <see cref="RenderingServer"/>. - /// </summary> - [StructLayout(LayoutKind.Sequential)] - public readonly struct RID - { - private readonly ulong _id; // Default is 0 - - internal RID(ulong id) - { - _id = id; - } - - /// <summary> - /// Constructs a new <see cref="RID"/> for the given <see cref="Object"/> <paramref name="from"/>. - /// </summary> - public RID(Object from) - => _id = from is Resource res ? res.GetRid()._id : default; - - /// <summary> - /// Returns the ID of the referenced resource. - /// </summary> - /// <returns>The ID of the referenced resource.</returns> - public ulong Id => _id; - - /// <summary> - /// Converts this <see cref="RID"/> to a string. - /// </summary> - /// <returns>A string representation of this RID.</returns> - public override string ToString() => $"RID({Id})"; - } -} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs index 1a8696d3bc..69444f8035 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs @@ -51,11 +51,11 @@ namespace Godot /// <summary> /// The area of this <see cref="Rect2"/>. + /// See also <see cref="HasArea"/>. /// </summary> - /// <value>Equivalent to <see cref="GetArea()"/>.</value> public readonly real_t Area { - get { return GetArea(); } + get { return _size.X * _size.Y; } } /// <summary> @@ -66,7 +66,7 @@ namespace Godot public readonly Rect2 Abs() { Vector2 end = End; - Vector2 topLeft = new Vector2(Mathf.Min(_position.x, end.x), Mathf.Min(_position.y, end.y)); + Vector2 topLeft = new Vector2(Mathf.Min(_position.X, end.X), Mathf.Min(_position.Y, end.Y)); return new Rect2(topLeft, _size.Abs()); } @@ -88,14 +88,14 @@ namespace Godot return new Rect2(); } - newRect._position.x = Mathf.Max(b._position.x, _position.x); - newRect._position.y = Mathf.Max(b._position.y, _position.y); + newRect._position.X = Mathf.Max(b._position.X, _position.X); + newRect._position.Y = Mathf.Max(b._position.Y, _position.Y); Vector2 bEnd = b._position + b._size; Vector2 end = _position + _size; - newRect._size.x = Mathf.Min(bEnd.x, end.x) - newRect._position.x; - newRect._size.y = Mathf.Min(bEnd.y, end.y) - newRect._position.y; + newRect._size.X = Mathf.Min(bEnd.X, end.X) - newRect._position.X; + newRect._size.Y = Mathf.Min(bEnd.Y, end.Y) - newRect._position.Y; return newRect; } @@ -119,9 +119,9 @@ namespace Godot /// </returns> public readonly bool Encloses(Rect2 b) { - return b._position.x >= _position.x && b._position.y >= _position.y && - b._position.x + b._size.x < _position.x + _size.x && - b._position.y + b._size.y < _position.y + _size.y; + return b._position.X >= _position.X && b._position.Y >= _position.Y && + b._position.X + b._size.X < _position.X + _size.X && + b._position.Y + b._size.Y < _position.Y + _size.Y; } /// <summary> @@ -136,22 +136,22 @@ namespace Godot Vector2 begin = expanded._position; Vector2 end = expanded._position + expanded._size; - if (to.x < begin.x) + if (to.X < begin.X) { - begin.x = to.x; + begin.X = to.X; } - if (to.y < begin.y) + if (to.Y < begin.Y) { - begin.y = to.y; + begin.Y = to.Y; } - if (to.x > end.x) + if (to.X > end.X) { - end.x = to.x; + end.X = to.X; } - if (to.y > end.y) + if (to.Y > end.Y) { - end.y = to.y; + end.Y = to.Y; } expanded._position = begin; @@ -161,15 +161,6 @@ namespace Godot } /// <summary> - /// Returns the area of the <see cref="Rect2"/>. - /// </summary> - /// <returns>The area.</returns> - public readonly real_t GetArea() - { - return _size.x * _size.y; - } - - /// <summary> /// Returns the center of the <see cref="Rect2"/>, which is equal /// to <see cref="Position"/> + (<see cref="Size"/> / 2). /// </summary> @@ -191,10 +182,10 @@ namespace Godot { Rect2 g = this; - g._position.x -= by; - g._position.y -= by; - g._size.x += by * 2; - g._size.y += by * 2; + g._position.X -= by; + g._position.Y -= by; + g._size.X += by * 2; + g._size.Y += by * 2; return g; } @@ -214,10 +205,10 @@ namespace Godot { Rect2 g = this; - g._position.x -= left; - g._position.y -= top; - g._size.x += left + right; - g._size.y += top + bottom; + g._position.X -= left; + g._position.Y -= top; + g._size.X += left + right; + g._size.Y += top + bottom; return g; } @@ -247,14 +238,14 @@ namespace Godot /// Returns <see langword="true"/> if the <see cref="Rect2"/> has /// area, and <see langword="false"/> if the <see cref="Rect2"/> /// is linear, empty, or has a negative <see cref="Size"/>. - /// See also <see cref="GetArea"/>. + /// See also <see cref="Area"/>. /// </summary> /// <returns> /// A <see langword="bool"/> for whether or not the <see cref="Rect2"/> has area. /// </returns> public readonly bool HasArea() { - return _size.x > 0.0f && _size.y > 0.0f; + return _size.X > 0.0f && _size.Y > 0.0f; } /// <summary> @@ -267,14 +258,14 @@ namespace Godot /// </returns> public readonly bool HasPoint(Vector2 point) { - if (point.x < _position.x) + if (point.X < _position.X) return false; - if (point.y < _position.y) + if (point.Y < _position.Y) return false; - if (point.x >= _position.x + _size.x) + if (point.X >= _position.X + _size.X) return false; - if (point.y >= _position.y + _size.y) + if (point.Y >= _position.Y + _size.Y) return false; return true; @@ -295,38 +286,38 @@ namespace Godot { if (includeBorders) { - if (_position.x > b._position.x + b._size.x) + if (_position.X > b._position.X + b._size.X) { return false; } - if (_position.x + _size.x < b._position.x) + if (_position.X + _size.X < b._position.X) { return false; } - if (_position.y > b._position.y + b._size.y) + if (_position.Y > b._position.Y + b._size.Y) { return false; } - if (_position.y + _size.y < b._position.y) + if (_position.Y + _size.Y < b._position.Y) { return false; } } else { - if (_position.x >= b._position.x + b._size.x) + if (_position.X >= b._position.X + b._size.X) { return false; } - if (_position.x + _size.x <= b._position.x) + if (_position.X + _size.X <= b._position.X) { return false; } - if (_position.y >= b._position.y + b._size.y) + if (_position.Y >= b._position.Y + b._size.Y) { return false; } - if (_position.y + _size.y <= b._position.y) + if (_position.Y + _size.Y <= b._position.Y) { return false; } @@ -344,11 +335,11 @@ namespace Godot { Rect2 newRect; - newRect._position.x = Mathf.Min(b._position.x, _position.x); - newRect._position.y = Mathf.Min(b._position.y, _position.y); + newRect._position.X = Mathf.Min(b._position.X, _position.X); + newRect._position.Y = Mathf.Min(b._position.Y, _position.Y); - newRect._size.x = Mathf.Max(b._position.x + b._size.x, _position.x + _size.x); - newRect._size.y = Mathf.Max(b._position.y + b._size.y, _position.y + _size.y); + newRect._size.X = Mathf.Max(b._position.X + b._size.X, _position.X + _size.X); + newRect._size.Y = Mathf.Max(b._position.Y + b._size.Y, _position.Y + _size.Y); newRect._size -= newRect._position; // Make relative again diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2I.cs index cf8939a859..2099d0abca 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2I.cs @@ -4,21 +4,21 @@ using System.Runtime.InteropServices; namespace Godot { /// <summary> - /// 2D axis-aligned bounding box using integers. Rect2i consists of a position, a size, and + /// 2D axis-aligned bounding box using integers. Rect2I consists of a position, a size, and /// several utility functions. It is typically used for fast overlap tests. /// </summary> [Serializable] [StructLayout(LayoutKind.Sequential)] - public struct Rect2i : IEquatable<Rect2i> + public struct Rect2I : IEquatable<Rect2I> { - private Vector2i _position; - private Vector2i _size; + private Vector2I _position; + private Vector2I _size; /// <summary> /// Beginning corner. Typically has values lower than <see cref="End"/>. /// </summary> /// <value>Directly uses a private field.</value> - public Vector2i Position + public Vector2I Position { readonly get { return _position; } set { _position = value; } @@ -29,7 +29,7 @@ namespace Godot /// If the size is negative, you can use <see cref="Abs"/> to fix it. /// </summary> /// <value>Directly uses a private field.</value> - public Vector2i Size + public Vector2I Size { readonly get { return _size; } set { _size = value; } @@ -43,105 +43,105 @@ namespace Godot /// Getting is equivalent to <paramref name="value"/> = <see cref="Position"/> + <see cref="Size"/>, /// setting is equivalent to <see cref="Size"/> = <paramref name="value"/> - <see cref="Position"/> /// </value> - public Vector2i End + public Vector2I End { readonly get { return _position + _size; } set { _size = value - _position; } } /// <summary> - /// The area of this <see cref="Rect2i"/>. + /// The area of this <see cref="Rect2I"/>. + /// See also <see cref="HasArea"/>. /// </summary> - /// <value>Equivalent to <see cref="GetArea()"/>.</value> public readonly int Area { - get { return GetArea(); } + get { return _size.X * _size.Y; } } /// <summary> - /// Returns a <see cref="Rect2i"/> with equivalent position and size, modified so that + /// Returns a <see cref="Rect2I"/> with equivalent position and size, modified so that /// the top-left corner is the origin and width and height are positive. /// </summary> - /// <returns>The modified <see cref="Rect2i"/>.</returns> - public readonly Rect2i Abs() + /// <returns>The modified <see cref="Rect2I"/>.</returns> + public readonly Rect2I Abs() { - Vector2i end = End; - Vector2i topLeft = new Vector2i(Mathf.Min(_position.x, end.x), Mathf.Min(_position.y, end.y)); - return new Rect2i(topLeft, _size.Abs()); + Vector2I end = End; + Vector2I topLeft = new Vector2I(Mathf.Min(_position.X, end.X), Mathf.Min(_position.Y, end.Y)); + return new Rect2I(topLeft, _size.Abs()); } /// <summary> - /// Returns the intersection of this <see cref="Rect2i"/> and <paramref name="b"/>. - /// If the rectangles do not intersect, an empty <see cref="Rect2i"/> is returned. + /// Returns the intersection of this <see cref="Rect2I"/> and <paramref name="b"/>. + /// If the rectangles do not intersect, an empty <see cref="Rect2I"/> is returned. /// </summary> - /// <param name="b">The other <see cref="Rect2i"/>.</param> + /// <param name="b">The other <see cref="Rect2I"/>.</param> /// <returns> - /// The intersection of this <see cref="Rect2i"/> and <paramref name="b"/>, - /// or an empty <see cref="Rect2i"/> if they do not intersect. + /// The intersection of this <see cref="Rect2I"/> and <paramref name="b"/>, + /// or an empty <see cref="Rect2I"/> if they do not intersect. /// </returns> - public readonly Rect2i Intersection(Rect2i b) + public readonly Rect2I Intersection(Rect2I b) { - Rect2i newRect = b; + Rect2I newRect = b; if (!Intersects(newRect)) { - return new Rect2i(); + return new Rect2I(); } - newRect._position.x = Mathf.Max(b._position.x, _position.x); - newRect._position.y = Mathf.Max(b._position.y, _position.y); + newRect._position.X = Mathf.Max(b._position.X, _position.X); + newRect._position.Y = Mathf.Max(b._position.Y, _position.Y); - Vector2i bEnd = b._position + b._size; - Vector2i end = _position + _size; + Vector2I bEnd = b._position + b._size; + Vector2I end = _position + _size; - newRect._size.x = Mathf.Min(bEnd.x, end.x) - newRect._position.x; - newRect._size.y = Mathf.Min(bEnd.y, end.y) - newRect._position.y; + newRect._size.X = Mathf.Min(bEnd.X, end.X) - newRect._position.X; + newRect._size.Y = Mathf.Min(bEnd.Y, end.Y) - newRect._position.Y; return newRect; } /// <summary> - /// Returns <see langword="true"/> if this <see cref="Rect2i"/> completely encloses another one. + /// Returns <see langword="true"/> if this <see cref="Rect2I"/> completely encloses another one. /// </summary> - /// <param name="b">The other <see cref="Rect2i"/> that may be enclosed.</param> + /// <param name="b">The other <see cref="Rect2I"/> that may be enclosed.</param> /// <returns> - /// A <see langword="bool"/> for whether or not this <see cref="Rect2i"/> encloses <paramref name="b"/>. + /// A <see langword="bool"/> for whether or not this <see cref="Rect2I"/> encloses <paramref name="b"/>. /// </returns> - public readonly bool Encloses(Rect2i b) + public readonly bool Encloses(Rect2I b) { - return b._position.x >= _position.x && b._position.y >= _position.y && - b._position.x + b._size.x < _position.x + _size.x && - b._position.y + b._size.y < _position.y + _size.y; + return b._position.X >= _position.X && b._position.Y >= _position.Y && + b._position.X + b._size.X < _position.X + _size.X && + b._position.Y + b._size.Y < _position.Y + _size.Y; } /// <summary> - /// Returns this <see cref="Rect2i"/> expanded to include a given point. + /// Returns this <see cref="Rect2I"/> expanded to include a given point. /// </summary> /// <param name="to">The point to include.</param> - /// <returns>The expanded <see cref="Rect2i"/>.</returns> - public readonly Rect2i Expand(Vector2i to) + /// <returns>The expanded <see cref="Rect2I"/>.</returns> + public readonly Rect2I Expand(Vector2I to) { - Rect2i expanded = this; + Rect2I expanded = this; - Vector2i begin = expanded._position; - Vector2i end = expanded._position + expanded._size; + Vector2I begin = expanded._position; + Vector2I end = expanded._position + expanded._size; - if (to.x < begin.x) + if (to.X < begin.X) { - begin.x = to.x; + begin.X = to.X; } - if (to.y < begin.y) + if (to.Y < begin.Y) { - begin.y = to.y; + begin.Y = to.Y; } - if (to.x > end.x) + if (to.X > end.X) { - end.x = to.x; + end.X = to.X; } - if (to.y > end.y) + if (to.Y > end.Y) { - end.y = to.y; + end.Y = to.Y; } expanded._position = begin; @@ -151,48 +151,39 @@ namespace Godot } /// <summary> - /// Returns the area of the <see cref="Rect2i"/>. - /// </summary> - /// <returns>The area.</returns> - public readonly int GetArea() - { - return _size.x * _size.y; - } - - /// <summary> - /// Returns the center of the <see cref="Rect2i"/>, which is equal + /// Returns the center of the <see cref="Rect2I"/>, which is equal /// to <see cref="Position"/> + (<see cref="Size"/> / 2). /// If <see cref="Size"/> is an odd number, the returned center /// value will be rounded towards <see cref="Position"/>. /// </summary> /// <returns>The center.</returns> - public readonly Vector2i GetCenter() + public readonly Vector2I GetCenter() { return _position + (_size / 2); } /// <summary> - /// Returns a copy of the <see cref="Rect2i"/> grown by the specified amount + /// Returns a copy of the <see cref="Rect2I"/> grown by the specified amount /// on all sides. /// </summary> /// <seealso cref="GrowIndividual(int, int, int, int)"/> /// <seealso cref="GrowSide(Side, int)"/> /// <param name="by">The amount to grow by.</param> - /// <returns>The grown <see cref="Rect2i"/>.</returns> - public readonly Rect2i Grow(int by) + /// <returns>The grown <see cref="Rect2I"/>.</returns> + public readonly Rect2I Grow(int by) { - Rect2i g = this; + Rect2I g = this; - g._position.x -= by; - g._position.y -= by; - g._size.x += by * 2; - g._size.y += by * 2; + g._position.X -= by; + g._position.Y -= by; + g._size.X += by * 2; + g._size.Y += by * 2; return g; } /// <summary> - /// Returns a copy of the <see cref="Rect2i"/> grown by the specified amount + /// Returns a copy of the <see cref="Rect2I"/> grown by the specified amount /// on each side individually. /// </summary> /// <seealso cref="Grow(int)"/> @@ -201,31 +192,31 @@ namespace Godot /// <param name="top">The amount to grow by on the top side.</param> /// <param name="right">The amount to grow by on the right side.</param> /// <param name="bottom">The amount to grow by on the bottom side.</param> - /// <returns>The grown <see cref="Rect2i"/>.</returns> - public readonly Rect2i GrowIndividual(int left, int top, int right, int bottom) + /// <returns>The grown <see cref="Rect2I"/>.</returns> + public readonly Rect2I GrowIndividual(int left, int top, int right, int bottom) { - Rect2i g = this; + Rect2I g = this; - g._position.x -= left; - g._position.y -= top; - g._size.x += left + right; - g._size.y += top + bottom; + g._position.X -= left; + g._position.Y -= top; + g._size.X += left + right; + g._size.Y += top + bottom; return g; } /// <summary> - /// Returns a copy of the <see cref="Rect2i"/> grown by the specified amount + /// Returns a copy of the <see cref="Rect2I"/> grown by the specified amount /// on the specified <see cref="Side"/>. /// </summary> /// <seealso cref="Grow(int)"/> /// <seealso cref="GrowIndividual(int, int, int, int)"/> /// <param name="side">The side to grow.</param> /// <param name="by">The amount to grow by.</param> - /// <returns>The grown <see cref="Rect2i"/>.</returns> - public readonly Rect2i GrowSide(Side side, int by) + /// <returns>The grown <see cref="Rect2I"/>.</returns> + public readonly Rect2I GrowSide(Side side, int by) { - Rect2i g = this; + Rect2I g = this; g = g.GrowIndividual(Side.Left == side ? by : 0, Side.Top == side ? by : 0, @@ -236,76 +227,76 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if the <see cref="Rect2i"/> has - /// area, and <see langword="false"/> if the <see cref="Rect2i"/> + /// Returns <see langword="true"/> if the <see cref="Rect2I"/> has + /// area, and <see langword="false"/> if the <see cref="Rect2I"/> /// is linear, empty, or has a negative <see cref="Size"/>. - /// See also <see cref="GetArea"/>. + /// See also <see cref="Area"/>. /// </summary> /// <returns> - /// A <see langword="bool"/> for whether or not the <see cref="Rect2i"/> has area. + /// A <see langword="bool"/> for whether or not the <see cref="Rect2I"/> has area. /// </returns> public readonly bool HasArea() { - return _size.x > 0 && _size.y > 0; + return _size.X > 0 && _size.Y > 0; } /// <summary> - /// Returns <see langword="true"/> if the <see cref="Rect2i"/> contains a point, + /// Returns <see langword="true"/> if the <see cref="Rect2I"/> contains a point, /// or <see langword="false"/> otherwise. /// </summary> /// <param name="point">The point to check.</param> /// <returns> - /// A <see langword="bool"/> for whether or not the <see cref="Rect2i"/> contains <paramref name="point"/>. + /// A <see langword="bool"/> for whether or not the <see cref="Rect2I"/> contains <paramref name="point"/>. /// </returns> - public readonly bool HasPoint(Vector2i point) + public readonly bool HasPoint(Vector2I point) { - if (point.x < _position.x) + if (point.X < _position.X) return false; - if (point.y < _position.y) + if (point.Y < _position.Y) return false; - if (point.x >= _position.x + _size.x) + if (point.X >= _position.X + _size.X) return false; - if (point.y >= _position.y + _size.y) + if (point.Y >= _position.Y + _size.Y) return false; return true; } /// <summary> - /// Returns <see langword="true"/> if the <see cref="Rect2i"/> overlaps with <paramref name="b"/> + /// Returns <see langword="true"/> if the <see cref="Rect2I"/> overlaps with <paramref name="b"/> /// (i.e. they have at least one point in common). /// </summary> - /// <param name="b">The other <see cref="Rect2i"/> to check for intersections with.</param> + /// <param name="b">The other <see cref="Rect2I"/> to check for intersections with.</param> /// <returns>A <see langword="bool"/> for whether or not they are intersecting.</returns> - public readonly bool Intersects(Rect2i b) + public readonly bool Intersects(Rect2I b) { - if (_position.x >= b._position.x + b._size.x) + if (_position.X >= b._position.X + b._size.X) return false; - if (_position.x + _size.x <= b._position.x) + if (_position.X + _size.X <= b._position.X) return false; - if (_position.y >= b._position.y + b._size.y) + if (_position.Y >= b._position.Y + b._size.Y) return false; - if (_position.y + _size.y <= b._position.y) + if (_position.Y + _size.Y <= b._position.Y) return false; return true; } /// <summary> - /// Returns a larger <see cref="Rect2i"/> that contains this <see cref="Rect2i"/> and <paramref name="b"/>. + /// Returns a larger <see cref="Rect2I"/> that contains this <see cref="Rect2I"/> and <paramref name="b"/>. /// </summary> - /// <param name="b">The other <see cref="Rect2i"/>.</param> - /// <returns>The merged <see cref="Rect2i"/>.</returns> - public readonly Rect2i Merge(Rect2i b) + /// <param name="b">The other <see cref="Rect2I"/>.</param> + /// <returns>The merged <see cref="Rect2I"/>.</returns> + public readonly Rect2I Merge(Rect2I b) { - Rect2i newRect; + Rect2I newRect; - newRect._position.x = Mathf.Min(b._position.x, _position.x); - newRect._position.y = Mathf.Min(b._position.y, _position.y); + newRect._position.X = Mathf.Min(b._position.X, _position.X); + newRect._position.Y = Mathf.Min(b._position.Y, _position.Y); - newRect._size.x = Mathf.Max(b._position.x + b._size.x, _position.x + _size.x); - newRect._size.y = Mathf.Max(b._position.y + b._size.y, _position.y + _size.y); + newRect._size.X = Mathf.Max(b._position.X + b._size.X, _position.X + _size.X); + newRect._size.Y = Mathf.Max(b._position.Y + b._size.Y, _position.Y + _size.Y); newRect._size -= newRect._position; // Make relative again @@ -313,93 +304,93 @@ namespace Godot } /// <summary> - /// Constructs a <see cref="Rect2i"/> from a position and size. + /// Constructs a <see cref="Rect2I"/> from a position and size. /// </summary> /// <param name="position">The position.</param> /// <param name="size">The size.</param> - public Rect2i(Vector2i position, Vector2i size) + public Rect2I(Vector2I position, Vector2I size) { _position = position; _size = size; } /// <summary> - /// Constructs a <see cref="Rect2i"/> from a position, width, and height. + /// Constructs a <see cref="Rect2I"/> from a position, width, and height. /// </summary> /// <param name="position">The position.</param> /// <param name="width">The width.</param> /// <param name="height">The height.</param> - public Rect2i(Vector2i position, int width, int height) + public Rect2I(Vector2I position, int width, int height) { _position = position; - _size = new Vector2i(width, height); + _size = new Vector2I(width, height); } /// <summary> - /// Constructs a <see cref="Rect2i"/> from x, y, and size. + /// Constructs a <see cref="Rect2I"/> from x, y, and size. /// </summary> /// <param name="x">The position's X coordinate.</param> /// <param name="y">The position's Y coordinate.</param> /// <param name="size">The size.</param> - public Rect2i(int x, int y, Vector2i size) + public Rect2I(int x, int y, Vector2I size) { - _position = new Vector2i(x, y); + _position = new Vector2I(x, y); _size = size; } /// <summary> - /// Constructs a <see cref="Rect2i"/> from x, y, width, and height. + /// Constructs a <see cref="Rect2I"/> from x, y, width, and height. /// </summary> /// <param name="x">The position's X coordinate.</param> /// <param name="y">The position's Y coordinate.</param> /// <param name="width">The width.</param> /// <param name="height">The height.</param> - public Rect2i(int x, int y, int width, int height) + public Rect2I(int x, int y, int width, int height) { - _position = new Vector2i(x, y); - _size = new Vector2i(width, height); + _position = new Vector2I(x, y); + _size = new Vector2I(width, height); } /// <summary> /// Returns <see langword="true"/> if the - /// <see cref="Rect2i"/>s are exactly equal. + /// <see cref="Rect2I"/>s are exactly equal. /// </summary> /// <param name="left">The left rect.</param> /// <param name="right">The right rect.</param> /// <returns>Whether or not the rects are equal.</returns> - public static bool operator ==(Rect2i left, Rect2i right) + public static bool operator ==(Rect2I left, Rect2I right) { return left.Equals(right); } /// <summary> /// Returns <see langword="true"/> if the - /// <see cref="Rect2i"/>s are not equal. + /// <see cref="Rect2I"/>s are not equal. /// </summary> /// <param name="left">The left rect.</param> /// <param name="right">The right rect.</param> /// <returns>Whether or not the rects are not equal.</returns> - public static bool operator !=(Rect2i left, Rect2i right) + public static bool operator !=(Rect2I left, Rect2I right) { return !left.Equals(right); } /// <summary> - /// Converts this <see cref="Rect2i"/> to a <see cref="Rect2"/>. + /// Converts this <see cref="Rect2I"/> to a <see cref="Rect2"/>. /// </summary> /// <param name="value">The rect to convert.</param> - public static implicit operator Rect2(Rect2i value) + public static implicit operator Rect2(Rect2I value) { return new Rect2(value._position, value._size); } /// <summary> - /// Converts a <see cref="Rect2"/> to a <see cref="Rect2i"/>. + /// Converts a <see cref="Rect2"/> to a <see cref="Rect2I"/>. /// </summary> /// <param name="value">The rect to convert.</param> - public static explicit operator Rect2i(Rect2 value) + public static explicit operator Rect2I(Rect2 value) { - return new Rect2i((Vector2i)value.Position, (Vector2i)value.Size); + return new Rect2I((Vector2I)value.Position, (Vector2I)value.Size); } /// <summary> @@ -409,7 +400,7 @@ namespace Godot /// <returns>Whether or not the rect and the other object are equal.</returns> public override readonly bool Equals(object obj) { - return obj is Rect2i other && Equals(other); + return obj is Rect2I other && Equals(other); } /// <summary> @@ -417,13 +408,13 @@ namespace Godot /// </summary> /// <param name="other">The other rect to compare.</param> /// <returns>Whether or not the rects are equal.</returns> - public readonly bool Equals(Rect2i other) + public readonly bool Equals(Rect2I other) { return _position.Equals(other._position) && _size.Equals(other._size); } /// <summary> - /// Serves as the hash function for <see cref="Rect2i"/>. + /// Serves as the hash function for <see cref="Rect2I"/>. /// </summary> /// <returns>A hash code for this rect.</returns> public override readonly int GetHashCode() @@ -432,7 +423,7 @@ namespace Godot } /// <summary> - /// Converts this <see cref="Rect2i"/> to a string. + /// Converts this <see cref="Rect2I"/> to a string. /// </summary> /// <returns>A string representation of this rect.</returns> public override readonly string ToString() @@ -441,7 +432,7 @@ namespace Godot } /// <summary> - /// Converts this <see cref="Rect2i"/> to a string with the given <paramref name="format"/>. + /// Converts this <see cref="Rect2I"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this rect.</returns> public readonly string ToString(string format) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rid.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rid.cs new file mode 100644 index 0000000000..350626389b --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rid.cs @@ -0,0 +1,104 @@ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Godot.NativeInterop; + +namespace Godot +{ + /// <summary> + /// The RID type is used to access a low-level resource by its unique ID. + /// RIDs are opaque, which means they do not grant access to the resource + /// by themselves. They are used by the low-level server classes, such as + /// <see cref="DisplayServer"/>, <see cref="RenderingServer"/>, + /// <see cref="TextServer"/>, etc. + /// + /// A low-level resource may correspond to a high-level <see cref="Resource"/>, + /// such as <see cref="Texture"/> or <see cref="Mesh"/> + /// </summary> + [StructLayout(LayoutKind.Sequential)] + public readonly struct Rid : IEquatable<Rid> + { + private readonly ulong _id; // Default is 0 + + internal Rid(ulong id) + { + _id = id; + } + + /// <summary> + /// Constructs a new <see cref="Rid"/> for the given <see cref="GodotObject"/> <paramref name="from"/>. + /// </summary> + public Rid(GodotObject from) + => _id = from is Resource res ? res.GetRid()._id : default; + + /// <summary> + /// Returns the ID of the referenced low-level resource. + /// </summary> + /// <returns>The ID of the referenced resource.</returns> + public ulong Id => _id; + + /// <summary> + /// Returns <see langword="true"/> if the <see cref="Rid"/> is not <c>0</c>. + /// </summary> + /// <returns>Whether or not the ID is valid.</returns> + public bool IsValid => _id != 0; + + /// <summary> + /// Returns <see langword="true"/> if both <see cref="Rid"/>s are equal, + /// which means they both refer to the same low-level resource. + /// </summary> + /// <param name="left">The left RID.</param> + /// <param name="right">The right RID.</param> + /// <returns>Whether or not the RIDs are equal.</returns> + public static bool operator ==(Rid left, Rid right) + { + return left.Equals(right); + } + + /// <summary> + /// Returns <see langword="true"/> if the <see cref="Rid"/>s are not equal. + /// </summary> + /// <param name="left">The left RID.</param> + /// <param name="right">The right RID.</param> + /// <returns>Whether or not the RIDs are equal.</returns> + public static bool operator !=(Rid left, Rid right) + { + return !left.Equals(right); + } + + /// <summary> + /// Returns <see langword="true"/> if this RID and <paramref name="obj"/> are equal. + /// </summary> + /// <param name="obj">The other object to compare.</param> + /// <returns>Whether or not the color and the other object are equal.</returns> + public override readonly bool Equals(object obj) + { + return obj is Rid other && Equals(other); + } + + /// <summary> + /// Returns <see langword="true"/> if the RIDs are equal. + /// </summary> + /// <param name="other">The other RID.</param> + /// <returns>Whether or not the RIDs are equal.</returns> + public readonly bool Equals(Rid other) + { + return _id == other.Id; + } + + /// <summary> + /// Serves as the hash function for <see cref="Rid"/>. + /// </summary> + /// <returns>A hash code for this RID.</returns> + public override readonly int GetHashCode() + { + return HashCode.Combine(_id); + } + + /// <summary> + /// Converts this <see cref="Rid"/> to a string. + /// </summary> + /// <returns>A string representation of this Rid.</returns> + public override string ToString() => $"RID({Id})"; + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Signal.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Signal.cs index f9b8f06603..9ac8abd37b 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Signal.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Signal.cs @@ -5,13 +5,14 @@ namespace Godot /// </summary> public readonly struct Signal : IAwaitable<Variant[]> { - private readonly Object _owner; + private readonly GodotObject _owner; private readonly StringName _signalName; /// <summary> /// Object that contains the signal. /// </summary> - public Object Owner => _owner; + public GodotObject Owner => _owner; + /// <summary> /// Name of the signal. /// </summary> @@ -23,7 +24,7 @@ namespace Godot /// </summary> /// <param name="owner">Object that contains the signal.</param> /// <param name="name">Name of the signal.</param> - public Signal(Object owner, StringName name) + public Signal(GodotObject owner, StringName name) { _owner = owner; _signalName = name; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs index 96fb891086..a67f626d35 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/SignalAwaiter.cs @@ -10,13 +10,13 @@ namespace Godot private Variant[] _result; private Action _continuation; - public SignalAwaiter(Object source, StringName signal, Object target) + public SignalAwaiter(GodotObject source, StringName signal, GodotObject target) { var awaiterGcHandle = CustomGCHandle.AllocStrong(this); 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(awaiterGcHandle)); + NativeFuncs.godotsharp_internal_signal_awaiter_connect(GodotObject.GetPtr(source), in signalSrc, + GodotObject.GetPtr(target), GCHandle.ToIntPtr(awaiterGcHandle)); } public bool IsCompleted => _completed; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs index d4329d78c1..df67e075ac 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs @@ -69,19 +69,6 @@ namespace Godot } /// <summary> - /// Returns <see langword="true"/> if the strings begins - /// with the given string <paramref name="text"/>. - /// </summary> - /// <param name="instance">The string to check.</param> - /// <param name="text">The beginning string.</param> - /// <returns>If the string begins with the given string.</returns> - [Obsolete("Use string.StartsWith instead.")] - public static bool BeginsWith(this string instance, string text) - { - return instance.StartsWith(text); - } - - /// <summary> /// Returns the bigrams (pairs of consecutive letters) of this string. /// </summary> /// <param name="instance">The string that will be used.</param> @@ -618,7 +605,7 @@ namespace Godot } else { - if (instance.BeginsWith("/")) + if (instance.StartsWith('/')) { rs = instance.Substring(1); directory = "/"; @@ -675,15 +662,15 @@ namespace Godot /// <summary> /// Converts ASCII encoded array to string. - /// Fast alternative to <see cref="GetStringFromUTF8"/> if the + /// Fast alternative to <see cref="GetStringFromUtf8"/> if the /// content is ASCII-only. Unlike the UTF-8 function this function /// maps every byte to a character in the array. Multibyte sequences /// will not be interpreted correctly. For parsing user input always - /// use <see cref="GetStringFromUTF8"/>. + /// use <see cref="GetStringFromUtf8"/>. /// </summary> /// <param name="bytes">A byte array of ASCII characters (on the range of 0-127).</param> /// <returns>A string created from the bytes.</returns> - public static string GetStringFromASCII(this byte[] bytes) + public static string GetStringFromAscii(this byte[] bytes) { return Encoding.ASCII.GetString(bytes); } @@ -693,7 +680,7 @@ namespace Godot /// </summary> /// <param name="bytes">A byte array of UTF-16 characters.</param> /// <returns>A string created from the bytes.</returns> - public static string GetStringFromUTF16(this byte[] bytes) + public static string GetStringFromUtf16(this byte[] bytes) { return Encoding.Unicode.GetString(bytes); } @@ -703,14 +690,14 @@ namespace Godot /// </summary> /// <param name="bytes">A byte array of UTF-32 characters.</param> /// <returns>A string created from the bytes.</returns> - public static string GetStringFromUTF32(this byte[] bytes) + public static string GetStringFromUtf32(this byte[] bytes) { return Encoding.UTF32.GetString(bytes); } /// <summary> /// Converts UTF-8 encoded array to string. - /// Slower than <see cref="GetStringFromASCII"/> but supports UTF-8 + /// Slower than <see cref="GetStringFromAscii"/> but supports UTF-8 /// encoded data. Use this function if you are unsure about the /// source of the data. For user input this function /// should always be preferred. @@ -719,7 +706,7 @@ namespace Godot /// A byte array of UTF-8 characters (a character may take up multiple bytes). /// </param> /// <returns>A string created from the bytes.</returns> - public static string GetStringFromUTF8(this byte[] bytes) + public static string GetStringFromUtf8(this byte[] bytes) { return Encoding.UTF8.GetString(bytes); } @@ -1199,23 +1186,6 @@ namespace Godot } /// <summary> - /// Returns a copy of the string with characters removed from the left. - /// The <paramref name="chars"/> argument is a string specifying the set of characters - /// to be removed. - /// Note: The <paramref name="chars"/> is not a prefix. See <see cref="TrimPrefix"/> - /// method that will remove a single prefix string rather than a set of characters. - /// </summary> - /// <seealso cref="RStrip(string, string)"/> - /// <param name="instance">The string to remove characters from.</param> - /// <param name="chars">The characters to be removed.</param> - /// <returns>A copy of the string with characters removed from the left.</returns> - [Obsolete("Use string.TrimStart instead.")] - public static string LStrip(this string instance, string chars) - { - return instance.TrimStart(chars.ToCharArray()); - } - - /// <summary> /// Do a simple expression match, where '*' matches zero or more /// arbitrary characters and '?' matches any single character except '.'. /// </summary> @@ -1287,10 +1257,10 @@ namespace Godot /// <summary> /// Returns the MD5 hash of the string as an array of bytes. /// </summary> - /// <seealso cref="MD5Text(string)"/> + /// <seealso cref="Md5Text(string)"/> /// <param name="instance">The string to hash.</param> /// <returns>The MD5 hash of the string.</returns> - public static byte[] MD5Buffer(this string instance) + public static byte[] Md5Buffer(this string instance) { #pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms return MD5.HashData(Encoding.UTF8.GetBytes(instance)); @@ -1300,12 +1270,12 @@ namespace Godot /// <summary> /// Returns the MD5 hash of the string as a string. /// </summary> - /// <seealso cref="MD5Buffer(string)"/> + /// <seealso cref="Md5Buffer(string)"/> /// <param name="instance">The string to hash.</param> /// <returns>The MD5 hash of the string.</returns> - public static string MD5Text(this string instance) + public static string Md5Text(this string instance) { - return instance.MD5Buffer().HexEncode(); + return instance.Md5Buffer().HexEncode(); } /// <summary> @@ -1504,29 +1474,12 @@ namespace Godot } /// <summary> - /// Returns a copy of the string with characters removed from the right. - /// The <paramref name="chars"/> argument is a string specifying the set of characters - /// to be removed. - /// Note: The <paramref name="chars"/> is not a suffix. See <see cref="TrimSuffix"/> - /// method that will remove a single suffix string rather than a set of characters. - /// </summary> - /// <seealso cref="LStrip(string, string)"/> - /// <param name="instance">The string to remove characters from.</param> - /// <param name="chars">The characters to be removed.</param> - /// <returns>A copy of the string with characters removed from the right.</returns> - [Obsolete("Use string.TrimEnd instead.")] - public static string RStrip(this string instance, string chars) - { - return instance.TrimEnd(chars.ToCharArray()); - } - - /// <summary> /// Returns the SHA-1 hash of the string as an array of bytes. /// </summary> - /// <seealso cref="SHA1Text(string)"/> + /// <seealso cref="Sha1Text(string)"/> /// <param name="instance">The string to hash.</param> /// <returns>The SHA-1 hash of the string.</returns> - public static byte[] SHA1Buffer(this string instance) + public static byte[] Sha1Buffer(this string instance) { #pragma warning disable CA5350 // Do Not Use Weak Cryptographic Algorithms return SHA1.HashData(Encoding.UTF8.GetBytes(instance)); @@ -1536,21 +1489,21 @@ namespace Godot /// <summary> /// Returns the SHA-1 hash of the string as a string. /// </summary> - /// <seealso cref="SHA1Buffer(string)"/> + /// <seealso cref="Sha1Buffer(string)"/> /// <param name="instance">The string to hash.</param> /// <returns>The SHA-1 hash of the string.</returns> - public static string SHA1Text(this string instance) + public static string Sha1Text(this string instance) { - return instance.SHA1Buffer().HexEncode(); + return instance.Sha1Buffer().HexEncode(); } /// <summary> /// Returns the SHA-256 hash of the string as an array of bytes. /// </summary> - /// <seealso cref="SHA256Text(string)"/> + /// <seealso cref="Sha256Text(string)"/> /// <param name="instance">The string to hash.</param> /// <returns>The SHA-256 hash of the string.</returns> - public static byte[] SHA256Buffer(this string instance) + public static byte[] Sha256Buffer(this string instance) { return SHA256.HashData(Encoding.UTF8.GetBytes(instance)); } @@ -1558,12 +1511,12 @@ namespace Godot /// <summary> /// Returns the SHA-256 hash of the string as a string. /// </summary> - /// <seealso cref="SHA256Buffer(string)"/> + /// <seealso cref="Sha256Buffer(string)"/> /// <param name="instance">The string to hash.</param> /// <returns>The SHA-256 hash of the string.</returns> - public static string SHA256Text(this string instance) + public static string Sha256Text(this string instance) { - return instance.SHA256Buffer().HexEncode(); + return instance.Sha256Buffer().HexEncode(); } /// <summary> @@ -1745,15 +1698,15 @@ namespace Godot /// <summary> /// Converts the String (which is a character array) to PackedByteArray (which is an array of bytes). - /// The conversion is faster compared to <see cref="ToUTF8Buffer(string)"/>, + /// The conversion is faster compared to <see cref="ToUtf8Buffer(string)"/>, /// as this method assumes that all the characters in the String are ASCII characters. /// </summary> - /// <seealso cref="ToUTF8Buffer(string)"/> - /// <seealso cref="ToUTF16Buffer(string)"/> - /// <seealso cref="ToUTF32Buffer(string)"/> + /// <seealso cref="ToUtf8Buffer(string)"/> + /// <seealso cref="ToUtf16Buffer(string)"/> + /// <seealso cref="ToUtf32Buffer(string)"/> /// <param name="instance">The string to convert.</param> /// <returns>The string as ASCII encoded bytes.</returns> - public static byte[] ToASCIIBuffer(this string instance) + public static byte[] ToAsciiBuffer(this string instance) { return Encoding.ASCII.GetBytes(instance); } @@ -1783,12 +1736,12 @@ namespace Godot /// <summary> /// Converts the string (which is an array of characters) to an UTF-16 encoded array of bytes. /// </summary> - /// <seealso cref="ToASCIIBuffer(string)"/> - /// <seealso cref="ToUTF32Buffer(string)"/> - /// <seealso cref="ToUTF8Buffer(string)"/> + /// <seealso cref="ToAsciiBuffer(string)"/> + /// <seealso cref="ToUtf32Buffer(string)"/> + /// <seealso cref="ToUtf8Buffer(string)"/> /// <param name="instance">The string to convert.</param> /// <returns>The string as UTF-16 encoded bytes.</returns> - public static byte[] ToUTF16Buffer(this string instance) + public static byte[] ToUtf16Buffer(this string instance) { return Encoding.Unicode.GetBytes(instance); } @@ -1796,28 +1749,28 @@ namespace Godot /// <summary> /// Converts the string (which is an array of characters) to an UTF-32 encoded array of bytes. /// </summary> - /// <seealso cref="ToASCIIBuffer(string)"/> - /// <seealso cref="ToUTF16Buffer(string)"/> - /// <seealso cref="ToUTF8Buffer(string)"/> + /// <seealso cref="ToAsciiBuffer(string)"/> + /// <seealso cref="ToUtf16Buffer(string)"/> + /// <seealso cref="ToUtf8Buffer(string)"/> /// <param name="instance">The string to convert.</param> /// <returns>The string as UTF-32 encoded bytes.</returns> - public static byte[] ToUTF32Buffer(this string instance) + public static byte[] ToUtf32Buffer(this string instance) { return Encoding.UTF32.GetBytes(instance); } /// <summary> /// Converts the string (which is an array of characters) to an UTF-8 encoded array of bytes. - /// The conversion is a bit slower than <see cref="ToASCIIBuffer(string)"/>, + /// The conversion is a bit slower than <see cref="ToAsciiBuffer(string)"/>, /// but supports all UTF-8 characters. Therefore, you should prefer this function - /// over <see cref="ToASCIIBuffer(string)"/>. + /// over <see cref="ToAsciiBuffer(string)"/>. /// </summary> - /// <seealso cref="ToASCIIBuffer(string)"/> - /// <seealso cref="ToUTF16Buffer(string)"/> - /// <seealso cref="ToUTF32Buffer(string)"/> + /// <seealso cref="ToAsciiBuffer(string)"/> + /// <seealso cref="ToUtf16Buffer(string)"/> + /// <seealso cref="ToUtf32Buffer(string)"/> /// <param name="instance">The string to convert.</param> /// <returns>The string as UTF-8 encoded bytes.</returns> - public static byte[] ToUTF8Buffer(this string instance) + public static byte[] ToUtf8Buffer(this string instance) { return Encoding.UTF8.GetBytes(instance); } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs index b9ee0bc278..97d28f9ee9 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs @@ -10,7 +10,7 @@ namespace Godot /// Comparing them is much faster than with regular strings, because only the pointers are compared, /// not the whole strings. /// </summary> - public sealed class StringName : IDisposable + public sealed class StringName : IDisposable, IEquatable<StringName> { internal godot_string_name.movable NativeValue; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs index fa060e3a53..d7392dbda8 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Godot @@ -18,22 +19,51 @@ namespace Godot /// <summary> /// The basis matrix's X vector (column 0). Equivalent to array index <c>[0]</c>. /// </summary> - public Vector2 x; + public Vector2 X; /// <summary> /// The basis matrix's Y vector (column 1). Equivalent to array index <c>[1]</c>. /// </summary> - public Vector2 y; + public Vector2 Y; /// <summary> /// The origin vector (column 2, the third column). Equivalent to array index <c>[2]</c>. /// The origin vector represents translation. /// </summary> - public Vector2 origin; + public Vector2 Origin; + + /// <summary> + /// Returns the transform's rotation (in radians). + /// </summary> + public readonly real_t Rotation => Mathf.Atan2(X.Y, X.X); + + /// <summary> + /// Returns the scale. + /// </summary> + public readonly Vector2 Scale + { + get + { + real_t detSign = Mathf.Sign(BasisDeterminant()); + return new Vector2(X.Length(), detSign * Y.Length()); + } + } + + /// <summary> + /// Returns the transform's skew (in radians). + /// </summary> + public readonly real_t Skew + { + get + { + real_t detSign = Mathf.Sign(BasisDeterminant()); + return Mathf.Acos(X.Normalized().Dot(detSign * Y.Normalized())) - Mathf.Pi * 0.5f; + } + } /// <summary> /// Access whole columns in the form of <see cref="Vector2"/>. - /// The third column is the <see cref="origin"/> vector. + /// The third column is the <see cref="Origin"/> vector. /// </summary> /// <param name="column">Which column vector.</param> /// <exception cref="ArgumentOutOfRangeException"> @@ -46,11 +76,11 @@ namespace Godot switch (column) { case 0: - return x; + return X; case 1: - return y; + return Y; case 2: - return origin; + return Origin; default: throw new ArgumentOutOfRangeException(nameof(column)); } @@ -60,13 +90,13 @@ namespace Godot switch (column) { case 0: - x = value; + X = value; return; case 1: - y = value; + Y = value; return; case 2: - origin = value; + Origin = value; return; default: throw new ArgumentOutOfRangeException(nameof(column)); @@ -76,7 +106,7 @@ namespace Godot /// <summary> /// Access matrix elements in column-major order. - /// The third column is the <see cref="origin"/> vector. + /// The third column is the <see cref="Origin"/> vector. /// </summary> /// <param name="column">Which column, the matrix horizontal position.</param> /// <param name="row">Which row, the matrix vertical position.</param> @@ -131,14 +161,15 @@ namespace Godot /// and is usually considered invalid. /// </summary> /// <returns>The determinant of the basis matrix.</returns> + [MethodImpl(MethodImplOptions.AggressiveInlining)] private readonly real_t BasisDeterminant() { - return (x.x * y.y) - (x.y * y.x); + return (X.X * Y.Y) - (X.Y * Y.X); } /// <summary> /// Returns a vector transformed (multiplied) by the basis matrix. - /// This method does not account for translation (the <see cref="origin"/> vector). + /// This method does not account for translation (the <see cref="Origin"/> vector). /// </summary> /// <seealso cref="BasisXformInv(Vector2)"/> /// <param name="v">A vector to transform.</param> @@ -150,7 +181,7 @@ namespace Godot /// <summary> /// Returns a vector transformed (multiplied) by the inverse basis matrix. - /// This method does not account for translation (the <see cref="origin"/> vector). + /// This method does not account for translation (the <see cref="Origin"/> vector). /// /// Note: This results in a multiplication by the inverse of the /// basis matrix only if it represents a rotation-reflection. @@ -160,24 +191,7 @@ namespace Godot /// <returns>The inversely transformed vector.</returns> public readonly Vector2 BasisXformInv(Vector2 v) { - return new Vector2(x.Dot(v), y.Dot(v)); - } - - /// <summary> - /// Returns the transform's rotation (in radians). - /// </summary> - public readonly real_t GetRotation() - { - return Mathf.Atan2(x.y, x.x); - } - - /// <summary> - /// Returns the scale. - /// </summary> - public readonly Vector2 GetScale() - { - real_t detSign = Mathf.Sign(BasisDeterminant()); - return new Vector2(x.Length(), detSign * y.Length()); + return new Vector2(X.Dot(v), Y.Dot(v)); } /// <summary> @@ -188,48 +202,13 @@ namespace Godot /// <returns>The interpolated transform.</returns> public readonly Transform2D InterpolateWith(Transform2D transform, real_t weight) { - real_t r1 = GetRotation(); - real_t r2 = transform.GetRotation(); - - Vector2 s1 = GetScale(); - Vector2 s2 = transform.GetScale(); - - // Slerp rotation - (real_t sin1, real_t cos1) = Mathf.SinCos(r1); - (real_t sin2, real_t cos2) = Mathf.SinCos(r2); - var v1 = new Vector2(cos1, sin1); - var v2 = new Vector2(cos2, sin2); - - real_t dot = v1.Dot(v2); - - dot = Mathf.Clamp(dot, -1.0f, 1.0f); - - Vector2 v; - - if (dot > 0.9995f) - { - // Linearly interpolate to avoid numerical precision issues - v = v1.Lerp(v2, weight).Normalized(); - } - else - { - real_t angle = weight * Mathf.Acos(dot); - Vector2 v3 = (v2 - (v1 * dot)).Normalized(); - (real_t sine, real_t cos) = Mathf.SinCos(angle); - v = (v1 * sine) + (v3 * cos); - } - - // Extract parameters - Vector2 p1 = origin; - Vector2 p2 = transform.origin; - - // Construct matrix - var res = new Transform2D(Mathf.Atan2(v.y, v.x), p1.Lerp(p2, weight)); - Vector2 scale = s1.Lerp(s2, weight); - res.x *= scale; - res.y *= scale; - - return res; + return new Transform2D + ( + Mathf.LerpAngle(Rotation, transform.Rotation, weight), + Scale.Lerp(transform.Scale, weight), + Mathf.LerpAngle(Skew, transform.Skew, weight), + Origin.Lerp(transform.Origin, weight) + ); } /// <summary> @@ -243,10 +222,10 @@ namespace Godot Transform2D inv = this; // Swap - inv.x.y = y.x; - inv.y.x = x.y; + inv.X.Y = Y.X; + inv.Y.X = X.Y; - inv.origin = inv.BasisXform(-inv.origin); + inv.Origin = inv.BasisXform(-inv.Origin); return inv; } @@ -258,7 +237,7 @@ namespace Godot /// <returns>Whether this vector is finite or not.</returns> public readonly bool IsFinite() { - return x.IsFinite() && y.IsFinite() && origin.IsFinite(); + return X.IsFinite() && Y.IsFinite() && Origin.IsFinite(); } /// <summary> @@ -268,19 +247,19 @@ namespace Godot /// <returns>The orthonormalized transform.</returns> public readonly Transform2D Orthonormalized() { - Transform2D on = this; + Transform2D ortho = this; - Vector2 onX = on.x; - Vector2 onY = on.y; + Vector2 orthoX = ortho.X; + Vector2 orthoY = ortho.Y; - onX.Normalize(); - onY = onY - (onX * onX.Dot(onY)); - onY.Normalize(); + orthoX.Normalize(); + orthoY = orthoY - orthoX * orthoX.Dot(orthoY); + orthoY.Normalize(); - on.x = onX; - on.y = onY; + ortho.X = orthoX; + ortho.Y = orthoY; - return on; + return ortho; } /// <summary> @@ -292,7 +271,7 @@ namespace Godot /// <returns>The rotated transformation matrix.</returns> public readonly Transform2D Rotated(real_t angle) { - return this * new Transform2D(angle, new Vector2()); + return new Transform2D(angle, new Vector2()) * this; } /// <summary> @@ -304,7 +283,7 @@ namespace Godot /// <returns>The rotated transformation matrix.</returns> public readonly Transform2D RotatedLocal(real_t angle) { - return new Transform2D(angle, new Vector2()) * this; + return this * new Transform2D(angle, new Vector2()); } /// <summary> @@ -317,9 +296,9 @@ namespace Godot public readonly Transform2D Scaled(Vector2 scale) { Transform2D copy = this; - copy.x *= scale; - copy.y *= scale; - copy.origin *= scale; + copy.X *= scale; + copy.Y *= scale; + copy.Origin *= scale; return copy; } @@ -333,8 +312,8 @@ namespace Godot public readonly Transform2D ScaledLocal(Vector2 scale) { Transform2D copy = this; - copy.x *= scale; - copy.y *= scale; + copy.X *= scale; + copy.Y *= scale; return copy; } @@ -358,7 +337,7 @@ namespace Godot public readonly Transform2D Translated(Vector2 offset) { Transform2D copy = this; - copy.origin += offset; + copy.Origin += offset; return copy; } @@ -372,7 +351,7 @@ namespace Godot public readonly Transform2D TranslatedLocal(Vector2 offset) { Transform2D copy = this; - copy.origin += copy.BasisXform(offset); + copy.Origin += copy.BasisXform(offset); return copy; } @@ -407,26 +386,26 @@ namespace Godot /// <param name="originPos">The origin vector, or column index 2.</param> public Transform2D(Vector2 xAxis, Vector2 yAxis, Vector2 originPos) { - x = xAxis; - y = yAxis; - origin = originPos; + X = xAxis; + Y = yAxis; + Origin = originPos; } /// <summary> /// Constructs a transformation matrix from the given components. - /// Arguments are named such that xy is equal to calling <c>x.y</c>. - /// </summary> - /// <param name="xx">The X component of the X column vector, accessed via <c>t.x.x</c> or <c>[0][0]</c>.</param> - /// <param name="xy">The Y component of the X column vector, accessed via <c>t.x.y</c> or <c>[0][1]</c>.</param> - /// <param name="yx">The X component of the Y column vector, accessed via <c>t.y.x</c> or <c>[1][0]</c>.</param> - /// <param name="yy">The Y component of the Y column vector, accessed via <c>t.y.y</c> or <c>[1][1]</c>.</param> - /// <param name="ox">The X component of the origin vector, accessed via <c>t.origin.x</c> or <c>[2][0]</c>.</param> - /// <param name="oy">The Y component of the origin vector, accessed via <c>t.origin.y</c> or <c>[2][1]</c>.</param> + /// Arguments are named such that xy is equal to calling <c>X.Y</c>. + /// </summary> + /// <param name="xx">The X component of the X column vector, accessed via <c>t.X.X</c> or <c>[0][0]</c>.</param> + /// <param name="xy">The Y component of the X column vector, accessed via <c>t.X.Y</c> or <c>[0][1]</c>.</param> + /// <param name="yx">The X component of the Y column vector, accessed via <c>t.Y.X</c> or <c>[1][0]</c>.</param> + /// <param name="yy">The Y component of the Y column vector, accessed via <c>t.Y.Y</c> or <c>[1][1]</c>.</param> + /// <param name="ox">The X component of the origin vector, accessed via <c>t.Origin.X</c> or <c>[2][0]</c>.</param> + /// <param name="oy">The Y component of the origin vector, accessed via <c>t.Origin.Y</c> or <c>[2][1]</c>.</param> public Transform2D(real_t xx, real_t xy, real_t yx, real_t yy, real_t ox, real_t oy) { - x = new Vector2(xx, xy); - y = new Vector2(yx, yy); - origin = new Vector2(ox, oy); + X = new Vector2(xx, xy); + Y = new Vector2(yx, yy); + Origin = new Vector2(ox, oy); } /// <summary> @@ -438,10 +417,10 @@ namespace Godot public Transform2D(real_t rotation, Vector2 origin) { (real_t sin, real_t cos) = Mathf.SinCos(rotation); - x.x = y.y = cos; - x.y = y.x = sin; - y.x *= -1; - this.origin = origin; + X.X = Y.Y = cos; + X.Y = Y.X = sin; + Y.X *= -1; + Origin = origin; } /// <summary> @@ -457,11 +436,11 @@ namespace Godot { (real_t rotationSin, real_t rotationCos) = Mathf.SinCos(rotation); (real_t rotationSkewSin, real_t rotationSkewCos) = Mathf.SinCos(rotation + skew); - x.x = rotationCos * scale.x; - y.y = rotationSkewCos * scale.y; - y.x = -rotationSkewSin * scale.y; - x.y = rotationSin * scale.x; - this.origin = origin; + X.X = rotationCos * scale.X; + Y.Y = rotationSkewCos * scale.Y; + Y.X = -rotationSkewSin * scale.Y; + X.Y = rotationSin * scale.X; + Origin = origin; } /// <summary> @@ -474,17 +453,17 @@ namespace Godot /// <returns>The composed transform.</returns> public static Transform2D operator *(Transform2D left, Transform2D right) { - left.origin = left * right.origin; + left.Origin = left * right.Origin; - real_t x0 = left.Tdotx(right.x); - real_t x1 = left.Tdoty(right.x); - real_t y0 = left.Tdotx(right.y); - real_t y1 = left.Tdoty(right.y); + real_t x0 = left.Tdotx(right.X); + real_t x1 = left.Tdoty(right.X); + real_t y0 = left.Tdotx(right.Y); + real_t y1 = left.Tdoty(right.Y); - left.x.x = x0; - left.x.y = x1; - left.y.x = y0; - left.y.y = y1; + left.X.X = x0; + left.X.Y = x1; + left.Y.X = y0; + left.Y.Y = y1; return left; } @@ -497,7 +476,7 @@ namespace Godot /// <returns>The transformed Vector2.</returns> public static Vector2 operator *(Transform2D transform, Vector2 vector) { - return new Vector2(transform.Tdotx(vector), transform.Tdoty(vector)) + transform.origin; + return new Vector2(transform.Tdotx(vector), transform.Tdoty(vector)) + transform.Origin; } /// <summary> @@ -508,8 +487,8 @@ namespace Godot /// <returns>The inversely transformed Vector2.</returns> public static Vector2 operator *(Vector2 vector, Transform2D transform) { - Vector2 vInv = vector - transform.origin; - return new Vector2(transform.x.Dot(vInv), transform.y.Dot(vInv)); + Vector2 vInv = vector - transform.Origin; + return new Vector2(transform.X.Dot(vInv), transform.Y.Dot(vInv)); } /// <summary> @@ -521,8 +500,8 @@ namespace Godot public static Rect2 operator *(Transform2D transform, Rect2 rect) { Vector2 pos = transform * rect.Position; - Vector2 toX = transform.x * rect.Size.x; - Vector2 toY = transform.y * rect.Size.y; + Vector2 toX = transform.X * rect.Size.X; + Vector2 toY = transform.Y * rect.Size.Y; return new Rect2(pos, new Vector2()).Expand(pos + toX).Expand(pos + toY).Expand(pos + toX + toY); } @@ -536,9 +515,9 @@ namespace Godot public static Rect2 operator *(Rect2 rect, Transform2D transform) { Vector2 pos = rect.Position * transform; - Vector2 to1 = new Vector2(rect.Position.x, rect.Position.y + rect.Size.y) * transform; - Vector2 to2 = new Vector2(rect.Position.x + rect.Size.x, rect.Position.y + rect.Size.y) * transform; - Vector2 to3 = new Vector2(rect.Position.x + rect.Size.x, rect.Position.y) * transform; + Vector2 to1 = new Vector2(rect.Position.X, rect.Position.Y + rect.Size.Y) * transform; + Vector2 to2 = new Vector2(rect.Position.X + rect.Size.X, rect.Position.Y + rect.Size.Y) * transform; + Vector2 to3 = new Vector2(rect.Position.X + rect.Size.X, rect.Position.Y) * transform; return new Rect2(pos, new Vector2()).Expand(to1).Expand(to2).Expand(to3); } @@ -627,7 +606,7 @@ namespace Godot /// <returns>Whether or not the matrices are exactly equal.</returns> public readonly bool Equals(Transform2D other) { - return x.Equals(other.x) && y.Equals(other.y) && origin.Equals(other.origin); + return X.Equals(other.X) && Y.Equals(other.Y) && Origin.Equals(other.Origin); } /// <summary> @@ -638,7 +617,7 @@ namespace Godot /// <returns>Whether or not the matrices are approximately equal.</returns> public readonly bool IsEqualApprox(Transform2D other) { - return x.IsEqualApprox(other.x) && y.IsEqualApprox(other.y) && origin.IsEqualApprox(other.origin); + return X.IsEqualApprox(other.X) && Y.IsEqualApprox(other.Y) && Origin.IsEqualApprox(other.Origin); } /// <summary> @@ -647,7 +626,7 @@ namespace Godot /// <returns>A hash code for this transform.</returns> public override readonly int GetHashCode() { - return x.GetHashCode() ^ y.GetHashCode() ^ origin.GetHashCode(); + return X.GetHashCode() ^ Y.GetHashCode() ^ Origin.GetHashCode(); } /// <summary> @@ -656,7 +635,7 @@ namespace Godot /// <returns>A string representation of this transform.</returns> public override readonly string ToString() { - return $"[X: {x}, Y: {y}, O: {origin}]"; + return $"[X: {X}, Y: {Y}, O: {Origin}]"; } /// <summary> @@ -665,7 +644,7 @@ namespace Godot /// <returns>A string representation of this transform.</returns> public readonly string ToString(string format) { - return $"[X: {x.ToString(format)}, Y: {y.ToString(format)}, O: {origin.ToString(format)}]"; + return $"[X: {X.ToString(format)}, Y: {Y.ToString(format)}, O: {Origin.ToString(format)}]"; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs index 6b2475fc59..b34e95c04d 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs @@ -6,7 +6,7 @@ namespace Godot /// <summary> /// 3×4 matrix (3 rows, 4 columns) used for 3D linear transformations. /// It can represent transformations such as translation, rotation, or scaling. - /// It consists of a <see cref="Basis"/> (first 3 columns) and a + /// It consists of a <see cref="Godot.Basis"/> (first 3 columns) and a /// <see cref="Vector3"/> for the origin (last column). /// /// For more information, read this documentation article: @@ -17,19 +17,19 @@ namespace Godot public struct Transform3D : IEquatable<Transform3D> { /// <summary> - /// The <see cref="Basis"/> of this transform. Contains the X, Y, and Z basis + /// The <see cref="Godot.Basis"/> of this transform. Contains the X, Y, and Z basis /// vectors (columns 0 to 2) and is responsible for rotation and scale. /// </summary> - public Basis basis; + public Basis Basis; /// <summary> /// The origin vector (column 3, the fourth column). Equivalent to array index <c>[3]</c>. /// </summary> - public Vector3 origin; + public Vector3 Origin; /// <summary> /// Access whole columns in the form of <see cref="Vector3"/>. - /// The fourth column is the <see cref="origin"/> vector. + /// The fourth column is the <see cref="Origin"/> vector. /// </summary> /// <param name="column">Which column vector.</param> /// <exception cref="ArgumentOutOfRangeException"> @@ -42,13 +42,13 @@ namespace Godot switch (column) { case 0: - return basis.Column0; + return Basis.Column0; case 1: - return basis.Column1; + return Basis.Column1; case 2: - return basis.Column2; + return Basis.Column2; case 3: - return origin; + return Origin; default: throw new ArgumentOutOfRangeException(nameof(column)); } @@ -58,16 +58,16 @@ namespace Godot switch (column) { case 0: - basis.Column0 = value; + Basis.Column0 = value; return; case 1: - basis.Column1 = value; + Basis.Column1 = value; return; case 2: - basis.Column2 = value; + Basis.Column2 = value; return; case 3: - origin = value; + Origin = value; return; default: throw new ArgumentOutOfRangeException(nameof(column)); @@ -77,7 +77,7 @@ namespace Godot /// <summary> /// Access matrix elements in column-major order. - /// The fourth column is the <see cref="origin"/> vector. + /// The fourth column is the <see cref="Origin"/> vector. /// </summary> /// <param name="column">Which column, the matrix horizontal position.</param> /// <param name="row">Which row, the matrix vertical position.</param> @@ -87,18 +87,18 @@ namespace Godot { if (column == 3) { - return origin[row]; + return Origin[row]; } - return basis[column, row]; + return Basis[column, row]; } set { if (column == 3) { - origin[row] = value; + Origin[row] = value; return; } - basis[column, row] = value; + Basis[column, row] = value; } } @@ -110,8 +110,8 @@ namespace Godot /// <returns>The inverse transformation matrix.</returns> public readonly Transform3D AffineInverse() { - Basis basisInv = basis.Inverse(); - return new Transform3D(basisInv, basisInv * -origin); + Basis basisInv = Basis.Inverse(); + return new Transform3D(basisInv, basisInv * -Origin); } /// <summary> @@ -124,19 +124,19 @@ namespace Godot /// <returns>The interpolated transform.</returns> public readonly Transform3D InterpolateWith(Transform3D transform, real_t weight) { - Vector3 sourceScale = basis.GetScale(); - Quaternion sourceRotation = basis.GetRotationQuaternion(); - Vector3 sourceLocation = origin; + Vector3 sourceScale = Basis.Scale; + Quaternion sourceRotation = Basis.GetRotationQuaternion(); + Vector3 sourceLocation = Origin; - Vector3 destinationScale = transform.basis.GetScale(); - Quaternion destinationRotation = transform.basis.GetRotationQuaternion(); - Vector3 destinationLocation = transform.origin; + Vector3 destinationScale = transform.Basis.Scale; + Quaternion destinationRotation = transform.Basis.GetRotationQuaternion(); + Vector3 destinationLocation = transform.Origin; var interpolated = new Transform3D(); Quaternion quaternion = sourceRotation.Slerp(destinationRotation, weight).Normalized(); Vector3 scale = sourceScale.Lerp(destinationScale, weight); - interpolated.basis.SetQuaternionScale(quaternion, scale); - interpolated.origin = sourceLocation.Lerp(destinationLocation, weight); + interpolated.Basis.SetQuaternionScale(quaternion, scale); + interpolated.Origin = sourceLocation.Lerp(destinationLocation, weight); return interpolated; } @@ -149,8 +149,8 @@ namespace Godot /// <returns>The inverse matrix.</returns> public readonly Transform3D Inverse() { - Basis basisTr = basis.Transposed(); - return new Transform3D(basisTr, basisTr * -origin); + Basis basisTr = Basis.Transposed(); + return new Transform3D(basisTr, basisTr * -Origin); } /// <summary> @@ -160,7 +160,7 @@ namespace Godot /// <returns>Whether this vector is finite or not.</returns> public readonly bool IsFinite() { - return basis.IsFinite() && origin.IsFinite(); + return Basis.IsFinite() && Origin.IsFinite(); } /// <summary> @@ -179,7 +179,7 @@ namespace Godot public readonly Transform3D LookingAt(Vector3 target, Vector3 up) { Transform3D t = this; - t.SetLookAt(origin, target, up); + t.SetLookAt(Origin, target, up); return t; } @@ -190,7 +190,7 @@ namespace Godot /// <returns>The orthonormalized transform.</returns> public readonly Transform3D Orthonormalized() { - return new Transform3D(basis.Orthonormalized(), origin); + return new Transform3D(Basis.Orthonormalized(), Origin); } /// <summary> @@ -219,7 +219,7 @@ namespace Godot public readonly Transform3D RotatedLocal(Vector3 axis, real_t angle) { Basis tmpBasis = new Basis(axis, angle); - return new Transform3D(basis * tmpBasis, origin); + return new Transform3D(Basis * tmpBasis, Origin); } /// <summary> @@ -231,7 +231,7 @@ namespace Godot /// <returns>The scaled transformation matrix.</returns> public readonly Transform3D Scaled(Vector3 scale) { - return new Transform3D(basis.Scaled(scale), origin * scale); + return new Transform3D(Basis.Scaled(scale), Origin * scale); } /// <summary> @@ -244,7 +244,7 @@ namespace Godot public readonly Transform3D ScaledLocal(Vector3 scale) { Basis tmpBasis = Basis.FromScale(scale); - return new Transform3D(basis * tmpBasis, origin); + return new Transform3D(Basis * tmpBasis, Origin); } private void SetLookAt(Vector3 eye, Vector3 target, Vector3 up) @@ -265,9 +265,9 @@ namespace Godot column0.Normalize(); column1.Normalize(); - basis = new Basis(column0, column1, column2); + Basis = new Basis(column0, column1, column2); - origin = eye; + Origin = eye; } /// <summary> @@ -279,7 +279,7 @@ namespace Godot /// <returns>The translated matrix.</returns> public readonly Transform3D Translated(Vector3 offset) { - return new Transform3D(basis, origin + offset); + return new Transform3D(Basis, Origin + offset); } /// <summary> @@ -291,11 +291,11 @@ namespace Godot /// <returns>The translated matrix.</returns> public readonly Transform3D TranslatedLocal(Vector3 offset) { - return new Transform3D(basis, new Vector3 + return new Transform3D(Basis, new Vector3 ( - origin[0] + basis.Row0.Dot(offset), - origin[1] + basis.Row1.Dot(offset), - origin[2] + basis.Row2.Dot(offset) + Origin[0] + Basis.Row0.Dot(offset), + Origin[1] + Basis.Row1.Dot(offset), + Origin[2] + Basis.Row2.Dot(offset) )); } @@ -337,64 +337,64 @@ namespace Godot /// <param name="origin">The origin vector, or column index 3.</param> public Transform3D(Vector3 column0, Vector3 column1, Vector3 column2, Vector3 origin) { - basis = new Basis(column0, column1, column2); - this.origin = origin; + Basis = new Basis(column0, column1, column2); + Origin = origin; } /// <summary> /// Constructs a transformation matrix from the given components. - /// Arguments are named such that xy is equal to calling <c>basis.x.y</c>. - /// </summary> - /// <param name="xx">The X component of the X column vector, accessed via <c>t.basis.x.x</c> or <c>[0][0]</c>.</param> - /// <param name="yx">The X component of the Y column vector, accessed via <c>t.basis.y.x</c> or <c>[1][0]</c>.</param> - /// <param name="zx">The X component of the Z column vector, accessed via <c>t.basis.z.x</c> or <c>[2][0]</c>.</param> - /// <param name="xy">The Y component of the X column vector, accessed via <c>t.basis.x.y</c> or <c>[0][1]</c>.</param> - /// <param name="yy">The Y component of the Y column vector, accessed via <c>t.basis.y.y</c> or <c>[1][1]</c>.</param> - /// <param name="zy">The Y component of the Z column vector, accessed via <c>t.basis.y.y</c> or <c>[2][1]</c>.</param> - /// <param name="xz">The Z component of the X column vector, accessed via <c>t.basis.x.y</c> or <c>[0][2]</c>.</param> - /// <param name="yz">The Z component of the Y column vector, accessed via <c>t.basis.y.y</c> or <c>[1][2]</c>.</param> - /// <param name="zz">The Z component of the Z column vector, accessed via <c>t.basis.y.y</c> or <c>[2][2]</c>.</param> - /// <param name="ox">The X component of the origin vector, accessed via <c>t.origin.x</c> or <c>[2][0]</c>.</param> - /// <param name="oy">The Y component of the origin vector, accessed via <c>t.origin.y</c> or <c>[2][1]</c>.</param> - /// <param name="oz">The Z component of the origin vector, accessed via <c>t.origin.z</c> or <c>[2][2]</c>.</param> + /// Arguments are named such that xy is equal to calling <c>Basis.X.Y</c>. + /// </summary> + /// <param name="xx">The X component of the X column vector, accessed via <c>t.Basis.X.X</c> or <c>[0][0]</c>.</param> + /// <param name="yx">The X component of the Y column vector, accessed via <c>t.Basis.Y.X</c> or <c>[1][0]</c>.</param> + /// <param name="zx">The X component of the Z column vector, accessed via <c>t.Basis.Z.X</c> or <c>[2][0]</c>.</param> + /// <param name="xy">The Y component of the X column vector, accessed via <c>t.Basis.X.Y</c> or <c>[0][1]</c>.</param> + /// <param name="yy">The Y component of the Y column vector, accessed via <c>t.Basis.Y.Y</c> or <c>[1][1]</c>.</param> + /// <param name="zy">The Y component of the Z column vector, accessed via <c>t.Basis.Y.Y</c> or <c>[2][1]</c>.</param> + /// <param name="xz">The Z component of the X column vector, accessed via <c>t.Basis.X.Y</c> or <c>[0][2]</c>.</param> + /// <param name="yz">The Z component of the Y column vector, accessed via <c>t.Basis.Y.Y</c> or <c>[1][2]</c>.</param> + /// <param name="zz">The Z component of the Z column vector, accessed via <c>t.Basis.Y.Y</c> or <c>[2][2]</c>.</param> + /// <param name="ox">The X component of the origin vector, accessed via <c>t.Origin.X</c> or <c>[2][0]</c>.</param> + /// <param name="oy">The Y component of the origin vector, accessed via <c>t.Origin.Y</c> or <c>[2][1]</c>.</param> + /// <param name="oz">The Z component of the origin vector, accessed via <c>t.Origin.Z</c> or <c>[2][2]</c>.</param> public Transform3D(real_t xx, real_t yx, real_t zx, real_t xy, real_t yy, real_t zy, real_t xz, real_t yz, real_t zz, real_t ox, real_t oy, real_t oz) { - basis = new Basis(xx, yx, zx, xy, yy, zy, xz, yz, zz); - origin = new Vector3(ox, oy, oz); + Basis = new Basis(xx, yx, zx, xy, yy, zy, xz, yz, zz); + Origin = new Vector3(ox, oy, oz); } /// <summary> /// Constructs a transformation matrix from the given <paramref name="basis"/> and /// <paramref name="origin"/> vector. /// </summary> - /// <param name="basis">The <see cref="Basis"/> to create the basis from.</param> + /// <param name="basis">The <see cref="Godot.Basis"/> to create the basis from.</param> /// <param name="origin">The origin vector, or column index 3.</param> public Transform3D(Basis basis, Vector3 origin) { - this.basis = basis; - this.origin = origin; + Basis = basis; + Origin = origin; } /// <summary> /// Constructs a transformation matrix from the given <paramref name="projection"/> - /// by trimming the last row of the projection matrix (<c>projection.x.w</c>, - /// <c>projection.y.w</c>, <c>projection.z.w</c>, and <c>projection.w.w</c> + /// by trimming the last row of the projection matrix (<c>projection.X.W</c>, + /// <c>projection.Y.W</c>, <c>projection.Z.W</c>, and <c>projection.W.W</c> /// are not copied over). /// </summary> /// <param name="projection">The <see cref="Projection"/> to create the transform from.</param> public Transform3D(Projection projection) { - basis = new Basis + Basis = new Basis ( - projection.x.x, projection.y.x, projection.z.x, - projection.x.y, projection.y.y, projection.z.y, - projection.x.z, projection.y.z, projection.z.z + projection.X.X, projection.Y.X, projection.Z.X, + projection.X.Y, projection.Y.Y, projection.Z.Y, + projection.X.Z, projection.Y.Z, projection.Z.Z ); - origin = new Vector3 + Origin = new Vector3 ( - projection.w.x, - projection.w.y, - projection.w.z + projection.W.X, + projection.W.Y, + projection.W.Z ); } @@ -408,8 +408,8 @@ namespace Godot /// <returns>The composed transform.</returns> public static Transform3D operator *(Transform3D left, Transform3D right) { - left.origin = left * right.origin; - left.basis *= right.basis; + left.Origin = left * right.Origin; + left.Basis *= right.Basis; return left; } @@ -423,9 +423,9 @@ namespace Godot { return new Vector3 ( - transform.basis.Row0.Dot(vector) + transform.origin.x, - transform.basis.Row1.Dot(vector) + transform.origin.y, - transform.basis.Row2.Dot(vector) + transform.origin.z + transform.Basis.Row0.Dot(vector) + transform.Origin.X, + transform.Basis.Row1.Dot(vector) + transform.Origin.Y, + transform.Basis.Row2.Dot(vector) + transform.Origin.Z ); } @@ -440,13 +440,13 @@ namespace Godot /// <returns>The inversely transformed Vector3.</returns> public static Vector3 operator *(Vector3 vector, Transform3D transform) { - Vector3 vInv = vector - transform.origin; + Vector3 vInv = vector - transform.Origin; return new Vector3 ( - (transform.basis.Row0[0] * vInv.x) + (transform.basis.Row1[0] * vInv.y) + (transform.basis.Row2[0] * vInv.z), - (transform.basis.Row0[1] * vInv.x) + (transform.basis.Row1[1] * vInv.y) + (transform.basis.Row2[1] * vInv.z), - (transform.basis.Row0[2] * vInv.x) + (transform.basis.Row1[2] * vInv.y) + (transform.basis.Row2[2] * vInv.z) + (transform.Basis.Row0[0] * vInv.X) + (transform.Basis.Row1[0] * vInv.Y) + (transform.Basis.Row2[0] * vInv.Z), + (transform.Basis.Row0[1] * vInv.X) + (transform.Basis.Row1[1] * vInv.Y) + (transform.Basis.Row2[1] * vInv.Z), + (transform.Basis.Row0[2] * vInv.X) + (transform.Basis.Row1[2] * vInv.Y) + (transform.Basis.Row2[2] * vInv.Z) ); } @@ -456,19 +456,19 @@ namespace Godot /// <param name="transform">The transformation to apply.</param> /// <param name="aabb">An AABB to transform.</param> /// <returns>The transformed AABB.</returns> - public static AABB operator *(Transform3D transform, AABB aabb) + public static Aabb operator *(Transform3D transform, Aabb aabb) { Vector3 min = aabb.Position; Vector3 max = aabb.Position + aabb.Size; - Vector3 tmin = transform.origin; - Vector3 tmax = transform.origin; + Vector3 tmin = transform.Origin; + Vector3 tmax = transform.Origin; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { - real_t e = transform.basis[i][j] * min[j]; - real_t f = transform.basis[i][j] * max[j]; + real_t e = transform.Basis[i][j] * min[j]; + real_t f = transform.Basis[i][j] * max[j]; if (e < f) { tmin[i] += e; @@ -482,7 +482,7 @@ namespace Godot } } - return new AABB(tmin, tmax - tmin); + return new Aabb(tmin, tmax - tmin); } /// <summary> @@ -491,18 +491,18 @@ namespace Godot /// <param name="aabb">An AABB to inversely transform.</param> /// <param name="transform">The transformation to apply.</param> /// <returns>The inversely transformed AABB.</returns> - public static AABB operator *(AABB aabb, Transform3D transform) + public static Aabb operator *(Aabb aabb, Transform3D transform) { - Vector3 pos = new Vector3(aabb.Position.x + aabb.Size.x, aabb.Position.y + aabb.Size.y, aabb.Position.z + aabb.Size.z) * transform; - Vector3 to1 = new Vector3(aabb.Position.x + aabb.Size.x, aabb.Position.y + aabb.Size.y, aabb.Position.z) * transform; - Vector3 to2 = new Vector3(aabb.Position.x + aabb.Size.x, aabb.Position.y, aabb.Position.z + aabb.Size.z) * transform; - Vector3 to3 = new Vector3(aabb.Position.x + aabb.Size.x, aabb.Position.y, aabb.Position.z) * transform; - Vector3 to4 = new Vector3(aabb.Position.x, aabb.Position.y + aabb.Size.y, aabb.Position.z + aabb.Size.z) * transform; - Vector3 to5 = new Vector3(aabb.Position.x, aabb.Position.y + aabb.Size.y, aabb.Position.z) * transform; - Vector3 to6 = new Vector3(aabb.Position.x, aabb.Position.y, aabb.Position.z + aabb.Size.z) * transform; - Vector3 to7 = new Vector3(aabb.Position.x, aabb.Position.y, aabb.Position.z) * transform; + Vector3 pos = new Vector3(aabb.Position.X + aabb.Size.X, aabb.Position.Y + aabb.Size.Y, aabb.Position.Z + aabb.Size.Z) * transform; + Vector3 to1 = new Vector3(aabb.Position.X + aabb.Size.X, aabb.Position.Y + aabb.Size.Y, aabb.Position.Z) * transform; + Vector3 to2 = new Vector3(aabb.Position.X + aabb.Size.X, aabb.Position.Y, aabb.Position.Z + aabb.Size.Z) * transform; + Vector3 to3 = new Vector3(aabb.Position.X + aabb.Size.X, aabb.Position.Y, aabb.Position.Z) * transform; + Vector3 to4 = new Vector3(aabb.Position.X, aabb.Position.Y + aabb.Size.Y, aabb.Position.Z + aabb.Size.Z) * transform; + Vector3 to5 = new Vector3(aabb.Position.X, aabb.Position.Y + aabb.Size.Y, aabb.Position.Z) * transform; + Vector3 to6 = new Vector3(aabb.Position.X, aabb.Position.Y, aabb.Position.Z + aabb.Size.Z) * transform; + Vector3 to7 = new Vector3(aabb.Position.X, aabb.Position.Y, aabb.Position.Z) * transform; - return new AABB(pos, new Vector3()).Expand(to1).Expand(to2).Expand(to3).Expand(to4).Expand(to5).Expand(to6).Expand(to7); + return new Aabb(pos, new Vector3()).Expand(to1).Expand(to2).Expand(to3).Expand(to4).Expand(to5).Expand(to6).Expand(to7); } /// <summary> @@ -513,7 +513,7 @@ namespace Godot /// <returns>The transformed Plane.</returns> public static Plane operator *(Transform3D transform, Plane plane) { - Basis bInvTrans = transform.basis.Inverse().Transposed(); + Basis bInvTrans = transform.Basis.Inverse().Transposed(); // Transform a single point on the plane. Vector3 point = transform * (plane.Normal * plane.D); @@ -534,7 +534,7 @@ namespace Godot public static Plane operator *(Plane plane, Transform3D transform) { Transform3D tInv = transform.AffineInverse(); - Basis bTrans = transform.basis.Transposed(); + Basis bTrans = transform.Basis.Transposed(); // Transform a single point on the plane. Vector3 point = tInv * (plane.Normal * plane.D); @@ -637,7 +637,7 @@ namespace Godot /// <returns>Whether or not the matrices are exactly equal.</returns> public readonly bool Equals(Transform3D other) { - return basis.Equals(other.basis) && origin.Equals(other.origin); + return Basis.Equals(other.Basis) && Origin.Equals(other.Origin); } /// <summary> @@ -648,7 +648,7 @@ namespace Godot /// <returns>Whether or not the matrices are approximately equal.</returns> public readonly bool IsEqualApprox(Transform3D other) { - return basis.IsEqualApprox(other.basis) && origin.IsEqualApprox(other.origin); + return Basis.IsEqualApprox(other.Basis) && Origin.IsEqualApprox(other.Origin); } /// <summary> @@ -657,7 +657,7 @@ namespace Godot /// <returns>A hash code for this transform.</returns> public override readonly int GetHashCode() { - return basis.GetHashCode() ^ origin.GetHashCode(); + return Basis.GetHashCode() ^ Origin.GetHashCode(); } /// <summary> @@ -666,7 +666,7 @@ namespace Godot /// <returns>A string representation of this transform.</returns> public override readonly string ToString() { - return $"[X: {basis.x}, Y: {basis.y}, Z: {basis.z}, O: {origin}]"; + return $"[X: {Basis.X}, Y: {Basis.Y}, Z: {Basis.Z}, O: {Origin}]"; } /// <summary> @@ -675,7 +675,7 @@ namespace Godot /// <returns>A string representation of this transform.</returns> public readonly string ToString(string format) { - return $"[X: {basis.x.ToString(format)}, Y: {basis.y.ToString(format)}, Z: {basis.z.ToString(format)}, O: {origin.ToString(format)}]"; + return $"[X: {Basis.X.ToString(format)}, Y: {Basis.Y.ToString(format)}, Z: {Basis.Z.ToString(format)}, O: {Origin.ToString(format)}]"; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Variant.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Variant.cs index da12309217..9aad965ad0 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Variant.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Variant.cs @@ -60,13 +60,13 @@ public partial struct Variant : IDisposable case Type.Int: case Type.Float: case Type.Vector2: - case Type.Vector2i: + case Type.Vector2I: case Type.Rect2: - case Type.Rect2i: + case Type.Rect2I: case Type.Vector3: - case Type.Vector3i: + case Type.Vector3I: case Type.Vector4: - case Type.Vector4i: + case Type.Vector4I: case Type.Plane: case Type.Quaternion: case Type.Color: @@ -117,24 +117,24 @@ public partial struct Variant : IDisposable Type.Float => AsDouble(), Type.String => AsString(), Type.Vector2 => AsVector2(), - Type.Vector2i => AsVector2i(), + Type.Vector2I => AsVector2I(), Type.Rect2 => AsRect2(), - Type.Rect2i => AsRect2i(), + Type.Rect2I => AsRect2I(), Type.Vector3 => AsVector3(), - Type.Vector3i => AsVector3i(), - Type.Transform2d => AsTransform2D(), + Type.Vector3I => AsVector3I(), + Type.Transform2D => AsTransform2D(), Type.Vector4 => AsVector4(), - Type.Vector4i => AsVector4i(), + Type.Vector4I => AsVector4I(), Type.Plane => AsPlane(), Type.Quaternion => AsQuaternion(), - Type.Aabb => AsAABB(), + Type.Aabb => AsAabb(), Type.Basis => AsBasis(), - Type.Transform3d => AsTransform3D(), + Type.Transform3D => AsTransform3D(), Type.Projection => AsProjection(), Type.Color => AsColor(), Type.StringName => AsStringName(), Type.NodePath => AsNodePath(), - Type.Rid => AsRID(), + Type.Rid => AsRid(), Type.Object => AsGodotObject(), Type.Callable => AsCallable(), Type.Signal => AsSignal(), @@ -219,16 +219,16 @@ public partial struct Variant : IDisposable VariantUtils.ConvertToVector2((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2i AsVector2i() => - VariantUtils.ConvertToVector2i((godot_variant)NativeVar); + public Vector2I AsVector2I() => + VariantUtils.ConvertToVector2I((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] public Rect2 AsRect2() => VariantUtils.ConvertToRect2((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Rect2i AsRect2i() => - VariantUtils.ConvertToRect2i((godot_variant)NativeVar); + public Rect2I AsRect2I() => + VariantUtils.ConvertToRect2I((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] public Transform2D AsTransform2D() => @@ -239,8 +239,8 @@ public partial struct Variant : IDisposable VariantUtils.ConvertToVector3((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector3i AsVector3i() => - VariantUtils.ConvertToVector3i((godot_variant)NativeVar); + public Vector3I AsVector3I() => + VariantUtils.ConvertToVector3I((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] public Basis AsBasis() => @@ -259,16 +259,16 @@ public partial struct Variant : IDisposable VariantUtils.ConvertToVector4((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector4i AsVector4i() => - VariantUtils.ConvertToVector4i((godot_variant)NativeVar); + public Vector4I AsVector4I() => + VariantUtils.ConvertToVector4I((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] public Projection AsProjection() => VariantUtils.ConvertToProjection((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public AABB AsAABB() => - VariantUtils.ConvertToAABB((godot_variant)NativeVar); + public Aabb AsAabb() => + VariantUtils.ConvertToAabb((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] public Color AsColor() => @@ -324,15 +324,15 @@ public partial struct Variant : IDisposable [MethodImpl(MethodImplOptions.AggressiveInlining)] public T[] AsGodotObjectArray<T>() - where T : Godot.Object => + where T : GodotObject => VariantUtils.ConvertToSystemArrayOfGodotObject<T>((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Collections.Dictionary<TKey, TValue> AsGodotDictionary<TKey, TValue>() => + public Collections.Dictionary<TKey, TValue> AsGodotDictionary<[MustBeVariant] TKey, [MustBeVariant] TValue>() => VariantUtils.ConvertToDictionary<TKey, TValue>((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Collections.Array<T> AsGodotArray<T>() => + public Collections.Array<T> AsGodotArray<[MustBeVariant] T>() => VariantUtils.ConvertToArray<T>((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -344,11 +344,11 @@ public partial struct Variant : IDisposable VariantUtils.ConvertToSystemArrayOfNodePath((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public RID[] AsSystemArrayOfRID() => - VariantUtils.ConvertToSystemArrayOfRID((godot_variant)NativeVar); + public Rid[] AsSystemArrayOfRid() => + VariantUtils.ConvertToSystemArrayOfRid((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Godot.Object AsGodotObject() => + public GodotObject AsGodotObject() => VariantUtils.ConvertToGodotObject((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -360,8 +360,8 @@ public partial struct Variant : IDisposable VariantUtils.ConvertToNodePath((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public RID AsRID() => - VariantUtils.ConvertToRID((godot_variant)NativeVar); + public Rid AsRid() => + VariantUtils.ConvertToRid((godot_variant)NativeVar); [MethodImpl(MethodImplOptions.AggressiveInlining)] public Collections.Dictionary AsGodotDictionary() => @@ -416,13 +416,13 @@ public partial struct Variant : IDisposable public static explicit operator Vector2(Variant from) => from.AsVector2(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static explicit operator Vector2i(Variant from) => from.AsVector2i(); + public static explicit operator Vector2I(Variant from) => from.AsVector2I(); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static explicit operator Rect2(Variant from) => from.AsRect2(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static explicit operator Rect2i(Variant from) => from.AsRect2i(); + public static explicit operator Rect2I(Variant from) => from.AsRect2I(); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static explicit operator Transform2D(Variant from) => from.AsTransform2D(); @@ -431,7 +431,7 @@ public partial struct Variant : IDisposable public static explicit operator Vector3(Variant from) => from.AsVector3(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static explicit operator Vector3i(Variant from) => from.AsVector3i(); + public static explicit operator Vector3I(Variant from) => from.AsVector3I(); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static explicit operator Basis(Variant from) => from.AsBasis(); @@ -446,13 +446,13 @@ public partial struct Variant : IDisposable public static explicit operator Vector4(Variant from) => from.AsVector4(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static explicit operator Vector4i(Variant from) => from.AsVector4i(); + public static explicit operator Vector4I(Variant from) => from.AsVector4I(); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static explicit operator Projection(Variant from) => from.AsProjection(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static explicit operator AABB(Variant from) => from.AsAABB(); + public static explicit operator Aabb(Variant from) => from.AsAabb(); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static explicit operator Color(Variant from) => from.AsColor(); @@ -500,10 +500,10 @@ public partial struct Variant : IDisposable public static explicit operator NodePath[](Variant from) => from.AsSystemArrayOfNodePath(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static explicit operator RID[](Variant from) => from.AsSystemArrayOfRID(); + public static explicit operator Rid[](Variant from) => from.AsSystemArrayOfRid(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static explicit operator Godot.Object(Variant from) => from.AsGodotObject(); + public static explicit operator GodotObject(Variant from) => from.AsGodotObject(); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static explicit operator StringName(Variant from) => from.AsStringName(); @@ -512,7 +512,7 @@ public partial struct Variant : IDisposable public static explicit operator NodePath(Variant from) => from.AsNodePath(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static explicit operator RID(Variant from) => from.AsRID(); + public static explicit operator Rid(Variant from) => from.AsRid(); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static explicit operator Collections.Dictionary(Variant from) => from.AsGodotDictionary(); @@ -566,13 +566,13 @@ public partial struct Variant : IDisposable public static Variant CreateFrom(Vector2 from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Variant CreateFrom(Vector2i from) => from; + public static Variant CreateFrom(Vector2I from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Variant CreateFrom(Rect2 from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Variant CreateFrom(Rect2i from) => from; + public static Variant CreateFrom(Rect2I from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Variant CreateFrom(Transform2D from) => from; @@ -581,7 +581,7 @@ public partial struct Variant : IDisposable public static Variant CreateFrom(Vector3 from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Variant CreateFrom(Vector3i from) => from; + public static Variant CreateFrom(Vector3I from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Variant CreateFrom(Basis from) => from; @@ -596,13 +596,13 @@ public partial struct Variant : IDisposable public static Variant CreateFrom(Vector4 from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Variant CreateFrom(Vector4i from) => from; + public static Variant CreateFrom(Vector4I from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Variant CreateFrom(Projection from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Variant CreateFrom(AABB from) => from; + public static Variant CreateFrom(Aabb from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Variant CreateFrom(Color from) => from; @@ -644,14 +644,14 @@ public partial struct Variant : IDisposable public static Variant CreateFrom(Span<Color> from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Variant CreateFrom(Godot.Object[] from) => from; + public static Variant CreateFrom(GodotObject[] from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Variant CreateFrom<TKey, TValue>(Collections.Dictionary<TKey, TValue> from) => + public static Variant CreateFrom<[MustBeVariant] TKey, [MustBeVariant] TValue>(Collections.Dictionary<TKey, TValue> from) => CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromDictionary(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Variant CreateFrom<T>(Collections.Array<T> from) => + public static Variant CreateFrom<[MustBeVariant] T>(Collections.Array<T> from) => CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromArray(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -661,10 +661,10 @@ public partial struct Variant : IDisposable public static Variant CreateFrom(Span<NodePath> from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Variant CreateFrom(Span<RID> from) => from; + public static Variant CreateFrom(Span<Rid> from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Variant CreateFrom(Godot.Object from) => from; + public static Variant CreateFrom(GodotObject from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Variant CreateFrom(StringName from) => from; @@ -673,7 +673,7 @@ public partial struct Variant : IDisposable public static Variant CreateFrom(NodePath from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Variant CreateFrom(RID from) => from; + public static Variant CreateFrom(Rid from) => from; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Variant CreateFrom(Collections.Dictionary from) => from; @@ -740,16 +740,16 @@ public partial struct Variant : IDisposable CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromVector2(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Variant(Vector2i from) => - CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromVector2i(from)); + public static implicit operator Variant(Vector2I from) => + CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromVector2I(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Variant(Rect2 from) => CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromRect2(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Variant(Rect2i from) => - CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromRect2i(from)); + public static implicit operator Variant(Rect2I from) => + CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromRect2I(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Variant(Transform2D from) => @@ -760,8 +760,8 @@ public partial struct Variant : IDisposable CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromVector3(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Variant(Vector3i from) => - CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromVector3i(from)); + public static implicit operator Variant(Vector3I from) => + CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromVector3I(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Variant(Basis from) => @@ -780,16 +780,16 @@ public partial struct Variant : IDisposable CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromVector4(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Variant(Vector4i from) => - CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromVector4i(from)); + public static implicit operator Variant(Vector4I from) => + CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromVector4I(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Variant(Projection from) => CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromProjection(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Variant(AABB from) => - CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromAABB(from)); + public static implicit operator Variant(Aabb from) => + CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromAabb(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Variant(Color from) => @@ -844,7 +844,7 @@ public partial struct Variant : IDisposable (Variant)from.AsSpan(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Variant(Godot.Object[] from) => + public static implicit operator Variant(GodotObject[] from) => CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemArrayOfGodotObject(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -856,7 +856,7 @@ public partial struct Variant : IDisposable (Variant)from.AsSpan(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Variant(RID[] from) => + public static implicit operator Variant(Rid[] from) => (Variant)from.AsSpan(); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -904,11 +904,11 @@ public partial struct Variant : IDisposable CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemArrayOfNodePath(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Variant(Span<RID> from) => - CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemArrayOfRID(from)); + public static implicit operator Variant(Span<Rid> from) => + CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromSystemArrayOfRid(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Variant(Godot.Object from) => + public static implicit operator Variant(GodotObject from) => CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromGodotObject(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -920,8 +920,8 @@ public partial struct Variant : IDisposable CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromNodePath(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Variant(RID from) => - CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromRID(from)); + public static implicit operator Variant(Rid from) => + CreateTakingOwnershipOfDisposableValue(VariantUtils.CreateFromRid(from)); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Variant(Collections.Dictionary from) => diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index 07cb34cadd..0bf8f25f06 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -29,12 +29,12 @@ namespace Godot /// <summary> /// The vector's X component. Also accessible by using the index position <c>[0]</c>. /// </summary> - public real_t x; + public real_t X; /// <summary> /// The vector's Y component. Also accessible by using the index position <c>[1]</c>. /// </summary> - public real_t y; + public real_t Y; /// <summary> /// Access vector components using their index. @@ -43,8 +43,8 @@ namespace Godot /// <paramref name="index"/> is not 0 or 1. /// </exception> /// <value> - /// <c>[0]</c> is equivalent to <see cref="x"/>, - /// <c>[1]</c> is equivalent to <see cref="y"/>. + /// <c>[0]</c> is equivalent to <see cref="X"/>, + /// <c>[1]</c> is equivalent to <see cref="Y"/>. /// </value> public real_t this[int index] { @@ -53,9 +53,9 @@ namespace Godot switch (index) { case 0: - return x; + return X; case 1: - return y; + return Y; default: throw new ArgumentOutOfRangeException(nameof(index)); } @@ -65,10 +65,10 @@ namespace Godot switch (index) { case 0: - x = value; + X = value; return; case 1: - y = value; + Y = value; return; default: throw new ArgumentOutOfRangeException(nameof(index)); @@ -81,8 +81,8 @@ namespace Godot /// </summary> public readonly void Deconstruct(out real_t x, out real_t y) { - x = this.x; - y = this.y; + x = X; + y = Y; } internal void Normalize() @@ -91,13 +91,13 @@ namespace Godot if (lengthsq == 0) { - x = y = 0f; + X = Y = 0f; } else { real_t length = Mathf.Sqrt(lengthsq); - x /= length; - y /= length; + X /= length; + Y /= length; } } @@ -107,19 +107,19 @@ namespace Godot /// <returns>A vector with <see cref="Mathf.Abs(real_t)"/> called on each component.</returns> public readonly Vector2 Abs() { - return new Vector2(Mathf.Abs(x), Mathf.Abs(y)); + return new Vector2(Mathf.Abs(X), Mathf.Abs(Y)); } /// <summary> /// Returns this vector's angle with respect to the X axis, or (1, 0) vector, in radians. /// /// Equivalent to the result of <see cref="Mathf.Atan2(real_t, real_t)"/> when - /// called with the vector's <see cref="y"/> and <see cref="x"/> as parameters: <c>Mathf.Atan2(v.y, v.x)</c>. + /// called with the vector's <see cref="Y"/> and <see cref="X"/> as parameters: <c>Mathf.Atan2(v.Y, v.X)</c>. /// </summary> /// <returns>The angle of this vector, in radians.</returns> public readonly real_t Angle() { - return Mathf.Atan2(y, x); + return Mathf.Atan2(Y, X); } /// <summary> @@ -139,16 +139,16 @@ namespace Godot /// <returns>The angle between the two vectors, in radians.</returns> public readonly real_t AngleToPoint(Vector2 to) { - return Mathf.Atan2(to.y - y, to.x - x); + return Mathf.Atan2(to.Y - Y, to.X - X); } /// <summary> - /// Returns the aspect ratio of this vector, the ratio of <see cref="x"/> to <see cref="y"/>. + /// Returns the aspect ratio of this vector, the ratio of <see cref="X"/> to <see cref="Y"/>. /// </summary> - /// <returns>The <see cref="x"/> component divided by the <see cref="y"/> component.</returns> + /// <returns>The <see cref="X"/> component divided by the <see cref="Y"/> component.</returns> public readonly real_t Aspect() { - return x / y; + return X / Y; } /// <summary> @@ -167,7 +167,7 @@ namespace Godot /// <returns>A vector with <see cref="Mathf.Ceil"/> called on each component.</returns> public readonly Vector2 Ceil() { - return new Vector2(Mathf.Ceil(x), Mathf.Ceil(y)); + return new Vector2(Mathf.Ceil(X), Mathf.Ceil(Y)); } /// <summary> @@ -182,8 +182,8 @@ namespace Godot { return new Vector2 ( - Mathf.Clamp(x, min.x, max.x), - Mathf.Clamp(y, min.y, max.y) + Mathf.Clamp(X, min.X, max.X), + Mathf.Clamp(Y, min.Y, max.Y) ); } @@ -194,7 +194,7 @@ namespace Godot /// <returns>The cross product value.</returns> public readonly real_t Cross(Vector2 with) { - return (x * with.y) - (y * with.x); + return (X * with.Y) - (Y * with.X); } /// <summary> @@ -210,8 +210,8 @@ namespace Godot { return new Vector2 ( - Mathf.CubicInterpolate(x, b.x, preA.x, postB.x, weight), - Mathf.CubicInterpolate(y, b.y, preA.y, postB.y, weight) + Mathf.CubicInterpolate(X, b.X, preA.X, postB.X, weight), + Mathf.CubicInterpolate(Y, b.Y, preA.Y, postB.Y, weight) ); } @@ -233,8 +233,8 @@ namespace Godot { return new Vector2 ( - Mathf.CubicInterpolateInTime(x, b.x, preA.x, postB.x, weight, t, preAT, postBT), - Mathf.CubicInterpolateInTime(y, b.y, preA.y, postB.y, weight, t, preAT, postBT) + Mathf.CubicInterpolateInTime(X, b.X, preA.X, postB.X, weight, t, preAT, postBT), + Mathf.CubicInterpolateInTime(Y, b.Y, preA.Y, postB.Y, weight, t, preAT, postBT) ); } @@ -251,8 +251,8 @@ namespace Godot { return new Vector2 ( - Mathf.BezierInterpolate(x, control1.x, control2.x, end.x, t), - Mathf.BezierInterpolate(y, control1.y, control2.y, end.y, t) + Mathf.BezierInterpolate(X, control1.X, control2.X, end.X, t), + Mathf.BezierInterpolate(Y, control1.Y, control2.Y, end.Y, t) ); } @@ -268,8 +268,8 @@ namespace Godot public readonly Vector2 BezierDerivative(Vector2 control1, Vector2 control2, Vector2 end, real_t t) { return new Vector2( - Mathf.BezierDerivative(x, control1.x, control2.x, end.x, t), - Mathf.BezierDerivative(y, control1.y, control2.y, end.y, t) + Mathf.BezierDerivative(X, control1.X, control2.X, end.X, t), + Mathf.BezierDerivative(Y, control1.Y, control2.Y, end.Y, t) ); } @@ -280,7 +280,7 @@ namespace Godot /// <returns>The direction from this vector to <paramref name="to"/>.</returns> public readonly Vector2 DirectionTo(Vector2 to) { - return new Vector2(to.x - x, to.y - y).Normalized(); + return new Vector2(to.X - X, to.Y - Y).Normalized(); } /// <summary> @@ -292,7 +292,7 @@ namespace Godot /// <returns>The squared distance between the two vectors.</returns> public readonly real_t DistanceSquaredTo(Vector2 to) { - return (x - to.x) * (x - to.x) + (y - to.y) * (y - to.y); + return (X - to.X) * (X - to.X) + (Y - to.Y) * (Y - to.Y); } /// <summary> @@ -302,7 +302,7 @@ namespace Godot /// <returns>The distance between the two vectors.</returns> public readonly real_t DistanceTo(Vector2 to) { - return Mathf.Sqrt((x - to.x) * (x - to.x) + (y - to.y) * (y - to.y)); + return Mathf.Sqrt((X - to.X) * (X - to.X) + (Y - to.Y) * (Y - to.Y)); } /// <summary> @@ -312,7 +312,7 @@ namespace Godot /// <returns>The dot product of the two vectors.</returns> public readonly real_t Dot(Vector2 with) { - return (x * with.x) + (y * with.y); + return (X * with.X) + (Y * with.Y); } /// <summary> @@ -321,16 +321,16 @@ namespace Godot /// <returns>A vector with <see cref="Mathf.Floor"/> called on each component.</returns> public readonly Vector2 Floor() { - return new Vector2(Mathf.Floor(x), Mathf.Floor(y)); + return new Vector2(Mathf.Floor(X), Mathf.Floor(Y)); } /// <summary> - /// Returns the inverse of this vector. This is the same as <c>new Vector2(1 / v.x, 1 / v.y)</c>. + /// Returns the inverse of this vector. This is the same as <c>new Vector2(1 / v.X, 1 / v.Y)</c>. /// </summary> /// <returns>The inverse of this vector.</returns> public readonly Vector2 Inverse() { - return new Vector2(1 / x, 1 / y); + return new Vector2(1 / X, 1 / Y); } /// <summary> @@ -340,7 +340,7 @@ namespace Godot /// <returns>Whether this vector is finite or not.</returns> public readonly bool IsFinite() { - return Mathf.IsFinite(x) && Mathf.IsFinite(y); + return Mathf.IsFinite(X) && Mathf.IsFinite(Y); } /// <summary> @@ -359,7 +359,7 @@ namespace Godot /// <returns>The length of this vector.</returns> public readonly real_t Length() { - return Mathf.Sqrt((x * x) + (y * y)); + return Mathf.Sqrt((X * X) + (Y * Y)); } /// <summary> @@ -370,7 +370,7 @@ namespace Godot /// <returns>The squared length of this vector.</returns> public readonly real_t LengthSquared() { - return (x * x) + (y * y); + return (X * X) + (Y * Y); } /// <summary> @@ -384,8 +384,8 @@ namespace Godot { return new Vector2 ( - Mathf.Lerp(x, to.x, weight), - Mathf.Lerp(y, to.y, weight) + Mathf.Lerp(X, to.X, weight), + Mathf.Lerp(Y, to.Y, weight) ); } @@ -415,7 +415,7 @@ namespace Godot /// <returns>The index of the highest axis.</returns> public readonly Axis MaxAxisIndex() { - return x < y ? Axis.Y : Axis.X; + return X < Y ? Axis.Y : Axis.X; } /// <summary> @@ -425,7 +425,7 @@ namespace Godot /// <returns>The index of the lowest axis.</returns> public readonly Axis MinAxisIndex() { - return x < y ? Axis.X : Axis.Y; + return X < Y ? Axis.X : Axis.Y; } /// <summary> @@ -467,8 +467,8 @@ namespace Godot public readonly Vector2 PosMod(real_t mod) { Vector2 v; - v.x = Mathf.PosMod(x, mod); - v.y = Mathf.PosMod(y, mod); + v.X = Mathf.PosMod(X, mod); + v.Y = Mathf.PosMod(Y, mod); return v; } @@ -483,8 +483,8 @@ namespace Godot public readonly Vector2 PosMod(Vector2 modv) { Vector2 v; - v.x = Mathf.PosMod(x, modv.x); - v.y = Mathf.PosMod(y, modv.y); + v.X = Mathf.PosMod(X, modv.X); + v.Y = Mathf.PosMod(Y, modv.Y); return v; } @@ -524,8 +524,8 @@ namespace Godot (real_t sin, real_t cos) = Mathf.SinCos(angle); return new Vector2 ( - x * cos - y * sin, - x * sin + y * cos + X * cos - Y * sin, + X * sin + Y * cos ); } @@ -536,7 +536,7 @@ namespace Godot /// <returns>The rounded vector.</returns> public readonly Vector2 Round() { - return new Vector2(Mathf.Round(x), Mathf.Round(y)); + return new Vector2(Mathf.Round(X), Mathf.Round(Y)); } /// <summary> @@ -548,8 +548,8 @@ namespace Godot public readonly Vector2 Sign() { Vector2 v; - v.x = Mathf.Sign(x); - v.y = Mathf.Sign(y); + v.X = Mathf.Sign(X); + v.Y = Mathf.Sign(Y); return v; } @@ -597,7 +597,7 @@ namespace Godot /// <returns>The snapped vector.</returns> public readonly Vector2 Snapped(Vector2 step) { - return new Vector2(Mathf.Snapped(x, step.x), Mathf.Snapped(y, step.y)); + return new Vector2(Mathf.Snapped(X, step.X), Mathf.Snapped(Y, step.Y)); } /// <summary> @@ -607,7 +607,7 @@ namespace Godot /// <returns>The perpendicular vector.</returns> public readonly Vector2 Orthogonal() { - return new Vector2(y, -x); + return new Vector2(Y, -X); } // Constants @@ -664,8 +664,8 @@ namespace Godot /// <param name="y">The vector's Y component.</param> public Vector2(real_t x, real_t y) { - this.x = x; - this.y = y; + X = x; + Y = y; } /// <summary> @@ -689,8 +689,8 @@ namespace Godot /// <returns>The added vector.</returns> public static Vector2 operator +(Vector2 left, Vector2 right) { - left.x += right.x; - left.y += right.y; + left.X += right.X; + left.Y += right.Y; return left; } @@ -703,14 +703,14 @@ namespace Godot /// <returns>The subtracted vector.</returns> public static Vector2 operator -(Vector2 left, Vector2 right) { - left.x -= right.x; - left.y -= right.y; + left.X -= right.X; + left.Y -= right.Y; return left; } /// <summary> /// Returns the negative value of the <see cref="Vector2"/>. - /// This is the same as writing <c>new Vector2(-v.x, -v.y)</c>. + /// This is the same as writing <c>new Vector2(-v.X, -v.Y)</c>. /// This operation flips the direction of the vector while /// keeping the same magnitude. /// With floats, the number zero can be either positive or negative. @@ -719,8 +719,8 @@ namespace Godot /// <returns>The negated/flipped vector.</returns> public static Vector2 operator -(Vector2 vec) { - vec.x = -vec.x; - vec.y = -vec.y; + vec.X = -vec.X; + vec.Y = -vec.Y; return vec; } @@ -733,8 +733,8 @@ namespace Godot /// <returns>The multiplied vector.</returns> public static Vector2 operator *(Vector2 vec, real_t scale) { - vec.x *= scale; - vec.y *= scale; + vec.X *= scale; + vec.Y *= scale; return vec; } @@ -747,8 +747,8 @@ namespace Godot /// <returns>The multiplied vector.</returns> public static Vector2 operator *(real_t scale, Vector2 vec) { - vec.x *= scale; - vec.y *= scale; + vec.X *= scale; + vec.Y *= scale; return vec; } @@ -761,8 +761,8 @@ namespace Godot /// <returns>The multiplied vector.</returns> public static Vector2 operator *(Vector2 left, Vector2 right) { - left.x *= right.x; - left.y *= right.y; + left.X *= right.X; + left.Y *= right.Y; return left; } @@ -775,8 +775,8 @@ namespace Godot /// <returns>The divided vector.</returns> public static Vector2 operator /(Vector2 vec, real_t divisor) { - vec.x /= divisor; - vec.y /= divisor; + vec.X /= divisor; + vec.Y /= divisor; return vec; } @@ -789,8 +789,8 @@ namespace Godot /// <returns>The divided vector.</returns> public static Vector2 operator /(Vector2 vec, Vector2 divisorv) { - vec.x /= divisorv.x; - vec.y /= divisorv.y; + vec.X /= divisorv.X; + vec.Y /= divisorv.Y; return vec; } @@ -812,8 +812,8 @@ namespace Godot /// <returns>The remainder vector.</returns> public static Vector2 operator %(Vector2 vec, real_t divisor) { - vec.x %= divisor; - vec.y %= divisor; + vec.X %= divisor; + vec.Y %= divisor; return vec; } @@ -835,8 +835,8 @@ namespace Godot /// <returns>The remainder vector.</returns> public static Vector2 operator %(Vector2 vec, Vector2 divisorv) { - vec.x %= divisorv.x; - vec.y %= divisorv.y; + vec.X %= divisorv.X; + vec.Y %= divisorv.Y; return vec; } @@ -879,11 +879,11 @@ namespace Godot /// <returns>Whether or not the left is less than the right.</returns> public static bool operator <(Vector2 left, Vector2 right) { - if (left.x == right.x) + if (left.X == right.X) { - return left.y < right.y; + return left.Y < right.Y; } - return left.x < right.x; + return left.X < right.X; } /// <summary> @@ -899,11 +899,11 @@ namespace Godot /// <returns>Whether or not the left is greater than the right.</returns> public static bool operator >(Vector2 left, Vector2 right) { - if (left.x == right.x) + if (left.X == right.X) { - return left.y > right.y; + return left.Y > right.Y; } - return left.x > right.x; + return left.X > right.X; } /// <summary> @@ -919,11 +919,11 @@ namespace Godot /// <returns>Whether or not the left is less than or equal to the right.</returns> public static bool operator <=(Vector2 left, Vector2 right) { - if (left.x == right.x) + if (left.X == right.X) { - return left.y <= right.y; + return left.Y <= right.Y; } - return left.x < right.x; + return left.X < right.X; } /// <summary> @@ -939,11 +939,11 @@ namespace Godot /// <returns>Whether or not the left is greater than or equal to the right.</returns> public static bool operator >=(Vector2 left, Vector2 right) { - if (left.x == right.x) + if (left.X == right.X) { - return left.y >= right.y; + return left.Y >= right.Y; } - return left.x > right.x; + return left.X > right.X; } /// <summary> @@ -968,7 +968,7 @@ namespace Godot /// <returns>Whether or not the vectors are exactly equal.</returns> public readonly bool Equals(Vector2 other) { - return x == other.x && y == other.y; + return X == other.X && Y == other.Y; } /// <summary> @@ -979,7 +979,7 @@ namespace Godot /// <returns>Whether or not the vectors are approximately equal.</returns> public readonly bool IsEqualApprox(Vector2 other) { - return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y); + return Mathf.IsEqualApprox(X, other.X) && Mathf.IsEqualApprox(Y, other.Y); } /// <summary> @@ -991,7 +991,7 @@ namespace Godot /// <returns>Whether or not the vector is approximately zero.</returns> public readonly bool IsZeroApprox() { - return Mathf.IsZeroApprox(x) && Mathf.IsZeroApprox(y); + return Mathf.IsZeroApprox(X) && Mathf.IsZeroApprox(Y); } /// <summary> @@ -1000,7 +1000,7 @@ namespace Godot /// <returns>A hash code for this vector.</returns> public override readonly int GetHashCode() { - return y.GetHashCode() ^ x.GetHashCode(); + return Y.GetHashCode() ^ X.GetHashCode(); } /// <summary> @@ -1009,7 +1009,7 @@ namespace Godot /// <returns>A string representation of this vector.</returns> public override readonly string ToString() { - return $"({x}, {y})"; + return $"({X}, {Y})"; } /// <summary> @@ -1018,7 +1018,7 @@ namespace Godot /// <returns>A string representation of this vector.</returns> public readonly string ToString(string format) { - return $"({x.ToString(format)}, {y.ToString(format)})"; + return $"({X.ToString(format)}, {Y.ToString(format)})"; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs index 740fedec66..e849939ebb 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs @@ -8,7 +8,7 @@ namespace Godot /// </summary> [Serializable] [StructLayout(LayoutKind.Sequential)] - public struct Vector2i : IEquatable<Vector2i> + public struct Vector2I : IEquatable<Vector2I> { /// <summary> /// Enumerated index values for the axes. @@ -29,12 +29,12 @@ namespace Godot /// <summary> /// The vector's X component. Also accessible by using the index position <c>[0]</c>. /// </summary> - public int x; + public int X; /// <summary> /// The vector's Y component. Also accessible by using the index position <c>[1]</c>. /// </summary> - public int y; + public int Y; /// <summary> /// Access vector components using their index. @@ -43,8 +43,8 @@ namespace Godot /// <paramref name="index"/> is not 0 or 1. /// </exception> /// <value> - /// <c>[0]</c> is equivalent to <see cref="x"/>, - /// <c>[1]</c> is equivalent to <see cref="y"/>. + /// <c>[0]</c> is equivalent to <see cref="X"/>, + /// <c>[1]</c> is equivalent to <see cref="Y"/>. /// </value> public int this[int index] { @@ -53,9 +53,9 @@ namespace Godot switch (index) { case 0: - return x; + return X; case 1: - return y; + return Y; default: throw new ArgumentOutOfRangeException(nameof(index)); } @@ -65,10 +65,10 @@ namespace Godot switch (index) { case 0: - x = value; + X = value; return; case 1: - y = value; + Y = value; return; default: throw new ArgumentOutOfRangeException(nameof(index)); @@ -81,26 +81,26 @@ namespace Godot /// </summary> public readonly void Deconstruct(out int x, out int y) { - x = this.x; - y = this.y; + x = X; + y = Y; } /// <summary> /// Returns a new vector with all components in absolute values (i.e. positive). /// </summary> /// <returns>A vector with <see cref="Mathf.Abs(int)"/> called on each component.</returns> - public readonly Vector2i Abs() + public readonly Vector2I Abs() { - return new Vector2i(Mathf.Abs(x), Mathf.Abs(y)); + return new Vector2I(Mathf.Abs(X), Mathf.Abs(Y)); } /// <summary> - /// Returns the aspect ratio of this vector, the ratio of <see cref="x"/> to <see cref="y"/>. + /// Returns the aspect ratio of this vector, the ratio of <see cref="X"/> to <see cref="Y"/>. /// </summary> - /// <returns>The <see cref="x"/> component divided by the <see cref="y"/> component.</returns> + /// <returns>The <see cref="X"/> component divided by the <see cref="Y"/> component.</returns> public readonly real_t Aspect() { - return x / (real_t)y; + return X / (real_t)Y; } /// <summary> @@ -111,12 +111,12 @@ namespace Godot /// <param name="min">The vector with minimum allowed values.</param> /// <param name="max">The vector with maximum allowed values.</param> /// <returns>The vector with all components clamped.</returns> - public readonly Vector2i Clamp(Vector2i min, Vector2i max) + public readonly Vector2I Clamp(Vector2I min, Vector2I max) { - return new Vector2i + return new Vector2I ( - Mathf.Clamp(x, min.x, max.x), - Mathf.Clamp(y, min.y, max.y) + Mathf.Clamp(X, min.X, max.X), + Mathf.Clamp(Y, min.Y, max.Y) ); } @@ -127,8 +127,8 @@ namespace Godot /// <returns>The length of this vector.</returns> public readonly real_t Length() { - int x2 = x * x; - int y2 = y * y; + int x2 = X * X; + int y2 = Y * Y; return Mathf.Sqrt(x2 + y2); } @@ -141,8 +141,8 @@ namespace Godot /// <returns>The squared length of this vector.</returns> public readonly int LengthSquared() { - int x2 = x * x; - int y2 = y * y; + int x2 = X * X; + int y2 = Y * Y; return x2 + y2; } @@ -154,7 +154,7 @@ namespace Godot /// <returns>The index of the highest axis.</returns> public readonly Axis MaxAxisIndex() { - return x < y ? Axis.Y : Axis.X; + return X < Y ? Axis.Y : Axis.X; } /// <summary> @@ -164,7 +164,7 @@ namespace Godot /// <returns>The index of the lowest axis.</returns> public readonly Axis MinAxisIndex() { - return x < y ? Axis.X : Axis.Y; + return X < Y ? Axis.X : Axis.Y; } /// <summary> @@ -173,181 +173,181 @@ namespace Godot /// by calling <see cref="Mathf.Sign(int)"/> on each component. /// </summary> /// <returns>A vector with all components as either <c>1</c>, <c>-1</c>, or <c>0</c>.</returns> - public readonly Vector2i Sign() + public readonly Vector2I Sign() { - Vector2i v = this; - v.x = Mathf.Sign(v.x); - v.y = Mathf.Sign(v.y); + Vector2I v = this; + v.X = Mathf.Sign(v.X); + v.Y = Mathf.Sign(v.Y); return v; } // Constants - private static readonly Vector2i _zero = new Vector2i(0, 0); - private static readonly Vector2i _one = new Vector2i(1, 1); + private static readonly Vector2I _zero = new Vector2I(0, 0); + private static readonly Vector2I _one = new Vector2I(1, 1); - private static readonly Vector2i _up = new Vector2i(0, -1); - private static readonly Vector2i _down = new Vector2i(0, 1); - private static readonly Vector2i _right = new Vector2i(1, 0); - private static readonly Vector2i _left = new Vector2i(-1, 0); + private static readonly Vector2I _up = new Vector2I(0, -1); + private static readonly Vector2I _down = new Vector2I(0, 1); + private static readonly Vector2I _right = new Vector2I(1, 0); + private static readonly Vector2I _left = new Vector2I(-1, 0); /// <summary> /// Zero vector, a vector with all components set to <c>0</c>. /// </summary> - /// <value>Equivalent to <c>new Vector2i(0, 0)</c>.</value> - public static Vector2i Zero { get { return _zero; } } + /// <value>Equivalent to <c>new Vector2I(0, 0)</c>.</value> + public static Vector2I Zero { get { return _zero; } } /// <summary> /// One vector, a vector with all components set to <c>1</c>. /// </summary> - /// <value>Equivalent to <c>new Vector2i(1, 1)</c>.</value> - public static Vector2i One { get { return _one; } } + /// <value>Equivalent to <c>new Vector2I(1, 1)</c>.</value> + public static Vector2I One { get { return _one; } } /// <summary> /// Up unit vector. Y is down in 2D, so this vector points -Y. /// </summary> - /// <value>Equivalent to <c>new Vector2i(0, -1)</c>.</value> - public static Vector2i Up { get { return _up; } } + /// <value>Equivalent to <c>new Vector2I(0, -1)</c>.</value> + public static Vector2I Up { get { return _up; } } /// <summary> /// Down unit vector. Y is down in 2D, so this vector points +Y. /// </summary> - /// <value>Equivalent to <c>new Vector2i(0, 1)</c>.</value> - public static Vector2i Down { get { return _down; } } + /// <value>Equivalent to <c>new Vector2I(0, 1)</c>.</value> + public static Vector2I Down { get { return _down; } } /// <summary> /// Right unit vector. Represents the direction of right. /// </summary> - /// <value>Equivalent to <c>new Vector2i(1, 0)</c>.</value> - public static Vector2i Right { get { return _right; } } + /// <value>Equivalent to <c>new Vector2I(1, 0)</c>.</value> + public static Vector2I Right { get { return _right; } } /// <summary> /// Left unit vector. Represents the direction of left. /// </summary> - /// <value>Equivalent to <c>new Vector2i(-1, 0)</c>.</value> - public static Vector2i Left { get { return _left; } } + /// <value>Equivalent to <c>new Vector2I(-1, 0)</c>.</value> + public static Vector2I Left { get { return _left; } } /// <summary> - /// Constructs a new <see cref="Vector2i"/> with the given components. + /// Constructs a new <see cref="Vector2I"/> with the given components. /// </summary> /// <param name="x">The vector's X component.</param> /// <param name="y">The vector's Y component.</param> - public Vector2i(int x, int y) + public Vector2I(int x, int y) { - this.x = x; - this.y = y; + X = x; + Y = y; } /// <summary> - /// Adds each component of the <see cref="Vector2i"/> - /// with the components of the given <see cref="Vector2i"/>. + /// Adds each component of the <see cref="Vector2I"/> + /// with the components of the given <see cref="Vector2I"/>. /// </summary> /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>The added vector.</returns> - public static Vector2i operator +(Vector2i left, Vector2i right) + public static Vector2I operator +(Vector2I left, Vector2I right) { - left.x += right.x; - left.y += right.y; + left.X += right.X; + left.Y += right.Y; return left; } /// <summary> - /// Subtracts each component of the <see cref="Vector2i"/> - /// by the components of the given <see cref="Vector2i"/>. + /// Subtracts each component of the <see cref="Vector2I"/> + /// by the components of the given <see cref="Vector2I"/>. /// </summary> /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>The subtracted vector.</returns> - public static Vector2i operator -(Vector2i left, Vector2i right) + public static Vector2I operator -(Vector2I left, Vector2I right) { - left.x -= right.x; - left.y -= right.y; + left.X -= right.X; + left.Y -= right.Y; return left; } /// <summary> - /// Returns the negative value of the <see cref="Vector2i"/>. - /// This is the same as writing <c>new Vector2i(-v.x, -v.y)</c>. + /// Returns the negative value of the <see cref="Vector2I"/>. + /// This is the same as writing <c>new Vector2I(-v.X, -v.Y)</c>. /// This operation flips the direction of the vector while /// keeping the same magnitude. /// </summary> /// <param name="vec">The vector to negate/flip.</param> /// <returns>The negated/flipped vector.</returns> - public static Vector2i operator -(Vector2i vec) + public static Vector2I operator -(Vector2I vec) { - vec.x = -vec.x; - vec.y = -vec.y; + vec.X = -vec.X; + vec.Y = -vec.Y; return vec; } /// <summary> - /// Multiplies each component of the <see cref="Vector2i"/> + /// Multiplies each component of the <see cref="Vector2I"/> /// by the given <see langword="int"/>. /// </summary> /// <param name="vec">The vector to multiply.</param> /// <param name="scale">The scale to multiply by.</param> /// <returns>The multiplied vector.</returns> - public static Vector2i operator *(Vector2i vec, int scale) + public static Vector2I operator *(Vector2I vec, int scale) { - vec.x *= scale; - vec.y *= scale; + vec.X *= scale; + vec.Y *= scale; return vec; } /// <summary> - /// Multiplies each component of the <see cref="Vector2i"/> + /// Multiplies each component of the <see cref="Vector2I"/> /// by the given <see langword="int"/>. /// </summary> /// <param name="scale">The scale to multiply by.</param> /// <param name="vec">The vector to multiply.</param> /// <returns>The multiplied vector.</returns> - public static Vector2i operator *(int scale, Vector2i vec) + public static Vector2I operator *(int scale, Vector2I vec) { - vec.x *= scale; - vec.y *= scale; + vec.X *= scale; + vec.Y *= scale; return vec; } /// <summary> - /// Multiplies each component of the <see cref="Vector2i"/> - /// by the components of the given <see cref="Vector2i"/>. + /// Multiplies each component of the <see cref="Vector2I"/> + /// by the components of the given <see cref="Vector2I"/>. /// </summary> /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>The multiplied vector.</returns> - public static Vector2i operator *(Vector2i left, Vector2i right) + public static Vector2I operator *(Vector2I left, Vector2I right) { - left.x *= right.x; - left.y *= right.y; + left.X *= right.X; + left.Y *= right.Y; return left; } /// <summary> - /// Divides each component of the <see cref="Vector2i"/> + /// Divides each component of the <see cref="Vector2I"/> /// by the given <see langword="int"/>. /// </summary> /// <param name="vec">The dividend vector.</param> /// <param name="divisor">The divisor value.</param> /// <returns>The divided vector.</returns> - public static Vector2i operator /(Vector2i vec, int divisor) + public static Vector2I operator /(Vector2I vec, int divisor) { - vec.x /= divisor; - vec.y /= divisor; + vec.X /= divisor; + vec.Y /= divisor; return vec; } /// <summary> - /// Divides each component of the <see cref="Vector2i"/> - /// by the components of the given <see cref="Vector2i"/>. + /// Divides each component of the <see cref="Vector2I"/> + /// by the components of the given <see cref="Vector2I"/>. /// </summary> /// <param name="vec">The dividend vector.</param> /// <param name="divisorv">The divisor vector.</param> /// <returns>The divided vector.</returns> - public static Vector2i operator /(Vector2i vec, Vector2i divisorv) + public static Vector2I operator /(Vector2I vec, Vector2I divisorv) { - vec.x /= divisorv.x; - vec.y /= divisorv.y; + vec.X /= divisorv.X; + vec.Y /= divisorv.Y; return vec; } /// <summary> - /// Gets the remainder of each component of the <see cref="Vector2i"/> + /// Gets the remainder of each component of the <see cref="Vector2I"/> /// with the components of the given <see langword="int"/>. /// This operation uses truncated division, which is often not desired /// as it does not work well with negative numbers. @@ -356,22 +356,22 @@ namespace Godot /// </summary> /// <example> /// <code> - /// GD.Print(new Vector2i(10, -20) % 7); // Prints "(3, -6)" + /// GD.Print(new Vector2I(10, -20) % 7); // Prints "(3, -6)" /// </code> /// </example> /// <param name="vec">The dividend vector.</param> /// <param name="divisor">The divisor value.</param> /// <returns>The remainder vector.</returns> - public static Vector2i operator %(Vector2i vec, int divisor) + public static Vector2I operator %(Vector2I vec, int divisor) { - vec.x %= divisor; - vec.y %= divisor; + vec.X %= divisor; + vec.Y %= divisor; return vec; } /// <summary> - /// Gets the remainder of each component of the <see cref="Vector2i"/> - /// with the components of the given <see cref="Vector2i"/>. + /// Gets the remainder of each component of the <see cref="Vector2I"/> + /// with the components of the given <see cref="Vector2I"/>. /// This operation uses truncated division, which is often not desired /// as it does not work well with negative numbers. /// Consider using <see cref="Mathf.PosMod(int, int)"/> instead @@ -379,16 +379,16 @@ namespace Godot /// </summary> /// <example> /// <code> - /// GD.Print(new Vector2i(10, -20) % new Vector2i(7, 8)); // Prints "(3, -4)" + /// GD.Print(new Vector2I(10, -20) % new Vector2I(7, 8)); // Prints "(3, -4)" /// </code> /// </example> /// <param name="vec">The dividend vector.</param> /// <param name="divisorv">The divisor vector.</param> /// <returns>The remainder vector.</returns> - public static Vector2i operator %(Vector2i vec, Vector2i divisorv) + public static Vector2I operator %(Vector2I vec, Vector2I divisorv) { - vec.x %= divisorv.x; - vec.y %= divisorv.y; + vec.X %= divisorv.X; + vec.Y %= divisorv.Y; return vec; } @@ -398,7 +398,7 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the vectors are equal.</returns> - public static bool operator ==(Vector2i left, Vector2i right) + public static bool operator ==(Vector2I left, Vector2I right) { return left.Equals(right); } @@ -409,13 +409,13 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the vectors are not equal.</returns> - public static bool operator !=(Vector2i left, Vector2i right) + public static bool operator !=(Vector2I left, Vector2I right) { return !left.Equals(right); } /// <summary> - /// Compares two <see cref="Vector2i"/> vectors by first checking if + /// Compares two <see cref="Vector2I"/> vectors by first checking if /// the X value of the <paramref name="left"/> vector is less than /// the X value of the <paramref name="right"/> vector. /// If the X values are exactly equal, then it repeats this check @@ -425,17 +425,17 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the left is less than the right.</returns> - public static bool operator <(Vector2i left, Vector2i right) + public static bool operator <(Vector2I left, Vector2I right) { - if (left.x == right.x) + if (left.X == right.X) { - return left.y < right.y; + return left.Y < right.Y; } - return left.x < right.x; + return left.X < right.X; } /// <summary> - /// Compares two <see cref="Vector2i"/> vectors by first checking if + /// Compares two <see cref="Vector2I"/> vectors by first checking if /// the X value of the <paramref name="left"/> vector is greater than /// the X value of the <paramref name="right"/> vector. /// If the X values are exactly equal, then it repeats this check @@ -445,17 +445,17 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the left is greater than the right.</returns> - public static bool operator >(Vector2i left, Vector2i right) + public static bool operator >(Vector2I left, Vector2I right) { - if (left.x == right.x) + if (left.X == right.X) { - return left.y > right.y; + return left.Y > right.Y; } - return left.x > right.x; + return left.X > right.X; } /// <summary> - /// Compares two <see cref="Vector2i"/> vectors by first checking if + /// Compares two <see cref="Vector2I"/> vectors by first checking if /// the X value of the <paramref name="left"/> vector is less than /// or equal to the X value of the <paramref name="right"/> vector. /// If the X values are exactly equal, then it repeats this check @@ -465,17 +465,17 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the left is less than or equal to the right.</returns> - public static bool operator <=(Vector2i left, Vector2i right) + public static bool operator <=(Vector2I left, Vector2I right) { - if (left.x == right.x) + if (left.X == right.X) { - return left.y <= right.y; + return left.Y <= right.Y; } - return left.x < right.x; + return left.X < right.X; } /// <summary> - /// Compares two <see cref="Vector2i"/> vectors by first checking if + /// Compares two <see cref="Vector2I"/> vectors by first checking if /// the X value of the <paramref name="left"/> vector is greater than /// or equal to the X value of the <paramref name="right"/> vector. /// If the X values are exactly equal, then it repeats this check @@ -485,33 +485,33 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the left is greater than or equal to the right.</returns> - public static bool operator >=(Vector2i left, Vector2i right) + public static bool operator >=(Vector2I left, Vector2I right) { - if (left.x == right.x) + if (left.X == right.X) { - return left.y >= right.y; + return left.Y >= right.Y; } - return left.x > right.x; + return left.X > right.X; } /// <summary> - /// Converts this <see cref="Vector2i"/> to a <see cref="Vector2"/>. + /// Converts this <see cref="Vector2I"/> to a <see cref="Vector2"/>. /// </summary> /// <param name="value">The vector to convert.</param> - public static implicit operator Vector2(Vector2i value) + public static implicit operator Vector2(Vector2I value) { - return new Vector2(value.x, value.y); + return new Vector2(value.X, value.Y); } /// <summary> - /// Converts a <see cref="Vector2"/> to a <see cref="Vector2i"/>. + /// Converts a <see cref="Vector2"/> to a <see cref="Vector2I"/>. /// </summary> /// <param name="value">The vector to convert.</param> - public static explicit operator Vector2i(Vector2 value) + public static explicit operator Vector2I(Vector2 value) { - return new Vector2i( - Mathf.RoundToInt(value.x), - Mathf.RoundToInt(value.y) + return new Vector2I( + Mathf.RoundToInt(value.X), + Mathf.RoundToInt(value.Y) ); } @@ -523,7 +523,7 @@ namespace Godot /// <returns>Whether or not the vector and the object are equal.</returns> public override readonly bool Equals(object obj) { - return obj is Vector2i other && Equals(other); + return obj is Vector2I other && Equals(other); } /// <summary> @@ -531,36 +531,36 @@ namespace Godot /// </summary> /// <param name="other">The other vector.</param> /// <returns>Whether or not the vectors are equal.</returns> - public readonly bool Equals(Vector2i other) + public readonly bool Equals(Vector2I other) { - return x == other.x && y == other.y; + return X == other.X && Y == other.Y; } /// <summary> - /// Serves as the hash function for <see cref="Vector2i"/>. + /// Serves as the hash function for <see cref="Vector2I"/>. /// </summary> /// <returns>A hash code for this vector.</returns> public override readonly int GetHashCode() { - return y.GetHashCode() ^ x.GetHashCode(); + return Y.GetHashCode() ^ X.GetHashCode(); } /// <summary> - /// Converts this <see cref="Vector2i"/> to a string. + /// Converts this <see cref="Vector2I"/> to a string. /// </summary> /// <returns>A string representation of this vector.</returns> public override readonly string ToString() { - return $"({x}, {y})"; + return $"({X}, {Y})"; } /// <summary> - /// Converts this <see cref="Vector2i"/> to a string with the given <paramref name="format"/>. + /// Converts this <see cref="Vector2I"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this vector.</returns> public readonly string ToString(string format) { - return $"({x.ToString(format)}, {y.ToString(format)})"; + return $"({X.ToString(format)}, {Y.ToString(format)})"; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index b017ba5853..c773c0fda6 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -33,17 +33,17 @@ namespace Godot /// <summary> /// The vector's X component. Also accessible by using the index position <c>[0]</c>. /// </summary> - public real_t x; + public real_t X; /// <summary> /// The vector's Y component. Also accessible by using the index position <c>[1]</c>. /// </summary> - public real_t y; + public real_t Y; /// <summary> /// The vector's Z component. Also accessible by using the index position <c>[2]</c>. /// </summary> - public real_t z; + public real_t Z; /// <summary> /// Access vector components using their index. @@ -52,9 +52,9 @@ namespace Godot /// <paramref name="index"/> is not 0, 1 or 2. /// </exception> /// <value> - /// <c>[0]</c> is equivalent to <see cref="x"/>, - /// <c>[1]</c> is equivalent to <see cref="y"/>, - /// <c>[2]</c> is equivalent to <see cref="z"/>. + /// <c>[0]</c> is equivalent to <see cref="X"/>, + /// <c>[1]</c> is equivalent to <see cref="Y"/>, + /// <c>[2]</c> is equivalent to <see cref="Z"/>. /// </value> public real_t this[int index] { @@ -63,11 +63,11 @@ namespace Godot switch (index) { case 0: - return x; + return X; case 1: - return y; + return Y; case 2: - return z; + return Z; default: throw new ArgumentOutOfRangeException(nameof(index)); } @@ -77,13 +77,13 @@ namespace Godot switch (index) { case 0: - x = value; + X = value; return; case 1: - y = value; + Y = value; return; case 2: - z = value; + Z = value; return; default: throw new ArgumentOutOfRangeException(nameof(index)); @@ -96,9 +96,9 @@ namespace Godot /// </summary> public readonly void Deconstruct(out real_t x, out real_t y, out real_t z) { - x = this.x; - y = this.y; - z = this.z; + x = X; + y = Y; + z = Z; } internal void Normalize() @@ -107,14 +107,14 @@ namespace Godot if (lengthsq == 0) { - x = y = z = 0f; + X = Y = Z = 0f; } else { real_t length = Mathf.Sqrt(lengthsq); - x /= length; - y /= length; - z /= length; + X /= length; + Y /= length; + Z /= length; } } @@ -124,7 +124,7 @@ namespace Godot /// <returns>A vector with <see cref="Mathf.Abs(real_t)"/> called on each component.</returns> public readonly Vector3 Abs() { - return new Vector3(Mathf.Abs(x), Mathf.Abs(y), Mathf.Abs(z)); + return new Vector3(Mathf.Abs(X), Mathf.Abs(Y), Mathf.Abs(Z)); } /// <summary> @@ -153,7 +153,7 @@ namespace Godot /// <returns>A vector with <see cref="Mathf.Ceil"/> called on each component.</returns> public readonly Vector3 Ceil() { - return new Vector3(Mathf.Ceil(x), Mathf.Ceil(y), Mathf.Ceil(z)); + return new Vector3(Mathf.Ceil(X), Mathf.Ceil(Y), Mathf.Ceil(Z)); } /// <summary> @@ -168,9 +168,9 @@ namespace Godot { return new Vector3 ( - Mathf.Clamp(x, min.x, max.x), - Mathf.Clamp(y, min.y, max.y), - Mathf.Clamp(z, min.z, max.z) + Mathf.Clamp(X, min.X, max.X), + Mathf.Clamp(Y, min.Y, max.Y), + Mathf.Clamp(Z, min.Z, max.Z) ); } @@ -183,9 +183,9 @@ namespace Godot { return new Vector3 ( - (y * with.z) - (z * with.y), - (z * with.x) - (x * with.z), - (x * with.y) - (y * with.x) + (Y * with.Z) - (Z * with.Y), + (Z * with.X) - (X * with.Z), + (X * with.Y) - (Y * with.X) ); } @@ -202,9 +202,9 @@ namespace Godot { return new Vector3 ( - Mathf.CubicInterpolate(x, b.x, preA.x, postB.x, weight), - Mathf.CubicInterpolate(y, b.y, preA.y, postB.y, weight), - Mathf.CubicInterpolate(z, b.z, preA.z, postB.z, weight) + Mathf.CubicInterpolate(X, b.X, preA.X, postB.X, weight), + Mathf.CubicInterpolate(Y, b.Y, preA.Y, postB.Y, weight), + Mathf.CubicInterpolate(Z, b.Z, preA.Z, postB.Z, weight) ); } @@ -226,9 +226,9 @@ namespace Godot { return new Vector3 ( - Mathf.CubicInterpolateInTime(x, b.x, preA.x, postB.x, weight, t, preAT, postBT), - Mathf.CubicInterpolateInTime(y, b.y, preA.y, postB.y, weight, t, preAT, postBT), - Mathf.CubicInterpolateInTime(z, b.z, preA.z, postB.z, weight, t, preAT, postBT) + Mathf.CubicInterpolateInTime(X, b.X, preA.X, postB.X, weight, t, preAT, postBT), + Mathf.CubicInterpolateInTime(Y, b.Y, preA.Y, postB.Y, weight, t, preAT, postBT), + Mathf.CubicInterpolateInTime(Z, b.Z, preA.Z, postB.Z, weight, t, preAT, postBT) ); } @@ -245,9 +245,9 @@ namespace Godot { return new Vector3 ( - Mathf.BezierInterpolate(x, control1.x, control2.x, end.x, t), - Mathf.BezierInterpolate(y, control1.y, control2.y, end.y, t), - Mathf.BezierInterpolate(z, control1.z, control2.z, end.z, t) + Mathf.BezierInterpolate(X, control1.X, control2.X, end.X, t), + Mathf.BezierInterpolate(Y, control1.Y, control2.Y, end.Y, t), + Mathf.BezierInterpolate(Z, control1.Z, control2.Z, end.Z, t) ); } @@ -263,9 +263,9 @@ namespace Godot public readonly Vector3 BezierDerivative(Vector3 control1, Vector3 control2, Vector3 end, real_t t) { return new Vector3( - Mathf.BezierDerivative(x, control1.x, control2.x, end.x, t), - Mathf.BezierDerivative(y, control1.y, control2.y, end.y, t), - Mathf.BezierDerivative(z, control1.z, control2.z, end.y, t) + Mathf.BezierDerivative(X, control1.X, control2.X, end.X, t), + Mathf.BezierDerivative(Y, control1.Y, control2.Y, end.Y, t), + Mathf.BezierDerivative(Z, control1.Z, control2.Z, end.Y, t) ); } @@ -276,7 +276,7 @@ namespace Godot /// <returns>The direction from this vector to <paramref name="to"/>.</returns> public readonly Vector3 DirectionTo(Vector3 to) { - return new Vector3(to.x - x, to.y - y, to.z - z).Normalized(); + return new Vector3(to.X - X, to.Y - Y, to.Z - Z).Normalized(); } /// <summary> @@ -309,7 +309,7 @@ namespace Godot /// <returns>The dot product of the two vectors.</returns> public readonly real_t Dot(Vector3 with) { - return (x * with.x) + (y * with.y) + (z * with.z); + return (X * with.X) + (Y * with.Y) + (Z * with.Z); } /// <summary> @@ -318,16 +318,16 @@ namespace Godot /// <returns>A vector with <see cref="Mathf.Floor"/> called on each component.</returns> public readonly Vector3 Floor() { - return new Vector3(Mathf.Floor(x), Mathf.Floor(y), Mathf.Floor(z)); + return new Vector3(Mathf.Floor(X), Mathf.Floor(Y), Mathf.Floor(Z)); } /// <summary> - /// Returns the inverse of this vector. This is the same as <c>new Vector3(1 / v.x, 1 / v.y, 1 / v.z)</c>. + /// Returns the inverse of this vector. This is the same as <c>new Vector3(1 / v.X, 1 / v.Y, 1 / v.Z)</c>. /// </summary> /// <returns>The inverse of this vector.</returns> public readonly Vector3 Inverse() { - return new Vector3(1 / x, 1 / y, 1 / z); + return new Vector3(1 / X, 1 / Y, 1 / Z); } /// <summary> @@ -337,7 +337,7 @@ namespace Godot /// <returns>Whether this vector is finite or not.</returns> public readonly bool IsFinite() { - return Mathf.IsFinite(x) && Mathf.IsFinite(y) && Mathf.IsFinite(z); + return Mathf.IsFinite(X) && Mathf.IsFinite(Y) && Mathf.IsFinite(Z); } /// <summary> @@ -356,9 +356,9 @@ namespace Godot /// <returns>The length of this vector.</returns> public readonly real_t Length() { - real_t x2 = x * x; - real_t y2 = y * y; - real_t z2 = z * z; + real_t x2 = X * X; + real_t y2 = Y * Y; + real_t z2 = Z * Z; return Mathf.Sqrt(x2 + y2 + z2); } @@ -371,9 +371,9 @@ namespace Godot /// <returns>The squared length of this vector.</returns> public readonly real_t LengthSquared() { - real_t x2 = x * x; - real_t y2 = y * y; - real_t z2 = z * z; + real_t x2 = X * X; + real_t y2 = Y * Y; + real_t z2 = Z * Z; return x2 + y2 + z2; } @@ -389,9 +389,9 @@ namespace Godot { return new Vector3 ( - Mathf.Lerp(x, to.x, weight), - Mathf.Lerp(y, to.y, weight), - Mathf.Lerp(z, to.z, weight) + Mathf.Lerp(X, to.X, weight), + Mathf.Lerp(Y, to.Y, weight), + Mathf.Lerp(Z, to.Z, weight) ); } @@ -421,7 +421,7 @@ namespace Godot /// <returns>The index of the highest axis.</returns> public readonly Axis MaxAxisIndex() { - return x < y ? (y < z ? Axis.Z : Axis.Y) : (x < z ? Axis.Z : Axis.X); + return X < Y ? (Y < Z ? Axis.Z : Axis.Y) : (X < Z ? Axis.Z : Axis.X); } /// <summary> @@ -431,7 +431,7 @@ namespace Godot /// <returns>The index of the lowest axis.</returns> public readonly Axis MinAxisIndex() { - return x < y ? (x < z ? Axis.X : Axis.Z) : (y < z ? Axis.Y : Axis.Z); + return X < Y ? (X < Z ? Axis.X : Axis.Z) : (Y < Z ? Axis.Y : Axis.Z); } /// <summary> @@ -470,9 +470,9 @@ namespace Godot public readonly Basis Outer(Vector3 with) { return new Basis( - x * with.x, x * with.y, x * with.z, - y * with.x, y * with.y, y * with.z, - z * with.x, z * with.y, z * with.z + X * with.X, X * with.Y, X * with.Z, + Y * with.X, Y * with.Y, Y * with.Z, + Z * with.X, Z * with.Y, Z * with.Z ); } @@ -487,9 +487,9 @@ namespace Godot public readonly Vector3 PosMod(real_t mod) { Vector3 v; - v.x = Mathf.PosMod(x, mod); - v.y = Mathf.PosMod(y, mod); - v.z = Mathf.PosMod(z, mod); + v.X = Mathf.PosMod(X, mod); + v.Y = Mathf.PosMod(Y, mod); + v.Z = Mathf.PosMod(Z, mod); return v; } @@ -504,9 +504,9 @@ namespace Godot public readonly Vector3 PosMod(Vector3 modv) { Vector3 v; - v.x = Mathf.PosMod(x, modv.x); - v.y = Mathf.PosMod(y, modv.y); - v.z = Mathf.PosMod(z, modv.z); + v.X = Mathf.PosMod(X, modv.X); + v.Y = Mathf.PosMod(Y, modv.Y); + v.Z = Mathf.PosMod(Z, modv.Z); return v; } @@ -561,7 +561,7 @@ namespace Godot /// <returns>The rounded vector.</returns> public readonly Vector3 Round() { - return new Vector3(Mathf.Round(x), Mathf.Round(y), Mathf.Round(z)); + return new Vector3(Mathf.Round(X), Mathf.Round(Y), Mathf.Round(Z)); } /// <summary> @@ -573,9 +573,9 @@ namespace Godot public readonly Vector3 Sign() { Vector3 v; - v.x = Mathf.Sign(x); - v.y = Mathf.Sign(y); - v.z = Mathf.Sign(z); + v.X = Mathf.Sign(X); + v.Y = Mathf.Sign(Y); + v.Z = Mathf.Sign(Z); return v; } @@ -642,9 +642,9 @@ namespace Godot { return new Vector3 ( - Mathf.Snapped(x, step.x), - Mathf.Snapped(y, step.y), - Mathf.Snapped(z, step.z) + Mathf.Snapped(X, step.X), + Mathf.Snapped(Y, step.Y), + Mathf.Snapped(Z, step.Z) ); } @@ -719,9 +719,9 @@ namespace Godot /// <param name="z">The vector's Z component.</param> public Vector3(real_t x, real_t y, real_t z) { - this.x = x; - this.y = y; - this.z = z; + X = x; + Y = y; + Z = z; } /// <summary> @@ -733,9 +733,9 @@ namespace Godot /// <returns>The added vector.</returns> public static Vector3 operator +(Vector3 left, Vector3 right) { - left.x += right.x; - left.y += right.y; - left.z += right.z; + left.X += right.X; + left.Y += right.Y; + left.Z += right.Z; return left; } @@ -748,15 +748,15 @@ namespace Godot /// <returns>The subtracted vector.</returns> public static Vector3 operator -(Vector3 left, Vector3 right) { - left.x -= right.x; - left.y -= right.y; - left.z -= right.z; + left.X -= right.X; + left.Y -= right.Y; + left.Z -= right.Z; return left; } /// <summary> /// Returns the negative value of the <see cref="Vector3"/>. - /// This is the same as writing <c>new Vector3(-v.x, -v.y, -v.z)</c>. + /// This is the same as writing <c>new Vector3(-v.X, -v.Y, -v.Z)</c>. /// This operation flips the direction of the vector while /// keeping the same magnitude. /// With floats, the number zero can be either positive or negative. @@ -765,9 +765,9 @@ namespace Godot /// <returns>The negated/flipped vector.</returns> public static Vector3 operator -(Vector3 vec) { - vec.x = -vec.x; - vec.y = -vec.y; - vec.z = -vec.z; + vec.X = -vec.X; + vec.Y = -vec.Y; + vec.Z = -vec.Z; return vec; } @@ -780,9 +780,9 @@ namespace Godot /// <returns>The multiplied vector.</returns> public static Vector3 operator *(Vector3 vec, real_t scale) { - vec.x *= scale; - vec.y *= scale; - vec.z *= scale; + vec.X *= scale; + vec.Y *= scale; + vec.Z *= scale; return vec; } @@ -795,9 +795,9 @@ namespace Godot /// <returns>The multiplied vector.</returns> public static Vector3 operator *(real_t scale, Vector3 vec) { - vec.x *= scale; - vec.y *= scale; - vec.z *= scale; + vec.X *= scale; + vec.Y *= scale; + vec.Z *= scale; return vec; } @@ -810,9 +810,9 @@ namespace Godot /// <returns>The multiplied vector.</returns> public static Vector3 operator *(Vector3 left, Vector3 right) { - left.x *= right.x; - left.y *= right.y; - left.z *= right.z; + left.X *= right.X; + left.Y *= right.Y; + left.Z *= right.Z; return left; } @@ -825,9 +825,9 @@ namespace Godot /// <returns>The divided vector.</returns> public static Vector3 operator /(Vector3 vec, real_t divisor) { - vec.x /= divisor; - vec.y /= divisor; - vec.z /= divisor; + vec.X /= divisor; + vec.Y /= divisor; + vec.Z /= divisor; return vec; } @@ -840,9 +840,9 @@ namespace Godot /// <returns>The divided vector.</returns> public static Vector3 operator /(Vector3 vec, Vector3 divisorv) { - vec.x /= divisorv.x; - vec.y /= divisorv.y; - vec.z /= divisorv.z; + vec.X /= divisorv.X; + vec.Y /= divisorv.Y; + vec.Z /= divisorv.Z; return vec; } @@ -864,9 +864,9 @@ namespace Godot /// <returns>The remainder vector.</returns> public static Vector3 operator %(Vector3 vec, real_t divisor) { - vec.x %= divisor; - vec.y %= divisor; - vec.z %= divisor; + vec.X %= divisor; + vec.Y %= divisor; + vec.Z %= divisor; return vec; } @@ -888,9 +888,9 @@ namespace Godot /// <returns>The remainder vector.</returns> public static Vector3 operator %(Vector3 vec, Vector3 divisorv) { - vec.x %= divisorv.x; - vec.y %= divisorv.y; - vec.z %= divisorv.z; + vec.X %= divisorv.X; + vec.Y %= divisorv.Y; + vec.Z %= divisorv.Z; return vec; } @@ -933,15 +933,15 @@ namespace Godot /// <returns>Whether or not the left is less than the right.</returns> public static bool operator <(Vector3 left, Vector3 right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - return left.z < right.z; + return left.Z < right.Z; } - return left.y < right.y; + return left.Y < right.Y; } - return left.x < right.x; + return left.X < right.X; } /// <summary> @@ -957,15 +957,15 @@ namespace Godot /// <returns>Whether or not the left is greater than the right.</returns> public static bool operator >(Vector3 left, Vector3 right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - return left.z > right.z; + return left.Z > right.Z; } - return left.y > right.y; + return left.Y > right.Y; } - return left.x > right.x; + return left.X > right.X; } /// <summary> @@ -981,15 +981,15 @@ namespace Godot /// <returns>Whether or not the left is less than or equal to the right.</returns> public static bool operator <=(Vector3 left, Vector3 right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - return left.z <= right.z; + return left.Z <= right.Z; } - return left.y < right.y; + return left.Y < right.Y; } - return left.x < right.x; + return left.X < right.X; } /// <summary> @@ -1005,15 +1005,15 @@ namespace Godot /// <returns>Whether or not the left is greater than or equal to the right.</returns> public static bool operator >=(Vector3 left, Vector3 right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - return left.z >= right.z; + return left.Z >= right.Z; } - return left.y > right.y; + return left.Y > right.Y; } - return left.x > right.x; + return left.X > right.X; } /// <summary> @@ -1038,7 +1038,7 @@ namespace Godot /// <returns>Whether or not the vectors are exactly equal.</returns> public readonly bool Equals(Vector3 other) { - return x == other.x && y == other.y && z == other.z; + return X == other.X && Y == other.Y && Z == other.Z; } /// <summary> @@ -1049,7 +1049,7 @@ namespace Godot /// <returns>Whether or not the vectors are approximately equal.</returns> public readonly bool IsEqualApprox(Vector3 other) { - return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y) && Mathf.IsEqualApprox(z, other.z); + return Mathf.IsEqualApprox(X, other.X) && Mathf.IsEqualApprox(Y, other.Y) && Mathf.IsEqualApprox(Z, other.Z); } /// <summary> @@ -1061,7 +1061,7 @@ namespace Godot /// <returns>Whether or not the vector is approximately zero.</returns> public readonly bool IsZeroApprox() { - return Mathf.IsZeroApprox(x) && Mathf.IsZeroApprox(y) && Mathf.IsZeroApprox(z); + return Mathf.IsZeroApprox(X) && Mathf.IsZeroApprox(Y) && Mathf.IsZeroApprox(Z); } /// <summary> @@ -1070,7 +1070,7 @@ namespace Godot /// <returns>A hash code for this vector.</returns> public override readonly int GetHashCode() { - return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode(); + return Y.GetHashCode() ^ X.GetHashCode() ^ Z.GetHashCode(); } /// <summary> @@ -1079,7 +1079,7 @@ namespace Godot /// <returns>A string representation of this vector.</returns> public override readonly string ToString() { - return $"({x}, {y}, {z})"; + return $"({X}, {Y}, {Z})"; } /// <summary> @@ -1088,7 +1088,7 @@ namespace Godot /// <returns>A string representation of this vector.</returns> public readonly string ToString(string format) { - return $"({x.ToString(format)}, {y.ToString(format)}, {z.ToString(format)})"; + return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)})"; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs index de0c6d27e7..fe899527ef 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs @@ -8,7 +8,7 @@ namespace Godot /// </summary> [Serializable] [StructLayout(LayoutKind.Sequential)] - public struct Vector3i : IEquatable<Vector3i> + public struct Vector3I : IEquatable<Vector3I> { /// <summary> /// Enumerated index values for the axes. @@ -33,17 +33,17 @@ namespace Godot /// <summary> /// The vector's X component. Also accessible by using the index position <c>[0]</c>. /// </summary> - public int x; + public int X; /// <summary> /// The vector's Y component. Also accessible by using the index position <c>[1]</c>. /// </summary> - public int y; + public int Y; /// <summary> /// The vector's Z component. Also accessible by using the index position <c>[2]</c>. /// </summary> - public int z; + public int Z; /// <summary> /// Access vector components using their <paramref name="index"/>. @@ -52,9 +52,9 @@ namespace Godot /// <paramref name="index"/> is not 0, 1 or 2. /// </exception> /// <value> - /// <c>[0]</c> is equivalent to <see cref="x"/>, - /// <c>[1]</c> is equivalent to <see cref="y"/>, - /// <c>[2]</c> is equivalent to <see cref="z"/>. + /// <c>[0]</c> is equivalent to <see cref="X"/>, + /// <c>[1]</c> is equivalent to <see cref="Y"/>, + /// <c>[2]</c> is equivalent to <see cref="Z"/>. /// </value> public int this[int index] { @@ -63,11 +63,11 @@ namespace Godot switch (index) { case 0: - return x; + return X; case 1: - return y; + return Y; case 2: - return z; + return Z; default: throw new ArgumentOutOfRangeException(nameof(index)); } @@ -77,13 +77,13 @@ namespace Godot switch (index) { case 0: - x = value; + X = value; return; case 1: - y = value; + Y = value; return; case 2: - z = value; + Z = value; return; default: throw new ArgumentOutOfRangeException(nameof(index)); @@ -96,18 +96,18 @@ namespace Godot /// </summary> public readonly void Deconstruct(out int x, out int y, out int z) { - x = this.x; - y = this.y; - z = this.z; + x = X; + y = Y; + z = Z; } /// <summary> /// Returns a new vector with all components in absolute values (i.e. positive). /// </summary> /// <returns>A vector with <see cref="Mathf.Abs(int)"/> called on each component.</returns> - public readonly Vector3i Abs() + public readonly Vector3I Abs() { - return new Vector3i(Mathf.Abs(x), Mathf.Abs(y), Mathf.Abs(z)); + return new Vector3I(Mathf.Abs(X), Mathf.Abs(Y), Mathf.Abs(Z)); } /// <summary> @@ -118,13 +118,13 @@ namespace Godot /// <param name="min">The vector with minimum allowed values.</param> /// <param name="max">The vector with maximum allowed values.</param> /// <returns>The vector with all components clamped.</returns> - public readonly Vector3i Clamp(Vector3i min, Vector3i max) + public readonly Vector3I Clamp(Vector3I min, Vector3I max) { - return new Vector3i + return new Vector3I ( - Mathf.Clamp(x, min.x, max.x), - Mathf.Clamp(y, min.y, max.y), - Mathf.Clamp(z, min.z, max.z) + Mathf.Clamp(X, min.X, max.X), + Mathf.Clamp(Y, min.Y, max.Y), + Mathf.Clamp(Z, min.Z, max.Z) ); } @@ -135,9 +135,9 @@ namespace Godot /// <returns>The length of this vector.</returns> public readonly real_t Length() { - int x2 = x * x; - int y2 = y * y; - int z2 = z * z; + int x2 = X * X; + int y2 = Y * Y; + int z2 = Z * Z; return Mathf.Sqrt(x2 + y2 + z2); } @@ -150,9 +150,9 @@ namespace Godot /// <returns>The squared length of this vector.</returns> public readonly int LengthSquared() { - int x2 = x * x; - int y2 = y * y; - int z2 = z * z; + int x2 = X * X; + int y2 = Y * Y; + int z2 = Z * Z; return x2 + y2 + z2; } @@ -164,7 +164,7 @@ namespace Godot /// <returns>The index of the highest axis.</returns> public readonly Axis MaxAxisIndex() { - return x < y ? (y < z ? Axis.Z : Axis.Y) : (x < z ? Axis.Z : Axis.X); + return X < Y ? (Y < Z ? Axis.Z : Axis.Y) : (X < Z ? Axis.Z : Axis.X); } /// <summary> @@ -174,7 +174,7 @@ namespace Godot /// <returns>The index of the lowest axis.</returns> public readonly Axis MinAxisIndex() { - return x < y ? (x < z ? Axis.X : Axis.Z) : (y < z ? Axis.Y : Axis.Z); + return X < Y ? (X < Z ? Axis.X : Axis.Z) : (Y < Z ? Axis.Y : Axis.Z); } /// <summary> @@ -183,208 +183,208 @@ namespace Godot /// by calling <see cref="Mathf.Sign(int)"/> on each component. /// </summary> /// <returns>A vector with all components as either <c>1</c>, <c>-1</c>, or <c>0</c>.</returns> - public readonly Vector3i Sign() + public readonly Vector3I Sign() { - Vector3i v = this; - v.x = Mathf.Sign(v.x); - v.y = Mathf.Sign(v.y); - v.z = Mathf.Sign(v.z); + Vector3I v = this; + v.X = Mathf.Sign(v.X); + v.Y = Mathf.Sign(v.Y); + v.Z = Mathf.Sign(v.Z); return v; } // Constants - private static readonly Vector3i _zero = new Vector3i(0, 0, 0); - private static readonly Vector3i _one = new Vector3i(1, 1, 1); + private static readonly Vector3I _zero = new Vector3I(0, 0, 0); + private static readonly Vector3I _one = new Vector3I(1, 1, 1); - private static readonly Vector3i _up = new Vector3i(0, 1, 0); - private static readonly Vector3i _down = new Vector3i(0, -1, 0); - private static readonly Vector3i _right = new Vector3i(1, 0, 0); - private static readonly Vector3i _left = new Vector3i(-1, 0, 0); - private static readonly Vector3i _forward = new Vector3i(0, 0, -1); - private static readonly Vector3i _back = new Vector3i(0, 0, 1); + private static readonly Vector3I _up = new Vector3I(0, 1, 0); + private static readonly Vector3I _down = new Vector3I(0, -1, 0); + private static readonly Vector3I _right = new Vector3I(1, 0, 0); + private static readonly Vector3I _left = new Vector3I(-1, 0, 0); + private static readonly Vector3I _forward = new Vector3I(0, 0, -1); + private static readonly Vector3I _back = new Vector3I(0, 0, 1); /// <summary> /// Zero vector, a vector with all components set to <c>0</c>. /// </summary> - /// <value>Equivalent to <c>new Vector3i(0, 0, 0)</c>.</value> - public static Vector3i Zero { get { return _zero; } } + /// <value>Equivalent to <c>new Vector3I(0, 0, 0)</c>.</value> + public static Vector3I Zero { get { return _zero; } } /// <summary> /// One vector, a vector with all components set to <c>1</c>. /// </summary> - /// <value>Equivalent to <c>new Vector3i(1, 1, 1)</c>.</value> - public static Vector3i One { get { return _one; } } + /// <value>Equivalent to <c>new Vector3I(1, 1, 1)</c>.</value> + public static Vector3I One { get { return _one; } } /// <summary> /// Up unit vector. /// </summary> - /// <value>Equivalent to <c>new Vector3i(0, 1, 0)</c>.</value> - public static Vector3i Up { get { return _up; } } + /// <value>Equivalent to <c>new Vector3I(0, 1, 0)</c>.</value> + public static Vector3I Up { get { return _up; } } /// <summary> /// Down unit vector. /// </summary> - /// <value>Equivalent to <c>new Vector3i(0, -1, 0)</c>.</value> - public static Vector3i Down { get { return _down; } } + /// <value>Equivalent to <c>new Vector3I(0, -1, 0)</c>.</value> + public static Vector3I Down { get { return _down; } } /// <summary> /// Right unit vector. Represents the local direction of right, /// and the global direction of east. /// </summary> - /// <value>Equivalent to <c>new Vector3i(1, 0, 0)</c>.</value> - public static Vector3i Right { get { return _right; } } + /// <value>Equivalent to <c>new Vector3I(1, 0, 0)</c>.</value> + public static Vector3I Right { get { return _right; } } /// <summary> /// Left unit vector. Represents the local direction of left, /// and the global direction of west. /// </summary> - /// <value>Equivalent to <c>new Vector3i(-1, 0, 0)</c>.</value> - public static Vector3i Left { get { return _left; } } + /// <value>Equivalent to <c>new Vector3I(-1, 0, 0)</c>.</value> + public static Vector3I Left { get { return _left; } } /// <summary> /// Forward unit vector. Represents the local direction of forward, /// and the global direction of north. /// </summary> - /// <value>Equivalent to <c>new Vector3i(0, 0, -1)</c>.</value> - public static Vector3i Forward { get { return _forward; } } + /// <value>Equivalent to <c>new Vector3I(0, 0, -1)</c>.</value> + public static Vector3I Forward { get { return _forward; } } /// <summary> /// Back unit vector. Represents the local direction of back, /// and the global direction of south. /// </summary> - /// <value>Equivalent to <c>new Vector3i(0, 0, 1)</c>.</value> - public static Vector3i Back { get { return _back; } } + /// <value>Equivalent to <c>new Vector3I(0, 0, 1)</c>.</value> + public static Vector3I Back { get { return _back; } } /// <summary> - /// Constructs a new <see cref="Vector3i"/> with the given components. + /// Constructs a new <see cref="Vector3I"/> with the given components. /// </summary> /// <param name="x">The vector's X component.</param> /// <param name="y">The vector's Y component.</param> /// <param name="z">The vector's Z component.</param> - public Vector3i(int x, int y, int z) + public Vector3I(int x, int y, int z) { - this.x = x; - this.y = y; - this.z = z; + X = x; + Y = y; + Z = z; } /// <summary> - /// Adds each component of the <see cref="Vector3i"/> - /// with the components of the given <see cref="Vector3i"/>. + /// Adds each component of the <see cref="Vector3I"/> + /// with the components of the given <see cref="Vector3I"/>. /// </summary> /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>The added vector.</returns> - public static Vector3i operator +(Vector3i left, Vector3i right) + public static Vector3I operator +(Vector3I left, Vector3I right) { - left.x += right.x; - left.y += right.y; - left.z += right.z; + left.X += right.X; + left.Y += right.Y; + left.Z += right.Z; return left; } /// <summary> - /// Subtracts each component of the <see cref="Vector3i"/> - /// by the components of the given <see cref="Vector3i"/>. + /// Subtracts each component of the <see cref="Vector3I"/> + /// by the components of the given <see cref="Vector3I"/>. /// </summary> /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>The subtracted vector.</returns> - public static Vector3i operator -(Vector3i left, Vector3i right) + public static Vector3I operator -(Vector3I left, Vector3I right) { - left.x -= right.x; - left.y -= right.y; - left.z -= right.z; + left.X -= right.X; + left.Y -= right.Y; + left.Z -= right.Z; return left; } /// <summary> - /// Returns the negative value of the <see cref="Vector3i"/>. - /// This is the same as writing <c>new Vector3i(-v.x, -v.y, -v.z)</c>. + /// Returns the negative value of the <see cref="Vector3I"/>. + /// This is the same as writing <c>new Vector3I(-v.X, -v.Y, -v.Z)</c>. /// This operation flips the direction of the vector while /// keeping the same magnitude. /// </summary> /// <param name="vec">The vector to negate/flip.</param> /// <returns>The negated/flipped vector.</returns> - public static Vector3i operator -(Vector3i vec) + public static Vector3I operator -(Vector3I vec) { - vec.x = -vec.x; - vec.y = -vec.y; - vec.z = -vec.z; + vec.X = -vec.X; + vec.Y = -vec.Y; + vec.Z = -vec.Z; return vec; } /// <summary> - /// Multiplies each component of the <see cref="Vector3i"/> + /// Multiplies each component of the <see cref="Vector3I"/> /// by the given <see langword="int"/>. /// </summary> /// <param name="vec">The vector to multiply.</param> /// <param name="scale">The scale to multiply by.</param> /// <returns>The multiplied vector.</returns> - public static Vector3i operator *(Vector3i vec, int scale) + public static Vector3I operator *(Vector3I vec, int scale) { - vec.x *= scale; - vec.y *= scale; - vec.z *= scale; + vec.X *= scale; + vec.Y *= scale; + vec.Z *= scale; return vec; } /// <summary> - /// Multiplies each component of the <see cref="Vector3i"/> + /// Multiplies each component of the <see cref="Vector3I"/> /// by the given <see langword="int"/>. /// </summary> /// <param name="scale">The scale to multiply by.</param> /// <param name="vec">The vector to multiply.</param> /// <returns>The multiplied vector.</returns> - public static Vector3i operator *(int scale, Vector3i vec) + public static Vector3I operator *(int scale, Vector3I vec) { - vec.x *= scale; - vec.y *= scale; - vec.z *= scale; + vec.X *= scale; + vec.Y *= scale; + vec.Z *= scale; return vec; } /// <summary> - /// Multiplies each component of the <see cref="Vector3i"/> - /// by the components of the given <see cref="Vector3i"/>. + /// Multiplies each component of the <see cref="Vector3I"/> + /// by the components of the given <see cref="Vector3I"/>. /// </summary> /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>The multiplied vector.</returns> - public static Vector3i operator *(Vector3i left, Vector3i right) + public static Vector3I operator *(Vector3I left, Vector3I right) { - left.x *= right.x; - left.y *= right.y; - left.z *= right.z; + left.X *= right.X; + left.Y *= right.Y; + left.Z *= right.Z; return left; } /// <summary> - /// Divides each component of the <see cref="Vector3i"/> + /// Divides each component of the <see cref="Vector3I"/> /// by the given <see langword="int"/>. /// </summary> /// <param name="vec">The dividend vector.</param> /// <param name="divisor">The divisor value.</param> /// <returns>The divided vector.</returns> - public static Vector3i operator /(Vector3i vec, int divisor) + public static Vector3I operator /(Vector3I vec, int divisor) { - vec.x /= divisor; - vec.y /= divisor; - vec.z /= divisor; + vec.X /= divisor; + vec.Y /= divisor; + vec.Z /= divisor; return vec; } /// <summary> - /// Divides each component of the <see cref="Vector3i"/> - /// by the components of the given <see cref="Vector3i"/>. + /// Divides each component of the <see cref="Vector3I"/> + /// by the components of the given <see cref="Vector3I"/>. /// </summary> /// <param name="vec">The dividend vector.</param> /// <param name="divisorv">The divisor vector.</param> /// <returns>The divided vector.</returns> - public static Vector3i operator /(Vector3i vec, Vector3i divisorv) + public static Vector3I operator /(Vector3I vec, Vector3I divisorv) { - vec.x /= divisorv.x; - vec.y /= divisorv.y; - vec.z /= divisorv.z; + vec.X /= divisorv.X; + vec.Y /= divisorv.Y; + vec.Z /= divisorv.Z; return vec; } /// <summary> - /// Gets the remainder of each component of the <see cref="Vector3i"/> + /// Gets the remainder of each component of the <see cref="Vector3I"/> /// with the components of the given <see langword="int"/>. /// This operation uses truncated division, which is often not desired /// as it does not work well with negative numbers. @@ -393,23 +393,23 @@ namespace Godot /// </summary> /// <example> /// <code> - /// GD.Print(new Vector3i(10, -20, 30) % 7); // Prints "(3, -6, 2)" + /// GD.Print(new Vector3I(10, -20, 30) % 7); // Prints "(3, -6, 2)" /// </code> /// </example> /// <param name="vec">The dividend vector.</param> /// <param name="divisor">The divisor value.</param> /// <returns>The remainder vector.</returns> - public static Vector3i operator %(Vector3i vec, int divisor) + public static Vector3I operator %(Vector3I vec, int divisor) { - vec.x %= divisor; - vec.y %= divisor; - vec.z %= divisor; + vec.X %= divisor; + vec.Y %= divisor; + vec.Z %= divisor; return vec; } /// <summary> - /// Gets the remainder of each component of the <see cref="Vector3i"/> - /// with the components of the given <see cref="Vector3i"/>. + /// Gets the remainder of each component of the <see cref="Vector3I"/> + /// with the components of the given <see cref="Vector3I"/>. /// This operation uses truncated division, which is often not desired /// as it does not work well with negative numbers. /// Consider using <see cref="Mathf.PosMod(int, int)"/> instead @@ -417,17 +417,17 @@ namespace Godot /// </summary> /// <example> /// <code> - /// GD.Print(new Vector3i(10, -20, 30) % new Vector3i(7, 8, 9)); // Prints "(3, -4, 3)" + /// GD.Print(new Vector3I(10, -20, 30) % new Vector3I(7, 8, 9)); // Prints "(3, -4, 3)" /// </code> /// </example> /// <param name="vec">The dividend vector.</param> /// <param name="divisorv">The divisor vector.</param> /// <returns>The remainder vector.</returns> - public static Vector3i operator %(Vector3i vec, Vector3i divisorv) + public static Vector3I operator %(Vector3I vec, Vector3I divisorv) { - vec.x %= divisorv.x; - vec.y %= divisorv.y; - vec.z %= divisorv.z; + vec.X %= divisorv.X; + vec.Y %= divisorv.Y; + vec.Z %= divisorv.Z; return vec; } @@ -437,7 +437,7 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the vectors are equal.</returns> - public static bool operator ==(Vector3i left, Vector3i right) + public static bool operator ==(Vector3I left, Vector3I right) { return left.Equals(right); } @@ -448,13 +448,13 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the vectors are not equal.</returns> - public static bool operator !=(Vector3i left, Vector3i right) + public static bool operator !=(Vector3I left, Vector3I right) { return !left.Equals(right); } /// <summary> - /// Compares two <see cref="Vector3i"/> vectors by first checking if + /// Compares two <see cref="Vector3I"/> vectors by first checking if /// the X value of the <paramref name="left"/> vector is less than /// the X value of the <paramref name="right"/> vector. /// If the X values are exactly equal, then it repeats this check @@ -464,21 +464,21 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the left is less than the right.</returns> - public static bool operator <(Vector3i left, Vector3i right) + public static bool operator <(Vector3I left, Vector3I right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - return left.z < right.z; + return left.Z < right.Z; } - return left.y < right.y; + return left.Y < right.Y; } - return left.x < right.x; + return left.X < right.X; } /// <summary> - /// Compares two <see cref="Vector3i"/> vectors by first checking if + /// Compares two <see cref="Vector3I"/> vectors by first checking if /// the X value of the <paramref name="left"/> vector is greater than /// the X value of the <paramref name="right"/> vector. /// If the X values are exactly equal, then it repeats this check @@ -488,21 +488,21 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the left is greater than the right.</returns> - public static bool operator >(Vector3i left, Vector3i right) + public static bool operator >(Vector3I left, Vector3I right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - return left.z > right.z; + return left.Z > right.Z; } - return left.y > right.y; + return left.Y > right.Y; } - return left.x > right.x; + return left.X > right.X; } /// <summary> - /// Compares two <see cref="Vector3i"/> vectors by first checking if + /// Compares two <see cref="Vector3I"/> vectors by first checking if /// the X value of the <paramref name="left"/> vector is less than /// or equal to the X value of the <paramref name="right"/> vector. /// If the X values are exactly equal, then it repeats this check @@ -512,21 +512,21 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the left is less than or equal to the right.</returns> - public static bool operator <=(Vector3i left, Vector3i right) + public static bool operator <=(Vector3I left, Vector3I right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - return left.z <= right.z; + return left.Z <= right.Z; } - return left.y < right.y; + return left.Y < right.Y; } - return left.x < right.x; + return left.X < right.X; } /// <summary> - /// Compares two <see cref="Vector3i"/> vectors by first checking if + /// Compares two <see cref="Vector3I"/> vectors by first checking if /// the X value of the <paramref name="left"/> vector is greater than /// or equal to the X value of the <paramref name="right"/> vector. /// If the X values are exactly equal, then it repeats this check @@ -536,38 +536,38 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the left is greater than or equal to the right.</returns> - public static bool operator >=(Vector3i left, Vector3i right) + public static bool operator >=(Vector3I left, Vector3I right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - return left.z >= right.z; + return left.Z >= right.Z; } - return left.y > right.y; + return left.Y > right.Y; } - return left.x > right.x; + return left.X > right.X; } /// <summary> - /// Converts this <see cref="Vector3i"/> to a <see cref="Vector3"/>. + /// Converts this <see cref="Vector3I"/> to a <see cref="Vector3"/>. /// </summary> /// <param name="value">The vector to convert.</param> - public static implicit operator Vector3(Vector3i value) + public static implicit operator Vector3(Vector3I value) { - return new Vector3(value.x, value.y, value.z); + return new Vector3(value.X, value.Y, value.Z); } /// <summary> - /// Converts a <see cref="Vector3"/> to a <see cref="Vector3i"/>. + /// Converts a <see cref="Vector3"/> to a <see cref="Vector3I"/>. /// </summary> /// <param name="value">The vector to convert.</param> - public static explicit operator Vector3i(Vector3 value) + public static explicit operator Vector3I(Vector3 value) { - return new Vector3i( - Mathf.RoundToInt(value.x), - Mathf.RoundToInt(value.y), - Mathf.RoundToInt(value.z) + return new Vector3I( + Mathf.RoundToInt(value.X), + Mathf.RoundToInt(value.Y), + Mathf.RoundToInt(value.Z) ); } @@ -579,7 +579,7 @@ namespace Godot /// <returns>Whether or not the vector and the object are equal.</returns> public override readonly bool Equals(object obj) { - return obj is Vector3i other && Equals(other); + return obj is Vector3I other && Equals(other); } /// <summary> @@ -587,36 +587,36 @@ namespace Godot /// </summary> /// <param name="other">The other vector.</param> /// <returns>Whether or not the vectors are equal.</returns> - public readonly bool Equals(Vector3i other) + public readonly bool Equals(Vector3I other) { - return x == other.x && y == other.y && z == other.z; + return X == other.X && Y == other.Y && Z == other.Z; } /// <summary> - /// Serves as the hash function for <see cref="Vector3i"/>. + /// Serves as the hash function for <see cref="Vector3I"/>. /// </summary> /// <returns>A hash code for this vector.</returns> public override readonly int GetHashCode() { - return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode(); + return Y.GetHashCode() ^ X.GetHashCode() ^ Z.GetHashCode(); } /// <summary> - /// Converts this <see cref="Vector3i"/> to a string. + /// Converts this <see cref="Vector3I"/> to a string. /// </summary> /// <returns>A string representation of this vector.</returns> public override readonly string ToString() { - return $"({x}, {y}, {z})"; + return $"({X}, {Y}, {Z})"; } /// <summary> - /// Converts this <see cref="Vector3i"/> to a string with the given <paramref name="format"/>. + /// Converts this <see cref="Vector3I"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this vector.</returns> public readonly string ToString(string format) { - return $"({x.ToString(format)}, {y.ToString(format)}, {z.ToString(format)})"; + return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)})"; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs index 0f4528bb40..1fd39632b0 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs @@ -37,22 +37,22 @@ namespace Godot /// <summary> /// The vector's X component. Also accessible by using the index position <c>[0]</c>. /// </summary> - public real_t x; + public real_t X; /// <summary> /// The vector's Y component. Also accessible by using the index position <c>[1]</c>. /// </summary> - public real_t y; + public real_t Y; /// <summary> /// The vector's Z component. Also accessible by using the index position <c>[2]</c>. /// </summary> - public real_t z; + public real_t Z; /// <summary> /// The vector's W component. Also accessible by using the index position <c>[3]</c>. /// </summary> - public real_t w; + public real_t W; /// <summary> /// Access vector components using their index. @@ -61,10 +61,10 @@ namespace Godot /// <paramref name="index"/> is not 0, 1, 2 or 3. /// </exception> /// <value> - /// <c>[0]</c> is equivalent to <see cref="x"/>, - /// <c>[1]</c> is equivalent to <see cref="y"/>, - /// <c>[2]</c> is equivalent to <see cref="z"/>. - /// <c>[3]</c> is equivalent to <see cref="w"/>. + /// <c>[0]</c> is equivalent to <see cref="X"/>, + /// <c>[1]</c> is equivalent to <see cref="Y"/>, + /// <c>[2]</c> is equivalent to <see cref="Z"/>. + /// <c>[3]</c> is equivalent to <see cref="W"/>. /// </value> public real_t this[int index] { @@ -73,13 +73,13 @@ namespace Godot switch (index) { case 0: - return x; + return X; case 1: - return y; + return Y; case 2: - return z; + return Z; case 3: - return w; + return W; default: throw new ArgumentOutOfRangeException(nameof(index)); } @@ -89,16 +89,16 @@ namespace Godot switch (index) { case 0: - x = value; + X = value; return; case 1: - y = value; + Y = value; return; case 2: - z = value; + Z = value; return; case 3: - w = value; + W = value; return; default: throw new ArgumentOutOfRangeException(nameof(index)); @@ -111,10 +111,10 @@ namespace Godot /// </summary> public readonly void Deconstruct(out real_t x, out real_t y, out real_t z, out real_t w) { - x = this.x; - y = this.y; - z = this.z; - w = this.w; + x = X; + y = Y; + z = Z; + w = W; } internal void Normalize() @@ -123,15 +123,15 @@ namespace Godot if (lengthsq == 0) { - x = y = z = w = 0f; + X = Y = Z = W = 0f; } else { real_t length = Mathf.Sqrt(lengthsq); - x /= length; - y /= length; - z /= length; - w /= length; + X /= length; + Y /= length; + Z /= length; + W /= length; } } @@ -141,7 +141,7 @@ namespace Godot /// <returns>A vector with <see cref="Mathf.Abs(real_t)"/> called on each component.</returns> public readonly Vector4 Abs() { - return new Vector4(Mathf.Abs(x), Mathf.Abs(y), Mathf.Abs(z), Mathf.Abs(w)); + return new Vector4(Mathf.Abs(X), Mathf.Abs(Y), Mathf.Abs(Z), Mathf.Abs(W)); } /// <summary> @@ -150,7 +150,7 @@ namespace Godot /// <returns>A vector with <see cref="Mathf.Ceil"/> called on each component.</returns> public readonly Vector4 Ceil() { - return new Vector4(Mathf.Ceil(x), Mathf.Ceil(y), Mathf.Ceil(z), Mathf.Ceil(w)); + return new Vector4(Mathf.Ceil(X), Mathf.Ceil(Y), Mathf.Ceil(Z), Mathf.Ceil(W)); } /// <summary> @@ -165,10 +165,10 @@ namespace Godot { return new Vector4 ( - Mathf.Clamp(x, min.x, max.x), - Mathf.Clamp(y, min.y, max.y), - Mathf.Clamp(z, min.z, max.z), - Mathf.Clamp(w, min.w, max.w) + Mathf.Clamp(X, min.X, max.X), + Mathf.Clamp(Y, min.Y, max.Y), + Mathf.Clamp(Z, min.Z, max.Z), + Mathf.Clamp(W, min.W, max.W) ); } @@ -185,10 +185,10 @@ namespace Godot { return new Vector4 ( - Mathf.CubicInterpolate(x, b.x, preA.x, postB.x, weight), - Mathf.CubicInterpolate(y, b.y, preA.y, postB.y, weight), - Mathf.CubicInterpolate(z, b.z, preA.z, postB.z, weight), - Mathf.CubicInterpolate(w, b.w, preA.w, postB.w, weight) + Mathf.CubicInterpolate(X, b.X, preA.X, postB.X, weight), + Mathf.CubicInterpolate(Y, b.Y, preA.Y, postB.Y, weight), + Mathf.CubicInterpolate(Z, b.Z, preA.Z, postB.Z, weight), + Mathf.CubicInterpolate(W, b.W, preA.W, postB.W, weight) ); } @@ -210,10 +210,10 @@ namespace Godot { return new Vector4 ( - Mathf.CubicInterpolateInTime(x, b.x, preA.x, postB.x, weight, t, preAT, postBT), - Mathf.CubicInterpolateInTime(y, b.y, preA.y, postB.y, weight, t, preAT, postBT), - Mathf.CubicInterpolateInTime(z, b.z, preA.z, postB.z, weight, t, preAT, postBT), - Mathf.CubicInterpolateInTime(w, b.w, preA.w, postB.w, weight, t, preAT, postBT) + Mathf.CubicInterpolateInTime(X, b.X, preA.X, postB.X, weight, t, preAT, postBT), + Mathf.CubicInterpolateInTime(Y, b.Y, preA.Y, postB.Y, weight, t, preAT, postBT), + Mathf.CubicInterpolateInTime(Z, b.Z, preA.Z, postB.Z, weight, t, preAT, postBT), + Mathf.CubicInterpolateInTime(W, b.W, preA.W, postB.W, weight, t, preAT, postBT) ); } @@ -224,7 +224,7 @@ namespace Godot /// <returns>The direction from this vector to <paramref name="to"/>.</returns> public readonly Vector4 DirectionTo(Vector4 to) { - Vector4 ret = new Vector4(to.x - x, to.y - y, to.z - z, to.w - w); + Vector4 ret = new Vector4(to.X - X, to.Y - Y, to.Z - Z, to.W - W); ret.Normalize(); return ret; } @@ -258,7 +258,7 @@ namespace Godot /// <returns>The dot product of the two vectors.</returns> public readonly real_t Dot(Vector4 with) { - return (x * with.x) + (y * with.y) + (z * with.z) + (w * with.w); + return (X * with.X) + (Y * with.Y) + (Z * with.Z) + (W * with.W); } /// <summary> @@ -267,16 +267,16 @@ namespace Godot /// <returns>A vector with <see cref="Mathf.Floor"/> called on each component.</returns> public readonly Vector4 Floor() { - return new Vector4(Mathf.Floor(x), Mathf.Floor(y), Mathf.Floor(z), Mathf.Floor(w)); + return new Vector4(Mathf.Floor(X), Mathf.Floor(Y), Mathf.Floor(Z), Mathf.Floor(W)); } /// <summary> - /// Returns the inverse of this vector. This is the same as <c>new Vector4(1 / v.x, 1 / v.y, 1 / v.z, 1 / v.w)</c>. + /// Returns the inverse of this vector. This is the same as <c>new Vector4(1 / v.X, 1 / v.Y, 1 / v.Z, 1 / v.W)</c>. /// </summary> /// <returns>The inverse of this vector.</returns> public readonly Vector4 Inverse() { - return new Vector4(1 / x, 1 / y, 1 / z, 1 / w); + return new Vector4(1 / X, 1 / Y, 1 / Z, 1 / W); } /// <summary> @@ -286,7 +286,7 @@ namespace Godot /// <returns>Whether this vector is finite or not.</returns> public readonly bool IsFinite() { - return Mathf.IsFinite(x) && Mathf.IsFinite(y) && Mathf.IsFinite(z) && Mathf.IsFinite(w); + return Mathf.IsFinite(X) && Mathf.IsFinite(Y) && Mathf.IsFinite(Z) && Mathf.IsFinite(W); } /// <summary> @@ -305,10 +305,10 @@ namespace Godot /// <returns>The length of this vector.</returns> public readonly real_t Length() { - real_t x2 = x * x; - real_t y2 = y * y; - real_t z2 = z * z; - real_t w2 = w * w; + real_t x2 = X * X; + real_t y2 = Y * Y; + real_t z2 = Z * Z; + real_t w2 = W * W; return Mathf.Sqrt(x2 + y2 + z2 + w2); } @@ -321,10 +321,10 @@ namespace Godot /// <returns>The squared length of this vector.</returns> public readonly real_t LengthSquared() { - real_t x2 = x * x; - real_t y2 = y * y; - real_t z2 = z * z; - real_t w2 = w * w; + real_t x2 = X * X; + real_t y2 = Y * Y; + real_t z2 = Z * Z; + real_t w2 = W * W; return x2 + y2 + z2 + w2; } @@ -340,10 +340,10 @@ namespace Godot { return new Vector4 ( - Mathf.Lerp(x, to.x, weight), - Mathf.Lerp(y, to.y, weight), - Mathf.Lerp(z, to.z, weight), - Mathf.Lerp(w, to.w, weight) + Mathf.Lerp(X, to.X, weight), + Mathf.Lerp(Y, to.Y, weight), + Mathf.Lerp(Z, to.Z, weight), + Mathf.Lerp(W, to.W, weight) ); } @@ -355,7 +355,7 @@ namespace Godot public readonly Axis MaxAxisIndex() { int max_index = 0; - real_t max_value = x; + real_t max_value = X; for (int i = 1; i < 4; i++) { if (this[i] > max_value) @@ -375,7 +375,7 @@ namespace Godot public readonly Axis MinAxisIndex() { int min_index = 0; - real_t min_value = x; + real_t min_value = X; for (int i = 1; i < 4; i++) { if (this[i] <= min_value) @@ -409,10 +409,10 @@ namespace Godot public readonly Vector4 PosMod(real_t mod) { return new Vector4( - Mathf.PosMod(x, mod), - Mathf.PosMod(y, mod), - Mathf.PosMod(z, mod), - Mathf.PosMod(w, mod) + Mathf.PosMod(X, mod), + Mathf.PosMod(Y, mod), + Mathf.PosMod(Z, mod), + Mathf.PosMod(W, mod) ); } @@ -427,10 +427,10 @@ namespace Godot public readonly Vector4 PosMod(Vector4 modv) { return new Vector4( - Mathf.PosMod(x, modv.x), - Mathf.PosMod(y, modv.y), - Mathf.PosMod(z, modv.z), - Mathf.PosMod(w, modv.w) + Mathf.PosMod(X, modv.X), + Mathf.PosMod(Y, modv.Y), + Mathf.PosMod(Z, modv.Z), + Mathf.PosMod(W, modv.W) ); } @@ -441,7 +441,7 @@ namespace Godot /// <returns>The rounded vector.</returns> public readonly Vector4 Round() { - return new Vector4(Mathf.Round(x), Mathf.Round(y), Mathf.Round(z), Mathf.Round(w)); + return new Vector4(Mathf.Round(X), Mathf.Round(Y), Mathf.Round(Z), Mathf.Round(W)); } /// <summary> @@ -453,10 +453,10 @@ namespace Godot public readonly Vector4 Sign() { Vector4 v; - v.x = Mathf.Sign(x); - v.y = Mathf.Sign(y); - v.z = Mathf.Sign(z); - v.w = Mathf.Sign(w); + v.X = Mathf.Sign(X); + v.Y = Mathf.Sign(Y); + v.Z = Mathf.Sign(Z); + v.W = Mathf.Sign(W); return v; } @@ -469,10 +469,10 @@ namespace Godot public readonly Vector4 Snapped(Vector4 step) { return new Vector4( - Mathf.Snapped(x, step.x), - Mathf.Snapped(y, step.y), - Mathf.Snapped(z, step.z), - Mathf.Snapped(w, step.w) + Mathf.Snapped(X, step.X), + Mathf.Snapped(Y, step.Y), + Mathf.Snapped(Z, step.Z), + Mathf.Snapped(W, step.W) ); } @@ -506,10 +506,10 @@ namespace Godot /// <param name="w">The vector's W component.</param> public Vector4(real_t x, real_t y, real_t z, real_t w) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; + X = x; + Y = y; + Z = z; + W = w; } /// <summary> @@ -521,10 +521,10 @@ namespace Godot /// <returns>The added vector.</returns> public static Vector4 operator +(Vector4 left, Vector4 right) { - left.x += right.x; - left.y += right.y; - left.z += right.z; - left.w += right.w; + left.X += right.X; + left.Y += right.Y; + left.Z += right.Z; + left.W += right.W; return left; } @@ -537,16 +537,16 @@ namespace Godot /// <returns>The subtracted vector.</returns> public static Vector4 operator -(Vector4 left, Vector4 right) { - left.x -= right.x; - left.y -= right.y; - left.z -= right.z; - left.w -= right.w; + left.X -= right.X; + left.Y -= right.Y; + left.Z -= right.Z; + left.W -= right.W; return left; } /// <summary> /// Returns the negative value of the <see cref="Vector4"/>. - /// This is the same as writing <c>new Vector4(-v.x, -v.y, -v.z, -v.w)</c>. + /// This is the same as writing <c>new Vector4(-v.X, -v.Y, -v.Z, -v.W)</c>. /// This operation flips the direction of the vector while /// keeping the same magnitude. /// With floats, the number zero can be either positive or negative. @@ -555,10 +555,10 @@ namespace Godot /// <returns>The negated/flipped vector.</returns> public static Vector4 operator -(Vector4 vec) { - vec.x = -vec.x; - vec.y = -vec.y; - vec.z = -vec.z; - vec.w = -vec.w; + vec.X = -vec.X; + vec.Y = -vec.Y; + vec.Z = -vec.Z; + vec.W = -vec.W; return vec; } @@ -571,10 +571,10 @@ namespace Godot /// <returns>The multiplied vector.</returns> public static Vector4 operator *(Vector4 vec, real_t scale) { - vec.x *= scale; - vec.y *= scale; - vec.z *= scale; - vec.w *= scale; + vec.X *= scale; + vec.Y *= scale; + vec.Z *= scale; + vec.W *= scale; return vec; } @@ -587,10 +587,10 @@ namespace Godot /// <returns>The multiplied vector.</returns> public static Vector4 operator *(real_t scale, Vector4 vec) { - vec.x *= scale; - vec.y *= scale; - vec.z *= scale; - vec.w *= scale; + vec.X *= scale; + vec.Y *= scale; + vec.Z *= scale; + vec.W *= scale; return vec; } @@ -603,10 +603,10 @@ namespace Godot /// <returns>The multiplied vector.</returns> public static Vector4 operator *(Vector4 left, Vector4 right) { - left.x *= right.x; - left.y *= right.y; - left.z *= right.z; - left.w *= right.w; + left.X *= right.X; + left.Y *= right.Y; + left.Z *= right.Z; + left.W *= right.W; return left; } @@ -619,10 +619,10 @@ namespace Godot /// <returns>The divided vector.</returns> public static Vector4 operator /(Vector4 vec, real_t divisor) { - vec.x /= divisor; - vec.y /= divisor; - vec.z /= divisor; - vec.w /= divisor; + vec.X /= divisor; + vec.Y /= divisor; + vec.Z /= divisor; + vec.W /= divisor; return vec; } @@ -635,10 +635,10 @@ namespace Godot /// <returns>The divided vector.</returns> public static Vector4 operator /(Vector4 vec, Vector4 divisorv) { - vec.x /= divisorv.x; - vec.y /= divisorv.y; - vec.z /= divisorv.z; - vec.w /= divisorv.w; + vec.X /= divisorv.X; + vec.Y /= divisorv.Y; + vec.Z /= divisorv.Z; + vec.W /= divisorv.W; return vec; } @@ -660,10 +660,10 @@ namespace Godot /// <returns>The remainder vector.</returns> public static Vector4 operator %(Vector4 vec, real_t divisor) { - vec.x %= divisor; - vec.y %= divisor; - vec.z %= divisor; - vec.w %= divisor; + vec.X %= divisor; + vec.Y %= divisor; + vec.Z %= divisor; + vec.W %= divisor; return vec; } @@ -685,10 +685,10 @@ namespace Godot /// <returns>The remainder vector.</returns> public static Vector4 operator %(Vector4 vec, Vector4 divisorv) { - vec.x %= divisorv.x; - vec.y %= divisorv.y; - vec.z %= divisorv.z; - vec.w %= divisorv.w; + vec.X %= divisorv.X; + vec.Y %= divisorv.Y; + vec.Z %= divisorv.Z; + vec.W %= divisorv.W; return vec; } @@ -731,19 +731,19 @@ namespace Godot /// <returns>Whether or not the left is less than the right.</returns> public static bool operator <(Vector4 left, Vector4 right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - if (left.z == right.z) + if (left.Z == right.Z) { - return left.w < right.w; + return left.W < right.W; } - return left.z < right.z; + return left.Z < right.Z; } - return left.y < right.y; + return left.Y < right.Y; } - return left.x < right.x; + return left.X < right.X; } /// <summary> @@ -759,19 +759,19 @@ namespace Godot /// <returns>Whether or not the left is greater than the right.</returns> public static bool operator >(Vector4 left, Vector4 right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - if (left.z == right.z) + if (left.Z == right.Z) { - return left.w > right.w; + return left.W > right.W; } - return left.z > right.z; + return left.Z > right.Z; } - return left.y > right.y; + return left.Y > right.Y; } - return left.x > right.x; + return left.X > right.X; } /// <summary> @@ -787,19 +787,19 @@ namespace Godot /// <returns>Whether or not the left is less than or equal to the right.</returns> public static bool operator <=(Vector4 left, Vector4 right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - if (left.z == right.z) + if (left.Z == right.Z) { - return left.w <= right.w; + return left.W <= right.W; } - return left.z < right.z; + return left.Z < right.Z; } - return left.y < right.y; + return left.Y < right.Y; } - return left.x < right.x; + return left.X < right.X; } /// <summary> @@ -815,19 +815,19 @@ namespace Godot /// <returns>Whether or not the left is greater than or equal to the right.</returns> public static bool operator >=(Vector4 left, Vector4 right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - if (left.z == right.z) + if (left.Z == right.Z) { - return left.w >= right.w; + return left.W >= right.W; } - return left.z > right.z; + return left.Z > right.Z; } - return left.y > right.y; + return left.Y > right.Y; } - return left.x > right.x; + return left.X > right.X; } /// <summary> @@ -852,7 +852,7 @@ namespace Godot /// <returns>Whether or not the vectors are exactly equal.</returns> public readonly bool Equals(Vector4 other) { - return x == other.x && y == other.y && z == other.z && w == other.w; + return X == other.X && Y == other.Y && Z == other.Z && W == other.W; } /// <summary> @@ -863,7 +863,7 @@ namespace Godot /// <returns>Whether or not the vectors are approximately equal.</returns> public readonly bool IsEqualApprox(Vector4 other) { - return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y) && Mathf.IsEqualApprox(z, other.z) && Mathf.IsEqualApprox(w, other.w); + return Mathf.IsEqualApprox(X, other.X) && Mathf.IsEqualApprox(Y, other.Y) && Mathf.IsEqualApprox(Z, other.Z) && Mathf.IsEqualApprox(W, other.W); } /// <summary> @@ -875,7 +875,7 @@ namespace Godot /// <returns>Whether or not the vector is approximately zero.</returns> public readonly bool IsZeroApprox() { - return Mathf.IsZeroApprox(x) && Mathf.IsZeroApprox(y) && Mathf.IsZeroApprox(z) && Mathf.IsZeroApprox(w); + return Mathf.IsZeroApprox(X) && Mathf.IsZeroApprox(Y) && Mathf.IsZeroApprox(Z) && Mathf.IsZeroApprox(W); } /// <summary> @@ -884,7 +884,7 @@ namespace Godot /// <returns>A hash code for this vector.</returns> public override readonly int GetHashCode() { - return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode(); + return Y.GetHashCode() ^ X.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode(); } /// <summary> @@ -893,7 +893,7 @@ namespace Godot /// <returns>A string representation of this vector.</returns> public override string ToString() { - return $"({x}, {y}, {z}, {w})"; + return $"({X}, {Y}, {Z}, {W})"; } /// <summary> @@ -902,7 +902,7 @@ namespace Godot /// <returns>A string representation of this vector.</returns> public readonly string ToString(string format) { - return $"({x.ToString(format)}, {y.ToString(format)}, {z.ToString(format)}, {w.ToString(format)})"; + return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)}, {W.ToString(format)})"; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs index 00ecc64856..f065327066 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs @@ -8,7 +8,7 @@ namespace Godot /// </summary> [Serializable] [StructLayout(LayoutKind.Sequential)] - public struct Vector4i : IEquatable<Vector4i> + public struct Vector4I : IEquatable<Vector4I> { /// <summary> /// Enumerated index values for the axes. @@ -37,22 +37,22 @@ namespace Godot /// <summary> /// The vector's X component. Also accessible by using the index position <c>[0]</c>. /// </summary> - public int x; + public int X; /// <summary> /// The vector's Y component. Also accessible by using the index position <c>[1]</c>. /// </summary> - public int y; + public int Y; /// <summary> /// The vector's Z component. Also accessible by using the index position <c>[2]</c>. /// </summary> - public int z; + public int Z; /// <summary> /// The vector's W component. Also accessible by using the index position <c>[3]</c>. /// </summary> - public int w; + public int W; /// <summary> /// Access vector components using their <paramref name="index"/>. @@ -61,10 +61,10 @@ namespace Godot /// <paramref name="index"/> is not 0, 1, 2 or 3. /// </exception> /// <value> - /// <c>[0]</c> is equivalent to <see cref="x"/>, - /// <c>[1]</c> is equivalent to <see cref="y"/>, - /// <c>[2]</c> is equivalent to <see cref="z"/>. - /// <c>[3]</c> is equivalent to <see cref="w"/>. + /// <c>[0]</c> is equivalent to <see cref="X"/>, + /// <c>[1]</c> is equivalent to <see cref="Y"/>, + /// <c>[2]</c> is equivalent to <see cref="Z"/>. + /// <c>[3]</c> is equivalent to <see cref="W"/>. /// </value> public int this[int index] { @@ -73,13 +73,13 @@ namespace Godot switch (index) { case 0: - return x; + return X; case 1: - return y; + return Y; case 2: - return z; + return Z; case 3: - return w; + return W; default: throw new ArgumentOutOfRangeException(nameof(index)); } @@ -89,16 +89,16 @@ namespace Godot switch (index) { case 0: - x = value; + X = value; return; case 1: - y = value; + Y = value; return; case 2: - z = value; + Z = value; return; case 3: - w = value; + W = value; return; default: throw new ArgumentOutOfRangeException(nameof(index)); @@ -111,19 +111,19 @@ namespace Godot /// </summary> public readonly void Deconstruct(out int x, out int y, out int z, out int w) { - x = this.x; - y = this.y; - z = this.z; - w = this.w; + x = X; + y = Y; + z = Z; + w = W; } /// <summary> /// Returns a new vector with all components in absolute values (i.e. positive). /// </summary> /// <returns>A vector with <see cref="Mathf.Abs(int)"/> called on each component.</returns> - public readonly Vector4i Abs() + public readonly Vector4I Abs() { - return new Vector4i(Mathf.Abs(x), Mathf.Abs(y), Mathf.Abs(z), Mathf.Abs(w)); + return new Vector4I(Mathf.Abs(X), Mathf.Abs(Y), Mathf.Abs(Z), Mathf.Abs(W)); } /// <summary> @@ -134,14 +134,14 @@ namespace Godot /// <param name="min">The vector with minimum allowed values.</param> /// <param name="max">The vector with maximum allowed values.</param> /// <returns>The vector with all components clamped.</returns> - public readonly Vector4i Clamp(Vector4i min, Vector4i max) + public readonly Vector4I Clamp(Vector4I min, Vector4I max) { - return new Vector4i + return new Vector4I ( - Mathf.Clamp(x, min.x, max.x), - Mathf.Clamp(y, min.y, max.y), - Mathf.Clamp(z, min.z, max.z), - Mathf.Clamp(w, min.w, max.w) + Mathf.Clamp(X, min.X, max.X), + Mathf.Clamp(Y, min.Y, max.Y), + Mathf.Clamp(Z, min.Z, max.Z), + Mathf.Clamp(W, min.W, max.W) ); } @@ -152,10 +152,10 @@ namespace Godot /// <returns>The length of this vector.</returns> public readonly real_t Length() { - int x2 = x * x; - int y2 = y * y; - int z2 = z * z; - int w2 = w * w; + int x2 = X * X; + int y2 = Y * Y; + int z2 = Z * Z; + int w2 = W * W; return Mathf.Sqrt(x2 + y2 + z2 + w2); } @@ -168,10 +168,10 @@ namespace Godot /// <returns>The squared length of this vector.</returns> public readonly int LengthSquared() { - int x2 = x * x; - int y2 = y * y; - int z2 = z * z; - int w2 = w * w; + int x2 = X * X; + int y2 = Y * Y; + int z2 = Z * Z; + int w2 = W * W; return x2 + y2 + z2 + w2; } @@ -184,7 +184,7 @@ namespace Godot public readonly Axis MaxAxisIndex() { int max_index = 0; - int max_value = x; + int max_value = X; for (int i = 1; i < 4; i++) { if (this[i] > max_value) @@ -204,7 +204,7 @@ namespace Godot public readonly Axis MinAxisIndex() { int min_index = 0; - int min_value = x; + int min_value = X; for (int i = 1; i < 4; i++) { if (this[i] <= min_value) @@ -222,213 +222,217 @@ namespace Godot /// by calling <see cref="Mathf.Sign(int)"/> on each component. /// </summary> /// <returns>A vector with all components as either <c>1</c>, <c>-1</c>, or <c>0</c>.</returns> - public readonly Vector4i Sign() + public readonly Vector4I Sign() { - return new Vector4i(Mathf.Sign(x), Mathf.Sign(y), Mathf.Sign(z), Mathf.Sign(w)); + return new Vector4I(Mathf.Sign(X), Mathf.Sign(Y), Mathf.Sign(Z), Mathf.Sign(W)); } // Constants - private static readonly Vector4i _zero = new Vector4i(0, 0, 0, 0); - private static readonly Vector4i _one = new Vector4i(1, 1, 1, 1); + private static readonly Vector4I _zero = new Vector4I(0, 0, 0, 0); + private static readonly Vector4I _one = new Vector4I(1, 1, 1, 1); /// <summary> /// Zero vector, a vector with all components set to <c>0</c>. /// </summary> - /// <value>Equivalent to <c>new Vector4i(0, 0, 0, 0)</c>.</value> - public static Vector4i Zero { get { return _zero; } } + /// <value>Equivalent to <c>new Vector4I(0, 0, 0, 0)</c>.</value> + public static Vector4I Zero { get { return _zero; } } /// <summary> /// One vector, a vector with all components set to <c>1</c>. /// </summary> - /// <value>Equivalent to <c>new Vector4i(1, 1, 1, 1)</c>.</value> - public static Vector4i One { get { return _one; } } + /// <value>Equivalent to <c>new Vector4I(1, 1, 1, 1)</c>.</value> + public static Vector4I One { get { return _one; } } /// <summary> - /// Constructs a new <see cref="Vector4i"/> with the given components. + /// Constructs a new <see cref="Vector4I"/> with the given components. /// </summary> /// <param name="x">The vector's X component.</param> /// <param name="y">The vector's Y component.</param> /// <param name="z">The vector's Z component.</param> /// <param name="w">The vector's W component.</param> - public Vector4i(int x, int y, int z, int w) + public Vector4I(int x, int y, int z, int w) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; + X = x; + Y = y; + Z = z; + W = w; } /// <summary> - /// Adds each component of the <see cref="Vector4i"/> - /// with the components of the given <see cref="Vector4i"/>. + /// Adds each component of the <see cref="Vector4I"/> + /// with the components of the given <see cref="Vector4I"/>. /// </summary> /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>The added vector.</returns> - public static Vector4i operator +(Vector4i left, Vector4i right) + public static Vector4I operator +(Vector4I left, Vector4I right) { - left.x += right.x; - left.y += right.y; - left.z += right.z; - left.w += right.w; + left.X += right.X; + left.Y += right.Y; + left.Z += right.Z; + left.W += right.W; return left; } /// <summary> - /// Subtracts each component of the <see cref="Vector4i"/> - /// by the components of the given <see cref="Vector4i"/>. + /// Subtracts each component of the <see cref="Vector4I"/> + /// by the components of the given <see cref="Vector4I"/>. /// </summary> /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>The subtracted vector.</returns> - public static Vector4i operator -(Vector4i left, Vector4i right) + public static Vector4I operator -(Vector4I left, Vector4I right) { - left.x -= right.x; - left.y -= right.y; - left.z -= right.z; - left.w -= right.w; + left.X -= right.X; + left.Y -= right.Y; + left.Z -= right.Z; + left.W -= right.W; return left; } /// <summary> - /// Returns the negative value of the <see cref="Vector4i"/>. - /// This is the same as writing <c>new Vector4i(-v.x, -v.y, -v.z, -v.w)</c>. + /// Returns the negative value of the <see cref="Vector4I"/>. + /// This is the same as writing <c>new Vector4I(-v.X, -v.Y, -v.Z, -v.W)</c>. /// This operation flips the direction of the vector while /// keeping the same magnitude. /// </summary> /// <param name="vec">The vector to negate/flip.</param> /// <returns>The negated/flipped vector.</returns> - public static Vector4i operator -(Vector4i vec) + public static Vector4I operator -(Vector4I vec) { - vec.x = -vec.x; - vec.y = -vec.y; - vec.z = -vec.z; - vec.w = -vec.w; + vec.X = -vec.X; + vec.Y = -vec.Y; + vec.Z = -vec.Z; + vec.W = -vec.W; return vec; } /// <summary> - /// Multiplies each component of the <see cref="Vector4i"/> + /// Multiplies each component of the <see cref="Vector4I"/> /// by the given <see langword="int"/>. /// </summary> /// <param name="vec">The vector to multiply.</param> /// <param name="scale">The scale to multiply by.</param> /// <returns>The multiplied vector.</returns> - public static Vector4i operator *(Vector4i vec, int scale) + public static Vector4I operator *(Vector4I vec, int scale) { - vec.x *= scale; - vec.y *= scale; - vec.z *= scale; - vec.w *= scale; + vec.X *= scale; + vec.Y *= scale; + vec.Z *= scale; + vec.W *= scale; return vec; } /// <summary> - /// Multiplies each component of the <see cref="Vector4i"/> + /// Multiplies each component of the <see cref="Vector4I"/> /// by the given <see langword="int"/>. /// </summary> /// <param name="scale">The scale to multiply by.</param> /// <param name="vec">The vector to multiply.</param> /// <returns>The multiplied vector.</returns> - public static Vector4i operator *(int scale, Vector4i vec) + public static Vector4I operator *(int scale, Vector4I vec) { - vec.x *= scale; - vec.y *= scale; - vec.z *= scale; - vec.w *= scale; + vec.X *= scale; + vec.Y *= scale; + vec.Z *= scale; + vec.W *= scale; return vec; } /// <summary> - /// Multiplies each component of the <see cref="Vector4i"/> - /// by the components of the given <see cref="Vector4i"/>. + /// Multiplies each component of the <see cref="Vector4I"/> + /// by the components of the given <see cref="Vector4I"/>. /// </summary> /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>The multiplied vector.</returns> - public static Vector4i operator *(Vector4i left, Vector4i right) + public static Vector4I operator *(Vector4I left, Vector4I right) { - left.x *= right.x; - left.y *= right.y; - left.z *= right.z; - left.w *= right.w; + left.X *= right.X; + left.Y *= right.Y; + left.Z *= right.Z; + left.W *= right.W; return left; } /// <summary> - /// Divides each component of the <see cref="Vector4i"/> + /// Divides each component of the <see cref="Vector4I"/> /// by the given <see langword="int"/>. /// </summary> /// <param name="vec">The dividend vector.</param> /// <param name="divisor">The divisor value.</param> /// <returns>The divided vector.</returns> - public static Vector4i operator /(Vector4i vec, int divisor) + public static Vector4I operator /(Vector4I vec, int divisor) { - vec.x /= divisor; - vec.y /= divisor; - vec.z /= divisor; - vec.w /= divisor; + vec.X /= divisor; + vec.Y /= divisor; + vec.Z /= divisor; + vec.W /= divisor; return vec; } /// <summary> - /// Divides each component of the <see cref="Vector4i"/> - /// by the components of the given <see cref="Vector4i"/>. + /// Divides each component of the <see cref="Vector4I"/> + /// by the components of the given <see cref="Vector4I"/>. /// </summary> /// <param name="vec">The dividend vector.</param> /// <param name="divisorv">The divisor vector.</param> /// <returns>The divided vector.</returns> - public static Vector4i operator /(Vector4i vec, Vector4i divisorv) + public static Vector4I operator /(Vector4I vec, Vector4I divisorv) { - vec.x /= divisorv.x; - vec.y /= divisorv.y; - vec.z /= divisorv.z; - vec.w /= divisorv.w; + vec.X /= divisorv.X; + vec.Y /= divisorv.Y; + vec.Z /= divisorv.Z; + vec.W /= divisorv.W; return vec; } /// <summary> - /// Gets the remainder of each component of the <see cref="Vector4i"/> + /// Gets the remainder of each component of the <see cref="Vector4I"/> /// with the components of the given <see langword="int"/>. /// This operation uses truncated division, which is often not desired /// as it does not work well with negative numbers. + /// Consider using <see cref="Mathf.PosMod(int, int)"/> instead + /// if you want to handle negative numbers. /// </summary> /// <example> /// <code> - /// GD.Print(new Vecto43i(10, -20, 30, -40) % 7); // Prints "(3, -6, 2, -5)" + /// GD.Print(new Vector4I(10, -20, 30, -40) % 7); // Prints "(3, -6, 2, -5)" /// </code> /// </example> /// <param name="vec">The dividend vector.</param> /// <param name="divisor">The divisor value.</param> /// <returns>The remainder vector.</returns> - public static Vector4i operator %(Vector4i vec, int divisor) + public static Vector4I operator %(Vector4I vec, int divisor) { - vec.x %= divisor; - vec.y %= divisor; - vec.z %= divisor; - vec.w %= divisor; + vec.X %= divisor; + vec.Y %= divisor; + vec.Z %= divisor; + vec.W %= divisor; return vec; } /// <summary> - /// Gets the remainder of each component of the <see cref="Vector4i"/> - /// with the components of the given <see cref="Vector4i"/>. + /// Gets the remainder of each component of the <see cref="Vector4I"/> + /// with the components of the given <see cref="Vector4I"/>. /// This operation uses truncated division, which is often not desired /// as it does not work well with negative numbers. + /// Consider using <see cref="Mathf.PosMod(int, int)"/> instead + /// if you want to handle negative numbers. /// </summary> /// <example> /// <code> - /// GD.Print(new Vector4i(10, -20, 30, -40) % new Vector4i(6, 7, 8, 9)); // Prints "(4, -6, 6, -4)" + /// GD.Print(new Vector4I(10, -20, 30, -40) % new Vector4I(6, 7, 8, 9)); // Prints "(4, -6, 6, -4)" /// </code> /// </example> /// <param name="vec">The dividend vector.</param> /// <param name="divisorv">The divisor vector.</param> /// <returns>The remainder vector.</returns> - public static Vector4i operator %(Vector4i vec, Vector4i divisorv) + public static Vector4I operator %(Vector4I vec, Vector4I divisorv) { - vec.x %= divisorv.x; - vec.y %= divisorv.y; - vec.z %= divisorv.z; - vec.w %= divisorv.w; + vec.X %= divisorv.X; + vec.Y %= divisorv.Y; + vec.Z %= divisorv.Z; + vec.W %= divisorv.W; return vec; } @@ -438,7 +442,7 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the vectors are equal.</returns> - public static bool operator ==(Vector4i left, Vector4i right) + public static bool operator ==(Vector4I left, Vector4I right) { return left.Equals(right); } @@ -449,13 +453,13 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the vectors are not equal.</returns> - public static bool operator !=(Vector4i left, Vector4i right) + public static bool operator !=(Vector4I left, Vector4I right) { return !left.Equals(right); } /// <summary> - /// Compares two <see cref="Vector4i"/> vectors by first checking if + /// Compares two <see cref="Vector4I"/> vectors by first checking if /// the X value of the <paramref name="left"/> vector is less than /// the X value of the <paramref name="right"/> vector. /// If the X values are exactly equal, then it repeats this check @@ -465,25 +469,25 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the left is less than the right.</returns> - public static bool operator <(Vector4i left, Vector4i right) + public static bool operator <(Vector4I left, Vector4I right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - if (left.z == right.z) + if (left.Z == right.Z) { - return left.w < right.w; + return left.W < right.W; } - return left.z < right.z; + return left.Z < right.Z; } - return left.y < right.y; + return left.Y < right.Y; } - return left.x < right.x; + return left.X < right.X; } /// <summary> - /// Compares two <see cref="Vector4i"/> vectors by first checking if + /// Compares two <see cref="Vector4I"/> vectors by first checking if /// the X value of the <paramref name="left"/> vector is greater than /// the X value of the <paramref name="right"/> vector. /// If the X values are exactly equal, then it repeats this check @@ -493,25 +497,25 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the left is greater than the right.</returns> - public static bool operator >(Vector4i left, Vector4i right) + public static bool operator >(Vector4I left, Vector4I right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - if (left.z == right.z) + if (left.Z == right.Z) { - return left.w > right.w; + return left.W > right.W; } - return left.z > right.z; + return left.Z > right.Z; } - return left.y > right.y; + return left.Y > right.Y; } - return left.x > right.x; + return left.X > right.X; } /// <summary> - /// Compares two <see cref="Vector4i"/> vectors by first checking if + /// Compares two <see cref="Vector4I"/> vectors by first checking if /// the X value of the <paramref name="left"/> vector is less than /// or equal to the X value of the <paramref name="right"/> vector. /// If the X values are exactly equal, then it repeats this check @@ -521,25 +525,25 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the left is less than or equal to the right.</returns> - public static bool operator <=(Vector4i left, Vector4i right) + public static bool operator <=(Vector4I left, Vector4I right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - if (left.z == right.z) + if (left.Z == right.Z) { - return left.w <= right.w; + return left.W <= right.W; } - return left.z < right.z; + return left.Z < right.Z; } - return left.y < right.y; + return left.Y < right.Y; } - return left.x < right.x; + return left.X < right.X; } /// <summary> - /// Compares two <see cref="Vector4i"/> vectors by first checking if + /// Compares two <see cref="Vector4I"/> vectors by first checking if /// the X value of the <paramref name="left"/> vector is greater than /// or equal to the X value of the <paramref name="right"/> vector. /// If the X values are exactly equal, then it repeats this check @@ -549,43 +553,43 @@ namespace Godot /// <param name="left">The left vector.</param> /// <param name="right">The right vector.</param> /// <returns>Whether or not the left is greater than or equal to the right.</returns> - public static bool operator >=(Vector4i left, Vector4i right) + public static bool operator >=(Vector4I left, Vector4I right) { - if (left.x == right.x) + if (left.X == right.X) { - if (left.y == right.y) + if (left.Y == right.Y) { - if (left.z == right.z) + if (left.Z == right.Z) { - return left.w >= right.w; + return left.W >= right.W; } - return left.z > right.z; + return left.Z > right.Z; } - return left.y > right.y; + return left.Y > right.Y; } - return left.x > right.x; + return left.X > right.X; } /// <summary> - /// Converts this <see cref="Vector4i"/> to a <see cref="Vector4"/>. + /// Converts this <see cref="Vector4I"/> to a <see cref="Vector4"/>. /// </summary> /// <param name="value">The vector to convert.</param> - public static implicit operator Vector4(Vector4i value) + public static implicit operator Vector4(Vector4I value) { - return new Vector4(value.x, value.y, value.z, value.w); + return new Vector4(value.X, value.Y, value.Z, value.W); } /// <summary> - /// Converts a <see cref="Vector4"/> to a <see cref="Vector4i"/>. + /// Converts a <see cref="Vector4"/> to a <see cref="Vector4I"/>. /// </summary> /// <param name="value">The vector to convert.</param> - public static explicit operator Vector4i(Vector4 value) + public static explicit operator Vector4I(Vector4 value) { - return new Vector4i( - Mathf.RoundToInt(value.x), - Mathf.RoundToInt(value.y), - Mathf.RoundToInt(value.z), - Mathf.RoundToInt(value.w) + return new Vector4I( + Mathf.RoundToInt(value.X), + Mathf.RoundToInt(value.Y), + Mathf.RoundToInt(value.Z), + Mathf.RoundToInt(value.W) ); } @@ -597,7 +601,7 @@ namespace Godot /// <returns>Whether or not the vector and the object are equal.</returns> public override readonly bool Equals(object obj) { - return obj is Vector4i other && Equals(other); + return obj is Vector4I other && Equals(other); } /// <summary> @@ -605,36 +609,36 @@ namespace Godot /// </summary> /// <param name="other">The other vector.</param> /// <returns>Whether or not the vectors are equal.</returns> - public readonly bool Equals(Vector4i other) + public readonly bool Equals(Vector4I other) { - return x == other.x && y == other.y && z == other.z && w == other.w; + return X == other.X && Y == other.Y && Z == other.Z && W == other.W; } /// <summary> - /// Serves as the hash function for <see cref="Vector4i"/>. + /// Serves as the hash function for <see cref="Vector4I"/>. /// </summary> /// <returns>A hash code for this vector.</returns> public override readonly int GetHashCode() { - return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode() ^ w.GetHashCode(); + return Y.GetHashCode() ^ X.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode(); } /// <summary> - /// Converts this <see cref="Vector4i"/> to a string. + /// Converts this <see cref="Vector4I"/> to a string. /// </summary> /// <returns>A string representation of this vector.</returns> public override readonly string ToString() { - return $"({x}, {y}, {z}, {w})"; + return $"({X}, {Y}, {Z}, {W})"; } /// <summary> - /// Converts this <see cref="Vector4i"/> to a string with the given <paramref name="format"/>. + /// Converts this <see cref="Vector4I"/> to a string with the given <paramref name="format"/>. /// </summary> /// <returns>A string representation of this vector.</returns> public readonly string ToString(string format) { - return $"({x.ToString(format)}, {y.ToString(format)}, {z.ToString(format)}), {w.ToString(format)})"; + return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)}), {W.ToString(format)})"; } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj index 644212c74d..7aa2f7e959 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj +++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj @@ -49,7 +49,7 @@ </ItemGroup> <!-- Sources --> <ItemGroup> - <Compile Include="Core\AABB.cs" /> + <Compile Include="Core\Aabb.cs" /> <Compile Include="Core\Bridge\GodotSerializationInfo.cs" /> <Compile Include="Core\Bridge\MethodInfo.cs" /> <Compile Include="Core\Callable.generics.cs" /> @@ -60,8 +60,9 @@ <Compile Include="Core\Attributes\ExportCategoryAttribute.cs" /> <Compile Include="Core\Attributes\ExportGroupAttribute.cs" /> <Compile Include="Core\Attributes\ExportSubgroupAttribute.cs" /> + <Compile Include="Core\Attributes\GodotClassNameAttribute.cs" /> <Compile Include="Core\Attributes\MustBeVariantAttribute.cs" /> - <Compile Include="Core\Attributes\RPCAttribute.cs" /> + <Compile Include="Core\Attributes\RpcAttribute.cs" /> <Compile Include="Core\Attributes\ScriptPathAttribute.cs" /> <Compile Include="Core\Attributes\SignalAttribute.cs" /> <Compile Include="Core\Attributes\ToolAttribute.cs" /> @@ -80,11 +81,13 @@ <Compile Include="Core\DelegateUtils.cs" /> <Compile Include="Core\Dictionary.cs" /> <Compile Include="Core\Dispatcher.cs" /> + <Compile Include="Core\Extensions\GodotObjectExtensions.cs" /> <Compile Include="Core\Extensions\NodeExtensions.cs" /> - <Compile Include="Core\Extensions\ObjectExtensions.cs" /> <Compile Include="Core\Extensions\PackedSceneExtensions.cs" /> <Compile Include="Core\Extensions\ResourceLoaderExtensions.cs" /> <Compile Include="Core\GD.cs" /> + <Compile Include="Core\GodotObject.base.cs" /> + <Compile Include="Core\GodotObject.exceptions.cs" /> <Compile Include="Core\GodotSynchronizationContext.cs" /> <Compile Include="Core\GodotTaskScheduler.cs" /> <Compile Include="Core\GodotTraceListener.cs" /> @@ -104,15 +107,13 @@ <Compile Include="Core\NativeInterop\VariantUtils.cs" /> <Compile Include="Core\NativeInterop\VariantUtils.generic.cs" /> <Compile Include="Core\NodePath.cs" /> - <Compile Include="Core\Object.base.cs" /> - <Compile Include="Core\Object.exceptions.cs" /> <Compile Include="Core\Plane.cs" /> <Compile Include="Core\Projection.cs" /> <Compile Include="Core\Quaternion.cs" /> <Compile Include="Core\Rect2.cs" /> - <Compile Include="Core\Rect2i.cs" /> + <Compile Include="Core\Rect2I.cs" /> <Compile Include="Core\ReflectionUtils.cs" /> - <Compile Include="Core\RID.cs" /> + <Compile Include="Core\Rid.cs" /> <Compile Include="Core\NativeInterop\NativeFuncs.cs" /> <Compile Include="Core\NativeInterop\InteropStructs.cs" /> <Compile Include="Core\NativeInterop\Marshaling.cs" /> @@ -124,11 +125,11 @@ <Compile Include="Core\Transform3D.cs" /> <Compile Include="Core\Variant.cs" /> <Compile Include="Core\Vector2.cs" /> - <Compile Include="Core\Vector2i.cs" /> + <Compile Include="Core\Vector2I.cs" /> <Compile Include="Core\Vector3.cs" /> - <Compile Include="Core\Vector3i.cs" /> + <Compile Include="Core\Vector3I.cs" /> <Compile Include="Core\Vector4.cs" /> - <Compile Include="Core\Vector4i.cs" /> + <Compile Include="Core\Vector4I.cs" /> <Compile Include="GlobalUsings.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> </ItemGroup> diff --git a/modules/mono/glue/runtime_interop.cpp b/modules/mono/glue/runtime_interop.cpp index f0ea0313ea..306ac333eb 100644 --- a/modules/mono/glue/runtime_interop.cpp +++ b/modules/mono/glue/runtime_interop.cpp @@ -31,6 +31,7 @@ #include "runtime_interop.h" #include "core/config/engine.h" +#include "core/config/project_settings.h" #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" #include "core/io/marshalls.h" @@ -45,6 +46,7 @@ #include "modules/mono/managed_callable.h" #include "modules/mono/mono_gd/gd_mono_cache.h" #include "modules/mono/signal_awaiter_utils.h" +#include "modules/mono/utils/path_utils.h" #ifdef __cplusplus extern "C" { @@ -84,7 +86,8 @@ void godotsharp_stack_info_vector_destroy( void godotsharp_internal_script_debugger_send_error(const String *p_func, const String *p_file, int32_t p_line, const String *p_err, const String *p_descr, bool p_warning, const Vector<ScriptLanguage::StackInfo> *p_stack_info_vector) { - EngineDebugger::get_script_debugger()->send_error(*p_func, *p_file, p_line, *p_err, *p_descr, + const String file = ProjectSettings::get_singleton()->localize_path(p_file->simplify_path()); + EngineDebugger::get_script_debugger()->send_error(*p_func, file, p_line, *p_err, *p_descr, true, p_warning ? ERR_HANDLER_WARNING : ERR_HANDLER_ERROR, *p_stack_info_vector); } @@ -989,18 +992,78 @@ int32_t godotsharp_array_add(Array *p_self, const Variant *p_item) { return p_self->size(); } +int32_t godotsharp_array_add_range(Array *p_self, const Array *p_collection) { + p_self->append_array(*p_collection); + return p_self->size(); +} + +int32_t godotsharp_array_binary_search(const Array *p_self, int32_t p_index, int32_t p_length, const Variant *p_value) { + ERR_FAIL_COND_V(p_index < 0, -1); + ERR_FAIL_COND_V(p_length < 0, -1); + ERR_FAIL_COND_V(p_self->size() - p_index < p_length, -1); + + const Variant &value = *p_value; + const Array &array = *p_self; + + int lo = p_index; + int hi = p_index + p_length - 1; + while (lo <= hi) { + int mid = lo + ((hi - lo) >> 1); + const Variant &mid_item = array[mid]; + + if (mid_item == value) { + return mid; + } + if (mid_item < value) { + lo = mid + 1; + } else { + hi = mid - 1; + } + } + + return ~lo; +} + void godotsharp_array_duplicate(const Array *p_self, bool p_deep, Array *r_dest) { memnew_placement(r_dest, Array(p_self->duplicate(p_deep))); } -int32_t godotsharp_array_index_of(const Array *p_self, const Variant *p_item) { - return p_self->find(*p_item); +void godotsharp_array_fill(Array *p_self, const Variant *p_value) { + p_self->fill(*p_value); +} + +int32_t godotsharp_array_index_of(const Array *p_self, const Variant *p_item, int32_t p_index = 0) { + return p_self->find(*p_item, p_index); } void godotsharp_array_insert(Array *p_self, int32_t p_index, const Variant *p_item) { p_self->insert(p_index, *p_item); } +int32_t godotsharp_array_last_index_of(const Array *p_self, const Variant *p_item, int32_t p_index) { + return p_self->rfind(*p_item, p_index); +} + +void godotsharp_array_make_read_only(Array *p_self) { + p_self->make_read_only(); +} + +void godotsharp_array_max(const Array *p_self, Variant *r_value) { + *r_value = p_self->max(); +} + +void godotsharp_array_min(const Array *p_self, Variant *r_value) { + *r_value = p_self->min(); +} + +void godotsharp_array_pick_random(const Array *p_self, Variant *r_value) { + *r_value = p_self->pick_random(); +} + +bool godotsharp_array_recursive_equal(const Array *p_self, const Array *p_other) { + return p_self->recursive_equal(*p_other, 0); +} + void godotsharp_array_remove_at(Array *p_self, int32_t p_index) { p_self->remove_at(p_index); } @@ -1009,10 +1072,22 @@ int32_t godotsharp_array_resize(Array *p_self, int32_t p_new_size) { return (int32_t)p_self->resize(p_new_size); } +void godotsharp_array_reverse(Array *p_self) { + p_self->reverse(); +} + void godotsharp_array_shuffle(Array *p_self) { p_self->shuffle(); } +void godotsharp_array_slice(Array *p_self, int32_t p_start, int32_t p_end, int32_t p_step, bool p_deep, Array *r_dest) { + memnew_placement(r_dest, Array(p_self->slice(p_start, p_end, p_step, p_deep))); +} + +void godotsharp_array_sort(Array *p_self) { + p_self->sort(); +} + void godotsharp_array_to_string(const Array *p_self, String *r_str) { *r_str = Variant(*p_self).operator String(); } @@ -1066,10 +1141,22 @@ void godotsharp_dictionary_duplicate(const Dictionary *p_self, bool p_deep, Dict memnew_placement(r_dest, Dictionary(p_self->duplicate(p_deep))); } +void godotsharp_dictionary_merge(Dictionary *p_self, const Dictionary *p_dictionary, bool p_overwrite) { + p_self->merge(*p_dictionary, p_overwrite); +} + +bool godotsharp_dictionary_recursive_equal(const Dictionary *p_self, const Dictionary *p_other) { + return p_self->recursive_equal(*p_other, 0); +} + bool godotsharp_dictionary_remove_key(Dictionary *p_self, const Variant *p_key) { return p_self->erase(*p_key); } +void godotsharp_dictionary_make_read_only(Dictionary *p_self) { + p_self->make_read_only(); +} + void godotsharp_dictionary_to_string(const Dictionary *p_self, String *r_str) { *r_str = Variant(*p_self).operator String(); } @@ -1122,6 +1209,14 @@ bool godotsharp_node_path_is_absolute(const NodePath *p_self) { return p_self->is_absolute(); } +bool godotsharp_node_path_equals(const NodePath *p_self, const NodePath *p_other) { + return *p_self == *p_other; +} + +int godotsharp_node_path_hash(const NodePath *p_self) { + return p_self->hash(); +} + void godotsharp_randomize() { Math::randomize(); } @@ -1180,21 +1275,6 @@ void godotsharp_weakref(Object *p_ptr, Ref<RefCounted> *r_weak_ref) { memnew_placement(r_weak_ref, Ref<RefCounted>(wref)); } -void godotsharp_str(const godot_array *p_what, godot_string *r_ret) { - String &str = *memnew_placement(r_ret, String); - const Array &what = *reinterpret_cast<const Array *>(p_what); - - for (int i = 0; i < what.size(); i++) { - String os = what[i].operator String(); - - if (i == 0) { - str = os; - } else { - str += os; - } - } -} - void godotsharp_print(const godot_string *p_what) { print_line(*reinterpret_cast<const String *>(p_what)); } @@ -1438,12 +1518,24 @@ static const void *unmanaged_callbacks[]{ (void *)godotsharp_array_destroy, (void *)godotsharp_dictionary_destroy, (void *)godotsharp_array_add, + (void *)godotsharp_array_add_range, + (void *)godotsharp_array_binary_search, (void *)godotsharp_array_duplicate, + (void *)godotsharp_array_fill, (void *)godotsharp_array_index_of, (void *)godotsharp_array_insert, + (void *)godotsharp_array_last_index_of, + (void *)godotsharp_array_make_read_only, + (void *)godotsharp_array_max, + (void *)godotsharp_array_min, + (void *)godotsharp_array_pick_random, + (void *)godotsharp_array_recursive_equal, (void *)godotsharp_array_remove_at, (void *)godotsharp_array_resize, + (void *)godotsharp_array_reverse, (void *)godotsharp_array_shuffle, + (void *)godotsharp_array_slice, + (void *)godotsharp_array_sort, (void *)godotsharp_array_to_string, (void *)godotsharp_dictionary_try_get_value, (void *)godotsharp_dictionary_set_value, @@ -1455,7 +1547,10 @@ static const void *unmanaged_callbacks[]{ (void *)godotsharp_dictionary_clear, (void *)godotsharp_dictionary_contains_key, (void *)godotsharp_dictionary_duplicate, + (void *)godotsharp_dictionary_merge, + (void *)godotsharp_dictionary_recursive_equal, (void *)godotsharp_dictionary_remove_key, + (void *)godotsharp_dictionary_make_read_only, (void *)godotsharp_dictionary_to_string, (void *)godotsharp_string_simplify_path, (void *)godotsharp_string_to_camel_case, @@ -1469,6 +1564,8 @@ static const void *unmanaged_callbacks[]{ (void *)godotsharp_node_path_get_subname, (void *)godotsharp_node_path_get_subname_count, (void *)godotsharp_node_path_is_absolute, + (void *)godotsharp_node_path_equals, + (void *)godotsharp_node_path_hash, (void *)godotsharp_bytes_to_var, (void *)godotsharp_convert, (void *)godotsharp_hash, @@ -1488,7 +1585,6 @@ static const void *unmanaged_callbacks[]{ (void *)godotsharp_rand_from_seed, (void *)godotsharp_seed, (void *)godotsharp_weakref, - (void *)godotsharp_str, (void *)godotsharp_str_to_var, (void *)godotsharp_var_to_bytes, (void *)godotsharp_var_to_str, diff --git a/modules/mono/utils/naming_utils.cpp b/modules/mono/utils/naming_utils.cpp new file mode 100644 index 0000000000..62fbf815f8 --- /dev/null +++ b/modules/mono/utils/naming_utils.cpp @@ -0,0 +1,293 @@ +/**************************************************************************/ +/* naming_utils.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "naming_utils.h" + +#include "core/string/ucaps.h" +#include "core/templates/hash_map.h" + +HashMap<String, String> _create_hashmap_from_vector(Vector<Pair<String, String>> vector) { + HashMap<String, String> hashmap = HashMap<String, String>(vector.size()); + for (const Pair<String, String> &pair : vector) { + hashmap.insert(pair.first, pair.second); + } + return hashmap; +} + +// Hardcoded collection of PascalCase name conversions. +const HashMap<String, String> pascal_case_name_overrides = _create_hashmap_from_vector({ + { "BitMap", "Bitmap" }, + { "JSONRPC", "JsonRpc" }, + { "Object", "GodotObject" }, + { "OpenXRIPBinding", "OpenXRIPBinding" }, + { "SkeletonModification2DCCDIK", "SkeletonModification2DCcdik" }, + { "SkeletonModification2DFABRIK", "SkeletonModification2DFabrik" }, + { "SkeletonModification3DCCDIK", "SkeletonModification3DCcdik" }, + { "SkeletonModification3DFABRIK", "SkeletonModification3DFabrik" }, + { "System", "System_" }, + { "Thread", "GodotThread" }, +}); + +// Hardcoded collection of PascalCase part conversions. +const HashMap<String, String> pascal_case_part_overrides = _create_hashmap_from_vector({ + { "AA", "AA" }, // Anti Aliasing + { "AO", "AO" }, // Ambient Occlusion + { "FILENAME", "FileName" }, + { "FADEIN", "FadeIn" }, + { "FADEOUT", "FadeOut" }, + { "FX", "FX" }, + { "GI", "GI" }, // Global Illumination + { "GZIP", "GZip" }, + { "HBOX", "HBox" }, // Horizontal Box + { "ID", "Id" }, + { "IO", "IO" }, // Input/Output + { "IP", "IP" }, // Internet Protocol + { "IV", "IV" }, // Initialization Vector + { "MACOS", "MacOS" }, + { "NODEPATH", "NodePath" }, + { "SPIRV", "SpirV" }, + { "STDIN", "StdIn" }, + { "STDOUT", "StdOut" }, + { "USERNAME", "UserName" }, + { "UV", "UV" }, + { "UV2", "UV2" }, + { "VBOX", "VBox" }, // Vertical Box + { "WHITESPACE", "WhiteSpace" }, + { "WM", "WM" }, + { "XR", "XR" }, + { "XRAPI", "XRApi" }, +}); + +String _get_pascal_case_part_override(String p_part, bool p_input_is_upper = true) { + if (!p_input_is_upper) { + for (int i = 0; i < p_part.length(); i++) { + p_part[i] = _find_upper(p_part[i]); + } + } + + if (pascal_case_part_overrides.has(p_part)) { + return pascal_case_part_overrides.get(p_part); + } + + return String(); +} + +Vector<String> _split_pascal_case(const String &p_identifier) { + Vector<String> parts; + int current_part_start = 0; + bool prev_was_upper = is_ascii_upper_case(p_identifier[0]); + for (int i = 1; i < p_identifier.length(); i++) { + if (prev_was_upper) { + if (is_digit(p_identifier[i]) || is_ascii_lower_case(p_identifier[i])) { + if (!is_digit(p_identifier[i])) { + // These conditions only apply when the separator is not a digit. + if (i - current_part_start == 1) { + // Upper character was only the beginning of a word. + prev_was_upper = false; + continue; + } + if (i != p_identifier.length()) { + // If this is not the last character, the last uppercase + // character is the start of the next word. + i--; + } + } + if (i - current_part_start > 0) { + parts.append(p_identifier.substr(current_part_start, i - current_part_start)); + current_part_start = i; + prev_was_upper = false; + } + } + } else { + if (is_digit(p_identifier[i]) || is_ascii_upper_case(p_identifier[i])) { + parts.append(p_identifier.substr(current_part_start, i - current_part_start)); + current_part_start = i; + prev_was_upper = true; + } + } + } + + // Add the rest of the identifier as the last part. + if (current_part_start != p_identifier.length()) { + parts.append(p_identifier.substr(current_part_start)); + } + + return parts; +} + +String pascal_to_pascal_case(const String &p_identifier) { + if (p_identifier.length() == 0) { + return p_identifier; + } + + if (p_identifier.length() <= 2) { + return p_identifier.to_upper(); + } + + if (pascal_case_name_overrides.has(p_identifier)) { + // Use hardcoded value for the identifier. + return pascal_case_name_overrides.get(p_identifier); + } + + Vector<String> parts = _split_pascal_case(p_identifier); + + String ret; + + for (String &part : parts) { + String part_override = _get_pascal_case_part_override(part); + if (!part_override.is_empty()) { + // Use hardcoded value for part. + ret += part_override; + continue; + } + + if (part.length() <= 2 && part.to_upper() == part) { + // Acronym of length 1 or 2. + for (int j = 0; j < part.length(); j++) { + part[j] = _find_upper(part[j]); + } + ret += part; + continue; + } + + part[0] = _find_upper(part[0]); + for (int i = 1; i < part.length(); i++) { + if (is_digit(part[i - 1])) { + // Use uppercase after digits. + part[i] = _find_upper(part[i]); + continue; + } + + part[i] = _find_lower(part[i]); + } + ret += part; + } + + return ret; +} + +String snake_to_pascal_case(const String &p_identifier, bool p_input_is_upper) { + String ret; + Vector<String> parts = p_identifier.split("_", true); + + for (int i = 0; i < parts.size(); i++) { + String part = parts[i]; + + String part_override = _get_pascal_case_part_override(part, p_input_is_upper); + if (!part_override.is_empty()) { + // Use hardcoded value for part. + ret += part_override; + continue; + } + + if (!part.is_empty()) { + part[0] = _find_upper(part[0]); + for (int j = 1; j < part.length(); j++) { + if (is_digit(part[j - 1])) { + // Use uppercase after digits. + part[j] = _find_upper(part[j]); + continue; + } + + if (p_input_is_upper) { + part[j] = _find_lower(part[j]); + } + } + ret += part; + } else { + if (i == 0 || i == (parts.size() - 1)) { + // Preserve underscores at the beginning and end + ret += "_"; + } else { + // Preserve contiguous underscores + if (parts[i - 1].length()) { + ret += "__"; + } else { + ret += "_"; + } + } + } + } + + return ret; +} + +String snake_to_camel_case(const String &p_identifier, bool p_input_is_upper) { + String ret; + Vector<String> parts = p_identifier.split("_", true); + + for (int i = 0; i < parts.size(); i++) { + String part = parts[i]; + + String part_override = _get_pascal_case_part_override(part, p_input_is_upper); + if (!part_override.is_empty()) { + // Use hardcoded value for part. + if (i == 0) { + part_override[0] = _find_lower(part_override[0]); + } + ret += part_override; + continue; + } + + if (!part.is_empty()) { + if (i == 0) { + part[0] = _find_lower(part[0]); + } else { + part[0] = _find_upper(part[0]); + } + for (int j = 1; j < part.length(); j++) { + if (is_digit(part[j - 1])) { + // Use uppercase after digits. + part[j] = _find_upper(part[j]); + continue; + } + + if (p_input_is_upper) { + part[j] = _find_lower(part[j]); + } + } + ret += part; + } else { + if (i == 0 || i == (parts.size() - 1)) { + // Preserve underscores at the beginning and end + ret += "_"; + } else { + // Preserve contiguous underscores + if (parts[i - 1].length()) { + ret += "__"; + } else { + ret += "_"; + } + } + } + } + + return ret; +} diff --git a/modules/mono/utils/naming_utils.h b/modules/mono/utils/naming_utils.h new file mode 100644 index 0000000000..ac64a5c114 --- /dev/null +++ b/modules/mono/utils/naming_utils.h @@ -0,0 +1,42 @@ +/**************************************************************************/ +/* naming_utils.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef MONO_NAMING_UTILS_H +#define MONO_NAMING_UTILS_H + +#include "core/string/ustring.h" + +String pascal_to_pascal_case(const String &p_identifier); + +String snake_to_pascal_case(const String &p_identifier, bool p_input_is_upper = false); + +String snake_to_camel_case(const String &p_identifier, bool p_input_is_upper = false); + +#endif // MONO_NAMING_UTILS_H |