diff options
Diffstat (limited to 'modules/mono')
-rw-r--r-- | modules/mono/csharp_script.cpp | 2 | ||||
-rw-r--r-- | modules/mono/csharp_script.h | 2 | ||||
-rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs | 6 | ||||
-rw-r--r-- | modules/mono/editor/bindings_generator.cpp | 105 | ||||
-rw-r--r-- | modules/mono/editor/bindings_generator.h | 1 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs | 101 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs | 2 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs | 16 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs | 21 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_log.cpp | 2 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_log.h | 4 |
11 files changed, 208 insertions, 54 deletions
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index bd29dc1876..25cc64393a 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -3644,7 +3644,7 @@ void CSharpScript::get_members(Set<StringName> *p_members) { /*************** RESOURCE ***************/ -RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { +RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; } diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 85edd8b9c6..a31135cd32 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -542,7 +542,7 @@ public: class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader { public: - RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false) override; + RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override; void get_recognized_extensions(List<String> *p_extensions) const override; bool handles_type(const String &p_type) const override; String get_resource_type(const String &p_path) const override; diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs index 5ef55fea49..774c49e705 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs @@ -86,7 +86,7 @@ namespace GodotTools.Build { case BuildTool.DotnetCli: { - string dotnetCliPath = OS.PathWhich("dotnet"); + string dotnetCliPath = FindBuildEngineOnUnix("dotnet"); if (!string.IsNullOrEmpty(dotnetCliPath)) return (dotnetCliPath, BuildTool.DotnetCli); GD.PushError($"Cannot find executable for '{BuildManager.PropNameDotnetCli}'. Fallback to MSBuild from Mono."); @@ -122,7 +122,11 @@ namespace GodotTools.Build if (OS.IsMacOS) { result.Add("/Library/Frameworks/Mono.framework/Versions/Current/bin/"); + result.Add("/opt/local/bin/"); result.Add("/usr/local/var/homebrew/linked/mono/bin/"); + result.Add("/usr/local/bin/"); + result.Add("/usr/local/bin/dotnet/"); + result.Add("/usr/local/share/dotnet/"); } result.Add("/opt/novell/mono/bin/"); diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 38e403b2e1..167e9d75a1 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -783,6 +783,72 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) { } } +void BindingsGenerator::_generate_array_extensions(StringBuilder &p_output) { + p_output.append("using System;\n\n"); + p_output.append("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK); + // The class where we put the extensions doesn't matter, so just use "GD". + p_output.append(INDENT1 "public static partial class " BINDINGS_GLOBAL_SCOPE_CLASS "\n" INDENT1 "{"); + +#define ARRAY_IS_EMPTY(m_type) \ + p_output.append("\n" INDENT2 "/// <summary>\n"); \ + p_output.append(INDENT2 "/// Returns true if this " #m_type " array is empty or doesn't exist.\n"); \ + p_output.append(INDENT2 "/// </summary>\n"); \ + p_output.append(INDENT2 "/// <param name=\"instance\">The " #m_type " array check.</param>\n"); \ + p_output.append(INDENT2 "/// <returns>Whether or not the array is empty.</returns>\n"); \ + p_output.append(INDENT2 "public static bool IsEmpty(this " #m_type "[] instance)\n"); \ + p_output.append(INDENT2 OPEN_BLOCK); \ + p_output.append(INDENT3 "return instance == null || instance.Length == 0;\n"); \ + p_output.append(INDENT2 CLOSE_BLOCK); + +#define ARRAY_JOIN(m_type) \ + p_output.append("\n" INDENT2 "/// <summary>\n"); \ + p_output.append(INDENT2 "/// Converts this " #m_type " array to a string delimited by the given string.\n"); \ + p_output.append(INDENT2 "/// </summary>\n"); \ + p_output.append(INDENT2 "/// <param name=\"instance\">The " #m_type " array to convert.</param>\n"); \ + p_output.append(INDENT2 "/// <param name=\"delimiter\">The delimiter to use between items.</param>\n"); \ + p_output.append(INDENT2 "/// <returns>A single string with all items.</returns>\n"); \ + p_output.append(INDENT2 "public static string Join(this " #m_type "[] instance, string delimiter = \", \")\n"); \ + p_output.append(INDENT2 OPEN_BLOCK); \ + p_output.append(INDENT3 "return String.Join(delimiter, instance);\n"); \ + p_output.append(INDENT2 CLOSE_BLOCK); + +#define ARRAY_STRINGIFY(m_type) \ + p_output.append("\n" INDENT2 "/// <summary>\n"); \ + p_output.append(INDENT2 "/// Converts this " #m_type " array to a string with brackets.\n"); \ + p_output.append(INDENT2 "/// </summary>\n"); \ + p_output.append(INDENT2 "/// <param name=\"instance\">The " #m_type " array to convert.</param>\n"); \ + p_output.append(INDENT2 "/// <returns>A single string with all items.</returns>\n"); \ + p_output.append(INDENT2 "public static string Stringify(this " #m_type "[] instance)\n"); \ + p_output.append(INDENT2 OPEN_BLOCK); \ + p_output.append(INDENT3 "return \"[\" + instance.Join() + \"]\";\n"); \ + p_output.append(INDENT2 CLOSE_BLOCK); + +#define ARRAY_ALL(m_type) \ + ARRAY_IS_EMPTY(m_type) \ + ARRAY_JOIN(m_type) \ + ARRAY_STRINGIFY(m_type) + + ARRAY_ALL(byte); + ARRAY_ALL(int); + ARRAY_ALL(long); + ARRAY_ALL(float); + ARRAY_ALL(double); + ARRAY_ALL(string); + ARRAY_ALL(Color); + ARRAY_ALL(Vector2); + ARRAY_ALL(Vector2i); + ARRAY_ALL(Vector3); + ARRAY_ALL(Vector3i); + +#undef ARRAY_ALL +#undef ARRAY_IS_EMPTY +#undef ARRAY_JOIN +#undef ARRAY_STRINGIFY + + p_output.append(INDENT1 CLOSE_BLOCK); // End of GD class. + p_output.append(CLOSE_BLOCK); // End of namespace. +} + void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) { // Constants (in partial GD class) @@ -926,6 +992,19 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) { compile_items.push_back(output_file); } + // Generate source file for array extensions + { + StringBuilder extensions_source; + _generate_array_extensions(extensions_source); + String output_file = path::join(base_gen_dir, BINDINGS_GLOBAL_SCOPE_CLASS "_extensions.cs"); + Error save_err = _save_file(output_file, extensions_source); + if (save_err != OK) { + return save_err; + } + + compile_items.push_back(output_file); + } + for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) { const TypeInterface &itype = E.get(); @@ -1479,6 +1558,12 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte ERR_FAIL_COND_V_MSG(prop_itype->is_singleton, ERR_BUG, "Property type is a singleton: '" + p_itype.name + "." + String(p_iprop.cname) + "'."); + if (p_itype.api_type == ClassDB::API_CORE) { + ERR_FAIL_COND_V_MSG(prop_itype->api_type == ClassDB::API_EDITOR, ERR_BUG, + "Property '" + p_itype.name + "." + String(p_iprop.cname) + "' has type '" + prop_itype->name + + "' from the editor API. Core API cannot have dependencies on the editor API."); + } + if (p_iprop.prop_doc && p_iprop.prop_doc->description.size()) { String xml_summary = bbcode_to_xml(fix_doc_description(p_iprop.prop_doc->description), &p_itype); Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>(); @@ -1575,6 +1660,12 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf ERR_FAIL_COND_V_MSG(return_type->is_singleton, ERR_BUG, "Method return type is a singleton: '" + p_itype.name + "." + p_imethod.name + "'."); + if (p_itype.api_type == ClassDB::API_CORE) { + ERR_FAIL_COND_V_MSG(return_type->api_type == ClassDB::API_EDITOR, ERR_BUG, + "Method '" + p_itype.name + "." + p_imethod.name + "' has return type '" + return_type->name + + "' from the editor API. Core API cannot have dependencies on the editor API."); + } + String method_bind_field = "__method_bind_" + itos(p_method_bind_count); String arguments_sig; @@ -1593,6 +1684,12 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG, "Argument type is a singleton: '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "'."); + if (p_itype.api_type == ClassDB::API_CORE) { + ERR_FAIL_COND_V_MSG(arg_type->api_type == ClassDB::API_EDITOR, ERR_BUG, + "Argument '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "' has type '" + + arg_type->name + "' from the editor API. Core API cannot have dependencies on the editor API."); + } + if (iarg.default_argument.size()) { CRASH_COND_MSG(!_arg_default_value_is_assignable_to_type(iarg.def_param_value, *arg_type), "Invalid default value for parameter '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "'."); @@ -1806,7 +1903,13 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type); ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG, - "Argument type is a singleton: '" + iarg.name + "' of signal" + p_itype.name + "." + p_isignal.name + "'."); + "Argument type is a singleton: '" + iarg.name + "' of signal '" + p_itype.name + "." + p_isignal.name + "'."); + + if (p_itype.api_type == ClassDB::API_CORE) { + ERR_FAIL_COND_V_MSG(arg_type->api_type == ClassDB::API_EDITOR, ERR_BUG, + "Argument '" + iarg.name + "' of signal '" + p_itype.name + "." + p_isignal.name + "' has type '" + + arg_type->name + "' from the editor API. Core API cannot have dependencies on the editor API."); + } // Add the current arguments to the signature diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index b18dfb0ec4..876046176b 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -661,6 +661,7 @@ class BindingsGenerator { Error _generate_cs_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, int &p_method_bind_count, StringBuilder &p_output); Error _generate_cs_signal(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::SignalInterface &p_isignal, StringBuilder &p_output); + void _generate_array_extensions(StringBuilder &p_output); void _generate_global_constants(StringBuilder &p_output); Error _generate_glue_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, StringBuilder &p_output); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs index 90141928ca..0c333d06ef 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs @@ -104,7 +104,7 @@ namespace Godot /// <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> + /// <value>Getting is a long process, refer to the source code for details. Setting uses <see cref="FromHSV"/>.</value> public float h { get @@ -145,14 +145,14 @@ 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> + /// <value>Getting is equivalent to the ratio between the min and max RGB value. Setting uses <see cref="FromHSV"/>.</value> public float s { get @@ -166,14 +166,14 @@ 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 `Max()` on the RGB components. Setting uses <see cref="FromHsv"/>.</value> + /// <value>Getting is equivalent to using `Max()` on the RGB components. Setting uses <see cref="FromHSV"/>.</value> public float v { get @@ -182,7 +182,7 @@ namespace Godot } set { - this = FromHsv(h, s, value, a); + this = FromHSV(h, s, value, a); } } @@ -455,7 +455,7 @@ namespace Godot /// </summary> /// <param name="includeAlpha">Whether or not to include alpha. If false, the color is RGB instead of RGBA.</param> /// <returns>A string for the HTML hexadecimal representation of this color.</returns> - public string ToHtml(bool includeAlpha = true) + public string ToHTML(bool includeAlpha = true) { var txt = string.Empty; @@ -532,18 +532,50 @@ namespace Godot } /// <summary> + /// Constructs a color either from an HTML color code or from a + /// standardized color name. Supported + /// color names are the same as the <see cref="Colors"/> constants. + /// </summary> + /// <param name="code">The HTML color code or color name to construct from.</param> + public Color(string code) + { + if (HtmlIsValid(code)) + { + this = FromHTML(code); + } + else + { + this = Named(code); + } + } + + /// <summary> + /// Constructs a color either from an HTML color code or from a + /// standardized color name, with `alpha` on the range of 0 to 1. Supported + /// color names are the same as the <see cref="Colors"/> constants. + /// </summary> + /// <param name="code">The HTML color code or color name to construct from.</param> + /// <param name="alpha">The alpha (transparency) value, typically on the range of 0 to 1.</param> + public Color(string code, float alpha) + { + this = new Color(code); + a = alpha; + } + + /// <summary> /// Constructs a color from the HTML hexadecimal color string in RGBA format. /// </summary> /// <param name="rgba">A string for the HTML hexadecimal representation of this color.</param> - public Color(string rgba) + private static Color FromHTML(string rgba) { + Color c; if (rgba.Length == 0) { - r = 0f; - g = 0f; - b = 0f; - a = 1.0f; - return; + c.r = 0f; + c.g = 0f; + c.b = 0f; + c.a = 1.0f; + return c; } if (rgba[0] == '#') @@ -577,47 +609,48 @@ namespace Godot throw new ArgumentOutOfRangeException("Invalid color code. Length is " + rgba.Length + " but a length of 6 or 8 is expected: " + rgba); } - a = 1.0f; + c.a = 1.0f; if (isShorthand) { - r = ParseCol4(rgba, 0) / 15f; - g = ParseCol4(rgba, 1) / 15f; - 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) { - a = ParseCol4(rgba, 3) / 15f; + c.a = ParseCol4(rgba, 3) / 15f; } } else { - r = ParseCol8(rgba, 0) / 255f; - g = ParseCol8(rgba, 2) / 255f; - 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) { - a = ParseCol8(rgba, 6) / 255f; + c.a = ParseCol8(rgba, 6) / 255f; } } - if (r < 0) + if (c.r < 0) { throw new ArgumentOutOfRangeException("Invalid color code. Red part is not valid hexadecimal: " + rgba); } - if (g < 0) + if (c.g < 0) { throw new ArgumentOutOfRangeException("Invalid color code. Green part is not valid hexadecimal: " + rgba); } - if (b < 0) + if (c.b < 0) { throw new ArgumentOutOfRangeException("Invalid color code. Blue part is not valid hexadecimal: " + rgba); } - if (a < 0) + if (c.a < 0) { throw new ArgumentOutOfRangeException("Invalid color code. Alpha part is not valid hexadecimal: " + rgba); } + return c; } /// <summary> @@ -640,9 +673,8 @@ namespace Godot /// the constants defined in <see cref="Colors"/>. /// </summary> /// <param name="name">The name of the color.</param> - /// <param name="alpha">The alpha (transparency) component represented on the range of 0 to 1. Default: 1.</param> /// <returns>The constructed color.</returns> - public static Color ColorN(string name, float alpha = 1f) + private static Color Named(string name) { name = name.Replace(" ", String.Empty); name = name.Replace("-", String.Empty); @@ -656,9 +688,7 @@ namespace Godot throw new ArgumentOutOfRangeException($"Invalid Color Name: {name}"); } - Color color = Colors.namedColors[name]; - color.a = alpha; - return color; + return Colors.namedColors[name]; } /// <summary> @@ -671,11 +701,11 @@ 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) { - // acp_hromatic (grey) + // Achromatic (grey) return new Color(value, value, value, alpha); } @@ -715,7 +745,7 @@ 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 void ToHsv(out float hue, out float saturation, out float value) + public 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)); @@ -803,7 +833,8 @@ namespace Godot } // Check if each hex digit is valid. - for (int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) + { if (ParseCol4(color, i) == -1) { return false; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs index 5f64c09a89..74fa05d1fd 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs @@ -2,7 +2,7 @@ namespace Godot { public static partial class ResourceLoader { - public static T Load<T>(string path, string typeHint = null, bool noCache = false) where T : class + public static T Load<T>(string path, string typeHint = null, CacheMode noCache = CacheMode.Reuse) where T : class { return (T)(object)Load(path, typeHint, noCache); } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs index 4dc182fb73..98efa89ef0 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs @@ -462,18 +462,18 @@ namespace Godot } // <summary> - // Hash the string and return a 32 bits integer. + // Hash the string and return a 32 bits unsigned integer. // </summary> - public static int Hash(this string instance) + public static uint Hash(this string instance) { - int index = 0; - int hashv = 5381; - int c; + uint hash = 5381; - while ((c = instance[index++]) != 0) - hashv = (hashv << 5) + hashv + c; // hash * 33 + c + foreach(uint c in instance) + { + hash = (hash << 5) + hash + c; // hash * 33 + c + } - return hashv; + return hash; } /// <summary> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index 42dbdf25c3..3b895bbbf6 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -111,10 +111,10 @@ namespace Godot } /// <summary> - /// Returns the minimum angle to the given vector, in radians. + /// Returns the unsigned minimum angle to the given vector, in radians. /// </summary> /// <param name="to">The other vector to compare this vector to.</param> - /// <returns>The angle between the two vectors, in radians.</returns> + /// <returns>The unsigned angle between the two vectors, in radians.</returns> public real_t AngleTo(Vector3 to) { return Mathf.Atan2(Cross(to).Length(), Dot(to)); @@ -469,6 +469,23 @@ namespace Godot } /// <summary> + /// Returns the signed angle to the given vector, in radians. + /// The sign of the angle is positive in a counter-clockwise + /// direction and negative in a clockwise direction when viewed + /// from the side specified by the `axis`. + /// </summary> + /// <param name="to">The other vector to compare this vector to.</param> + /// <param name="axis">The reference axis to use for the angle sign.</param> + /// <returns>The signed angle between the two vectors, in radians.</returns> + public real_t SignedAngleTo(Vector3 to, Vector3 axis) + { + Vector3 crossTo = Cross(to); + real_t unsignedAngle = Mathf.Atan2(crossTo.Length(), Dot(to)); + real_t sign = crossTo.Dot(axis); + return (sign < 0) ? -unsignedAngle : unsignedAngle; + } + + /// <summary> /// Returns the result of the spherical linear interpolation between /// this vector and `to` by amount `weight`. /// diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp index e1d283242c..dafd36c36b 100644 --- a/modules/mono/mono_gd/gd_mono_log.cpp +++ b/modules/mono/mono_gd/gd_mono_log.cpp @@ -189,8 +189,6 @@ void GDMonoLog::initialize() { GDMonoLog::GDMonoLog() { singleton = this; - - log_level_id = -1; } GDMonoLog::~GDMonoLog() { diff --git a/modules/mono/mono_gd/gd_mono_log.h b/modules/mono/mono_gd/gd_mono_log.h index 9a95e3cb0a..f7a53156ab 100644 --- a/modules/mono/mono_gd/gd_mono_log.h +++ b/modules/mono/mono_gd/gd_mono_log.h @@ -46,9 +46,9 @@ class GDMonoLog { #ifdef GD_MONO_LOG_ENABLED - int log_level_id; + int log_level_id = -1; - FileAccess *log_file; + FileAccess *log_file = nullptr; String log_file_path; bool _try_create_logs_dir(const String &p_logs_dir); |