C#: Re-write GD and some other icalls as P/Invoke
This commit is contained in:
parent
9a51430441
commit
5e37d073bb
19 changed files with 442 additions and 635 deletions
|
@ -109,7 +109,7 @@ Error CSharpLanguage::execute_file(const String &p_path) {
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void *godotsharp_pinvoke_funcs[138];
|
extern void *godotsharp_pinvoke_funcs[164];
|
||||||
[[maybe_unused]] volatile void **do_not_strip_godotsharp_pinvoke_funcs;
|
[[maybe_unused]] volatile void **do_not_strip_godotsharp_pinvoke_funcs;
|
||||||
|
|
||||||
void CSharpLanguage::init() {
|
void CSharpLanguage::init() {
|
||||||
|
@ -705,19 +705,14 @@ void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) {
|
||||||
|
|
||||||
void CSharpLanguage::frame() {
|
void CSharpLanguage::frame() {
|
||||||
if (gdmono && gdmono->is_runtime_initialized() && gdmono->get_core_api_assembly() != nullptr) {
|
if (gdmono && gdmono->is_runtime_initialized() && gdmono->get_core_api_assembly() != nullptr) {
|
||||||
const Ref<MonoGCHandleRef> &task_scheduler_handle = GDMonoCache::cached_data.task_scheduler_handle;
|
MonoException *exc = nullptr;
|
||||||
|
gdmono->get_core_api_assembly()
|
||||||
|
->get_class("Godot", "ScriptManager")
|
||||||
|
->get_method("FrameCallback")
|
||||||
|
->invoke(nullptr, &exc);
|
||||||
|
|
||||||
if (task_scheduler_handle.is_valid()) {
|
if (exc) {
|
||||||
MonoObject *task_scheduler = task_scheduler_handle->get_target();
|
GDMonoUtils::debug_unhandled_exception(exc);
|
||||||
|
|
||||||
if (task_scheduler) {
|
|
||||||
MonoException *exc = nullptr;
|
|
||||||
CACHED_METHOD_THUNK(GodotTaskScheduler, Activate).invoke(task_scheduler, &exc);
|
|
||||||
|
|
||||||
if (exc) {
|
|
||||||
GDMonoUtils::debug_unhandled_exception(exc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace Godot
|
namespace Godot
|
||||||
{
|
{
|
||||||
public static class Dispatcher
|
public static class Dispatcher
|
||||||
{
|
{
|
||||||
/// <summary>
|
internal static GodotTaskScheduler DefaultGodotTaskScheduler;
|
||||||
/// Implements an external instance of GodotTaskScheduler.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>A GodotTaskScheduler instance.</returns>
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
private static extern GodotTaskScheduler godot_icall_DefaultGodotTaskScheduler();
|
|
||||||
|
|
||||||
/// <summary>
|
private static void InitializeDefaultGodotTaskScheduler()
|
||||||
/// Initializes the synchronization context as the context of the GodotTaskScheduler.
|
{
|
||||||
/// </summary>
|
DefaultGodotTaskScheduler = new GodotTaskScheduler();
|
||||||
public static GodotSynchronizationContext SynchronizationContext =>
|
}
|
||||||
godot_icall_DefaultGodotTaskScheduler().Context;
|
|
||||||
|
public static GodotSynchronizationContext SynchronizationContext => DefaultGodotTaskScheduler.Context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using Godot.NativeInterop;
|
||||||
|
|
||||||
namespace Godot
|
namespace Godot
|
||||||
{
|
{
|
||||||
|
@ -32,10 +32,20 @@ namespace Godot
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public static WeakRef WeakRef(Object obj)
|
public static WeakRef WeakRef(Object obj)
|
||||||
{
|
{
|
||||||
return godot_icall_Object_weakref(GetPtr(obj));
|
if (!IsInstanceValid(obj))
|
||||||
}
|
return null;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
using godot_ref weakRef = default;
|
||||||
internal static extern WeakRef godot_icall_Object_weakref(IntPtr obj);
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
NativeFuncs.godotsharp_weakref(GetPtr(obj), &weakRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weakRef.IsNull)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return (WeakRef)InteropUtils.UnmanagedGetManaged(weakRef._reference);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ using real_t = System.Single;
|
||||||
#endif
|
#endif
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using Godot.NativeInterop;
|
using Godot.NativeInterop;
|
||||||
|
|
||||||
namespace Godot
|
namespace Godot
|
||||||
|
@ -30,7 +29,9 @@ namespace Godot
|
||||||
public static unsafe object Bytes2Var(byte[] bytes, bool allowObjects = false)
|
public static unsafe object Bytes2Var(byte[] bytes, bool allowObjects = false)
|
||||||
{
|
{
|
||||||
using var varBytes = Marshaling.mono_array_to_PackedByteArray(bytes);
|
using var varBytes = Marshaling.mono_array_to_PackedByteArray(bytes);
|
||||||
return godot_icall_GD_bytes2var(&varBytes, allowObjects);
|
using godot_variant ret = default;
|
||||||
|
NativeFuncs.godotsharp_bytes2var(&varBytes, allowObjects, &ret);
|
||||||
|
return Marshaling.variant_to_mono_object(&ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -48,9 +49,12 @@ namespace Godot
|
||||||
/// </code>
|
/// </code>
|
||||||
/// </example>
|
/// </example>
|
||||||
/// <returns>The <c>Variant</c> converted to the given <paramref name="type"/>.</returns>
|
/// <returns>The <c>Variant</c> converted to the given <paramref name="type"/>.</returns>
|
||||||
public static object Convert(object what, Variant.Type type)
|
public static unsafe object Convert(object what, Variant.Type type)
|
||||||
{
|
{
|
||||||
return godot_icall_GD_convert(what, type);
|
using var whatVariant = Marshaling.mono_object_to_variant(what);
|
||||||
|
using godot_variant ret = default;
|
||||||
|
NativeFuncs.godotsharp_convert(&whatVariant, (int)type, &ret);
|
||||||
|
return Marshaling.variant_to_mono_object(&ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -64,7 +68,7 @@ namespace Godot
|
||||||
return (real_t)Math.Exp(db * 0.11512925464970228420089957273422);
|
return (real_t)Math.Exp(db * 0.11512925464970228420089957273422);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static object[] GetPrintParams(object[] parameters)
|
private static string[] GetPrintParams(object[] parameters)
|
||||||
{
|
{
|
||||||
if (parameters == null)
|
if (parameters == null)
|
||||||
{
|
{
|
||||||
|
@ -84,9 +88,10 @@ namespace Godot
|
||||||
/// </example>
|
/// </example>
|
||||||
/// <param name="var">Variable that will be hashed.</param>
|
/// <param name="var">Variable that will be hashed.</param>
|
||||||
/// <returns>Hash of the variable passed.</returns>
|
/// <returns>Hash of the variable passed.</returns>
|
||||||
public static int Hash(object var)
|
public static unsafe int Hash(object var)
|
||||||
{
|
{
|
||||||
return godot_icall_GD_hash(var);
|
using var variant = Marshaling.mono_object_to_variant(var);
|
||||||
|
return NativeFuncs.godotsharp_hash(&variant);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -112,7 +117,7 @@ namespace Godot
|
||||||
/// <returns>The <see cref="Object"/> instance.</returns>
|
/// <returns>The <see cref="Object"/> instance.</returns>
|
||||||
public static Object InstanceFromId(ulong instanceId)
|
public static Object InstanceFromId(ulong instanceId)
|
||||||
{
|
{
|
||||||
return godot_icall_GD_instance_from_id(instanceId);
|
return InteropUtils.UnmanagedGetManaged(NativeFuncs.godotsharp_instance_from_id(instanceId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -202,9 +207,10 @@ namespace Godot
|
||||||
/// </code>
|
/// </code>
|
||||||
/// </example>
|
/// </example>
|
||||||
/// <param name="message">Error message.</param>
|
/// <param name="message">Error message.</param>
|
||||||
public static void PushError(string message)
|
public static unsafe void PushError(string message)
|
||||||
{
|
{
|
||||||
godot_icall_GD_pusherror(message);
|
using var godotStr = Marshaling.mono_string_to_godot(message);
|
||||||
|
NativeFuncs.godotsharp_pusherror(&godotStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -214,9 +220,10 @@ namespace Godot
|
||||||
/// GD.PushWarning("test warning"); // Prints "test warning" to debugger and terminal as warning call
|
/// GD.PushWarning("test warning"); // Prints "test warning" to debugger and terminal as warning call
|
||||||
/// </example>
|
/// </example>
|
||||||
/// <param name="message">Warning message.</param>
|
/// <param name="message">Warning message.</param>
|
||||||
public static void PushWarning(string message)
|
public static unsafe void PushWarning(string message)
|
||||||
{
|
{
|
||||||
godot_icall_GD_pushwarning(message);
|
using var godotStr = Marshaling.mono_string_to_godot(message);
|
||||||
|
NativeFuncs.godotsharp_pushwarning(&godotStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -235,9 +242,11 @@ namespace Godot
|
||||||
/// </code>
|
/// </code>
|
||||||
/// </example>
|
/// </example>
|
||||||
/// <param name="what">Arguments that will be printed.</param>
|
/// <param name="what">Arguments that will be printed.</param>
|
||||||
public static void Print(params object[] what)
|
public static unsafe void Print(params object[] what)
|
||||||
{
|
{
|
||||||
godot_icall_GD_print(GetPrintParams(what));
|
string str = string.Concat(GetPrintParams(what));
|
||||||
|
using var godotStr = Marshaling.mono_string_to_godot(str);
|
||||||
|
NativeFuncs.godotsharp_print(&godotStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -264,9 +273,11 @@ namespace Godot
|
||||||
/// </code>
|
/// </code>
|
||||||
/// </example>
|
/// </example>
|
||||||
/// <param name="what">Arguments that will be printed.</param>
|
/// <param name="what">Arguments that will be printed.</param>
|
||||||
public static void PrintRich(params object[] what)
|
public static unsafe void PrintRich(params object[] what)
|
||||||
{
|
{
|
||||||
godot_icall_GD_print_rich(GetPrintParams(what));
|
string str = string.Concat(GetPrintParams(what));
|
||||||
|
using var godotStr = Marshaling.mono_string_to_godot(str);
|
||||||
|
NativeFuncs.godotsharp_print_rich(&godotStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -286,9 +297,11 @@ namespace Godot
|
||||||
/// </code>
|
/// </code>
|
||||||
/// </example>
|
/// </example>
|
||||||
/// <param name="what">Arguments that will be printed.</param>
|
/// <param name="what">Arguments that will be printed.</param>
|
||||||
public static void PrintErr(params object[] what)
|
public static unsafe void PrintErr(params object[] what)
|
||||||
{
|
{
|
||||||
godot_icall_GD_printerr(GetPrintParams(what));
|
string str = string.Concat(GetPrintParams(what));
|
||||||
|
using var godotStr = Marshaling.mono_string_to_godot(str);
|
||||||
|
NativeFuncs.godotsharp_printerr(&godotStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -306,9 +319,11 @@ namespace Godot
|
||||||
/// </code>
|
/// </code>
|
||||||
/// </example>
|
/// </example>
|
||||||
/// <param name="what">Arguments that will be printed.</param>
|
/// <param name="what">Arguments that will be printed.</param>
|
||||||
public static void PrintRaw(params object[] what)
|
public static unsafe void PrintRaw(params object[] what)
|
||||||
{
|
{
|
||||||
godot_icall_GD_printraw(GetPrintParams(what));
|
string str = string.Concat(GetPrintParams(what));
|
||||||
|
using var godotStr = Marshaling.mono_string_to_godot(str);
|
||||||
|
NativeFuncs.godotsharp_printraw(&godotStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -320,9 +335,11 @@ namespace Godot
|
||||||
/// </code>
|
/// </code>
|
||||||
/// </example>
|
/// </example>
|
||||||
/// <param name="what">Arguments that will be printed.</param>
|
/// <param name="what">Arguments that will be printed.</param>
|
||||||
public static void PrintS(params object[] what)
|
public static unsafe void PrintS(params object[] what)
|
||||||
{
|
{
|
||||||
godot_icall_GD_prints(GetPrintParams(what));
|
string str = string.Join(' ', GetPrintParams(what));
|
||||||
|
using var godotStr = Marshaling.mono_string_to_godot(str);
|
||||||
|
NativeFuncs.godotsharp_prints(&godotStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -334,9 +351,11 @@ namespace Godot
|
||||||
/// </code>
|
/// </code>
|
||||||
/// </example>
|
/// </example>
|
||||||
/// <param name="what">Arguments that will be printed.</param>
|
/// <param name="what">Arguments that will be printed.</param>
|
||||||
public static void PrintT(params object[] what)
|
public static unsafe void PrintT(params object[] what)
|
||||||
{
|
{
|
||||||
godot_icall_GD_printt(GetPrintParams(what));
|
string str = string.Join('\t', GetPrintParams(what));
|
||||||
|
using var godotStr = Marshaling.mono_string_to_godot(str);
|
||||||
|
NativeFuncs.godotsharp_printt(&godotStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -350,7 +369,7 @@ namespace Godot
|
||||||
/// <returns>A random <see langword="float"/> number.</returns>
|
/// <returns>A random <see langword="float"/> number.</returns>
|
||||||
public static float Randf()
|
public static float Randf()
|
||||||
{
|
{
|
||||||
return godot_icall_GD_randf();
|
return NativeFuncs.godotsharp_randf();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -360,7 +379,7 @@ namespace Godot
|
||||||
/// <returns>A random normally-distributed <see langword="float"/> number.</returns>
|
/// <returns>A random normally-distributed <see langword="float"/> number.</returns>
|
||||||
public static double Randfn(double mean, double deviation)
|
public static double Randfn(double mean, double deviation)
|
||||||
{
|
{
|
||||||
return godot_icall_GD_randfn(mean, deviation);
|
return NativeFuncs.godotsharp_randfn(mean, deviation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -378,7 +397,7 @@ namespace Godot
|
||||||
/// <returns>A random <see langword="uint"/> number.</returns>
|
/// <returns>A random <see langword="uint"/> number.</returns>
|
||||||
public static uint Randi()
|
public static uint Randi()
|
||||||
{
|
{
|
||||||
return godot_icall_GD_randi();
|
return NativeFuncs.godotsharp_randi();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -391,7 +410,7 @@ namespace Godot
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void Randomize()
|
public static void Randomize()
|
||||||
{
|
{
|
||||||
godot_icall_GD_randomize();
|
NativeFuncs.godotsharp_randomize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -406,7 +425,7 @@ namespace Godot
|
||||||
/// <returns>A random <see langword="double"/> number inside the given range.</returns>
|
/// <returns>A random <see langword="double"/> number inside the given range.</returns>
|
||||||
public static double RandRange(double from, double to)
|
public static double RandRange(double from, double to)
|
||||||
{
|
{
|
||||||
return godot_icall_GD_randf_range(from, to);
|
return NativeFuncs.godotsharp_randf_range(from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -423,7 +442,7 @@ namespace Godot
|
||||||
/// <returns>A random <see langword="int"/> number inside the given range.</returns>
|
/// <returns>A random <see langword="int"/> number inside the given range.</returns>
|
||||||
public static int RandRange(int from, int to)
|
public static int RandRange(int from, int to)
|
||||||
{
|
{
|
||||||
return godot_icall_GD_randi_range(from, to);
|
return NativeFuncs.godotsharp_randi_range(from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -436,7 +455,7 @@ namespace Godot
|
||||||
/// <returns>A random <see langword="uint"/> number.</returns>
|
/// <returns>A random <see langword="uint"/> number.</returns>
|
||||||
public static uint RandFromSeed(ref ulong seed)
|
public static uint RandFromSeed(ref ulong seed)
|
||||||
{
|
{
|
||||||
return godot_icall_GD_rand_seed(seed, out seed);
|
return NativeFuncs.godotsharp_rand_from_seed(seed, out seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -493,7 +512,7 @@ namespace Godot
|
||||||
/// <param name="seed">Seed that will be used.</param>
|
/// <param name="seed">Seed that will be used.</param>
|
||||||
public static void Seed(ulong seed)
|
public static void Seed(ulong seed)
|
||||||
{
|
{
|
||||||
godot_icall_GD_seed(seed);
|
NativeFuncs.godotsharp_seed(seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -501,9 +520,12 @@ namespace Godot
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="what">Arguments that will converted to string.</param>
|
/// <param name="what">Arguments that will converted to string.</param>
|
||||||
/// <returns>The string formed by the given arguments.</returns>
|
/// <returns>The string formed by the given arguments.</returns>
|
||||||
public static string Str(params object[] what)
|
public static unsafe string Str(params object[] what)
|
||||||
{
|
{
|
||||||
return godot_icall_GD_str(what);
|
using var whatGodotArray = Marshaling.mono_array_to_Array(what);
|
||||||
|
using godot_string ret = default;
|
||||||
|
NativeFuncs.godotsharp_str(&whatGodotArray, &ret);
|
||||||
|
return Marshaling.mono_string_from_godot(&ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -518,18 +540,12 @@ namespace Godot
|
||||||
/// </example>
|
/// </example>
|
||||||
/// <param name="str">String that will be converted to Variant.</param>
|
/// <param name="str">String that will be converted to Variant.</param>
|
||||||
/// <returns>The decoded <c>Variant</c>.</returns>
|
/// <returns>The decoded <c>Variant</c>.</returns>
|
||||||
public static object Str2Var(string str)
|
public static unsafe object Str2Var(string str)
|
||||||
{
|
{
|
||||||
return godot_icall_GD_str2var(str);
|
using var godotStr = Marshaling.mono_string_to_godot(str);
|
||||||
}
|
using godot_variant ret = default;
|
||||||
|
NativeFuncs.godotsharp_str2var(&godotStr, &ret);
|
||||||
/// <summary>
|
return Marshaling.variant_to_mono_object(&ret);
|
||||||
/// Returns whether the given class exists in <see cref="ClassDB"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>If the class exists in <see cref="ClassDB"/>.</returns>
|
|
||||||
public static bool TypeExists(StringName type)
|
|
||||||
{
|
|
||||||
return godot_icall_GD_type_exists(ref type.NativeValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -543,12 +559,11 @@ namespace Godot
|
||||||
/// <returns>The <c>Variant</c> encoded as an array of bytes.</returns>
|
/// <returns>The <c>Variant</c> encoded as an array of bytes.</returns>
|
||||||
public static unsafe byte[] Var2Bytes(object var, bool fullObjects = false)
|
public static unsafe byte[] Var2Bytes(object var, bool fullObjects = false)
|
||||||
{
|
{
|
||||||
godot_packed_byte_array varBytes;
|
using var variant = Marshaling.mono_object_to_variant(var);
|
||||||
godot_icall_GD_var2bytes(var, fullObjects, &varBytes);
|
using godot_packed_byte_array varBytes = default;
|
||||||
|
NativeFuncs.godotsharp_var2bytes(&variant, fullObjects, &varBytes);
|
||||||
using (varBytes)
|
using (varBytes)
|
||||||
{
|
|
||||||
return Marshaling.PackedByteArray_to_mono_array(&varBytes);
|
return Marshaling.PackedByteArray_to_mono_array(&varBytes);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -568,9 +583,12 @@ namespace Godot
|
||||||
/// </example>
|
/// </example>
|
||||||
/// <param name="var">Variant that will be converted to string.</param>
|
/// <param name="var">Variant that will be converted to string.</param>
|
||||||
/// <returns>The <c>Variant</c> encoded as a string.</returns>
|
/// <returns>The <c>Variant</c> encoded as a string.</returns>
|
||||||
public static string Var2Str(object var)
|
public static unsafe string Var2Str(object var)
|
||||||
{
|
{
|
||||||
return godot_icall_GD_var2str(var);
|
using var variant = Marshaling.mono_object_to_variant(var);
|
||||||
|
using godot_string ret = default;
|
||||||
|
NativeFuncs.godotsharp_var2str(&variant, &ret);
|
||||||
|
return Marshaling.mono_string_from_godot(&ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -579,85 +597,7 @@ namespace Godot
|
||||||
/// <returns>The <see cref="Variant.Type"/> for the given <paramref name="type"/>.</returns>
|
/// <returns>The <see cref="Variant.Type"/> for the given <paramref name="type"/>.</returns>
|
||||||
public static Variant.Type TypeToVariantType(Type type)
|
public static Variant.Type TypeToVariantType(Type type)
|
||||||
{
|
{
|
||||||
return godot_icall_TypeToVariantType(type);
|
return Marshaling.managed_to_variant_type(type, out bool _);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern unsafe object godot_icall_GD_bytes2var(godot_packed_byte_array* bytes, bool allowObjects);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern object godot_icall_GD_convert(object what, Variant.Type type);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern int godot_icall_GD_hash(object var);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern Object godot_icall_GD_instance_from_id(ulong instanceId);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern void godot_icall_GD_print(object[] what);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern void godot_icall_GD_print_rich(object[] what);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern void godot_icall_GD_printerr(object[] what);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern void godot_icall_GD_printraw(object[] what);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern void godot_icall_GD_prints(object[] what);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern void godot_icall_GD_printt(object[] what);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern void godot_icall_GD_randomize();
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern uint godot_icall_GD_randi();
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern float godot_icall_GD_randf();
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern int godot_icall_GD_randi_range(int from, int to);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern double godot_icall_GD_randf_range(double from, double to);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern double godot_icall_GD_randfn(double mean, double deviation);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern uint godot_icall_GD_rand_seed(ulong seed, out ulong newSeed);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern void godot_icall_GD_seed(ulong seed);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern string godot_icall_GD_str(object[] what);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern object godot_icall_GD_str2var(string str);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern bool godot_icall_GD_type_exists(ref godot_string_name type);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern unsafe void godot_icall_GD_var2bytes(object what, bool fullObjects, godot_packed_byte_array* bytes);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern string godot_icall_GD_var2str(object var);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern void godot_icall_GD_pusherror(string type);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern void godot_icall_GD_pushwarning(string type);
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
private static extern Variant.Type godot_icall_TypeToVariantType(Type type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,8 @@ namespace Godot.NativeInterop
|
||||||
NativeFuncs.godotsharp_ref_destroy(ref this);
|
NativeFuncs.godotsharp_ref_destroy(ref this);
|
||||||
_reference = IntPtr.Zero;
|
_reference = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsNull => _reference == IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
|
|
|
@ -18,8 +18,10 @@ namespace Godot.NativeInterop
|
||||||
fieldInfo.SetValue(obj, valueObj);
|
fieldInfo.SetValue(obj, valueObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Variant.Type managed_to_variant_type(Type type, ref bool r_nil_is_variant)
|
public static Variant.Type managed_to_variant_type(Type type, out bool r_nil_is_variant)
|
||||||
{
|
{
|
||||||
|
r_nil_is_variant = false;
|
||||||
|
|
||||||
switch (Type.GetTypeCode(type))
|
switch (Type.GetTypeCode(type))
|
||||||
{
|
{
|
||||||
case TypeCode.Boolean:
|
case TypeCode.Boolean:
|
||||||
|
@ -199,8 +201,6 @@ namespace Godot.NativeInterop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r_nil_is_variant = false;
|
|
||||||
|
|
||||||
// Unknown
|
// Unknown
|
||||||
return Variant.Type.Nil;
|
return Variant.Type.Nil;
|
||||||
}
|
}
|
||||||
|
@ -711,7 +711,7 @@ namespace Godot.NativeInterop
|
||||||
if (typeof(Godot.Object[]).IsAssignableFrom(type))
|
if (typeof(Godot.Object[]).IsAssignableFrom(type))
|
||||||
{
|
{
|
||||||
using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var);
|
using var godotArray = NativeFuncs.godotsharp_variant_as_array(p_var);
|
||||||
return Array_to_mono_array_of_type(&godotArray, type);
|
return Array_to_mono_array_of_godot_object_type(&godotArray, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == typeof(object[]))
|
if (type == typeof(object[]))
|
||||||
|
@ -1136,7 +1136,7 @@ namespace Godot.NativeInterop
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe object Array_to_mono_array_of_type(godot_array* p_array, Type type)
|
public static unsafe object Array_to_mono_array_of_godot_object_type(godot_array* p_array, Type type)
|
||||||
{
|
{
|
||||||
var array = Collections.Array.CreateTakingOwnershipOfDisposableValue(
|
var array = Collections.Array.CreateTakingOwnershipOfDisposableValue(
|
||||||
NativeFuncs.godotsharp_array_new_copy(p_array));
|
NativeFuncs.godotsharp_array_new_copy(p_array));
|
||||||
|
@ -1144,7 +1144,9 @@ namespace Godot.NativeInterop
|
||||||
int length = array.Count;
|
int length = array.Count;
|
||||||
object ret = Activator.CreateInstance(type, length);
|
object ret = Activator.CreateInstance(type, length);
|
||||||
|
|
||||||
array.CopyTo((object[])ret, 0); // variant_to_mono_object handled by Collections.Array
|
// variant_to_mono_object handled by Collections.Array
|
||||||
|
// variant_to_mono_object_of_type is not needed because target element types are Godot.Object (or derived)
|
||||||
|
array.CopyTo((object[])ret, 0);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -510,5 +510,89 @@ namespace Godot.NativeInterop
|
||||||
|
|
||||||
[DllImport(GodotDllName)]
|
[DllImport(GodotDllName)]
|
||||||
public static extern bool godotsharp_node_path_is_absolute(ref godot_node_path p_self);
|
public static extern bool godotsharp_node_path_is_absolute(ref godot_node_path p_self);
|
||||||
|
|
||||||
|
// GD, etc
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_bytes2var(godot_packed_byte_array* p_bytes, bool p_allow_objects,
|
||||||
|
godot_variant* r_ret);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_convert(godot_variant* p_what, int p_type, godot_variant* r_ret);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern int godotsharp_hash(godot_variant* var);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern IntPtr godotsharp_instance_from_id(ulong instanceId);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_print(godot_string* p_what);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_print_rich(godot_string* p_what);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_printerr(godot_string* p_what);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_printraw(godot_string* p_what);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_prints(godot_string* p_what);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_printt(godot_string* p_what);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern float godotsharp_randf();
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern uint godotsharp_randi();
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_randomize();
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern double godotsharp_randf_range(double from, double to);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern double godotsharp_randfn(double mean, double deviation);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern int godotsharp_randi_range(int from, int to);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern uint godotsharp_rand_from_seed(ulong seed, out ulong newSeed);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_seed(ulong seed);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_weakref(IntPtr obj, godot_ref* r_weak_ref);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern string godotsharp_str(godot_array* p_what, godot_string* r_ret);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_str2var(godot_string* p_str, godot_variant* r_ret);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_var2bytes(godot_variant* what, bool fullObjects,
|
||||||
|
godot_packed_byte_array* bytes);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_var2str(godot_variant* var, godot_string* r_ret);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_pusherror(godot_string* type);
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern void godotsharp_pushwarning(godot_string* type);
|
||||||
|
|
||||||
|
// Object
|
||||||
|
|
||||||
|
[DllImport(GodotDllName)]
|
||||||
|
public static extern string godotsharp_object_to_string(IntPtr ptr, godot_string* r_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using Godot.NativeInterop;
|
||||||
|
|
||||||
namespace Godot
|
namespace Godot
|
||||||
{
|
{
|
||||||
|
@ -101,9 +102,11 @@ namespace Godot
|
||||||
/// Converts this <see cref="Object"/> to a string.
|
/// Converts this <see cref="Object"/> to a string.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A string representation of this object.</returns>
|
/// <returns>A string representation of this object.</returns>
|
||||||
public override string ToString()
|
public override unsafe string ToString()
|
||||||
{
|
{
|
||||||
return godot_icall_Object_ToString(GetPtr(this));
|
using godot_string str = default;
|
||||||
|
NativeFuncs.godotsharp_object_to_string(GetPtr(this), &str);
|
||||||
|
return Marshaling.mono_string_from_godot(&str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -190,8 +193,5 @@ namespace Godot
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
internal static extern void godot_icall_Object_ConnectEventSignals(IntPtr obj);
|
internal static extern void godot_icall_Object_ConnectEventSignals(IntPtr obj);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
||||||
internal static extern string godot_icall_Object_ToString(IntPtr ptr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
namespace Godot
|
||||||
|
{
|
||||||
|
internal class ScriptManager
|
||||||
|
{
|
||||||
|
internal static void FrameCallback()
|
||||||
|
{
|
||||||
|
Dispatcher.DefaultGodotTaskScheduler?.Activate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -71,6 +71,7 @@
|
||||||
<Compile Include="Core\NativeInterop\NativeFuncs.cs" />
|
<Compile Include="Core\NativeInterop\NativeFuncs.cs" />
|
||||||
<Compile Include="Core\NativeInterop\InteropStructs.cs" />
|
<Compile Include="Core\NativeInterop\InteropStructs.cs" />
|
||||||
<Compile Include="Core\NativeInterop\Marshaling.cs" />
|
<Compile Include="Core\NativeInterop\Marshaling.cs" />
|
||||||
|
<Compile Include="Core\ScriptManager.cs" />
|
||||||
<Compile Include="Core\SignalInfo.cs" />
|
<Compile Include="Core\SignalInfo.cs" />
|
||||||
<Compile Include="Core\SignalAwaiter.cs" />
|
<Compile Include="Core\SignalAwaiter.cs" />
|
||||||
<Compile Include="Core\StringExtensions.cs" />
|
<Compile Include="Core\StringExtensions.cs" />
|
||||||
|
|
|
@ -124,50 +124,14 @@ void godot_icall_Object_ConnectEventSignals(Object *p_ptr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoObject *godot_icall_Object_weakref(Object *p_ptr) {
|
|
||||||
if (!p_ptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref<WeakRef> wref;
|
|
||||||
RefCounted *rc = Object::cast_to<RefCounted>(p_ptr);
|
|
||||||
|
|
||||||
if (rc) {
|
|
||||||
Ref<RefCounted> r = rc;
|
|
||||||
if (!r.is_valid()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
wref.instantiate();
|
|
||||||
wref->set_ref(r);
|
|
||||||
} else {
|
|
||||||
wref.instantiate();
|
|
||||||
wref->set_obj(p_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GDMonoUtils::unmanaged_get_managed(wref.ptr());
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t godot_icall_SignalAwaiter_connect(Object *p_source, StringName *p_signal, Object *p_target, MonoObject *p_awaiter) {
|
int32_t godot_icall_SignalAwaiter_connect(Object *p_source, StringName *p_signal, Object *p_target, MonoObject *p_awaiter) {
|
||||||
StringName signal = p_signal ? *p_signal : StringName();
|
StringName signal = p_signal ? *p_signal : StringName();
|
||||||
return (int32_t)gd_mono_connect_signal_awaiter(p_source, signal, p_target, p_awaiter);
|
return (int32_t)gd_mono_connect_signal_awaiter(p_source, signal, p_target, p_awaiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
MonoString *godot_icall_Object_ToString(Object *p_ptr) {
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
// Cannot happen in C#; would get an ObjectDisposedException instead.
|
|
||||||
CRASH_COND(p_ptr == nullptr);
|
|
||||||
#endif
|
|
||||||
// Can't call 'Object::to_string()' here, as that can end up calling 'ToString' again resulting in an endless circular loop.
|
|
||||||
String result = "[" + p_ptr->get_class() + ":" + itos(p_ptr->get_instance_id()) + "]";
|
|
||||||
return GDMonoMarshal::mono_string_from_godot(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void godot_register_object_icalls() {
|
void godot_register_object_icalls() {
|
||||||
GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_Disposed", godot_icall_Object_Disposed);
|
GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_Disposed", godot_icall_Object_Disposed);
|
||||||
GDMonoUtils::add_internal_call("Godot.Object::godot_icall_RefCounted_Disposed", godot_icall_RefCounted_Disposed);
|
GDMonoUtils::add_internal_call("Godot.Object::godot_icall_RefCounted_Disposed", godot_icall_RefCounted_Disposed);
|
||||||
GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_ConnectEventSignals", godot_icall_Object_ConnectEventSignals);
|
GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_ConnectEventSignals", godot_icall_Object_ConnectEventSignals);
|
||||||
GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_ToString", godot_icall_Object_ToString);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_weakref", godot_icall_Object_weakref);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.SignalAwaiter::godot_icall_SignalAwaiter_connect", godot_icall_SignalAwaiter_connect);
|
GDMonoUtils::add_internal_call("Godot.SignalAwaiter::godot_icall_SignalAwaiter_connect", godot_icall_SignalAwaiter_connect);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,342 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* gd_glue.cpp */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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 "core/io/marshalls.h"
|
|
||||||
#include "core/os/os.h"
|
|
||||||
#include "core/string/ustring.h"
|
|
||||||
#include "core/variant/array.h"
|
|
||||||
#include "core/variant/variant.h"
|
|
||||||
#include "core/variant/variant_parser.h"
|
|
||||||
|
|
||||||
#include "../mono_gd/gd_mono_cache.h"
|
|
||||||
#include "../mono_gd/gd_mono_marshal.h"
|
|
||||||
#include "../mono_gd/gd_mono_utils.h"
|
|
||||||
|
|
||||||
MonoObject *godot_icall_GD_bytes2var(PackedByteArray *p_bytes, MonoBoolean p_allow_objects) {
|
|
||||||
Variant ret;
|
|
||||||
Error err = decode_variant(ret, p_bytes->ptr(), p_bytes->size(), nullptr, p_allow_objects);
|
|
||||||
if (err != OK) {
|
|
||||||
ret = RTR("Not enough bytes for decoding bytes, or invalid format.");
|
|
||||||
}
|
|
||||||
return GDMonoMarshal::variant_to_mono_object(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoObject *godot_icall_GD_convert(MonoObject *p_what, int32_t p_type) {
|
|
||||||
Variant what = GDMonoMarshal::mono_object_to_variant(p_what);
|
|
||||||
const Variant *args[1] = { &what };
|
|
||||||
Callable::CallError ce;
|
|
||||||
Variant ret;
|
|
||||||
Variant::construct(Variant::Type(p_type), ret, args, 1, ce);
|
|
||||||
ERR_FAIL_COND_V(ce.error != Callable::CallError::CALL_OK, nullptr);
|
|
||||||
return GDMonoMarshal::variant_to_mono_object(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
int godot_icall_GD_hash(MonoObject *p_var) {
|
|
||||||
return GDMonoMarshal::mono_object_to_variant(p_var).hash();
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoObject *godot_icall_GD_instance_from_id(uint64_t p_instance_id) {
|
|
||||||
return GDMonoUtils::unmanaged_get_managed(ObjectDB::get_instance(ObjectID(p_instance_id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void godot_icall_GD_print(MonoArray *p_what) {
|
|
||||||
String str;
|
|
||||||
int length = mono_array_length(p_what);
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
MonoObject *elem = mono_array_get(p_what, MonoObject *, i);
|
|
||||||
|
|
||||||
MonoException *exc = nullptr;
|
|
||||||
String elem_str = GDMonoMarshal::mono_object_to_variant_string(elem, &exc);
|
|
||||||
|
|
||||||
if (exc) {
|
|
||||||
GDMonoUtils::set_pending_exception(exc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
str += elem_str;
|
|
||||||
}
|
|
||||||
|
|
||||||
print_line(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void godot_icall_GD_print_rich(MonoArray *p_what) {
|
|
||||||
String str;
|
|
||||||
int length = mono_array_length(p_what);
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
MonoObject *elem = mono_array_get(p_what, MonoObject *, i);
|
|
||||||
|
|
||||||
MonoException *exc = nullptr;
|
|
||||||
String elem_str = GDMonoMarshal::mono_object_to_variant_string(elem, &exc);
|
|
||||||
|
|
||||||
if (exc) {
|
|
||||||
GDMonoUtils::set_pending_exception(exc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
str += elem_str;
|
|
||||||
}
|
|
||||||
|
|
||||||
print_line_rich(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void godot_icall_GD_printerr(MonoArray *p_what) {
|
|
||||||
String str;
|
|
||||||
int length = mono_array_length(p_what);
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
MonoObject *elem = mono_array_get(p_what, MonoObject *, i);
|
|
||||||
|
|
||||||
MonoException *exc = nullptr;
|
|
||||||
String elem_str = GDMonoMarshal::mono_object_to_variant_string(elem, &exc);
|
|
||||||
|
|
||||||
if (exc) {
|
|
||||||
GDMonoUtils::set_pending_exception(exc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
str += elem_str;
|
|
||||||
}
|
|
||||||
|
|
||||||
print_error(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void godot_icall_GD_printraw(MonoArray *p_what) {
|
|
||||||
String str;
|
|
||||||
int length = mono_array_length(p_what);
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
MonoObject *elem = mono_array_get(p_what, MonoObject *, i);
|
|
||||||
|
|
||||||
MonoException *exc = nullptr;
|
|
||||||
String elem_str = GDMonoMarshal::mono_object_to_variant_string(elem, &exc);
|
|
||||||
|
|
||||||
if (exc) {
|
|
||||||
GDMonoUtils::set_pending_exception(exc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
str += elem_str;
|
|
||||||
}
|
|
||||||
|
|
||||||
OS::get_singleton()->print("%s", str.utf8().get_data());
|
|
||||||
}
|
|
||||||
|
|
||||||
void godot_icall_GD_prints(MonoArray *p_what) {
|
|
||||||
String str;
|
|
||||||
int length = mono_array_length(p_what);
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
MonoObject *elem = mono_array_get(p_what, MonoObject *, i);
|
|
||||||
|
|
||||||
MonoException *exc = nullptr;
|
|
||||||
String elem_str = GDMonoMarshal::mono_object_to_variant_string(elem, &exc);
|
|
||||||
|
|
||||||
if (exc) {
|
|
||||||
GDMonoUtils::set_pending_exception(exc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i) {
|
|
||||||
str += " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
str += elem_str;
|
|
||||||
}
|
|
||||||
|
|
||||||
print_line(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void godot_icall_GD_printt(MonoArray *p_what) {
|
|
||||||
String str;
|
|
||||||
int length = mono_array_length(p_what);
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
MonoObject *elem = mono_array_get(p_what, MonoObject *, i);
|
|
||||||
|
|
||||||
MonoException *exc = nullptr;
|
|
||||||
String elem_str = GDMonoMarshal::mono_object_to_variant_string(elem, &exc);
|
|
||||||
|
|
||||||
if (exc) {
|
|
||||||
GDMonoUtils::set_pending_exception(exc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i) {
|
|
||||||
str += "\t";
|
|
||||||
}
|
|
||||||
|
|
||||||
str += elem_str;
|
|
||||||
}
|
|
||||||
|
|
||||||
print_line(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void godot_icall_GD_randomize() {
|
|
||||||
Math::randomize();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t godot_icall_GD_randi() {
|
|
||||||
return Math::rand();
|
|
||||||
}
|
|
||||||
|
|
||||||
float godot_icall_GD_randf() {
|
|
||||||
return Math::randf();
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t godot_icall_GD_randi_range(int32_t from, int32_t to) {
|
|
||||||
return Math::random(from, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
double godot_icall_GD_randf_range(double from, double to) {
|
|
||||||
return Math::random(from, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
double godot_icall_GD_randfn(double mean, double deviation) {
|
|
||||||
return Math::randfn(mean, deviation);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t godot_icall_GD_rand_seed(uint64_t seed, uint64_t *newSeed) {
|
|
||||||
uint32_t ret = Math::rand_from_seed(&seed);
|
|
||||||
*newSeed = seed;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void godot_icall_GD_seed(uint64_t p_seed) {
|
|
||||||
Math::seed(p_seed);
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoString *godot_icall_GD_str(MonoArray *p_what) {
|
|
||||||
String str;
|
|
||||||
Array what = GDMonoMarshal::mono_array_to_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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return GDMonoMarshal::mono_string_from_godot(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoObject *godot_icall_GD_str2var(MonoString *p_str) {
|
|
||||||
Variant ret;
|
|
||||||
|
|
||||||
VariantParser::StreamString ss;
|
|
||||||
ss.s = GDMonoMarshal::mono_string_to_godot(p_str);
|
|
||||||
|
|
||||||
String errs;
|
|
||||||
int line;
|
|
||||||
Error err = VariantParser::parse(&ss, ret, errs, line);
|
|
||||||
if (err != OK) {
|
|
||||||
String err_str = "Parse error at line " + itos(line) + ": " + errs + ".";
|
|
||||||
ERR_PRINT(err_str);
|
|
||||||
ret = err_str;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GDMonoMarshal::variant_to_mono_object(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoBoolean godot_icall_GD_type_exists(StringName *p_type) {
|
|
||||||
StringName type = p_type ? *p_type : StringName();
|
|
||||||
return ClassDB::class_exists(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void godot_icall_GD_pusherror(MonoString *p_str) {
|
|
||||||
ERR_PRINT(GDMonoMarshal::mono_string_to_godot(p_str));
|
|
||||||
}
|
|
||||||
|
|
||||||
void godot_icall_GD_pushwarning(MonoString *p_str) {
|
|
||||||
WARN_PRINT(GDMonoMarshal::mono_string_to_godot(p_str));
|
|
||||||
}
|
|
||||||
|
|
||||||
void godot_icall_GD_var2bytes(MonoObject *p_var, MonoBoolean p_full_objects, PackedByteArray *r_bytes) {
|
|
||||||
memnew_placement(r_bytes, PackedByteArray);
|
|
||||||
|
|
||||||
Variant var = GDMonoMarshal::mono_object_to_variant(p_var);
|
|
||||||
|
|
||||||
int len;
|
|
||||||
Error err = encode_variant(var, nullptr, len, p_full_objects);
|
|
||||||
ERR_FAIL_COND_MSG(err != OK, "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).");
|
|
||||||
|
|
||||||
r_bytes->resize(len);
|
|
||||||
encode_variant(var, r_bytes->ptrw(), len, p_full_objects);
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoString *godot_icall_GD_var2str(MonoObject *p_var) {
|
|
||||||
String vars;
|
|
||||||
VariantWriter::write_to_string(GDMonoMarshal::mono_object_to_variant(p_var), vars);
|
|
||||||
return GDMonoMarshal::mono_string_from_godot(vars);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t godot_icall_TypeToVariantType(MonoReflectionType *p_refl_type) {
|
|
||||||
return (uint32_t)GDMonoMarshal::managed_to_variant_type(ManagedType::from_reftype(p_refl_type));
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoObject *godot_icall_DefaultGodotTaskScheduler() {
|
|
||||||
return GDMonoCache::cached_data.task_scheduler_handle->get_target();
|
|
||||||
}
|
|
||||||
|
|
||||||
void godot_register_gd_icalls() {
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_bytes2var", godot_icall_GD_bytes2var);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_convert", godot_icall_GD_convert);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_hash", godot_icall_GD_hash);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_instance_from_id", godot_icall_GD_instance_from_id);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_pusherror", godot_icall_GD_pusherror);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_pushwarning", godot_icall_GD_pushwarning);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_print", godot_icall_GD_print);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_print_rich", godot_icall_GD_print_rich);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_printerr", godot_icall_GD_printerr);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_printraw", godot_icall_GD_printraw);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_prints", godot_icall_GD_prints);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_printt", godot_icall_GD_printt);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randomize", godot_icall_GD_randomize);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randi", godot_icall_GD_randi);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randf", godot_icall_GD_randf);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randi_range", godot_icall_GD_randi_range);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randf_range", godot_icall_GD_randf_range);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randfn", godot_icall_GD_randfn);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_rand_seed", godot_icall_GD_rand_seed);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_seed", godot_icall_GD_seed);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_str", godot_icall_GD_str);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_str2var", godot_icall_GD_str2var);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_type_exists", godot_icall_GD_type_exists);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_var2bytes", godot_icall_GD_var2bytes);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_var2str", godot_icall_GD_var2str);
|
|
||||||
GDMonoUtils::add_internal_call("Godot.GD::godot_icall_TypeToVariantType", godot_icall_TypeToVariantType);
|
|
||||||
|
|
||||||
// Dispatcher
|
|
||||||
GDMonoUtils::add_internal_call("Godot.Dispatcher::godot_icall_DefaultGodotTaskScheduler", godot_icall_DefaultGodotTaskScheduler);
|
|
||||||
}
|
|
|
@ -29,8 +29,10 @@
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
#include "core/config/engine.h"
|
#include "core/config/engine.h"
|
||||||
|
#include "core/io/marshalls.h"
|
||||||
#include "core/object/class_db.h"
|
#include "core/object/class_db.h"
|
||||||
#include "core/object/method_bind.h"
|
#include "core/object/method_bind.h"
|
||||||
|
#include "core/os/os.h"
|
||||||
#include "core/string/string_name.h"
|
#include "core/string/string_name.h"
|
||||||
|
|
||||||
#include "../interop_types.h"
|
#include "../interop_types.h"
|
||||||
|
@ -839,12 +841,194 @@ GD_PINVOKE_EXPORT bool godotsharp_node_path_is_absolute(const NodePath *p_self)
|
||||||
return p_self->is_absolute();
|
return p_self->is_absolute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_randomize() {
|
||||||
|
Math::randomize();
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT uint32_t godotsharp_randi() {
|
||||||
|
return Math::rand();
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT float godotsharp_randf() {
|
||||||
|
return Math::randf();
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT int32_t godotsharp_randi_range(int32_t p_from, int32_t p_to) {
|
||||||
|
return Math::random(p_from, p_to);
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT double godotsharp_randf_range(double p_from, double p_to) {
|
||||||
|
return Math::random(p_from, p_to);
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT double godotsharp_randfn(double p_mean, double p_deviation) {
|
||||||
|
return Math::randfn(p_mean, p_deviation);
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_seed(uint64_t p_seed) {
|
||||||
|
Math::seed(p_seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT uint32_t godotsharp_rand_from_seed(uint64_t p_seed, uint64_t *r_new_seed) {
|
||||||
|
uint32_t ret = Math::rand_from_seed(&p_seed);
|
||||||
|
*r_new_seed = p_seed;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_weakref(Object *p_ptr, Ref<RefCounted> *r_weak_ref) {
|
||||||
|
if (!p_ptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<WeakRef> wref;
|
||||||
|
RefCounted *rc = Object::cast_to<RefCounted>(p_ptr);
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
Ref<RefCounted> r = rc;
|
||||||
|
if (!r.is_valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wref.instantiate();
|
||||||
|
wref->set_ref(r);
|
||||||
|
} else {
|
||||||
|
wref.instantiate();
|
||||||
|
wref->set_obj(p_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
memnew_placement(r_weak_ref, Ref<RefCounted>(wref));
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_print(const godot_string *p_what) {
|
||||||
|
print_line(*reinterpret_cast<const String *>(p_what));
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_print_rich(const godot_string *p_what) {
|
||||||
|
print_line_rich(*reinterpret_cast<const String *>(p_what));
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_printerr(const godot_string *p_what) {
|
||||||
|
print_error(*reinterpret_cast<const String *>(p_what));
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_printt(const godot_string *p_what) {
|
||||||
|
print_line(*reinterpret_cast<const String *>(p_what));
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_prints(const godot_string *p_what) {
|
||||||
|
print_line(*reinterpret_cast<const String *>(p_what));
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_printraw(const godot_string *p_what) {
|
||||||
|
OS::get_singleton()->print("%s", reinterpret_cast<const String *>(p_what)->utf8().get_data());
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_pusherror(const godot_string *p_str) {
|
||||||
|
ERR_PRINT(*reinterpret_cast<const String *>(p_str));
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_pushwarning(const godot_string *p_str) {
|
||||||
|
WARN_PRINT(*reinterpret_cast<const String *>(p_str));
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_var2str(const godot_variant *p_var, godot_string *r_ret) {
|
||||||
|
const Variant &var = *reinterpret_cast<const Variant *>(p_var);
|
||||||
|
String &vars = *memnew_placement(r_ret, String);
|
||||||
|
VariantWriter::write_to_string(var, vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_str2var(const godot_string *p_str, godot_variant *r_ret) {
|
||||||
|
Variant ret;
|
||||||
|
|
||||||
|
VariantParser::StreamString ss;
|
||||||
|
ss.s = *reinterpret_cast<const String *>(p_str);
|
||||||
|
|
||||||
|
String errs;
|
||||||
|
int line;
|
||||||
|
Error err = VariantParser::parse(&ss, ret, errs, line);
|
||||||
|
if (err != OK) {
|
||||||
|
String err_str = "Parse error at line " + itos(line) + ": " + errs + ".";
|
||||||
|
ERR_PRINT(err_str);
|
||||||
|
ret = err_str;
|
||||||
|
}
|
||||||
|
memnew_placement(r_ret, Variant(ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_var2bytes(const godot_variant *p_var, bool p_full_objects, godot_packed_array *r_bytes) {
|
||||||
|
const Variant &var = *reinterpret_cast<const Variant *>(p_var);
|
||||||
|
PackedByteArray &bytes = *memnew_placement(r_bytes, PackedByteArray);
|
||||||
|
|
||||||
|
int len;
|
||||||
|
Error err = encode_variant(var, nullptr, len, p_full_objects);
|
||||||
|
ERR_FAIL_COND_MSG(err != OK, "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).");
|
||||||
|
|
||||||
|
bytes.resize(len);
|
||||||
|
encode_variant(var, bytes.ptrw(), len, p_full_objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_bytes2var(const godot_packed_array *p_bytes, bool p_allow_objects, godot_variant *r_ret) {
|
||||||
|
const PackedByteArray *bytes = reinterpret_cast<const PackedByteArray *>(p_bytes);
|
||||||
|
Variant ret;
|
||||||
|
Error err = decode_variant(ret, bytes->ptr(), bytes->size(), nullptr, p_allow_objects);
|
||||||
|
if (err != OK) {
|
||||||
|
ret = RTR("Not enough bytes for decoding bytes, or invalid format.");
|
||||||
|
}
|
||||||
|
memnew_placement(r_ret, Variant(ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT int godotsharp_hash(const godot_variant *p_var) {
|
||||||
|
return reinterpret_cast<const Variant *>(p_var)->hash();
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_convert(const godot_variant *p_what, int32_t p_type, godot_variant *r_ret) {
|
||||||
|
const Variant *args[1] = { reinterpret_cast<const Variant *>(p_what) };
|
||||||
|
Callable::CallError ce;
|
||||||
|
Variant ret;
|
||||||
|
Variant::construct(Variant::Type(p_type), ret, args, 1, ce);
|
||||||
|
if (ce.error != Callable::CallError::CALL_OK) {
|
||||||
|
memnew_placement(r_ret, Variant);
|
||||||
|
ERR_FAIL_MSG("Unable to convert parameter from '" +
|
||||||
|
Variant::get_type_name(reinterpret_cast<const Variant *>(p_what)->get_type()) +
|
||||||
|
"' to '" + Variant::get_type_name(Variant::Type(p_type)) + "'.");
|
||||||
|
}
|
||||||
|
memnew_placement(r_ret, Variant(ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT Object *godotsharp_instance_from_id(uint64_t p_instance_id) {
|
||||||
|
return ObjectDB::get_instance(ObjectID(p_instance_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
GD_PINVOKE_EXPORT void godotsharp_object_to_string(Object *p_ptr, godot_string *r_str) {
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
// Cannot happen in C#; would get an ObjectDisposedException instead.
|
||||||
|
CRASH_COND(p_ptr == nullptr);
|
||||||
|
#endif
|
||||||
|
// Can't call 'Object::to_string()' here, as that can end up calling 'ToString' again resulting in an endless circular loop.
|
||||||
|
memnew_placement(r_str,
|
||||||
|
String("[" + p_ptr->get_class() + ":" + itos(p_ptr->get_instance_id()) + "]"));
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We need this to prevent the functions from being stripped.
|
// We need this to prevent the functions from being stripped.
|
||||||
void *godotsharp_pinvoke_funcs[138] = {
|
void *godotsharp_pinvoke_funcs[164] = {
|
||||||
(void *)godotsharp_method_bind_get_method,
|
(void *)godotsharp_method_bind_get_method,
|
||||||
(void *)godotsharp_get_class_constructor,
|
(void *)godotsharp_get_class_constructor,
|
||||||
(void *)godotsharp_invoke_class_constructor,
|
(void *)godotsharp_invoke_class_constructor,
|
||||||
|
@ -982,5 +1166,31 @@ void *godotsharp_pinvoke_funcs[138] = {
|
||||||
(void *)godotsharp_node_path_get_name_count,
|
(void *)godotsharp_node_path_get_name_count,
|
||||||
(void *)godotsharp_node_path_get_subname,
|
(void *)godotsharp_node_path_get_subname,
|
||||||
(void *)godotsharp_node_path_get_subname_count,
|
(void *)godotsharp_node_path_get_subname_count,
|
||||||
(void *)godotsharp_node_path_is_absolute
|
(void *)godotsharp_node_path_is_absolute,
|
||||||
|
(void *)godotsharp_randomize,
|
||||||
|
(void *)godotsharp_randi,
|
||||||
|
(void *)godotsharp_randf,
|
||||||
|
(void *)godotsharp_randi_range,
|
||||||
|
(void *)godotsharp_randf_range,
|
||||||
|
(void *)godotsharp_randfn,
|
||||||
|
(void *)godotsharp_seed,
|
||||||
|
(void *)godotsharp_rand_from_seed,
|
||||||
|
(void *)godotsharp_weakref,
|
||||||
|
(void *)godotsharp_str,
|
||||||
|
(void *)godotsharp_print,
|
||||||
|
(void *)godotsharp_print_rich,
|
||||||
|
(void *)godotsharp_printerr,
|
||||||
|
(void *)godotsharp_printt,
|
||||||
|
(void *)godotsharp_prints,
|
||||||
|
(void *)godotsharp_printraw,
|
||||||
|
(void *)godotsharp_pusherror,
|
||||||
|
(void *)godotsharp_pushwarning,
|
||||||
|
(void *)godotsharp_var2str,
|
||||||
|
(void *)godotsharp_str2var,
|
||||||
|
(void *)godotsharp_var2bytes,
|
||||||
|
(void *)godotsharp_bytes2var,
|
||||||
|
(void *)godotsharp_hash,
|
||||||
|
(void *)godotsharp_convert,
|
||||||
|
(void *)godotsharp_instance_from_id,
|
||||||
|
(void *)godotsharp_object_to_string,
|
||||||
};
|
};
|
||||||
|
|
|
@ -442,14 +442,12 @@ bool GDMono::_are_api_assemblies_out_of_sync() {
|
||||||
return out_of_sync;
|
return out_of_sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
void godot_register_gd_icalls();
|
|
||||||
void godot_register_object_icalls();
|
void godot_register_object_icalls();
|
||||||
void godot_register_scene_tree_icalls();
|
void godot_register_scene_tree_icalls();
|
||||||
void godot_register_placeholder_icalls();
|
void godot_register_placeholder_icalls();
|
||||||
|
|
||||||
void GDMono::_register_internal_calls() {
|
void GDMono::_register_internal_calls() {
|
||||||
// Registers internal calls that were not generated.
|
// Registers internal calls that were not generated.
|
||||||
godot_register_gd_icalls();
|
|
||||||
godot_register_object_icalls();
|
godot_register_object_icalls();
|
||||||
godot_register_scene_tree_icalls();
|
godot_register_scene_tree_icalls();
|
||||||
godot_register_placeholder_icalls();
|
godot_register_placeholder_icalls();
|
||||||
|
@ -987,6 +985,8 @@ Error GDMono::_load_scripts_domain() {
|
||||||
Error GDMono::_unload_scripts_domain() {
|
Error GDMono::_unload_scripts_domain() {
|
||||||
ERR_FAIL_NULL_V(scripts_domain, ERR_BUG);
|
ERR_FAIL_NULL_V(scripts_domain, ERR_BUG);
|
||||||
|
|
||||||
|
CSharpLanguage::get_singleton()->_on_scripts_domain_about_to_unload();
|
||||||
|
|
||||||
print_verbose("Mono: Finalizing scripts domain...");
|
print_verbose("Mono: Finalizing scripts domain...");
|
||||||
|
|
||||||
if (mono_domain_get() != root_domain) {
|
if (mono_domain_get() != root_domain) {
|
||||||
|
@ -1040,8 +1040,6 @@ Error GDMono::_unload_scripts_domain() {
|
||||||
Error GDMono::reload_scripts_domain() {
|
Error GDMono::reload_scripts_domain() {
|
||||||
ERR_FAIL_COND_V(!runtime_initialized, ERR_BUG);
|
ERR_FAIL_COND_V(!runtime_initialized, ERR_BUG);
|
||||||
|
|
||||||
CSharpLanguage::get_singleton()->_on_scripts_domain_about_to_unload();
|
|
||||||
|
|
||||||
if (scripts_domain) {
|
if (scripts_domain) {
|
||||||
Error domain_unload_err = _unload_scripts_domain();
|
Error domain_unload_err = _unload_scripts_domain();
|
||||||
ERR_FAIL_COND_V_MSG(domain_unload_err != OK, domain_unload_err, "Mono: Failed to unload scripts domain.");
|
ERR_FAIL_COND_V_MSG(domain_unload_err != OK, domain_unload_err, "Mono: Failed to unload scripts domain.");
|
||||||
|
|
|
@ -116,7 +116,6 @@ void CachedData::clear_godot_api_cache() {
|
||||||
|
|
||||||
methodthunk_GodotObject_Dispose.nullify();
|
methodthunk_GodotObject_Dispose.nullify();
|
||||||
methodthunk_SignalAwaiter_SignalCallback.nullify();
|
methodthunk_SignalAwaiter_SignalCallback.nullify();
|
||||||
methodthunk_GodotTaskScheduler_Activate.nullify();
|
|
||||||
|
|
||||||
methodthunk_Delegate_Equals.nullify();
|
methodthunk_Delegate_Equals.nullify();
|
||||||
|
|
||||||
|
@ -137,8 +136,6 @@ void CachedData::clear_godot_api_cache() {
|
||||||
methodthunk_Marshaling_SetFieldValue.nullify();
|
methodthunk_Marshaling_SetFieldValue.nullify();
|
||||||
|
|
||||||
methodthunk_MarshalUtils_TypeHasFlagsAttribute.nullify();
|
methodthunk_MarshalUtils_TypeHasFlagsAttribute.nullify();
|
||||||
|
|
||||||
task_scheduler_handle = Ref<MonoGCHandleRef>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GODOT_API_CLASS(m_class) (GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, #m_class))
|
#define GODOT_API_CLASS(m_class) (GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, #m_class))
|
||||||
|
@ -197,7 +194,6 @@ void update_godot_api_cache() {
|
||||||
|
|
||||||
CACHE_METHOD_THUNK_AND_CHECK(GodotObject, Dispose, CACHED_CLASS(GodotObject)->get_method("Dispose", 0));
|
CACHE_METHOD_THUNK_AND_CHECK(GodotObject, Dispose, CACHED_CLASS(GodotObject)->get_method("Dispose", 0));
|
||||||
CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, SignalCallback, GODOT_API_CLASS(SignalAwaiter)->get_method("SignalCallback", 1));
|
CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, SignalCallback, GODOT_API_CLASS(SignalAwaiter)->get_method("SignalCallback", 1));
|
||||||
CACHE_METHOD_THUNK_AND_CHECK(GodotTaskScheduler, Activate, GODOT_API_CLASS(GodotTaskScheduler)->get_method("Activate", 0));
|
|
||||||
|
|
||||||
CACHE_METHOD_THUNK_AND_CHECK(DelegateUtils, TrySerializeDelegateWithGCHandle, GODOT_API_CLASS(DelegateUtils)->get_method("TrySerializeDelegateWithGCHandle", 2));
|
CACHE_METHOD_THUNK_AND_CHECK(DelegateUtils, TrySerializeDelegateWithGCHandle, GODOT_API_CLASS(DelegateUtils)->get_method("TrySerializeDelegateWithGCHandle", 2));
|
||||||
CACHE_METHOD_THUNK_AND_CHECK(DelegateUtils, TryDeserializeDelegateWithGCHandle, GODOT_API_CLASS(DelegateUtils)->get_method("TryDeserializeDelegateWithGCHandle", 2));
|
CACHE_METHOD_THUNK_AND_CHECK(DelegateUtils, TryDeserializeDelegateWithGCHandle, GODOT_API_CLASS(DelegateUtils)->get_method("TryDeserializeDelegateWithGCHandle", 2));
|
||||||
|
@ -233,10 +229,16 @@ void update_godot_api_cache() {
|
||||||
CACHE_METHOD_THUNK_AND_CHECK(DebuggingUtils, GetStackFrameInfo, GODOT_API_CLASS(DebuggingUtils)->get_method("GetStackFrameInfo", 4));
|
CACHE_METHOD_THUNK_AND_CHECK(DebuggingUtils, GetStackFrameInfo, GODOT_API_CLASS(DebuggingUtils)->get_method("GetStackFrameInfo", 4));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO Move to CSharpLanguage::init() and do handle disposal
|
MonoException *exc = nullptr;
|
||||||
MonoObject *task_scheduler = mono_object_new(mono_domain_get(), GODOT_API_CLASS(GodotTaskScheduler)->get_mono_ptr());
|
GDMono::get_singleton()
|
||||||
GDMonoUtils::runtime_object_init(task_scheduler, GODOT_API_CLASS(GodotTaskScheduler));
|
->get_core_api_assembly()
|
||||||
cached_data.task_scheduler_handle = MonoGCHandleRef::create_strong(task_scheduler);
|
->get_class("Godot", "Dispatcher")
|
||||||
|
->get_method("InitializeDefaultGodotTaskScheduler")
|
||||||
|
->invoke(nullptr, &exc);
|
||||||
|
|
||||||
|
if (exc) {
|
||||||
|
GDMonoUtils::debug_unhandled_exception(exc);
|
||||||
|
}
|
||||||
|
|
||||||
cached_data.godot_api_cache_updated = true;
|
cached_data.godot_api_cache_updated = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,6 @@ struct CachedData {
|
||||||
|
|
||||||
GDMonoMethodThunk<MonoObject *> methodthunk_GodotObject_Dispose;
|
GDMonoMethodThunk<MonoObject *> methodthunk_GodotObject_Dispose;
|
||||||
GDMonoMethodThunk<MonoObject *, MonoArray *> methodthunk_SignalAwaiter_SignalCallback;
|
GDMonoMethodThunk<MonoObject *, MonoArray *> methodthunk_SignalAwaiter_SignalCallback;
|
||||||
GDMonoMethodThunk<MonoObject *> methodthunk_GodotTaskScheduler_Activate;
|
|
||||||
|
|
||||||
GDMonoMethodThunkR<MonoBoolean, MonoObject *, MonoObject *> methodthunk_Delegate_Equals;
|
GDMonoMethodThunkR<MonoBoolean, MonoObject *, MonoObject *> methodthunk_Delegate_Equals;
|
||||||
|
|
||||||
|
@ -114,8 +113,6 @@ struct CachedData {
|
||||||
|
|
||||||
GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeHasFlagsAttribute;
|
GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeHasFlagsAttribute;
|
||||||
|
|
||||||
Ref<MonoGCHandleRef> task_scheduler_handle;
|
|
||||||
|
|
||||||
bool corlib_cache_updated;
|
bool corlib_cache_updated;
|
||||||
bool godot_api_cache_updated;
|
bool godot_api_cache_updated;
|
||||||
|
|
||||||
|
|
|
@ -40,9 +40,7 @@ namespace GDMonoMarshal {
|
||||||
// TODO: Those are just temporary until the code that needs them is moved to C#
|
// TODO: Those are just temporary until the code that needs them is moved to C#
|
||||||
|
|
||||||
Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_variant) {
|
Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_variant) {
|
||||||
if (p_type.type_encoding == MONO_TYPE_VOID) {
|
CRASH_COND(p_type.type_class == nullptr);
|
||||||
return Variant::NIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoReflectionType *refltype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type());
|
MonoReflectionType *refltype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type());
|
||||||
MonoBoolean nil_is_variant = false;
|
MonoBoolean nil_is_variant = false;
|
||||||
|
@ -137,59 +135,6 @@ Variant mono_object_to_variant_no_err(MonoObject *p_obj) {
|
||||||
return mono_object_to_variant_impl(p_obj, /* fail_with_err: */ false);
|
return mono_object_to_variant_impl(p_obj, /* fail_with_err: */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) {
|
|
||||||
if (p_obj == nullptr) {
|
|
||||||
return String("null");
|
|
||||||
}
|
|
||||||
|
|
||||||
Variant var = GDMonoMarshal::mono_object_to_variant_no_err(p_obj);
|
|
||||||
|
|
||||||
if (var.get_type() == Variant::NIL) { // `&& p_obj != nullptr` but omitted because always true
|
|
||||||
// Cannot convert MonoObject* to Variant; fallback to 'ToString()'.
|
|
||||||
MonoException *exc = nullptr;
|
|
||||||
MonoString *mono_str = GDMonoUtils::object_to_string(p_obj, &exc);
|
|
||||||
|
|
||||||
if (exc) {
|
|
||||||
if (r_exc) {
|
|
||||||
*r_exc = exc;
|
|
||||||
}
|
|
||||||
return String();
|
|
||||||
}
|
|
||||||
|
|
||||||
return GDMonoMarshal::mono_string_to_godot(mono_str);
|
|
||||||
} else {
|
|
||||||
return var.operator String();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoArray *Array_to_mono_array(const Array &p_array) {
|
|
||||||
int length = p_array.size();
|
|
||||||
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), length);
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
MonoObject *boxed = variant_to_mono_object(p_array[i]);
|
|
||||||
mono_array_setref(ret, i, boxed);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
Array mono_array_to_Array(MonoArray *p_array) {
|
|
||||||
Array ret;
|
|
||||||
if (!p_array) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
int length = mono_array_length(p_array);
|
|
||||||
ret.resize(length);
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
MonoObject *elem = mono_array_get(p_array, MonoObject *, i);
|
|
||||||
ret[i] = mono_object_to_variant(elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoArray *PackedStringArray_to_mono_array(const PackedStringArray &p_array) {
|
MonoArray *PackedStringArray_to_mono_array(const PackedStringArray &p_array) {
|
||||||
const String *r = p_array.ptr();
|
const String *r = p_array.ptr();
|
||||||
int length = p_array.size();
|
int length = p_array.size();
|
||||||
|
|
|
@ -88,15 +88,6 @@ _FORCE_INLINE_ MonoObject *variant_to_mono_object(const Variant *p_var) {
|
||||||
Variant mono_object_to_variant(MonoObject *p_obj);
|
Variant mono_object_to_variant(MonoObject *p_obj);
|
||||||
Variant mono_object_to_variant_no_err(MonoObject *p_obj);
|
Variant mono_object_to_variant_no_err(MonoObject *p_obj);
|
||||||
|
|
||||||
/// Tries to convert the MonoObject* to Variant and then convert the Variant to String.
|
|
||||||
/// If the MonoObject* cannot be converted to Variant, then 'ToString()' is called instead.
|
|
||||||
String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc);
|
|
||||||
|
|
||||||
// Array
|
|
||||||
|
|
||||||
MonoArray *Array_to_mono_array(const Array &p_array);
|
|
||||||
Array mono_array_to_Array(MonoArray *p_array);
|
|
||||||
|
|
||||||
// PackedStringArray
|
// PackedStringArray
|
||||||
|
|
||||||
MonoArray *PackedStringArray_to_mono_array(const PackedStringArray &p_array);
|
MonoArray *PackedStringArray_to_mono_array(const PackedStringArray &p_array);
|
||||||
|
|
|
@ -253,9 +253,13 @@ const MethodInfo &GDMonoMethod::get_method_info() {
|
||||||
method_info.name = name;
|
method_info.name = name;
|
||||||
|
|
||||||
bool nil_is_variant = false;
|
bool nil_is_variant = false;
|
||||||
method_info.return_val = PropertyInfo(GDMonoMarshal::managed_to_variant_type(return_type, &nil_is_variant), "");
|
if (return_type.type_encoding == MONO_TYPE_VOID) {
|
||||||
if (method_info.return_val.type == Variant::NIL && nil_is_variant) {
|
method_info.return_val = PropertyInfo(Variant::NIL, "");
|
||||||
method_info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
|
} else {
|
||||||
|
method_info.return_val = PropertyInfo(GDMonoMarshal::managed_to_variant_type(return_type, &nil_is_variant), "");
|
||||||
|
if (method_info.return_val.type == Variant::NIL && nil_is_variant) {
|
||||||
|
method_info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<StringName> names;
|
Vector<StringName> names;
|
||||||
|
|
Loading…
Reference in a new issue