/// <summary> /// Calls the method represented by this <see cref="Callable"/>. /// Arguments can be passed and should match the method's signature. /// </summary> /// <param name="args">Arguments that will be passed to the method call.</param> /// <returns>The value returned by the method.</returns> public unsafe Variant Call(params Variant[] args) { using godot_callable callable = Marshaling.ConvertCallableToNative(this); int argc = args.Length; Span <godot_variant.movable> argsStoreSpan = argc <= VarArgsSpanThreshold ? stackalloc godot_variant.movable[VarArgsSpanThreshold].Cleared() : new godot_variant.movable[argc]; Span <IntPtr> argsSpan = argc <= 10 ? stackalloc IntPtr[argc] : new IntPtr[argc]; using var variantSpanDisposer = new VariantSpanDisposer(argsStoreSpan); fixed(godot_variant *varargs = &MemoryMarshal.GetReference(argsStoreSpan).DangerousSelfRef) fixed(IntPtr * argsPtr = &MemoryMarshal.GetReference(argsSpan)) { for (int i = 0; i < argc; i++) { varargs[i] = (godot_variant)args[i].NativeVar; argsPtr[i] = new IntPtr(&varargs[i]); } godot_variant ret = NativeFuncs.godotsharp_callable_call(callable, (godot_variant **)argsPtr, argc, out _); return(Variant.CreateTakingOwnershipOfDisposableValue(ret)); } }
/// <summary> /// Converts from a <c>Variant</c> type to another 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); /// </code> /// </example> /// <returns>The <c>Variant</c> converted to the given <paramref name="type"/>.</returns> public static Variant Convert(Variant what, Variant.Type type) { NativeFuncs.godotsharp_convert((godot_variant)what.NativeVar, (int)type, out godot_variant ret); return(Variant.CreateTakingOwnershipOfDisposableValue(ret)); }
/// <summary> /// 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 /// </code> /// </example> /// <param name="str">String that will be converted to Variant.</param> /// <returns>The decoded <c>Variant</c>.</returns> public static Variant StrToVar(string str) { using var godotStr = Marshaling.ConvertStringToNative(str); NativeFuncs.godotsharp_str_to_var(godotStr, out godot_variant ret); return(Variant.CreateTakingOwnershipOfDisposableValue(ret)); }
/// <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). /// </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) { using var varBytes = Marshaling.ConvertSystemArrayToNativePackedByteArray(bytes); NativeFuncs.godotsharp_bytes_to_var(varBytes, allowObjects.ToGodotBool(), out godot_variant ret); return(Variant.CreateTakingOwnershipOfDisposableValue(ret)); }