From 47ca2f2e092b985e6c56a70781ac1a18972245a1 Mon Sep 17 00:00:00 2001 From: Raul Santos Date: Tue, 24 Jan 2023 02:08:15 +0100 Subject: C#: Sync GD with Core - Add overloads to print methods that take a single `string`. - Use `StringBuilder` to append print parameters. - Remove `PrintStack` method. - Add `ErrorString`. - Remove `Str` method. - Add exception to `Range` when step is 0. - Add `VarToBytesWithObjects` and `BytesToVarWithObjects`. - Remove optional boolean parameter from `VarToBytes` and `BytesToVar`. - Move `InstanceFromId` to `Godot.Object`. - Add `Godot.Object.IsInstanceIdValid`. - Update documentation. --- doc/classes/@GlobalScope.xml | 187 +++++++-- .../GodotSharp/GodotSharp/Core/DelegateUtils.cs | 2 +- .../GodotSharp/Core/Extensions/ObjectExtensions.cs | 42 ++- modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs | 419 +++++++++++++-------- .../GodotSharp/Core/NativeInterop/Marshaling.cs | 2 +- .../GodotSharp/Core/NativeInterop/NativeFuncs.cs | 2 - modules/mono/glue/runtime_interop.cpp | 16 - 7 files changed, 459 insertions(+), 211 deletions(-) diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 2be15d5100..1da7c652be 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -442,9 +442,14 @@ Returns the integer hash of the passed [param variable]. - [codeblock] + [codeblocks] + [gdscript] print(hash("a")) # Prints 177670 - [/codeblock] + [/gdscript] + [csharp] + GD.Print(GD.Hash("a")); // Prints 177670 + [/csharp] + [/codeblocks] @@ -452,13 +457,29 @@ Returns the [Object] that corresponds to [param instance_id]. All Objects have a unique instance ID. See also [method Object.get_instance_id]. - [codeblock] + [codeblocks] + [gdscript] var foo = "bar" + func _ready(): var id = get_instance_id() var inst = instance_from_id(id) print(inst.foo) # Prints bar - [/codeblock] + [/gdscript] + [csharp] + 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 + } + } + [/csharp] + [/codeblocks] @@ -764,10 +785,16 @@ Converts one or more arguments of any type to string in the best way possible and prints them to the console. - [codeblock] + [codeblocks] + [gdscript] var a = [1, 2, 3] print("a", "b", a) # Prints ab[1, 2, 3] - [/codeblock] + [/gdscript] + [csharp] + var a = new Godot.Collections.Array { 1, 2, 3 }; + GD.Print("a", "b", a); // Prints ab[1, 2, 3] + [/csharp] + [/codeblocks] [b]Note:[/b] Consider using [method push_error] and [method push_warning] to print error and warning messages instead of [method print] or [method print_rich]. This distinguishes them from print messages used for debugging purposes, while also displaying a stack trace when an error or warning is printed. @@ -775,9 +802,14 @@ Converts one or more arguments of any type to string in the best way possible and prints them 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 [code]red[/code], [i]not[/i] 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. - [codeblock] + [codeblocks] + [gdscript] print_rich("[code][b]Hello world![/b][/code]") # Prints out: [b]Hello world![/b] - [/codeblock] + [/gdscript] + [csharp] + GD.PrintRich("[code][b]Hello world![/b][/code]"); // Prints out: [b]Hello world![/b] + [/csharp] + [/codeblocks] [b]Note:[/b] Consider using [method push_error] and [method push_warning] to print error and warning messages instead of [method print] or [method print_rich]. This distinguishes them from print messages used for debugging purposes, while also displaying a stack trace when an error or warning is printed. @@ -789,53 +821,86 @@ Prints one or more arguments to strings in the best way possible to standard error line. - [codeblock] + [codeblocks] + [gdscript] printerr("prints to stderr") - [/codeblock] + [/gdscript] + [csharp] + GD.PrintErr("prints to stderr"); + [/csharp] + [/codeblocks] Prints one or more arguments to strings in the best way possible to the OS terminal. Unlike [method print], no newline is automatically added at the end. - [codeblock] + [codeblocks] + [gdscript] printraw("A") printraw("B") printraw("C") # Prints ABC to terminal - [/codeblock] + [/gdscript] + [csharp] + GD.PrintRaw("A"); + GD.PrintRaw("B"); + GD.PrintRaw("C"); + // Prints ABC to terminal + [/csharp] + [/codeblocks] Prints one or more arguments to the console with a space between each argument. - [codeblock] + [codeblocks] + [gdscript] prints("A", "B", "C") # Prints A B C - [/codeblock] + [/gdscript] + [csharp] + GD.PrintS("A", "B", "C"); // Prints A B C + [/csharp] + [/codeblocks] Prints one or more arguments to the console with a tab between each argument. - [codeblock] + [codeblocks] + [gdscript] printt("A", "B", "C") # Prints A B C - [/codeblock] + [/gdscript] + [csharp] + GD.PrintT("A", "B", "C"); // Prints A B C + [/csharp] + [/codeblocks] Pushes an error message to Godot's built-in debugger and to the OS terminal. - [codeblock] + [codeblocks] + [gdscript] push_error("test error") # Prints "test error" to debugger and terminal as error call - [/codeblock] + [/gdscript] + [csharp] + GD.PushError("test error"); // Prints "test error" to debugger and terminal as error call + [/csharp] + [/codeblocks] [b]Note:[/b] This function does not pause project execution. To print an error message and pause project execution in debug builds, use [code]assert(false, "test error")[/code] instead. Pushes a warning message to Godot's built-in debugger and to the OS terminal. - [codeblock] + [codeblocks] + [gdscript] push_warning("test warning") # Prints "test warning" to debugger and terminal as warning call - [/codeblock] + [/gdscript] + [csharp] + GD.PushWarning("test warning"); // Prints "test warning" to debugger and terminal as warning call + [/csharp] + [/codeblocks] @@ -868,9 +933,14 @@ Returns a random floating point value between [code]0.0[/code] and [code]1.0[/code] (inclusive). - [codeblock] + [codeblocks] + [gdscript] randf() # Returns e.g. 0.375671 - [/codeblock] + [/gdscript] + [csharp] + GD.Randf(); // Returns e.g. 0.375671 + [/csharp] + [/codeblocks] @@ -879,10 +949,16 @@ Returns a random floating point value between [param from] and [param to] (inclusive). - [codeblock] + [codeblocks] + [gdscript] randf_range(0, 20.5) # Returns e.g. 7.45315 randf_range(-10, 10) # Returns e.g. -3.844535 - [/codeblock] + [/gdscript] + [csharp] + GD.RandRange(0.0, 20.5); // Returns e.g. 7.45315 + GD.RandRange(-10.0, 10.0); // Returns e.g. -3.844535 + [/csharp] + [/codeblocks] @@ -897,12 +973,20 @@ Returns a random unsigned 32-bit integer. Use remainder to obtain a random value in the interval [code][0, N - 1][/code] (where N is smaller than 2^32). - [codeblock] + [codeblocks] + [gdscript] randi() # Returns random integer between 0 and 2^32 - 1 randi() % 20 # Returns random integer between 0 and 19 randi() % 100 # Returns random integer between 0 and 99 randi() % 100 + 1 # Returns random integer between 1 and 100 - [/codeblock] + [/gdscript] + [csharp] + GD.Randi(); // Returns random integer between 0 and 2^32 - 1 + GD.Randi() % 20; // Returns random integer between 0 and 19 + GD.Randi() % 100; // Returns random integer between 0 and 99 + GD.Randi() % 100 + 1; // Returns random integer between 1 and 100 + [/csharp] + [/codeblocks] @@ -911,10 +995,16 @@ Returns a random signed 32-bit integer between [param from] and [param to] (inclusive). If [param to] is lesser than [param from], they are swapped. - [codeblock] + [codeblocks] + [gdscript] randi_range(0, 1) # Returns either 0 or 1 randi_range(-10, 1000) # Returns random integer between -10 and 1000 - [/codeblock] + [/gdscript] + [csharp] + GD.RandRange(0, 1); // Returns either 0 or 1 + GD.RandRange(-10, 1000); // Returns random integer between -10 and 1000 + [/csharp] + [/codeblocks] @@ -985,14 +1075,24 @@ Sets the seed for the random number generator to [param base]. Setting the seed manually can ensure consistent, repeatable results for most random functions. - [codeblock] + [codeblocks] + [gdscript] var my_seed = "Godot Rocks".hash() seed(my_seed) var a = randf() + randi() seed(my_seed) var b = randf() + randi() # a and b are now identical - [/codeblock] + [/gdscript] + [csharp] + 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 + [/csharp] + [/codeblocks] @@ -1154,11 +1254,18 @@ Converts a formatted [param string] that was returned by [method var_to_str] to the original [Variant]. - [codeblock] + [codeblocks] + [gdscript] var a = '{ "a": 1, "b": 2 }' # a is a String var b = str_to_var(a) # b is a Dictionary print(b["a"]) # Prints 1 - [/codeblock] + [/gdscript] + [csharp] + 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 + [/csharp] + [/codeblocks] @@ -1218,15 +1325,21 @@ Converts a [Variant] [param variable] to a formatted [String] that can then be parsed using [method str_to_var]. - [codeblock] - a = { "a": 1, "b": 2 } + [codeblocks] + [gdscript] + var a = { "a": 1, "b": 2 } print(var_to_str(a)) - [/codeblock] + [/gdscript] + [csharp] + var a = new Godot.Collections.Dictionary { ["a"] = 1, ["b"] = 2 }; + GD.Print(GD.VarToStr(a)); + [/csharp] + [/codeblocks] Prints: [codeblock] { - "a": 1, - "b": 2 + "a": 1, + "b": 2 } [/codeblock] diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs index d94fbff331..0f97149130 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs @@ -399,7 +399,7 @@ namespace Godot { ulong objectId = reader.ReadUInt64(); // ReSharper disable once RedundantNameQualifier - Godot.Object godotObject = GD.InstanceFromId(objectId); + Godot.Object godotObject = Godot.Object.InstanceFromId(objectId); if (godotObject == null) return false; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs index 4094ceeb22..a9f3f02856 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ObjectExtensions.cs @@ -6,8 +6,46 @@ namespace Godot public partial class Object { /// - /// Returns whether is a valid object - /// (e.g. has not been deleted from memory). + /// Returns the that corresponds to . + /// All Objects have a unique instance ID. See also . + /// + /// + /// + /// 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 + /// } + /// } + /// + /// + /// Instance ID of the Object to retrieve. + /// The instance. + public static Object InstanceFromId(ulong instanceId) + { + return InteropUtils.UnmanagedGetManaged(NativeFuncs.godotsharp_instance_from_id(instanceId)); + } + + /// + /// Returns if the that corresponds + /// to is a valid object (e.g. has not been deleted from + /// memory). All Objects have a unique instance ID. + /// + /// The Object ID to check. + /// If the instance with the given ID is a valid object. + public static bool IsInstanceIdValid(ulong id) + { + return IsInstanceValid(InstanceFromId(id)); + } + + /// + /// Returns if is a + /// valid (e.g. has not been deleted from memory). /// /// The instance to check. /// If the instance is a valid object. 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 { /// - /// Decodes a byte array back to a Variant value. - /// If is decoding objects is allowed. - /// - /// WARNING: Deserialized object can contain code which gets executed. - /// Do not set to - /// if the serialized object comes from untrusted sources to avoid - /// potential security threats (remote code execution). + /// Decodes a byte array back to a value, without decoding objects. + /// Note: If you need object deserialization, see . /// - /// Byte array that will be decoded to a Variant. - /// If objects should be decoded. - /// The decoded Variant. - public static Variant BytesToVar(Span bytes, bool allowObjects = false) + /// Byte array that will be decoded to a . + /// The decoded . + public static Variant BytesToVar(Span bytes) + { + using var varBytes = Marshaling.ConvertSystemArrayToNativePackedByteArray(bytes); + NativeFuncs.godotsharp_bytes_to_var(varBytes, godot_bool.False, out godot_variant ret); + return Variant.CreateTakingOwnershipOfDisposableValue(ret); + } + + /// + /// Decodes a byte array back to a 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). + /// + /// Byte array that will be decoded to a . + /// The decoded . + public static Variant BytesToVarWithObjects(Span 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); } /// - /// Converts from a Variant type to another in the best way possible. + /// Converts to in the best way possible. /// The parameter uses the values. /// /// /// - /// 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 /// /// /// The Variant converted to the given . @@ -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"); - } - /// - /// Returns the integer hash of the variable passed. + /// Returns the integer hash of the passed . /// /// /// @@ -74,32 +74,6 @@ namespace Godot return NativeFuncs.godotsharp_hash((godot_variant)var.NativeVar); } - /// - /// Returns the that corresponds to . - /// All Objects have a unique instance ID. - /// - /// - /// - /// 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 - /// } - /// } - /// - /// - /// Instance ID of the Object to retrieve. - /// The instance. - public static Object InstanceFromId(ulong instanceId) - { - return InteropUtils.UnmanagedGetManaged(NativeFuncs.godotsharp_instance_from_id(instanceId)); - } - /// /// Loads a resource from the filesystem located at . /// The resource is loaded on the method call (unless it's referenced already @@ -154,57 +128,96 @@ namespace Godot return ResourceLoader.Load(path); } - /// - /// 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. - /// - /// - /// - /// GD.PushError("test_error"); // Prints "test error" to debugger and terminal as error call - /// - /// - /// Error message. - 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(); } /// - /// Pushes a warning message to Godot's built-in debugger and to the OS terminal. + /// Prints a message to the console. + /// + /// Note: Consider using and + /// to print error and warning messages instead of . + /// This distinguishes them from print messages used for debugging purposes, + /// while also displaying a stack trace when an error or warning is printed. /// - /// - /// GD.PushWarning("test warning"); // Prints "test warning" to debugger and terminal as warning call - /// - /// Warning message. - public static void PushWarning(string message) + /// Message that will be printed. + 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); } /// /// Converts one or more arguments of any type to string in the best way possible /// and prints them to the console. /// - /// Note: Consider using and + /// Note: Consider using and /// to print error and warning messages instead of . /// This distinguishes them from print messages used for debugging purposes, /// while also displaying a stack trace when an error or warning is printed. /// /// /// - /// 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] /// /// /// Arguments that will be printed. 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)); + } + + /// + /// 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 red, 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 and + /// to print error and warning messages instead of or + /// . + /// This distinguishes them from print messages used for debugging purposes, + /// while also displaying a stack trace when an error or warning is printed. + /// + /// Message that will be printed. + public static void PrintRich(string what) + { + using var godotStr = Marshaling.ConvertStringToNative(what); + NativeFuncs.godotsharp_print_rich(godotStr); } /// @@ -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 and + /// Note: Consider using and /// to print error and warning messages instead of or /// . /// This distinguishes them from print messages used for debugging purposes, @@ -227,23 +240,23 @@ namespace Godot /// /// /// - /// 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] /// /// /// Arguments that will be printed. 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)); } /// - /// Prints the current stack trace information to the console. + /// Prints a message to standard error line. /// - public static void PrintStack() + /// Message that will be printed. + public static void PrintErr(string what) { - Print(System.Environment.StackTrace); + using var godotStr = Marshaling.ConvertStringToNative(what); + NativeFuncs.godotsharp_printerr(godotStr); } /// @@ -257,31 +270,36 @@ namespace Godot /// Arguments that will be printed. 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)); } /// - /// 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 . + /// Prints a message to the OS terminal. + /// Unlike , no newline is added at the end. + /// + /// Message that will be printed. + public static void PrintRaw(string what) + { + using var godotStr = Marshaling.ConvertStringToNative(what); + NativeFuncs.godotsharp_printraw(godotStr); + } + + /// + /// Prints one or more arguments to strings in the best way possible to the OS terminal. + /// Unlike , no newline is added at the end. /// /// /// /// GD.PrintRaw("A"); /// GD.PrintRaw("B"); - /// // Prints AB + /// GD.PrintRaw("C"); + /// // Prints ABC to terminal /// /// /// Arguments that will be printed. 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)); } /// @@ -295,8 +313,8 @@ namespace Godot /// Arguments that will be printed. 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,11 +329,73 @@ namespace Godot /// Arguments that will be printed. 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); } + /// + /// 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. + /// + /// + /// + /// GD.PushError("test error"); // Prints "test error" to debugger and terminal as error call + /// + /// + /// Error message. + public static void PushError(string message) + { + using var godotStr = Marshaling.ConvertStringToNative(message); + NativeFuncs.godotsharp_pusherror(godotStr); + } + + /// + /// 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. + /// + /// + /// + /// GD.PushError("test_error"); // Prints "test error" to debugger and terminal as error call + /// + /// + /// Arguments that form the error message. + public static void PushError(params object[] what) + { + PushError(AppendPrintParams(what)); + } + + /// + /// Pushes a warning message to Godot's built-in debugger and to the OS terminal. + /// + /// + /// + /// GD.PushWarning("test warning"); // Prints "test warning" to debugger and terminal as warning call + /// + /// + /// Warning message. + public static void PushWarning(string message) + { + using var godotStr = Marshaling.ConvertStringToNative(message); + NativeFuncs.godotsharp_pushwarning(godotStr); + } + + /// + /// Pushes a warning message to Godot's built-in debugger and to the OS terminal. + /// + /// + /// + /// GD.PushWarning("test warning"); // Prints "test warning" to debugger and terminal as warning call + /// + /// + /// Arguments that form the warning message. + public static void PushWarning(params object[] what) + { + PushWarning(AppendPrintParams(what)); + } + /// /// Returns a random floating point value between 0.0 and 1.0 (inclusive). /// @@ -331,7 +411,9 @@ namespace Godot } /// - /// Returns a normally-distributed pseudo-random number, using Box-Muller transform with the specified mean and a standard deviation. + /// Returns a normally-distributed pseudo-random floating point value + /// using Box-Muller transform with the specified + /// and a standard . /// This is also called Gaussian distribution. /// /// A random normally-distributed number. @@ -342,7 +424,8 @@ namespace Godot /// /// Returns a random unsigned 32-bit integer. - /// Use remainder to obtain a random value in the interval [0, N - 1] (where N is smaller than 2^32). + /// Use remainder to obtain a random value in the interval [0, N - 1] + /// (where N is smaller than 2^32). /// /// /// @@ -360,11 +443,11 @@ namespace Godot /// /// 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 - /// to initialize the random number generator. + /// If you need to fix the seed to have consistent, reproducible results, + /// use to initialize the random number generator. /// public static void Randomize() { @@ -372,12 +455,13 @@ namespace Godot } /// - /// Returns a random floating point value on the interval between + /// Returns a random floating point value between /// and (inclusive). /// /// /// - /// 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 /// /// /// A random number inside the given range. @@ -393,8 +477,8 @@ namespace Godot /// /// /// - /// 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 /// /// /// A random number inside the given range. @@ -404,8 +488,18 @@ namespace Godot } /// - /// Returns a random unsigned 32-bit integer, using the given . + /// Given a , returns a randomized + /// value. The may be modified. + /// Passing the same 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. /// + /// + /// + /// var a = GD.RandFromSeed(4); + /// + /// /// /// 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 /// /// Returns a that iterates from - /// 0 to in steps of 1. + /// 0 (inclusive) to (exclusive) + /// in steps of 1. /// /// The last index. public static IEnumerable Range(int end) @@ -428,7 +523,8 @@ namespace Godot /// /// Returns a that iterates from - /// to in steps of 1. + /// (inclusive) to (exclusive) + /// in steps of 1. /// /// The first index. /// The last index. @@ -439,13 +535,21 @@ namespace Godot /// /// Returns a that iterates from - /// to in steps of . + /// (inclusive) to (exclusive) + /// in steps of . + /// The argument can be negative, but not 0. /// + /// + /// is 0. + /// /// The first index. /// The last index. /// The amount by which to increment the index on each iteration. public static IEnumerable 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 } /// - /// Sets seed for the random number generator. + /// Sets seed for the random number generator to . + /// Setting the seed manually can ensure consistent, repeatable results for + /// most random functions. /// + /// + /// + /// 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 + /// + /// /// Seed that will be used. public static void Seed(ulong seed) { @@ -474,26 +590,14 @@ namespace Godot } /// - /// Converts one or more arguments of any type to string in the best way possible. - /// - /// Arguments that will converted to string. - /// The string formed by the given arguments. - 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); - } - - /// - /// Converts a formatted string that was returned by to the original value. + /// Converts a formatted string that was returned by + /// to the original value. /// /// /// - /// 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 /// /// /// String that will be converted to Variant. @@ -506,38 +610,49 @@ namespace Godot } /// - /// Encodes a Variant value to a byte array. - /// If is encoding objects is allowed - /// (and can potentially include code). - /// Deserialization can be done with . + /// Encodes a value to a byte array, without encoding objects. + /// Deserialization can be done with . + /// Note: If you need object serialization, see . + /// + /// that will be encoded. + /// The encoded as an array of bytes. + 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); + } + + /// + /// Encodes a . Encoding objects is allowed (and can potentially + /// include executable code). Deserialization can be done with . /// - /// Variant that will be encoded. - /// If objects should be serialized. - /// The Variant encoded as an array of bytes. - public static byte[] VarToBytes(Variant var, bool fullObjects = false) + /// that will be encoded. + /// The encoded as an array of bytes. + 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); } /// - /// Converts a Variant to a formatted string that + /// Converts a to a formatted string that /// can later be parsed using . /// /// /// /// 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 /// // } /// /// /// Variant that will be converted to string. - /// The Variant encoded as a string. + /// The encoded as a string. 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/NativeInterop/Marshaling.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs index 0d9a698af0..11e600ca0b 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs @@ -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 = Godot.Object.InstanceFromId(p_signal.ObjectId); var name = StringName.CreateTakingOwnershipOfDisposableValue( NativeFuncs.godotsharp_string_name_new_copy(p_signal.Name)); return new Signal(owner, name); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs index 57488bd586..3807806080 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs @@ -494,8 +494,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/runtime_interop.cpp b/modules/mono/glue/runtime_interop.cpp index f0ea0313ea..7ac65e5d31 100644 --- a/modules/mono/glue/runtime_interop.cpp +++ b/modules/mono/glue/runtime_interop.cpp @@ -1180,21 +1180,6 @@ void godotsharp_weakref(Object *p_ptr, Ref *r_weak_ref) { memnew_placement(r_weak_ref, Ref(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(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(p_what)); } @@ -1488,7 +1473,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, -- cgit v1.2.3