From 2c180f62d985194060f1a8d2070c130081177c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ignacio=20Rold=C3=A1n=20Etcheverry?= Date: Fri, 5 Aug 2022 03:32:59 +0200 Subject: C#: Replace P/Invoke with delegate pointers - Moves interop functions to UnmanagedCallbacks struct that contains the function pointers and is passed to C#. - Implements UnmanagedCallbacksGenerator, a C# source generator that generates the UnmanagedCallbacks struct in C# and the body for the NativeFuncs methods (their implementation just calls the function pointer in the UnmanagedCallbacks). The generated methods are needed because .NET pins byref parameters of native calls, even if they are 'ref struct's, which don't need pinning. The generated methods use `Unsafe.AsPointer` so that we can benefit from byref parameters without suffering overhead of pinning. Co-authored-by: Raul Santos --- modules/mono/editor/GodotTools/GodotTools.sln | 6 ++ .../GodotTools/GodotTools/GodotSharpEditor.cs | 3 +- .../editor/GodotTools/GodotTools/GodotTools.csproj | 1 + .../GodotTools/GodotTools/Internals/Internal.cs | 119 +++++++++++---------- modules/mono/editor/editor_internal_calls.cpp | 79 +++++++------- modules/mono/editor/editor_internal_calls.h | 6 +- 6 files changed, 110 insertions(+), 104 deletions(-) (limited to 'modules/mono/editor') diff --git a/modules/mono/editor/GodotTools/GodotTools.sln b/modules/mono/editor/GodotTools/GodotTools.sln index f3d2f90f39..564775635d 100644 --- a/modules/mono/editor/GodotTools/GodotTools.sln +++ b/modules/mono/editor/GodotTools/GodotTools.sln @@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.Shared", "GodotT EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Godot.SourceGenerators", "..\Godot.NET.Sdk\Godot.SourceGenerators\Godot.SourceGenerators.csproj", "{D8C421B2-8911-41EB-B983-F675C7141EB7}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Godot.SourceGenerators.Internal", "..\..\glue\GodotSharp\Godot.SourceGenerators.Internal\Godot.SourceGenerators.Internal.csproj", "{55666071-BEC1-4A52-8A98-9A4A7A947DBF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -55,5 +57,9 @@ Global {D8C421B2-8911-41EB-B983-F675C7141EB7}.Debug|Any CPU.Build.0 = Debug|Any CPU {D8C421B2-8911-41EB-B983-F675C7141EB7}.Release|Any CPU.ActiveCfg = Release|Any CPU {D8C421B2-8911-41EB-B983-F675C7141EB7}.Release|Any CPU.Build.0 = Release|Any CPU + {55666071-BEC1-4A52-8A98-9A4A7A947DBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55666071-BEC1-4A52-8A98-9A4A7A947DBF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55666071-BEC1-4A52-8A98-9A4A7A947DBF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55666071-BEC1-4A52-8A98-9A4A7A947DBF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index 45a29d89de..0aca60dad4 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -547,8 +547,9 @@ namespace GodotTools public static GodotSharpEditor Instance { get; private set; } [UsedImplicitly] - private static IntPtr InternalCreateInstance() + private static IntPtr InternalCreateInstance(IntPtr unmanagedCallbacks, int unmanagedCallbacksSize) { + Internal.Initialize(unmanagedCallbacks, unmanagedCallbacksSize); return new GodotSharpEditor().NativeInstance; } } diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj index f5734e6e69..30525ba04a 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj +++ b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj @@ -43,6 +43,7 @@ + diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs index f0d2bed246..e3fe1622d0 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs @@ -1,12 +1,16 @@ using System; -using System.Runtime.InteropServices; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using Godot; using Godot.NativeInterop; +using Godot.SourceGenerators.Internal; using GodotTools.IdeMessaging.Requests; namespace GodotTools.Internals { - internal static class Internal + [SuppressMessage("ReSharper", "InconsistentNaming")] + [GenerateUnmanagedCallbacks(typeof(InternalUnmanagedCallbacks))] + internal static partial class Internal { public const string CSharpLanguageType = "CSharpScript"; public const string CSharpLanguageExtension = ".cs"; @@ -64,97 +68,94 @@ namespace GodotTools.Internals #region Internal - private const string GodotDllName = "__Internal"; + private static bool initialized = false; - [DllImport(GodotDllName)] - public static extern void godot_icall_GodotSharpDirs_ResMetadataDir(out godot_string r_dest); + // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Global + internal static unsafe void Initialize(IntPtr unmanagedCallbacks, int unmanagedCallbacksSize) + { + if (initialized) + throw new InvalidOperationException("Already initialized"); + initialized = true; + + if (unmanagedCallbacksSize != sizeof(InternalUnmanagedCallbacks)) + throw new ArgumentException("Unmanaged callbacks size mismatch"); + + _unmanagedCallbacks = Unsafe.AsRef((void*)unmanagedCallbacks); + } + + private partial struct InternalUnmanagedCallbacks + { + } + + /* + * IMPORTANT: + * The order of the methods defined in NativeFuncs must match the order + * in the array defined at the bottom of 'editor/editor_internal_calls.cpp'. + */ + + public static partial void godot_icall_GodotSharpDirs_ResMetadataDir(out godot_string r_dest); - [DllImport(GodotDllName)] - public static extern void godot_icall_GodotSharpDirs_MonoUserDir(out godot_string r_dest); + public static partial void godot_icall_GodotSharpDirs_MonoUserDir(out godot_string r_dest); - [DllImport(GodotDllName)] - public static extern void godot_icall_GodotSharpDirs_BuildLogsDirs(out godot_string r_dest); + public static partial void godot_icall_GodotSharpDirs_BuildLogsDirs(out godot_string r_dest); - [DllImport(GodotDllName)] - public static extern void godot_icall_GodotSharpDirs_DataEditorToolsDir(out godot_string r_dest); + public static partial void godot_icall_GodotSharpDirs_DataEditorToolsDir(out godot_string r_dest); - [DllImport(GodotDllName)] - public static extern void godot_icall_EditorProgress_Create(in godot_string task, in godot_string label, + public static partial void godot_icall_EditorProgress_Create(in godot_string task, in godot_string label, int amount, bool canCancel); - [DllImport(GodotDllName)] - public static extern void godot_icall_EditorProgress_Dispose(in godot_string task); + public static partial void godot_icall_EditorProgress_Dispose(in godot_string task); - [DllImport(GodotDllName)] - public static extern bool godot_icall_EditorProgress_Step(in godot_string task, in godot_string state, int step, + public static partial bool godot_icall_EditorProgress_Step(in godot_string task, in godot_string state, + int step, bool forceRefresh); - [DllImport(GodotDllName)] - private static extern void godot_icall_Internal_FullExportTemplatesDir(out godot_string dest); + private static partial void godot_icall_Internal_FullExportTemplatesDir(out godot_string dest); - [DllImport(GodotDllName)] - private static extern bool godot_icall_Internal_IsMacOSAppBundleInstalled(in godot_string bundleId); + private static partial bool godot_icall_Internal_IsMacOSAppBundleInstalled(in godot_string bundleId); - [DllImport(GodotDllName)] - private static extern bool godot_icall_Internal_GodotIs32Bits(); + private static partial bool godot_icall_Internal_GodotIs32Bits(); - [DllImport(GodotDllName)] - private static extern bool godot_icall_Internal_GodotIsRealTDouble(); + private static partial bool godot_icall_Internal_GodotIsRealTDouble(); - [DllImport(GodotDllName)] - private static extern void godot_icall_Internal_GodotMainIteration(); + private static partial void godot_icall_Internal_GodotMainIteration(); - [DllImport(GodotDllName)] - private static extern bool godot_icall_Internal_IsAssembliesReloadingNeeded(); + private static partial bool godot_icall_Internal_IsAssembliesReloadingNeeded(); - [DllImport(GodotDllName)] - private static extern void godot_icall_Internal_ReloadAssemblies(bool softReload); + private static partial void godot_icall_Internal_ReloadAssemblies(bool softReload); - [DllImport(GodotDllName)] - private static extern void godot_icall_Internal_EditorDebuggerNodeReloadScripts(); + private static partial void godot_icall_Internal_EditorDebuggerNodeReloadScripts(); - [DllImport(GodotDllName)] - private static extern bool godot_icall_Internal_ScriptEditorEdit(IntPtr resource, int line, int col, + private static partial bool godot_icall_Internal_ScriptEditorEdit(IntPtr resource, int line, int col, bool grabFocus); - [DllImport(GodotDllName)] - private static extern void godot_icall_Internal_EditorNodeShowScriptScreen(); + private static partial void godot_icall_Internal_EditorNodeShowScriptScreen(); - [DllImport(GodotDllName)] - private static extern void godot_icall_Internal_EditorRunPlay(); + private static partial void godot_icall_Internal_EditorRunPlay(); - [DllImport(GodotDllName)] - private static extern void godot_icall_Internal_EditorRunStop(); + private static partial void godot_icall_Internal_EditorRunStop(); - [DllImport(GodotDllName)] - private static extern void godot_icall_Internal_ScriptEditorDebugger_ReloadScripts(); + private static partial void godot_icall_Internal_ScriptEditorDebugger_ReloadScripts(); - [DllImport(GodotDllName)] - private static extern void godot_icall_Internal_CodeCompletionRequest(int kind, in godot_string scriptFile, + private static partial void godot_icall_Internal_CodeCompletionRequest(int kind, in godot_string scriptFile, out godot_packed_string_array res); - [DllImport(GodotDllName)] - public static extern float godot_icall_Globals_EditorScale(); + public static partial float godot_icall_Globals_EditorScale(); - [DllImport(GodotDllName)] - public static extern void godot_icall_Globals_GlobalDef(in godot_string setting, in godot_variant defaultValue, + public static partial void godot_icall_Globals_GlobalDef(in godot_string setting, in godot_variant defaultValue, bool restartIfChanged, out godot_variant result); - [DllImport(GodotDllName)] - public static extern void godot_icall_Globals_EditorDef(in godot_string setting, in godot_variant defaultValue, + public static partial void godot_icall_Globals_EditorDef(in godot_string setting, in godot_variant defaultValue, bool restartIfChanged, out godot_variant result); - [DllImport(GodotDllName)] - public static extern void godot_icall_Globals_EditorShortcut(in godot_string setting, out godot_variant result); + public static partial void + godot_icall_Globals_EditorShortcut(in godot_string setting, out godot_variant result); - [DllImport(GodotDllName)] - public static extern void godot_icall_Globals_TTR(in godot_string text, out godot_string dest); + public static partial void godot_icall_Globals_TTR(in godot_string text, out godot_string dest); - [DllImport(GodotDllName)] - public static extern void godot_icall_Utils_OS_GetPlatformName(out godot_string dest); + public static partial void godot_icall_Utils_OS_GetPlatformName(out godot_string dest); - [DllImport(GodotDllName)] - public static extern bool godot_icall_Utils_OS_UnixFileHasExecutableAccess(in godot_string filePath); + public static partial bool godot_icall_Utils_OS_UnixFileHasExecutableAccess(in godot_string filePath); #endregion } diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index bf0309126b..1ef78c3ac2 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -56,29 +56,15 @@ extern "C" { #endif -#ifdef __cplusplus -#define MAYBE_UNUSED [[maybe_unused]] -#else -#define MAYBE_UNUSED -#endif - -#ifdef __GNUC__ -#define GD_PINVOKE_EXPORT MAYBE_UNUSED __attribute__((visibility("default"))) -#elif defined(_WIN32) -#define GD_PINVOKE_EXPORT MAYBE_UNUSED __declspec(dllexport) -#else -#define GD_PINVOKE_EXPORT MAYBE_UNUSED -#endif - -GD_PINVOKE_EXPORT void godot_icall_GodotSharpDirs_ResMetadataDir(godot_string *r_dest) { +void godot_icall_GodotSharpDirs_ResMetadataDir(godot_string *r_dest) { memnew_placement(r_dest, String(GodotSharpDirs::get_res_metadata_dir())); } -GD_PINVOKE_EXPORT void godot_icall_GodotSharpDirs_MonoUserDir(godot_string *r_dest) { +void godot_icall_GodotSharpDirs_MonoUserDir(godot_string *r_dest) { memnew_placement(r_dest, String(GodotSharpDirs::get_mono_user_dir())); } -GD_PINVOKE_EXPORT void godot_icall_GodotSharpDirs_BuildLogsDirs(godot_string *r_dest) { +void godot_icall_GodotSharpDirs_BuildLogsDirs(godot_string *r_dest) { #ifdef TOOLS_ENABLED memnew_placement(r_dest, String(GodotSharpDirs::get_build_logs_dir())); #else @@ -86,7 +72,7 @@ GD_PINVOKE_EXPORT void godot_icall_GodotSharpDirs_BuildLogsDirs(godot_string *r_ #endif } -GD_PINVOKE_EXPORT void godot_icall_GodotSharpDirs_DataEditorToolsDir(godot_string *r_dest) { +void godot_icall_GodotSharpDirs_DataEditorToolsDir(godot_string *r_dest) { #ifdef TOOLS_ENABLED memnew_placement(r_dest, String(GodotSharpDirs::get_data_editor_tools_dir())); #else @@ -94,29 +80,29 @@ GD_PINVOKE_EXPORT void godot_icall_GodotSharpDirs_DataEditorToolsDir(godot_strin #endif } -GD_PINVOKE_EXPORT void godot_icall_EditorProgress_Create(const godot_string *p_task, const godot_string *p_label, int32_t p_amount, bool p_can_cancel) { +void godot_icall_EditorProgress_Create(const godot_string *p_task, const godot_string *p_label, int32_t p_amount, bool p_can_cancel) { String task = *reinterpret_cast(p_task); String label = *reinterpret_cast(p_label); EditorNode::progress_add_task(task, label, p_amount, (bool)p_can_cancel); } -GD_PINVOKE_EXPORT void godot_icall_EditorProgress_Dispose(const godot_string *p_task) { +void godot_icall_EditorProgress_Dispose(const godot_string *p_task) { String task = *reinterpret_cast(p_task); EditorNode::progress_end_task(task); } -GD_PINVOKE_EXPORT bool godot_icall_EditorProgress_Step(const godot_string *p_task, const godot_string *p_state, int32_t p_step, bool p_force_refresh) { +bool godot_icall_EditorProgress_Step(const godot_string *p_task, const godot_string *p_state, int32_t p_step, bool p_force_refresh) { String task = *reinterpret_cast(p_task); String state = *reinterpret_cast(p_state); return EditorNode::progress_task_step(task, state, p_step, (bool)p_force_refresh); } -GD_PINVOKE_EXPORT void godot_icall_Internal_FullExportTemplatesDir(godot_string *r_dest) { +void godot_icall_Internal_FullExportTemplatesDir(godot_string *r_dest) { String full_templates_dir = EditorPaths::get_singleton()->get_export_templates_dir().plus_file(VERSION_FULL_CONFIG); memnew_placement(r_dest, String(full_templates_dir)); } -GD_PINVOKE_EXPORT bool godot_icall_Internal_IsMacOSAppBundleInstalled(const godot_string *p_bundle_id) { +bool godot_icall_Internal_IsMacOSAppBundleInstalled(const godot_string *p_bundle_id) { #ifdef MACOS_ENABLED String bundle_id = *reinterpret_cast(p_bundle_id); return (bool)macos_is_app_bundle_installed(bundle_id); @@ -126,11 +112,11 @@ GD_PINVOKE_EXPORT bool godot_icall_Internal_IsMacOSAppBundleInstalled(const godo #endif } -GD_PINVOKE_EXPORT bool godot_icall_Internal_GodotIs32Bits() { +bool godot_icall_Internal_GodotIs32Bits() { return sizeof(void *) == 4; } -GD_PINVOKE_EXPORT bool godot_icall_Internal_GodotIsRealTDouble() { +bool godot_icall_Internal_GodotIsRealTDouble() { #ifdef REAL_T_IS_DOUBLE return (bool)true; #else @@ -138,11 +124,11 @@ GD_PINVOKE_EXPORT bool godot_icall_Internal_GodotIsRealTDouble() { #endif } -GD_PINVOKE_EXPORT void godot_icall_Internal_GodotMainIteration() { +void godot_icall_Internal_GodotMainIteration() { Main::iteration(); } -GD_PINVOKE_EXPORT bool godot_icall_Internal_IsAssembliesReloadingNeeded() { +bool godot_icall_Internal_IsAssembliesReloadingNeeded() { #ifdef GD_MONO_HOT_RELOAD return (bool)CSharpLanguage::get_singleton()->is_assembly_reloading_needed(); #else @@ -150,81 +136,81 @@ GD_PINVOKE_EXPORT bool godot_icall_Internal_IsAssembliesReloadingNeeded() { #endif } -GD_PINVOKE_EXPORT void godot_icall_Internal_ReloadAssemblies(bool p_soft_reload) { +void godot_icall_Internal_ReloadAssemblies(bool p_soft_reload) { #ifdef GD_MONO_HOT_RELOAD mono_bind::GodotSharp::get_singleton()->call_deferred(SNAME("_reload_assemblies"), (bool)p_soft_reload); #endif } -GD_PINVOKE_EXPORT void godot_icall_Internal_EditorDebuggerNodeReloadScripts() { +void godot_icall_Internal_EditorDebuggerNodeReloadScripts() { EditorDebuggerNode::get_singleton()->reload_scripts(); } -GD_PINVOKE_EXPORT bool godot_icall_Internal_ScriptEditorEdit(Resource *p_resource, int32_t p_line, int32_t p_col, bool p_grab_focus) { +bool godot_icall_Internal_ScriptEditorEdit(Resource *p_resource, int32_t p_line, int32_t p_col, bool p_grab_focus) { Ref resource = p_resource; return (bool)ScriptEditor::get_singleton()->edit(resource, p_line, p_col, (bool)p_grab_focus); } -GD_PINVOKE_EXPORT void godot_icall_Internal_EditorNodeShowScriptScreen() { +void godot_icall_Internal_EditorNodeShowScriptScreen() { EditorNode::get_singleton()->call("_editor_select", EditorNode::EDITOR_SCRIPT); } -GD_PINVOKE_EXPORT void godot_icall_Internal_EditorRunPlay() { +void godot_icall_Internal_EditorRunPlay() { EditorNode::get_singleton()->run_play(); } -GD_PINVOKE_EXPORT void godot_icall_Internal_EditorRunStop() { +void godot_icall_Internal_EditorRunStop() { EditorNode::get_singleton()->run_stop(); } -GD_PINVOKE_EXPORT void godot_icall_Internal_ScriptEditorDebugger_ReloadScripts() { +void godot_icall_Internal_ScriptEditorDebugger_ReloadScripts() { EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton(); if (ed) { ed->reload_scripts(); } } -GD_PINVOKE_EXPORT void godot_icall_Internal_CodeCompletionRequest(int32_t p_kind, const godot_string *p_script_file, godot_packed_array *r_ret) { +void godot_icall_Internal_CodeCompletionRequest(int32_t p_kind, const godot_string *p_script_file, godot_packed_array *r_ret) { String script_file = *reinterpret_cast(p_script_file); PackedStringArray suggestions = gdmono::get_code_completion((gdmono::CompletionKind)p_kind, script_file); memnew_placement(r_ret, PackedStringArray(suggestions)); } -GD_PINVOKE_EXPORT float godot_icall_Globals_EditorScale() { +float godot_icall_Globals_EditorScale() { return EDSCALE; } -GD_PINVOKE_EXPORT void godot_icall_Globals_GlobalDef(const godot_string *p_setting, const godot_variant *p_default_value, bool p_restart_if_changed, godot_variant *r_result) { +void godot_icall_Globals_GlobalDef(const godot_string *p_setting, const godot_variant *p_default_value, bool p_restart_if_changed, godot_variant *r_result) { String setting = *reinterpret_cast(p_setting); Variant default_value = *reinterpret_cast(p_default_value); Variant result = _GLOBAL_DEF(setting, default_value, (bool)p_restart_if_changed); memnew_placement(r_result, Variant(result)); } -GD_PINVOKE_EXPORT void godot_icall_Globals_EditorDef(const godot_string *p_setting, const godot_variant *p_default_value, bool p_restart_if_changed, godot_variant *r_result) { +void godot_icall_Globals_EditorDef(const godot_string *p_setting, const godot_variant *p_default_value, bool p_restart_if_changed, godot_variant *r_result) { String setting = *reinterpret_cast(p_setting); Variant default_value = *reinterpret_cast(p_default_value); Variant result = _EDITOR_DEF(setting, default_value, (bool)p_restart_if_changed); memnew_placement(r_result, Variant(result)); } -GD_PINVOKE_EXPORT void godot_icall_Globals_EditorShortcut(const godot_string *p_setting, godot_variant *r_result) { +void godot_icall_Globals_EditorShortcut(const godot_string *p_setting, godot_variant *r_result) { String setting = *reinterpret_cast(p_setting); Ref result = ED_GET_SHORTCUT(setting); memnew_placement(r_result, Variant(result)); } -GD_PINVOKE_EXPORT void godot_icall_Globals_TTR(const godot_string *p_text, godot_string *r_dest) { +void godot_icall_Globals_TTR(const godot_string *p_text, godot_string *r_dest) { String text = *reinterpret_cast(p_text); memnew_placement(r_dest, String(TTR(text))); } -GD_PINVOKE_EXPORT void godot_icall_Utils_OS_GetPlatformName(godot_string *r_dest) { +void godot_icall_Utils_OS_GetPlatformName(godot_string *r_dest) { String os_name = OS::get_singleton()->get_name(); memnew_placement(r_dest, String(os_name)); } -GD_PINVOKE_EXPORT bool godot_icall_Utils_OS_UnixFileHasExecutableAccess(const godot_string *p_file_path) { +bool godot_icall_Utils_OS_UnixFileHasExecutableAccess(const godot_string *p_file_path) { #ifdef UNIX_ENABLED String file_path = *reinterpret_cast(p_file_path); return access(file_path.utf8().get_data(), X_OK) == 0; @@ -237,7 +223,9 @@ GD_PINVOKE_EXPORT bool godot_icall_Utils_OS_UnixFileHasExecutableAccess(const go } #endif -void *godotsharp_editor_pinvoke_funcs[28] = { +// The order in this array must match the declaration order of +// the methods in 'GodotTools/Internals/Internal.cs'. +static const void *unmanaged_callbacks[]{ (void *)godot_icall_GodotSharpDirs_ResMetadataDir, (void *)godot_icall_GodotSharpDirs_MonoUserDir, (void *)godot_icall_GodotSharpDirs_BuildLogsDirs, @@ -267,3 +255,8 @@ void *godotsharp_editor_pinvoke_funcs[28] = { (void *)godot_icall_Utils_OS_GetPlatformName, (void *)godot_icall_Utils_OS_UnixFileHasExecutableAccess, }; + +const void **godotsharp::get_editor_interop_funcs(int32_t &r_size) { + r_size = sizeof(unmanaged_callbacks); + return unmanaged_callbacks; +} diff --git a/modules/mono/editor/editor_internal_calls.h b/modules/mono/editor/editor_internal_calls.h index 8262ac211a..35391f1f04 100644 --- a/modules/mono/editor/editor_internal_calls.h +++ b/modules/mono/editor/editor_internal_calls.h @@ -31,6 +31,10 @@ #ifndef EDITOR_INTERNAL_CALLS_H #define EDITOR_INTERNAL_CALLS_H -void register_editor_internal_calls(); +#include "core/typedefs.h" + +namespace godotsharp { +const void **get_editor_interop_funcs(int32_t &r_size); +} #endif // EDITOR_INTERNAL_CALLS_H -- cgit v1.2.3