summaryrefslogtreecommitdiff
path: root/modules/mono/editor
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/editor')
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Shared/GenerateGodotNupkgsVersions.targets4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Shared/GodotTools.Shared.csproj2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs10
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/EditorProgress.cs14
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs22
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs14
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs10
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs6
-rw-r--r--modules/mono/editor/bindings_generator.cpp181
-rw-r--r--modules/mono/editor/bindings_generator.h23
10 files changed, 163 insertions, 123 deletions
diff --git a/modules/mono/editor/GodotTools/GodotTools.Shared/GenerateGodotNupkgsVersions.targets b/modules/mono/editor/GodotTools/GodotTools.Shared/GenerateGodotNupkgsVersions.targets
index aab2d73bdd..4baae77b34 100644
--- a/modules/mono/editor/GodotTools/GodotTools.Shared/GenerateGodotNupkgsVersions.targets
+++ b/modules/mono/editor/GodotTools/GodotTools.Shared/GenerateGodotNupkgsVersions.targets
@@ -8,8 +8,8 @@
</Target>
<Target Name="GenerateGodotNupkgsVersionsFile"
- DependsOnTargets="PrepareForBuild;_GenerateGodotNupkgsVersionsFile"
- BeforeTargets="BeforeCompile;CoreCompile">
+ DependsOnTargets="_GenerateGodotNupkgsVersionsFile"
+ BeforeTargets="PrepareForBuild;CompileDesignTime;BeforeCompile;CoreCompile">
<ItemGroup>
<Compile Include="$(GeneratedGodotNupkgsVersionsFile)" />
<FileWrites Include="$(GeneratedGodotNupkgsVersionsFile)" />
diff --git a/modules/mono/editor/GodotTools/GodotTools.Shared/GodotTools.Shared.csproj b/modules/mono/editor/GodotTools/GodotTools.Shared/GodotTools.Shared.csproj
index 4b058a5daa..7d8b83d5f0 100644
--- a/modules/mono/editor/GodotTools/GodotTools.Shared/GodotTools.Shared.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools.Shared/GodotTools.Shared.csproj
@@ -1,6 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
+ <!-- Specify compile items manually to avoid including dangling generated items. -->
+ <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>
<Import Project="GenerateGodotNupkgsVersions.targets" />
</Project>
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
index 25c2e4ab59..d8ebe762e1 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
@@ -233,11 +233,11 @@ namespace GodotTools.Export
}
}
- var initialAssemblies = assemblies.Duplicate();
- godot_dictionary initialAssembliesAux = ((Godot.Collections.Dictionary)initialAssemblies).NativeValue;
- using godot_string buildConfigAux = Marshaling.mono_string_to_godot(buildConfig);
- using godot_string bclDirAux = Marshaling.mono_string_to_godot(bclDir);
- godot_dictionary assembliesAux = ((Godot.Collections.Dictionary)assemblies).NativeValue;
+ // var initialAssemblies = assemblies.Duplicate();
+ // godot_dictionary initialAssembliesAux = ((Godot.Collections.Dictionary)initialAssemblies).NativeValue;
+ // using godot_string buildConfigAux = Marshaling.ConvertStringToNative(buildConfig);
+ // using godot_string bclDirAux = Marshaling.ConvertStringToNative(bclDir);
+ // godot_dictionary assembliesAux = ((Godot.Collections.Dictionary)assemblies).NativeValue;
// TODO
throw new NotImplementedException();
//internal_GetExportedAssemblyDependencies(initialAssembliesAux, buildConfigAux, bclDirAux, ref assembliesAux);
diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/EditorProgress.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/EditorProgress.cs
index 7d2eb2d869..8f39ad063e 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/EditorProgress.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Internals/EditorProgress.cs
@@ -12,8 +12,8 @@ namespace GodotTools.Internals
public EditorProgress(string task, string label, int amount, bool canCancel = false)
{
Task = task;
- using godot_string taskIn = Marshaling.mono_string_to_godot(task);
- using godot_string labelIn = Marshaling.mono_string_to_godot(label);
+ using godot_string taskIn = Marshaling.ConvertStringToNative(task);
+ using godot_string labelIn = Marshaling.ConvertStringToNative(label);
Internal.godot_icall_EditorProgress_Create(taskIn, labelIn, amount, canCancel);
}
@@ -27,22 +27,22 @@ namespace GodotTools.Internals
public void Dispose()
{
- using godot_string taskIn = Marshaling.mono_string_to_godot(Task);
+ using godot_string taskIn = Marshaling.ConvertStringToNative(Task);
Internal.godot_icall_EditorProgress_Dispose(taskIn);
GC.SuppressFinalize(this);
}
public void Step(string state, int step = -1, bool forceRefresh = true)
{
- using godot_string taskIn = Marshaling.mono_string_to_godot(Task);
- using godot_string stateIn = Marshaling.mono_string_to_godot(state);
+ using godot_string taskIn = Marshaling.ConvertStringToNative(Task);
+ using godot_string stateIn = Marshaling.ConvertStringToNative(state);
Internal.godot_icall_EditorProgress_Step(taskIn, stateIn, step, forceRefresh);
}
public bool TryStep(string state, int step = -1, bool forceRefresh = true)
{
- using godot_string taskIn = Marshaling.mono_string_to_godot(Task);
- using godot_string stateIn = Marshaling.mono_string_to_godot(state);
+ using godot_string taskIn = Marshaling.ConvertStringToNative(Task);
+ using godot_string stateIn = Marshaling.ConvertStringToNative(state);
return Internal.godot_icall_EditorProgress_Step(taskIn, stateIn, step, forceRefresh);
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs
index 3b65263aa9..acb7cc3ab0 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs
@@ -10,37 +10,37 @@ namespace GodotTools.Internals
public static unsafe object GlobalDef(string setting, object defaultValue, bool restartIfChanged = false)
{
- using godot_string settingIn = Marshaling.mono_string_to_godot(setting);
- using godot_variant defaultValueIn = Marshaling.mono_object_to_variant(defaultValue);
+ using godot_string settingIn = Marshaling.ConvertStringToNative(setting);
+ using godot_variant defaultValueIn = Marshaling.ConvertManagedObjectToVariant(defaultValue);
Internal.godot_icall_Globals_GlobalDef(settingIn, defaultValueIn, restartIfChanged, out godot_variant result);
using (result)
- return Marshaling.variant_to_mono_object(&result);
+ return Marshaling.ConvertVariantToManagedObject(result);
}
public static unsafe object EditorDef(string setting, object defaultValue, bool restartIfChanged = false)
{
- using godot_string settingIn = Marshaling.mono_string_to_godot(setting);
- using godot_variant defaultValueIn = Marshaling.mono_object_to_variant(defaultValue);
+ using godot_string settingIn = Marshaling.ConvertStringToNative(setting);
+ using godot_variant defaultValueIn = Marshaling.ConvertManagedObjectToVariant(defaultValue);
Internal.godot_icall_Globals_EditorDef(settingIn, defaultValueIn, restartIfChanged, out godot_variant result);
using (result)
- return Marshaling.variant_to_mono_object(&result);
+ return Marshaling.ConvertVariantToManagedObject(result);
}
- public static unsafe object EditorShortcut(string setting)
+ public static object EditorShortcut(string setting)
{
- using godot_string settingIn = Marshaling.mono_string_to_godot(setting);
+ using godot_string settingIn = Marshaling.ConvertStringToNative(setting);
Internal.godot_icall_Globals_EditorShortcut(settingIn, out godot_variant result);
using (result)
- return Marshaling.variant_to_mono_object(&result);
+ return Marshaling.ConvertVariantToManagedObject(result);
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
public static string TTR(this string text)
{
- using godot_string textIn = Marshaling.mono_string_to_godot(text);
+ using godot_string textIn = Marshaling.ConvertStringToNative(text);
Internal.godot_icall_Globals_TTR(textIn, out godot_string dest);
using (dest)
- return Marshaling.mono_string_from_godot(dest);
+ return Marshaling.ConvertStringToManaged(dest);
}
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs
index 9011662248..eca7da07c8 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs
@@ -11,7 +11,7 @@ namespace GodotTools.Internals
{
Internal.godot_icall_GodotSharpDirs_ResMetadataDir(out godot_string dest);
using (dest)
- return Marshaling.mono_string_from_godot(dest);
+ return Marshaling.ConvertStringToManaged(dest);
}
}
@@ -21,7 +21,7 @@ namespace GodotTools.Internals
{
Internal.godot_icall_GodotSharpDirs_ResTempAssembliesBaseDir(out godot_string dest);
using (dest)
- return Marshaling.mono_string_from_godot(dest);
+ return Marshaling.ConvertStringToManaged(dest);
}
}
@@ -31,7 +31,7 @@ namespace GodotTools.Internals
{
Internal.godot_icall_GodotSharpDirs_MonoUserDir(out godot_string dest);
using (dest)
- return Marshaling.mono_string_from_godot(dest);
+ return Marshaling.ConvertStringToManaged(dest);
}
}
@@ -41,7 +41,7 @@ namespace GodotTools.Internals
{
Internal.godot_icall_GodotSharpDirs_BuildLogsDirs(out godot_string dest);
using (dest)
- return Marshaling.mono_string_from_godot(dest);
+ return Marshaling.ConvertStringToManaged(dest);
}
}
@@ -51,7 +51,7 @@ namespace GodotTools.Internals
{
Internal.godot_icall_GodotSharpDirs_ProjectSlnPath(out godot_string dest);
using (dest)
- return Marshaling.mono_string_from_godot(dest);
+ return Marshaling.ConvertStringToManaged(dest);
}
}
@@ -61,7 +61,7 @@ namespace GodotTools.Internals
{
Internal.godot_icall_GodotSharpDirs_ProjectCsProjPath(out godot_string dest);
using (dest)
- return Marshaling.mono_string_from_godot(dest);
+ return Marshaling.ConvertStringToManaged(dest);
}
}
@@ -71,7 +71,7 @@ namespace GodotTools.Internals
{
Internal.godot_icall_GodotSharpDirs_DataEditorToolsDir(out godot_string dest);
using (dest)
- return Marshaling.mono_string_from_godot(dest);
+ return Marshaling.ConvertStringToManaged(dest);
}
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
index 8e4eb031db..7b39f8ecdb 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
@@ -18,7 +18,7 @@ namespace GodotTools.Internals
{
godot_icall_Internal_FullExportTemplatesDir(out godot_string dest);
using (dest)
- return Marshaling.mono_string_from_godot(dest);
+ return Marshaling.ConvertStringToManaged(dest);
}
}
@@ -26,7 +26,7 @@ namespace GodotTools.Internals
public static bool IsMacOSAppBundleInstalled(string bundleId)
{
- using godot_string bundleIdIn = Marshaling.mono_string_to_godot(bundleId);
+ using godot_string bundleIdIn = Marshaling.ConvertStringToNative(bundleId);
return godot_icall_Internal_IsMacOSAppBundleInstalled(bundleIdIn);
}
@@ -53,7 +53,7 @@ namespace GodotTools.Internals
{
godot_icall_Internal_MonoWindowsInstallRoot(out godot_string dest);
using (dest)
- return Marshaling.mono_string_from_godot(dest);
+ return Marshaling.ConvertStringToManaged(dest);
}
}
@@ -67,10 +67,10 @@ namespace GodotTools.Internals
public static unsafe string[] CodeCompletionRequest(CodeCompletionRequest.CompletionKind kind,
string scriptFile)
{
- using godot_string scriptFileIn = Marshaling.mono_string_to_godot(scriptFile);
+ using godot_string scriptFileIn = Marshaling.ConvertStringToNative(scriptFile);
godot_icall_Internal_CodeCompletionRequest((int)kind, scriptFileIn, out godot_packed_string_array res);
using (res)
- return Marshaling.PackedStringArray_to_mono_array(&res);
+ return Marshaling.ConvertNativePackedStringArrayToSystemArray(res);
}
#region Internal
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
index d9b5942237..db77a71c2f 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
@@ -63,7 +63,7 @@ namespace GodotTools.Utils
Internal.godot_icall_Utils_OS_GetPlatformName(out godot_string dest);
using (dest)
{
- string platformName = Marshaling.mono_string_from_godot(dest);
+ string platformName = Marshaling.ConvertStringToManaged(dest);
return name.Equals(platformName, StringComparison.OrdinalIgnoreCase);
}
}
@@ -73,7 +73,7 @@ namespace GodotTools.Utils
Internal.godot_icall_Utils_OS_GetPlatformName(out godot_string dest);
using (dest)
{
- string platformName = Marshaling.mono_string_from_godot(dest);
+ string platformName = Marshaling.ConvertStringToManaged(dest);
return names.Any(p => p.Equals(platformName, StringComparison.OrdinalIgnoreCase));
}
}
@@ -185,7 +185,7 @@ namespace GodotTools.Utils
return searchDirs.Select(dir => Path.Combine(dir, name))
.FirstOrDefault(path =>
{
- using godot_string pathIn = Marshaling.mono_string_to_godot(path);
+ using godot_string pathIn = Marshaling.ConvertStringToNative(path);
return File.Exists(path) && Internal.godot_icall_Utils_OS_UnixFileHasExecutableAccess(pathIn);
});
}
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 1d4750a2a5..cce00a6ae1 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -101,12 +101,12 @@ StringBuilder &operator<<(StringBuilder &r_sb, const char *p_cstring) {
#define C_METHOD_ENGINE_GET_SINGLETON C_NS_MONOUTILS ".EngineGetSingleton"
#define C_NS_MONOMARSHAL "Marshaling"
-#define C_METHOD_MANAGED_TO_VARIANT C_NS_MONOMARSHAL ".mono_object_to_variant"
-#define C_METHOD_MANAGED_FROM_VARIANT C_NS_MONOMARSHAL ".variant_to_mono_object"
-#define C_METHOD_MONOSTR_TO_GODOT C_NS_MONOMARSHAL ".mono_string_to_godot"
-#define C_METHOD_MONOSTR_FROM_GODOT C_NS_MONOMARSHAL ".mono_string_from_godot"
-#define C_METHOD_MONOARRAY_TO(m_type) C_NS_MONOMARSHAL ".mono_array_to_" #m_type
-#define C_METHOD_MONOARRAY_FROM(m_type) C_NS_MONOMARSHAL "." #m_type "_to_mono_array"
+#define C_METHOD_MANAGED_TO_VARIANT C_NS_MONOMARSHAL ".ConvertManagedObjectToVariant"
+#define C_METHOD_MANAGED_FROM_VARIANT C_NS_MONOMARSHAL ".ConvertVariantToManagedObject"
+#define C_METHOD_MONOSTR_TO_GODOT C_NS_MONOMARSHAL ".ConvertStringToNative"
+#define C_METHOD_MONOSTR_FROM_GODOT C_NS_MONOMARSHAL ".ConvertStringToManaged"
+#define C_METHOD_MONOARRAY_TO(m_type) C_NS_MONOMARSHAL ".ConvertSystemArrayToNative" #m_type
+#define C_METHOD_MONOARRAY_FROM(m_type) C_NS_MONOMARSHAL ".ConvertNative" #m_type "ToSystemArray"
#define C_METHOD_MANAGED_TO_CALLABLE C_NS_MONOMARSHAL ".ConvertCallableToNative"
#define C_METHOD_MANAGED_FROM_CALLABLE C_NS_MONOMARSHAL ".ConvertCallableToManaged"
#define C_METHOD_MANAGED_TO_SIGNAL C_NS_MONOMARSHAL ".ConvertSignalToNative"
@@ -122,7 +122,7 @@ void BindingsGenerator::TypeInterface::postsetup_enum_type(BindingsGenerator::Ty
// any of the changes done here to the 'uint32_t' type interface as well.
r_enum_itype.cs_type = r_enum_itype.proxy_name;
- r_enum_itype.cs_in = "(int)%s";
+ r_enum_itype.cs_in_expr = "(int)%0";
r_enum_itype.cs_out = "%5return (%2)%0(%1);";
{
@@ -391,23 +391,23 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append(tag);
xml_output.append("</c>");
} else if (tag == "PackedByteArray") {
- xml_output.append("<see cref=\"T:byte[]\"/>");
+ xml_output.append("<see cref=\"byte\"/>[]");
} else if (tag == "PackedInt32Array") {
- xml_output.append("<see cref=\"T:int[]\"/>");
+ xml_output.append("<see cref=\"int\"/>[]");
} else if (tag == "PackedInt64Array") {
- xml_output.append("<see cref=\"T:long[]\"/>");
+ xml_output.append("<see cref=\"long\"/>[]");
} else if (tag == "PackedFloat32Array") {
- xml_output.append("<see cref=\"T:float[]\"/>");
+ xml_output.append("<see cref=\"float\"/>[]");
} else if (tag == "PackedFloat64Array") {
- xml_output.append("<see cref=\"T:double[]\"/>");
+ xml_output.append("<see cref=\"double\"/>[]");
} else if (tag == "PackedStringArray") {
- xml_output.append("<see cref=\"T:string[]\"/>");
+ xml_output.append("<see cref=\"string\"/>[]");
} else if (tag == "PackedVector2Array") {
- xml_output.append("<see cref=\"T:" BINDINGS_NAMESPACE ".Vector2[]\"/>");
+ xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".Vector2\"/>[]");
} else if (tag == "PackedVector3Array") {
- xml_output.append("<see cref=\"T:" BINDINGS_NAMESPACE ".Vector3[]\"/>");
+ xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".Vector3\"/>[]");
} else if (tag == "PackedColorArray") {
- xml_output.append("<see cref=\"T:" BINDINGS_NAMESPACE ".Color[]\"/>");
+ xml_output.append("<see cref=\"" BINDINGS_NAMESPACE ".Color\"/>[]");
} else {
const TypeInterface *target_itype = _get_type_or_null(TypeReference(tag));
@@ -1380,6 +1380,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
"#pragma warning disable CS1573 // Disable warning: "
"'Parameter has no matching param tag in the XML comment'\n");
+ output.append("\n#nullable disable\n");
+
output.append("\nnamespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK);
const DocData::ClassDoc *class_doc = itype.class_doc;
@@ -1413,20 +1415,17 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
}
output.append(itype.proxy_name);
- if (itype.is_singleton) {
- output.append("\n");
- } else if (is_derived_type) {
+ if (is_derived_type && !itype.is_singleton) {
if (obj_types.has(itype.base_name)) {
output.append(" : ");
output.append(obj_types[itype.base_name].proxy_name);
- output.append("\n");
} else {
ERR_PRINT("Base type '" + itype.base_name.operator String() + "' does not exist, for class '" + itype.name + "'.");
return ERR_INVALID_DATA;
}
}
- output.append(INDENT1 "{");
+ output.append("\n" INDENT1 "{");
// Add constants
@@ -1546,7 +1545,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
// Add native constructor static field
output << MEMBER_BEGIN << "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n"
- << INDENT2 "private static unsafe readonly delegate* unmanaged<IntPtr> "
+ << INDENT2 "private static readonly unsafe delegate* unmanaged<IntPtr> "
<< CS_STATIC_FIELD_NATIVE_CTOR " = " ICALL_CLASSDB_GET_CONSTRUCTOR
<< "(" BINDINGS_NATIVE_NAME_FIELD ");\n";
}
@@ -1608,7 +1607,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
// TODO: string is ok for now. But should be replaced with StringName in the future for performance.
output << MEMBER_BEGIN "internal " << (is_derived_type ? "override" : "virtual")
- << " unsafe bool InternalGodotScriptCall(string method, godot_variant** args, "
+ << " bool InternalGodotScriptCall(string method, NativeVariantPtrArgs args, "
<< "int argCount, out godot_variant ret)\n"
<< INDENT2 "{\n";
@@ -1646,10 +1645,10 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
if (arg_type->cname == name_cache.type_Array_generic || arg_type->cname == name_cache.type_Dictionary_generic) {
String arg_cs_type = arg_type->cs_type + _get_generic_type_parameters(*arg_type, iarg.type.generic_type_parameters);
- output << "new " << arg_cs_type << "((" << arg_type->cs_type << ")Marshaling.variant_to_mono_object_of_type(args["
+ output << "new " << arg_cs_type << "((" << arg_type->cs_type << ")Marshaling.ConvertVariantToManagedObjectOfType(args["
<< itos(i) << "], typeof(" << arg_type->cs_type << ")))";
} else {
- output << "(" << arg_type->cs_type << ")Marshaling.variant_to_mono_object_of_type(args["
+ output << "(" << arg_type->cs_type << ")Marshaling.ConvertVariantToManagedObjectOfType(args["
<< itos(i) << "], typeof(" << arg_type->cs_type << "))";
}
}
@@ -1658,7 +1657,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
if (imethod.return_type.cname != name_cache.type_void) {
// TODO: static marshaling (no reflection, no runtime type checks)
- output << INDENT4 "ret = Marshaling.mono_object_to_variant(retBoxed);\n";
+ output << INDENT4 "ret = Marshaling.ConvertManagedObjectToVariant(retBoxed);\n";
output << INDENT4 "return true;\n";
} else {
output << INDENT4 "ret = default;\n";
@@ -1858,11 +1857,17 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
String arguments_sig;
StringBuilder cs_in_statements;
- bool cs_in_is_unsafe = false;
+ bool cs_in_expr_is_unsafe = false;
String icall_params = method_bind_field;
+
if (!p_imethod.is_static) {
- icall_params += ", " + sformat(p_itype.cs_in, "this");
+ if (p_itype.cs_in.size()) {
+ cs_in_statements << sformat(p_itype.cs_in, p_itype.c_type, "this",
+ String(), String(), String(), INDENT3);
+ }
+
+ icall_params += ", " + sformat(p_itype.cs_in_expr, "this");
}
StringBuilder default_args_doc;
@@ -1924,10 +1929,10 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
if (iarg.default_argument.size() && iarg.def_param_mode != ArgumentInterface::CONSTANT) {
// The default value of an argument must be constant. Otherwise we make it Nullable and do the following:
// Type arg_in = arg.HasValue ? arg.Value : <non-const default value>;
- String arg_in = iarg.name;
- arg_in += "_in";
+ String arg_or_defval_local = iarg.name;
+ arg_or_defval_local += "OrDefVal";
- cs_in_statements << INDENT3 << arg_cs_type << " " << arg_in << " = " << iarg.name;
+ cs_in_statements << INDENT3 << arg_cs_type << " " << arg_or_defval_local << " = " << iarg.name;
if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL) {
cs_in_statements << ".HasValue ? ";
@@ -1952,7 +1957,16 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
cs_in_statements << def_arg << ";\n";
- icall_params += arg_type->cs_in.is_empty() ? arg_in : sformat(arg_type->cs_in, arg_in);
+ if (arg_type->cs_in.size()) {
+ cs_in_statements << sformat(arg_type->cs_in, arg_type->c_type, arg_or_defval_local,
+ String(), String(), String(), INDENT3);
+ }
+
+ if (arg_type->cs_in_expr.is_empty()) {
+ icall_params += arg_or_defval_local;
+ } else {
+ icall_params += sformat(arg_type->cs_in_expr, arg_or_defval_local, arg_type->c_type);
+ }
// Apparently the name attribute must not include the @
String param_tag_name = iarg.name.begins_with("@") ? iarg.name.substr(1, iarg.name.length()) : iarg.name;
@@ -1961,10 +1975,15 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
default_args_doc.append(MEMBER_BEGIN "/// <param name=\"" + param_tag_name + "\">If the parameter is null, then the default value is <c>" + param_def_arg + "</c>.</param>");
} else {
- icall_params += arg_type->cs_in.is_empty() ? iarg.name : sformat(arg_type->cs_in, iarg.name);
+ if (arg_type->cs_in.size()) {
+ cs_in_statements << sformat(arg_type->cs_in, arg_type->c_type, iarg.name,
+ String(), String(), String(), INDENT3);
+ }
+
+ icall_params += arg_type->cs_in_expr.is_empty() ? iarg.name : sformat(arg_type->cs_in_expr, iarg.name, arg_type->c_type);
}
- cs_in_is_unsafe |= arg_type->cs_in_is_unsafe;
+ cs_in_expr_is_unsafe |= arg_type->cs_in_expr_is_unsafe;
}
// Generate method
@@ -2034,7 +2053,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
p_output.append("virtual ");
}
- if (cs_in_is_unsafe) {
+ if (cs_in_expr_is_unsafe) {
p_output.append("unsafe ");
}
@@ -2082,7 +2101,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
im_call += ".";
im_call += im_icall->name;
- if (p_imethod.arguments.size()) {
+ if (p_imethod.arguments.size() && cs_in_statements.get_string_length() > 0) {
p_output.append(cs_in_statements.as_string());
}
@@ -2319,8 +2338,6 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall,
auto generate_call_and_return_stmts = [&](const char *base_indent) {
if (p_icall.is_vararg) {
- r_output << base_indent << "godot_variant_call_error vcall_error;\n";
-
// MethodBind Call
r_output << base_indent;
@@ -2341,12 +2358,12 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall,
r_output << C_CLASS_NATIVE_FUNCS ".godotsharp_method_bind_call("
<< CS_PARAM_METHODBIND ", " << (p_icall.is_static ? "IntPtr.Zero" : CS_PARAM_INSTANCE)
<< ", " << (p_icall.get_arguments_count() ? "(godot_variant**)" C_LOCAL_PTRCALL_ARGS : "null")
- << ", total_length, &vcall_error);\n";
+ << ", total_length, out _);\n";
if (!ret_void) {
if (return_type->cname != name_cache.type_Variant) {
if (return_type->cname == name_cache.enum_Error) {
- r_output << base_indent << C_LOCAL_RET " = VariantUtils.ConvertToInt64(&" C_LOCAL_VARARG_RET ");\n";
+ r_output << base_indent << C_LOCAL_RET " = VariantUtils.ConvertToInt64(" C_LOCAL_VARARG_RET ");\n";
} else {
// TODO: Use something similar to c_in_vararg (see usage above, with error if not implemented)
CRASH_NOW_MSG("Custom VarArg return type not implemented: " + return_type->name);
@@ -2384,9 +2401,9 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall,
r_output << INDENT3 "int vararg_length = " << vararg_arg << ".Length;\n"
<< INDENT3 "int total_length = " << real_argc_str << " + vararg_length;\n";
- r_output << INDENT3 "Span<godot_variant> varargs_span = vararg_length <= VarArgsSpanThreshold ?\n"
- << INDENT4 "stackalloc godot_variant[VarArgsSpanThreshold].Cleared() :\n"
- << INDENT4 "new godot_variant[vararg_length];\n";
+ r_output << INDENT3 "Span<godot_variant.movable> varargs_span = vararg_length <= VarArgsSpanThreshold ?\n"
+ << INDENT4 "stackalloc godot_variant.movable[VarArgsSpanThreshold].Cleared() :\n"
+ << INDENT4 "new godot_variant.movable[vararg_length];\n";
r_output << INDENT3 "Span<IntPtr> " C_LOCAL_PTRCALL_ARGS "_span = total_length <= VarArgsSpanThreshold ?\n"
<< INDENT4 "stackalloc IntPtr[VarArgsSpanThreshold] :\n"
@@ -2394,7 +2411,7 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall,
r_output << INDENT3 "using var variantSpanDisposer = new VariantSpanDisposer(varargs_span);\n";
- r_output << INDENT3 "fixed (godot_variant* varargs = &MemoryMarshal.GetReference(varargs_span))\n"
+ r_output << INDENT3 "fixed (godot_variant* varargs = &MemoryMarshal.GetReference(varargs_span).DangerousSelfRef)\n"
<< INDENT3 "fixed (IntPtr* " C_LOCAL_PTRCALL_ARGS " = "
"&MemoryMarshal.GetReference(" C_LOCAL_PTRCALL_ARGS "_span))\n"
<< OPEN_BLOCK_L3;
@@ -2678,14 +2695,14 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
itype.c_out = "%5return ";
itype.c_out += C_METHOD_UNMANAGED_GET_MANAGED;
- itype.c_out += itype.is_ref_counted ? "(%1._reference);\n" : "(%1);\n";
+ itype.c_out += itype.is_ref_counted ? "(%1.Reference);\n" : "(%1);\n";
itype.cs_type = itype.proxy_name;
if (itype.is_singleton) {
- itype.cs_in = "Object." CS_STATIC_METHOD_GETINSTANCE "(" CS_PROPERTY_SINGLETON ")";
+ itype.cs_in_expr = "Object." CS_STATIC_METHOD_GETINSTANCE "(" CS_PROPERTY_SINGLETON ")";
} else {
- itype.cs_in = "Object." CS_STATIC_METHOD_GETINSTANCE "(%0)";
+ itype.cs_in_expr = "Object." CS_STATIC_METHOD_GETINSTANCE "(%0)";
}
itype.cs_out = "%5return (%2)%0(%1);";
@@ -3128,8 +3145,13 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
case Variant::STRING_NAME:
case Variant::NODE_PATH:
if (r_iarg.type.cname == name_cache.type_StringName || r_iarg.type.cname == name_cache.type_NodePath) {
- r_iarg.default_argument = "(%s)\"" + r_iarg.default_argument + "\"";
- r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF;
+ if (r_iarg.default_argument.length() > 0) {
+ r_iarg.default_argument = "(%s)\"" + r_iarg.default_argument + "\"";
+ r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF;
+ } else {
+ // No need for a special `in` statement to change `null` to `""`. Marshaling takes care of this already.
+ r_iarg.default_argument = "null";
+ }
} else {
CRASH_COND(r_iarg.type.cname != name_cache.type_String);
r_iarg.default_argument = "\"" + r_iarg.default_argument + "\"";
@@ -3175,8 +3197,11 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
r_iarg.default_argument = "null";
break;
case Variant::DICTIONARY:
- r_iarg.default_argument = "new %s()";
- r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF;
+ ERR_FAIL_COND_V_MSG(!p_val.operator Dictionary().is_empty(), false,
+ "Default value of type 'Dictionary' must be an empty dictionary.");
+ // The [cs_in] expression already interprets null values as empty dictionaries.
+ r_iarg.default_argument = "null";
+ r_iarg.def_param_mode = ArgumentInterface::CONSTANT;
break;
case Variant::RID:
ERR_FAIL_COND_V_MSG(r_iarg.type.cname != name_cache.type_RID, false,
@@ -3188,8 +3213,11 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
r_iarg.default_argument = "default";
break;
case Variant::ARRAY:
- r_iarg.default_argument = "new %s { }";
- r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF;
+ ERR_FAIL_COND_V_MSG(!p_val.operator Array().is_empty(), false,
+ "Default value of type 'Array' must be an empty array.");
+ // The [cs_in] expression already interprets null values as empty arrays.
+ r_iarg.default_argument = "null";
+ r_iarg.def_param_mode = ArgumentInterface::CONSTANT;
break;
case Variant::PACKED_BYTE_ARRAY:
case Variant::PACKED_INT32_ARRAY:
@@ -3285,8 +3313,8 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype = TypeInterface::create_value_type(String(#m_type)); \
itype.c_type_in = #m_type "*"; \
itype.c_type_out = itype.cs_type; \
- itype.cs_in = "&%s"; \
- itype.cs_in_is_unsafe = true; \
+ itype.cs_in_expr = "&%0"; \
+ itype.cs_in_expr_is_unsafe = true; \
builtin_types.insert(itype.cname, itype); \
}
@@ -3311,7 +3339,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
// bool
itype = TypeInterface::create_value_type(String("bool"));
- itype.cs_in = "%s.ToGodotBool()";
+ itype.cs_in_expr = "%0.ToGodotBool()";
itype.cs_out = "%5return %0(%1).ToBool();";
itype.c_type = "godot_bool";
itype.c_type_in = itype.c_type;
@@ -3411,15 +3439,14 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.cname = itype.name;
itype.proxy_name = "StringName";
itype.cs_type = itype.proxy_name;
- itype.cs_in = "ref %0.NativeValue";
+ itype.cs_in_expr = "(%1)(%0?.NativeValue ?? default)";
// Cannot pass null StringName to ptrcall
- itype.c_in = "%5using %0 %1_in = " C_CLASS_NATIVE_FUNCS ".godotsharp_string_name_new_copy(%1);\n";
itype.c_out = "%5return %0.CreateTakingOwnershipOfDisposableValue(%1);\n";
- itype.c_arg_in = "&%s_in";
+ itype.c_arg_in = "&%s";
itype.c_type = "godot_string_name";
- itype.c_type_in = "ref " + itype.c_type;
+ itype.c_type_in = itype.c_type;
itype.c_type_out = itype.cs_type;
- itype.c_in_vararg = "%5using godot_variant %1_in = VariantUtils.CreateFromStringName(ref %1);\n";
+ itype.c_in_vararg = "%5using godot_variant %1_in = VariantUtils.CreateFromStringName(%1);\n";
itype.c_type_is_disposable_struct = false; // [c_out] takes ownership
itype.c_ret_needs_default_initialization = true;
builtin_types.insert(itype.cname, itype);
@@ -3430,13 +3457,12 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.cname = itype.name;
itype.proxy_name = "NodePath";
itype.cs_type = itype.proxy_name;
- itype.cs_in = "ref %0.NativeValue";
+ itype.cs_in_expr = "(%1)(%0?.NativeValue ?? default)";
// Cannot pass null NodePath to ptrcall
- itype.c_in = "%5using %0 %1_in = " C_CLASS_NATIVE_FUNCS ".godotsharp_node_path_new_copy(%1);\n";
itype.c_out = "%5return %0.CreateTakingOwnershipOfDisposableValue(%1);\n";
- itype.c_arg_in = "&%s_in";
+ itype.c_arg_in = "&%s";
itype.c_type = "godot_node_path";
- itype.c_type_in = "ref " + itype.c_type;
+ itype.c_type_in = itype.c_type;
itype.c_type_out = itype.cs_type;
itype.c_type_is_disposable_struct = false; // [c_out] takes ownership
itype.c_ret_needs_default_initialization = true;
@@ -3461,7 +3487,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.proxy_name = "object";
itype.cs_type = itype.proxy_name;
itype.c_in = "%5using %0 %1_in = " C_METHOD_MANAGED_TO_VARIANT "(%1);\n";
- itype.c_out = "%5return " C_METHOD_MANAGED_FROM_VARIANT "(&%1);\n";
+ itype.c_out = "%5return " C_METHOD_MANAGED_FROM_VARIANT "(%1);\n";
itype.c_arg_in = "&%s_in";
itype.c_type = "godot_variant";
itype.c_type_in = itype.cs_type;
@@ -3471,9 +3497,9 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
// Callable
itype = TypeInterface::create_value_type(String("Callable"));
- itype.cs_in = "ref %s";
+ itype.cs_in_expr = "ref %0";
itype.c_in = "%5using %0 %1_in = " C_METHOD_MANAGED_TO_CALLABLE "(ref %1);\n";
- itype.c_out = "%5return " C_METHOD_MANAGED_FROM_CALLABLE "(&%1);\n";
+ itype.c_out = "%5return " C_METHOD_MANAGED_FROM_CALLABLE "(in %1);\n";
itype.c_arg_in = "&%s_in";
itype.c_type = "godot_callable";
itype.c_type_in = "ref " + itype.cs_type;
@@ -3487,7 +3513,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.cname = itype.name;
itype.proxy_name = "SignalInfo";
itype.cs_type = itype.proxy_name;
- itype.cs_in = "ref %s";
+ itype.cs_in_expr = "ref %0";
itype.c_in = "%5using %0 %1_in = " C_METHOD_MANAGED_TO_SIGNAL "(ref %1);\n";
itype.c_out = "%5return " C_METHOD_MANAGED_FROM_SIGNAL "(&%1);\n";
itype.c_arg_in = "&%s_in";
@@ -3503,6 +3529,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.cname = itype.name;
itype.proxy_name = "object[]";
itype.cs_type = "params object[]";
+ itype.cs_in_expr = "%0 ?? Array.Empty<object>()";
// c_type, c_in and c_arg_in are hard-coded in the generator.
// c_out and c_type_out are not applicable to VarArg.
itype.c_arg_in = "&%s_in";
@@ -3517,7 +3544,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.proxy_name = #m_proxy_t "[]"; \
itype.cs_type = itype.proxy_name; \
itype.c_in = "%5using %0 %1_in = " C_METHOD_MONOARRAY_TO(m_type) "(%1);\n"; \
- itype.c_out = "%5return " C_METHOD_MONOARRAY_FROM(m_type) "(&%1);\n"; \
+ itype.c_out = "%5return " C_METHOD_MONOARRAY_FROM(m_type) "(%1);\n"; \
itype.c_arg_in = "&%s_in"; \
itype.c_type = #m_managed_type; \
itype.c_type_in = itype.proxy_name; \
@@ -3550,12 +3577,11 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.proxy_name = itype.name;
itype.type_parameter_count = 1;
itype.cs_type = BINDINGS_NAMESPACE_COLLECTIONS "." + itype.proxy_name;
- itype.cs_in = "ref %0.NativeValue";
- itype.c_in = "%5using %0 %1_in = " C_CLASS_NATIVE_FUNCS ".godotsharp_array_new_copy(%1);\n";
+ itype.cs_in_expr = "(%1)(%0 ?? new()).NativeValue";
itype.c_out = "%5return %0.CreateTakingOwnershipOfDisposableValue(%1);\n";
- itype.c_arg_in = "&%s_in";
+ itype.c_arg_in = "&%s";
itype.c_type = "godot_array";
- itype.c_type_in = "ref " + itype.c_type;
+ itype.c_type_in = itype.c_type;
itype.c_type_out = itype.cs_type;
itype.c_type_is_disposable_struct = false; // [c_out] takes ownership
itype.c_ret_needs_default_initialization = true;
@@ -3575,12 +3601,11 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.proxy_name = itype.name;
itype.type_parameter_count = 2;
itype.cs_type = BINDINGS_NAMESPACE_COLLECTIONS "." + itype.proxy_name;
- itype.cs_in = "ref %0.NativeValue";
- itype.c_in = "%5using %0 %1_in = " C_CLASS_NATIVE_FUNCS ".godotsharp_dictionary_new_copy(%1);\n";
+ itype.cs_in_expr = "(%1)(%0 ?? new()).NativeValue";
itype.c_out = "%5return %0.CreateTakingOwnershipOfDisposableValue(%1);\n";
- itype.c_arg_in = "&%s_in";
+ itype.c_arg_in = "&%s";
itype.c_type = "godot_dictionary";
- itype.c_type_in = "ref " + itype.c_type;
+ itype.c_type_in = itype.c_type;
itype.c_type_out = itype.cs_type;
itype.c_type_is_disposable_struct = false; // [c_out] takes ownership
itype.c_ret_needs_default_initialization = true;
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index c9eb8e6317..d53e67896e 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -265,9 +265,9 @@ class BindingsGenerator {
// --- C INTERFACE ---
/**
- * One or more statements that manipulate the parameter before being passed as argument of a ptrcall.
+ * One or more statements that transform the parameter before being passed as argument of a ptrcall.
* If the statement adds a local that must be passed as the argument instead of the parameter,
- * the name of that local must be specified with [c_arg_in].
+ * the expression with the name of that local must be specified with [c_arg_in].
* Formatting elements:
* %0: [c_type] of the parameter
* %1: name of the parameter
@@ -277,7 +277,7 @@ class BindingsGenerator {
String c_in;
/**
- * One or more statements that manipulate the parameter before being passed as argument of a vararg call.
+ * One or more statements that transform the parameter before being passed as argument of a vararg call.
* If the statement adds a local that must be passed as the argument instead of the parameter,
* the name of that local must be specified with [c_arg_in].
* Formatting elements:
@@ -348,10 +348,23 @@ class BindingsGenerator {
* An expression that overrides the way the parameter is passed to the internal call.
* If empty, the parameter is passed as is.
* Formatting elements:
- * %0 or %s: name of the parameter
+ * %0: name of the parameter
+ * %1: [c_type] of the parameter
+ */
+ String cs_in_expr;
+ bool cs_in_expr_is_unsafe = false;
+
+ /**
+ * One or more statements that transform the parameter before being passed to the internal call.
+ * If the statement adds a local that must be passed as the argument instead of the parameter,
+ * the expression with the name of that local must be specified with [cs_in_expr].
+ * Formatting elements:
+ * %0: [c_type] of the parameter
+ * %1: name of the parameter
+ * %2-4: reserved
+ * %5: indentation text
*/
String cs_in;
- bool cs_in_is_unsafe = false;
/**
* One or more statements that determine how a variable of this type is returned from a method.