summaryrefslogtreecommitdiff
path: root/modules/mono
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono')
-rw-r--r--modules/mono/Directory.Build.props3
-rw-r--r--modules/mono/SdkPackageVersions.props6
-rw-r--r--modules/mono/build_scripts/godot_net_sdk_build.py24
-rw-r--r--modules/mono/build_scripts/make_android_mono_config.py5
-rw-r--r--modules/mono/build_scripts/mono_configure.py10
-rw-r--r--modules/mono/class_db_api_json.cpp16
-rw-r--r--modules/mono/class_db_api_json.h4
-rw-r--r--modules/mono/config.py9
-rw-r--r--modules/mono/csharp_script.cpp191
-rw-r--r--modules/mono/csharp_script.h51
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk.sln18
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.csproj43
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.nuspec22
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk_PackageVersion.txt1
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props3
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets5
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs15
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs11
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Godot.SourceGenerators.Sample.csproj31
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs33
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs89
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.csproj40
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.props7
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs9
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs182
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs47
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Shared/GenerateGodotNupkgsVersions.targets6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs31
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs36
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs8
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs3
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs86
-rw-r--r--[-rwxr-xr-x]modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs0
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs48
-rw-r--r--[-rwxr-xr-x]modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs8
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs61
-rw-r--r--modules/mono/editor/bindings_generator.cpp369
-rw-r--r--modules/mono/editor/bindings_generator.h14
-rw-r--r--modules/mono/editor/code_completion.cpp19
-rw-r--r--modules/mono/editor/code_completion.h6
-rw-r--r--modules/mono/editor/editor_internal_calls.cpp186
-rw-r--r--modules/mono/editor/editor_internal_calls.h4
-rw-r--r--modules/mono/editor/godotsharp_export.cpp13
-rw-r--r--modules/mono/editor/godotsharp_export.h5
-rw-r--r--modules/mono/editor/script_class_parser.cpp753
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs22
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs9
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs15
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs162
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs27
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs8
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs21
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs10
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs65
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs65
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs222
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs3
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs20
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs7
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs32
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj6
-rw-r--r--modules/mono/glue/arguments_vector.h4
-rw-r--r--modules/mono/glue/base_object_glue.cpp32
-rw-r--r--modules/mono/glue/collections_glue.cpp110
-rw-r--r--modules/mono/glue/gd_glue.cpp57
-rw-r--r--modules/mono/glue/glue_header.h4
-rw-r--r--modules/mono/glue/nodepath_glue.cpp26
-rw-r--r--modules/mono/glue/rid_glue.cpp10
-rw-r--r--modules/mono/glue/scene_tree_glue.cpp8
-rw-r--r--modules/mono/glue/string_glue.cpp16
-rw-r--r--modules/mono/glue/string_name_glue.cpp12
-rw-r--r--modules/mono/godotsharp_defs.h4
-rw-r--r--modules/mono/godotsharp_dirs.cpp17
-rw-r--r--modules/mono/godotsharp_dirs.h5
-rw-r--r--modules/mono/managed_callable.cpp4
-rw-r--r--modules/mono/managed_callable.h4
-rw-r--r--modules/mono/mono_gc_handle.cpp4
-rw-r--r--modules/mono/mono_gc_handle.h5
-rw-r--r--modules/mono/mono_gd/android_mono_config.h4
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp36
-rw-r--r--modules/mono/mono_gd/gd_mono.h5
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.cpp121
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.h17
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.cpp15
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.h10
-rw-r--r--modules/mono/mono_gd/gd_mono_class.cpp22
-rw-r--r--modules/mono/mono_gd/gd_mono_class.h15
-rw-r--r--modules/mono/mono_gd/gd_mono_field.cpp329
-rw-r--r--modules/mono/mono_gd/gd_mono_field.h4
-rw-r--r--modules/mono/mono_gd/gd_mono_header.h4
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.cpp16
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.h6
-rw-r--r--modules/mono/mono_gd/gd_mono_log.cpp12
-rw-r--r--modules/mono/mono_gd/gd_mono_log.h8
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.cpp982
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.h49
-rw-r--r--modules/mono/mono_gd/gd_mono_method.cpp29
-rw-r--r--modules/mono/mono_gd/gd_mono_method.h15
-rw-r--r--modules/mono/mono_gd/gd_mono_method_thunk.h4
-rw-r--r--modules/mono/mono_gd/gd_mono_property.cpp11
-rw-r--r--modules/mono/mono_gd/gd_mono_property.h4
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp14
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h24
-rw-r--r--modules/mono/mono_gd/gd_mono_wasm_m2n.cpp (renamed from modules/mono/editor/script_class_parser.h)105
-rw-r--r--modules/mono/mono_gd/gd_mono_wasm_m2n.h263
-rw-r--r--modules/mono/mono_gd/i_mono_class_member.h4
-rw-r--r--modules/mono/mono_gd/managed_type.cpp4
-rw-r--r--modules/mono/mono_gd/managed_type.h4
-rw-r--r--modules/mono/mono_gd/support/android_support.cpp33
-rw-r--r--[-rwxr-xr-x]modules/mono/mono_gd/support/android_support.h5
-rw-r--r--[-rwxr-xr-x]modules/mono/mono_gd/support/ios_support.h5
-rw-r--r--modules/mono/mono_gd/support/ios_support.mm5
-rw-r--r--modules/mono/register_types.cpp4
-rw-r--r--modules/mono/register_types.h4
-rw-r--r--modules/mono/signal_awaiter_utils.cpp28
-rw-r--r--modules/mono/signal_awaiter_utils.h4
-rw-r--r--modules/mono/utils/macros.h5
-rw-r--r--modules/mono/utils/mono_reg_utils.cpp9
-rw-r--r--modules/mono/utils/mono_reg_utils.h4
-rw-r--r--modules/mono/utils/osx_utils.cpp4
-rw-r--r--modules/mono/utils/osx_utils.h4
-rw-r--r--modules/mono/utils/path_utils.cpp9
-rw-r--r--modules/mono/utils/path_utils.h5
-rw-r--r--modules/mono/utils/string_utils.cpp5
-rw-r--r--modules/mono/utils/string_utils.h4
130 files changed, 3011 insertions, 2823 deletions
diff --git a/modules/mono/Directory.Build.props b/modules/mono/Directory.Build.props
new file mode 100644
index 0000000000..fbf864b11b
--- /dev/null
+++ b/modules/mono/Directory.Build.props
@@ -0,0 +1,3 @@
+<Project>
+ <Import Project="$(MSBuildThisFileDirectory)\SdkPackageVersions.props" />
+</Project>
diff --git a/modules/mono/SdkPackageVersions.props b/modules/mono/SdkPackageVersions.props
new file mode 100644
index 0000000000..df3ebe581c
--- /dev/null
+++ b/modules/mono/SdkPackageVersions.props
@@ -0,0 +1,6 @@
+<Project>
+ <PropertyGroup>
+ <PackageVersion_Godot_NET_Sdk>4.0.0-dev5</PackageVersion_Godot_NET_Sdk>
+ <PackageVersion_Godot_SourceGenerators>4.0.0-dev2</PackageVersion_Godot_SourceGenerators>
+ </PropertyGroup>
+</Project>
diff --git a/modules/mono/build_scripts/godot_net_sdk_build.py b/modules/mono/build_scripts/godot_net_sdk_build.py
index 3bfba0f0f6..8c5a60d2db 100644
--- a/modules/mono/build_scripts/godot_net_sdk_build.py
+++ b/modules/mono/build_scripts/godot_net_sdk_build.py
@@ -21,6 +21,18 @@ def build_godot_net_sdk(source, target, env):
# No need to copy targets. The Godot.NET.Sdk csproj takes care of copying them.
+def get_nupkgs_versions(props_file):
+ import xml.etree.ElementTree as ET
+
+ tree = ET.parse(props_file)
+ root = tree.getroot()
+
+ return {
+ "Godot.NET.Sdk": root.find("./PropertyGroup/PackageVersion_Godot_NET_Sdk").text.strip(),
+ "Godot.SourceGenerators": root.find("./PropertyGroup/PackageVersion_Godot_SourceGenerators").text.strip(),
+ }
+
+
def build(env_mono):
assert env_mono["tools"]
@@ -30,14 +42,12 @@ def build(env_mono):
module_dir = os.getcwd()
- package_version_file = os.path.join(
- module_dir, "editor", "Godot.NET.Sdk", "Godot.NET.Sdk", "Godot.NET.Sdk_PackageVersion.txt"
- )
-
- with open(package_version_file, mode="r") as f:
- version = f.read().strip()
+ nupkgs_versions = get_nupkgs_versions(os.path.join(module_dir, "SdkPackageVersions.props"))
- target_filenames = ["Godot.NET.Sdk.%s.nupkg" % version]
+ target_filenames = [
+ "Godot.NET.Sdk.%s.nupkg" % nupkgs_versions["Godot.NET.Sdk"],
+ "Godot.SourceGenerators.%s.nupkg" % nupkgs_versions["Godot.SourceGenerators"],
+ ]
targets = [os.path.join(nupkgs_dir, filename) for filename in target_filenames]
diff --git a/modules/mono/build_scripts/make_android_mono_config.py b/modules/mono/build_scripts/make_android_mono_config.py
index d276d7d886..28494bff6e 100644
--- a/modules/mono/build_scripts/make_android_mono_config.py
+++ b/modules/mono/build_scripts/make_android_mono_config.py
@@ -32,17 +32,16 @@ namespace {
static const int config_compressed_size = %d;
static const int config_uncompressed_size = %d;
static const unsigned char config_compressed_data[] = { %s };
-
} // namespace
String get_godot_android_mono_config() {
Vector<uint8_t> data;
data.resize(config_uncompressed_size);
uint8_t* w = data.ptrw();
- Compression::decompress(w.ptr(), config_uncompressed_size, config_compressed_data,
+ Compression::decompress(w, config_uncompressed_size, config_compressed_data,
config_compressed_size, Compression::MODE_DEFLATE);
String s;
- if (s.parse_utf8((const char *)w.ptr(), data.size())) {
+ if (s.parse_utf8((const char *)w, data.size())) {
ERR_FAIL_V(String());
}
return s;
diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py
index 6057004166..309abfbff7 100644
--- a/modules/mono/build_scripts/mono_configure.py
+++ b/modules/mono/build_scripts/mono_configure.py
@@ -97,6 +97,7 @@ def configure(env, env_mono):
copy_mono_root = env["copy_mono_root"]
mono_prefix = env["mono_prefix"]
+ mono_bcl = env["mono_bcl"]
mono_lib_names = ["mono-2.0-sgen", "monosgen-2.0"]
@@ -262,7 +263,8 @@ def configure(env, env_mono):
env_mono.Append(CPPDEFINES=["_REENTRANT"])
if mono_static:
- env.Append(LINKFLAGS=["-rdynamic"])
+ if not is_javascript:
+ env.Append(LINKFLAGS=["-rdynamic"])
mono_lib_file = os.path.join(mono_lib_path, "lib" + mono_lib + ".a")
@@ -397,7 +399,7 @@ def configure(env, env_mono):
if tools_enabled:
# Only supported for editor builds.
- copy_mono_root_files(env, mono_root)
+ copy_mono_root_files(env, mono_root, mono_bcl)
def make_template_dir(env, mono_root):
@@ -430,7 +432,7 @@ def make_template_dir(env, mono_root):
copy_mono_shared_libs(env, mono_root, template_mono_root_dir)
-def copy_mono_root_files(env, mono_root):
+def copy_mono_root_files(env, mono_root, mono_bcl):
from glob import glob
from shutil import copy
from shutil import rmtree
@@ -455,7 +457,7 @@ def copy_mono_root_files(env, mono_root):
# Copy framework assemblies
- mono_framework_dir = os.path.join(mono_root, "lib", "mono", "4.5")
+ mono_framework_dir = mono_bcl or os.path.join(mono_root, "lib", "mono", "4.5")
mono_framework_facades_dir = os.path.join(mono_framework_dir, "Facades")
editor_mono_framework_dir = os.path.join(editor_mono_root_dir, "lib", "mono", "4.5")
diff --git a/modules/mono/class_db_api_json.cpp b/modules/mono/class_db_api_json.cpp
index e3119a8da7..553c6eca53 100644
--- a/modules/mono/class_db_api_json.cpp
+++ b/modules/mono/class_db_api_json.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -71,7 +71,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
while ((k = t->method_map.next(k))) {
String name = k->operator String();
- ERR_CONTINUE(name.empty());
+ ERR_CONTINUE(name.is_empty());
if (name[0] == '_') {
continue; // Ignore non-virtual methods that start with an underscore
@@ -122,7 +122,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
method_dict["hint_flags"] = mb->get_hint_flags();
}
- if (!methods.empty()) {
+ if (!methods.is_empty()) {
class_dict["methods"] = methods;
}
}
@@ -149,7 +149,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
constant_dict["value"] = t->constant_map[F->get()];
}
- if (!constants.empty()) {
+ if (!constants.is_empty()) {
class_dict["constants"] = constants;
}
}
@@ -184,7 +184,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
}
}
- if (!signals.empty()) {
+ if (!signals.is_empty()) {
class_dict["signals"] = signals;
}
}
@@ -214,7 +214,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
property_dict["getter"] = psg->getter;
}
- if (!properties.empty()) {
+ if (!properties.is_empty()) {
class_dict["property_setget"] = properties;
}
}
@@ -233,7 +233,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
property_dict["usage"] = F->get().usage;
}
- if (!property_list.empty()) {
+ if (!property_list.is_empty()) {
class_dict["property_list"] = property_list;
}
}
diff --git a/modules/mono/class_db_api_json.h b/modules/mono/class_db_api_json.h
index 6b7f5a4d88..6698a6260f 100644
--- a/modules/mono/class_db_api_json.h
+++ b/modules/mono/class_db_api_json.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/config.py b/modules/mono/config.py
index d060ae9b28..4c851a2989 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -11,7 +11,6 @@ def configure(env):
if platform not in supported_platforms:
raise RuntimeError("This module does not currently support building for this platform")
- env.use_ptrcall = True
env.add_module_version_string("mono")
from SCons.Script import BoolVariable, PathVariable, Variables, Help
@@ -28,6 +27,14 @@ def configure(env):
PathVariable.PathAccept,
)
)
+ envvars.Add(
+ PathVariable(
+ "mono_bcl",
+ "Path to a custom Mono BCL (Base Class Library) directory for the target platform",
+ "",
+ PathVariable.PathAccept,
+ )
+ )
envvars.Add(BoolVariable("mono_static", "Statically link Mono", default_mono_static))
envvars.Add(BoolVariable("mono_glue", "Build with the Mono glue sources", True))
envvars.Add(BoolVariable("build_cil", "Build C# solutions", True))
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index e59dd24c34..43f57a7caa 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -31,6 +31,7 @@
#include "csharp_script.h"
#include <mono/metadata/threads.h>
+#include <mono/metadata/tokentype.h>
#include <stdint.h>
#include "core/config/project_settings.h"
@@ -327,7 +328,7 @@ Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const Strin
String script_template = "using " BINDINGS_NAMESPACE ";\n"
"using System;\n"
"\n"
- "public class %CLASS% : %BASE%\n"
+ "public partial class %CLASS% : %BASE%\n"
"{\n"
" // Declare member variables here. Examples:\n"
" // private int a = 2;\n"
@@ -346,14 +347,18 @@ Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const Strin
"// }\n"
"}\n";
- String base_class_name = get_base_class_name(p_base_class_name, p_class_name);
+ // Replaces all spaces in p_class_name with underscores to prevent
+ // erronous C# Script templates from being generated when the object name
+ // has spaces in it.
+ String class_name_no_spaces = p_class_name.replace(" ", "_");
+ String base_class_name = get_base_class_name(p_base_class_name, class_name_no_spaces);
script_template = script_template.replace("%BASE%", base_class_name)
- .replace("%CLASS%", p_class_name);
+ .replace("%CLASS%", class_name_no_spaces);
Ref<CSharpScript> script;
script.instance();
script->set_source_code(script_template);
- script->set_name(p_class_name);
+ script->set_name(class_name_no_spaces);
return script;
}
@@ -364,9 +369,10 @@ bool CSharpLanguage::is_using_templates() {
void CSharpLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {
String src = p_script->get_source_code();
- String base_class_name = get_base_class_name(p_base_class_name, p_class_name);
+ String class_name_no_spaces = p_class_name.replace(" ", "_");
+ String base_class_name = get_base_class_name(p_base_class_name, class_name_no_spaces);
src = src.replace("%BASE%", base_class_name)
- .replace("%CLASS%", p_class_name)
+ .replace("%CLASS%", class_name_no_spaces)
.replace("%TS%", _get_indentation());
p_script->set_source_code(src);
}
@@ -395,7 +401,7 @@ bool CSharpLanguage::supports_builtin_mode() const {
#ifdef TOOLS_ENABLED
static String variant_type_to_managed_name(const String &p_var_type_name) {
- if (p_var_type_name.empty()) {
+ if (p_var_type_name.is_empty()) {
return "object";
}
@@ -477,7 +483,7 @@ static String variant_type_to_managed_name(const String &p_var_type_name) {
Variant::COLOR,
Variant::STRING_NAME,
Variant::NODE_PATH,
- Variant::_RID,
+ Variant::RID,
Variant::CALLABLE
};
@@ -757,7 +763,7 @@ bool CSharpLanguage::is_assembly_reloading_needed() {
String appname = ProjectSettings::get_singleton()->get("application/config/name");
String appname_safe = OS::get_singleton()->get_safe_dir_name(appname);
- if (appname_safe.empty()) {
+ if (appname_safe.is_empty()) {
appname_safe = "UnnamedProject";
}
@@ -854,7 +860,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
to_reload.push_back(script);
- if (script->get_path().empty()) {
+ if (script->get_path().is_empty()) {
script->tied_class_name_for_reload = script->script_class->get_name_for_lookup();
script->tied_class_namespace_for_reload = script->script_class->get_namespace();
}
@@ -971,7 +977,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
#endif
script->signals_invalidated = true;
- if (!script->get_path().empty()) {
+ if (!script->get_path().is_empty()) {
script->reload(p_soft_reload);
if (!script->valid) {
@@ -1177,46 +1183,56 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
}
#endif
-void CSharpLanguage::_load_scripts_metadata() {
- scripts_metadata.clear();
+void CSharpLanguage::lookup_script_for_class(GDMonoClass *p_class) {
+ if (!p_class->has_attribute(CACHED_CLASS(ScriptPathAttribute))) {
+ return;
+ }
- String scripts_metadata_filename = "scripts_metadata.";
+ MonoObject *attr = p_class->get_attribute(CACHED_CLASS(ScriptPathAttribute));
+ String path = CACHED_FIELD(ScriptPathAttribute, path)->get_string_value(attr);
-#ifdef TOOLS_ENABLED
- scripts_metadata_filename += Engine::get_singleton()->is_editor_hint() ? "editor" : "editor_player";
-#else
-#ifdef DEBUG_ENABLED
- scripts_metadata_filename += "debug";
-#else
- scripts_metadata_filename += "release";
-#endif
-#endif
+ dotnet_script_lookup_map[path] = DotNetScriptLookupInfo(
+ p_class->get_namespace(), p_class->get_name(), p_class);
+}
- String scripts_metadata_path = GodotSharpDirs::get_res_metadata_dir().plus_file(scripts_metadata_filename);
+void CSharpLanguage::lookup_scripts_in_assembly(GDMonoAssembly *p_assembly) {
+ if (p_assembly->has_attribute(CACHED_CLASS(AssemblyHasScriptsAttribute))) {
+ MonoObject *attr = p_assembly->get_attribute(CACHED_CLASS(AssemblyHasScriptsAttribute));
+ bool requires_lookup = CACHED_FIELD(AssemblyHasScriptsAttribute, requiresLookup)->get_bool_value(attr);
- if (FileAccess::exists(scripts_metadata_path)) {
- String old_json;
+ if (requires_lookup) {
+ // This is supported for scenarios where specifying all types would be cumbersome,
+ // such as when disabling C# source generators (for whatever reason) or when using a
+ // language other than C# that has nothing similar to source generators to automate it.
+ MonoImage *image = p_assembly->get_image();
- Error ferr = read_all_file_utf8(scripts_metadata_path, old_json);
+ int rows = mono_image_get_table_rows(image, MONO_TABLE_TYPEDEF);
- ERR_FAIL_COND(ferr != OK);
+ for (int i = 1; i < rows; i++) {
+ // We don't search inner classes, only top-level.
+ MonoClass *mono_class = mono_class_get(image, (i + 1) | MONO_TOKEN_TYPE_DEF);
- Variant old_dict_var;
- String err_str;
- int err_line;
- Error json_err = JSON::parse(old_json, old_dict_var, err_str, err_line);
- if (json_err != OK) {
- ERR_PRINT("Failed to parse metadata file: '" + err_str + "' (" + String::num_int64(err_line) + ").");
- return;
- }
+ if (!mono_class_is_assignable_from(CACHED_CLASS_RAW(GodotObject), mono_class)) {
+ continue;
+ }
- scripts_metadata = old_dict_var.operator Dictionary();
- scripts_metadata_invalidated = false;
+ GDMonoClass *current = p_assembly->get_class(mono_class);
+ if (current) {
+ lookup_script_for_class(current);
+ }
+ }
+ } else {
+ // This is the most likely scenario as we use C# source generators
+ MonoArray *script_types = (MonoArray *)CACHED_FIELD(AssemblyHasScriptsAttribute, scriptTypes)->get_value(attr);
- print_verbose("Successfully loaded scripts metadata");
- } else {
- if (!Engine::get_singleton()->is_editor_hint()) {
- ERR_PRINT("Missing scripts metadata file.");
+ int length = mono_array_length(script_types);
+
+ for (int i = 0; i < length; i++) {
+ MonoReflectionType *reftype = mono_array_get(script_types, MonoReflectionType *, i);
+ ManagedType type = ManagedType::from_reftype(reftype);
+ ERR_CONTINUE(!type.type_class);
+ lookup_script_for_class(type.type_class);
+ }
}
}
}
@@ -1295,7 +1311,7 @@ void CSharpLanguage::_on_scripts_domain_unloaded() {
}
#endif
- scripts_metadata_invalidated = true;
+ dotnet_script_lookup_map.clear();
}
#ifdef TOOLS_ENABLED
@@ -1441,7 +1457,7 @@ Map<Object *, CSharpScriptBinding>::Element *CSharpLanguage::insert_script_bindi
void CSharpLanguage::free_instance_binding_data(void *p_data) {
if (GDMono::get_singleton() == nullptr) {
#ifdef DEBUG_ENABLED
- CRASH_COND(!script_bindings.empty());
+ CRASH_COND(!script_bindings.is_empty());
#endif
// Mono runtime finalized, all the gchandle bindings were already released
return;
@@ -2002,22 +2018,20 @@ void CSharpInstance::connect_event_signals() {
// TODO: Use pooling for ManagedCallable instances.
auto event_signal_callable = memnew(EventSignalCallable(owner, &event_signal));
- owner->connect(signal_name, Callable(event_signal_callable));
+ Callable callable(event_signal_callable);
+ connected_event_signals.push_back(callable);
+ owner->connect(signal_name, callable);
}
}
void CSharpInstance::disconnect_event_signals() {
- for (const Map<StringName, CSharpScript::EventSignal>::Element *E = script->event_signals.front(); E; E = E->next()) {
- const CSharpScript::EventSignal &event_signal = E->value();
-
- StringName signal_name = event_signal.field->get_name();
-
- // TODO: It would be great if we could store this EventSignalCallable on the stack.
- // The problem is that Callable memdeletes it when it's destructed...
- auto event_signal_callable = memnew(EventSignalCallable(owner, &event_signal));
-
- owner->disconnect(signal_name, Callable(event_signal_callable));
+ for (const List<Callable>::Element *E = connected_event_signals.front(); E; E = E->next()) {
+ const Callable &callable = E->get();
+ auto event_signal_callable = static_cast<const EventSignalCallable *>(callable.get_custom());
+ owner->disconnect(event_signal_callable->get_signal(), callable);
}
+
+ connected_event_signals.clear();
}
void CSharpInstance::refcount_incremented() {
@@ -2599,7 +2613,7 @@ void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_nati
MonoCustomAttrInfo *event_attrs = mono_custom_attrs_from_event(top->get_mono_ptr(), raw_event);
if (event_attrs) {
if (mono_custom_attrs_has_attr(event_attrs, CACHED_CLASS(SignalAttribute)->get_mono_ptr())) {
- const char *event_name = mono_event_get_name(raw_event);
+ String event_name = String::utf8(mono_event_get_name(raw_event));
found_event_signals.push_back(StringName(event_name));
}
@@ -2803,7 +2817,7 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
name_only_hint_string += ",";
}
- String enum_field_name = mono_field_get_name(field);
+ String enum_field_name = String::utf8(mono_field_get_name(field));
r_hint_string += enum_field_name;
name_only_hint_string += enum_field_name;
@@ -2984,7 +2998,7 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) {
p_script->tool = nesting_class && nesting_class->has_attribute(CACHED_CLASS(ToolAttribute));
}
-#if TOOLS_ENABLED
+#ifdef TOOLS_ENABLED
if (!p_script->tool) {
p_script->tool = p_script->script_class->get_assembly() == GDMono::get_singleton()->get_tools_assembly();
}
@@ -3123,7 +3137,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
ERR_FAIL_COND_V_MSG(p_argcount == 0, nullptr,
"Cannot create script instance. The class '" + script_class->get_full_name() +
"' does not define a parameterless constructor." +
- (get_path().empty() ? String() : " Path: '" + get_path() + "'."));
+ (get_path().is_empty() ? String() : " Path: '" + get_path() + "'."));
ERR_FAIL_V_MSG(nullptr, "Constructor not found.");
}
@@ -3278,7 +3292,7 @@ bool CSharpScript::instance_has(const Object *p_this) const {
}
bool CSharpScript::has_source_code() const {
- return !source.empty();
+ return !source.is_empty();
}
String CSharpScript::get_source_code() const {
@@ -3351,45 +3365,34 @@ Error CSharpScript::reload(bool p_keep_state) {
GD_MONO_SCOPE_THREAD_ATTACH;
- GDMonoAssembly *project_assembly = GDMono::get_singleton()->get_project_assembly();
-
- if (project_assembly) {
- const Variant *script_metadata_var = CSharpLanguage::get_singleton()->get_scripts_metadata().getptr(get_path());
- if (script_metadata_var) {
- Dictionary script_metadata = script_metadata_var->operator Dictionary()["class"];
- const Variant *namespace_ = script_metadata.getptr("namespace");
- const Variant *class_name = script_metadata.getptr("class_name");
- ERR_FAIL_NULL_V(namespace_, ERR_BUG);
- ERR_FAIL_NULL_V(class_name, ERR_BUG);
- GDMonoClass *klass = project_assembly->get_class(namespace_->operator String(), class_name->operator String());
- if (klass && CACHED_CLASS(GodotObject)->is_assignable_from(klass)) {
- script_class = klass;
- }
- } else {
- // Missing script metadata. Fallback to legacy method
- script_class = project_assembly->get_object_derived_class(name);
+ const DotNetScriptLookupInfo *lookup_info =
+ CSharpLanguage::get_singleton()->lookup_dotnet_script(get_path());
+
+ if (lookup_info) {
+ GDMonoClass *klass = lookup_info->script_class;
+ if (klass) {
+ ERR_FAIL_COND_V(!CACHED_CLASS(GodotObject)->is_assignable_from(klass), FAILED);
+ script_class = klass;
}
+ }
- valid = script_class != nullptr;
+ valid = script_class != nullptr;
- if (script_class) {
+ if (script_class) {
#ifdef DEBUG_ENABLED
- print_verbose("Found class " + script_class->get_full_name() + " for script " + get_path());
+ print_verbose("Found class " + script_class->get_full_name() + " for script " + get_path());
#endif
- native = GDMonoUtils::get_class_native_base(script_class);
-
- CRASH_COND(native == nullptr);
+ native = GDMonoUtils::get_class_native_base(script_class);
- update_script_class_info(this);
+ CRASH_COND(native == nullptr);
- _update_exports();
- }
+ update_script_class_info(this);
- return OK;
+ _update_exports();
}
- return ERR_FILE_MISSING_DEPENDENCIES;
+ return OK;
}
ScriptLanguage *CSharpScript::get_language() const {
@@ -3579,9 +3582,9 @@ Error CSharpScript::load_source_code(const String &p_path) {
ERR_FAIL_COND_V_MSG(ferr != OK, ferr,
ferr == ERR_INVALID_DATA ?
- "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded."
+ "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded."
" Please ensure that scripts are saved in valid UTF-8 unicode." :
- "Failed to read file: '" + p_path + "'.");
+ "Failed to read file: '" + p_path + "'.");
#ifdef TOOLS_ENABLED
source_changed_cache = true;
@@ -3593,7 +3596,7 @@ Error CSharpScript::load_source_code(const String &p_path) {
void CSharpScript::_update_name() {
String path = get_path();
- if (!path.empty()) {
+ if (!path.is_empty()) {
name = get_path().get_file().get_basename();
}
}
@@ -3639,7 +3642,7 @@ void CSharpScript::get_members(Set<StringName> *p_members) {
/*************** RESOURCE ***************/
-RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
}
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index 3e4e6c3f86..dd93a86d7a 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -31,6 +31,7 @@
#ifndef CSHARP_SCRIPT_H
#define CSHARP_SCRIPT_H
+#include "core/doc_data.h"
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
#include "core/object/script_language.h"
@@ -65,6 +66,18 @@ TScriptInstance *cast_script_instance(ScriptInstance *p_inst) {
#define CAST_CSHARP_INSTANCE(m_inst) (cast_script_instance<CSharpInstance, CSharpLanguage>(m_inst))
+struct DotNetScriptLookupInfo {
+ String class_namespace;
+ String class_name;
+ GDMonoClass *script_class = nullptr;
+
+ DotNetScriptLookupInfo() {} // Required by HashMap...
+
+ DotNetScriptLookupInfo(const String &p_class_namespace, const String &p_class_name, GDMonoClass *p_script_class) :
+ class_namespace(p_class_namespace), class_name(p_class_name), script_class(p_script_class) {
+ }
+};
+
class CSharpScript : public Script {
GDCLASS(CSharpScript, Script);
@@ -189,6 +202,14 @@ public:
String get_source_code() const override;
void set_source_code(const String &p_code) override;
+#ifdef TOOLS_ENABLED
+ virtual const Vector<DocData::ClassDoc> &get_documentation() const override {
+ // TODO
+ static Vector<DocData::ClassDoc> docs;
+ return docs;
+ }
+#endif // TOOLS_ENABLED
+
Error reload(bool p_keep_state = false) override;
bool has_script_signal(const StringName &p_signal) const override;
@@ -250,6 +271,8 @@ class CSharpInstance : public ScriptInstance {
Ref<CSharpScript> script;
MonoGCHandleData gchandle;
+ List<Callable> connected_event_signals;
+
bool _reference_owner_unsafe();
/*
@@ -381,16 +404,15 @@ class CSharpLanguage : public ScriptLanguage {
int lang_idx = -1;
- Dictionary scripts_metadata;
- bool scripts_metadata_invalidated = true;
+ HashMap<String, DotNetScriptLookupInfo> dotnet_script_lookup_map;
+
+ void lookup_script_for_class(GDMonoClass *p_class);
// For debug_break and debug_break_parse
int _debug_parse_err_line = -1;
String _debug_parse_err_file;
String _debug_error;
- void _load_scripts_metadata();
-
friend class GDMono;
void _on_scripts_domain_unloaded();
@@ -427,18 +449,13 @@ public:
void reload_assemblies(bool p_soft_reload);
#endif
- _FORCE_INLINE_ Dictionary get_scripts_metadata_or_nothing() {
- return scripts_metadata_invalidated ? Dictionary() : scripts_metadata;
- }
+ _FORCE_INLINE_ ManagedCallableMiddleman *get_managed_callable_middleman() const { return managed_callable_middleman; }
- _FORCE_INLINE_ const Dictionary &get_scripts_metadata() {
- if (scripts_metadata_invalidated) {
- _load_scripts_metadata();
- }
- return scripts_metadata;
- }
+ void lookup_scripts_in_assembly(GDMonoAssembly *p_assembly);
- _FORCE_INLINE_ ManagedCallableMiddleman *get_managed_callable_middleman() const { return managed_callable_middleman; }
+ const DotNetScriptLookupInfo *lookup_dotnet_script(const String &p_script_path) const {
+ return dotnet_script_lookup_map.getptr(p_script_path);
+ }
String get_name() const override;
@@ -533,7 +550,7 @@ public:
class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader {
public:
- RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false) override;
+ RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override;
void get_recognized_extensions(List<String> *p_extensions) const override;
bool handles_type(const String &p_type) const override;
String get_resource_type(const String &p_path) const override;
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk.sln b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk.sln
index 56c0cb7703..d1868f52ef 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk.sln
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk.sln
@@ -2,6 +2,12 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Godot.NET.Sdk", "Godot.NET.Sdk\Godot.NET.Sdk.csproj", "{31B00BFA-DEA1-42FA-A472-9E54A92A8A5F}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Godot.SourceGenerators", "Godot.SourceGenerators\Godot.SourceGenerators.csproj", "{32D31B23-2A45-4099-B4F5-95B4C8FF7D9F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Godot.SourceGenerators.Sample", "Godot.SourceGenerators.Sample\Godot.SourceGenerators.Sample.csproj", "{7297A614-8DF5-43DE-9EAD-99671B26BD1F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotSharp", "..\..\glue\GodotSharp\GodotSharp\GodotSharp.csproj", "{AEBF0036-DA76-4341-B651-A3F2856AB2FA}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -12,5 +18,17 @@ Global
{31B00BFA-DEA1-42FA-A472-9E54A92A8A5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31B00BFA-DEA1-42FA-A472-9E54A92A8A5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31B00BFA-DEA1-42FA-A472-9E54A92A8A5F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {32D31B23-2A45-4099-B4F5-95B4C8FF7D9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {32D31B23-2A45-4099-B4F5-95B4C8FF7D9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {32D31B23-2A45-4099-B4F5-95B4C8FF7D9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {32D31B23-2A45-4099-B4F5-95B4C8FF7D9F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7297A614-8DF5-43DE-9EAD-99671B26BD1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7297A614-8DF5-43DE-9EAD-99671B26BD1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7297A614-8DF5-43DE-9EAD-99671B26BD1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7297A614-8DF5-43DE-9EAD-99671B26BD1F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AEBF0036-DA76-4341-B651-A3F2856AB2FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AEBF0036-DA76-4341-B651-A3F2856AB2FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AEBF0036-DA76-4341-B651-A3F2856AB2FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AEBF0036-DA76-4341-B651-A3F2856AB2FA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.csproj b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.csproj
index 8304d9e321..4e9e7184da 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.csproj
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.csproj
@@ -8,43 +8,34 @@
<PackageId>Godot.NET.Sdk</PackageId>
<Version>4.0.0</Version>
- <PackageProjectUrl>https://github.com/godotengine/godot/tree/master/modules/mono/editor/Godot.NET.Sdk</PackageProjectUrl>
+ <PackageVersion>$(PackageVersion_Godot_NET_Sdk)</PackageVersion>
+ <RepositoryUrl>https://github.com/godotengine/godot/tree/master/modules/mono/editor/Godot.NET.Sdk</RepositoryUrl>
+ <PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
<PackageType>MSBuildSdk</PackageType>
<PackageTags>MSBuildSdk</PackageTags>
+ <PackageLicenseExpression>MIT</PackageLicenseExpression>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
- </PropertyGroup>
- <PropertyGroup>
- <NuspecFile>Godot.NET.Sdk.nuspec</NuspecFile>
- <GenerateNuspecDependsOn>$(GenerateNuspecDependsOn);SetNuSpecProperties</GenerateNuspecDependsOn>
+ <!-- Exclude target framework from the package dependencies as we don't include the build output -->
+ <SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
+ <IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>
- <Target Name="ReadGodotNETSdkVersion" BeforeTargets="BeforeBuild;BeforeRebuild;CoreCompile">
- <PropertyGroup>
- <PackageVersion>$([System.IO.File]::ReadAllText('$(ProjectDir)Godot.NET.Sdk_PackageVersion.txt').Trim())</PackageVersion>
- </PropertyGroup>
- </Target>
-
- <Target Name="SetNuSpecProperties" Condition=" Exists('$(NuspecFile)') " DependsOnTargets="ReadGodotNETSdkVersion">
- <PropertyGroup>
- <NuspecProperties>
- id=$(PackageId);
- description=$(Description);
- authors=$(Authors);
- version=$(PackageVersion);
- packagetype=$(PackageType);
- tags=$(PackageTags);
- projecturl=$(PackageProjectUrl)
- </NuspecProperties>
- </PropertyGroup>
- </Target>
+ <ItemGroup>
+ <!-- Package Sdk\Sdk.props and Sdk\Sdk.targets file -->
+ <None Include="Sdk\Sdk.props" Pack="true" PackagePath="Sdk" />
+ <None Include="Sdk\Sdk.targets" Pack="true" PackagePath="Sdk" />
+ <!-- SdkPackageVersions.props -->
+ <None Include="..\..\..\SdkPackageVersions.props" Pack="true" PackagePath="Sdk">
+ <Link>Sdk\SdkPackageVersions.props</Link>
+ </None>
+ </ItemGroup>
<Target Name="CopyNupkgToSConsOutputDir" AfterTargets="Pack">
<PropertyGroup>
<GodotSourceRootPath>$(SolutionDir)\..\..\..\..\</GodotSourceRootPath>
<GodotOutputDataDir>$(GodotSourceRootPath)\bin\GodotSharp\</GodotOutputDataDir>
</PropertyGroup>
- <Copy SourceFiles="$(OutputPath)$(PackageId).$(PackageVersion).nupkg"
- DestinationFolder="$(GodotOutputDataDir)Tools\nupkgs\" />
+ <Copy SourceFiles="$(PackageOutputPath)$(PackageId).$(PackageVersion).nupkg" DestinationFolder="$(GodotOutputDataDir)Tools\nupkgs\" />
</Target>
</Project>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.nuspec b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.nuspec
deleted file mode 100644
index ba68a4da43..0000000000
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk.nuspec
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<package xmlns="http://schemas.microsoft.com/packaging/2011/10/nuspec.xsd">
- <metadata>
- <id>$id$</id>
- <version>$version$</version>
- <description>$description$</description>
- <authors>$authors$</authors>
- <owners>$authors$</owners>
- <projectUrl>$projecturl$</projectUrl>
- <requireLicenseAcceptance>false</requireLicenseAcceptance>
- <license type="expression">MIT</license>
- <licenseUrl>https://licenses.nuget.org/MIT</licenseUrl>
- <tags>$tags$</tags>
- <packageTypes>
- <packageType name="$packagetype$" />
- </packageTypes>
- <repository url="$projecturl$" />
- </metadata>
- <files>
- <file src="Sdk\**" target="Sdk" />
- </files>
-</package>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk_PackageVersion.txt b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk_PackageVersion.txt
deleted file mode 100644
index 34749489b9..0000000000
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Godot.NET.Sdk_PackageVersion.txt
+++ /dev/null
@@ -1 +0,0 @@
-4.0.0-dev3
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
index 5febcf3175..0128f5c706 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
@@ -1,4 +1,6 @@
<Project>
+ <Import Project="$(MSBuildThisFileDirectory)\SdkPackageVersions.props" />
+
<PropertyGroup>
<!-- Determines if we should import Microsoft.NET.Sdk, if it wasn't already imported. -->
<GodotSdkImportsMicrosoftNetSdk Condition=" '$(UsingMicrosoftNETSdk)' != 'true' ">true</GodotSdkImportsMicrosoftNetSdk>
@@ -94,6 +96,7 @@
<DefineConstants>$(GodotDefineConstants);$(DefineConstants)</DefineConstants>
</PropertyGroup>
+ <!-- Godot API references -->
<ItemGroup>
<!--
TODO:
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets
index f5afd75505..92e299d2f3 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets
@@ -14,4 +14,9 @@
-->
<DefineConstants Condition=" '$(GodotRealTIsDouble)' == 'true' ">GODOT_REAL_T_IS_DOUBLE;$(DefineConstants)</DefineConstants>
</PropertyGroup>
+
+ <!-- C# source generators -->
+ <ItemGroup Condition=" '$(DisableImplicitGodotGeneratorReferences)' != 'true' ">
+ <PackageReference Include="Godot.SourceGenerators" Version="$(PackageVersion_Godot_SourceGenerators)" />
+ </ItemGroup>
</Project>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs
new file mode 100644
index 0000000000..5eaebc4474
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs
@@ -0,0 +1,15 @@
+namespace Godot.SourceGenerators.Sample
+{
+ partial class Bar : Godot.Object
+ {
+ }
+
+ // Foo in another file
+ partial class Foo
+ {
+ }
+
+ partial class NotSameNameAsFile : Godot.Object
+ {
+ }
+}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs
new file mode 100644
index 0000000000..21a5bfe560
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs
@@ -0,0 +1,11 @@
+namespace Godot.SourceGenerators.Sample
+{
+ partial class Foo : Godot.Object
+ {
+ }
+
+ // Foo again in the same file
+ partial class Foo
+ {
+ }
+}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Godot.SourceGenerators.Sample.csproj b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Godot.SourceGenerators.Sample.csproj
new file mode 100644
index 0000000000..24f7909861
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Godot.SourceGenerators.Sample.csproj
@@ -0,0 +1,31 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netstandard2.1</TargetFramework>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <!-- $(GodotProjectDir) would normally be defined by the Godot.NET.Sdk -->
+ <GodotProjectDir>$(MSBuildProjectDirectory)</GodotProjectDir>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <!-- The emitted files are not part of the compilation nor design.
+ They're only for peeking at the generated sources. Sometimes the
+ emitted files get corrupted, but that won't break anything. -->
+ <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
+ <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GeneratedFiles</CompilerGeneratedFilesOutputPath>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\glue\GodotSharp\GodotSharp\GodotSharp.csproj">
+ <Private>False</Private>
+ </ProjectReference>
+ <ProjectReference Include="..\Godot.SourceGenerators\Godot.SourceGenerators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
+ </ItemGroup>
+
+ <!-- This file is imported automatically when using PackageReference to
+ reference Godot.SourceGenerators, but not when using ProjectReference -->
+ <Import Project="..\Godot.SourceGenerators\Godot.SourceGenerators.props" />
+
+</Project>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
new file mode 100644
index 0000000000..4867c986e6
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
@@ -0,0 +1,33 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace Godot.SourceGenerators
+{
+ public static class Common
+ {
+ public static void ReportNonPartialGodotScriptClass(
+ GeneratorExecutionContext context,
+ ClassDeclarationSyntax cds, INamedTypeSymbol symbol
+ )
+ {
+ string message =
+ "Missing partial modifier on declaration of type '" +
+ $"{symbol.FullQualifiedName()}' which is a subclass of '{GodotClasses.Object}'";
+
+ string description = $"{message}. Subclasses of '{GodotClasses.Object}' must be " +
+ "declared with the partial modifier or annotated with the " +
+ $"attribute '{GodotClasses.DisableGodotGeneratorsAttr}'.";
+
+ context.ReportDiagnostic(Diagnostic.Create(
+ new DiagnosticDescriptor(id: "GODOT-G0001",
+ title: message,
+ messageFormat: message,
+ category: "Usage",
+ DiagnosticSeverity.Error,
+ isEnabledByDefault: true,
+ description),
+ cds.GetLocation(),
+ cds.SyntaxTree.FilePath));
+ }
+ }
+}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
new file mode 100644
index 0000000000..e16f72f43a
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
@@ -0,0 +1,89 @@
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace Godot.SourceGenerators
+{
+ static class ExtensionMethods
+ {
+ public static bool TryGetGlobalAnalyzerProperty(
+ this GeneratorExecutionContext context, string property, out string? value
+ ) => context.AnalyzerConfigOptions.GlobalOptions
+ .TryGetValue("build_property." + property, out value);
+
+ private static bool InheritsFrom(this INamedTypeSymbol? symbol, string baseName)
+ {
+ if (symbol == null)
+ return false;
+
+ while (true)
+ {
+ if (symbol.ToString() == baseName)
+ {
+ return true;
+ }
+
+ if (symbol.BaseType != null)
+ {
+ symbol = symbol.BaseType;
+ continue;
+ }
+
+ break;
+ }
+
+ return false;
+ }
+
+ private static bool IsGodotScriptClass(
+ this ClassDeclarationSyntax cds, Compilation compilation,
+ out INamedTypeSymbol? symbol
+ )
+ {
+ var sm = compilation.GetSemanticModel(cds.SyntaxTree);
+
+ var classTypeSymbol = sm.GetDeclaredSymbol(cds);
+
+ if (classTypeSymbol?.BaseType == null
+ || !classTypeSymbol.BaseType.InheritsFrom(GodotClasses.Object))
+ {
+ symbol = null;
+ return false;
+ }
+
+ symbol = classTypeSymbol;
+ return true;
+ }
+
+ public static IEnumerable<(ClassDeclarationSyntax cds, INamedTypeSymbol symbol)> SelectGodotScriptClasses(
+ this IEnumerable<ClassDeclarationSyntax> source,
+ Compilation compilation
+ )
+ {
+ foreach (var cds in source)
+ {
+ if (cds.IsGodotScriptClass(compilation, out var symbol))
+ yield return (cds, symbol!);
+ }
+ }
+
+ public static bool IsPartial(this ClassDeclarationSyntax cds)
+ => cds.Modifiers.Any(SyntaxKind.PartialKeyword);
+
+ public static bool HasDisableGeneratorsAttribute(this INamedTypeSymbol symbol)
+ => symbol.GetAttributes().Any(attr =>
+ attr.AttributeClass?.ToString() == GodotClasses.DisableGodotGeneratorsAttr);
+
+ private static SymbolDisplayFormat FullyQualifiedFormatOmitGlobal { get; } =
+ SymbolDisplayFormat.FullyQualifiedFormat
+ .WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted);
+
+ public static string FullQualifiedName(this INamedTypeSymbol symbol)
+ => symbol.ToDisplayString(NullableFlowState.NotNull, FullyQualifiedFormatOmitGlobal);
+
+ public static string FullQualifiedName(this INamespaceSymbol namespaceSymbol)
+ => namespaceSymbol.ToDisplayString(FullyQualifiedFormatOmitGlobal);
+ }
+}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.csproj b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.csproj
new file mode 100644
index 0000000000..224d7e5b5a
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.csproj
@@ -0,0 +1,40 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <TargetFramework>netstandard2.0</TargetFramework>
+ <LangVersion>8.0</LangVersion>
+ <Nullable>enable</Nullable>
+ </PropertyGroup>
+ <PropertyGroup>
+ <Description>Core C# source generator for Godot projects.</Description>
+ <Authors>Godot Engine contributors</Authors>
+
+ <PackageId>Godot.SourceGenerators</PackageId>
+ <Version>4.0.0</Version>
+ <PackageVersion>$(PackageVersion_Godot_SourceGenerators)</PackageVersion>
+ <RepositoryUrl>https://github.com/godotengine/godot/tree/master/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators</RepositoryUrl>
+ <PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
+ <PackageLicenseExpression>MIT</PackageLicenseExpression>
+
+ <GeneratePackageOnBuild>true</GeneratePackageOnBuild> <!-- Generates a package at build -->
+ <IncludeBuildOutput>false</IncludeBuildOutput> <!-- Do not include the generator as a lib dependency -->
+ </PropertyGroup>
+ <ItemGroup>
+ <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" PrivateAssets="all" />
+ <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.1" PrivateAssets="all" />
+ </ItemGroup>
+ <ItemGroup>
+ <!-- Package the generator in the analyzer directory of the nuget package -->
+ <None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
+
+ <!-- Package the props file -->
+ <None Include="Godot.SourceGenerators.props" Pack="true" PackagePath="build" Visible="false" />
+ </ItemGroup>
+
+ <Target Name="CopyNupkgToSConsOutputDir" AfterTargets="Pack">
+ <PropertyGroup>
+ <GodotSourceRootPath>$(SolutionDir)\..\..\..\..\</GodotSourceRootPath>
+ <GodotOutputDataDir>$(GodotSourceRootPath)\bin\GodotSharp\</GodotOutputDataDir>
+ </PropertyGroup>
+ <Copy SourceFiles="$(PackageOutputPath)$(PackageId).$(PackageVersion).nupkg" DestinationFolder="$(GodotOutputDataDir)Tools\nupkgs\" />
+ </Target>
+</Project>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.props b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.props
new file mode 100644
index 0000000000..f9b47ad5b1
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.props
@@ -0,0 +1,7 @@
+<Project>
+ <ItemGroup>
+ <!-- $(GodotProjectDir) is defined by Godot.NET.Sdk -->
+ <CompilerVisibleProperty Include="GodotProjectDir" />
+ <CompilerVisibleProperty Include="GodotScriptPathAttributeGenerator" />
+ </ItemGroup>
+</Project>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs
new file mode 100644
index 0000000000..29e41d155a
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs
@@ -0,0 +1,9 @@
+namespace Godot.SourceGenerators
+{
+ public static class GodotClasses
+ {
+ public const string Object = "Godot.Object";
+ public const string DisableGodotGeneratorsAttr = "Godot.DisableGodotGeneratorsAttribute";
+ public const string AssemblyHasScriptsAttr = "Godot.AssemblyHasScriptsAttribute";
+ }
+}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs
new file mode 100644
index 0000000000..a51728e221
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs
@@ -0,0 +1,182 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Text;
+
+namespace Godot.SourceGenerators
+{
+ [Generator]
+ public class ScriptPathAttributeGenerator : ISourceGenerator
+ {
+ public void Execute(GeneratorExecutionContext context)
+ {
+ if (context.TryGetGlobalAnalyzerProperty("GodotScriptPathAttributeGenerator", out string? toggle)
+ && toggle == "disabled")
+ {
+ return;
+ }
+
+ // NOTE: IsNullOrEmpty doesn't work well with nullable checks
+ // ReSharper disable once ReplaceWithStringIsNullOrEmpty
+ if (!context.TryGetGlobalAnalyzerProperty("GodotProjectDir", out string? godotProjectDir)
+ || godotProjectDir!.Length == 0)
+ {
+ throw new InvalidOperationException("Property 'GodotProjectDir' is null or empty.");
+ }
+
+ var godotClasses = context.Compilation.SyntaxTrees
+ .SelectMany(tree =>
+ tree.GetRoot().DescendantNodes()
+ .OfType<ClassDeclarationSyntax>()
+ // Ignore inner classes
+ .Where(cds => !(cds.Parent is ClassDeclarationSyntax))
+ .SelectGodotScriptClasses(context.Compilation)
+ // Report and skip non-partial classes
+ .Where(x =>
+ {
+ if (x.cds.IsPartial() || x.symbol.HasDisableGeneratorsAttribute())
+ return true;
+ Common.ReportNonPartialGodotScriptClass(context, x.cds, x.symbol);
+ return false;
+ })
+ )
+ // Ignore classes whose name is not the same as the file name
+ .Where(x => Path.GetFileNameWithoutExtension(x.cds.SyntaxTree.FilePath) == x.symbol.Name)
+ .GroupBy(x => x.symbol)
+ .ToDictionary(g => g.Key, g => g.Select(x => x.cds));
+
+ foreach (var godotClass in godotClasses)
+ {
+ VisitGodotScriptClass(context, godotProjectDir,
+ symbol: godotClass.Key,
+ classDeclarations: godotClass.Value);
+ }
+
+ if (godotClasses.Count <= 0)
+ return;
+
+ AddScriptTypesAssemblyAttr(context, godotClasses);
+ }
+
+ private static void VisitGodotScriptClass(
+ GeneratorExecutionContext context,
+ string godotProjectDir,
+ INamedTypeSymbol symbol,
+ IEnumerable<ClassDeclarationSyntax> classDeclarations
+ )
+ {
+ var attributes = new StringBuilder();
+
+ // Remember syntax trees for which we already added an attribute, to prevent unnecessary duplicates.
+ var attributedTrees = new List<SyntaxTree>();
+
+ foreach (var cds in classDeclarations)
+ {
+ if (attributedTrees.Contains(cds.SyntaxTree))
+ continue;
+
+ attributedTrees.Add(cds.SyntaxTree);
+
+ if (attributes.Length != 0)
+ attributes.Append("\n");
+
+ attributes.Append(@"[ScriptPathAttribute(""res://");
+ attributes.Append(RelativeToDir(cds.SyntaxTree.FilePath, godotProjectDir));
+ attributes.Append(@""")]");
+ }
+
+ string className = symbol.Name;
+
+ INamespaceSymbol namespaceSymbol = symbol.ContainingNamespace;
+ string classNs = namespaceSymbol != null && !namespaceSymbol.IsGlobalNamespace ?
+ namespaceSymbol.FullQualifiedName() :
+ string.Empty;
+ bool hasNamespace = classNs.Length != 0;
+
+ string uniqueName = hasNamespace ?
+ classNs + "." + className + "_ScriptPath_Generated" :
+ className + "_ScriptPath_Generated";
+
+ var source = new StringBuilder();
+
+ // using Godot;
+ // namespace {classNs} {
+ // {attributesBuilder}
+ // partial class {className} { }
+ // }
+
+ source.Append("using Godot;\n");
+
+ if (hasNamespace)
+ {
+ source.Append("namespace ");
+ source.Append(classNs);
+ source.Append(" {\n\n");
+ }
+
+ source.Append(attributes);
+ source.Append("\n partial class ");
+ source.Append(className);
+ source.Append("\n{\n}\n");
+
+ if (hasNamespace)
+ {
+ source.Append("\n}\n");
+ }
+
+ context.AddSource(uniqueName, SourceText.From(source.ToString(), Encoding.UTF8));
+ }
+
+ private static void AddScriptTypesAssemblyAttr(GeneratorExecutionContext context,
+ Dictionary<INamedTypeSymbol, IEnumerable<ClassDeclarationSyntax>> godotClasses)
+ {
+ var sourceBuilder = new StringBuilder();
+
+ sourceBuilder.Append("[assembly:");
+ sourceBuilder.Append(GodotClasses.AssemblyHasScriptsAttr);
+ sourceBuilder.Append("(new System.Type[] {");
+
+ bool first = true;
+
+ foreach (var godotClass in godotClasses)
+ {
+ var qualifiedName = godotClass.Key.ToDisplayString(
+ NullableFlowState.NotNull, SymbolDisplayFormat.FullyQualifiedFormat);
+ if (!first)
+ sourceBuilder.Append(", ");
+ first = false;
+ sourceBuilder.Append("typeof(");
+ sourceBuilder.Append(qualifiedName);
+ sourceBuilder.Append(")");
+ }
+
+ sourceBuilder.Append("})]\n");
+
+ context.AddSource("AssemblyScriptTypes_Generated",
+ SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
+ }
+
+ public void Initialize(GeneratorInitializationContext context)
+ {
+ }
+
+ private static string RelativeToDir(string path, string dir)
+ {
+ // Make sure the directory ends with a path separator
+ dir = Path.Combine(dir, " ").TrimEnd();
+
+ if (Path.DirectorySeparatorChar == '\\')
+ dir = dir.Replace("/", "\\") + "\\";
+
+ var fullPath = new Uri(Path.GetFullPath(path), UriKind.Absolute);
+ var relRoot = new Uri(Path.GetFullPath(dir), UriKind.Absolute);
+
+ // MakeRelativeUri converts spaces to %20, hence why we need UnescapeDataString
+ return Uri.UnescapeDataString(relRoot.MakeRelativeUri(fullPath).ToString());
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
index 4e2c0f17cc..cdac9acb25 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
@@ -1,11 +1,5 @@
using System;
-using GodotTools.Core;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
using Microsoft.Build.Construction;
-using Microsoft.Build.Globbing;
namespace GodotTools.ProjectEditor
{
@@ -31,47 +25,6 @@ namespace GodotTools.ProjectEditor
return root != null ? new MSBuildProject(root) : null;
}
- private static List<string> GetAllFilesRecursive(string rootDirectory, string mask)
- {
- string[] files = Directory.GetFiles(rootDirectory, mask, SearchOption.AllDirectories);
-
- // We want relative paths
- for (int i = 0; i < files.Length; i++)
- {
- files[i] = files[i].RelativeToPath(rootDirectory);
- }
-
- return new List<string>(files);
- }
-
- // NOTE: Assumes auto-including items. Only used by the scripts metadata generator, which will be replaced with source generators in the future.
- public static IEnumerable<string> GetIncludeFiles(string projectPath, string itemType)
- {
- var excluded = new List<string>();
- var includedFiles = GetAllFilesRecursive(Path.GetDirectoryName(projectPath), "*.cs");
-
- var root = ProjectRootElement.Open(projectPath);
- Debug.Assert(root != null);
-
- foreach (var item in root.Items)
- {
- if (string.IsNullOrEmpty(item.Condition))
- continue;
-
- if (item.ItemType != itemType)
- continue;
-
- string normalizedRemove = item.Remove.NormalizePath();
-
- var glob = MSBuildGlob.Parse(normalizedRemove);
- excluded.AddRange(includedFiles.Where(includedFile => glob.IsMatch(includedFile)));
- }
-
- includedFiles.RemoveAll(f => excluded.Contains(f));
-
- return includedFiles;
- }
-
public static void MigrateToProjectSdksStyle(MSBuildProject project, string projectName)
{
var origRoot = project.Root;
diff --git a/modules/mono/editor/GodotTools/GodotTools.Shared/GenerateGodotNupkgsVersions.targets b/modules/mono/editor/GodotTools/GodotTools.Shared/GenerateGodotNupkgsVersions.targets
index 1d382dcb43..aab2d73bdd 100644
--- a/modules/mono/editor/GodotTools/GodotTools.Shared/GenerateGodotNupkgsVersions.targets
+++ b/modules/mono/editor/GodotTools/GodotTools.Shared/GenerateGodotNupkgsVersions.targets
@@ -3,7 +3,6 @@
<Target Name="SetPropertiesForGenerateGodotNupkgsVersions">
<PropertyGroup>
- <GodotNETSdkPackageVersionFile>$(SolutionDir)..\Godot.NET.Sdk\Godot.NET.Sdk\Godot.NET.Sdk_PackageVersion.txt</GodotNETSdkPackageVersionFile>
<GeneratedGodotNupkgsVersionsFile>$(IntermediateOutputPath)GodotNupkgsVersions.g.cs</GeneratedGodotNupkgsVersionsFile>
</PropertyGroup>
</Target>
@@ -18,13 +17,14 @@
</Target>
<Target Name="_GenerateGodotNupkgsVersionsFile"
DependsOnTargets="SetPropertiesForGenerateGodotNupkgsVersions"
- Inputs="$(MSBuildProjectFile);@(GodotNETSdkPackageVersionFile)"
+ Inputs="$(MSBuildProjectFile);$(MSBuildThisFileDirectory);$(MSBuildProjectFile)\..\..\..\SdkPackageVersions.props"
Outputs="$(GeneratedGodotNupkgsVersionsFile)">
<PropertyGroup>
<GenerateGodotNupkgsVersionsCode><![CDATA[
namespace $(RootNamespace) {
public class GeneratedGodotNupkgsVersions {
- public const string GodotNETSdk = "$([System.IO.File]::ReadAllText('$(GodotNETSdkPackageVersionFile)').Trim())"%3b
+ public const string GodotNETSdk = "$(PackageVersion_Godot_NET_Sdk)"%3b
+ public const string GodotSourceGenerators = "$(PackageVersion_Godot_SourceGenerators)"%3b
}
}
]]></GenerateGodotNupkgsVersionsCode>
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs
index b96b0c8175..2b6f972529 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs
@@ -218,43 +218,12 @@ namespace GodotTools.Build
Godot.GD.PushError("Failed to setup Godot NuGet Offline Packages: " + e.Message);
}
- GenerateEditorScriptMetadata();
-
if (GodotSharpEditor.Instance.SkipBuildBeforePlaying)
return true; // Requested play from an external editor/IDE which already built the project
return BuildProjectBlocking("Debug");
}
- // NOTE: This will be replaced with C# source generators in 4.0
- public static void GenerateEditorScriptMetadata()
- {
- string editorScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor");
- string playerScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor_player");
-
- CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, editorScriptsMetadataPath);
-
- if (!File.Exists(editorScriptsMetadataPath))
- return;
-
- try
- {
- File.Copy(editorScriptsMetadataPath, playerScriptsMetadataPath);
- }
- catch (IOException e)
- {
- throw new IOException("Failed to copy scripts metadata file.", innerException: e);
- }
- }
-
- // NOTE: This will be replaced with C# source generators in 4.0
- public static string GenerateExportedGameScriptMetadata(bool isDebug)
- {
- string scriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, $"scripts_metadata.{(isDebug ? "debug" : "release")}");
- CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, scriptsMetadataPath);
- return scriptsMetadataPath;
- }
-
public static void Initialize()
{
// Build tool settings
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
index 9514cc9622..1a1639aac7 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
@@ -2,6 +2,7 @@ using Godot;
using System;
using Godot.Collections;
using GodotTools.Internals;
+using JetBrains.Annotations;
using File = GodotTools.Utils.File;
using Path = System.IO.Path;
@@ -26,6 +27,9 @@ namespace GodotTools.Build
private TextEdit buildLog;
private PopupMenu issuesListContextMenu;
+ private readonly object pendingBuildLogTextLock = new object();
+ [NotNull] private string pendingBuildLogText = string.Empty;
+
[Signal] public event Action BuildStateChanged;
public bool HasBuildExited { get; private set; } = false;
@@ -240,16 +244,34 @@ namespace GodotTools.Build
EmitSignal(nameof(BuildStateChanged));
}
+ private void UpdateBuildLogText()
+ {
+ lock (pendingBuildLogTextLock)
+ {
+ buildLog.Text += pendingBuildLogText;
+ pendingBuildLogText = string.Empty;
+ ScrollToLastNonEmptyLogLine();
+ }
+ }
+
private void StdOutputReceived(string text)
{
- buildLog.Text += text + "\n";
- ScrollToLastNonEmptyLogLine();
+ lock (pendingBuildLogTextLock)
+ {
+ if (pendingBuildLogText.Length == 0)
+ CallDeferred(nameof(UpdateBuildLogText));
+ pendingBuildLogText += text + "\n";
+ }
}
private void StdErrorReceived(string text)
{
- buildLog.Text += text + "\n";
- ScrollToLastNonEmptyLogLine();
+ lock (pendingBuildLogTextLock)
+ {
+ if (pendingBuildLogText.Length == 0)
+ CallDeferred(nameof(UpdateBuildLogText));
+ pendingBuildLogText += text + "\n";
+ }
}
private void ScrollToLastNonEmptyLogLine()
@@ -377,12 +399,14 @@ namespace GodotTools.Build
BuildManager.BuildStarted += BuildStarted;
BuildManager.BuildFinished += BuildFinished;
// StdOutput/Error can be received from different threads, so we need to use CallDeferred
- BuildManager.StdOutputReceived += line => CallDeferred(nameof(StdOutputReceived), line);
- BuildManager.StdErrorReceived += line => CallDeferred(nameof(StdErrorReceived), line);
+ BuildManager.StdOutputReceived += StdOutputReceived;
+ BuildManager.StdErrorReceived += StdErrorReceived;
}
public void OnBeforeSerialize()
{
+ // In case it didn't update yet. We don't want to have to serialize any pending output.
+ UpdateBuildLogText();
}
public void OnAfterDeserialize()
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
index 708ec73454..ed69c2b833 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
@@ -43,8 +43,6 @@ namespace GodotTools.Build
GD.PushError("Failed to setup Godot NuGet Offline Packages: " + e.Message);
}
- BuildManager.GenerateEditorScriptMetadata();
-
if (!BuildManager.BuildProjectBlocking("Debug"))
return; // Build failed
@@ -74,8 +72,6 @@ namespace GodotTools.Build
GD.PushError("Failed to setup Godot NuGet Offline Packages: " + e.Message);
}
- BuildManager.GenerateEditorScriptMetadata();
-
if (!BuildManager.BuildProjectBlocking("Debug", targets: new[] {"Rebuild"}))
return; // Build failed
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
index e2feb66e35..774c49e705 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
@@ -86,7 +86,7 @@ namespace GodotTools.Build
{
case BuildTool.DotnetCli:
{
- string dotnetCliPath = OS.PathWhich("dotnet");
+ string dotnetCliPath = FindBuildEngineOnUnix("dotnet");
if (!string.IsNullOrEmpty(dotnetCliPath))
return (dotnetCliPath, BuildTool.DotnetCli);
GD.PushError($"Cannot find executable for '{BuildManager.PropNameDotnetCli}'. Fallback to MSBuild from Mono.");
@@ -122,7 +122,11 @@ namespace GodotTools.Build
if (OS.IsMacOS)
{
result.Add("/Library/Frameworks/Mono.framework/Versions/Current/bin/");
+ result.Add("/opt/local/bin/");
result.Add("/usr/local/var/homebrew/linked/mono/bin/");
+ result.Add("/usr/local/bin/");
+ result.Add("/usr/local/bin/dotnet/");
+ result.Add("/usr/local/share/dotnet/");
}
result.Add("/opt/novell/mono/bin/");
@@ -181,7 +185,7 @@ namespace GodotTools.Build
var outputArray = new Godot.Collections.Array<string>();
int exitCode = Godot.OS.Execute(vsWherePath, vsWhereArgs,
- blocking: true, output: (Godot.Collections.Array)outputArray);
+ output: (Godot.Collections.Array)outputArray);
if (exitCode != 0)
return string.Empty;
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs b/modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs
index 793ef7fd71..16dd1c8c6b 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/NuGetUtils.cs
@@ -290,7 +290,8 @@ namespace GodotTools.Build
private static readonly (string packageId, string packageVersion)[] PackagesToAdd =
{
- ("Godot.NET.Sdk", GeneratedGodotNupkgsVersions.GodotNETSdk)
+ ("Godot.NET.Sdk", GeneratedGodotNupkgsVersions.GodotNETSdk),
+ ("Godot.SourceGenerators", GeneratedGodotNupkgsVersions.GodotSourceGenerators),
};
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
index 1d800b8151..e43f10804d 100644
--- a/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs
@@ -1,11 +1,6 @@
using Godot;
using System;
-using System.Linq;
-using Godot.Collections;
-using GodotTools.Internals;
using GodotTools.ProjectEditor;
-using File = GodotTools.Utils.File;
-using Directory = GodotTools.Utils.Directory;
namespace GodotTools
{
@@ -23,86 +18,5 @@ namespace GodotTools
return string.Empty;
}
}
-
- private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
-
- private static ulong ConvertToTimestamp(this DateTime value)
- {
- TimeSpan elapsedTime = value - Epoch;
- return (ulong)elapsedTime.TotalSeconds;
- }
-
- private static bool TryParseFileMetadata(string includeFile, ulong modifiedTime, out Dictionary fileMetadata)
- {
- fileMetadata = null;
-
- var parseError = ScriptClassParser.ParseFile(includeFile, out var classes, out string errorStr);
-
- if (parseError != Error.Ok)
- {
- GD.PushError($"Failed to determine namespace and class for script: {includeFile}. Parse error: {errorStr ?? parseError.ToString()}");
- return false;
- }
-
- string searchName = System.IO.Path.GetFileNameWithoutExtension(includeFile);
-
- var firstMatch = classes.FirstOrDefault(classDecl =>
- classDecl.BaseCount != 0 && // If it doesn't inherit anything, it can't be a Godot.Object.
- classDecl.SearchName == searchName // Filter by the name we're looking for
- );
-
- if (firstMatch == null)
- return false; // Not found
-
- fileMetadata = new Dictionary
- {
- ["modified_time"] = $"{modifiedTime}",
- ["class"] = new Dictionary
- {
- ["namespace"] = firstMatch.Namespace,
- ["class_name"] = firstMatch.Name,
- ["nested"] = firstMatch.Nested
- }
- };
-
- return true;
- }
-
- public static void GenerateScriptsMetadata(string projectPath, string outputPath)
- {
- var metadataDict = Internal.GetScriptsMetadataOrNothing().Duplicate();
-
- bool IsUpToDate(string includeFile, ulong modifiedTime)
- {
- return metadataDict.TryGetValue(includeFile, out var oldFileVar) &&
- ulong.TryParse(((Dictionary)oldFileVar)["modified_time"] as string,
- out ulong storedModifiedTime) && storedModifiedTime == modifiedTime;
- }
-
- var outdatedFiles = ProjectUtils.GetIncludeFiles(projectPath, "Compile")
- .Select(path => ("res://" + path).SimplifyGodotPath())
- .ToDictionary(path => path, path => File.GetLastWriteTime(path).ConvertToTimestamp())
- .Where(pair => !IsUpToDate(includeFile: pair.Key, modifiedTime: pair.Value))
- .ToArray();
-
- foreach (var pair in outdatedFiles)
- {
- metadataDict.Remove(pair.Key);
-
- string includeFile = pair.Key;
-
- if (TryParseFileMetadata(includeFile, modifiedTime: pair.Value, out var fileMetadata))
- metadataDict[includeFile] = fileMetadata;
- }
-
- string json = metadataDict.Count <= 0 ? "{}" : JSON.Print(metadataDict);
-
- string baseDir = outputPath.GetBaseDir();
-
- if (!Directory.Exists(baseDir))
- Directory.CreateDirectory(baseDir);
-
- File.WriteAllText(outputPath, json);
- }
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
index 5bb8d444c2..5bb8d444c2 100755..100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
index e18ed7f107..270be8b6bf 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
@@ -157,9 +157,6 @@ namespace GodotTools.Export
string buildConfig = isDebug ? "ExportDebug" : "ExportRelease";
- string scriptsMetadataPath = BuildManager.GenerateExportedGameScriptMetadata(isDebug);
- AddFile(scriptsMetadataPath, scriptsMetadataPath);
-
if (!BuildManager.BuildProjectBlocking(buildConfig, platform: platform))
throw new Exception("Failed to build project");
@@ -173,6 +170,8 @@ namespace GodotTools.Export
assemblies[projectDllName] = projectDllSrcPath;
+ string bclDir = DeterminePlatformBclDir(platform);
+
if (platform == OS.Platforms.Android)
{
string godotAndroidExtProfileDir = GetBclProfileDir("godot_android_ext");
@@ -183,8 +182,49 @@ namespace GodotTools.Export
assemblies["Mono.Android"] = monoAndroidAssemblyPath;
}
+ else if (platform == OS.Platforms.HTML5)
+ {
+ // Ideally these would be added automatically since they're referenced by the wasm BCL assemblies.
+ // However, at least in the case of 'WebAssembly.Net.Http' for some reason the BCL assemblies
+ // reference a different version even though the assembly is the same, for some weird reason.
- string bclDir = DeterminePlatformBclDir(platform);
+ var wasmFrameworkAssemblies = new[] {"WebAssembly.Bindings", "WebAssembly.Net.WebSockets"};
+
+ foreach (string thisWasmFrameworkAssemblyName in wasmFrameworkAssemblies)
+ {
+ string thisWasmFrameworkAssemblyPath = Path.Combine(bclDir, thisWasmFrameworkAssemblyName + ".dll");
+ if (!File.Exists(thisWasmFrameworkAssemblyPath))
+ throw new FileNotFoundException($"Assembly not found: '{thisWasmFrameworkAssemblyName}'", thisWasmFrameworkAssemblyPath);
+ assemblies[thisWasmFrameworkAssemblyName] = thisWasmFrameworkAssemblyPath;
+ }
+
+ // Assemblies that can have a different name in a newer version. Newer version must come first and it has priority.
+ (string newName, string oldName)[] wasmFrameworkAssembliesOneOf = new[]
+ {
+ ("System.Net.Http.WebAssemblyHttpHandler", "WebAssembly.Net.Http")
+ };
+
+ foreach (var thisWasmFrameworkAssemblyName in wasmFrameworkAssembliesOneOf)
+ {
+ string thisWasmFrameworkAssemblyPath = Path.Combine(bclDir, thisWasmFrameworkAssemblyName.newName + ".dll");
+ if (File.Exists(thisWasmFrameworkAssemblyPath))
+ {
+ assemblies[thisWasmFrameworkAssemblyName.newName] = thisWasmFrameworkAssemblyPath;
+ }
+ else
+ {
+ thisWasmFrameworkAssemblyPath = Path.Combine(bclDir, thisWasmFrameworkAssemblyName.oldName + ".dll");
+ if (!File.Exists(thisWasmFrameworkAssemblyPath))
+ {
+ throw new FileNotFoundException("Expected one of the following assemblies but none were found: " +
+ $"'{thisWasmFrameworkAssemblyName.newName}' / '{thisWasmFrameworkAssemblyName.oldName}'",
+ thisWasmFrameworkAssemblyPath);
+ }
+
+ assemblies[thisWasmFrameworkAssemblyName.oldName] = thisWasmFrameworkAssemblyPath;
+ }
+ }
+ }
var initialAssemblies = assemblies.Duplicate();
internal_GetExportedAssemblyDependencies(initialAssemblies, buildConfig, bclDir, assemblies);
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs b/modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs
index 219b7a698a..93ef837a83 100755..100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/XcodeHelper.cs
@@ -27,7 +27,7 @@ namespace GodotTools.Export
{
var outputWrapper = new Godot.Collections.Array();
- int exitCode = Godot.OS.Execute("xcode-select", new string[] { "--print-path" }, blocking: true, output: outputWrapper);
+ int exitCode = Godot.OS.Execute("xcode-select", new string[] { "--print-path" }, output: outputWrapper);
if (exitCode == 0)
{
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
index 16f91a0925..ed25cdaa63 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
@@ -104,7 +104,7 @@ namespace GodotTools.Ides.Rider
if (line >= 0)
{
args.Add("--line");
- args.Add(line.ToString());
+ args.Add((line + 1).ToString()); // https://github.com/JetBrains/godot-support/issues/61
}
args.Add(scriptPath);
try
diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
index 7e5049e4b7..77370090ec 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
@@ -1,7 +1,5 @@
-using System;
using System.Runtime.CompilerServices;
using Godot;
-using Godot.Collections;
using GodotTools.IdeMessaging.Requests;
namespace GodotTools.Internals
@@ -42,9 +40,6 @@ namespace GodotTools.Internals
public static void EditorNodeShowScriptScreen() => internal_EditorNodeShowScriptScreen();
- public static Dictionary<string, object> GetScriptsMetadataOrNothing() =>
- internal_GetScriptsMetadataOrNothing(typeof(Dictionary<string, object>));
-
public static string MonoWindowsInstallRoot => internal_MonoWindowsInstallRoot();
public static void EditorRunPlay() => internal_EditorRunPlay();
@@ -101,9 +96,6 @@ namespace GodotTools.Internals
private static extern void internal_EditorNodeShowScriptScreen();
[MethodImpl(MethodImplOptions.InternalCall)]
- private static extern Dictionary<string, object> internal_GetScriptsMetadataOrNothing(Type dictType);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
private static extern string internal_MonoWindowsInstallRoot();
[MethodImpl(MethodImplOptions.InternalCall)]
diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs
deleted file mode 100644
index c72a84c513..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-using Godot;
-using Godot.Collections;
-
-namespace GodotTools.Internals
-{
- public static class ScriptClassParser
- {
- public class ClassDecl
- {
- public string Name { get; }
- public string Namespace { get; }
- public bool Nested { get; }
- public long BaseCount { get; }
-
- public string SearchName => Nested ?
- Name.Substring(Name.LastIndexOf(".", StringComparison.Ordinal) + 1) :
- Name;
-
- public ClassDecl(string name, string @namespace, bool nested, long baseCount)
- {
- Name = name;
- Namespace = @namespace;
- Nested = nested;
- BaseCount = baseCount;
- }
- }
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern Error internal_ParseFile(string filePath, Array<Dictionary> classes, out string errorStr);
-
- public static Error ParseFile(string filePath, out IEnumerable<ClassDecl> classes, out string errorStr)
- {
- var classesArray = new Array<Dictionary>();
- var error = internal_ParseFile(filePath, classesArray, out errorStr);
- if (error != Error.Ok)
- {
- classes = null;
- return error;
- }
-
- var classesList = new List<ClassDecl>();
-
- foreach (var classDeclDict in classesArray)
- {
- classesList.Add(new ClassDecl(
- (string)classDeclDict["name"],
- (string)classDeclDict["namespace"],
- (bool)classDeclDict["nested"],
- (long)classDeclDict["base_count"]
- ));
- }
-
- classes = classesList;
-
- return Error.Ok;
- }
- }
-}
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 4ad5cdbf47..b48e5df9eb 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -39,6 +39,7 @@
#include "core/os/file_access.h"
#include "core/os/os.h"
#include "core/string/ucaps.h"
+#include "main/main.h"
#include "../glue/cs_glue_version.gen.h"
#include "../godotsharp_defs.h"
@@ -97,7 +98,7 @@
#define C_METHOD_MANAGED_TO_SIGNAL C_NS_MONOMARSHAL "::signal_info_to_callable"
#define C_METHOD_MANAGED_FROM_SIGNAL C_NS_MONOMARSHAL "::callable_to_signal_info"
-#define BINDINGS_GENERATOR_VERSION UINT32_C(12)
+#define BINDINGS_GENERATOR_VERSION UINT32_C(13)
const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN("\t%0 %1_in = %1;\n");
@@ -181,11 +182,11 @@ static String snake_to_camel_case(const String &p_identifier, bool p_input_is_up
String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterface *p_itype) {
// Based on the version in EditorHelp
- if (p_bbcode.empty()) {
+ if (p_bbcode.is_empty()) {
return String();
}
- DocData *doc = EditorHelp::get_doc_data();
+ DocTools *doc = EditorHelp::get_doc_data();
String bbcode = p_bbcode;
@@ -365,7 +366,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
xml_output.append("</c>");
} else if (link_tag == "enum") {
StringName search_cname = !target_itype ? target_cname :
- StringName(target_itype->name + "." + (String)target_cname);
+ StringName(target_itype->name + "." + (String)target_cname);
const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(search_cname);
@@ -644,7 +645,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
}
int BindingsGenerator::_determine_enum_prefix(const EnumInterface &p_ienum) {
- CRASH_COND(p_ienum.constants.empty());
+ CRASH_COND(p_ienum.constants.is_empty());
const ConstantInterface &front_iconstant = p_ienum.constants.front()->get();
Vector<String> front_parts = front_iconstant.name.split("_", /* p_allow_empty: */ true);
@@ -783,6 +784,72 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) {
}
}
+void BindingsGenerator::_generate_array_extensions(StringBuilder &p_output) {
+ p_output.append("using System;\n\n");
+ p_output.append("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK);
+ // The class where we put the extensions doesn't matter, so just use "GD".
+ p_output.append(INDENT1 "public static partial class " BINDINGS_GLOBAL_SCOPE_CLASS "\n" INDENT1 "{");
+
+#define ARRAY_IS_EMPTY(m_type) \
+ p_output.append("\n" INDENT2 "/// <summary>\n"); \
+ p_output.append(INDENT2 "/// Returns true if this " #m_type " array is empty or doesn't exist.\n"); \
+ p_output.append(INDENT2 "/// </summary>\n"); \
+ p_output.append(INDENT2 "/// <param name=\"instance\">The " #m_type " array check.</param>\n"); \
+ p_output.append(INDENT2 "/// <returns>Whether or not the array is empty.</returns>\n"); \
+ p_output.append(INDENT2 "public static bool IsEmpty(this " #m_type "[] instance)\n"); \
+ p_output.append(INDENT2 OPEN_BLOCK); \
+ p_output.append(INDENT3 "return instance == null || instance.Length == 0;\n"); \
+ p_output.append(INDENT2 CLOSE_BLOCK);
+
+#define ARRAY_JOIN(m_type) \
+ p_output.append("\n" INDENT2 "/// <summary>\n"); \
+ p_output.append(INDENT2 "/// Converts this " #m_type " array to a string delimited by the given string.\n"); \
+ p_output.append(INDENT2 "/// </summary>\n"); \
+ p_output.append(INDENT2 "/// <param name=\"instance\">The " #m_type " array to convert.</param>\n"); \
+ p_output.append(INDENT2 "/// <param name=\"delimiter\">The delimiter to use between items.</param>\n"); \
+ p_output.append(INDENT2 "/// <returns>A single string with all items.</returns>\n"); \
+ p_output.append(INDENT2 "public static string Join(this " #m_type "[] instance, string delimiter = \", \")\n"); \
+ p_output.append(INDENT2 OPEN_BLOCK); \
+ p_output.append(INDENT3 "return String.Join(delimiter, instance);\n"); \
+ p_output.append(INDENT2 CLOSE_BLOCK);
+
+#define ARRAY_STRINGIFY(m_type) \
+ p_output.append("\n" INDENT2 "/// <summary>\n"); \
+ p_output.append(INDENT2 "/// Converts this " #m_type " array to a string with brackets.\n"); \
+ p_output.append(INDENT2 "/// </summary>\n"); \
+ p_output.append(INDENT2 "/// <param name=\"instance\">The " #m_type " array to convert.</param>\n"); \
+ p_output.append(INDENT2 "/// <returns>A single string with all items.</returns>\n"); \
+ p_output.append(INDENT2 "public static string Stringify(this " #m_type "[] instance)\n"); \
+ p_output.append(INDENT2 OPEN_BLOCK); \
+ p_output.append(INDENT3 "return \"[\" + instance.Join() + \"]\";\n"); \
+ p_output.append(INDENT2 CLOSE_BLOCK);
+
+#define ARRAY_ALL(m_type) \
+ ARRAY_IS_EMPTY(m_type) \
+ ARRAY_JOIN(m_type) \
+ ARRAY_STRINGIFY(m_type)
+
+ ARRAY_ALL(byte);
+ ARRAY_ALL(int);
+ ARRAY_ALL(long);
+ ARRAY_ALL(float);
+ ARRAY_ALL(double);
+ ARRAY_ALL(string);
+ ARRAY_ALL(Color);
+ ARRAY_ALL(Vector2);
+ ARRAY_ALL(Vector2i);
+ ARRAY_ALL(Vector3);
+ ARRAY_ALL(Vector3i);
+
+#undef ARRAY_ALL
+#undef ARRAY_IS_EMPTY
+#undef ARRAY_JOIN
+#undef ARRAY_STRINGIFY
+
+ p_output.append(INDENT1 CLOSE_BLOCK); // End of GD class.
+ p_output.append(CLOSE_BLOCK); // End of namespace.
+}
+
void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
// Constants (in partial GD class)
@@ -819,7 +886,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
p_output.append(";");
}
- if (!global_constants.empty()) {
+ if (!global_constants.is_empty()) {
p_output.append("\n");
}
@@ -830,7 +897,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
for (List<EnumInterface>::Element *E = global_enums.front(); E; E = E->next()) {
const EnumInterface &ienum = E->get();
- CRASH_COND(ienum.constants.empty());
+ CRASH_COND(ienum.constants.is_empty());
String enum_proxy_name = ienum.cname.operator String();
@@ -926,6 +993,19 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
compile_items.push_back(output_file);
}
+ // Generate source file for array extensions
+ {
+ StringBuilder extensions_source;
+ _generate_array_extensions(extensions_source);
+ String output_file = path::join(base_gen_dir, BINDINGS_GLOBAL_SCOPE_CLASS "_extensions.cs");
+ Error save_err = _save_file(output_file, extensions_source);
+ if (save_err != OK) {
+ return save_err;
+ }
+
+ compile_items.push_back(output_file);
+ }
+
for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) {
const TypeInterface &itype = E.get();
@@ -1283,7 +1363,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
for (const List<EnumInterface>::Element *E = itype.enums.front(); E; E = E->next()) {
const EnumInterface &ienum = E->get();
- ERR_FAIL_COND_V(ienum.constants.empty(), ERR_BUG);
+ ERR_FAIL_COND_V(ienum.constants.is_empty(), ERR_BUG);
output.append(MEMBER_BEGIN "public enum ");
output.append(ienum.cname.operator String());
@@ -1479,6 +1559,12 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
ERR_FAIL_COND_V_MSG(prop_itype->is_singleton, ERR_BUG,
"Property type is a singleton: '" + p_itype.name + "." + String(p_iprop.cname) + "'.");
+ if (p_itype.api_type == ClassDB::API_CORE) {
+ ERR_FAIL_COND_V_MSG(prop_itype->api_type == ClassDB::API_EDITOR, ERR_BUG,
+ "Property '" + p_itype.name + "." + String(p_iprop.cname) + "' has type '" + prop_itype->name +
+ "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
+
if (p_iprop.prop_doc && p_iprop.prop_doc->description.size()) {
String xml_summary = bbcode_to_xml(fix_doc_description(p_iprop.prop_doc->description), &p_itype);
Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>();
@@ -1575,6 +1661,12 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
ERR_FAIL_COND_V_MSG(return_type->is_singleton, ERR_BUG,
"Method return type is a singleton: '" + p_itype.name + "." + p_imethod.name + "'.");
+ if (p_itype.api_type == ClassDB::API_CORE) {
+ ERR_FAIL_COND_V_MSG(return_type->api_type == ClassDB::API_EDITOR, ERR_BUG,
+ "Method '" + p_itype.name + "." + p_imethod.name + "' has return type '" + return_type->name +
+ "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
+
String method_bind_field = "__method_bind_" + itos(p_method_bind_count);
String arguments_sig;
@@ -1593,6 +1685,12 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG,
"Argument type is a singleton: '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "'.");
+ if (p_itype.api_type == ClassDB::API_CORE) {
+ ERR_FAIL_COND_V_MSG(arg_type->api_type == ClassDB::API_EDITOR, ERR_BUG,
+ "Argument '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "' has type '" +
+ arg_type->name + "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
+
if (iarg.default_argument.size()) {
CRASH_COND_MSG(!_arg_default_value_is_assignable_to_type(iarg.def_param_value, *arg_type),
"Invalid default value for parameter '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "'.");
@@ -1661,14 +1759,14 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
cs_in_statements += def_arg;
cs_in_statements += ";\n" INDENT3;
- icall_params += arg_type->cs_in.empty() ? arg_in : sformat(arg_type->cs_in, arg_in);
+ icall_params += arg_type->cs_in.is_empty() ? arg_in : sformat(arg_type->cs_in, arg_in);
// 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;
default_args_doc.append(MEMBER_BEGIN "/// <param name=\"" + param_tag_name + "\">If the parameter is null, then the default value is " + def_arg + "</param>");
} else {
- icall_params += arg_type->cs_in.empty() ? iarg.name : sformat(arg_type->cs_in, iarg.name);
+ icall_params += arg_type->cs_in.is_empty() ? iarg.name : sformat(arg_type->cs_in, iarg.name);
}
}
@@ -1714,7 +1812,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
}
if (p_imethod.is_deprecated) {
- if (p_imethod.deprecation_message.empty()) {
+ if (p_imethod.deprecation_message.is_empty()) {
WARN_PRINT("An empty deprecation message is discouraged. Method: '" + p_imethod.proxy_name + "'.");
}
@@ -1782,7 +1880,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
if (return_type->cname == name_cache.type_void) {
p_output.append(im_call + "(" + icall_params + ");\n");
- } else if (return_type->cs_out.empty()) {
+ } else if (return_type->cs_out.is_empty()) {
p_output.append("return " + im_call + "(" + icall_params + ");\n");
} else {
p_output.append(sformat(return_type->cs_out, im_call, icall_params, return_type->cs_type, return_type->im_type_out));
@@ -1806,7 +1904,13 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type);
ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG,
- "Argument type is a singleton: '" + iarg.name + "' of signal" + p_itype.name + "." + p_isignal.name + "'.");
+ "Argument type is a singleton: '" + iarg.name + "' of signal '" + p_itype.name + "." + p_isignal.name + "'.");
+
+ if (p_itype.api_type == ClassDB::API_CORE) {
+ ERR_FAIL_COND_V_MSG(arg_type->api_type == ClassDB::API_EDITOR, ERR_BUG,
+ "Argument '" + iarg.name + "' of signal '" + p_itype.name + "." + p_isignal.name + "' has type '" +
+ arg_type->name + "' from the editor API. Core API cannot have dependencies on the editor API.");
+ }
// Add the current arguments to the signature
@@ -1839,7 +1943,7 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
}
if (p_isignal.is_deprecated) {
- if (p_isignal.deprecation_message.empty()) {
+ if (p_isignal.deprecation_message.is_empty()) {
WARN_PRINT("An empty deprecation message is discouraged. Signal: '" + p_isignal.proxy_name + "'.");
}
@@ -1999,12 +2103,12 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
#define ADD_INTERNAL_CALL_REGISTRATION(m_icall) \
{ \
- output.append("\tmono_add_internal_call("); \
+ output.append("\tGDMonoUtils::add_internal_call("); \
output.append("\"" BINDINGS_NAMESPACE "."); \
output.append(m_icall.editor_only ? BINDINGS_CLASS_NATIVECALLS_EDITOR : BINDINGS_CLASS_NATIVECALLS); \
output.append("::"); \
output.append(m_icall.name); \
- output.append("\", (void*)"); \
+ output.append("\", "); \
output.append(m_icall.name); \
output.append(");\n"); \
}
@@ -2263,7 +2367,7 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
}
if (!ret_void) {
- if (return_type->c_out.empty()) {
+ if (return_type->c_out.is_empty()) {
p_output.append("\treturn " C_LOCAL_RET ";\n");
} else if (return_type->ret_as_byref_arg) {
p_output.append(sformat(return_type->c_out, return_type->c_type_out, C_LOCAL_RET, return_type->name, "arg_ret"));
@@ -2426,7 +2530,7 @@ bool BindingsGenerator::_arg_default_value_is_assignable_to_type(const Variant &
case Variant::VECTOR2:
case Variant::RECT2:
case Variant::VECTOR3:
- case Variant::_RID:
+ case Variant::RID:
case Variant::ARRAY:
case Variant::DICTIONARY:
case Variant::PACKED_BYTE_ARRAY:
@@ -2585,7 +2689,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
int argc = method_info.arguments.size();
- if (method_info.name.empty()) {
+ if (method_info.name.is_empty()) {
continue;
}
@@ -2932,9 +3036,9 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
}
break;
case Variant::FLOAT:
-#ifndef REAL_T_IS_DOUBLE
- r_iarg.default_argument += "f";
-#endif
+ if (r_iarg.type.cname == name_cache.type_float) {
+ r_iarg.default_argument += "f";
+ }
break;
case Variant::STRING:
case Variant::STRING_NAME:
@@ -2947,23 +3051,32 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
r_iarg.default_argument = "\"" + r_iarg.default_argument + "\"";
}
break;
- case Variant::TRANSFORM:
- if (p_val.operator Transform() == Transform()) {
- r_iarg.default_argument.clear();
- }
- r_iarg.default_argument = "new %s(" + r_iarg.default_argument + ")";
+ case Variant::PLANE: {
+ Plane plane = p_val.operator Plane();
+ r_iarg.default_argument = "new Plane(new Vector3(" + plane.normal.operator String() + "), " + rtos(plane.d) + ")";
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
- break;
- case Variant::PLANE:
- case Variant::AABB:
+ } break;
+ case Variant::AABB: {
+ AABB aabb = p_val.operator ::AABB();
+ r_iarg.default_argument = "new AABB(new Vector3(" + aabb.position.operator String() + "), new Vector3(" + aabb.position.operator String() + "))";
+ r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+ } break;
+ case Variant::RECT2: {
+ Rect2 rect = p_val.operator Rect2();
+ r_iarg.default_argument = "new Rect2(new Vector2(" + rect.position.operator String() + "), new Vector2(" + rect.position.operator String() + "))";
+ r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+ } break;
+ case Variant::RECT2I: {
+ Rect2i rect = p_val.operator Rect2i();
+ r_iarg.default_argument = "new Rect2i(new Vector2i(" + rect.position.operator String() + "), new Vector2i(" + rect.position.operator String() + "))";
+ r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+ } break;
case Variant::COLOR:
- r_iarg.default_argument = "new Color(1, 1, 1, 1)";
+ r_iarg.default_argument = "new %s(" + r_iarg.default_argument + ")";
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
break;
case Variant::VECTOR2:
case Variant::VECTOR2I:
- case Variant::RECT2:
- case Variant::RECT2I:
case Variant::VECTOR3:
case Variant::VECTOR3I:
r_iarg.default_argument = "new %s" + r_iarg.default_argument;
@@ -2979,7 +3092,7 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
r_iarg.default_argument = "new %s()";
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF;
break;
- case Variant::_RID:
+ case Variant::RID:
ERR_FAIL_COND_V_MSG(r_iarg.type.cname != name_cache.type_RID, false,
"Parameter of type '" + String(r_iarg.type.cname) + "' cannot have a default value of type '" + String(name_cache.type_RID) + "'.");
@@ -3001,12 +3114,43 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
r_iarg.default_argument = "new %s {}";
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF;
break;
- case Variant::TRANSFORM2D:
- case Variant::BASIS:
- case Variant::QUAT:
- r_iarg.default_argument = Variant::get_type_name(p_val.get_type()) + ".Identity";
+ case Variant::TRANSFORM2D: {
+ Transform2D transform = p_val.operator Transform2D();
+ if (transform == Transform2D()) {
+ r_iarg.default_argument = "Transform2D.Identity";
+ } else {
+ r_iarg.default_argument = "new Transform2D(new Vector2" + transform.elements[0].operator String() + ", new Vector2" + transform.elements[1].operator String() + ", new Vector2" + transform.elements[2].operator String() + ")";
+ }
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
- break;
+ } break;
+ case Variant::TRANSFORM: {
+ Transform transform = p_val.operator Transform();
+ if (transform == Transform()) {
+ r_iarg.default_argument = "Transform.Identity";
+ } else {
+ Basis basis = transform.basis;
+ r_iarg.default_argument = "new Transform(new Vector3" + basis.get_column(0).operator String() + ", new Vector3" + basis.get_column(1).operator String() + ", new Vector3" + basis.get_column(2).operator String() + ", new Vector3" + transform.origin.operator String() + ")";
+ }
+ r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+ } break;
+ case Variant::BASIS: {
+ Basis basis = p_val.operator Basis();
+ if (basis == Basis()) {
+ r_iarg.default_argument = "Basis.Identity";
+ } else {
+ r_iarg.default_argument = "new Basis(new Vector3" + basis.get_column(0).operator String() + ", new Vector3" + basis.get_column(1).operator String() + ", new Vector3" + basis.get_column(2).operator String() + ")";
+ }
+ r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+ } break;
+ case Variant::QUAT: {
+ Quat quat = p_val.operator Quat();
+ if (quat == Quat()) {
+ r_iarg.default_argument = "Quat.Identity";
+ } else {
+ r_iarg.default_argument = "new Quat" + quat.operator String();
+ }
+ r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
+ } break;
case Variant::CALLABLE:
case Variant::SIGNAL:
CRASH_NOW_MSG("Parameter of type '" + String(r_iarg.type.cname) + "' cannot have a default value.");
@@ -3100,44 +3244,11 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
INSERT_INT_TYPE("sbyte", int8_t, int64_t);
INSERT_INT_TYPE("short", int16_t, int64_t);
INSERT_INT_TYPE("int", int32_t, int64_t);
+ INSERT_INT_TYPE("long", int64_t, int64_t);
INSERT_INT_TYPE("byte", uint8_t, int64_t);
INSERT_INT_TYPE("ushort", uint16_t, int64_t);
INSERT_INT_TYPE("uint", uint32_t, int64_t);
-
- itype = TypeInterface::create_value_type(String("long"));
- {
- itype.c_out = "\treturn (%0)%1;\n";
- itype.c_in = "\t%0 %1_in = (%0)*%1;\n";
- itype.c_out = "\t*%3 = (%0)%1;\n";
- itype.c_type = "int64_t";
- itype.c_arg_in = "&%s_in";
- }
- itype.c_type_in = "int64_t*";
- itype.c_type_out = "int64_t";
- itype.im_type_in = "ref " + itype.name;
- itype.im_type_out = "out " + itype.name;
- itype.cs_in = "ref %0";
- /* in cs_out, im_type_out (%3) includes the 'out ' part */
- itype.cs_out = "%0(%1, %3 argRet); return argRet;";
- itype.ret_as_byref_arg = true;
- builtin_types.insert(itype.cname, itype);
-
- itype = TypeInterface::create_value_type(String("ulong"));
- {
- itype.c_in = "\t%0 %1_in = (%0)*%1;\n";
- itype.c_out = "\t*%3 = (%0)%1;\n";
- itype.c_type = "int64_t";
- itype.c_arg_in = "&%s_in";
- }
- itype.c_type_in = "uint64_t*";
- itype.c_type_out = "uint64_t";
- itype.im_type_in = "ref " + itype.name;
- itype.im_type_out = "out " + itype.name;
- itype.cs_in = "ref %0";
- /* in cs_out, im_type_out (%3) includes the 'out ' part */
- itype.cs_out = "%0(%1, %3 argRet); return argRet;";
- itype.ret_as_byref_arg = true;
- builtin_types.insert(itype.cname, itype);
+ INSERT_INT_TYPE("ulong", uint64_t, int64_t);
}
// Floating point types
@@ -3149,20 +3260,16 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.proxy_name = "float";
{
// The expected type for 'float' in ptrcall is 'double'
- itype.c_in = "\t%0 %1_in = (%0)*%1;\n";
- itype.c_out = "\t*%3 = (%0)%1;\n";
+ itype.c_in = "\t%0 %1_in = (%0)%1;\n";
+ itype.c_out = "\treturn (%0)%1;\n";
itype.c_type = "double";
- itype.c_type_in = "float*";
+ itype.c_type_in = "float";
itype.c_type_out = "float";
itype.c_arg_in = "&%s_in";
}
itype.cs_type = itype.proxy_name;
- itype.im_type_in = "ref " + itype.proxy_name;
- itype.im_type_out = "out " + itype.proxy_name;
- itype.cs_in = "ref %0";
- /* in cs_out, im_type_out (%3) includes the 'out ' part */
- itype.cs_out = "%0(%1, %3 argRet); return argRet;";
- itype.ret_as_byref_arg = true;
+ itype.im_type_in = itype.proxy_name;
+ itype.im_type_out = itype.proxy_name;
builtin_types.insert(itype.cname, itype);
// double
@@ -3171,20 +3278,14 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.cname = itype.name;
itype.proxy_name = "double";
{
- itype.c_in = "\t%0 %1_in = (%0)*%1;\n";
- itype.c_out = "\t*%3 = (%0)%1;\n";
itype.c_type = "double";
- itype.c_type_in = "double*";
+ itype.c_type_in = "double";
itype.c_type_out = "double";
- itype.c_arg_in = "&%s_in";
+ itype.c_arg_in = "&%s";
}
itype.cs_type = itype.proxy_name;
- itype.im_type_in = "ref " + itype.proxy_name;
- itype.im_type_out = "out " + itype.proxy_name;
- itype.cs_in = "ref %0";
- /* in cs_out, im_type_out (%3) includes the 'out ' part */
- itype.cs_out = "%0(%1, %3 argRet); return argRet;";
- itype.ret_as_byref_arg = true;
+ itype.im_type_in = itype.proxy_name;
+ itype.im_type_out = itype.proxy_name;
builtin_types.insert(itype.cname, itype);
}
@@ -3530,11 +3631,44 @@ void BindingsGenerator::_initialize() {
initialized = true;
}
+static String generate_all_glue_option = "--generate-mono-glue";
+static String generate_cs_glue_option = "--generate-mono-cs-glue";
+static String generate_cpp_glue_option = "--generate-mono-cpp-glue";
+
+static void handle_cmdline_options(String glue_dir_path, String cs_dir_path, String cpp_dir_path) {
+ BindingsGenerator bindings_generator;
+ bindings_generator.set_log_print_enabled(true);
+
+ if (!bindings_generator.is_initialized()) {
+ ERR_PRINT("Failed to initialize the bindings generator");
+ return;
+ }
+
+ if (glue_dir_path.length()) {
+ if (bindings_generator.generate_glue(glue_dir_path) != OK) {
+ ERR_PRINT(generate_all_glue_option + ": Failed to generate the C++ glue.");
+ }
+
+ if (bindings_generator.generate_cs_api(glue_dir_path.plus_file(API_SOLUTION_NAME)) != OK) {
+ ERR_PRINT(generate_all_glue_option + ": Failed to generate the C# API.");
+ }
+ }
+
+ if (cs_dir_path.length()) {
+ if (bindings_generator.generate_cs_api(cs_dir_path) != OK) {
+ ERR_PRINT(generate_cs_glue_option + ": Failed to generate the C# API.");
+ }
+ }
+
+ if (cpp_dir_path.length()) {
+ if (bindings_generator.generate_glue(cpp_dir_path) != OK) {
+ ERR_PRINT(generate_cpp_glue_option + ": Failed to generate the C++ glue.");
+ }
+ }
+}
+
void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) {
const int NUM_OPTIONS = 2;
- String generate_all_glue_option = "--generate-mono-glue";
- String generate_cs_glue_option = "--generate-mono-cs-glue";
- String generate_cpp_glue_option = "--generate-mono-cpp-glue";
String glue_dir_path;
String cs_dir_path;
@@ -3542,6 +3676,8 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
int options_left = NUM_OPTIONS;
+ bool exit_godot = false;
+
const List<String>::Element *elem = p_cmdline_args.front();
while (elem && options_left) {
@@ -3553,6 +3689,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
elem = elem->next();
} else {
ERR_PRINT(generate_all_glue_option + ": No output directory specified (expected path to '{GODOT_ROOT}/modules/mono/glue').");
+ exit_godot = true;
}
--options_left;
@@ -3564,6 +3701,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
elem = elem->next();
} else {
ERR_PRINT(generate_cs_glue_option + ": No output directory specified.");
+ exit_godot = true;
}
--options_left;
@@ -3575,6 +3713,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
elem = elem->next();
} else {
ERR_PRINT(generate_cpp_glue_option + ": No output directory specified.");
+ exit_godot = true;
}
--options_left;
@@ -3584,37 +3723,13 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
}
if (glue_dir_path.length() || cs_dir_path.length() || cpp_dir_path.length()) {
- BindingsGenerator bindings_generator;
- bindings_generator.set_log_print_enabled(true);
-
- if (!bindings_generator.initialized) {
- ERR_PRINT("Failed to initialize the bindings generator");
- ::exit(0);
- }
-
- if (glue_dir_path.length()) {
- if (bindings_generator.generate_glue(glue_dir_path) != OK) {
- ERR_PRINT(generate_all_glue_option + ": Failed to generate the C++ glue.");
- }
-
- if (bindings_generator.generate_cs_api(glue_dir_path.plus_file(API_SOLUTION_NAME)) != OK) {
- ERR_PRINT(generate_all_glue_option + ": Failed to generate the C# API.");
- }
- }
-
- if (cs_dir_path.length()) {
- if (bindings_generator.generate_cs_api(cs_dir_path) != OK) {
- ERR_PRINT(generate_cs_glue_option + ": Failed to generate the C# API.");
- }
- }
-
- if (cpp_dir_path.length()) {
- if (bindings_generator.generate_glue(cpp_dir_path) != OK) {
- ERR_PRINT(generate_cpp_glue_option + ": Failed to generate the C++ glue.");
- }
- }
+ handle_cmdline_options(glue_dir_path, cs_dir_path, cpp_dir_path);
+ exit_godot = true;
+ }
+ if (exit_godot) {
// Exit once done
+ Main::cleanup(true);
::exit(0);
}
}
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index eeab518954..876046176b 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -31,9 +31,10 @@
#ifndef BINDINGS_GENERATOR_H
#define BINDINGS_GENERATOR_H
+#include "core/doc_data.h"
#include "core/object/class_db.h"
#include "core/string/string_builder.h"
-#include "editor/doc_data.h"
+#include "editor/doc_tools.h"
#include "editor/editor_help.h"
#if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED)
@@ -44,7 +45,7 @@ class BindingsGenerator {
struct ConstantInterface {
String name;
String proxy_name;
- int value;
+ int value = 0;
const DocData::ConstantDoc *const_doc;
ConstantInterface() {}
@@ -74,7 +75,7 @@ class BindingsGenerator {
struct PropertyInterface {
StringName cname;
String proxy_name;
- int index;
+ int index = 0;
StringName setter;
StringName getter;
@@ -479,7 +480,7 @@ class BindingsGenerator {
String im_type_out; // Return type for the C# method declaration. Also used as companion of [unique_siq]
String im_sig; // Signature for the C# method declaration
String unique_sig; // Unique signature to avoid duplicates in containers
- bool editor_only;
+ bool editor_only = false;
InternalCall() {}
@@ -660,6 +661,7 @@ class BindingsGenerator {
Error _generate_cs_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, int &p_method_bind_count, StringBuilder &p_output);
Error _generate_cs_signal(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::SignalInterface &p_isignal, StringBuilder &p_output);
+ void _generate_array_extensions(StringBuilder &p_output);
void _generate_global_constants(StringBuilder &p_output);
Error _generate_glue_method(const TypeInterface &p_itype, const MethodInterface &p_imethod, StringBuilder &p_output);
diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp
index 9defd65190..bbfba83e6f 100644
--- a/modules/mono/editor/code_completion.cpp
+++ b/modules/mono/editor/code_completion.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -150,7 +150,7 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr
List<String> directories;
directories.push_back(dir_access->get_current_dir());
- while (!directories.empty()) {
+ while (!directories.is_empty()) {
dir_access->change_dir(directories.back()->get());
directories.pop_back();
@@ -228,6 +228,18 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr
}
}
} break;
+ case CompletionKind::THEME_FONT_SIZES: {
+ Ref<Script> script = ResourceLoader::load(p_script_file.simplify_path());
+ Node *base = _try_find_owner_node_in_tree(script);
+ if (base && Object::cast_to<Control>(base)) {
+ List<StringName> sn;
+ Theme::get_default()->get_font_size_list(base->get_class(), &sn);
+
+ for (List<StringName>::Element *E = sn.front(); E; E = E->next()) {
+ suggestions.push_back(quoted(E->get()));
+ }
+ }
+ } break;
case CompletionKind::THEME_STYLES: {
Ref<Script> script = ResourceLoader::load(p_script_file.simplify_path());
Node *base = _try_find_owner_node_in_tree(script);
@@ -246,5 +258,4 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr
return suggestions;
}
-
} // namespace gdmono
diff --git a/modules/mono/editor/code_completion.h b/modules/mono/editor/code_completion.h
index b9d22de0b3..7f7521672b 100644
--- a/modules/mono/editor/code_completion.h
+++ b/modules/mono/editor/code_completion.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -46,11 +46,11 @@ enum class CompletionKind {
THEME_COLORS,
THEME_CONSTANTS,
THEME_FONTS,
+ THEME_FONT_SIZES,
THEME_STYLES
};
PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_script_file);
-
} // namespace gdmono
#endif // CODE_COMPLETION_H
diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp
index 68fc372959..21efd58938 100644
--- a/modules/mono/editor/editor_internal_calls.cpp
+++ b/modules/mono/editor/editor_internal_calls.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -47,10 +47,8 @@
#include "../godotsharp_dirs.h"
#include "../mono_gd/gd_mono_marshal.h"
#include "../utils/osx_utils.h"
-#include "bindings_generator.h"
#include "code_completion.h"
#include "godotsharp_export.h"
-#include "script_class_parser.h"
MonoString *godot_icall_GodotSharpDirs_ResDataDir() {
return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_res_data_dir());
@@ -173,65 +171,6 @@ MonoBoolean godot_icall_EditorProgress_Step(MonoString *p_task, MonoString *p_st
return EditorNode::progress_task_step(task, state, p_step, (bool)p_force_refresh);
}
-BindingsGenerator *godot_icall_BindingsGenerator_Ctor() {
- return memnew(BindingsGenerator);
-}
-
-void godot_icall_BindingsGenerator_Dtor(BindingsGenerator *p_handle) {
- memdelete(p_handle);
-}
-
-MonoBoolean godot_icall_BindingsGenerator_LogPrintEnabled(BindingsGenerator *p_handle) {
- return p_handle->is_log_print_enabled();
-}
-
-void godot_icall_BindingsGenerator_SetLogPrintEnabled(BindingsGenerator p_handle, MonoBoolean p_enabled) {
- p_handle.set_log_print_enabled(p_enabled);
-}
-
-int32_t godot_icall_BindingsGenerator_GenerateCsApi(BindingsGenerator *p_handle, MonoString *p_output_dir) {
- String output_dir = GDMonoMarshal::mono_string_to_godot(p_output_dir);
- return p_handle->generate_cs_api(output_dir);
-}
-
-uint32_t godot_icall_BindingsGenerator_Version() {
- return BindingsGenerator::get_version();
-}
-
-uint32_t godot_icall_BindingsGenerator_CsGlueVersion() {
- return CS_GLUE_VERSION;
-}
-
-int32_t godot_icall_ScriptClassParser_ParseFile(MonoString *p_filepath, MonoObject *p_classes, MonoString **r_error_str) {
- *r_error_str = nullptr;
-
- String filepath = GDMonoMarshal::mono_string_to_godot(p_filepath);
-
- ScriptClassParser scp;
- Error err = scp.parse_file(filepath);
- if (err == OK) {
- Array classes = GDMonoMarshal::mono_object_to_variant(p_classes);
- const Vector<ScriptClassParser::ClassDecl> &class_decls = scp.get_classes();
-
- for (int i = 0; i < class_decls.size(); i++) {
- const ScriptClassParser::ClassDecl &classDecl = class_decls[i];
-
- Dictionary classDeclDict;
- classDeclDict["name"] = classDecl.name;
- classDeclDict["namespace"] = classDecl.namespace_;
- classDeclDict["nested"] = classDecl.nested;
- classDeclDict["base_count"] = classDecl.base.size();
- classes.push_back(classDeclDict);
- }
- } else {
- String error_str = scp.get_error();
- if (!error_str.empty()) {
- *r_error_str = GDMonoMarshal::mono_string_from_godot(error_str);
- }
- }
- return err;
-}
-
uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoObject *p_initial_assemblies,
MonoString *p_build_config, MonoString *p_custom_bcl_dir, MonoObject *r_assembly_dependencies) {
Dictionary initial_dependencies = GDMonoMarshal::mono_object_to_variant(p_initial_assemblies);
@@ -319,18 +258,6 @@ void godot_icall_Internal_EditorNodeShowScriptScreen() {
EditorNode::get_singleton()->call("_editor_select", EditorNode::EDITOR_SCRIPT);
}
-MonoObject *godot_icall_Internal_GetScriptsMetadataOrNothing(MonoReflectionType *p_dict_reftype) {
- Dictionary maybe_metadata = CSharpLanguage::get_singleton()->get_scripts_metadata_or_nothing();
-
- MonoType *dict_type = mono_reflection_type_get_type(p_dict_reftype);
-
- int type_encoding = mono_type_get_type(dict_type);
- MonoClass *type_class_raw = mono_class_from_mono_type(dict_type);
- GDMonoClass *type_class = GDMono::get_singleton()->get_class(type_class_raw);
-
- return GDMonoMarshal::variant_to_mono_object(maybe_metadata, ManagedType(type_encoding, type_class));
-}
-
MonoString *godot_icall_Internal_MonoWindowsInstallRoot() {
#ifdef WINDOWS_ENABLED
String install_root_dir = GDMono::get_singleton()->get_mono_reg_info().install_root_dir;
@@ -400,75 +327,62 @@ MonoBoolean godot_icall_Utils_OS_UnixFileHasExecutableAccess(MonoString *p_file_
void register_editor_internal_calls() {
// GodotSharpDirs
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResDataDir", (void *)godot_icall_GodotSharpDirs_ResDataDir);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResMetadataDir", (void *)godot_icall_GodotSharpDirs_ResMetadataDir);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResAssembliesBaseDir", (void *)godot_icall_GodotSharpDirs_ResAssembliesBaseDir);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResAssembliesDir", (void *)godot_icall_GodotSharpDirs_ResAssembliesDir);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResConfigDir", (void *)godot_icall_GodotSharpDirs_ResConfigDir);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResTempDir", (void *)godot_icall_GodotSharpDirs_ResTempDir);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResTempAssembliesBaseDir", (void *)godot_icall_GodotSharpDirs_ResTempAssembliesBaseDir);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResTempAssembliesDir", (void *)godot_icall_GodotSharpDirs_ResTempAssembliesDir);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_MonoUserDir", (void *)godot_icall_GodotSharpDirs_MonoUserDir);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_MonoLogsDir", (void *)godot_icall_GodotSharpDirs_MonoLogsDir);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_MonoSolutionsDir", (void *)godot_icall_GodotSharpDirs_MonoSolutionsDir);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_BuildLogsDirs", (void *)godot_icall_GodotSharpDirs_BuildLogsDirs);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ProjectSlnPath", (void *)godot_icall_GodotSharpDirs_ProjectSlnPath);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ProjectCsProjPath", (void *)godot_icall_GodotSharpDirs_ProjectCsProjPath);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataEditorToolsDir", (void *)godot_icall_GodotSharpDirs_DataEditorToolsDir);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataEditorPrebuiltApiDir", (void *)godot_icall_GodotSharpDirs_DataEditorPrebuiltApiDir);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataMonoEtcDir", (void *)godot_icall_GodotSharpDirs_DataMonoEtcDir);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataMonoLibDir", (void *)godot_icall_GodotSharpDirs_DataMonoLibDir);
- mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataMonoBinDir", (void *)godot_icall_GodotSharpDirs_DataMonoBinDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResDataDir", godot_icall_GodotSharpDirs_ResDataDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResMetadataDir", godot_icall_GodotSharpDirs_ResMetadataDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResAssembliesBaseDir", godot_icall_GodotSharpDirs_ResAssembliesBaseDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResAssembliesDir", godot_icall_GodotSharpDirs_ResAssembliesDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResConfigDir", godot_icall_GodotSharpDirs_ResConfigDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResTempDir", godot_icall_GodotSharpDirs_ResTempDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResTempAssembliesBaseDir", godot_icall_GodotSharpDirs_ResTempAssembliesBaseDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResTempAssembliesDir", godot_icall_GodotSharpDirs_ResTempAssembliesDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_MonoUserDir", godot_icall_GodotSharpDirs_MonoUserDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_MonoLogsDir", godot_icall_GodotSharpDirs_MonoLogsDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_MonoSolutionsDir", godot_icall_GodotSharpDirs_MonoSolutionsDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_BuildLogsDirs", godot_icall_GodotSharpDirs_BuildLogsDirs);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ProjectSlnPath", godot_icall_GodotSharpDirs_ProjectSlnPath);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ProjectCsProjPath", godot_icall_GodotSharpDirs_ProjectCsProjPath);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataEditorToolsDir", godot_icall_GodotSharpDirs_DataEditorToolsDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataEditorPrebuiltApiDir", godot_icall_GodotSharpDirs_DataEditorPrebuiltApiDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataMonoEtcDir", godot_icall_GodotSharpDirs_DataMonoEtcDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataMonoLibDir", godot_icall_GodotSharpDirs_DataMonoLibDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataMonoBinDir", godot_icall_GodotSharpDirs_DataMonoBinDir);
// EditorProgress
- mono_add_internal_call("GodotTools.Internals.EditorProgress::internal_Create", (void *)godot_icall_EditorProgress_Create);
- mono_add_internal_call("GodotTools.Internals.EditorProgress::internal_Dispose", (void *)godot_icall_EditorProgress_Dispose);
- mono_add_internal_call("GodotTools.Internals.EditorProgress::internal_Step", (void *)godot_icall_EditorProgress_Step);
-
- // BiningsGenerator
- mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_Ctor", (void *)godot_icall_BindingsGenerator_Ctor);
- mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_Dtor", (void *)godot_icall_BindingsGenerator_Dtor);
- mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_LogPrintEnabled", (void *)godot_icall_BindingsGenerator_LogPrintEnabled);
- mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_SetLogPrintEnabled", (void *)godot_icall_BindingsGenerator_SetLogPrintEnabled);
- mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_GenerateCsApi", (void *)godot_icall_BindingsGenerator_GenerateCsApi);
- mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_Version", (void *)godot_icall_BindingsGenerator_Version);
- mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_CsGlueVersion", (void *)godot_icall_BindingsGenerator_CsGlueVersion);
-
- // ScriptClassParser
- mono_add_internal_call("GodotTools.Internals.ScriptClassParser::internal_ParseFile", (void *)godot_icall_ScriptClassParser_ParseFile);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.EditorProgress::internal_Create", godot_icall_EditorProgress_Create);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.EditorProgress::internal_Dispose", godot_icall_EditorProgress_Dispose);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.EditorProgress::internal_Step", godot_icall_EditorProgress_Step);
// ExportPlugin
- mono_add_internal_call("GodotTools.Export.ExportPlugin::internal_GetExportedAssemblyDependencies", (void *)godot_icall_ExportPlugin_GetExportedAssemblyDependencies);
+ GDMonoUtils::add_internal_call("GodotTools.Export.ExportPlugin::internal_GetExportedAssemblyDependencies", godot_icall_ExportPlugin_GetExportedAssemblyDependencies);
// Internals
- mono_add_internal_call("GodotTools.Internals.Internal::internal_UpdateApiAssembliesFromPrebuilt", (void *)godot_icall_Internal_UpdateApiAssembliesFromPrebuilt);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_FullTemplatesDir", (void *)godot_icall_Internal_FullTemplatesDir);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_SimplifyGodotPath", (void *)godot_icall_Internal_SimplifyGodotPath);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_IsOsxAppBundleInstalled", (void *)godot_icall_Internal_IsOsxAppBundleInstalled);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_GodotIs32Bits", (void *)godot_icall_Internal_GodotIs32Bits);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_GodotIsRealTDouble", (void *)godot_icall_Internal_GodotIsRealTDouble);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_GodotMainIteration", (void *)godot_icall_Internal_GodotMainIteration);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_GetCoreApiHash", (void *)godot_icall_Internal_GetCoreApiHash);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_GetEditorApiHash", (void *)godot_icall_Internal_GetEditorApiHash);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_IsAssembliesReloadingNeeded", (void *)godot_icall_Internal_IsAssembliesReloadingNeeded);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_ReloadAssemblies", (void *)godot_icall_Internal_ReloadAssemblies);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorDebuggerNodeReloadScripts", (void *)godot_icall_Internal_EditorDebuggerNodeReloadScripts);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorEdit", (void *)godot_icall_Internal_ScriptEditorEdit);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorNodeShowScriptScreen", (void *)godot_icall_Internal_EditorNodeShowScriptScreen);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_GetScriptsMetadataOrNothing", (void *)godot_icall_Internal_GetScriptsMetadataOrNothing);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_MonoWindowsInstallRoot", (void *)godot_icall_Internal_MonoWindowsInstallRoot);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorRunPlay", (void *)godot_icall_Internal_EditorRunPlay);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorRunStop", (void *)godot_icall_Internal_EditorRunStop);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorDebugger_ReloadScripts", (void *)godot_icall_Internal_ScriptEditorDebugger_ReloadScripts);
- mono_add_internal_call("GodotTools.Internals.Internal::internal_CodeCompletionRequest", (void *)godot_icall_Internal_CodeCompletionRequest);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_UpdateApiAssembliesFromPrebuilt", godot_icall_Internal_UpdateApiAssembliesFromPrebuilt);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_FullTemplatesDir", godot_icall_Internal_FullTemplatesDir);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_SimplifyGodotPath", godot_icall_Internal_SimplifyGodotPath);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_IsOsxAppBundleInstalled", godot_icall_Internal_IsOsxAppBundleInstalled);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GodotIs32Bits", godot_icall_Internal_GodotIs32Bits);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GodotIsRealTDouble", godot_icall_Internal_GodotIsRealTDouble);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GodotMainIteration", godot_icall_Internal_GodotMainIteration);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GetCoreApiHash", godot_icall_Internal_GetCoreApiHash);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GetEditorApiHash", godot_icall_Internal_GetEditorApiHash);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_IsAssembliesReloadingNeeded", godot_icall_Internal_IsAssembliesReloadingNeeded);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_ReloadAssemblies", godot_icall_Internal_ReloadAssemblies);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_EditorDebuggerNodeReloadScripts", godot_icall_Internal_EditorDebuggerNodeReloadScripts);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorEdit", godot_icall_Internal_ScriptEditorEdit);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_EditorNodeShowScriptScreen", godot_icall_Internal_EditorNodeShowScriptScreen);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_MonoWindowsInstallRoot", godot_icall_Internal_MonoWindowsInstallRoot);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_EditorRunPlay", godot_icall_Internal_EditorRunPlay);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_EditorRunStop", godot_icall_Internal_EditorRunStop);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorDebugger_ReloadScripts", godot_icall_Internal_ScriptEditorDebugger_ReloadScripts);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_CodeCompletionRequest", godot_icall_Internal_CodeCompletionRequest);
// Globals
- mono_add_internal_call("GodotTools.Internals.Globals::internal_EditorScale", (void *)godot_icall_Globals_EditorScale);
- mono_add_internal_call("GodotTools.Internals.Globals::internal_GlobalDef", (void *)godot_icall_Globals_GlobalDef);
- mono_add_internal_call("GodotTools.Internals.Globals::internal_EditorDef", (void *)godot_icall_Globals_EditorDef);
- mono_add_internal_call("GodotTools.Internals.Globals::internal_TTR", (void *)godot_icall_Globals_TTR);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Globals::internal_EditorScale", godot_icall_Globals_EditorScale);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Globals::internal_GlobalDef", godot_icall_Globals_GlobalDef);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Globals::internal_EditorDef", godot_icall_Globals_EditorDef);
+ GDMonoUtils::add_internal_call("GodotTools.Internals.Globals::internal_TTR", godot_icall_Globals_TTR);
// Utils.OS
- mono_add_internal_call("GodotTools.Utils.OS::GetPlatformName", (void *)godot_icall_Utils_OS_GetPlatformName);
- mono_add_internal_call("GodotTools.Utils.OS::UnixFileHasExecutableAccess", (void *)godot_icall_Utils_OS_UnixFileHasExecutableAccess);
+ GDMonoUtils::add_internal_call("GodotTools.Utils.OS::GetPlatformName", godot_icall_Utils_OS_GetPlatformName);
+ GDMonoUtils::add_internal_call("GodotTools.Utils.OS::UnixFileHasExecutableAccess", godot_icall_Utils_OS_UnixFileHasExecutableAccess);
}
diff --git a/modules/mono/editor/editor_internal_calls.h b/modules/mono/editor/editor_internal_calls.h
index ef4e639161..24080cd867 100644
--- a/modules/mono/editor/editor_internal_calls.h
+++ b/modules/mono/editor/editor_internal_calls.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp
index 4fa753ab8b..4b858c0e82 100644
--- a/modules/mono/editor/godotsharp_export.cpp
+++ b/modules/mono/editor/godotsharp_export.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -55,10 +55,10 @@ MonoAssemblyName *new_mono_assembly_name() {
struct AssemblyRefInfo {
String name;
- uint16_t major;
- uint16_t minor;
- uint16_t build;
- uint16_t revision;
+ uint16_t major = 0;
+ uint16_t minor = 0;
+ uint16_t build = 0;
+ uint16_t revision = 0;
};
AssemblyRefInfo get_assemblyref_name(MonoImage *p_image, int index) {
@@ -141,5 +141,4 @@ Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies,
return OK;
}
-
} // namespace GodotSharpExport
diff --git a/modules/mono/editor/godotsharp_export.h b/modules/mono/editor/godotsharp_export.h
index bd0f86a74b..0e9d689618 100644
--- a/modules/mono/editor/godotsharp_export.h
+++ b/modules/mono/editor/godotsharp_export.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -43,7 +43,6 @@ Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String>
Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies,
const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_assembly_dependencies);
-
} // namespace GodotSharpExport
#endif // GODOTSHARP_EXPORT_H
diff --git a/modules/mono/editor/script_class_parser.cpp b/modules/mono/editor/script_class_parser.cpp
deleted file mode 100644
index 70940c279e..0000000000
--- a/modules/mono/editor/script_class_parser.cpp
+++ /dev/null
@@ -1,753 +0,0 @@
-/*************************************************************************/
-/* script_class_parser.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 "script_class_parser.h"
-
-#include "core/os/os.h"
-#include "core/templates/map.h"
-
-#include "../utils/string_utils.h"
-
-const char *ScriptClassParser::token_names[ScriptClassParser::TK_MAX] = {
- "[",
- "]",
- "{",
- "}",
- ".",
- ":",
- ",",
- "Symbol",
- "Identifier",
- "String",
- "Number",
- "<",
- ">",
- "EOF",
- "Error"
-};
-
-String ScriptClassParser::get_token_name(ScriptClassParser::Token p_token) {
- ERR_FAIL_INDEX_V(p_token, TK_MAX, "<error>");
- return token_names[p_token];
-}
-
-ScriptClassParser::Token ScriptClassParser::get_token() {
- while (true) {
- switch (code[idx]) {
- case '\n': {
- line++;
- idx++;
- break;
- };
- case 0: {
- return TK_EOF;
- } break;
- case '{': {
- idx++;
- return TK_CURLY_BRACKET_OPEN;
- };
- case '}': {
- idx++;
- return TK_CURLY_BRACKET_CLOSE;
- };
- case '[': {
- idx++;
- return TK_BRACKET_OPEN;
- };
- case ']': {
- idx++;
- return TK_BRACKET_CLOSE;
- };
- case '<': {
- idx++;
- return TK_OP_LESS;
- };
- case '>': {
- idx++;
- return TK_OP_GREATER;
- };
- case ':': {
- idx++;
- return TK_COLON;
- };
- case ',': {
- idx++;
- return TK_COMMA;
- };
- case '.': {
- idx++;
- return TK_PERIOD;
- };
- case '#': {
- //compiler directive
- while (code[idx] != '\n' && code[idx] != 0) {
- idx++;
- }
- continue;
- } break;
- case '/': {
- switch (code[idx + 1]) {
- case '*': { // block comment
- idx += 2;
- while (true) {
- if (code[idx] == 0) {
- error_str = "Unterminated comment";
- error = true;
- return TK_ERROR;
- } else if (code[idx] == '*' && code[idx + 1] == '/') {
- idx += 2;
- break;
- } else if (code[idx] == '\n') {
- line++;
- }
-
- idx++;
- }
-
- } break;
- case '/': { // line comment skip
- while (code[idx] != '\n' && code[idx] != 0) {
- idx++;
- }
-
- } break;
- default: {
- value = "/";
- idx++;
- return TK_SYMBOL;
- }
- }
-
- continue; // a comment
- } break;
- case '\'':
- case '"': {
- bool verbatim = idx != 0 && code[idx - 1] == '@';
-
- char32_t begin_str = code[idx];
- idx++;
- String tk_string = String();
- while (true) {
- if (code[idx] == 0) {
- error_str = "Unterminated String";
- error = true;
- return TK_ERROR;
- } else if (code[idx] == begin_str) {
- if (verbatim && code[idx + 1] == '"') { // '""' is verbatim string's '\"'
- idx += 2; // skip next '"' as well
- continue;
- }
-
- idx += 1;
- break;
- } else if (code[idx] == '\\' && !verbatim) {
- //escaped characters...
- idx++;
- char32_t next = code[idx];
- if (next == 0) {
- error_str = "Unterminated String";
- error = true;
- return TK_ERROR;
- }
- char32_t res = 0;
-
- switch (next) {
- case 'b':
- res = 8;
- break;
- case 't':
- res = 9;
- break;
- case 'n':
- res = 10;
- break;
- case 'f':
- res = 12;
- break;
- case 'r':
- res = 13;
- break;
- case '\"':
- res = '\"';
- break;
- case '\\':
- res = '\\';
- break;
- default: {
- res = next;
- } break;
- }
-
- tk_string += res;
-
- } else {
- if (code[idx] == '\n') {
- line++;
- }
- tk_string += code[idx];
- }
- idx++;
- }
-
- value = tk_string;
-
- return TK_STRING;
- } break;
- default: {
- if (code[idx] <= 32) {
- idx++;
- break;
- }
-
- if ((code[idx] >= 33 && code[idx] <= 47) || (code[idx] >= 58 && code[idx] <= 63) || (code[idx] >= 91 && code[idx] <= 94) || code[idx] == 96 || (code[idx] >= 123 && code[idx] <= 127)) {
- value = String::chr(code[idx]);
- idx++;
- return TK_SYMBOL;
- }
-
- if (code[idx] == '-' || (code[idx] >= '0' && code[idx] <= '9')) {
- //a number
- const char32_t *rptr;
- double number = String::to_float(&code[idx], &rptr);
- idx += (rptr - &code[idx]);
- value = number;
- return TK_NUMBER;
-
- } else if ((code[idx] == '@' && code[idx + 1] != '"') || code[idx] == '_' || (code[idx] >= 'A' && code[idx] <= 'Z') || (code[idx] >= 'a' && code[idx] <= 'z') || code[idx] > 127) {
- String id;
-
- id += code[idx];
- idx++;
-
- while (code[idx] == '_' || (code[idx] >= 'A' && code[idx] <= 'Z') || (code[idx] >= 'a' && code[idx] <= 'z') || (code[idx] >= '0' && code[idx] <= '9') || code[idx] > 127) {
- id += code[idx];
- idx++;
- }
-
- value = id;
- return TK_IDENTIFIER;
- } else if (code[idx] == '@' && code[idx + 1] == '"') {
- // begin of verbatim string
- idx++;
- } else {
- error_str = "Unexpected character.";
- error = true;
- return TK_ERROR;
- }
- }
- }
- }
-}
-
-Error ScriptClassParser::_skip_generic_type_params() {
- Token tk;
-
- while (true) {
- tk = get_token();
-
- if (tk == TK_IDENTIFIER) {
- tk = get_token();
- // Type specifications can end with "?" to denote nullable types, such as IList<int?>
- if (tk == TK_SYMBOL) {
- tk = get_token();
- if (value.operator String() != "?") {
- error_str = "Expected " + get_token_name(TK_IDENTIFIER) + ", found unexpected symbol '" + value + "'";
- error = true;
- return ERR_PARSE_ERROR;
- }
- if (tk != TK_OP_GREATER && tk != TK_COMMA) {
- error_str = "Nullable type symbol '?' is only allowed after an identifier, but found " + get_token_name(tk) + " next.";
- error = true;
- return ERR_PARSE_ERROR;
- }
- }
-
- if (tk == TK_PERIOD) {
- while (true) {
- tk = get_token();
-
- if (tk != TK_IDENTIFIER) {
- error_str = "Expected " + get_token_name(TK_IDENTIFIER) + ", found: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- tk = get_token();
-
- if (tk != TK_PERIOD) {
- break;
- }
- }
- }
-
- if (tk == TK_OP_LESS) {
- Error err = _skip_generic_type_params();
- if (err) {
- return err;
- }
- tk = get_token();
- }
-
- if (tk == TK_OP_GREATER) {
- return OK;
- } else if (tk != TK_COMMA) {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
- } else if (tk == TK_OP_LESS) {
- error_str = "Expected " + get_token_name(TK_IDENTIFIER) + ", found " + get_token_name(TK_OP_LESS);
- error = true;
- return ERR_PARSE_ERROR;
- } else if (tk == TK_OP_GREATER) {
- return OK;
- } else {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
- }
-}
-
-Error ScriptClassParser::_parse_type_full_name(String &r_full_name) {
- Token tk = get_token();
-
- if (tk != TK_IDENTIFIER) {
- error_str = "Expected " + get_token_name(TK_IDENTIFIER) + ", found: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- r_full_name += String(value);
-
- if (code[idx] == '<') {
- idx++;
-
- // We don't mind if the base is generic, but we skip it any ways since this information is not needed
- Error err = _skip_generic_type_params();
- if (err) {
- return err;
- }
- }
-
- if (code[idx] != '.') { // We only want to take the next token if it's a period
- return OK;
- }
-
- tk = get_token();
-
- CRASH_COND(tk != TK_PERIOD); // Assertion
-
- r_full_name += ".";
-
- return _parse_type_full_name(r_full_name);
-}
-
-Error ScriptClassParser::_parse_class_base(Vector<String> &r_base) {
- String name;
-
- Error err = _parse_type_full_name(name);
- if (err) {
- return err;
- }
-
- Token tk = get_token();
-
- if (tk == TK_COMMA) {
- err = _parse_class_base(r_base);
- if (err) {
- return err;
- }
- } else if (tk == TK_IDENTIFIER && String(value) == "where") {
- err = _parse_type_constraints();
- if (err) {
- return err;
- }
-
- // An open curly bracket was parsed by _parse_type_constraints, so we can exit
- } else if (tk == TK_CURLY_BRACKET_OPEN) {
- // we are finished when we hit the open curly bracket
- } else {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- r_base.push_back(name);
-
- return OK;
-}
-
-Error ScriptClassParser::_parse_type_constraints() {
- Token tk = get_token();
- if (tk != TK_IDENTIFIER) {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- tk = get_token();
- if (tk != TK_COLON) {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- while (true) {
- tk = get_token();
- if (tk == TK_IDENTIFIER) {
- if (String(value) == "where") {
- return _parse_type_constraints();
- }
-
- tk = get_token();
- if (tk == TK_PERIOD) {
- while (true) {
- tk = get_token();
-
- if (tk != TK_IDENTIFIER) {
- error_str = "Expected " + get_token_name(TK_IDENTIFIER) + ", found: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- tk = get_token();
-
- if (tk != TK_PERIOD) {
- break;
- }
- }
- }
- }
-
- if (tk == TK_COMMA) {
- continue;
- } else if (tk == TK_IDENTIFIER && String(value) == "where") {
- return _parse_type_constraints();
- } else if (tk == TK_SYMBOL && String(value) == "(") {
- tk = get_token();
- if (tk != TK_SYMBOL || String(value) != ")") {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
- } else if (tk == TK_OP_LESS) {
- Error err = _skip_generic_type_params();
- if (err) {
- return err;
- }
- } else if (tk == TK_CURLY_BRACKET_OPEN) {
- return OK;
- } else {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
- }
-}
-
-Error ScriptClassParser::_parse_namespace_name(String &r_name, int &r_curly_stack) {
- Token tk = get_token();
-
- if (tk == TK_IDENTIFIER) {
- r_name += String(value);
- } else {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- tk = get_token();
-
- if (tk == TK_PERIOD) {
- r_name += ".";
- return _parse_namespace_name(r_name, r_curly_stack);
- } else if (tk == TK_CURLY_BRACKET_OPEN) {
- r_curly_stack++;
- return OK;
- } else {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
-}
-
-Error ScriptClassParser::parse(const String &p_code) {
- code = p_code;
- idx = 0;
- line = 0;
- error_str = String();
- error = false;
- value = Variant();
- classes.clear();
-
- Token tk = get_token();
-
- Map<int, NameDecl> name_stack;
- int curly_stack = 0;
- int type_curly_stack = 0;
-
- while (!error && tk != TK_EOF) {
- String identifier = value;
- if (tk == TK_IDENTIFIER && (identifier == "class" || identifier == "struct")) {
- bool is_class = identifier == "class";
-
- tk = get_token();
-
- if (tk == TK_IDENTIFIER) {
- String name = value;
- int at_level = curly_stack;
-
- ClassDecl class_decl;
-
- for (Map<int, NameDecl>::Element *E = name_stack.front(); E; E = E->next()) {
- const NameDecl &name_decl = E->value();
-
- if (name_decl.type == NameDecl::NAMESPACE_DECL) {
- if (E != name_stack.front()) {
- class_decl.namespace_ += ".";
- }
- class_decl.namespace_ += name_decl.name;
- } else {
- class_decl.name += name_decl.name + ".";
- }
- }
-
- class_decl.name += name;
- class_decl.nested = type_curly_stack > 0;
-
- bool generic = false;
-
- while (true) {
- tk = get_token();
-
- if (tk == TK_COLON) {
- Error err = _parse_class_base(class_decl.base);
- if (err) {
- return err;
- }
-
- curly_stack++;
- type_curly_stack++;
-
- break;
- } else if (tk == TK_CURLY_BRACKET_OPEN) {
- curly_stack++;
- type_curly_stack++;
- break;
- } else if (tk == TK_OP_LESS && !generic) {
- generic = true;
-
- Error err = _skip_generic_type_params();
- if (err) {
- return err;
- }
- } else if (tk == TK_IDENTIFIER && String(value) == "where") {
- Error err = _parse_type_constraints();
- if (err) {
- return err;
- }
-
- // An open curly bracket was parsed by _parse_type_constraints, so we can exit
- curly_stack++;
- type_curly_stack++;
- break;
- } else {
- error_str = "Unexpected token: " + get_token_name(tk);
- error = true;
- return ERR_PARSE_ERROR;
- }
- }
-
- NameDecl name_decl;
- name_decl.name = name;
- name_decl.type = is_class ? NameDecl::CLASS_DECL : NameDecl::STRUCT_DECL;
- name_stack[at_level] = name_decl;
-
- if (is_class) {
- if (!generic) { // no generics, thanks
- classes.push_back(class_decl);
- } else if (OS::get_singleton()->is_stdout_verbose()) {
- String full_name = class_decl.namespace_;
- if (full_name.length()) {
- full_name += ".";
- }
- full_name += class_decl.name;
- OS::get_singleton()->print("Ignoring generic class declaration: %s\n", full_name.utf8().get_data());
- }
- }
- }
- } else if (tk == TK_IDENTIFIER && identifier == "namespace") {
- if (type_curly_stack > 0) {
- error_str = "Found namespace nested inside type.";
- error = true;
- return ERR_PARSE_ERROR;
- }
-
- String name;
- int at_level = curly_stack;
-
- Error err = _parse_namespace_name(name, curly_stack);
- if (err) {
- return err;
- }
-
- NameDecl name_decl;
- name_decl.name = name;
- name_decl.type = NameDecl::NAMESPACE_DECL;
- name_stack[at_level] = name_decl;
- } else if (tk == TK_CURLY_BRACKET_OPEN) {
- curly_stack++;
- } else if (tk == TK_CURLY_BRACKET_CLOSE) {
- curly_stack--;
- if (name_stack.has(curly_stack)) {
- if (name_stack[curly_stack].type != NameDecl::NAMESPACE_DECL) {
- type_curly_stack--;
- }
- name_stack.erase(curly_stack);
- }
- }
-
- tk = get_token();
- }
-
- if (!error && tk == TK_EOF && curly_stack > 0) {
- error_str = "Reached EOF with missing close curly brackets.";
- error = true;
- }
-
- if (error) {
- return ERR_PARSE_ERROR;
- }
-
- return OK;
-}
-
-static String get_preprocessor_directive(const String &p_line, int p_from) {
- CRASH_COND(p_line[p_from] != '#');
- p_from++;
- int i = p_from;
- while (i < p_line.length() && (p_line[i] == '_' || (p_line[i] >= 'A' && p_line[i] <= 'Z') ||
- (p_line[i] >= 'a' && p_line[i] <= 'z') || p_line[i] > 127)) {
- i++;
- }
- return p_line.substr(p_from, i - p_from);
-}
-
-static void run_dummy_preprocessor(String &r_source, const String &p_filepath) {
- Vector<String> lines = r_source.split("\n", /* p_allow_empty: */ true);
-
- bool *include_lines = memnew_arr(bool, lines.size());
-
- int if_level = -1;
- Vector<bool> is_branch_being_compiled;
-
- for (int i = 0; i < lines.size(); i++) {
- const String &line = lines[i];
-
- const int line_len = line.length();
-
- int j;
- for (j = 0; j < line_len; j++) {
- if (line[j] != ' ' && line[j] != '\t') {
- if (line[j] == '#') {
- // First non-whitespace char of the line is '#'
- include_lines[i] = false;
-
- String directive = get_preprocessor_directive(line, j);
-
- if (directive == "if") {
- if_level++;
- is_branch_being_compiled.push_back(if_level == 0 || is_branch_being_compiled[if_level - 1]);
- } else if (directive == "elif") {
- ERR_CONTINUE_MSG(if_level == -1, "Found unexpected '#elif' directive. File: '" + p_filepath + "'.");
- is_branch_being_compiled.write[if_level] = false;
- } else if (directive == "else") {
- ERR_CONTINUE_MSG(if_level == -1, "Found unexpected '#else' directive. File: '" + p_filepath + "'.");
- is_branch_being_compiled.write[if_level] = false;
- } else if (directive == "endif") {
- ERR_CONTINUE_MSG(if_level == -1, "Found unexpected '#endif' directive. File: '" + p_filepath + "'.");
- is_branch_being_compiled.remove(if_level);
- if_level--;
- }
-
- break;
- } else {
- // First non-whitespace char of the line is not '#'
- include_lines[i] = if_level == -1 || is_branch_being_compiled[if_level];
- break;
- }
- }
- }
-
- if (j == line_len) {
- // Loop ended without finding a non-whitespace character.
- // Either the line was empty or it only contained whitespaces.
- include_lines[i] = if_level == -1 || is_branch_being_compiled[if_level];
- }
- }
-
- r_source.clear();
-
- // Custom join ignoring lines removed by the preprocessor
- for (int i = 0; i < lines.size(); i++) {
- if (i > 0 && include_lines[i - 1]) {
- r_source += '\n';
- }
-
- if (include_lines[i]) {
- r_source += lines[i];
- }
- }
-}
-
-Error ScriptClassParser::parse_file(const String &p_filepath) {
- String source;
-
- Error ferr = read_all_file_utf8(p_filepath, source);
-
- ERR_FAIL_COND_V_MSG(ferr != OK, ferr,
- ferr == ERR_INVALID_DATA ?
- "File '" + p_filepath + "' contains invalid unicode (UTF-8), so it was not loaded."
- " Please ensure that scripts are saved in valid UTF-8 unicode." :
- "Failed to read file: '" + p_filepath + "'.");
-
- run_dummy_preprocessor(source, p_filepath);
-
- return parse(source);
-}
-
-String ScriptClassParser::get_error() {
- return error_str;
-}
-
-Vector<ScriptClassParser::ClassDecl> ScriptClassParser::get_classes() {
- return classes;
-}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs
new file mode 100644
index 0000000000..ef135da51a
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/AssemblyHasScriptsAttribute.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace Godot
+{
+ [AttributeUsage(AttributeTargets.Assembly)]
+ public class AssemblyHasScriptsAttribute : Attribute
+ {
+ private readonly bool requiresLookup;
+ private readonly System.Type[] scriptTypes;
+
+ public AssemblyHasScriptsAttribute()
+ {
+ requiresLookup = true;
+ }
+
+ public AssemblyHasScriptsAttribute(System.Type[] scriptTypes)
+ {
+ requiresLookup = false;
+ this.scriptTypes = scriptTypes;
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs
new file mode 100644
index 0000000000..ac6cffceb2
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/DisableGodotGeneratorsAttribute.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Godot
+{
+ [AttributeUsage(AttributeTargets.Class)]
+ public class DisableGodotGeneratorsAttribute : Attribute
+ {
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs
new file mode 100644
index 0000000000..12eb1035c3
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ScriptPathAttribute.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace Godot
+{
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
+ public class ScriptPathAttribute : Attribute
+ {
+ private string path;
+
+ public ScriptPathAttribute(string path)
+ {
+ this.path = path;
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
index d0add835c0..0c333d06ef 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
@@ -104,7 +104,7 @@ namespace Godot
/// <summary>
/// The HSV hue of this color, on the range 0 to 1.
/// </summary>
- /// <value>Getting is a long process, refer to the source code for details. Setting uses <see cref="FromHsv"/>.</value>
+ /// <value>Getting is a long process, refer to the source code for details. Setting uses <see cref="FromHSV"/>.</value>
public float h
{
get
@@ -145,14 +145,14 @@ namespace Godot
}
set
{
- this = FromHsv(value, s, v, a);
+ this = FromHSV(value, s, v, a);
}
}
/// <summary>
/// The HSV saturation of this color, on the range 0 to 1.
/// </summary>
- /// <value>Getting is equivalent to the ratio between the min and max RGB value. Setting uses <see cref="FromHsv"/>.</value>
+ /// <value>Getting is equivalent to the ratio between the min and max RGB value. Setting uses <see cref="FromHSV"/>.</value>
public float s
{
get
@@ -166,14 +166,14 @@ namespace Godot
}
set
{
- this = FromHsv(h, value, v, a);
+ this = FromHSV(h, value, v, a);
}
}
/// <summary>
/// The HSV value (brightness) of this color, on the range 0 to 1.
/// </summary>
- /// <value>Getting is equivalent to using `Max()` on the RGB components. Setting uses <see cref="FromHsv"/>.</value>
+ /// <value>Getting is equivalent to using `Max()` on the RGB components. Setting uses <see cref="FromHSV"/>.</value>
public float v
{
get
@@ -182,7 +182,7 @@ namespace Godot
}
set
{
- this = FromHsv(h, s, value, a);
+ this = FromHSV(h, s, value, a);
}
}
@@ -337,8 +337,8 @@ namespace Godot
}
/// <summary>
- /// Returns the color's 32-bit integer in ABGR format
- /// (each byte represents a component of the ABGR profile).
+ /// Returns the color converted to an unsigned 32-bit integer in ABGR
+ /// format (each byte represents a color channel).
/// ABGR is the reversed version of the default format.
/// </summary>
/// <returns>A uint representing this color in ABGR32 format.</returns>
@@ -356,8 +356,8 @@ namespace Godot
}
/// <summary>
- /// Returns the color's 64-bit integer in ABGR format
- /// (each word represents a component of the ABGR profile).
+ /// Returns the color converted to an unsigned 64-bit integer in ABGR
+ /// format (each word represents a color channel).
/// ABGR is the reversed version of the default format.
/// </summary>
/// <returns>A ulong representing this color in ABGR64 format.</returns>
@@ -375,8 +375,8 @@ namespace Godot
}
/// <summary>
- /// Returns the color's 32-bit integer in ARGB format
- /// (each byte represents a component of the ARGB profile).
+ /// Returns the color converted to an unsigned 32-bit integer in ARGB
+ /// format (each byte represents a color channel).
/// ARGB is more compatible with DirectX, but not used much in Godot.
/// </summary>
/// <returns>A uint representing this color in ARGB32 format.</returns>
@@ -394,8 +394,8 @@ namespace Godot
}
/// <summary>
- /// Returns the color's 64-bit integer in ARGB format
- /// (each word represents a component of the ARGB profile).
+ /// Returns the color converted to an unsigned 64-bit integer in ARGB
+ /// format (each word represents a color channel).
/// ARGB is more compatible with DirectX, but not used much in Godot.
/// </summary>
/// <returns>A ulong representing this color in ARGB64 format.</returns>
@@ -413,8 +413,8 @@ namespace Godot
}
/// <summary>
- /// Returns the color's 32-bit integer in RGBA format
- /// (each byte represents a component of the RGBA profile).
+ /// Returns the color converted to an unsigned 32-bit integer in RGBA
+ /// format (each byte represents a color channel).
/// RGBA is Godot's default and recommended format.
/// </summary>
/// <returns>A uint representing this color in RGBA32 format.</returns>
@@ -432,8 +432,8 @@ namespace Godot
}
/// <summary>
- /// Returns the color's 64-bit integer in RGBA format
- /// (each word represents a component of the RGBA profile).
+ /// Returns the color converted to an unsigned 64-bit integer in RGBA
+ /// format (each word represents a color channel).
/// RGBA is Godot's default and recommended format.
/// </summary>
/// <returns>A ulong representing this color in RGBA64 format.</returns>
@@ -455,7 +455,7 @@ namespace Godot
/// </summary>
/// <param name="includeAlpha">Whether or not to include alpha. If false, the color is RGB instead of RGBA.</param>
/// <returns>A string for the HTML hexadecimal representation of this color.</returns>
- public string ToHtml(bool includeAlpha = true)
+ public string ToHTML(bool includeAlpha = true)
{
var txt = string.Empty;
@@ -472,7 +472,7 @@ namespace Godot
}
/// <summary>
- /// Constructs a color from RGBA values on the range of 0 to 1.
+ /// Constructs a color from RGBA values, typically on the range of 0 to 1.
/// </summary>
/// <param name="r">The color's red component, typically on the range of 0 to 1.</param>
/// <param name="g">The color's green component, typically on the range of 0 to 1.</param>
@@ -500,8 +500,8 @@ namespace Godot
}
/// <summary>
- /// Constructs a color from a 32-bit integer
- /// (each byte represents a component of the RGBA profile).
+ /// Constructs a color from an unsigned 32-bit integer in RGBA format
+ /// (each byte represents a color channel).
/// </summary>
/// <param name="rgba">The uint representing the color.</param>
public Color(uint rgba)
@@ -516,8 +516,8 @@ namespace Godot
}
/// <summary>
- /// Constructs a color from a 64-bit integer
- /// (each word represents a component of the RGBA profile).
+ /// Constructs a color from an unsigned 64-bit integer in RGBA format
+ /// (each word represents a color channel).
/// </summary>
/// <param name="rgba">The ulong representing the color.</param>
public Color(ulong rgba)
@@ -532,18 +532,50 @@ namespace Godot
}
/// <summary>
+ /// Constructs a color either from an HTML color code or from a
+ /// standardized color name. Supported
+ /// color names are the same as the <see cref="Colors"/> constants.
+ /// </summary>
+ /// <param name="code">The HTML color code or color name to construct from.</param>
+ public Color(string code)
+ {
+ if (HtmlIsValid(code))
+ {
+ this = FromHTML(code);
+ }
+ else
+ {
+ this = Named(code);
+ }
+ }
+
+ /// <summary>
+ /// Constructs a color either from an HTML color code or from a
+ /// standardized color name, with `alpha` on the range of 0 to 1. Supported
+ /// color names are the same as the <see cref="Colors"/> constants.
+ /// </summary>
+ /// <param name="code">The HTML color code or color name to construct from.</param>
+ /// <param name="alpha">The alpha (transparency) value, typically on the range of 0 to 1.</param>
+ public Color(string code, float alpha)
+ {
+ this = new Color(code);
+ a = alpha;
+ }
+
+ /// <summary>
/// Constructs a color from the HTML hexadecimal color string in RGBA format.
/// </summary>
/// <param name="rgba">A string for the HTML hexadecimal representation of this color.</param>
- public Color(string rgba)
+ private static Color FromHTML(string rgba)
{
+ Color c;
if (rgba.Length == 0)
{
- r = 0f;
- g = 0f;
- b = 0f;
- a = 1.0f;
- return;
+ c.r = 0f;
+ c.g = 0f;
+ c.b = 0f;
+ c.a = 1.0f;
+ return c;
}
if (rgba[0] == '#')
@@ -577,47 +609,48 @@ namespace Godot
throw new ArgumentOutOfRangeException("Invalid color code. Length is " + rgba.Length + " but a length of 6 or 8 is expected: " + rgba);
}
- a = 1.0f;
+ c.a = 1.0f;
if (isShorthand)
{
- r = ParseCol4(rgba, 0) / 15f;
- g = ParseCol4(rgba, 1) / 15f;
- b = ParseCol4(rgba, 2) / 15f;
+ c.r = ParseCol4(rgba, 0) / 15f;
+ c.g = ParseCol4(rgba, 1) / 15f;
+ c.b = ParseCol4(rgba, 2) / 15f;
if (alpha)
{
- a = ParseCol4(rgba, 3) / 15f;
+ c.a = ParseCol4(rgba, 3) / 15f;
}
}
else
{
- r = ParseCol8(rgba, 0) / 255f;
- g = ParseCol8(rgba, 2) / 255f;
- b = ParseCol8(rgba, 4) / 255f;
+ c.r = ParseCol8(rgba, 0) / 255f;
+ c.g = ParseCol8(rgba, 2) / 255f;
+ c.b = ParseCol8(rgba, 4) / 255f;
if (alpha)
{
- a = ParseCol8(rgba, 6) / 255f;
+ c.a = ParseCol8(rgba, 6) / 255f;
}
}
- if (r < 0)
+ if (c.r < 0)
{
throw new ArgumentOutOfRangeException("Invalid color code. Red part is not valid hexadecimal: " + rgba);
}
- if (g < 0)
+ if (c.g < 0)
{
throw new ArgumentOutOfRangeException("Invalid color code. Green part is not valid hexadecimal: " + rgba);
}
- if (b < 0)
+ if (c.b < 0)
{
throw new ArgumentOutOfRangeException("Invalid color code. Blue part is not valid hexadecimal: " + rgba);
}
- if (a < 0)
+ if (c.a < 0)
{
throw new ArgumentOutOfRangeException("Invalid color code. Alpha part is not valid hexadecimal: " + rgba);
}
+ return c;
}
/// <summary>
@@ -640,9 +673,8 @@ namespace Godot
/// the constants defined in <see cref="Colors"/>.
/// </summary>
/// <param name="name">The name of the color.</param>
- /// <param name="alpha">The alpha (transparency) component represented on the range of 0 to 1. Default: 1.</param>
/// <returns>The constructed color.</returns>
- public static Color ColorN(string name, float alpha = 1f)
+ private static Color Named(string name)
{
name = name.Replace(" ", String.Empty);
name = name.Replace("-", String.Empty);
@@ -656,9 +688,7 @@ namespace Godot
throw new ArgumentOutOfRangeException($"Invalid Color Name: {name}");
}
- Color color = Colors.namedColors[name];
- color.a = alpha;
- return color;
+ return Colors.namedColors[name];
}
/// <summary>
@@ -671,11 +701,11 @@ namespace Godot
/// <param name="value">The HSV value (brightness), typically on the range of 0 to 1.</param>
/// <param name="alpha">The alpha (transparency) value, typically on the range of 0 to 1.</param>
/// <returns>The constructed color.</returns>
- public static Color FromHsv(float hue, float saturation, float value, float alpha = 1.0f)
+ public static Color FromHSV(float hue, float saturation, float value, float alpha = 1.0f)
{
if (saturation == 0)
{
- // acp_hromatic (grey)
+ // Achromatic (grey)
return new Color(value, value, value, alpha);
}
@@ -715,7 +745,7 @@ namespace Godot
/// <param name="hue">Output parameter for the HSV hue.</param>
/// <param name="saturation">Output parameter for the HSV saturation.</param>
/// <param name="value">Output parameter for the HSV value.</param>
- public void ToHsv(out float hue, out float saturation, out float value)
+ public void ToHSV(out float hue, out float saturation, out float value)
{
float max = (float)Mathf.Max(r, Mathf.Max(g, b));
float min = (float)Mathf.Min(r, Mathf.Min(g, b));
@@ -777,31 +807,10 @@ namespace Godot
return ParseCol4(str, ofs) * 16 + ParseCol4(str, ofs + 1);
}
- private String ToHex32(float val)
+ private string ToHex32(float val)
{
- int v = Mathf.RoundToInt(Mathf.Clamp(val * 255, 0, 255));
-
- var ret = string.Empty;
-
- for (int i = 0; i < 2; i++)
- {
- char c;
- int lv = v & 0xF;
-
- if (lv < 10)
- {
- c = (char)('0' + lv);
- }
- else
- {
- c = (char)('a' + lv - 10);
- }
-
- v >>= 4;
- ret = c + ret;
- }
-
- return ret;
+ byte b = (byte)Mathf.RoundToInt(Mathf.Clamp(val * 255, 0, 255));
+ return b.HexEncode();
}
internal static bool HtmlIsValid(string color)
@@ -824,7 +833,8 @@ namespace Godot
}
// Check if each hex digit is valid.
- for (int i = 0; i < len; i++) {
+ for (int i = 0; i < len; i++)
+ {
if (ParseCol4(color, i) == -1)
{
return false;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs
new file mode 100644
index 0000000000..763f470504
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs
@@ -0,0 +1,27 @@
+namespace Godot
+{
+ public partial class PackedScene
+ {
+ /// <summary>
+ /// Instantiates the scene's node hierarchy, erroring on failure.
+ /// Triggers child scene instantiation(s). Triggers a
+ /// `Node.NotificationInstanced` notification on the root node.
+ /// </summary>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of Node.</typeparam>
+ public T Instance<T>(PackedScene.GenEditState editState = (PackedScene.GenEditState)0) where T : class
+ {
+ return (T)(object)Instance(editState);
+ }
+
+ /// <summary>
+ /// Instantiates the scene's node hierarchy, returning null on failure.
+ /// Triggers child scene instantiation(s). Triggers a
+ /// `Node.NotificationInstanced` notification on the root node.
+ /// </summary>
+ /// <typeparam name="T">The type to cast to. Should be a descendant of Node.</typeparam>
+ public T InstanceOrNull<T>(PackedScene.GenEditState editState = (PackedScene.GenEditState)0) where T : class
+ {
+ return Instance(editState) as T;
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs
index 5f64c09a89..74fa05d1fd 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/ResourceLoaderExtensions.cs
@@ -2,7 +2,7 @@ namespace Godot
{
public static partial class ResourceLoader
{
- public static T Load<T>(string path, string typeHint = null, bool noCache = false) where T : class
+ public static T Load<T>(string path, string typeHint = null, CacheMode noCache = CacheMode.Reuse) where T : class
{
return (T)(object)Load(path, typeHint, noCache);
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
index 7f4777777c..6699c5992c 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
@@ -39,14 +39,6 @@ namespace Godot
return val * sgn;
}
- public static FuncRef FuncRef(Object instance, StringName funcName)
- {
- var ret = new FuncRef();
- ret.SetInstance(instance);
- ret.SetFunction(funcName);
- return ret;
- }
-
public static int Hash(object var)
{
return godot_icall_GD_hash(var);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs
new file mode 100644
index 0000000000..702a6c76ba
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Godot
+{
+ public static partial class GD
+ {
+ /// <summary>
+ /// Fires when an unhandled exception occurs, regardless of project settings.
+ /// </summary>
+ public static event EventHandler<UnhandledExceptionArgs> UnhandledException;
+
+ private static void OnUnhandledException(Exception e)
+ {
+ UnhandledException?.Invoke(null, new UnhandledExceptionArgs(e));
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
index 6eecc262d6..c3f372d415 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
@@ -618,10 +618,10 @@ namespace Godot
/// This can also be used to round a floating point
/// number to an arbitrary number of decimals.
/// </summary>
- /// <param name="s">The value to stepify.</param>
+ /// <param name="s">The value to snap.</param>
/// <param name="step">The step size to snap to.</param>
/// <returns></returns>
- public static real_t Stepify(real_t s, real_t step)
+ public static real_t Snapped(real_t s, real_t step)
{
if (step != 0f)
{
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs
index b33490f9cb..bd3bcb0c58 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs
@@ -120,13 +120,13 @@ namespace Godot
/// <param name="b">The destination quaternion.</param>
/// <param name="preA">A quaternion before this quaternion.</param>
/// <param name="postB">A quaternion after `b`.</param>
- /// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
+ /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The interpolated quaternion.</returns>
- public Quat CubicSlerp(Quat b, Quat preA, Quat postB, real_t t)
+ public Quat CubicSlerp(Quat b, Quat preA, Quat postB, real_t weight)
{
- real_t t2 = (1.0f - t) * t * 2f;
- Quat sp = Slerp(b, t);
- Quat sq = preA.Slerpni(postB, t);
+ real_t t2 = (1.0f - weight) * weight * 2f;
+ Quat sp = Slerp(b, weight);
+ Quat sq = preA.Slerpni(postB, weight);
return sp.Slerpni(sq, t2);
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
index f7703c77cc..868c3536fe 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
@@ -52,7 +52,7 @@ namespace Godot
}
/// <summary>
- /// The area of this rect.
+ /// The area of this Rect2.
/// </summary>
/// <value>Equivalent to <see cref="GetArea()"/>.</value>
public real_t Area
@@ -64,7 +64,7 @@ namespace Godot
/// Returns a Rect2 with equivalent position and size, modified so that
/// the top-left corner is the origin and width and height are positive.
/// </summary>
- /// <returns>The modified rect.</returns>
+ /// <returns>The modified Rect2.</returns>
public Rect2 Abs()
{
Vector2 end = End;
@@ -74,10 +74,11 @@ namespace Godot
/// <summary>
/// Returns the intersection of this Rect2 and `b`.
+ /// If the rectangles do not intersect, an empty Rect2 is returned.
/// </summary>
- /// <param name="b">The other rect.</param>
- /// <returns>The clipped rect.</returns>
- public Rect2 Clip(Rect2 b)
+ /// <param name="b">The other Rect2.</param>
+ /// <returns>The intersection of this Rect2 and `b`, or an empty Rect2 if they do not intersect.</returns>
+ public Rect2 Intersection(Rect2 b)
{
var newRect = b;
@@ -101,8 +102,8 @@ namespace Godot
/// <summary>
/// Returns true if this Rect2 completely encloses another one.
/// </summary>
- /// <param name="b">The other rect that may be enclosed.</param>
- /// <returns>A bool for whether or not this rect encloses `b`.</returns>
+ /// <param name="b">The other Rect2 that may be enclosed.</param>
+ /// <returns>A bool for whether or not this Rect2 encloses `b`.</returns>
public bool Encloses(Rect2 b)
{
return b._position.x >= _position.x && b._position.y >= _position.y &&
@@ -114,7 +115,7 @@ namespace Godot
/// Returns this Rect2 expanded to include a given point.
/// </summary>
/// <param name="to">The point to include.</param>
- /// <returns>The expanded rect.</returns>
+ /// <returns>The expanded Rect2.</returns>
public Rect2 Expand(Vector2 to)
{
var expanded = this;
@@ -156,10 +157,10 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2 grown a given amount of units towards all the sides.
+ /// Returns a copy of the Rect2 grown by the specified amount on all sides.
/// </summary>
/// <param name="by">The amount to grow by.</param>
- /// <returns>The grown rect.</returns>
+ /// <returns>The grown Rect2.</returns>
public Rect2 Grow(real_t by)
{
var g = this;
@@ -173,13 +174,13 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2 grown a given amount of units towards each direction individually.
+ /// Returns a copy of the Rect2 grown by the specified amount on each side individually.
/// </summary>
- /// <param name="left">The amount to grow by on the left.</param>
- /// <param name="top">The amount to grow by on the top.</param>
- /// <param name="right">The amount to grow by on the right.</param>
- /// <param name="bottom">The amount to grow by on the bottom.</param>
- /// <returns>The grown rect.</returns>
+ /// <param name="left">The amount to grow by on the left side.</param>
+ /// <param name="top">The amount to grow by on the top side.</param>
+ /// <param name="right">The amount to grow by on the right side.</param>
+ /// <param name="bottom">The amount to grow by on the bottom side.</param>
+ /// <returns>The grown Rect2.</returns>
public Rect2 GrowIndividual(real_t left, real_t top, real_t right, real_t bottom)
{
var g = this;
@@ -193,19 +194,19 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2 grown a given amount of units towards the <see cref="Margin"/> direction.
+ /// Returns a copy of the Rect2 grown by the specified amount on the specified Side.
/// </summary>
- /// <param name="margin">The direction to grow in.</param>
+ /// <param name="side">The side to grow.</param>
/// <param name="by">The amount to grow by.</param>
- /// <returns>The grown rect.</returns>
- public Rect2 GrowMargin(Margin margin, real_t by)
+ /// <returns>The grown Rect2.</returns>
+ public Rect2 GrowSide(Side side, real_t by)
{
var g = this;
- g = g.GrowIndividual(Margin.Left == margin ? by : 0,
- Margin.Top == margin ? by : 0,
- Margin.Right == margin ? by : 0,
- Margin.Bottom == margin ? by : 0);
+ g = g.GrowIndividual(Side.Left == side ? by : 0,
+ Side.Top == side ? by : 0,
+ Side.Right == side ? by : 0,
+ Side.Bottom == side ? by : 0);
return g;
}
@@ -213,7 +214,7 @@ namespace Godot
/// <summary>
/// Returns true if the Rect2 is flat or empty, or false otherwise.
/// </summary>
- /// <returns>A bool for whether or not the rect has area.</returns>
+ /// <returns>A bool for whether or not the Rect2 has area.</returns>
public bool HasNoArea()
{
return _size.x <= 0 || _size.y <= 0;
@@ -223,7 +224,7 @@ namespace Godot
/// Returns true if the Rect2 contains a point, or false otherwise.
/// </summary>
/// <param name="point">The point to check.</param>
- /// <returns>A bool for whether or not the rect contains `point`.</returns>
+ /// <returns>A bool for whether or not the Rect2 contains `point`.</returns>
public bool HasPoint(Vector2 point)
{
if (point.x < _position.x)
@@ -246,7 +247,7 @@ namespace Godot
/// If `includeBorders` is true, they will also be considered overlapping
/// if their borders touch, even without intersection.
/// </summary>
- /// <param name="b">The other rect to check for intersections with.</param>
+ /// <param name="b">The other Rect2 to check for intersections with.</param>
/// <param name="includeBorders">Whether or not to consider borders.</param>
/// <returns>A bool for whether or not they are intersecting.</returns>
public bool Intersects(Rect2 b, bool includeBorders = false)
@@ -296,8 +297,8 @@ namespace Godot
/// <summary>
/// Returns a larger Rect2 that contains this Rect2 and `b`.
/// </summary>
- /// <param name="b">The other rect.</param>
- /// <returns>The merged rect.</returns>
+ /// <param name="b">The other Rect2.</param>
+ /// <returns>The merged Rect2.</returns>
public Rect2 Merge(Rect2 b)
{
Rect2 newRect;
@@ -387,11 +388,11 @@ namespace Godot
}
/// <summary>
- /// Returns true if this rect and `other` are approximately equal, by running
+ /// Returns true if this Rect2 and `other` are approximately equal, by running
/// <see cref="Vector2.IsEqualApprox(Vector2)"/> on each component.
/// </summary>
- /// <param name="other">The other rect to compare.</param>
- /// <returns>Whether or not the rects are approximately equal.</returns>
+ /// <param name="other">The other Rect2 to compare.</param>
+ /// <returns>Whether or not the Rect2s are approximately equal.</returns>
public bool IsEqualApprox(Rect2 other)
{
return _position.IsEqualApprox(other._position) && _size.IsEqualApprox(other.Size);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
index 8f71c00d76..c27af74866 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
@@ -47,7 +47,7 @@ namespace Godot
}
/// <summary>
- /// The area of this rect.
+ /// The area of this Rect2i.
/// </summary>
/// <value>Equivalent to <see cref="GetArea()"/>.</value>
public int Area
@@ -59,7 +59,7 @@ namespace Godot
/// Returns a Rect2i with equivalent position and size, modified so that
/// the top-left corner is the origin and width and height are positive.
/// </summary>
- /// <returns>The modified rect.</returns>
+ /// <returns>The modified Rect2i.</returns>
public Rect2i Abs()
{
Vector2i end = End;
@@ -69,10 +69,11 @@ namespace Godot
/// <summary>
/// Returns the intersection of this Rect2i and `b`.
+ /// If the rectangles do not intersect, an empty Rect2i is returned.
/// </summary>
- /// <param name="b">The other rect.</param>
- /// <returns>The clipped rect.</returns>
- public Rect2i Clip(Rect2i b)
+ /// <param name="b">The other Rect2i.</param>
+ /// <returns>The intersection of this Rect2i and `b`, or an empty Rect2i if they do not intersect.</returns>
+ public Rect2i Intersection(Rect2i b)
{
var newRect = b;
@@ -96,8 +97,8 @@ namespace Godot
/// <summary>
/// Returns true if this Rect2i completely encloses another one.
/// </summary>
- /// <param name="b">The other rect that may be enclosed.</param>
- /// <returns>A bool for whether or not this rect encloses `b`.</returns>
+ /// <param name="b">The other Rect2i that may be enclosed.</param>
+ /// <returns>A bool for whether or not this Rect2i encloses `b`.</returns>
public bool Encloses(Rect2i b)
{
return b._position.x >= _position.x && b._position.y >= _position.y &&
@@ -109,7 +110,7 @@ namespace Godot
/// Returns this Rect2i expanded to include a given point.
/// </summary>
/// <param name="to">The point to include.</param>
- /// <returns>The expanded rect.</returns>
+ /// <returns>The expanded Rect2i.</returns>
public Rect2i Expand(Vector2i to)
{
var expanded = this;
@@ -151,10 +152,10 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2i grown a given amount of units towards all the sides.
+ /// Returns a copy of the Rect2i grown by the specified amount on all sides.
/// </summary>
/// <param name="by">The amount to grow by.</param>
- /// <returns>The grown rect.</returns>
+ /// <returns>The grown Rect2i.</returns>
public Rect2i Grow(int by)
{
var g = this;
@@ -168,13 +169,13 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2i grown a given amount of units towards each direction individually.
+ /// Returns a copy of the Rect2i grown by the specified amount on each side individually.
/// </summary>
- /// <param name="left">The amount to grow by on the left.</param>
- /// <param name="top">The amount to grow by on the top.</param>
- /// <param name="right">The amount to grow by on the right.</param>
- /// <param name="bottom">The amount to grow by on the bottom.</param>
- /// <returns>The grown rect.</returns>
+ /// <param name="left">The amount to grow by on the left side.</param>
+ /// <param name="top">The amount to grow by on the top side.</param>
+ /// <param name="right">The amount to grow by on the right side.</param>
+ /// <param name="bottom">The amount to grow by on the bottom side.</param>
+ /// <returns>The grown Rect2i.</returns>
public Rect2i GrowIndividual(int left, int top, int right, int bottom)
{
var g = this;
@@ -188,37 +189,37 @@ namespace Godot
}
/// <summary>
- /// Returns a copy of the Rect2i grown a given amount of units towards the <see cref="Margin"/> direction.
+ /// Returns a copy of the Rect2i grown by the specified amount on the specified Side.
/// </summary>
- /// <param name="margin">The direction to grow in.</param>
+ /// <param name="side">The side to grow.</param>
/// <param name="by">The amount to grow by.</param>
- /// <returns>The grown rect.</returns>
- public Rect2i GrowMargin(Margin margin, int by)
+ /// <returns>The grown Rect2i.</returns>
+ public Rect2i GrowSide(Side side, int by)
{
var g = this;
- g = g.GrowIndividual(Margin.Left == margin ? by : 0,
- Margin.Top == margin ? by : 0,
- Margin.Right == margin ? by : 0,
- Margin.Bottom == margin ? by : 0);
+ g = g.GrowIndividual(Side.Left == side ? by : 0,
+ Side.Top == side ? by : 0,
+ Side.Right == side ? by : 0,
+ Side.Bottom == side ? by : 0);
return g;
}
/// <summary>
- /// Returns true if the Rect2 is flat or empty, or false otherwise.
+ /// Returns true if the Rect2i is flat or empty, or false otherwise.
/// </summary>
- /// <returns>A bool for whether or not the rect has area.</returns>
+ /// <returns>A bool for whether or not the Rect2i has area.</returns>
public bool HasNoArea()
{
return _size.x <= 0 || _size.y <= 0;
}
/// <summary>
- /// Returns true if the Rect2 contains a point, or false otherwise.
+ /// Returns true if the Rect2i contains a point, or false otherwise.
/// </summary>
/// <param name="point">The point to check.</param>
- /// <returns>A bool for whether or not the rect contains `point`.</returns>
+ /// <returns>A bool for whether or not the Rect2i contains `point`.</returns>
public bool HasPoint(Vector2i point)
{
if (point.x < _position.x)
@@ -241,7 +242,7 @@ namespace Godot
/// If `includeBorders` is true, they will also be considered overlapping
/// if their borders touch, even without intersection.
/// </summary>
- /// <param name="b">The other rect to check for intersections with.</param>
+ /// <param name="b">The other Rect2i to check for intersections with.</param>
/// <param name="includeBorders">Whether or not to consider borders.</param>
/// <returns>A bool for whether or not they are intersecting.</returns>
public bool Intersects(Rect2i b, bool includeBorders = false)
@@ -273,10 +274,10 @@ namespace Godot
}
/// <summary>
- /// Returns a larger Rect2i that contains this Rect2 and `b`.
+ /// Returns a larger Rect2i that contains this Rect2i and `b`.
/// </summary>
- /// <param name="b">The other rect.</param>
- /// <returns>The merged rect.</returns>
+ /// <param name="b">The other Rect2i.</param>
+ /// <returns>The merged Rect2i.</returns>
public Rect2i Merge(Rect2i b)
{
Rect2i newRect;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
index d63db0f905..98efa89ef0 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
@@ -97,6 +97,36 @@ namespace Godot
return b;
}
+ /// <summary>
+ /// Converts a string containing a binary number into an integer.
+ /// Binary strings can either be prefixed with `0b` or not,
+ /// and they can also start with a `-` before the optional prefix.
+ /// </summary>
+ /// <param name="instance">The string to convert.</param>
+ /// <returns>The converted string.</returns>
+ public static int BinToInt(this string instance)
+ {
+ if (instance.Length == 0)
+ {
+ return 0;
+ }
+
+ int sign = 1;
+
+ if (instance[0] == '-')
+ {
+ sign = -1;
+ instance = instance.Substring(1);
+ }
+
+ if (instance.StartsWith("0b"))
+ {
+ instance = instance.Substring(2);
+ }
+
+ return sign * Convert.ToInt32(instance, 2);;
+ }
+
// <summary>
// Return the amount of substrings in string.
// </summary>
@@ -322,6 +352,15 @@ namespace Godot
return instance.IndexOf(what, from, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
}
+ /// <summary>Find the first occurrence of a char. Optionally, the search starting position can be passed.</summary>
+ /// <returns>The first instance of the char, or -1 if not found.</returns>
+ public static int Find(this string instance, char what, int from = 0, bool caseSensitive = true)
+ {
+ // TODO: Could be more efficient if we get a char version of `IndexOf`.
+ // See https://github.com/dotnet/runtime/issues/44116
+ return instance.IndexOf(what.ToString(), from, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
+ }
+
/// <summary>Find the last occurrence of a substring.</summary>
/// <returns>The starting position of the substring, or -1 if not found.</returns>
public static int FindLast(this string instance, string what, bool caseSensitive = true)
@@ -423,25 +462,81 @@ namespace Godot
}
// <summary>
- // Hash the string and return a 32 bits integer.
+ // Hash the string and return a 32 bits unsigned integer.
// </summary>
- public static int Hash(this string instance)
+ public static uint Hash(this string instance)
{
- int index = 0;
- int hashv = 5381;
- int c;
+ uint hash = 5381;
- while ((c = instance[index++]) != 0)
- hashv = (hashv << 5) + hashv + c; // hash * 33 + c
+ foreach(uint c in instance)
+ {
+ hash = (hash << 5) + hash + c; // hash * 33 + c
+ }
- return hashv;
+ return hash;
}
- // <summary>
- // Convert a string containing an hexadecimal number into an int.
- // </summary>
+ /// <summary>
+ /// Returns a hexadecimal representation of this byte as a string.
+ /// </summary>
+ /// <param name="b">The byte to encode.</param>
+ /// <returns>The hexadecimal representation of this byte.</returns>
+ internal static string HexEncode(this byte b)
+ {
+ var ret = string.Empty;
+
+ for (int i = 0; i < 2; i++)
+ {
+ char c;
+ int lv = b & 0xF;
+
+ if (lv < 10)
+ {
+ c = (char)('0' + lv);
+ }
+ else
+ {
+ c = (char)('a' + lv - 10);
+ }
+
+ b >>= 4;
+ ret = c + ret;
+ }
+
+ return ret;
+ }
+
+ /// <summary>
+ /// Returns a hexadecimal representation of this byte array as a string.
+ /// </summary>
+ /// <param name="bytes">The byte array to encode.</param>
+ /// <returns>The hexadecimal representation of this byte array.</returns>
+ public static string HexEncode(this byte[] bytes)
+ {
+ var ret = string.Empty;
+
+ foreach (byte b in bytes)
+ {
+ ret += b.HexEncode();
+ }
+
+ return ret;
+ }
+
+ /// <summary>
+ /// Converts a string containing a hexadecimal number into an integer.
+ /// Hexadecimal strings can either be prefixed with `0x` or not,
+ /// and they can also start with a `-` before the optional prefix.
+ /// </summary>
+ /// <param name="instance">The string to convert.</param>
+ /// <returns>The converted string.</returns>
public static int HexToInt(this string instance)
{
+ if (instance.Length == 0)
+ {
+ return 0;
+ }
+
int sign = 1;
if (instance[0] == '-')
@@ -450,10 +545,12 @@ namespace Godot
instance = instance.Substring(1);
}
- if (!instance.StartsWith("0x"))
- return 0;
+ if (instance.StartsWith("0x"))
+ {
+ instance = instance.Substring(2);
+ }
- return sign * int.Parse(instance.Substring(2), NumberStyles.HexNumber);
+ return sign * int.Parse(instance, NumberStyles.HexNumber);
}
// <summary>
@@ -659,6 +756,33 @@ namespace Godot
}
/// <summary>
+ /// Returns a copy of the string with characters removed from the left.
+ /// </summary>
+ /// <param name="instance">The string to remove characters from.</param>
+ /// <param name="chars">The characters to be removed.</param>
+ /// <returns>A copy of the string with characters removed from the left.</returns>
+ public static string LStrip(this string instance, string chars)
+ {
+ int len = instance.Length;
+ int beg;
+
+ for (beg = 0; beg < len; beg++)
+ {
+ if (chars.Find(instance[beg]) == -1)
+ {
+ break;
+ }
+ }
+
+ if (beg == 0)
+ {
+ return instance;
+ }
+
+ return instance.Substr(beg, len - beg);
+ }
+
+ /// <summary>
/// Do a simple expression match, where '*' matches zero or more arbitrary characters and '?' matches any single character except '.'.
/// </summary>
private static bool ExprMatch(this string instance, string expr, bool caseSensitive)
@@ -809,22 +933,6 @@ namespace Godot
}
// <summary>
- // Decode a percent-encoded string. See [method percent_encode].
- // </summary>
- public static string PercentDecode(this string instance)
- {
- return Uri.UnescapeDataString(instance);
- }
-
- // <summary>
- // Percent-encode a string. This is meant to encode parameters in a URL when sending a HTTP GET request and bodies of form-urlencoded POST request.
- // </summary>
- public static string PercentEncode(this string instance)
- {
- return Uri.EscapeDataString(instance);
- }
-
- // <summary>
// If the string is a path, this concatenates [code]file[/code] at the end of the string as a subpath. E.g. [code]"this/is".plus_file("path") == "this/is/path"[/code].
// </summary>
public static string PlusFile(this string instance, string file)
@@ -886,6 +994,33 @@ namespace Godot
return instance.Substring(pos, instance.Length - pos);
}
+ /// <summary>
+ /// Returns a copy of the string with characters removed from the right.
+ /// </summary>
+ /// <param name="instance">The string to remove characters from.</param>
+ /// <param name="chars">The characters to be removed.</param>
+ /// <returns>A copy of the string with characters removed from the right.</returns>
+ public static string RStrip(this string instance, string chars)
+ {
+ int len = instance.Length;
+ int end;
+
+ for (end = len - 1; end >= 0; end--)
+ {
+ if (chars.Find(instance[end]) == -1)
+ {
+ break;
+ }
+ }
+
+ if (end == len - 1)
+ {
+ return instance;
+ }
+
+ return instance.Substr(0, end + 1);
+ }
+
public static byte[] SHA256Buffer(this string instance)
{
return godot_icall_String_sha256_buffer(instance);
@@ -1059,6 +1194,33 @@ namespace Godot
return Encoding.UTF8.GetBytes(instance);
}
+ /// <summary>
+ /// Decodes a string in URL encoded format. This is meant to
+ /// decode parameters in a URL when receiving an HTTP request.
+ /// This mostly wraps around `System.Uri.UnescapeDataString()`,
+ /// but also handles `+`.
+ /// See <see cref="URIEncode"/> for encoding.
+ /// </summary>
+ /// <param name="instance">The string to decode.</param>
+ /// <returns>The unescaped string.</returns>
+ public static string URIDecode(this string instance)
+ {
+ return Uri.UnescapeDataString(instance.Replace("+", "%20"));
+ }
+
+ /// <summary>
+ /// Encodes a string to URL friendly format. This is meant to
+ /// encode parameters in a URL when sending an HTTP request.
+ /// This wraps around `System.Uri.EscapeDataString()`.
+ /// See <see cref="URIDecode"/> for decoding.
+ /// </summary>
+ /// <param name="instance">The string to encode.</param>
+ /// <returns>The escaped string.</returns>
+ public static string URIEncode(this string instance)
+ {
+ return Uri.EscapeDataString(instance);
+ }
+
// <summary>
// Return a copy of the string with special characters escaped using the XML standard.
// </summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
index 06bbe98497..bc0f81b2a7 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
@@ -221,8 +221,7 @@ namespace Godot
real_t dot = v1.Dot(v2);
- // Clamp dot to [-1, 1]
- dot = dot < -1.0f ? -1.0f : (dot > 1.0f ? 1.0f : dot);
+ dot = Mathf.Clamp(dot, -1.0f, 1.0f);
Vector2 v;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs
new file mode 100644
index 0000000000..be01674568
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace Godot
+{
+ /// <summary>
+ /// Event arguments for when unhandled exceptions occur.
+ /// </summary>
+ public class UnhandledExceptionArgs
+ {
+ /// <summary>
+ /// Exception object
+ /// </summary>
+ public Exception Exception { get; private set; }
+
+ internal UnhandledExceptionArgs(Exception exception)
+ {
+ Exception = exception;
+ }
+ }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
index d536b14eac..6279ea1ace 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
@@ -194,15 +194,16 @@ namespace Godot
/// <param name="b">The destination vector.</param>
/// <param name="preA">A vector before this vector.</param>
/// <param name="postB">A vector after `b`.</param>
- /// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
+ /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The interpolated vector.</returns>
- public Vector2 CubicInterpolate(Vector2 b, Vector2 preA, Vector2 postB, real_t t)
+ public Vector2 CubicInterpolate(Vector2 b, Vector2 preA, Vector2 postB, real_t weight)
{
Vector2 p0 = preA;
Vector2 p1 = this;
Vector2 p2 = b;
Vector2 p3 = postB;
+ real_t t = weight;
real_t t2 = t * t;
real_t t3 = t2 * t;
@@ -510,7 +511,7 @@ namespace Godot
/// <returns>The snapped vector.</returns>
public Vector2 Snapped(Vector2 step)
{
- return new Vector2(Mathf.Stepify(x, step.x), Mathf.Stepify(y, step.y));
+ return new Vector2(Mathf.Snapped(x, step.x), Mathf.Snapped(y, step.y));
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
index 4a4a2a43cd..3b895bbbf6 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
@@ -111,10 +111,10 @@ namespace Godot
}
/// <summary>
- /// Returns the minimum angle to the given vector, in radians.
+ /// Returns the unsigned minimum angle to the given vector, in radians.
/// </summary>
/// <param name="to">The other vector to compare this vector to.</param>
- /// <returns>The angle between the two vectors, in radians.</returns>
+ /// <returns>The unsigned angle between the two vectors, in radians.</returns>
public real_t AngleTo(Vector3 to)
{
return Mathf.Atan2(Cross(to).Length(), Dot(to));
@@ -161,15 +161,16 @@ namespace Godot
/// <param name="b">The destination vector.</param>
/// <param name="preA">A vector before this vector.</param>
/// <param name="postB">A vector after `b`.</param>
- /// <param name="t">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
+ /// <param name="weight">A value on the range of 0.0 to 1.0, representing the amount of interpolation.</param>
/// <returns>The interpolated vector.</returns>
- public Vector3 CubicInterpolate(Vector3 b, Vector3 preA, Vector3 postB, real_t t)
+ public Vector3 CubicInterpolate(Vector3 b, Vector3 preA, Vector3 postB, real_t weight)
{
Vector3 p0 = preA;
Vector3 p1 = this;
Vector3 p2 = b;
Vector3 p3 = postB;
+ real_t t = weight;
real_t t2 = t * t;
real_t t3 = t2 * t;
@@ -468,6 +469,23 @@ namespace Godot
}
/// <summary>
+ /// Returns the signed angle to the given vector, in radians.
+ /// The sign of the angle is positive in a counter-clockwise
+ /// direction and negative in a clockwise direction when viewed
+ /// from the side specified by the `axis`.
+ /// </summary>
+ /// <param name="to">The other vector to compare this vector to.</param>
+ /// <param name="axis">The reference axis to use for the angle sign.</param>
+ /// <returns>The signed angle between the two vectors, in radians.</returns>
+ public real_t SignedAngleTo(Vector3 to, Vector3 axis)
+ {
+ Vector3 crossTo = Cross(to);
+ real_t unsignedAngle = Mathf.Atan2(crossTo.Length(), Dot(to));
+ real_t sign = crossTo.Dot(axis);
+ return (sign < 0) ? -unsignedAngle : unsignedAngle;
+ }
+
+ /// <summary>
/// Returns the result of the spherical linear interpolation between
/// this vector and `to` by amount `weight`.
///
@@ -512,9 +530,9 @@ namespace Godot
{
return new Vector3
(
- Mathf.Stepify(x, step.x),
- Mathf.Stepify(y, step.y),
- Mathf.Stepify(z, step.z)
+ Mathf.Snapped(x, step.x),
+ Mathf.Snapped(y, step.y),
+ Mathf.Snapped(z, step.z)
);
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
index 86a16c17f1..54aaaf1f92 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
+++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
@@ -14,9 +14,12 @@
<ItemGroup>
<Compile Include="Core\AABB.cs" />
<Compile Include="Core\Array.cs" />
+ <Compile Include="Core\Attributes\AssemblyHasScriptsAttribute.cs" />
+ <Compile Include="Core\Attributes\DisableGodotGeneratorsAttribute.cs" />
<Compile Include="Core\Attributes\ExportAttribute.cs" />
<Compile Include="Core\Attributes\GodotMethodAttribute.cs" />
<Compile Include="Core\Attributes\RPCAttributes.cs" />
+ <Compile Include="Core\Attributes\ScriptPathAttribute.cs" />
<Compile Include="Core\Attributes\SignalAttribute.cs" />
<Compile Include="Core\Attributes\ToolAttribute.cs" />
<Compile Include="Core\Basis.cs" />
@@ -30,12 +33,14 @@
<Compile Include="Core\DynamicObject.cs" />
<Compile Include="Core\Extensions\NodeExtensions.cs" />
<Compile Include="Core\Extensions\ObjectExtensions.cs" />
+ <Compile Include="Core\Extensions\PackedSceneExtensions.cs" />
<Compile Include="Core\Extensions\ResourceLoaderExtensions.cs" />
<Compile Include="Core\Extensions\SceneTreeExtensions.cs" />
<Compile Include="Core\GD.cs" />
<Compile Include="Core\GodotSynchronizationContext.cs" />
<Compile Include="Core\GodotTaskScheduler.cs" />
<Compile Include="Core\GodotTraceListener.cs" />
+ <Compile Include="Core\GodotUnhandledExceptionEvent.cs" />
<Compile Include="Core\Interfaces\IAwaitable.cs" />
<Compile Include="Core\Interfaces\IAwaiter.cs" />
<Compile Include="Core\Interfaces\ISerializationListener.cs" />
@@ -55,6 +60,7 @@
<Compile Include="Core\StringName.cs" />
<Compile Include="Core\Transform.cs" />
<Compile Include="Core\Transform2D.cs" />
+ <Compile Include="Core\UnhandledExceptionArgs.cs" />
<Compile Include="Core\Vector2.cs" />
<Compile Include="Core\Vector2i.cs" />
<Compile Include="Core\Vector3.cs" />
diff --git a/modules/mono/glue/arguments_vector.h b/modules/mono/glue/arguments_vector.h
index ab48904571..9ba6a05ac6 100644
--- a/modules/mono/glue/arguments_vector.h
+++ b/modules/mono/glue/arguments_vector.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp
index 544f414cba..34a96eba17 100644
--- a/modules/mono/glue/base_object_glue.cpp
+++ b/modules/mono/glue/base_object_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -163,9 +163,9 @@ MonoObject *godot_icall_Object_weakref(Object *p_ptr) {
return GDMonoUtils::unmanaged_get_managed(wref.ptr());
}
-Error 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();
- return 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);
}
MonoArray *godot_icall_DynamicGodotObject_SetMemberList(Object *p_ptr) {
@@ -240,18 +240,18 @@ MonoString *godot_icall_Object_ToString(Object *p_ptr) {
}
void godot_register_object_icalls() {
- mono_add_internal_call("Godot.Object::godot_icall_Object_Ctor", (void *)godot_icall_Object_Ctor);
- mono_add_internal_call("Godot.Object::godot_icall_Object_Disposed", (void *)godot_icall_Object_Disposed);
- mono_add_internal_call("Godot.Object::godot_icall_Reference_Disposed", (void *)godot_icall_Reference_Disposed);
- mono_add_internal_call("Godot.Object::godot_icall_Object_ConnectEventSignals", (void *)godot_icall_Object_ConnectEventSignals);
- mono_add_internal_call("Godot.Object::godot_icall_Object_ClassDB_get_method", (void *)godot_icall_Object_ClassDB_get_method);
- mono_add_internal_call("Godot.Object::godot_icall_Object_ToString", (void *)godot_icall_Object_ToString);
- mono_add_internal_call("Godot.Object::godot_icall_Object_weakref", (void *)godot_icall_Object_weakref);
- mono_add_internal_call("Godot.SignalAwaiter::godot_icall_SignalAwaiter_connect", (void *)godot_icall_SignalAwaiter_connect);
- mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMemberList", (void *)godot_icall_DynamicGodotObject_SetMemberList);
- mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_InvokeMember", (void *)godot_icall_DynamicGodotObject_InvokeMember);
- mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_GetMember", (void *)godot_icall_DynamicGodotObject_GetMember);
- mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMember", (void *)godot_icall_DynamicGodotObject_SetMember);
+ GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_Ctor", godot_icall_Object_Ctor);
+ GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_Disposed", godot_icall_Object_Disposed);
+ GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Reference_Disposed", godot_icall_Reference_Disposed);
+ GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_ConnectEventSignals", godot_icall_Object_ConnectEventSignals);
+ GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_ClassDB_get_method", godot_icall_Object_ClassDB_get_method);
+ 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.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMemberList", godot_icall_DynamicGodotObject_SetMemberList);
+ GDMonoUtils::add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_InvokeMember", godot_icall_DynamicGodotObject_InvokeMember);
+ GDMonoUtils::add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_GetMember", godot_icall_DynamicGodotObject_GetMember);
+ GDMonoUtils::add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMember", godot_icall_DynamicGodotObject_SetMember);
}
#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp
index bb3ea0f730..191f863350 100644
--- a/modules/mono/glue/collections_glue.cpp
+++ b/modules/mono/glue/collections_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -47,7 +47,7 @@ void godot_icall_Array_Dtor(Array *ptr) {
memdelete(ptr);
}
-MonoObject *godot_icall_Array_At(Array *ptr, int index) {
+MonoObject *godot_icall_Array_At(Array *ptr, int32_t index) {
if (index < 0 || index >= ptr->size()) {
GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
return nullptr;
@@ -55,7 +55,7 @@ MonoObject *godot_icall_Array_At(Array *ptr, int index) {
return GDMonoMarshal::variant_to_mono_object(ptr->operator[](index));
}
-MonoObject *godot_icall_Array_At_Generic(Array *ptr, int index, uint32_t type_encoding, GDMonoClass *type_class) {
+MonoObject *godot_icall_Array_At_Generic(Array *ptr, int32_t index, uint32_t type_encoding, GDMonoClass *type_class) {
if (index < 0 || index >= ptr->size()) {
GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
return nullptr;
@@ -63,7 +63,7 @@ MonoObject *godot_icall_Array_At_Generic(Array *ptr, int index, uint32_t type_en
return GDMonoMarshal::variant_to_mono_object(ptr->operator[](index), ManagedType(type_encoding, type_class));
}
-void godot_icall_Array_SetAt(Array *ptr, int index, MonoObject *value) {
+void godot_icall_Array_SetAt(Array *ptr, int32_t index, MonoObject *value) {
if (index < 0 || index >= ptr->size()) {
GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
return;
@@ -71,11 +71,11 @@ void godot_icall_Array_SetAt(Array *ptr, int index, MonoObject *value) {
ptr->operator[](index) = GDMonoMarshal::mono_object_to_variant(value);
}
-int godot_icall_Array_Count(Array *ptr) {
+int32_t godot_icall_Array_Count(Array *ptr) {
return ptr->size();
}
-int godot_icall_Array_Add(Array *ptr, MonoObject *item) {
+int32_t godot_icall_Array_Add(Array *ptr, MonoObject *item) {
ptr->append(GDMonoMarshal::mono_object_to_variant(item));
return ptr->size();
}
@@ -88,7 +88,7 @@ MonoBoolean godot_icall_Array_Contains(Array *ptr, MonoObject *item) {
return ptr->find(GDMonoMarshal::mono_object_to_variant(item)) != -1;
}
-void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int array_index) {
+void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int32_t array_index) {
unsigned int count = ptr->size();
if (mono_array_length(array) < (array_index + count)) {
@@ -129,11 +129,11 @@ Array *godot_icall_Array_Concatenate(Array *left, Array *right) {
return new_array;
}
-int godot_icall_Array_IndexOf(Array *ptr, MonoObject *item) {
+int32_t godot_icall_Array_IndexOf(Array *ptr, MonoObject *item) {
return ptr->find(GDMonoMarshal::mono_object_to_variant(item));
}
-void godot_icall_Array_Insert(Array *ptr, int index, MonoObject *item) {
+void godot_icall_Array_Insert(Array *ptr, int32_t index, MonoObject *item) {
if (index < 0 || index > ptr->size()) {
GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
return;
@@ -150,7 +150,7 @@ MonoBoolean godot_icall_Array_Remove(Array *ptr, MonoObject *item) {
return false;
}
-void godot_icall_Array_RemoveAt(Array *ptr, int index) {
+void godot_icall_Array_RemoveAt(Array *ptr, int32_t index) {
if (index < 0 || index >= ptr->size()) {
GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
return;
@@ -158,8 +158,8 @@ void godot_icall_Array_RemoveAt(Array *ptr, int index) {
ptr->remove(index);
}
-Error godot_icall_Array_Resize(Array *ptr, int new_size) {
- return ptr->resize(new_size);
+int32_t godot_icall_Array_Resize(Array *ptr, int32_t new_size) {
+ return (int32_t)ptr->resize(new_size);
}
void godot_icall_Array_Shuffle(Array *ptr) {
@@ -226,7 +226,7 @@ Array *godot_icall_Dictionary_Values(Dictionary *ptr) {
return memnew(Array(ptr->values()));
}
-int godot_icall_Dictionary_Count(Dictionary *ptr) {
+int32_t godot_icall_Dictionary_Count(Dictionary *ptr) {
return ptr->size();
}
@@ -308,47 +308,47 @@ MonoString *godot_icall_Dictionary_ToString(Dictionary *ptr) {
}
void godot_register_collections_icalls() {
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Ctor", (void *)godot_icall_Array_Ctor);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Ctor_MonoArray", (void *)godot_icall_Array_Ctor_MonoArray);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Dtor", (void *)godot_icall_Array_Dtor);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_At", (void *)godot_icall_Array_At);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_At_Generic", (void *)godot_icall_Array_At_Generic);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_SetAt", (void *)godot_icall_Array_SetAt);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Count", (void *)godot_icall_Array_Count);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Add", (void *)godot_icall_Array_Add);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Clear", (void *)godot_icall_Array_Clear);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Concatenate", (void *)godot_icall_Array_Concatenate);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Contains", (void *)godot_icall_Array_Contains);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_CopyTo", (void *)godot_icall_Array_CopyTo);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Duplicate", (void *)godot_icall_Array_Duplicate);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_IndexOf", (void *)godot_icall_Array_IndexOf);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Insert", (void *)godot_icall_Array_Insert);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Remove", (void *)godot_icall_Array_Remove);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_RemoveAt", (void *)godot_icall_Array_RemoveAt);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Resize", (void *)godot_icall_Array_Resize);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Shuffle", (void *)godot_icall_Array_Shuffle);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Generic_GetElementTypeInfo", (void *)godot_icall_Array_Generic_GetElementTypeInfo);
- mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_ToString", (void *)godot_icall_Array_ToString);
-
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Ctor", (void *)godot_icall_Dictionary_Ctor);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Dtor", (void *)godot_icall_Dictionary_Dtor);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_GetValue", (void *)godot_icall_Dictionary_GetValue);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_GetValue_Generic", (void *)godot_icall_Dictionary_GetValue_Generic);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_SetValue", (void *)godot_icall_Dictionary_SetValue);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Keys", (void *)godot_icall_Dictionary_Keys);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Values", (void *)godot_icall_Dictionary_Values);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Count", (void *)godot_icall_Dictionary_Count);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Add", (void *)godot_icall_Dictionary_Add);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Clear", (void *)godot_icall_Dictionary_Clear);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Contains", (void *)godot_icall_Dictionary_Contains);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_ContainsKey", (void *)godot_icall_Dictionary_ContainsKey);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Duplicate", (void *)godot_icall_Dictionary_Duplicate);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_RemoveKey", (void *)godot_icall_Dictionary_RemoveKey);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Remove", (void *)godot_icall_Dictionary_Remove);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_TryGetValue", (void *)godot_icall_Dictionary_TryGetValue);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_TryGetValue_Generic", (void *)godot_icall_Dictionary_TryGetValue_Generic);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Generic_GetValueTypeInfo", (void *)godot_icall_Dictionary_Generic_GetValueTypeInfo);
- mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_ToString", (void *)godot_icall_Dictionary_ToString);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Ctor", godot_icall_Array_Ctor);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Ctor_MonoArray", godot_icall_Array_Ctor_MonoArray);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Dtor", godot_icall_Array_Dtor);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_At", godot_icall_Array_At);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_At_Generic", godot_icall_Array_At_Generic);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_SetAt", godot_icall_Array_SetAt);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Count", godot_icall_Array_Count);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Add", godot_icall_Array_Add);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Clear", godot_icall_Array_Clear);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Concatenate", godot_icall_Array_Concatenate);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Contains", godot_icall_Array_Contains);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_CopyTo", godot_icall_Array_CopyTo);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Duplicate", godot_icall_Array_Duplicate);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_IndexOf", godot_icall_Array_IndexOf);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Insert", godot_icall_Array_Insert);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Remove", godot_icall_Array_Remove);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_RemoveAt", godot_icall_Array_RemoveAt);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Resize", godot_icall_Array_Resize);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Shuffle", godot_icall_Array_Shuffle);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Generic_GetElementTypeInfo", godot_icall_Array_Generic_GetElementTypeInfo);
+ GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_ToString", godot_icall_Array_ToString);
+
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Ctor", godot_icall_Dictionary_Ctor);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Dtor", godot_icall_Dictionary_Dtor);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_GetValue", godot_icall_Dictionary_GetValue);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_GetValue_Generic", godot_icall_Dictionary_GetValue_Generic);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_SetValue", godot_icall_Dictionary_SetValue);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Keys", godot_icall_Dictionary_Keys);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Values", godot_icall_Dictionary_Values);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Count", godot_icall_Dictionary_Count);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Add", godot_icall_Dictionary_Add);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Clear", godot_icall_Dictionary_Clear);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Contains", godot_icall_Dictionary_Contains);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_ContainsKey", godot_icall_Dictionary_ContainsKey);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Duplicate", godot_icall_Dictionary_Duplicate);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_RemoveKey", godot_icall_Dictionary_RemoveKey);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Remove", godot_icall_Dictionary_Remove);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_TryGetValue", godot_icall_Dictionary_TryGetValue);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_TryGetValue_Generic", godot_icall_Dictionary_TryGetValue_Generic);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Generic_GetValueTypeInfo", godot_icall_Dictionary_Generic_GetValueTypeInfo);
+ GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_ToString", godot_icall_Dictionary_ToString);
}
#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp
index 4c1df529fc..a2ff868f65 100644
--- a/modules/mono/glue/gd_glue.cpp
+++ b/modules/mono/glue/gd_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -55,7 +55,8 @@ 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), args, 1, 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);
}
@@ -288,33 +289,33 @@ MonoObject *godot_icall_DefaultGodotTaskScheduler() {
}
void godot_register_gd_icalls() {
- mono_add_internal_call("Godot.GD::godot_icall_GD_bytes2var", (void *)godot_icall_GD_bytes2var);
- mono_add_internal_call("Godot.GD::godot_icall_GD_convert", (void *)godot_icall_GD_convert);
- mono_add_internal_call("Godot.GD::godot_icall_GD_hash", (void *)godot_icall_GD_hash);
- mono_add_internal_call("Godot.GD::godot_icall_GD_instance_from_id", (void *)godot_icall_GD_instance_from_id);
- mono_add_internal_call("Godot.GD::godot_icall_GD_pusherror", (void *)godot_icall_GD_pusherror);
- mono_add_internal_call("Godot.GD::godot_icall_GD_pushwarning", (void *)godot_icall_GD_pushwarning);
- mono_add_internal_call("Godot.GD::godot_icall_GD_print", (void *)godot_icall_GD_print);
- mono_add_internal_call("Godot.GD::godot_icall_GD_printerr", (void *)godot_icall_GD_printerr);
- mono_add_internal_call("Godot.GD::godot_icall_GD_printraw", (void *)godot_icall_GD_printraw);
- mono_add_internal_call("Godot.GD::godot_icall_GD_prints", (void *)godot_icall_GD_prints);
- mono_add_internal_call("Godot.GD::godot_icall_GD_printt", (void *)godot_icall_GD_printt);
- mono_add_internal_call("Godot.GD::godot_icall_GD_randf", (void *)godot_icall_GD_randf);
- mono_add_internal_call("Godot.GD::godot_icall_GD_randi", (void *)godot_icall_GD_randi);
- mono_add_internal_call("Godot.GD::godot_icall_GD_randomize", (void *)godot_icall_GD_randomize);
- mono_add_internal_call("Godot.GD::godot_icall_GD_randf_range", (void *)godot_icall_GD_randf_range);
- mono_add_internal_call("Godot.GD::godot_icall_GD_randi_range", (void *)godot_icall_GD_randi_range);
- mono_add_internal_call("Godot.GD::godot_icall_GD_rand_seed", (void *)godot_icall_GD_rand_seed);
- mono_add_internal_call("Godot.GD::godot_icall_GD_seed", (void *)godot_icall_GD_seed);
- mono_add_internal_call("Godot.GD::godot_icall_GD_str", (void *)godot_icall_GD_str);
- mono_add_internal_call("Godot.GD::godot_icall_GD_str2var", (void *)godot_icall_GD_str2var);
- mono_add_internal_call("Godot.GD::godot_icall_GD_type_exists", (void *)godot_icall_GD_type_exists);
- mono_add_internal_call("Godot.GD::godot_icall_GD_var2bytes", (void *)godot_icall_GD_var2bytes);
- mono_add_internal_call("Godot.GD::godot_icall_GD_var2str", (void *)godot_icall_GD_var2str);
- mono_add_internal_call("Godot.GD::godot_icall_TypeToVariantType", (void *)godot_icall_TypeToVariantType);
+ 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_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_randf", godot_icall_GD_randf);
+ GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randi", godot_icall_GD_randi);
+ GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randomize", godot_icall_GD_randomize);
+ 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_randi_range", godot_icall_GD_randi_range);
+ 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
- mono_add_internal_call("Godot.Dispatcher::godot_icall_DefaultGodotTaskScheduler", (void *)godot_icall_DefaultGodotTaskScheduler);
+ GDMonoUtils::add_internal_call("Godot.Dispatcher::godot_icall_DefaultGodotTaskScheduler", godot_icall_DefaultGodotTaskScheduler);
}
#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/glue_header.h b/modules/mono/glue/glue_header.h
index f4263e286e..3db52d7c30 100644
--- a/modules/mono/glue/glue_header.h
+++ b/modules/mono/glue/glue_header.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/glue/nodepath_glue.cpp b/modules/mono/glue/nodepath_glue.cpp
index 09c6d8f482..4ddb94e1a8 100644
--- a/modules/mono/glue/nodepath_glue.cpp
+++ b/modules/mono/glue/nodepath_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -81,17 +81,17 @@ MonoBoolean godot_icall_NodePath_is_empty(NodePath *p_ptr) {
}
void godot_register_nodepath_icalls() {
- mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_Ctor", (void *)godot_icall_NodePath_Ctor);
- mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_Dtor", (void *)godot_icall_NodePath_Dtor);
- mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_operator_String", (void *)godot_icall_NodePath_operator_String);
- mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_as_property_path", (void *)godot_icall_NodePath_get_as_property_path);
- mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_concatenated_subnames", (void *)godot_icall_NodePath_get_concatenated_subnames);
- mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_name", (void *)godot_icall_NodePath_get_name);
- mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_name_count", (void *)godot_icall_NodePath_get_name_count);
- mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_subname", (void *)godot_icall_NodePath_get_subname);
- mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_subname_count", (void *)godot_icall_NodePath_get_subname_count);
- mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_is_absolute", (void *)godot_icall_NodePath_is_absolute);
- mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_is_empty", (void *)godot_icall_NodePath_is_empty);
+ GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_Ctor", godot_icall_NodePath_Ctor);
+ GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_Dtor", godot_icall_NodePath_Dtor);
+ GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_operator_String", godot_icall_NodePath_operator_String);
+ GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_as_property_path", godot_icall_NodePath_get_as_property_path);
+ GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_concatenated_subnames", godot_icall_NodePath_get_concatenated_subnames);
+ GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_name", godot_icall_NodePath_get_name);
+ GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_name_count", godot_icall_NodePath_get_name_count);
+ GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_subname", godot_icall_NodePath_get_subname);
+ GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_subname_count", godot_icall_NodePath_get_subname_count);
+ GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_is_absolute", godot_icall_NodePath_is_absolute);
+ GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_is_empty", godot_icall_NodePath_is_empty);
}
#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/rid_glue.cpp b/modules/mono/glue/rid_glue.cpp
index cb4f26511f..f464e63a81 100644
--- a/modules/mono/glue/rid_glue.cpp
+++ b/modules/mono/glue/rid_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -56,9 +56,9 @@ uint32_t godot_icall_RID_get_id(RID *p_ptr) {
}
void godot_register_rid_icalls() {
- mono_add_internal_call("Godot.RID::godot_icall_RID_Ctor", (void *)godot_icall_RID_Ctor);
- mono_add_internal_call("Godot.RID::godot_icall_RID_Dtor", (void *)godot_icall_RID_Dtor);
- mono_add_internal_call("Godot.RID::godot_icall_RID_get_id", (void *)godot_icall_RID_get_id);
+ GDMonoUtils::add_internal_call("Godot.RID::godot_icall_RID_Ctor", godot_icall_RID_Ctor);
+ GDMonoUtils::add_internal_call("Godot.RID::godot_icall_RID_Dtor", godot_icall_RID_Dtor);
+ GDMonoUtils::add_internal_call("Godot.RID::godot_icall_RID_get_id", godot_icall_RID_get_id);
}
#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/scene_tree_glue.cpp b/modules/mono/glue/scene_tree_glue.cpp
index 53d6c1436d..5a6fd69db8 100644
--- a/modules/mono/glue/scene_tree_glue.cpp
+++ b/modules/mono/glue/scene_tree_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -48,7 +48,7 @@ Array *godot_icall_SceneTree_get_nodes_in_group_Generic(SceneTree *ptr, StringNa
ptr->get_nodes_in_group(*group, &nodes);
// No need to bother if the group is empty
- if (!nodes.empty()) {
+ if (!nodes.is_empty()) {
MonoType *elem_type = mono_reflection_type_get_type(refltype);
MonoClass *mono_class = mono_class_from_mono_type(elem_type);
GDMonoClass *klass = GDMono::get_singleton()->get_class(mono_class);
@@ -80,7 +80,7 @@ Array *godot_icall_SceneTree_get_nodes_in_group_Generic(SceneTree *ptr, StringNa
}
void godot_register_scene_tree_icalls() {
- mono_add_internal_call("Godot.SceneTree::godot_icall_SceneTree_get_nodes_in_group_Generic", (void *)godot_icall_SceneTree_get_nodes_in_group_Generic);
+ GDMonoUtils::add_internal_call("Godot.SceneTree::godot_icall_SceneTree_get_nodes_in_group_Generic", godot_icall_SceneTree_get_nodes_in_group_Generic);
}
#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/string_glue.cpp b/modules/mono/glue/string_glue.cpp
index 9271731573..18a9221f89 100644
--- a/modules/mono/glue/string_glue.cpp
+++ b/modules/mono/glue/string_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -68,12 +68,12 @@ MonoString *godot_icall_String_sha256_text(MonoString *p_str) {
}
void godot_register_string_icalls() {
- mono_add_internal_call("Godot.StringExtensions::godot_icall_String_md5_buffer", (void *)godot_icall_String_md5_buffer);
- mono_add_internal_call("Godot.StringExtensions::godot_icall_String_md5_text", (void *)godot_icall_String_md5_text);
- mono_add_internal_call("Godot.StringExtensions::godot_icall_String_rfind", (void *)godot_icall_String_rfind);
- mono_add_internal_call("Godot.StringExtensions::godot_icall_String_rfindn", (void *)godot_icall_String_rfindn);
- mono_add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_buffer", (void *)godot_icall_String_sha256_buffer);
- mono_add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_text", (void *)godot_icall_String_sha256_text);
+ GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_md5_buffer", godot_icall_String_md5_buffer);
+ GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_md5_text", godot_icall_String_md5_text);
+ GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_rfind", godot_icall_String_rfind);
+ GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_rfindn", godot_icall_String_rfindn);
+ GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_buffer", godot_icall_String_sha256_buffer);
+ GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_text", godot_icall_String_sha256_text);
}
#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/string_name_glue.cpp b/modules/mono/glue/string_name_glue.cpp
index 9323e3bbb3..f537896559 100644
--- a/modules/mono/glue/string_name_glue.cpp
+++ b/modules/mono/glue/string_name_glue.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -53,10 +53,10 @@ MonoBoolean godot_icall_StringName_is_empty(StringName *p_ptr) {
}
void godot_register_string_name_icalls() {
- mono_add_internal_call("Godot.StringName::godot_icall_StringName_Ctor", (void *)godot_icall_StringName_Ctor);
- mono_add_internal_call("Godot.StringName::godot_icall_StringName_Dtor", (void *)godot_icall_StringName_Dtor);
- mono_add_internal_call("Godot.StringName::godot_icall_StringName_operator_String", (void *)godot_icall_StringName_operator_String);
- mono_add_internal_call("Godot.StringName::godot_icall_StringName_is_empty", (void *)godot_icall_StringName_is_empty);
+ GDMonoUtils::add_internal_call("Godot.StringName::godot_icall_StringName_Ctor", godot_icall_StringName_Ctor);
+ GDMonoUtils::add_internal_call("Godot.StringName::godot_icall_StringName_Dtor", godot_icall_StringName_Dtor);
+ GDMonoUtils::add_internal_call("Godot.StringName::godot_icall_StringName_operator_String", godot_icall_StringName_operator_String);
+ GDMonoUtils::add_internal_call("Godot.StringName::godot_icall_StringName_is_empty", godot_icall_StringName_is_empty);
}
#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/godotsharp_defs.h b/modules/mono/godotsharp_defs.h
index 7d57d0fac3..273dba52f9 100644
--- a/modules/mono/godotsharp_defs.h
+++ b/modules/mono/godotsharp_defs.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp
index 4233732bff..020a40575c 100644
--- a/modules/mono/godotsharp_dirs.cpp
+++ b/modules/mono/godotsharp_dirs.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -146,7 +146,7 @@ private:
String appname = ProjectSettings::get_singleton()->get("application/config/name");
String appname_safe = OS::get_singleton()->get_safe_dir_name(appname);
- if (appname_safe.empty()) {
+ if (appname_safe.is_empty()) {
appname_safe = "UnnamedProject";
}
@@ -179,16 +179,16 @@ private:
#ifdef OSX_ENABLED
if (!DirAccess::exists(data_editor_tools_dir)) {
- data_editor_tools_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Tools");
+ data_editor_tools_dir = exe_dir.plus_file("../Resources/GodotSharp/Tools");
}
if (!DirAccess::exists(data_editor_prebuilt_api_dir)) {
- data_editor_prebuilt_api_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Api");
+ data_editor_prebuilt_api_dir = exe_dir.plus_file("../Resources/GodotSharp/Api");
}
if (!DirAccess::exists(data_mono_root_dir)) {
data_mono_etc_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/etc");
- data_mono_lib_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Mono/lib");
+ data_mono_lib_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/lib");
}
#endif
@@ -218,11 +218,11 @@ private:
#ifdef OSX_ENABLED
if (!DirAccess::exists(data_mono_root_dir)) {
data_mono_etc_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/etc");
- data_mono_lib_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Mono/lib");
+ data_mono_lib_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/lib");
}
if (!DirAccess::exists(data_game_assemblies_dir)) {
- data_game_assemblies_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Assemblies");
+ data_game_assemblies_dir = exe_dir.plus_file("../Resources/GodotSharp/Assemblies");
}
#endif
@@ -322,5 +322,4 @@ String get_data_mono_bin_dir() {
return _GodotSharpDirs::get_singleton().data_mono_bin_dir;
}
#endif
-
} // namespace GodotSharpDirs
diff --git a/modules/mono/godotsharp_dirs.h b/modules/mono/godotsharp_dirs.h
index 6391616419..3a3c6f980e 100644
--- a/modules/mono/godotsharp_dirs.h
+++ b/modules/mono/godotsharp_dirs.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -66,7 +66,6 @@ String get_data_mono_lib_dir();
#ifdef WINDOWS_ENABLED
String get_data_mono_bin_dir();
#endif
-
} // namespace GodotSharpDirs
#endif // GODOTSHARP_DIRS_H
diff --git a/modules/mono/managed_callable.cpp b/modules/mono/managed_callable.cpp
index dbe9c7fc5d..6d868b527c 100644
--- a/modules/mono/managed_callable.cpp
+++ b/modules/mono/managed_callable.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/managed_callable.h b/modules/mono/managed_callable.h
index bde1b41781..c620eee60d 100644
--- a/modules/mono/managed_callable.h
+++ b/modules/mono/managed_callable.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/mono_gc_handle.cpp b/modules/mono/mono_gc_handle.cpp
index 16a6875406..8583065016 100644
--- a/modules/mono/mono_gc_handle.cpp
+++ b/modules/mono/mono_gc_handle.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/mono_gc_handle.h b/modules/mono/mono_gc_handle.h
index 5c3a210e97..f435aab3dd 100644
--- a/modules/mono/mono_gc_handle.h
+++ b/modules/mono/mono_gc_handle.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -42,7 +42,6 @@ enum class GCHandleType : char {
STRONG_HANDLE,
WEAK_HANDLE
};
-
}
// Manual release of the GC handle must be done when using this struct
diff --git a/modules/mono/mono_gd/android_mono_config.h b/modules/mono/mono_gd/android_mono_config.h
index 9e304939b2..9d7cfe1b7c 100644
--- a/modules/mono/mono_gd/android_mono_config.h
+++ b/modules/mono/mono_gd/android_mono_config.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 0e335b3349..560788fb3a 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -142,7 +142,7 @@ void gd_mono_debug_init() {
int da_timeout = GLOBAL_DEF("mono/debugger_agent/wait_timeout", 3000);
if (Engine::get_singleton()->is_editor_hint() ||
- ProjectSettings::get_singleton()->get_resource_path().empty() ||
+ ProjectSettings::get_singleton()->get_resource_path().is_empty() ||
Main::is_project_manager()) {
if (da_args.size() == 0) {
return;
@@ -201,7 +201,6 @@ MonoDomain *gd_initialize_mono_runtime() {
return mono_jit_init_version("GodotEngine.RootDomain", runtime_version);
}
#endif
-
} // namespace
void GDMono::add_mono_shared_libs_dir_to_path() {
@@ -298,7 +297,7 @@ void GDMono::determine_mono_dirs(String &r_assembly_rootdir, String &r_config_di
}
#ifdef WINDOWS_ENABLED
- if (r_assembly_rootdir.empty() || r_config_dir.empty()) {
+ if (r_assembly_rootdir.is_empty() || r_config_dir.is_empty()) {
ERR_PRINT("Cannot find Mono in the registry.");
// Assertion: if they are not set, then they weren't found in the registry
CRASH_COND(mono_reg_info.assembly_dir.length() > 0 || mono_reg_info.config_dir.length() > 0);
@@ -361,7 +360,7 @@ void GDMono::initialize() {
#ifndef TOOLS_ENABLED
// Exported games that don't use C# must still work. They likely don't ship with mscorlib.
// We only initialize the Mono runtime if we can find mscorlib. Otherwise it would crash.
- if (GDMonoAssembly::find_assembly("mscorlib.dll").empty()) {
+ if (GDMonoAssembly::find_assembly("mscorlib.dll").is_empty()) {
print_verbose("Mono: Skipping runtime initialization because 'mscorlib.dll' could not be found");
return;
}
@@ -594,8 +593,8 @@ ApiAssemblyInfo::Version ApiAssemblyInfo::Version::get_from_loaded_assembly(GDMo
ApiAssemblyInfo::Version api_assembly_version;
const char *nativecalls_name = p_api_type == ApiAssemblyInfo::API_CORE ?
- BINDINGS_CLASS_NATIVECALLS :
- BINDINGS_CLASS_NATIVECALLS_EDITOR;
+ BINDINGS_CLASS_NATIVECALLS :
+ BINDINGS_CLASS_NATIVECALLS_EDITOR;
GDMonoClass *nativecalls_klass = p_api_assembly->get_class(BINDINGS_NAMESPACE, nativecalls_name);
@@ -758,11 +757,11 @@ String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const
#define FAIL_REASON(m_out_of_sync, m_prebuilt_exists) \
( \
(m_out_of_sync ? \
- String("The assembly is invalidated ") : \
- String("The assembly was not found ")) + \
+ String("The assembly is invalidated ") : \
+ String("The assembly was not found ")) + \
(m_prebuilt_exists ? \
- String("and the prebuilt assemblies are missing.") : \
- String("and we failed to copy the prebuilt assemblies.")))
+ String("and the prebuilt assemblies are missing.") : \
+ String("and we failed to copy the prebuilt assemblies.")))
String dst_assemblies_dir = GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config);
@@ -821,8 +820,8 @@ bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, c
// If running the project manager, load it from the prebuilt API directory
String assembly_dir = !Main::is_project_manager() ?
- GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) :
- GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config);
+ GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) :
+ GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config);
String assembly_path = assembly_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll");
@@ -854,8 +853,8 @@ bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly,
// If running the project manager, load it from the prebuilt API directory
String assembly_dir = !Main::is_project_manager() ?
- GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) :
- GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config);
+ GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) :
+ GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config);
String assembly_path = assembly_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
@@ -945,7 +944,7 @@ void GDMono::_load_api_assemblies() {
// 2. Update the API assemblies
String update_error = update_api_assemblies_from_prebuilt("Debug", &core_api_assembly.out_of_sync, &editor_api_assembly.out_of_sync);
- CRASH_COND_MSG(!update_error.empty(), update_error);
+ CRASH_COND_MSG(!update_error.is_empty(), update_error);
// 3. Load the scripts domain again
Error domain_load_err = _load_scripts_domain();
@@ -999,7 +998,7 @@ bool GDMono::_load_project_assembly() {
String appname = ProjectSettings::get_singleton()->get("application/config/name");
String appname_safe = OS::get_singleton()->get_safe_dir_name(appname);
- if (appname_safe.empty()) {
+ if (appname_safe.is_empty()) {
appname_safe = "UnnamedProject";
}
@@ -1007,6 +1006,7 @@ bool GDMono::_load_project_assembly() {
if (success) {
mono_assembly_set_main(project_assembly->get_assembly());
+ CSharpLanguage::get_singleton()->lookup_scripts_in_assembly(project_assembly);
}
return success;
diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h
index 18f7418049..5accc21f8e 100644
--- a/modules/mono/mono_gd/gd_mono.h
+++ b/modules/mono/mono_gd/gd_mono.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -283,7 +283,6 @@ public:
}
}
};
-
} // namespace gdmono
#define _GDMONO_SCOPE_DOMAIN_(m_mono_domain) \
diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp
index 33628b3ce3..a1556bace5 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.cpp
+++ b/modules/mono/mono_gd/gd_mono_assembly.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -48,20 +48,20 @@ Vector<String> GDMonoAssembly::search_dirs;
void GDMonoAssembly::fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config, const String &p_custom_bcl_dir) {
String framework_dir;
- if (!p_custom_bcl_dir.empty()) {
+ if (!p_custom_bcl_dir.is_empty()) {
framework_dir = p_custom_bcl_dir;
} else if (mono_assembly_getrootdir()) {
framework_dir = String::utf8(mono_assembly_getrootdir()).plus_file("mono").plus_file("4.5");
}
- if (!framework_dir.empty()) {
+ if (!framework_dir.is_empty()) {
r_search_dirs.push_back(framework_dir);
r_search_dirs.push_back(framework_dir.plus_file("Facades"));
}
#if !defined(TOOLS_ENABLED)
String data_game_assemblies_dir = GodotSharpDirs::get_data_game_assemblies_dir();
- if (!data_game_assemblies_dir.empty()) {
+ if (!data_game_assemblies_dir.is_empty()) {
r_search_dirs.push_back(data_game_assemblies_dir);
}
#endif
@@ -72,7 +72,7 @@ void GDMonoAssembly::fill_search_dirs(Vector<String> &r_search_dirs, const Strin
r_search_dirs.push_back(GodotSharpDirs::get_res_temp_assemblies_dir());
}
- if (p_custom_config.empty()) {
+ if (p_custom_config.is_empty()) {
r_search_dirs.push_back(GodotSharpDirs::get_res_assemblies_dir());
} else {
String api_config = p_custom_config == "ExportRelease" ? "Release" : "Debug";
@@ -230,7 +230,7 @@ void GDMonoAssembly::initialize() {
MonoAssembly *GDMonoAssembly::_real_load_assembly_from(const String &p_path, bool p_refonly, MonoAssemblyName *p_aname) {
Vector<uint8_t> data = FileAccess::get_file_as_array(p_path);
- ERR_FAIL_COND_V_MSG(data.empty(), nullptr, "Could read the assembly in the specified location");
+ ERR_FAIL_COND_V_MSG(data.is_empty(), nullptr, "Could read the assembly in the specified location");
String image_filename;
@@ -345,6 +345,45 @@ String GDMonoAssembly::get_path() const {
return String::utf8(mono_image_get_filename(image));
}
+bool GDMonoAssembly::has_attribute(GDMonoClass *p_attr_class) {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_NULL_V(p_attr_class, false);
+#endif
+
+ if (!attrs_fetched) {
+ fetch_attributes();
+ }
+
+ if (!attributes) {
+ return false;
+ }
+
+ return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr());
+}
+
+MonoObject *GDMonoAssembly::get_attribute(GDMonoClass *p_attr_class) {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_NULL_V(p_attr_class, nullptr);
+#endif
+
+ if (!attrs_fetched) {
+ fetch_attributes();
+ }
+
+ if (!attributes) {
+ return nullptr;
+ }
+
+ return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr());
+}
+
+void GDMonoAssembly::fetch_attributes() {
+ ERR_FAIL_COND(attributes != nullptr);
+
+ attributes = mono_custom_attrs_from_assembly(assembly);
+ attrs_fetched = true;
+}
+
GDMonoClass *GDMonoAssembly::get_class(const StringName &p_namespace, const StringName &p_name) {
ERR_FAIL_NULL_V(image, nullptr);
@@ -379,8 +418,8 @@ GDMonoClass *GDMonoAssembly::get_class(MonoClass *p_mono_class) {
return match->value();
}
- StringName namespace_name = mono_class_get_namespace(p_mono_class);
- StringName class_name = mono_class_get_name(p_mono_class);
+ StringName namespace_name = String::utf8(mono_class_get_namespace(p_mono_class));
+ StringName class_name = String::utf8(mono_class_get_name(p_mono_class));
GDMonoClass *wrapped_class = memnew(GDMonoClass(namespace_name, class_name, p_mono_class, this));
@@ -390,70 +429,6 @@ GDMonoClass *GDMonoAssembly::get_class(MonoClass *p_mono_class) {
return wrapped_class;
}
-GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class) {
- GDMonoClass *match = nullptr;
-
- if (gdobject_class_cache_updated) {
- Map<StringName, GDMonoClass *>::Element *result = gdobject_class_cache.find(p_class);
-
- if (result) {
- match = result->get();
- }
- } else {
- List<GDMonoClass *> nested_classes;
-
- int rows = mono_image_get_table_rows(image, MONO_TABLE_TYPEDEF);
-
- for (int i = 1; i < rows; i++) {
- MonoClass *mono_class = mono_class_get(image, (i + 1) | MONO_TOKEN_TYPE_DEF);
-
- if (!mono_class_is_assignable_from(CACHED_CLASS_RAW(GodotObject), mono_class)) {
- continue;
- }
-
- GDMonoClass *current = get_class(mono_class);
-
- if (!current) {
- continue;
- }
-
- nested_classes.push_back(current);
-
- if (!match && current->get_name() == p_class) {
- match = current;
- }
-
- while (!nested_classes.empty()) {
- GDMonoClass *current_nested = nested_classes.front()->get();
- nested_classes.pop_front();
-
- void *iter = nullptr;
-
- while (true) {
- MonoClass *raw_nested = mono_class_get_nested_types(current_nested->get_mono_ptr(), &iter);
-
- if (!raw_nested) {
- break;
- }
-
- GDMonoClass *nested_class = get_class(raw_nested);
-
- if (nested_class) {
- gdobject_class_cache.insert(nested_class->get_name(), nested_class);
- nested_classes.push_back(nested_class);
- }
- }
- }
-
- gdobject_class_cache.insert(current->get_name(), current);
- }
-
- gdobject_class_cache_updated = true;
- }
-
- return match;
-}
-
GDMonoAssembly *GDMonoAssembly::load(const String &p_name, MonoAssemblyName *p_aname, bool p_refonly, const Vector<String> &p_search_dirs) {
if (GDMono::get_singleton()->get_corlib_assembly() && (p_name == "mscorlib" || p_name == "mscorlib.dll")) {
return GDMono::get_singleton()->get_corlib_assembly();
diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h
index fc10480e07..6191c491f4 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.h
+++ b/modules/mono/mono_gd/gd_mono_assembly.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -71,13 +71,13 @@ class GDMonoAssembly {
MonoImage *image;
MonoAssembly *assembly;
+ bool attrs_fetched = false;
+ MonoCustomAttrInfo *attributes = nullptr;
+
#ifdef GD_MONO_HOT_RELOAD
uint64_t modified_time = 0;
#endif
- bool gdobject_class_cache_updated = false;
- Map<StringName, GDMonoClass *> gdobject_class_cache;
-
HashMap<ClassKey, GDMonoClass *, ClassKey::Hasher> cached_classes;
Map<MonoClass *, GDMonoClass *> cached_raw;
@@ -111,11 +111,14 @@ public:
String get_path() const;
+ bool has_attribute(GDMonoClass *p_attr_class);
+ MonoObject *get_attribute(GDMonoClass *p_attr_class);
+
+ void fetch_attributes();
+
GDMonoClass *get_class(const StringName &p_namespace, const StringName &p_name);
GDMonoClass *get_class(MonoClass *p_mono_class);
- GDMonoClass *get_object_derived_class(const StringName &p_class);
-
static String find_assembly(const String &p_name);
static void fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config = String(), const String &p_custom_bcl_dir = String());
diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp
index 29aef6e609..d66cc29b9a 100644
--- a/modules/mono/mono_gd/gd_mono_cache.cpp
+++ b/modules/mono/mono_gd/gd_mono_cache.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -148,6 +148,11 @@ void CachedData::clear_godot_api_cache() {
class_PuppetSyncAttribute = nullptr;
class_GodotMethodAttribute = nullptr;
field_GodotMethodAttribute_methodName = nullptr;
+ class_ScriptPathAttribute = nullptr;
+ field_ScriptPathAttribute_path = nullptr;
+ class_AssemblyHasScriptsAttribute = nullptr;
+ field_AssemblyHasScriptsAttribute_requiresLookup = nullptr;
+ field_AssemblyHasScriptsAttribute_scriptTypes = nullptr;
field_GodotObject_ptr = nullptr;
field_StringName_ptr = nullptr;
@@ -272,6 +277,11 @@ void update_godot_api_cache() {
CACHE_CLASS_AND_CHECK(PuppetSyncAttribute, GODOT_API_CLASS(PuppetSyncAttribute));
CACHE_CLASS_AND_CHECK(GodotMethodAttribute, GODOT_API_CLASS(GodotMethodAttribute));
CACHE_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName"));
+ CACHE_CLASS_AND_CHECK(ScriptPathAttribute, GODOT_API_CLASS(ScriptPathAttribute));
+ CACHE_FIELD_AND_CHECK(ScriptPathAttribute, path, CACHED_CLASS(ScriptPathAttribute)->get_field("path"));
+ CACHE_CLASS_AND_CHECK(AssemblyHasScriptsAttribute, GODOT_API_CLASS(AssemblyHasScriptsAttribute));
+ CACHE_FIELD_AND_CHECK(AssemblyHasScriptsAttribute, requiresLookup, CACHED_CLASS(AssemblyHasScriptsAttribute)->get_field("requiresLookup"));
+ CACHE_FIELD_AND_CHECK(AssemblyHasScriptsAttribute, scriptTypes, CACHED_CLASS(AssemblyHasScriptsAttribute)->get_field("scriptTypes"));
CACHE_FIELD_AND_CHECK(GodotObject, ptr, CACHED_CLASS(GodotObject)->get_field(BINDINGS_PTR_FIELD));
CACHE_FIELD_AND_CHECK(StringName, ptr, CACHED_CLASS(StringName)->get_field(BINDINGS_PTR_FIELD));
@@ -316,5 +326,4 @@ void update_godot_api_cache() {
cached_data.godot_api_cache_updated = true;
}
-
} // namespace GDMonoCache
diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h
index a7bbc763a7..51370da452 100644
--- a/modules/mono/mono_gd/gd_mono_cache.h
+++ b/modules/mono/mono_gd/gd_mono_cache.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -119,6 +119,11 @@ struct CachedData {
GDMonoClass *class_PuppetSyncAttribute;
GDMonoClass *class_GodotMethodAttribute;
GDMonoField *field_GodotMethodAttribute_methodName;
+ GDMonoClass *class_ScriptPathAttribute;
+ GDMonoField *field_ScriptPathAttribute_path;
+ GDMonoClass *class_AssemblyHasScriptsAttribute;
+ GDMonoField *field_AssemblyHasScriptsAttribute_requiresLookup;
+ GDMonoField *field_AssemblyHasScriptsAttribute_scriptTypes;
GDMonoField *field_GodotObject_ptr;
GDMonoField *field_StringName_ptr;
@@ -181,7 +186,6 @@ inline void clear_corlib_cache() {
inline void clear_godot_api_cache() {
cached_data.clear_godot_api_cache();
}
-
} // namespace GDMonoCache
#define CACHED_CLASS(m_class) (GDMonoCache::cached_data.class_##m_class)
diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp
index 6575cbc1c8..f9fddd931b 100644
--- a/modules/mono/mono_gd/gd_mono_class.cpp
+++ b/modules/mono/mono_gd/gd_mono_class.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -177,7 +177,7 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
void *iter = nullptr;
MonoMethod *raw_method = nullptr;
while ((raw_method = mono_class_get_methods(get_mono_ptr(), &iter)) != nullptr) {
- StringName name = mono_method_get_name(raw_method);
+ StringName name = String::utf8(mono_method_get_name(raw_method));
// get_method implicitly fetches methods and adds them to this->methods
GDMonoMethod *method = get_method(raw_method, name);
@@ -290,7 +290,7 @@ bool GDMonoClass::has_public_parameterless_ctor() {
return ctor && ctor->get_visibility() == IMonoClassMember::PUBLIC;
}
-GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_count) {
+GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, uint16_t p_params_count) {
MethodKey key = MethodKey(p_name, p_params_count);
GDMonoMethod **match = methods.getptr(key);
@@ -319,7 +319,7 @@ GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method) {
MonoMethodSignature *sig = mono_method_signature(p_raw_method);
int params_count = mono_signature_get_param_count(sig);
- StringName method_name = mono_method_get_name(p_raw_method);
+ StringName method_name = String::utf8(mono_method_get_name(p_raw_method));
return get_method(p_raw_method, method_name, params_count);
}
@@ -330,7 +330,7 @@ GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName
return get_method(p_raw_method, p_name, params_count);
}
-GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName &p_name, int p_params_count) {
+GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName &p_name, uint16_t p_params_count) {
ERR_FAIL_NULL_V(p_raw_method, nullptr);
MethodKey key = MethodKey(p_name, p_params_count);
@@ -392,7 +392,7 @@ const Vector<GDMonoField *> &GDMonoClass::get_all_fields() {
void *iter = nullptr;
MonoClassField *raw_field = nullptr;
while ((raw_field = mono_class_get_fields(mono_class, &iter)) != nullptr) {
- StringName name = mono_field_get_name(raw_field);
+ StringName name = String::utf8(mono_field_get_name(raw_field));
Map<StringName, GDMonoField *>::Element *match = fields.find(name);
@@ -441,7 +441,7 @@ const Vector<GDMonoProperty *> &GDMonoClass::get_all_properties() {
void *iter = nullptr;
MonoProperty *raw_property = nullptr;
while ((raw_property = mono_class_get_properties(mono_class, &iter)) != nullptr) {
- StringName name = mono_property_get_name(raw_property);
+ StringName name = String::utf8(mono_property_get_name(raw_property));
Map<StringName, GDMonoProperty *>::Element *match = properties.find(name);
@@ -468,14 +468,14 @@ const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() {
MonoClass *raw_class = nullptr;
while ((raw_class = mono_class_get_nested_types(mono_class, &iter)) != nullptr) {
if (mono_class_is_delegate(raw_class)) {
- StringName name = mono_class_get_name(raw_class);
+ StringName name = String::utf8(mono_class_get_name(raw_class));
Map<StringName, GDMonoClass *>::Element *match = delegates.find(name);
if (match) {
delegates_list.push_back(match->get());
} else {
- GDMonoClass *delegate = memnew(GDMonoClass(mono_class_get_namespace(raw_class), mono_class_get_name(raw_class), raw_class, assembly));
+ GDMonoClass *delegate = memnew(GDMonoClass(String::utf8(mono_class_get_namespace(raw_class)), String::utf8(mono_class_get_name(raw_class)), raw_class, assembly));
delegates.insert(name, delegate);
delegates_list.push_back(delegate);
}
@@ -492,7 +492,7 @@ const Vector<GDMonoMethod *> &GDMonoClass::get_all_methods() {
void *iter = nullptr;
MonoMethod *raw_method = nullptr;
while ((raw_method = mono_class_get_methods(get_mono_ptr(), &iter)) != nullptr) {
- method_list.push_back(memnew(GDMonoMethod(mono_method_get_name(raw_method), raw_method)));
+ method_list.push_back(memnew(GDMonoMethod(String::utf8(mono_method_get_name(raw_method)), raw_method)));
}
method_list_fetched = true;
diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h
index 87db2fa033..daea75bae8 100644
--- a/modules/mono/mono_gd/gd_mono_class.h
+++ b/modules/mono/mono_gd/gd_mono_class.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -59,13 +59,12 @@ class GDMonoClass {
MethodKey() {}
- MethodKey(const StringName &p_name, int p_params_count) {
- name = p_name;
- params_count = p_params_count;
+ MethodKey(const StringName &p_name, uint16_t p_params_count) :
+ name(p_name), params_count(p_params_count) {
}
StringName name;
- int params_count;
+ uint16_t params_count = 0;
};
StringName namespace_name;
@@ -139,10 +138,10 @@ public:
bool implements_interface(GDMonoClass *p_interface);
bool has_public_parameterless_ctor();
- GDMonoMethod *get_method(const StringName &p_name, int p_params_count = 0);
+ GDMonoMethod *get_method(const StringName &p_name, uint16_t p_params_count = 0);
GDMonoMethod *get_method(MonoMethod *p_raw_method);
GDMonoMethod *get_method(MonoMethod *p_raw_method, const StringName &p_name);
- GDMonoMethod *get_method(MonoMethod *p_raw_method, const StringName &p_name, int p_params_count);
+ GDMonoMethod *get_method(MonoMethod *p_raw_method, const StringName &p_name, uint16_t p_params_count);
GDMonoMethod *get_method_with_desc(const String &p_description, bool p_include_namespace);
GDMonoField *get_field(const StringName &p_name);
diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp
index 563c45e71f..1d4d52dfce 100644
--- a/modules/mono/mono_gd/gd_mono_field.cpp
+++ b/modules/mono/mono_gd/gd_mono_field.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -46,29 +46,15 @@ void GDMonoField::set_value_raw(MonoObject *p_object, void *p_ptr) {
}
void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_value) {
-#define SET_FROM_STRUCT(m_type) \
- { \
- GDMonoMarshal::M_##m_type from = MARSHALLED_OUT(m_type, p_value.operator ::m_type()); \
- mono_field_set_value(p_object, mono_field, &from); \
- }
-
-#define SET_FROM_ARRAY(m_type) \
- { \
- MonoArray *managed = GDMonoMarshal::m_type##_to_mono_array(p_value.operator ::m_type()); \
- mono_field_set_value(p_object, mono_field, managed); \
- }
-
switch (type.type_encoding) {
case MONO_TYPE_BOOLEAN: {
MonoBoolean val = p_value.operator bool();
mono_field_set_value(p_object, mono_field, &val);
} break;
-
case MONO_TYPE_CHAR: {
int16_t val = p_value.operator unsigned short();
mono_field_set_value(p_object, mono_field, &val);
} break;
-
case MONO_TYPE_I1: {
int8_t val = p_value.operator signed char();
mono_field_set_value(p_object, mono_field, &val);
@@ -85,7 +71,6 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
int64_t val = p_value.operator int64_t();
mono_field_set_value(p_object, mono_field, &val);
} break;
-
case MONO_TYPE_U1: {
uint8_t val = p_value.operator unsigned char();
mono_field_set_value(p_object, mono_field, &val);
@@ -102,93 +87,92 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
uint64_t val = p_value.operator uint64_t();
mono_field_set_value(p_object, mono_field, &val);
} break;
-
case MONO_TYPE_R4: {
float val = p_value.operator float();
mono_field_set_value(p_object, mono_field, &val);
} break;
-
case MONO_TYPE_R8: {
double val = p_value.operator double();
mono_field_set_value(p_object, mono_field, &val);
} break;
-
- case MONO_TYPE_STRING: {
- if (p_value.get_type() == Variant::NIL) {
- // Otherwise, Variant -> String would return the string "Null"
- MonoString *mono_string = nullptr;
- mono_field_set_value(p_object, mono_field, mono_string);
- } else {
- MonoString *mono_string = GDMonoMarshal::mono_string_from_godot(p_value);
- mono_field_set_value(p_object, mono_field, mono_string);
- }
- } break;
-
case MONO_TYPE_VALUETYPE: {
GDMonoClass *tclass = type.type_class;
if (tclass == CACHED_CLASS(Vector2)) {
- SET_FROM_STRUCT(Vector2);
+ GDMonoMarshal::M_Vector2 from = MARSHALLED_OUT(Vector2, p_value.operator ::Vector2());
+ mono_field_set_value(p_object, mono_field, &from);
break;
}
if (tclass == CACHED_CLASS(Vector2i)) {
- SET_FROM_STRUCT(Vector2i);
+ GDMonoMarshal::M_Vector2i from = MARSHALLED_OUT(Vector2i, p_value.operator ::Vector2i());
+ mono_field_set_value(p_object, mono_field, &from);
break;
}
if (tclass == CACHED_CLASS(Rect2)) {
- SET_FROM_STRUCT(Rect2);
+ GDMonoMarshal::M_Rect2 from = MARSHALLED_OUT(Rect2, p_value.operator ::Rect2());
+ mono_field_set_value(p_object, mono_field, &from);
break;
}
if (tclass == CACHED_CLASS(Rect2i)) {
- SET_FROM_STRUCT(Rect2i);
+ GDMonoMarshal::M_Rect2i from = MARSHALLED_OUT(Rect2i, p_value.operator ::Rect2i());
+ mono_field_set_value(p_object, mono_field, &from);
break;
}
if (tclass == CACHED_CLASS(Transform2D)) {
- SET_FROM_STRUCT(Transform2D);
+ GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_value.operator ::Transform2D());
+ mono_field_set_value(p_object, mono_field, &from);
break;
}
if (tclass == CACHED_CLASS(Vector3)) {
- SET_FROM_STRUCT(Vector3);
+ GDMonoMarshal::M_Vector3 from = MARSHALLED_OUT(Vector3, p_value.operator ::Vector3());
+ mono_field_set_value(p_object, mono_field, &from);
break;
}
if (tclass == CACHED_CLASS(Vector3i)) {
- SET_FROM_STRUCT(Vector3i);
+ GDMonoMarshal::M_Vector3i from = MARSHALLED_OUT(Vector3i, p_value.operator ::Vector3i());
+ mono_field_set_value(p_object, mono_field, &from);
break;
}
if (tclass == CACHED_CLASS(Basis)) {
- SET_FROM_STRUCT(Basis);
+ GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_value.operator ::Basis());
+ mono_field_set_value(p_object, mono_field, &from);
break;
}
if (tclass == CACHED_CLASS(Quat)) {
- SET_FROM_STRUCT(Quat);
+ GDMonoMarshal::M_Quat from = MARSHALLED_OUT(Quat, p_value.operator ::Quat());
+ mono_field_set_value(p_object, mono_field, &from);
break;
}
if (tclass == CACHED_CLASS(Transform)) {
- SET_FROM_STRUCT(Transform);
+ GDMonoMarshal::M_Transform from = MARSHALLED_OUT(Transform, p_value.operator ::Transform());
+ mono_field_set_value(p_object, mono_field, &from);
break;
}
if (tclass == CACHED_CLASS(AABB)) {
- SET_FROM_STRUCT(AABB);
+ GDMonoMarshal::M_AABB from = MARSHALLED_OUT(AABB, p_value.operator ::AABB());
+ mono_field_set_value(p_object, mono_field, &from);
break;
}
if (tclass == CACHED_CLASS(Color)) {
- SET_FROM_STRUCT(Color);
+ GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_value.operator ::Color());
+ mono_field_set_value(p_object, mono_field, &from);
break;
}
if (tclass == CACHED_CLASS(Plane)) {
- SET_FROM_STRUCT(Plane);
+ GDMonoMarshal::M_Plane from = MARSHALLED_OUT(Plane, p_value.operator ::Plane());
+ mono_field_set_value(p_object, mono_field, &from);
break;
}
@@ -267,118 +251,35 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
ERR_FAIL_MSG("Attempted to set the value of a field of unmarshallable type: '" + tclass->get_name() + "'.");
} break;
-
+ case MONO_TYPE_STRING: {
+ if (p_value.get_type() == Variant::NIL) {
+ // Otherwise, Variant -> String would return the string "Null"
+ MonoString *mono_string = nullptr;
+ mono_field_set_value(p_object, mono_field, mono_string);
+ } else {
+ MonoString *mono_string = GDMonoMarshal::mono_string_from_godot(p_value);
+ mono_field_set_value(p_object, mono_field, mono_string);
+ }
+ } break;
case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY: {
- MonoArrayType *array_type = mono_type_get_array_type(type.type_class->get_mono_type());
-
- if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) {
- SET_FROM_ARRAY(Array);
- break;
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) {
- SET_FROM_ARRAY(PackedByteArray);
- break;
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) {
- SET_FROM_ARRAY(PackedInt32Array);
- break;
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) {
- SET_FROM_ARRAY(PackedInt64Array);
- break;
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(float)) {
- SET_FROM_ARRAY(PackedFloat32Array);
- break;
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(double)) {
- SET_FROM_ARRAY(PackedFloat64Array);
- break;
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(String)) {
- SET_FROM_ARRAY(PackedStringArray);
- break;
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) {
- SET_FROM_ARRAY(PackedVector2Array);
- break;
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) {
- SET_FROM_ARRAY(PackedVector3Array);
- break;
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(Color)) {
- SET_FROM_ARRAY(PackedColorArray);
- break;
- }
-
- GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
- if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) {
- MonoArray *managed = GDMonoMarshal::Array_to_mono_array(p_value.operator ::Array(), array_type_class);
+ MonoArray *managed = GDMonoMarshal::variant_to_mono_array(p_value, type.type_class);
+ if (likely(managed != nullptr)) {
mono_field_set_value(p_object, mono_field, managed);
- break;
}
-
- ERR_FAIL_MSG("Attempted to convert Variant to a managed array of unmarshallable element type.");
} break;
-
case MONO_TYPE_CLASS: {
- GDMonoClass *type_class = type.type_class;
-
- // GodotObject
- if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) {
- MonoObject *managed = GDMonoUtils::unmanaged_get_managed(p_value.operator Object *());
+ MonoObject *managed = GDMonoMarshal::variant_to_mono_object_of_class(p_value, type.type_class);
+ if (likely(managed != nullptr)) {
mono_field_set_value(p_object, mono_field, managed);
- break;
}
-
- if (CACHED_CLASS(StringName) == type_class) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator StringName());
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- if (CACHED_CLASS(NodePath) == type_class) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath());
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- if (CACHED_CLASS(RID) == type_class) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator RID());
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- // Godot.Collections.Dictionary or IDictionary
- if (CACHED_CLASS(Dictionary) == type_class || type_class == CACHED_CLASS(System_Collections_IDictionary)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- // Godot.Collections.Array or ICollection or IEnumerable
- if (CACHED_CLASS(Array) == type_class ||
- type_class == CACHED_CLASS(System_Collections_ICollection) ||
- type_class == CACHED_CLASS(System_Collections_IEnumerable)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
+ } break;
+ case MONO_TYPE_GENERICINST: {
+ MonoObject *managed = GDMonoMarshal::variant_to_mono_object_of_genericinst(p_value, type.type_class);
+ if (likely(managed != nullptr)) {
mono_field_set_value(p_object, mono_field, managed);
- break;
}
-
- ERR_FAIL_MSG("Attempted to set the value of a field of unmarshallable type: '" + type_class->get_name() + "'.");
} break;
-
case MONO_TYPE_OBJECT: {
// Variant
switch (p_value.get_type()) {
@@ -404,43 +305,56 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
mono_field_set_value(p_object, mono_field, mono_string);
} break;
case Variant::VECTOR2: {
- SET_FROM_STRUCT(Vector2);
+ GDMonoMarshal::M_Vector2 from = MARSHALLED_OUT(Vector2, p_value.operator ::Vector2());
+ mono_field_set_value(p_object, mono_field, &from);
} break;
case Variant::VECTOR2I: {
- SET_FROM_STRUCT(Vector2i);
+ GDMonoMarshal::M_Vector2i from = MARSHALLED_OUT(Vector2i, p_value.operator ::Vector2i());
+ mono_field_set_value(p_object, mono_field, &from);
} break;
case Variant::RECT2: {
- SET_FROM_STRUCT(Rect2);
+ GDMonoMarshal::M_Rect2 from = MARSHALLED_OUT(Rect2, p_value.operator ::Rect2());
+ mono_field_set_value(p_object, mono_field, &from);
} break;
case Variant::RECT2I: {
- SET_FROM_STRUCT(Rect2i);
+ GDMonoMarshal::M_Rect2i from = MARSHALLED_OUT(Rect2i, p_value.operator ::Rect2i());
+ mono_field_set_value(p_object, mono_field, &from);
} break;
case Variant::VECTOR3: {
- SET_FROM_STRUCT(Vector3);
+ GDMonoMarshal::M_Vector3 from = MARSHALLED_OUT(Vector3, p_value.operator ::Vector3());
+ mono_field_set_value(p_object, mono_field, &from);
} break;
case Variant::VECTOR3I: {
- SET_FROM_STRUCT(Vector3i);
+ GDMonoMarshal::M_Vector3i from = MARSHALLED_OUT(Vector3i, p_value.operator ::Vector3i());
+ mono_field_set_value(p_object, mono_field, &from);
} break;
case Variant::TRANSFORM2D: {
- SET_FROM_STRUCT(Transform2D);
+ GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_value.operator ::Transform2D());
+ mono_field_set_value(p_object, mono_field, &from);
} break;
case Variant::PLANE: {
- SET_FROM_STRUCT(Plane);
+ GDMonoMarshal::M_Plane from = MARSHALLED_OUT(Plane, p_value.operator ::Plane());
+ mono_field_set_value(p_object, mono_field, &from);
} break;
case Variant::QUAT: {
- SET_FROM_STRUCT(Quat);
+ GDMonoMarshal::M_Quat from = MARSHALLED_OUT(Quat, p_value.operator ::Quat());
+ mono_field_set_value(p_object, mono_field, &from);
} break;
case Variant::AABB: {
- SET_FROM_STRUCT(AABB);
+ GDMonoMarshal::M_AABB from = MARSHALLED_OUT(AABB, p_value.operator ::AABB());
+ mono_field_set_value(p_object, mono_field, &from);
} break;
case Variant::BASIS: {
- SET_FROM_STRUCT(Basis);
+ GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_value.operator ::Basis());
+ mono_field_set_value(p_object, mono_field, &from);
} break;
case Variant::TRANSFORM: {
- SET_FROM_STRUCT(Transform);
+ GDMonoMarshal::M_Transform from = MARSHALLED_OUT(Transform, p_value.operator ::Transform());
+ mono_field_set_value(p_object, mono_field, &from);
} break;
case Variant::COLOR: {
- SET_FROM_STRUCT(Color);
+ GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_value.operator ::Color());
+ mono_field_set_value(p_object, mono_field, &from);
} break;
case Variant::STRING_NAME: {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator StringName());
@@ -450,8 +364,8 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath());
mono_field_set_value(p_object, mono_field, managed);
} break;
- case Variant::_RID: {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator RID());
+ case Variant::RID: {
+ MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator ::RID());
mono_field_set_value(p_object, mono_field, managed);
} break;
case Variant::OBJECT: {
@@ -475,106 +389,49 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
mono_field_set_value(p_object, mono_field, managed);
} break;
case Variant::PACKED_BYTE_ARRAY: {
- SET_FROM_ARRAY(PackedByteArray);
+ MonoArray *managed = GDMonoMarshal::PackedByteArray_to_mono_array(p_value.operator ::PackedByteArray());
+ mono_field_set_value(p_object, mono_field, managed);
} break;
case Variant::PACKED_INT32_ARRAY: {
- SET_FROM_ARRAY(PackedInt32Array);
+ MonoArray *managed = GDMonoMarshal::PackedInt32Array_to_mono_array(p_value.operator ::PackedInt32Array());
+ mono_field_set_value(p_object, mono_field, managed);
} break;
case Variant::PACKED_INT64_ARRAY: {
- SET_FROM_ARRAY(PackedInt64Array);
+ MonoArray *managed = GDMonoMarshal::PackedInt64Array_to_mono_array(p_value.operator ::PackedInt64Array());
+ mono_field_set_value(p_object, mono_field, managed);
} break;
case Variant::PACKED_FLOAT32_ARRAY: {
- SET_FROM_ARRAY(PackedFloat32Array);
+ MonoArray *managed = GDMonoMarshal::PackedFloat32Array_to_mono_array(p_value.operator ::PackedFloat32Array());
+ mono_field_set_value(p_object, mono_field, managed);
} break;
case Variant::PACKED_FLOAT64_ARRAY: {
- SET_FROM_ARRAY(PackedFloat64Array);
+ MonoArray *managed = GDMonoMarshal::PackedFloat64Array_to_mono_array(p_value.operator ::PackedFloat64Array());
+ mono_field_set_value(p_object, mono_field, managed);
} break;
case Variant::PACKED_STRING_ARRAY: {
- SET_FROM_ARRAY(PackedStringArray);
+ MonoArray *managed = GDMonoMarshal::PackedStringArray_to_mono_array(p_value.operator ::PackedStringArray());
+ mono_field_set_value(p_object, mono_field, managed);
} break;
case Variant::PACKED_VECTOR2_ARRAY: {
- SET_FROM_ARRAY(PackedVector2Array);
+ MonoArray *managed = GDMonoMarshal::PackedVector2Array_to_mono_array(p_value.operator ::PackedVector2Array());
+ mono_field_set_value(p_object, mono_field, managed);
} break;
case Variant::PACKED_VECTOR3_ARRAY: {
- SET_FROM_ARRAY(PackedVector3Array);
+ MonoArray *managed = GDMonoMarshal::PackedVector3Array_to_mono_array(p_value.operator ::PackedVector3Array());
+ mono_field_set_value(p_object, mono_field, managed);
} break;
case Variant::PACKED_COLOR_ARRAY: {
- SET_FROM_ARRAY(PackedColorArray);
+ MonoArray *managed = GDMonoMarshal::PackedColorArray_to_mono_array(p_value.operator ::PackedColorArray());
+ mono_field_set_value(p_object, mono_field, managed);
} break;
default:
break;
}
} break;
-
- case MONO_TYPE_GENERICINST: {
- MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type.type_class->get_mono_type());
-
- // Godot.Collections.Dictionary<TKey, TValue>
- if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), type.type_class);
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- // Godot.Collections.Array<T>
- if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), type.type_class);
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- // System.Collections.Generic.Dictionary<TKey, TValue>
- if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
- MonoReflectionType *key_reftype = nullptr;
- MonoReflectionType *value_reftype = nullptr;
- GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
- MonoObject *managed = GDMonoMarshal::Dictionary_to_system_generic_dict(p_value.operator Dictionary(),
- type.type_class, key_reftype, value_reftype);
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- // System.Collections.Generic.List<T>
- if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
- MonoReflectionType *elem_reftype = nullptr;
- GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
- MonoObject *managed = GDMonoMarshal::Array_to_system_generic_list(p_value.operator Array(),
- type.type_class, elem_reftype);
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- // IDictionary<TKey, TValue>
- if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) {
- MonoReflectionType *key_reftype;
- MonoReflectionType *value_reftype;
- GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
- GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype);
-
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), godot_dict_class);
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- // ICollection<T> or IEnumerable<T>
- if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) {
- MonoReflectionType *elem_reftype;
- GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
- GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(elem_reftype);
-
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), godot_array_class);
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
- } break;
-
default: {
ERR_PRINT("Attempted to set the value of a field of unexpected type encoding: " + itos(type.type_encoding) + ".");
} break;
}
-
-#undef SET_FROM_ARRAY_AND_BREAK
-#undef SET_FROM_STRUCT_AND_BREAK
}
MonoObject *GDMonoField::get_value(MonoObject *p_object) {
@@ -652,7 +509,7 @@ IMonoClassMember::Visibility GDMonoField::get_visibility() {
GDMonoField::GDMonoField(MonoClassField *p_mono_field, GDMonoClass *p_owner) {
owner = p_owner;
mono_field = p_mono_field;
- name = mono_field_get_name(mono_field);
+ name = String::utf8(mono_field_get_name(mono_field));
MonoType *field_type = mono_field_get_type(mono_field);
type.type_encoding = mono_type_get_type(field_type);
MonoClass *field_type_class = mono_class_from_mono_type(field_type);
diff --git a/modules/mono/mono_gd/gd_mono_field.h b/modules/mono/mono_gd/gd_mono_field.h
index 5b40b439f9..ed5078c673 100644
--- a/modules/mono/mono_gd/gd_mono_field.h
+++ b/modules/mono/mono_gd/gd_mono_field.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/mono_gd/gd_mono_header.h b/modules/mono/mono_gd/gd_mono_header.h
index ffb56e7cec..483030610f 100644
--- a/modules/mono/mono_gd/gd_mono_header.h
+++ b/modules/mono/mono_gd/gd_mono_header.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp
index 0ed9e441ef..fa93c6533a 100644
--- a/modules/mono/mono_gd/gd_mono_internals.cpp
+++ b/modules/mono/mono_gd/gd_mono_internals.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -43,7 +43,6 @@
#include <mono/metadata/exception.h>
namespace GDMonoInternals {
-
void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
// This method should not fail
@@ -113,9 +112,11 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
void unhandled_exception(MonoException *p_exc) {
mono_print_unhandled_exception((MonoObject *)p_exc);
+ gd_unhandled_exception_event(p_exc);
if (GDMono::get_singleton()->get_unhandled_exception_policy() == GDMono::POLICY_TERMINATE_APP) {
// Too bad 'mono_invoke_unhandled_exception_hook' is not exposed to embedders
+ mono_unhandled_exception((MonoObject *)p_exc);
GDMono::unhandled_exception_hook((MonoObject *)p_exc, nullptr);
GD_UNREACHABLE();
} else {
@@ -128,4 +129,13 @@ void unhandled_exception(MonoException *p_exc) {
}
}
+void gd_unhandled_exception_event(MonoException *p_exc) {
+ MonoImage *mono_image = GDMono::get_singleton()->get_core_api_assembly()->get_image();
+
+ MonoClass *gd_klass = mono_class_from_name(mono_image, "Godot", "GD");
+ MonoMethod *unhandled_exception_method = mono_class_get_method_from_name(gd_klass, "OnUnhandledException", -1);
+ void *args[1];
+ args[0] = p_exc;
+ mono_runtime_invoke(unhandled_exception_method, nullptr, (void **)args, nullptr);
+}
} // namespace GDMonoInternals
diff --git a/modules/mono/mono_gd/gd_mono_internals.h b/modules/mono/mono_gd/gd_mono_internals.h
index d1d5eca263..26eb270eee 100644
--- a/modules/mono/mono_gd/gd_mono_internals.h
+++ b/modules/mono/mono_gd/gd_mono_internals.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -38,7 +38,6 @@
#include "core/object/class_db.h"
namespace GDMonoInternals {
-
void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged);
/**
@@ -47,6 +46,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged);
*/
void unhandled_exception(MonoException *p_exc);
+void gd_unhandled_exception_event(MonoException *p_exc);
} // namespace GDMonoInternals
#endif // GD_MONO_INTERNALS_H
diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp
index b8ee0204c4..dafd36c36b 100644
--- a/modules/mono/mono_gd/gd_mono_log.cpp
+++ b/modules/mono/mono_gd/gd_mono_log.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -160,13 +160,13 @@ void GDMonoLog::initialize() {
OS::Date date_now = OS::get_singleton()->get_date();
OS::Time time_now = OS::get_singleton()->get_time();
- String log_file_name = str_format("%d_%02d_%02d %02d.%02d.%02d",
+ String log_file_name = str_format("%04d-%02d-%02d_%02d.%02d.%02d",
date_now.year, date_now.month, date_now.day,
time_now.hour, time_now.min, time_now.sec);
- log_file_name += str_format(" (%d)", OS::get_singleton()->get_process_id());
+ log_file_name += str_format("_%d", OS::get_singleton()->get_process_id());
- log_file_name += ".txt";
+ log_file_name += ".log";
log_file_path = logs_dir.plus_file(log_file_name);
@@ -189,8 +189,6 @@ void GDMonoLog::initialize() {
GDMonoLog::GDMonoLog() {
singleton = this;
-
- log_level_id = -1;
}
GDMonoLog::~GDMonoLog() {
diff --git a/modules/mono/mono_gd/gd_mono_log.h b/modules/mono/mono_gd/gd_mono_log.h
index 3a52316060..f7a53156ab 100644
--- a/modules/mono/mono_gd/gd_mono_log.h
+++ b/modules/mono/mono_gd/gd_mono_log.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -46,9 +46,9 @@
class GDMonoLog {
#ifdef GD_MONO_LOG_ENABLED
- int log_level_id;
+ int log_level_id = -1;
- FileAccess *log_file;
+ FileAccess *log_file = nullptr;
String log_file_path;
bool _try_create_logs_dir(const String &p_logs_dir);
diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp
index c460e283ea..359f6bba4d 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.cpp
+++ b/modules/mono/mono_gd/gd_mono_marshal.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -204,7 +204,7 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_
}
if (CACHED_CLASS(RID) == type_class) {
- return Variant::_RID;
+ return Variant::RID;
}
if (CACHED_CLASS(Dictionary) == type_class) {
@@ -311,152 +311,590 @@ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_
return false;
}
-MonoObject *variant_to_mono_object(const Variant *p_var) {
- ManagedType type;
+MonoString *variant_to_mono_string(const Variant &p_var) {
+ if (p_var.get_type() == Variant::NIL) {
+ return nullptr; // Otherwise, Variant -> String would return the string "Null"
+ }
+ return mono_string_from_godot(p_var.operator String());
+}
+
+MonoArray *variant_to_mono_array(const Variant &p_var, GDMonoClass *p_type_class) {
+ MonoArrayType *array_type = mono_type_get_array_type(p_type_class->get_mono_type());
+
+ if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) {
+ return Array_to_mono_array(p_var.operator Array());
+ }
+
+ if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) {
+ return PackedByteArray_to_mono_array(p_var.operator PackedByteArray());
+ }
+
+ if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) {
+ return PackedInt32Array_to_mono_array(p_var.operator PackedInt32Array());
+ }
+
+ if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) {
+ return PackedInt64Array_to_mono_array(p_var.operator PackedInt64Array());
+ }
+
+ if (array_type->eklass == CACHED_CLASS_RAW(float)) {
+ return PackedFloat32Array_to_mono_array(p_var.operator PackedFloat32Array());
+ }
+
+ if (array_type->eklass == CACHED_CLASS_RAW(double)) {
+ return PackedFloat64Array_to_mono_array(p_var.operator PackedFloat64Array());
+ }
+
+ if (array_type->eklass == CACHED_CLASS_RAW(String)) {
+ return PackedStringArray_to_mono_array(p_var.operator PackedStringArray());
+ }
+
+ if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) {
+ return PackedVector2Array_to_mono_array(p_var.operator PackedVector2Array());
+ }
+
+ if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) {
+ return PackedVector3Array_to_mono_array(p_var.operator PackedVector3Array());
+ }
+
+ if (array_type->eklass == CACHED_CLASS_RAW(Color)) {
+ return PackedColorArray_to_mono_array(p_var.operator PackedColorArray());
+ }
+
+ if (mono_class_is_assignable_from(CACHED_CLASS(GodotObject)->get_mono_ptr(), array_type->eklass)) {
+ return Array_to_mono_array(p_var.operator ::Array(), array_type->eklass);
+ }
+
+ ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to array of unsupported element type:" +
+ GDMonoClass::get_full_name(array_type->eklass) + "'.");
+}
+
+MonoObject *variant_to_mono_object_of_class(const Variant &p_var, GDMonoClass *p_type_class) {
+ // GodotObject
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(p_type_class)) {
+ return GDMonoUtils::unmanaged_get_managed(p_var.operator Object *());
+ }
+
+ if (CACHED_CLASS(StringName) == p_type_class) {
+ return GDMonoUtils::create_managed_from(p_var.operator StringName());
+ }
+
+ if (CACHED_CLASS(NodePath) == p_type_class) {
+ return GDMonoUtils::create_managed_from(p_var.operator NodePath());
+ }
+
+ if (CACHED_CLASS(RID) == p_type_class) {
+ return GDMonoUtils::create_managed_from(p_var.operator ::RID());
+ }
+
+ // Godot.Collections.Dictionary or IDictionary
+ if (CACHED_CLASS(Dictionary) == p_type_class || CACHED_CLASS(System_Collections_IDictionary) == p_type_class) {
+ return GDMonoUtils::create_managed_from(p_var.operator Dictionary(), CACHED_CLASS(Dictionary));
+ }
+
+ // Godot.Collections.Array or ICollection or IEnumerable
+ if (CACHED_CLASS(Array) == p_type_class ||
+ CACHED_CLASS(System_Collections_ICollection) == p_type_class ||
+ CACHED_CLASS(System_Collections_IEnumerable) == p_type_class) {
+ return GDMonoUtils::create_managed_from(p_var.operator Array(), CACHED_CLASS(Array));
+ }
+
+ ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported type: '" +
+ p_type_class->get_full_name() + "'.");
+}
+
+MonoObject *variant_to_mono_object_of_genericinst(const Variant &p_var, GDMonoClass *p_type_class) {
+ MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type_class->get_mono_type());
+
+ // Godot.Collections.Dictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
+ return GDMonoUtils::create_managed_from(p_var.operator Dictionary(), p_type_class);
+ }
- type.type_encoding = MONO_TYPE_OBJECT;
- // type.type_class is not needed when we specify the MONO_TYPE_OBJECT encoding
+ // Godot.Collections.Array<T>
+ if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
+ return GDMonoUtils::create_managed_from(p_var.operator Array(), p_type_class);
+ }
+
+ // System.Collections.Generic.Dictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
+ MonoReflectionType *key_reftype = nullptr;
+ MonoReflectionType *value_reftype = nullptr;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ return Dictionary_to_system_generic_dict(p_var.operator Dictionary(), p_type_class, key_reftype, value_reftype);
+ }
+
+ // System.Collections.Generic.List<T>
+ if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
+ MonoReflectionType *elem_reftype = nullptr;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ return Array_to_system_generic_list(p_var.operator Array(), p_type_class, elem_reftype);
+ }
+
+ // IDictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) {
+ MonoReflectionType *key_reftype;
+ MonoReflectionType *value_reftype;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype);
+
+ return GDMonoUtils::create_managed_from(p_var.operator Dictionary(), godot_dict_class);
+ }
+
+ // ICollection<T> or IEnumerable<T>
+ if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) {
+ MonoReflectionType *elem_reftype;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(elem_reftype);
+
+ return GDMonoUtils::create_managed_from(p_var.operator Array(), godot_array_class);
+ }
- return variant_to_mono_object(p_var, type);
+ ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported generic type: '" +
+ p_type_class->get_full_name() + "'.");
+}
+
+MonoObject *variant_to_mono_object(const Variant &p_var) {
+ // Variant
+ switch (p_var.get_type()) {
+ case Variant::BOOL: {
+ MonoBoolean val = p_var.operator bool();
+ return BOX_BOOLEAN(val);
+ }
+ case Variant::INT: {
+ int64_t val = p_var.operator int64_t();
+ return BOX_INT64(val);
+ }
+ case Variant::FLOAT: {
+#ifdef REAL_T_IS_DOUBLE
+ double val = p_var.operator double();
+ return BOX_DOUBLE(val);
+#else
+ float val = p_var.operator float();
+ return BOX_FLOAT(val);
+#endif
+ }
+ case Variant::STRING:
+ return (MonoObject *)mono_string_from_godot(p_var.operator String());
+ case Variant::VECTOR2: {
+ GDMonoMarshal::M_Vector2 from = MARSHALLED_OUT(Vector2, p_var.operator ::Vector2());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2), &from);
+ }
+ case Variant::VECTOR2I: {
+ GDMonoMarshal::M_Vector2i from = MARSHALLED_OUT(Vector2i, p_var.operator ::Vector2i());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2i), &from);
+ }
+ case Variant::RECT2: {
+ GDMonoMarshal::M_Rect2 from = MARSHALLED_OUT(Rect2, p_var.operator ::Rect2());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2), &from);
+ }
+ case Variant::RECT2I: {
+ GDMonoMarshal::M_Rect2i from = MARSHALLED_OUT(Rect2i, p_var.operator ::Rect2i());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2i), &from);
+ }
+ case Variant::VECTOR3: {
+ GDMonoMarshal::M_Vector3 from = MARSHALLED_OUT(Vector3, p_var.operator ::Vector3());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3), &from);
+ }
+ case Variant::VECTOR3I: {
+ GDMonoMarshal::M_Vector3i from = MARSHALLED_OUT(Vector3i, p_var.operator ::Vector3i());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3i), &from);
+ }
+ case Variant::TRANSFORM2D: {
+ GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_var.operator ::Transform2D());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform2D), &from);
+ }
+ case Variant::PLANE: {
+ GDMonoMarshal::M_Plane from = MARSHALLED_OUT(Plane, p_var.operator ::Plane());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Plane), &from);
+ }
+ case Variant::QUAT: {
+ GDMonoMarshal::M_Quat from = MARSHALLED_OUT(Quat, p_var.operator ::Quat());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Quat), &from);
+ }
+ case Variant::AABB: {
+ GDMonoMarshal::M_AABB from = MARSHALLED_OUT(AABB, p_var.operator ::AABB());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(AABB), &from);
+ }
+ case Variant::BASIS: {
+ GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_var.operator ::Basis());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Basis), &from);
+ }
+ case Variant::TRANSFORM: {
+ GDMonoMarshal::M_Transform from = MARSHALLED_OUT(Transform, p_var.operator ::Transform());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform), &from);
+ }
+ case Variant::COLOR: {
+ GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_var.operator ::Color());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Color), &from);
+ }
+ case Variant::STRING_NAME:
+ return GDMonoUtils::create_managed_from(p_var.operator StringName());
+ case Variant::NODE_PATH:
+ return GDMonoUtils::create_managed_from(p_var.operator NodePath());
+ case Variant::RID:
+ return GDMonoUtils::create_managed_from(p_var.operator ::RID());
+ case Variant::OBJECT:
+ return GDMonoUtils::unmanaged_get_managed(p_var.operator Object *());
+ case Variant::CALLABLE: {
+ GDMonoMarshal::M_Callable from = GDMonoMarshal::callable_to_managed(p_var.operator Callable());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Callable), &from);
+ }
+ case Variant::SIGNAL: {
+ GDMonoMarshal::M_SignalInfo from = GDMonoMarshal::signal_info_to_managed(p_var.operator Signal());
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(SignalInfo), &from);
+ }
+ case Variant::DICTIONARY:
+ return GDMonoUtils::create_managed_from(p_var.operator Dictionary(), CACHED_CLASS(Dictionary));
+ case Variant::ARRAY:
+ return GDMonoUtils::create_managed_from(p_var.operator Array(), CACHED_CLASS(Array));
+ case Variant::PACKED_BYTE_ARRAY:
+ return (MonoObject *)PackedByteArray_to_mono_array(p_var.operator PackedByteArray());
+ case Variant::PACKED_INT32_ARRAY:
+ return (MonoObject *)PackedInt32Array_to_mono_array(p_var.operator PackedInt32Array());
+ case Variant::PACKED_INT64_ARRAY:
+ return (MonoObject *)PackedInt64Array_to_mono_array(p_var.operator PackedInt64Array());
+ case Variant::PACKED_FLOAT32_ARRAY:
+ return (MonoObject *)PackedFloat32Array_to_mono_array(p_var.operator PackedFloat32Array());
+ case Variant::PACKED_FLOAT64_ARRAY:
+ return (MonoObject *)PackedFloat64Array_to_mono_array(p_var.operator PackedFloat64Array());
+ case Variant::PACKED_STRING_ARRAY:
+ return (MonoObject *)PackedStringArray_to_mono_array(p_var.operator PackedStringArray());
+ case Variant::PACKED_VECTOR2_ARRAY:
+ return (MonoObject *)PackedVector2Array_to_mono_array(p_var.operator PackedVector2Array());
+ case Variant::PACKED_VECTOR3_ARRAY:
+ return (MonoObject *)PackedVector3Array_to_mono_array(p_var.operator PackedVector3Array());
+ case Variant::PACKED_COLOR_ARRAY:
+ return (MonoObject *)PackedColorArray_to_mono_array(p_var.operator PackedColorArray());
+ default:
+ return nullptr;
+ }
}
-MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_type) {
+size_t variant_get_managed_unboxed_size(const ManagedType &p_type) {
+ // This method prints no errors for unsupported types. It's called on all methods, not only
+ // those that end up being invoked with Variant parameters.
+
+ // For MonoObject* we return 0, as it doesn't need to be stored.
+ constexpr size_t zero_for_mono_object = 0;
+
+ switch (p_type.type_encoding) {
+ case MONO_TYPE_BOOLEAN:
+ return sizeof(MonoBoolean);
+ case MONO_TYPE_CHAR:
+ return sizeof(uint16_t);
+ case MONO_TYPE_I1:
+ return sizeof(int8_t);
+ case MONO_TYPE_I2:
+ return sizeof(int16_t);
+ case MONO_TYPE_I4:
+ return sizeof(int32_t);
+ case MONO_TYPE_I8:
+ return sizeof(int64_t);
+ case MONO_TYPE_U1:
+ return sizeof(uint8_t);
+ case MONO_TYPE_U2:
+ return sizeof(uint16_t);
+ case MONO_TYPE_U4:
+ return sizeof(uint32_t);
+ case MONO_TYPE_U8:
+ return sizeof(uint64_t);
+ case MONO_TYPE_R4:
+ return sizeof(float);
+ case MONO_TYPE_R8:
+ return sizeof(double);
+ case MONO_TYPE_VALUETYPE: {
+ GDMonoClass *vtclass = p_type.type_class;
+
+#define RETURN_CHECK_FOR_STRUCT(m_struct) \
+ if (vtclass == CACHED_CLASS(m_struct)) { \
+ return sizeof(M_##m_struct); \
+ }
+
+ RETURN_CHECK_FOR_STRUCT(Vector2);
+ RETURN_CHECK_FOR_STRUCT(Vector2i);
+ RETURN_CHECK_FOR_STRUCT(Rect2);
+ RETURN_CHECK_FOR_STRUCT(Rect2i);
+ RETURN_CHECK_FOR_STRUCT(Transform2D);
+ RETURN_CHECK_FOR_STRUCT(Vector3);
+ RETURN_CHECK_FOR_STRUCT(Vector3i);
+ RETURN_CHECK_FOR_STRUCT(Basis);
+ RETURN_CHECK_FOR_STRUCT(Quat);
+ RETURN_CHECK_FOR_STRUCT(Transform);
+ RETURN_CHECK_FOR_STRUCT(AABB);
+ RETURN_CHECK_FOR_STRUCT(Color);
+ RETURN_CHECK_FOR_STRUCT(Plane);
+ RETURN_CHECK_FOR_STRUCT(Callable);
+ RETURN_CHECK_FOR_STRUCT(SignalInfo);
+
+#undef RETURN_CHECK_FOR_STRUCT
+
+ if (mono_class_is_enum(vtclass->get_mono_ptr())) {
+ MonoType *enum_basetype = mono_class_enum_basetype(vtclass->get_mono_ptr());
+ switch (mono_type_get_type(enum_basetype)) {
+ case MONO_TYPE_BOOLEAN:
+ return sizeof(MonoBoolean);
+ case MONO_TYPE_CHAR:
+ return sizeof(uint16_t);
+ case MONO_TYPE_I1:
+ return sizeof(int8_t);
+ case MONO_TYPE_I2:
+ return sizeof(int16_t);
+ case MONO_TYPE_I4:
+ return sizeof(int32_t);
+ case MONO_TYPE_I8:
+ return sizeof(int64_t);
+ case MONO_TYPE_U1:
+ return sizeof(uint8_t);
+ case MONO_TYPE_U2:
+ return sizeof(uint16_t);
+ case MONO_TYPE_U4:
+ return sizeof(uint32_t);
+ case MONO_TYPE_U8:
+ return sizeof(uint64_t);
+ default: {
+ // Enum with unsupported base type. We return nullptr MonoObject* on error.
+ return zero_for_mono_object;
+ }
+ }
+ }
+
+ // Enum with unsupported value type. We return nullptr MonoObject* on error.
+ } break;
+ case MONO_TYPE_STRING:
+ return zero_for_mono_object;
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_GENERICINST:
+ return zero_for_mono_object;
+ case MONO_TYPE_OBJECT:
+ return zero_for_mono_object;
+ }
+
+ // Unsupported type encoding. We return nullptr MonoObject* on error.
+ return zero_for_mono_object;
+}
+
+void *variant_to_managed_unboxed(const Variant &p_var, const ManagedType &p_type, void *r_buffer, unsigned int &r_offset) {
+#define RETURN_TYPE_VAL(m_type, m_val) \
+ *reinterpret_cast<m_type *>(r_buffer) = m_val; \
+ r_offset += sizeof(m_type); \
+ return r_buffer;
+
+ switch (p_type.type_encoding) {
+ case MONO_TYPE_BOOLEAN:
+ RETURN_TYPE_VAL(MonoBoolean, (MonoBoolean)p_var.operator bool());
+ case MONO_TYPE_CHAR:
+ RETURN_TYPE_VAL(uint16_t, p_var.operator unsigned short());
+ case MONO_TYPE_I1:
+ RETURN_TYPE_VAL(int8_t, p_var.operator signed char());
+ case MONO_TYPE_I2:
+ RETURN_TYPE_VAL(int16_t, p_var.operator signed short());
+ case MONO_TYPE_I4:
+ RETURN_TYPE_VAL(int32_t, p_var.operator signed int());
+ case MONO_TYPE_I8:
+ RETURN_TYPE_VAL(int64_t, p_var.operator int64_t());
+ case MONO_TYPE_U1:
+ RETURN_TYPE_VAL(uint8_t, p_var.operator unsigned char());
+ case MONO_TYPE_U2:
+ RETURN_TYPE_VAL(uint16_t, p_var.operator unsigned short());
+ case MONO_TYPE_U4:
+ RETURN_TYPE_VAL(uint32_t, p_var.operator unsigned int());
+ case MONO_TYPE_U8:
+ RETURN_TYPE_VAL(uint64_t, p_var.operator uint64_t());
+ case MONO_TYPE_R4:
+ RETURN_TYPE_VAL(float, p_var.operator float());
+ case MONO_TYPE_R8:
+ RETURN_TYPE_VAL(double, p_var.operator double());
+ case MONO_TYPE_VALUETYPE: {
+ GDMonoClass *vtclass = p_type.type_class;
+
+#define RETURN_CHECK_FOR_STRUCT(m_struct) \
+ if (vtclass == CACHED_CLASS(m_struct)) { \
+ GDMonoMarshal::M_##m_struct from = MARSHALLED_OUT(m_struct, p_var.operator ::m_struct()); \
+ RETURN_TYPE_VAL(M_##m_struct, from); \
+ }
+
+ RETURN_CHECK_FOR_STRUCT(Vector2);
+ RETURN_CHECK_FOR_STRUCT(Vector2i);
+ RETURN_CHECK_FOR_STRUCT(Rect2);
+ RETURN_CHECK_FOR_STRUCT(Rect2i);
+ RETURN_CHECK_FOR_STRUCT(Transform2D);
+ RETURN_CHECK_FOR_STRUCT(Vector3);
+ RETURN_CHECK_FOR_STRUCT(Vector3i);
+ RETURN_CHECK_FOR_STRUCT(Basis);
+ RETURN_CHECK_FOR_STRUCT(Quat);
+ RETURN_CHECK_FOR_STRUCT(Transform);
+ RETURN_CHECK_FOR_STRUCT(AABB);
+ RETURN_CHECK_FOR_STRUCT(Color);
+ RETURN_CHECK_FOR_STRUCT(Plane);
+
+#undef RETURN_CHECK_FOR_STRUCT
+
+ if (vtclass == CACHED_CLASS(Callable)) {
+ GDMonoMarshal::M_Callable from = GDMonoMarshal::callable_to_managed(p_var.operator Callable());
+ RETURN_TYPE_VAL(M_Callable, from);
+ }
+
+ if (vtclass == CACHED_CLASS(SignalInfo)) {
+ GDMonoMarshal::M_SignalInfo from = GDMonoMarshal::signal_info_to_managed(p_var.operator Signal());
+ RETURN_TYPE_VAL(M_SignalInfo, from);
+ }
+
+ if (mono_class_is_enum(vtclass->get_mono_ptr())) {
+ MonoType *enum_basetype = mono_class_enum_basetype(vtclass->get_mono_ptr());
+ switch (mono_type_get_type(enum_basetype)) {
+ case MONO_TYPE_BOOLEAN: {
+ MonoBoolean val = p_var.operator bool();
+ RETURN_TYPE_VAL(MonoBoolean, val);
+ }
+ case MONO_TYPE_CHAR: {
+ uint16_t val = p_var.operator unsigned short();
+ RETURN_TYPE_VAL(uint16_t, val);
+ }
+ case MONO_TYPE_I1: {
+ int8_t val = p_var.operator signed char();
+ RETURN_TYPE_VAL(int8_t, val);
+ }
+ case MONO_TYPE_I2: {
+ int16_t val = p_var.operator signed short();
+ RETURN_TYPE_VAL(int16_t, val);
+ }
+ case MONO_TYPE_I4: {
+ int32_t val = p_var.operator signed int();
+ RETURN_TYPE_VAL(int32_t, val);
+ }
+ case MONO_TYPE_I8: {
+ int64_t val = p_var.operator int64_t();
+ RETURN_TYPE_VAL(int64_t, val);
+ }
+ case MONO_TYPE_U1: {
+ uint8_t val = p_var.operator unsigned char();
+ RETURN_TYPE_VAL(uint8_t, val);
+ }
+ case MONO_TYPE_U2: {
+ uint16_t val = p_var.operator unsigned short();
+ RETURN_TYPE_VAL(uint16_t, val);
+ }
+ case MONO_TYPE_U4: {
+ uint32_t val = p_var.operator unsigned int();
+ RETURN_TYPE_VAL(uint32_t, val);
+ }
+ case MONO_TYPE_U8: {
+ uint64_t val = p_var.operator uint64_t();
+ RETURN_TYPE_VAL(uint64_t, val);
+ }
+ default: {
+ ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to enum value of unsupported base type: '" +
+ GDMonoClass::get_full_name(mono_class_from_mono_type(enum_basetype)) + "'.");
+ }
+ }
+ }
+
+ ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported value type: '" +
+ p_type.type_class->get_full_name() + "'.");
+ } break;
+#undef RETURN_TYPE_VAL
+ case MONO_TYPE_STRING:
+ return variant_to_mono_string(p_var);
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_SZARRAY:
+ return variant_to_mono_array(p_var, p_type.type_class);
+ case MONO_TYPE_CLASS:
+ return variant_to_mono_object_of_class(p_var, p_type.type_class);
+ case MONO_TYPE_GENERICINST:
+ return variant_to_mono_object_of_genericinst(p_var, p_type.type_class);
+ case MONO_TYPE_OBJECT:
+ return variant_to_mono_object(p_var);
+ }
+
+ ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported type with encoding: " +
+ itos(p_type.type_encoding) + ".");
+}
+
+MonoObject *variant_to_mono_object(const Variant &p_var, const ManagedType &p_type) {
switch (p_type.type_encoding) {
case MONO_TYPE_BOOLEAN: {
- MonoBoolean val = p_var->operator bool();
+ MonoBoolean val = p_var.operator bool();
return BOX_BOOLEAN(val);
}
-
case MONO_TYPE_CHAR: {
- uint16_t val = p_var->operator unsigned short();
+ uint16_t val = p_var.operator unsigned short();
return BOX_UINT16(val);
}
-
case MONO_TYPE_I1: {
- int8_t val = p_var->operator signed char();
+ int8_t val = p_var.operator signed char();
return BOX_INT8(val);
}
case MONO_TYPE_I2: {
- int16_t val = p_var->operator signed short();
+ int16_t val = p_var.operator signed short();
return BOX_INT16(val);
}
case MONO_TYPE_I4: {
- int32_t val = p_var->operator signed int();
+ int32_t val = p_var.operator signed int();
return BOX_INT32(val);
}
case MONO_TYPE_I8: {
- int64_t val = p_var->operator int64_t();
+ int64_t val = p_var.operator int64_t();
return BOX_INT64(val);
}
-
case MONO_TYPE_U1: {
- uint8_t val = p_var->operator unsigned char();
+ uint8_t val = p_var.operator unsigned char();
return BOX_UINT8(val);
}
case MONO_TYPE_U2: {
- uint16_t val = p_var->operator unsigned short();
+ uint16_t val = p_var.operator unsigned short();
return BOX_UINT16(val);
}
case MONO_TYPE_U4: {
- uint32_t val = p_var->operator unsigned int();
+ uint32_t val = p_var.operator unsigned int();
return BOX_UINT32(val);
}
case MONO_TYPE_U8: {
- uint64_t val = p_var->operator uint64_t();
+ uint64_t val = p_var.operator uint64_t();
return BOX_UINT64(val);
}
-
case MONO_TYPE_R4: {
- float val = p_var->operator float();
+ float val = p_var.operator float();
return BOX_FLOAT(val);
}
case MONO_TYPE_R8: {
- double val = p_var->operator double();
+ double val = p_var.operator double();
return BOX_DOUBLE(val);
}
-
- case MONO_TYPE_STRING: {
- if (p_var->get_type() == Variant::NIL) {
- return nullptr; // Otherwise, Variant -> String would return the string "Null"
- }
- return (MonoObject *)mono_string_from_godot(p_var->operator String());
- } break;
-
case MONO_TYPE_VALUETYPE: {
GDMonoClass *vtclass = p_type.type_class;
- if (vtclass == CACHED_CLASS(Vector2)) {
- GDMonoMarshal::M_Vector2 from = MARSHALLED_OUT(Vector2, p_var->operator ::Vector2());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2), &from);
- }
-
- if (vtclass == CACHED_CLASS(Vector2i)) {
- GDMonoMarshal::M_Vector2i from = MARSHALLED_OUT(Vector2i, p_var->operator ::Vector2i());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2i), &from);
- }
-
- if (vtclass == CACHED_CLASS(Rect2)) {
- GDMonoMarshal::M_Rect2 from = MARSHALLED_OUT(Rect2, p_var->operator ::Rect2());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2), &from);
- }
-
- if (vtclass == CACHED_CLASS(Rect2i)) {
- GDMonoMarshal::M_Rect2i from = MARSHALLED_OUT(Rect2i, p_var->operator ::Rect2i());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2i), &from);
- }
-
- if (vtclass == CACHED_CLASS(Transform2D)) {
- GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_var->operator ::Transform2D());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform2D), &from);
- }
-
- if (vtclass == CACHED_CLASS(Vector3)) {
- GDMonoMarshal::M_Vector3 from = MARSHALLED_OUT(Vector3, p_var->operator ::Vector3());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3), &from);
- }
-
- if (vtclass == CACHED_CLASS(Vector3i)) {
- GDMonoMarshal::M_Vector3i from = MARSHALLED_OUT(Vector3i, p_var->operator ::Vector3i());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3i), &from);
- }
-
- if (vtclass == CACHED_CLASS(Basis)) {
- GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_var->operator ::Basis());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Basis), &from);
- }
-
- if (vtclass == CACHED_CLASS(Quat)) {
- GDMonoMarshal::M_Quat from = MARSHALLED_OUT(Quat, p_var->operator ::Quat());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Quat), &from);
- }
-
- if (vtclass == CACHED_CLASS(Transform)) {
- GDMonoMarshal::M_Transform from = MARSHALLED_OUT(Transform, p_var->operator ::Transform());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform), &from);
- }
-
- if (vtclass == CACHED_CLASS(AABB)) {
- GDMonoMarshal::M_AABB from = MARSHALLED_OUT(AABB, p_var->operator ::AABB());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(AABB), &from);
- }
-
- if (vtclass == CACHED_CLASS(Color)) {
- GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_var->operator ::Color());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Color), &from);
- }
+#define RETURN_CHECK_FOR_STRUCT(m_struct) \
+ if (vtclass == CACHED_CLASS(m_struct)) { \
+ GDMonoMarshal::M_##m_struct from = MARSHALLED_OUT(m_struct, p_var.operator ::m_struct()); \
+ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(m_struct), &from); \
+ }
- if (vtclass == CACHED_CLASS(Plane)) {
- GDMonoMarshal::M_Plane from = MARSHALLED_OUT(Plane, p_var->operator ::Plane());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Plane), &from);
- }
+ RETURN_CHECK_FOR_STRUCT(Vector2);
+ RETURN_CHECK_FOR_STRUCT(Vector2i);
+ RETURN_CHECK_FOR_STRUCT(Rect2);
+ RETURN_CHECK_FOR_STRUCT(Rect2i);
+ RETURN_CHECK_FOR_STRUCT(Transform2D);
+ RETURN_CHECK_FOR_STRUCT(Vector3);
+ RETURN_CHECK_FOR_STRUCT(Vector3i);
+ RETURN_CHECK_FOR_STRUCT(Basis);
+ RETURN_CHECK_FOR_STRUCT(Quat);
+ RETURN_CHECK_FOR_STRUCT(Transform);
+ RETURN_CHECK_FOR_STRUCT(AABB);
+ RETURN_CHECK_FOR_STRUCT(Color);
+ RETURN_CHECK_FOR_STRUCT(Plane);
+
+#undef RETURN_CHECK_FOR_STRUCT
if (vtclass == CACHED_CLASS(Callable)) {
- GDMonoMarshal::M_Callable from = GDMonoMarshal::callable_to_managed(p_var->operator Callable());
+ GDMonoMarshal::M_Callable from = GDMonoMarshal::callable_to_managed(p_var.operator Callable());
return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Callable), &from);
}
if (vtclass == CACHED_CLASS(SignalInfo)) {
- GDMonoMarshal::M_SignalInfo from = GDMonoMarshal::signal_info_to_managed(p_var->operator Signal());
+ GDMonoMarshal::M_SignalInfo from = GDMonoMarshal::signal_info_to_managed(p_var.operator Signal());
return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(SignalInfo), &from);
}
@@ -465,316 +903,84 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
MonoClass *enum_baseclass = mono_class_from_mono_type(enum_basetype);
switch (mono_type_get_type(enum_basetype)) {
case MONO_TYPE_BOOLEAN: {
- MonoBoolean val = p_var->operator bool();
+ MonoBoolean val = p_var.operator bool();
return BOX_ENUM(enum_baseclass, val);
}
case MONO_TYPE_CHAR: {
- uint16_t val = p_var->operator unsigned short();
+ uint16_t val = p_var.operator unsigned short();
return BOX_ENUM(enum_baseclass, val);
}
case MONO_TYPE_I1: {
- int8_t val = p_var->operator signed char();
+ int8_t val = p_var.operator signed char();
return BOX_ENUM(enum_baseclass, val);
}
case MONO_TYPE_I2: {
- int16_t val = p_var->operator signed short();
+ int16_t val = p_var.operator signed short();
return BOX_ENUM(enum_baseclass, val);
}
case MONO_TYPE_I4: {
- int32_t val = p_var->operator signed int();
+ int32_t val = p_var.operator signed int();
return BOX_ENUM(enum_baseclass, val);
}
case MONO_TYPE_I8: {
- int64_t val = p_var->operator int64_t();
+ int64_t val = p_var.operator int64_t();
return BOX_ENUM(enum_baseclass, val);
}
case MONO_TYPE_U1: {
- uint8_t val = p_var->operator unsigned char();
+ uint8_t val = p_var.operator unsigned char();
return BOX_ENUM(enum_baseclass, val);
}
case MONO_TYPE_U2: {
- uint16_t val = p_var->operator unsigned short();
+ uint16_t val = p_var.operator unsigned short();
return BOX_ENUM(enum_baseclass, val);
}
case MONO_TYPE_U4: {
- uint32_t val = p_var->operator unsigned int();
+ uint32_t val = p_var.operator unsigned int();
return BOX_ENUM(enum_baseclass, val);
}
case MONO_TYPE_U8: {
- uint64_t val = p_var->operator uint64_t();
+ uint64_t val = p_var.operator uint64_t();
return BOX_ENUM(enum_baseclass, val);
}
default: {
- ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to a managed enum value of unmarshallable base type.");
+ ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to enum value of unsupported base type: '" +
+ GDMonoClass::get_full_name(enum_baseclass) + "'.");
}
}
}
- } break;
-
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_SZARRAY: {
- MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type());
-
- if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) {
- return (MonoObject *)Array_to_mono_array(p_var->operator Array());
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) {
- return (MonoObject *)PackedByteArray_to_mono_array(p_var->operator PackedByteArray());
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) {
- return (MonoObject *)PackedInt32Array_to_mono_array(p_var->operator PackedInt32Array());
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) {
- return (MonoObject *)PackedInt64Array_to_mono_array(p_var->operator PackedInt64Array());
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(float)) {
- return (MonoObject *)PackedFloat32Array_to_mono_array(p_var->operator PackedFloat32Array());
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(double)) {
- return (MonoObject *)PackedFloat64Array_to_mono_array(p_var->operator PackedFloat64Array());
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(String)) {
- return (MonoObject *)PackedStringArray_to_mono_array(p_var->operator PackedStringArray());
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) {
- return (MonoObject *)PackedVector2Array_to_mono_array(p_var->operator PackedVector2Array());
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) {
- return (MonoObject *)PackedVector3Array_to_mono_array(p_var->operator PackedVector3Array());
- }
-
- if (array_type->eklass == CACHED_CLASS_RAW(Color)) {
- return (MonoObject *)PackedColorArray_to_mono_array(p_var->operator PackedColorArray());
- }
-
- GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
- if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) {
- return (MonoObject *)Array_to_mono_array(p_var->operator Array(), array_type_class);
- }
-
- ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to a managed array of unmarshallable element type.");
- } break;
-
- case MONO_TYPE_CLASS: {
- GDMonoClass *type_class = p_type.type_class;
-
- // GodotObject
- if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) {
- return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *());
- }
-
- if (CACHED_CLASS(StringName) == type_class) {
- return GDMonoUtils::create_managed_from(p_var->operator StringName());
- }
-
- if (CACHED_CLASS(NodePath) == type_class) {
- return GDMonoUtils::create_managed_from(p_var->operator NodePath());
- }
-
- if (CACHED_CLASS(RID) == type_class) {
- return GDMonoUtils::create_managed_from(p_var->operator RID());
- }
-
- // Godot.Collections.Dictionary or IDictionary
- if (CACHED_CLASS(Dictionary) == type_class || CACHED_CLASS(System_Collections_IDictionary) == type_class) {
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary));
- }
- // Godot.Collections.Array or ICollection or IEnumerable
- if (CACHED_CLASS(Array) == type_class ||
- CACHED_CLASS(System_Collections_ICollection) == type_class ||
- CACHED_CLASS(System_Collections_IEnumerable) == type_class) {
- return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array));
- }
- } break;
- case MONO_TYPE_OBJECT: {
- // Variant
- switch (p_var->get_type()) {
- case Variant::BOOL: {
- MonoBoolean val = p_var->operator bool();
- return BOX_BOOLEAN(val);
- }
- case Variant::INT: {
- int64_t val = p_var->operator int64_t();
- return BOX_INT64(val);
- }
- case Variant::FLOAT: {
-#ifdef REAL_T_IS_DOUBLE
- double val = p_var->operator double();
- return BOX_DOUBLE(val);
-#else
- float val = p_var->operator float();
- return BOX_FLOAT(val);
-#endif
- }
- case Variant::STRING:
- return (MonoObject *)mono_string_from_godot(p_var->operator String());
- case Variant::VECTOR2: {
- GDMonoMarshal::M_Vector2 from = MARSHALLED_OUT(Vector2, p_var->operator ::Vector2());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2), &from);
- }
- case Variant::VECTOR2I: {
- GDMonoMarshal::M_Vector2i from = MARSHALLED_OUT(Vector2i, p_var->operator ::Vector2i());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2i), &from);
- }
- case Variant::RECT2: {
- GDMonoMarshal::M_Rect2 from = MARSHALLED_OUT(Rect2, p_var->operator ::Rect2());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2), &from);
- }
- case Variant::RECT2I: {
- GDMonoMarshal::M_Rect2i from = MARSHALLED_OUT(Rect2i, p_var->operator ::Rect2i());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2i), &from);
- }
- case Variant::VECTOR3: {
- GDMonoMarshal::M_Vector3 from = MARSHALLED_OUT(Vector3, p_var->operator ::Vector3());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3), &from);
- }
- case Variant::VECTOR3I: {
- GDMonoMarshal::M_Vector3i from = MARSHALLED_OUT(Vector3i, p_var->operator ::Vector3i());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3i), &from);
- }
- case Variant::TRANSFORM2D: {
- GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_var->operator ::Transform2D());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform2D), &from);
- }
- case Variant::PLANE: {
- GDMonoMarshal::M_Plane from = MARSHALLED_OUT(Plane, p_var->operator ::Plane());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Plane), &from);
- }
- case Variant::QUAT: {
- GDMonoMarshal::M_Quat from = MARSHALLED_OUT(Quat, p_var->operator ::Quat());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Quat), &from);
- }
- case Variant::AABB: {
- GDMonoMarshal::M_AABB from = MARSHALLED_OUT(AABB, p_var->operator ::AABB());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(AABB), &from);
- }
- case Variant::BASIS: {
- GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_var->operator ::Basis());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Basis), &from);
- }
- case Variant::TRANSFORM: {
- GDMonoMarshal::M_Transform from = MARSHALLED_OUT(Transform, p_var->operator ::Transform());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform), &from);
- }
- case Variant::COLOR: {
- GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_var->operator ::Color());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Color), &from);
- }
- case Variant::STRING_NAME:
- return GDMonoUtils::create_managed_from(p_var->operator StringName());
- case Variant::NODE_PATH:
- return GDMonoUtils::create_managed_from(p_var->operator NodePath());
- case Variant::_RID:
- return GDMonoUtils::create_managed_from(p_var->operator RID());
- case Variant::OBJECT:
- return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *());
- case Variant::CALLABLE: {
- GDMonoMarshal::M_Callable from = GDMonoMarshal::callable_to_managed(p_var->operator Callable());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Callable), &from);
- }
- case Variant::SIGNAL: {
- GDMonoMarshal::M_SignalInfo from = GDMonoMarshal::signal_info_to_managed(p_var->operator Signal());
- return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(SignalInfo), &from);
- }
- case Variant::DICTIONARY:
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary));
- case Variant::ARRAY:
- return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array));
- case Variant::PACKED_BYTE_ARRAY:
- return (MonoObject *)PackedByteArray_to_mono_array(p_var->operator PackedByteArray());
- case Variant::PACKED_INT32_ARRAY:
- return (MonoObject *)PackedInt32Array_to_mono_array(p_var->operator PackedInt32Array());
- case Variant::PACKED_INT64_ARRAY:
- return (MonoObject *)PackedInt64Array_to_mono_array(p_var->operator PackedInt64Array());
- case Variant::PACKED_FLOAT32_ARRAY:
- return (MonoObject *)PackedFloat32Array_to_mono_array(p_var->operator PackedFloat32Array());
- case Variant::PACKED_FLOAT64_ARRAY:
- return (MonoObject *)PackedFloat64Array_to_mono_array(p_var->operator PackedFloat64Array());
- case Variant::PACKED_STRING_ARRAY:
- return (MonoObject *)PackedStringArray_to_mono_array(p_var->operator PackedStringArray());
- case Variant::PACKED_VECTOR2_ARRAY:
- return (MonoObject *)PackedVector2Array_to_mono_array(p_var->operator PackedVector2Array());
- case Variant::PACKED_VECTOR3_ARRAY:
- return (MonoObject *)PackedVector3Array_to_mono_array(p_var->operator PackedVector3Array());
- case Variant::PACKED_COLOR_ARRAY:
- return (MonoObject *)PackedColorArray_to_mono_array(p_var->operator PackedColorArray());
- default:
- return nullptr;
- }
- break;
- case MONO_TYPE_GENERICINST: {
- MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type());
-
- // Godot.Collections.Dictionary<TKey, TValue>
- if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), p_type.type_class);
- }
-
- // Godot.Collections.Array<T>
- if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
- return GDMonoUtils::create_managed_from(p_var->operator Array(), p_type.type_class);
- }
-
- // System.Collections.Generic.Dictionary<TKey, TValue>
- if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
- MonoReflectionType *key_reftype = nullptr;
- MonoReflectionType *value_reftype = nullptr;
- GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
- return Dictionary_to_system_generic_dict(p_var->operator Dictionary(), p_type.type_class, key_reftype, value_reftype);
- }
-
- // System.Collections.Generic.List<T>
- if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
- MonoReflectionType *elem_reftype = nullptr;
- GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
- return Array_to_system_generic_list(p_var->operator Array(), p_type.type_class, elem_reftype);
- }
-
- // IDictionary<TKey, TValue>
- if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) {
- MonoReflectionType *key_reftype;
- MonoReflectionType *value_reftype;
- GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
- GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype);
-
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), godot_dict_class);
- }
-
- // ICollection<T> or IEnumerable<T>
- if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) {
- MonoReflectionType *elem_reftype;
- GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
- GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(elem_reftype);
-
- return GDMonoUtils::create_managed_from(p_var->operator Array(), godot_array_class);
- }
- } break;
+ ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported value type: '" +
+ p_type.type_class->get_full_name() + "'.");
} break;
+ case MONO_TYPE_STRING:
+ return (MonoObject *)variant_to_mono_string(p_var);
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_SZARRAY:
+ return (MonoObject *)variant_to_mono_array(p_var, p_type.type_class);
+ case MONO_TYPE_CLASS:
+ return variant_to_mono_object_of_class(p_var, p_type.type_class);
+ case MONO_TYPE_GENERICINST:
+ return variant_to_mono_object_of_genericinst(p_var, p_type.type_class);
+ case MONO_TYPE_OBJECT:
+ return variant_to_mono_object(p_var);
}
- ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to an unmarshallable managed type. Name: '" +
- p_type.type_class->get_name() + "' Encoding: " + itos(p_type.type_encoding) + ".");
+ ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported type with encoding: " +
+ itos(p_type.type_encoding) + ".");
}
Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type, bool p_fail_with_err = true) {
ERR_FAIL_COND_V(!p_type.type_class, Variant());
+#ifdef DEBUG_ENABLED
+ CRASH_COND_MSG(p_type.type_encoding == MONO_TYPE_OBJECT, "Type of object should be known.");
+#endif
+
switch (p_type.type_encoding) {
case MONO_TYPE_BOOLEAN:
return (bool)unbox<MonoBoolean>(p_obj);
-
case MONO_TYPE_CHAR:
return unbox<uint16_t>(p_obj);
-
case MONO_TYPE_I1:
return unbox<int8_t>(p_obj);
case MONO_TYPE_I2:
@@ -783,7 +989,6 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return unbox<int32_t>(p_obj);
case MONO_TYPE_I8:
return unbox<int64_t>(p_obj);
-
case MONO_TYPE_U1:
return unbox<uint8_t>(p_obj);
case MONO_TYPE_U2:
@@ -792,19 +997,10 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return unbox<uint32_t>(p_obj);
case MONO_TYPE_U8:
return unbox<uint64_t>(p_obj);
-
case MONO_TYPE_R4:
return unbox<float>(p_obj);
case MONO_TYPE_R8:
return unbox<double>(p_obj);
-
- case MONO_TYPE_STRING: {
- if (p_obj == nullptr) {
- return Variant(); // NIL
- }
- return mono_string_to_godot_not_null((MonoString *)p_obj);
- } break;
-
case MONO_TYPE_VALUETYPE: {
GDMonoClass *vtclass = p_type.type_class;
@@ -872,7 +1068,12 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return unbox<int32_t>(p_obj);
}
} break;
-
+ case MONO_TYPE_STRING: {
+ if (p_obj == nullptr) {
+ return Variant(); // NIL
+ }
+ return mono_string_to_godot_not_null((MonoString *)p_obj);
+ } break;
case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY: {
MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type());
@@ -928,7 +1129,6 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return Variant();
}
} break;
-
case MONO_TYPE_CLASS: {
GDMonoClass *type_class = p_type.type_class;
@@ -973,7 +1173,6 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return ptr ? Variant(*ptr) : Variant();
}
} break;
-
case MONO_TYPE_GENERICINST: {
MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type());
@@ -1005,7 +1204,7 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
MonoReflectionType *elem_reftype = nullptr;
GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
- return system_generic_list_to_Array(p_obj, p_type.type_class, elem_reftype);
+ return system_generic_list_to_Array_variant(p_obj, p_type.type_class, elem_reftype);
}
} break;
}
@@ -1052,7 +1251,7 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) {
ManagedType type = ManagedType::from_class(mono_object_get_class(p_obj));
Variant var = GDMonoMarshal::mono_object_to_variant_no_err(p_obj, type);
- if (var.get_type() == Variant::NIL && p_obj != nullptr) {
+ 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);
@@ -1115,9 +1314,10 @@ Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, [[maybe_unused]]
}
MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype) {
- GDMonoClass *elem_class = ManagedType::from_reftype(p_elem_reftype).type_class;
+ MonoType *elem_type = mono_reflection_type_get_type(p_elem_reftype);
+ MonoClass *elem_class = mono_class_from_mono_type(elem_type);
- String ctor_desc = ":.ctor(System.Collections.Generic.IEnumerable`1<" + elem_class->get_type_desc() + ">)";
+ String ctor_desc = ":.ctor(System.Collections.Generic.IEnumerable`1<" + GDMonoUtils::get_type_desc(elem_type) + ">)";
GDMonoMethod *ctor = p_class->get_method_with_desc(ctor_desc, true);
CRASH_COND(ctor == nullptr);
@@ -1133,15 +1333,22 @@ MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_cl
return mono_object;
}
-Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, [[maybe_unused]] MonoReflectionType *p_elem_reftype) {
+Variant system_generic_list_to_Array_variant(MonoObject *p_obj, GDMonoClass *p_class, [[maybe_unused]] MonoReflectionType *p_elem_reftype) {
GDMonoMethod *to_array = p_class->get_method("ToArray", 0);
CRASH_COND(to_array == nullptr);
MonoException *exc = nullptr;
- MonoArray *mono_array = (MonoArray *)to_array->invoke_raw(p_obj, nullptr, &exc);
+ MonoObject *array = to_array->invoke_raw(p_obj, nullptr, &exc);
UNHANDLED_EXCEPTION(exc);
- return mono_array_to_Array(mono_array);
+ ERR_FAIL_NULL_V(array, Variant());
+
+ ManagedType type = ManagedType::from_class(mono_object_get_class(array));
+
+ bool result_is_array = type.type_encoding != MONO_TYPE_SZARRAY && type.type_encoding != MONO_TYPE_ARRAY;
+ ERR_FAIL_COND_V(result_is_array, Variant());
+
+ return mono_object_to_variant(array, type);
}
MonoArray *Array_to_mono_array(const Array &p_array) {
@@ -1156,9 +1363,9 @@ MonoArray *Array_to_mono_array(const Array &p_array) {
return ret;
}
-MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class) {
+MonoArray *Array_to_mono_array(const Array &p_array, MonoClass *p_array_type_class) {
int length = p_array.size();
- MonoArray *ret = mono_array_new(mono_domain_get(), p_array_type_class->get_mono_ptr(), length);
+ MonoArray *ret = mono_array_new(mono_domain_get(), p_array_type_class, length);
for (int i = 0; i < length; i++) {
MonoObject *boxed = variant_to_mono_object(p_array[i]);
@@ -1477,8 +1684,8 @@ Callable managed_to_callable(const M_Callable &p_managed_callable) {
return Callable(managed_callable);
} else {
Object *target = p_managed_callable.target ?
- unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_callable.target)) :
- nullptr;
+ unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_callable.target)) :
+ nullptr;
StringName *method_ptr = unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_callable.method_string_name));
StringName method = method_ptr ? *method_ptr : StringName();
return Callable(target, method);
@@ -1523,8 +1730,8 @@ M_Callable callable_to_managed(const Callable &p_callable) {
Signal managed_to_signal_info(const M_SignalInfo &p_managed_signal) {
Object *owner = p_managed_signal.owner ?
- unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_signal.owner)) :
- nullptr;
+ unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_signal.owner)) :
+ nullptr;
StringName *name_ptr = unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_signal.name_string_name));
StringName name = name_ptr ? *name_ptr : StringName();
return Signal(owner, name);
@@ -1536,5 +1743,4 @@ M_SignalInfo signal_info_to_managed(const Signal &p_signal) {
MonoObject *name_string_name_managed = GDMonoUtils::create_managed_from(p_signal.get_name());
return { owner_managed, name_string_name_managed };
}
-
} // namespace GDMonoMarshal
diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h
index d2c564d67d..668809ae5d 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.h
+++ b/modules/mono/mono_gd/gd_mono_marshal.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -90,15 +90,40 @@ _FORCE_INLINE_ MonoString *mono_string_from_godot(const String &p_string) {
// Variant
-MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_type);
-MonoObject *variant_to_mono_object(const Variant *p_var);
+size_t variant_get_managed_unboxed_size(const ManagedType &p_type);
+void *variant_to_managed_unboxed(const Variant &p_var, const ManagedType &p_type, void *r_buffer, unsigned int &r_offset);
+MonoObject *variant_to_mono_object(const Variant &p_var, const ManagedType &p_type);
-_FORCE_INLINE_ MonoObject *variant_to_mono_object(const Variant &p_var) {
- return variant_to_mono_object(&p_var);
-}
+MonoObject *variant_to_mono_object(const Variant &p_var);
+MonoArray *variant_to_mono_array(const Variant &p_var, GDMonoClass *p_type_class);
+MonoObject *variant_to_mono_object_of_class(const Variant &p_var, GDMonoClass *p_type_class);
+MonoObject *variant_to_mono_object_of_genericinst(const Variant &p_var, GDMonoClass *p_type_class);
+MonoString *variant_to_mono_string(const Variant &p_var);
+
+// These overloads were added to avoid passing a `const Variant *` to the `const Variant &`
+// parameter. That would result in the `Variant(bool)` copy constructor being called as
+// pointers are implicitly converted to bool. Implicit conversions are f-ing evil.
-_FORCE_INLINE_ MonoObject *variant_to_mono_object(const Variant &p_var, const ManagedType &p_type) {
- return variant_to_mono_object(&p_var, p_type);
+_FORCE_INLINE_ void *variant_to_managed_unboxed(const Variant *p_var, const ManagedType &p_type, void *r_buffer, unsigned int &r_offset) {
+ return variant_to_managed_unboxed(*p_var, p_type, r_buffer, r_offset);
+}
+_FORCE_INLINE_ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_type) {
+ return variant_to_mono_object(*p_var, p_type);
+}
+_FORCE_INLINE_ MonoObject *variant_to_mono_object(const Variant *p_var) {
+ return variant_to_mono_object(*p_var);
+}
+_FORCE_INLINE_ MonoArray *variant_to_mono_array(const Variant *p_var, GDMonoClass *p_type_class) {
+ return variant_to_mono_array(*p_var, p_type_class);
+}
+_FORCE_INLINE_ MonoObject *variant_to_mono_object_of_class(const Variant *p_var, GDMonoClass *p_type_class) {
+ return variant_to_mono_object_of_class(*p_var, p_type_class);
+}
+_FORCE_INLINE_ MonoObject *variant_to_mono_object_of_genericinst(const Variant *p_var, GDMonoClass *p_type_class) {
+ return variant_to_mono_object_of_genericinst(*p_var, p_type_class);
+}
+_FORCE_INLINE_ MonoString *variant_to_mono_string(const Variant *p_var) {
+ return variant_to_mono_string(*p_var);
}
Variant mono_object_to_variant(MonoObject *p_obj);
@@ -115,12 +140,12 @@ MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoCl
Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype);
MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype);
-Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype);
+Variant system_generic_list_to_Array_variant(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype);
// Array
MonoArray *Array_to_mono_array(const Array &p_array);
-MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class);
+MonoArray *Array_to_mono_array(const Array &p_array, MonoClass *p_array_type_class);
Array mono_array_to_Array(MonoArray *p_array);
// PackedInt32Array
@@ -271,7 +296,6 @@ static_assert(MATCHES_Vector2 && MATCHES_Rect2 && MATCHES_Transform2D && MATCHES
MATCHES_Plane && MATCHES_Vector2i && MATCHES_Rect2i && MATCHES_Vector3i);
/* clang-format on */
#endif
-
} // namespace InteropLayout
#pragma pack(push, 1)
@@ -517,7 +541,6 @@ DECL_TYPE_MARSHAL_TEMPLATES(Plane)
#define MARSHALLED_IN(m_type, m_from_ptr) (GDMonoMarshal::marshalled_in_##m_type(m_from_ptr))
#define MARSHALLED_OUT(m_type, m_from) (GDMonoMarshal::marshalled_out_##m_type(m_from))
-
} // namespace GDMonoMarshal
#endif // GDMONOMARSHAL_H
diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp
index 04f3b25a70..67aabcde10 100644
--- a/modules/mono/mono_gd/gd_mono_method.cpp
+++ b/modules/mono/mono_gd/gd_mono_method.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -75,6 +75,10 @@ void GDMonoMethod::_update_signature(MonoMethodSignature *p_method_sig) {
// clear the cache
method_info_fetched = false;
method_info = MethodInfo();
+
+ for (int i = 0; i < params_count; i++) {
+ params_buffer_size += GDMonoMarshal::variant_get_managed_unboxed_size(param_types[i]);
+ }
}
GDMonoClass *GDMonoMethod::get_enclosing_class() const {
@@ -107,14 +111,15 @@ MonoObject *GDMonoMethod::invoke(MonoObject *p_object, const Variant **p_params,
MonoObject *ret;
if (params_count > 0) {
- MonoArray *params = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), params_count);
+ void **params = (void **)alloca(params_count * sizeof(void *));
+ uint8_t *buffer = (uint8_t *)alloca(params_buffer_size);
+ unsigned int offset = 0;
for (int i = 0; i < params_count; i++) {
- MonoObject *boxed_param = GDMonoMarshal::variant_to_mono_object(p_params[i], param_types[i]);
- mono_array_setref(params, i, boxed_param);
+ params[i] = GDMonoMarshal::variant_to_managed_unboxed(p_params[i], param_types[i], buffer + offset, offset);
}
- ret = GDMonoUtils::runtime_invoke_array(mono_method, p_object, params, &exc);
+ ret = GDMonoUtils::runtime_invoke(mono_method, p_object, params, &exc);
} else {
ret = GDMonoUtils::runtime_invoke(mono_method, p_object, nullptr, &exc);
}
@@ -279,16 +284,8 @@ const MethodInfo &GDMonoMethod::get_method_info() {
return method_info;
}
-GDMonoMethod::GDMonoMethod(StringName p_name, MonoMethod *p_method) {
- name = p_name;
-
- mono_method = p_method;
-
- method_info_fetched = false;
-
- attrs_fetched = false;
- attributes = nullptr;
-
+GDMonoMethod::GDMonoMethod(StringName p_name, MonoMethod *p_method) :
+ name(p_name), mono_method(p_method) {
_update_signature();
}
diff --git a/modules/mono/mono_gd/gd_mono_method.h b/modules/mono/mono_gd/gd_mono_method.h
index f78f57dca0..c08ffe904b 100644
--- a/modules/mono/mono_gd/gd_mono_method.h
+++ b/modules/mono/mono_gd/gd_mono_method.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -38,15 +38,16 @@
class GDMonoMethod : public IMonoClassMember {
StringName name;
- int params_count;
+ uint16_t params_count;
+ unsigned int params_buffer_size = 0;
ManagedType return_type;
Vector<ManagedType> param_types;
- bool method_info_fetched;
+ bool method_info_fetched = false;
MethodInfo method_info;
- bool attrs_fetched;
- MonoCustomAttrInfo *attributes;
+ bool attrs_fetched = false;
+ MonoCustomAttrInfo *attributes = nullptr;
void _update_signature();
void _update_signature(MonoMethodSignature *p_method_sig);
@@ -72,7 +73,7 @@ public:
_FORCE_INLINE_ MonoMethod *get_mono_ptr() const { return mono_method; }
- _FORCE_INLINE_ int get_parameters_count() const { return params_count; }
+ _FORCE_INLINE_ uint16_t get_parameters_count() const { return params_count; }
_FORCE_INLINE_ ManagedType get_return_type() const { return return_type; }
MonoObject *invoke(MonoObject *p_object, const Variant **p_params, MonoException **r_exc = nullptr) const;
diff --git a/modules/mono/mono_gd/gd_mono_method_thunk.h b/modules/mono/mono_gd/gd_mono_method_thunk.h
index 01f3ae342a..091d26df1d 100644
--- a/modules/mono/mono_gd/gd_mono_method_thunk.h
+++ b/modules/mono/mono_gd/gd_mono_method_thunk.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/mono_gd/gd_mono_property.cpp b/modules/mono/mono_gd/gd_mono_property.cpp
index bc3be97102..5391b7775e 100644
--- a/modules/mono/mono_gd/gd_mono_property.cpp
+++ b/modules/mono/mono_gd/gd_mono_property.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -40,7 +40,7 @@
GDMonoProperty::GDMonoProperty(MonoProperty *p_mono_property, GDMonoClass *p_owner) {
owner = p_owner;
mono_property = p_mono_property;
- name = mono_property_get_name(mono_property);
+ name = String::utf8(mono_property_get_name(mono_property));
MonoMethod *prop_method = mono_property_get_get_method(mono_property);
@@ -149,10 +149,9 @@ bool GDMonoProperty::has_setter() {
void GDMonoProperty::set_value(MonoObject *p_object, MonoObject *p_value, MonoException **r_exc) {
MonoMethod *prop_method = mono_property_get_set_method(mono_property);
- MonoArray *params = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), 1);
- mono_array_setref(params, 0, p_value);
+ void *params[1] = { p_value };
MonoException *exc = nullptr;
- GDMonoUtils::runtime_invoke_array(prop_method, p_object, params, &exc);
+ GDMonoUtils::runtime_invoke(prop_method, p_object, params, &exc);
if (exc) {
if (r_exc) {
*r_exc = exc;
diff --git a/modules/mono/mono_gd/gd_mono_property.h b/modules/mono/mono_gd/gd_mono_property.h
index 611ac293e4..af7a2c02e5 100644
--- a/modules/mono/mono_gd/gd_mono_property.h
+++ b/modules/mono/mono_gd/gd_mono_property.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 2676165cbc..6e0a263c7f 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -480,6 +480,7 @@ void set_pending_exception(MonoException *p_exc) {
#else
if (get_runtime_invoke_count() == 0) {
debug_unhandled_exception(p_exc);
+ return;
}
if (!mono_runtime_set_pending_exception(p_exc, false)) {
@@ -498,13 +499,6 @@ MonoObject *runtime_invoke(MonoMethod *p_method, void *p_obj, void **p_params, M
return ret;
}
-MonoObject *runtime_invoke_array(MonoMethod *p_method, void *p_obj, MonoArray *p_params, MonoException **r_exc) {
- GD_MONO_BEGIN_RUNTIME_INVOKE;
- MonoObject *ret = mono_runtime_invoke_array(p_method, p_obj, p_params, (MonoObject **)r_exc);
- GD_MONO_END_RUNTIME_INVOKE;
- return ret;
-}
-
MonoString *object_to_string(MonoObject *p_obj, MonoException **r_exc) {
GD_MONO_BEGIN_RUNTIME_INVOKE;
MonoString *ret = mono_object_to_string(p_obj, (MonoObject **)r_exc);
@@ -659,7 +653,6 @@ GDMonoClass *make_generic_dictionary_type(MonoReflectionType *p_key_reftype, Mon
UNHANDLED_EXCEPTION(exc);
return GDMono::get_singleton()->get_class(mono_class_from_mono_type(mono_reflection_type_get_type(reftype)));
}
-
} // namespace Marshal
ScopeThreadAttach::ScopeThreadAttach() {
@@ -679,5 +672,4 @@ StringName get_native_godot_class_name(GDMonoClass *p_class) {
StringName *ptr = GDMonoMarshal::unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(native_name_obj));
return ptr ? *ptr : StringName();
}
-
} // namespace GDMonoUtils
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index 7088385c4f..9e024418e1 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -36,6 +36,9 @@
#include "../mono_gc_handle.h"
#include "../utils/macros.h"
#include "gd_mono_header.h"
+#ifdef JAVASCRIPT_ENABLED
+#include "gd_mono_wasm_m2n.h"
+#endif
#include "core/object/class_db.h"
#include "core/object/reference.h"
@@ -64,7 +67,6 @@ void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoRefl
GDMonoClass *make_generic_array_type(MonoReflectionType *p_elem_reftype);
GDMonoClass *make_generic_dictionary_type(MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype);
-
} // namespace Marshal
_FORCE_INLINE_ void hash_combine(uint32_t &p_hash, const uint32_t &p_with_hash) {
@@ -136,7 +138,6 @@ _FORCE_INLINE_ int &get_runtime_invoke_count_ref() {
}
MonoObject *runtime_invoke(MonoMethod *p_method, void *p_obj, void **p_params, MonoException **r_exc);
-MonoObject *runtime_invoke_array(MonoMethod *p_method, void *p_obj, MonoArray *p_params, MonoException **r_exc);
MonoString *object_to_string(MonoObject *p_obj, MonoException **r_exc);
@@ -157,6 +158,21 @@ private:
StringName get_native_godot_class_name(GDMonoClass *p_class);
+template <typename... P>
+void add_internal_call(const char *p_name, void (*p_func)(P...)) {
+#ifdef JAVASCRIPT_ENABLED
+ GDMonoWasmM2n::ICallTrampolines<P...>::add();
+#endif
+ mono_add_internal_call(p_name, (void *)p_func);
+}
+
+template <typename R, typename... P>
+void add_internal_call(const char *p_name, R (*p_func)(P...)) {
+#ifdef JAVASCRIPT_ENABLED
+ GDMonoWasmM2n::ICallTrampolinesR<R, P...>::add();
+#endif
+ mono_add_internal_call(p_name, (void *)p_func);
+}
} // namespace GDMonoUtils
#define NATIVE_GDMONOCLASS_NAME(m_class) (GDMonoUtils::get_native_godot_class_name(m_class))
diff --git a/modules/mono/editor/script_class_parser.h b/modules/mono/mono_gd/gd_mono_wasm_m2n.cpp
index 3c55fa07a7..a477c55456 100644
--- a/modules/mono/editor/script_class_parser.h
+++ b/modules/mono/mono_gd/gd_mono_wasm_m2n.cpp
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* script_class_parser.h */
+/* gd_mono_wasm_m2n.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -28,81 +28,52 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SCRIPT_CLASS_PARSER_H
-#define SCRIPT_CLASS_PARSER_H
+#include "gd_mono_wasm_m2n.h"
-#include "core/string/ustring.h"
-#include "core/templates/vector.h"
-#include "core/variant/variant.h"
+#ifdef JAVASCRIPT_ENABLED
-class ScriptClassParser {
-public:
- struct NameDecl {
- enum Type {
- NAMESPACE_DECL,
- CLASS_DECL,
- STRUCT_DECL
- };
+#include "core/templates/oa_hash_map.h"
- String name;
- Type type;
- };
+typedef mono_bool (*GodotMonoM2nIcallTrampolineDispatch)(const char *cookie, void *target_func, Mono_InterpMethodArguments *margs);
- struct ClassDecl {
- String name;
- String namespace_;
- Vector<String> base;
- bool nested;
- };
+// This extern function is implemented in our patched version of Mono
+MONO_API void godot_mono_register_m2n_icall_trampoline_dispatch_hook(GodotMonoM2nIcallTrampolineDispatch hook);
-private:
- String code;
- int idx;
- int line;
- String error_str;
- bool error;
- Variant value;
+namespace GDMonoWasmM2n {
- Vector<ClassDecl> classes;
-
- enum Token {
- TK_BRACKET_OPEN,
- TK_BRACKET_CLOSE,
- TK_CURLY_BRACKET_OPEN,
- TK_CURLY_BRACKET_CLOSE,
- TK_PERIOD,
- TK_COLON,
- TK_COMMA,
- TK_SYMBOL,
- TK_IDENTIFIER,
- TK_STRING,
- TK_NUMBER,
- TK_OP_LESS,
- TK_OP_GREATER,
- TK_EOF,
- TK_ERROR,
- TK_MAX
- };
+struct HashMapCookieComparator {
+ static bool compare(const char *p_lhs, const char *p_rhs) {
+ return strcmp(p_lhs, p_rhs) == 0;
+ }
+};
- static const char *token_names[TK_MAX];
- static String get_token_name(Token p_token);
+// The default hasher supports 'const char *' C Strings, but we need a custom comparator
+OAHashMap<const char *, TrampolineFunc, HashMapHasherDefault, HashMapCookieComparator> trampolines;
- Token get_token();
+void set_trampoline(const char *cookies, GDMonoWasmM2n::TrampolineFunc trampoline_func) {
+ trampolines.set(cookies, trampoline_func);
+}
- Error _skip_generic_type_params();
+mono_bool trampoline_dispatch_hook(const char *cookie, void *target_func, Mono_InterpMethodArguments *margs) {
+ TrampolineFunc *trampoline_func = trampolines.lookup_ptr(cookie);
- Error _parse_type_full_name(String &r_full_name);
- Error _parse_class_base(Vector<String> &r_base);
- Error _parse_type_constraints();
- Error _parse_namespace_name(String &r_name, int &r_curly_stack);
+ if (!trampoline_func) {
+ return false;
+ }
-public:
- Error parse(const String &p_code);
- Error parse_file(const String &p_filepath);
+ (*trampoline_func)(target_func, margs);
+ return true;
+}
- String get_error();
+bool initialized = false;
- Vector<ClassDecl> get_classes();
-};
+void lazy_initialize() {
+ // Doesn't need to be thread safe
+ if (!initialized) {
+ initialized = true;
+ godot_mono_register_m2n_icall_trampoline_dispatch_hook(&trampoline_dispatch_hook);
+ }
+}
+} // namespace GDMonoWasmM2n
-#endif // SCRIPT_CLASS_PARSER_H
+#endif
diff --git a/modules/mono/mono_gd/gd_mono_wasm_m2n.h b/modules/mono/mono_gd/gd_mono_wasm_m2n.h
new file mode 100644
index 0000000000..159a2ed7b6
--- /dev/null
+++ b/modules/mono/mono_gd/gd_mono_wasm_m2n.h
@@ -0,0 +1,263 @@
+/*************************************************************************/
+/* gd_mono_wasm_m2n.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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. */
+/*************************************************************************/
+
+#ifndef GD_MONO_WASM_M2N_H
+#define GD_MONO_WASM_M2N_H
+
+#ifdef JAVASCRIPT_ENABLED
+
+#include "core/string/ustring.h"
+#include "core/typedefs.h"
+
+#include <mono/metadata/loader.h>
+#include <mono/utils/mono-publib.h>
+#include <stdexcept>
+#include <type_traits>
+
+extern "C" {
+
+struct Mono_InterpMethodArguments {
+ size_t ilen;
+ void **iargs;
+ size_t flen;
+ double *fargs;
+ void **retval;
+ size_t is_float_ret;
+ //#ifdef TARGET_WASM
+ void *sig;
+ //#endif
+};
+} // extern "C"
+
+namespace GDMonoWasmM2n {
+
+template <typename T, size_t Size>
+struct array {
+ T elems[Size];
+};
+
+template <typename T>
+constexpr char get_m2n_cookie_impl() {
+#define M2N_REG_COOKIE(m_type, m_cookie) \
+ if constexpr (std::is_same_v<m_type, T>) { \
+ return m_cookie; \
+ }
+
+ M2N_REG_COOKIE(MonoBoolean, 'I');
+ M2N_REG_COOKIE(int8_t, 'I');
+ M2N_REG_COOKIE(uint8_t, 'I');
+ M2N_REG_COOKIE(int16_t, 'I');
+ M2N_REG_COOKIE(uint16_t, 'I');
+ M2N_REG_COOKIE(int32_t, 'I');
+ M2N_REG_COOKIE(uint32_t, 'I');
+ M2N_REG_COOKIE(int64_t, 'L');
+ M2N_REG_COOKIE(uint64_t, 'L');
+ M2N_REG_COOKIE(float, 'F');
+ M2N_REG_COOKIE(double, 'D');
+
+ if constexpr (std::is_pointer_v<T>) {
+ if constexpr (sizeof(void *) == 4) {
+ return 'I';
+ } else {
+ return 'L';
+ }
+ }
+
+ if constexpr (std::is_void_v<T>) {
+ return 'V';
+ }
+
+ return 'X';
+
+#undef M2N_REG_COOKIE
+}
+
+template <typename T>
+constexpr char get_m2n_cookie() {
+ constexpr char cookie = get_m2n_cookie_impl<T>();
+ static_assert(cookie != 'X', "Type not supported in internal call signature.");
+ return cookie;
+}
+
+template <typename... T>
+constexpr array<const char, sizeof...(T) + 2> get_m2n_cookies() {
+ return array<const char, sizeof...(T) + 2>{ 'V', get_m2n_cookie<T>()..., '\0' };
+}
+
+template <typename R, typename... T>
+constexpr array<const char, sizeof...(T) + 2> get_m2n_cookies_r() {
+ return array<const char, sizeof...(T) + 2>{ get_m2n_cookie<R>(), get_m2n_cookie<T>()..., '\0' };
+}
+
+template <typename T>
+constexpr size_t calc_m2n_index(size_t &r_int_idx, size_t &r_float_idx) {
+ constexpr char cookie = get_m2n_cookie<T>();
+
+ static_assert(cookie == 'I' || cookie == 'L' || cookie == 'F' || cookie == 'D');
+
+ if constexpr (cookie == 'I' || cookie == 'L') {
+ size_t ret = r_int_idx;
+ r_int_idx += cookie == 'I' ? 1 : 2;
+ return ret;
+ } else {
+ size_t ret = r_float_idx;
+ r_float_idx += cookie == 'F' ? 1 : 2;
+ return ret;
+ }
+}
+
+template <typename... P>
+constexpr array<size_t, sizeof...(P)> get_indices_for_type() {
+ size_t int_idx = 0;
+ size_t float_idx = 0;
+ return array<size_t, sizeof...(P)>{ calc_m2n_index<P>(int_idx, float_idx)... };
+}
+
+constexpr size_t fidx(size_t p_x) {
+ if constexpr (sizeof(void *) == 4) {
+ return p_x * 2;
+ } else {
+ return p_x;
+ }
+}
+
+template <typename T>
+T m2n_arg_cast(Mono_InterpMethodArguments *p_margs, size_t p_idx) {
+ constexpr char cookie = get_m2n_cookie<T>();
+
+ static_assert(cookie == 'I' || cookie == 'L' || cookie == 'F' || cookie == 'D');
+
+ if constexpr (cookie == 'I') {
+ return (T)(size_t)p_margs->iargs[p_idx];
+ } else if constexpr (cookie == 'L') {
+ static_assert(std::is_same_v<T, int64_t> || std::is_same_v<T, uint64_t> ||
+ (sizeof(void *) == 8 && std::is_pointer_v<T>),
+ "Invalid type for cookie 'L'.");
+
+ union {
+ T l;
+ struct {
+ int32_t lo;
+ int32_t hi;
+ } pair;
+ } p;
+
+ p.pair.lo = (int32_t)(size_t)p_margs->iargs[p_idx];
+ p.pair.hi = (int32_t)(size_t)p_margs->iargs[p_idx + 1];
+
+ return p.l;
+ } else if constexpr (cookie == 'F') {
+ return *reinterpret_cast<float *>(&p_margs->fargs[fidx(p_idx)]);
+ } else if constexpr (cookie == 'D') {
+ return (T)(size_t)p_margs->fargs[p_idx];
+ }
+}
+
+template <typename... P, size_t... Is>
+void m2n_trampoline_with_idx_seq(void *p_target_func, Mono_InterpMethodArguments *p_margs, IndexSequence<Is...>) {
+ constexpr array<size_t, sizeof...(P)> indices = get_indices_for_type<P...>();
+ typedef void (*Func)(P...);
+ Func func = (Func)p_target_func;
+ func(m2n_arg_cast<P>(p_margs, indices.elems[Is])...);
+}
+
+template <typename R, typename... P, size_t... Is>
+void m2n_trampoline_with_idx_seq_r(void *p_target_func, Mono_InterpMethodArguments *p_margs, IndexSequence<Is...>) {
+ constexpr array<size_t, sizeof...(P)> indices = get_indices_for_type<P...>();
+ typedef R (*Func)(P...);
+ Func func = (Func)p_target_func;
+ R res = func(m2n_arg_cast<P>(p_margs, indices.elems[Is])...);
+ *reinterpret_cast<R *>(p_margs->retval) = res;
+}
+
+inline void m2n_trampoline_with_idx_seq_0(void *p_target_func, Mono_InterpMethodArguments *p_margs) {
+ typedef void (*Func)();
+ Func func = (Func)p_target_func;
+ func();
+}
+
+template <typename R>
+void m2n_trampoline_with_idx_seq_r0(void *p_target_func, Mono_InterpMethodArguments *p_margs) {
+ typedef R (*Func)();
+ Func func = (Func)p_target_func;
+ R res = func();
+ *reinterpret_cast<R *>(p_margs->retval) = res;
+}
+
+template <typename... P>
+void m2n_trampoline(void *p_target_func, Mono_InterpMethodArguments *p_margs) {
+ if constexpr (sizeof...(P) == 0) {
+ m2n_trampoline_with_idx_seq_0(p_target_func, p_margs);
+ } else {
+ m2n_trampoline_with_idx_seq<P...>(p_target_func, p_margs, BuildIndexSequence<sizeof...(P)>{});
+ }
+}
+
+template <typename R, typename... P>
+void m2n_trampoline_r(void *p_target_func, Mono_InterpMethodArguments *p_margs) {
+ if constexpr (sizeof...(P) == 0) {
+ m2n_trampoline_with_idx_seq_r0<R>(p_target_func, p_margs);
+ } else {
+ m2n_trampoline_with_idx_seq_r<R, P...>(p_target_func, p_margs, BuildIndexSequence<sizeof...(P)>{});
+ }
+}
+
+typedef void (*TrampolineFunc)(void *p_target_func, Mono_InterpMethodArguments *p_margs);
+
+void set_trampoline(const char *cookies, TrampolineFunc trampoline_func);
+
+void lazy_initialize();
+
+template <typename... P>
+struct ICallTrampolines {
+ static constexpr auto cookies = get_m2n_cookies<P...>();
+
+ static void add() {
+ lazy_initialize();
+ set_trampoline(cookies.elems, &m2n_trampoline<P...>);
+ }
+};
+
+template <typename R, typename... P>
+struct ICallTrampolinesR {
+ static constexpr auto cookies = get_m2n_cookies_r<R, P...>();
+
+ static void add() {
+ lazy_initialize();
+ set_trampoline(cookies.elems, &m2n_trampoline_r<R, P...>);
+ }
+};
+
+void initialize();
+} // namespace GDMonoWasmM2n
+
+#endif
+
+#endif // GD_MONO_WASM_M2N_H
diff --git a/modules/mono/mono_gd/i_mono_class_member.h b/modules/mono/mono_gd/i_mono_class_member.h
index 2e8e01c80e..36e14ba27c 100644
--- a/modules/mono/mono_gd/i_mono_class_member.h
+++ b/modules/mono/mono_gd/i_mono_class_member.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/mono_gd/managed_type.cpp b/modules/mono/mono_gd/managed_type.cpp
index 3e971efece..0acfafe841 100644
--- a/modules/mono/mono_gd/managed_type.cpp
+++ b/modules/mono/mono_gd/managed_type.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/mono_gd/managed_type.h b/modules/mono/mono_gd/managed_type.h
index 491a2f3d20..0456a9a864 100644
--- a/modules/mono/mono_gd/managed_type.h
+++ b/modules/mono/mono_gd/managed_type.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/mono_gd/support/android_support.cpp b/modules/mono/mono_gd/support/android_support.cpp
index 386e0576b3..c65353dfd1 100644
--- a/modules/mono/mono_gd/support/android_support.cpp
+++ b/modules/mono/mono_gd/support/android_support.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -109,7 +109,7 @@ bool jni_exception_check(JNIEnv *p_env) {
String app_native_lib_dir_cache;
String determine_app_native_lib_dir() {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
ScopedLocalRef<jclass> activityThreadClass(env, env->FindClass("android/app/ActivityThread"));
jmethodID currentActivityThread = env->GetStaticMethodID(activityThreadClass, "currentActivityThread", "()Landroid/app/ActivityThread;");
@@ -134,7 +134,7 @@ String determine_app_native_lib_dir() {
}
String get_app_native_lib_dir() {
- if (app_native_lib_dir_cache.empty())
+ if (app_native_lib_dir_cache.is_empty())
app_native_lib_dir_cache = determine_app_native_lib_dir();
return app_native_lib_dir_cache;
}
@@ -253,7 +253,7 @@ int32_t get_build_version_sdk_int() {
// android.os.Build.VERSION.SDK_INT
if (build_version_sdk_int == 0) {
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jclass versionClass = env->FindClass("android/os/Build$VERSION");
ERR_FAIL_NULL_V(versionClass, 0);
@@ -281,7 +281,7 @@ MonoBoolean _gd_mono_init_cert_store() {
// return false;
// }
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
ScopedLocalRef<jclass> keyStoreClass(env, env->FindClass("java/security/KeyStore"));
@@ -322,7 +322,7 @@ MonoArray *_gd_mono_android_cert_store_lookup(MonoString *p_alias) {
return nullptr;
}
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
ScopedLocalRef<jstring> js_alias(env, env->NewStringUTF(alias_utf8));
mono_free(alias_utf8);
@@ -355,8 +355,8 @@ MonoArray *_gd_mono_android_cert_store_lookup(MonoString *p_alias) {
}
void register_internal_calls() {
- mono_add_internal_call("Android.Runtime.AndroidEnvironment::_gd_mono_init_cert_store", (void *)_gd_mono_init_cert_store);
- mono_add_internal_call("Android.Runtime.AndroidEnvironment::_gd_mono_android_cert_store_lookup", (void *)_gd_mono_android_cert_store_lookup);
+ GDMonoUtils::add_internal_call("Android.Runtime.AndroidEnvironment::_gd_mono_init_cert_store", _gd_mono_init_cert_store);
+ GDMonoUtils::add_internal_call("Android.Runtime.AndroidEnvironment::_gd_mono_android_cert_store_lookup", _gd_mono_android_cert_store_lookup);
}
void initialize() {
@@ -380,14 +380,13 @@ void cleanup() {
if (godot_dl_handle)
gd_mono_android_dlclose(godot_dl_handle, nullptr);
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
if (certStore) {
env->DeleteGlobalRef(certStore);
certStore = nullptr;
}
}
-
} // namespace support
} // namespace android
} // namespace gdmono
@@ -416,8 +415,7 @@ GD_PINVOKE_EXPORT int32_t monodroid_get_system_property(const char *p_name, char
if (r_value) {
if (len >= 0) {
*r_value = (char *)malloc(len + 1);
- if (!*r_value)
- return -1;
+ ERR_FAIL_NULL_V_MSG(*r_value, -1, "Out of memory.");
memcpy(*r_value, prop_value_str, len);
(*r_value)[len] = '\0';
} else {
@@ -438,7 +436,7 @@ GD_PINVOKE_EXPORT mono_bool _monodroid_get_network_interface_up_state(const char
*r_is_up = 0;
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jclass networkInterfaceClass = env->FindClass("java/net/NetworkInterface");
ERR_FAIL_NULL_V(networkInterfaceClass, 0);
@@ -470,7 +468,7 @@ GD_PINVOKE_EXPORT mono_bool _monodroid_get_network_interface_supports_multicast(
*r_supports_multicast = 0;
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
jclass networkInterfaceClass = env->FindClass("java/net/NetworkInterface");
ERR_FAIL_NULL_V(networkInterfaceClass, 0);
@@ -508,7 +506,7 @@ static void interop_get_active_network_dns_servers(char **r_dns_servers, int *dn
CRASH_COND(get_build_version_sdk_int() < 23);
#endif
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
GodotJavaWrapper *godot_java = ((OS_Android *)OS::get_singleton())->get_godot_java();
jobject activity = godot_java->get_activity();
@@ -638,6 +636,7 @@ GD_PINVOKE_EXPORT int32_t _monodroid_get_dns_servers(void **r_dns_servers_array)
if (dns_servers_count > 0) {
size_t ret_size = sizeof(char *) * (size_t)dns_servers_count;
*r_dns_servers_array = malloc(ret_size); // freed by the BCL
+ ERR_FAIL_NULL_V_MSG(*r_dns_servers_array, -1, "Out of memory.");
memcpy(*r_dns_servers_array, dns_servers, ret_size);
}
@@ -649,7 +648,7 @@ GD_PINVOKE_EXPORT const char *_monodroid_timezone_get_default_id() {
//
// TimeZone.getDefault().getID()
- JNIEnv *env = ThreadAndroid::get_env();
+ JNIEnv *env = get_jni_env();
ScopedLocalRef<jclass> timeZoneClass(env, env->FindClass("java/util/TimeZone"));
ERR_FAIL_NULL_V(timeZoneClass, nullptr);
diff --git a/modules/mono/mono_gd/support/android_support.h b/modules/mono/mono_gd/support/android_support.h
index 5947395a99..0c5dd2764c 100755..100644
--- a/modules/mono/mono_gd/support/android_support.h
+++ b/modules/mono/mono_gd/support/android_support.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -45,7 +45,6 @@ void initialize();
void cleanup();
void register_internal_calls();
-
} // namespace support
} // namespace android
} // namespace gdmono
diff --git a/modules/mono/mono_gd/support/ios_support.h b/modules/mono/mono_gd/support/ios_support.h
index ed251cb23a..28a8806d0e 100755..100644
--- a/modules/mono/mono_gd/support/ios_support.h
+++ b/modules/mono/mono_gd/support/ios_support.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -41,7 +41,6 @@ namespace support {
void initialize();
void cleanup();
-
} // namespace support
} // namespace ios
} // namespace gdmono
diff --git a/modules/mono/mono_gd/support/ios_support.mm b/modules/mono/mono_gd/support/ios_support.mm
index dc23c06eba..cdee04edcf 100644
--- a/modules/mono/mono_gd/support/ios_support.mm
+++ b/modules/mono/mono_gd/support/ios_support.mm
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -72,7 +72,6 @@ void initialize() {
void cleanup() {
}
-
} // namespace support
} // namespace ios
} // namespace gdmono
diff --git a/modules/mono/register_types.cpp b/modules/mono/register_types.cpp
index f5c1bda18b..80eb47bfd4 100644
--- a/modules/mono/register_types.cpp
+++ b/modules/mono/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/register_types.h b/modules/mono/register_types.h
index e30d9a8abd..1a2ff004b5 100644
--- a/modules/mono/register_types.h
+++ b/modules/mono/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp
index bd67b03c8e..3aaf726fc8 100644
--- a/modules/mono/signal_awaiter_utils.cpp
+++ b/modules/mono/signal_awaiter_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -48,18 +48,10 @@ Error gd_mono_connect_signal_awaiter(Object *p_source, const StringName &p_signa
}
bool SignalAwaiterCallable::compare_equal(const CallableCustom *p_a, const CallableCustom *p_b) {
+ // Only called if both instances are of type SignalAwaiterCallable. Static cast is safe.
const SignalAwaiterCallable *a = static_cast<const SignalAwaiterCallable *>(p_a);
const SignalAwaiterCallable *b = static_cast<const SignalAwaiterCallable *>(p_b);
-
- if (a->target_id != b->target_id) {
- return false;
- }
-
- if (a->signal != b->signal) {
- return false;
- }
-
- return true;
+ return a->awaiter_handle.handle == b->awaiter_handle.handle;
}
bool SignalAwaiterCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
@@ -109,11 +101,15 @@ void SignalAwaiterCallable::call(const Variant **p_arguments, int p_argcount, Va
"Resumed after await, but class instance is gone.");
#endif
- MonoArray *signal_args = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), p_argcount);
+ MonoArray *signal_args = nullptr;
- for (int i = 0; i < p_argcount; i++) {
- MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_arguments[i]);
- mono_array_setref(signal_args, i, boxed);
+ if (p_argcount > 0) {
+ signal_args = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), p_argcount);
+
+ for (int i = 0; i < p_argcount; i++) {
+ MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_arguments[i]);
+ mono_array_setref(signal_args, i, boxed);
+ }
}
MonoObject *awaiter = awaiter_handle.get_target();
diff --git a/modules/mono/signal_awaiter_utils.h b/modules/mono/signal_awaiter_utils.h
index 18d1e43e14..4c77f8cfed 100644
--- a/modules/mono/signal_awaiter_utils.h
+++ b/modules/mono/signal_awaiter_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/utils/macros.h b/modules/mono/utils/macros.h
index c76619cca4..4a220d89c8 100644
--- a/modules/mono/utils/macros.h
+++ b/modules/mono/utils/macros.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -64,7 +64,6 @@ public:
template <typename F>
ScopeExit<F> operator+(F p_exit_func) { return ScopeExit<F>(p_exit_func); }
};
-
} // namespace gdmono
#define SCOPE_EXIT \
diff --git a/modules/mono/utils/mono_reg_utils.cpp b/modules/mono/utils/mono_reg_utils.cpp
index a619f0b975..bb1265e959 100644
--- a/modules/mono/utils/mono_reg_utils.cpp
+++ b/modules/mono/utils/mono_reg_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -173,7 +173,7 @@ String find_msbuild_tools_path() {
String output;
int exit_code;
- OS::get_singleton()->execute(vswhere_path, vswhere_args, true, nullptr, &output, &exit_code);
+ OS::get_singleton()->execute(vswhere_path, vswhere_args, &output, &exit_code);
if (exit_code == 0) {
Vector<String> lines = output.split("\n");
@@ -188,7 +188,7 @@ String find_msbuild_tools_path() {
if (key == "installationPath") {
String val = line.substr(sep_idx + 1, line.length()).strip_edges();
- ERR_BREAK(val.empty());
+ ERR_BREAK(val.is_empty());
if (!val.ends_with("\\")) {
val += "\\";
@@ -225,7 +225,6 @@ cleanup:
return msbuild_tools_path;
}
-
} // namespace MonoRegUtils
#endif // WINDOWS_ENABLED
diff --git a/modules/mono/utils/mono_reg_utils.h b/modules/mono/utils/mono_reg_utils.h
index cc3f1cb035..0e617761ea 100644
--- a/modules/mono/utils/mono_reg_utils.h
+++ b/modules/mono/utils/mono_reg_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/utils/osx_utils.cpp b/modules/mono/utils/osx_utils.cpp
index 41be198bcf..f4216c8129 100644
--- a/modules/mono/utils/osx_utils.cpp
+++ b/modules/mono/utils/osx_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/utils/osx_utils.h b/modules/mono/utils/osx_utils.h
index 92faead0fb..6704f19077 100644
--- a/modules/mono/utils/osx_utils.h
+++ b/modules/mono/utils/osx_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
diff --git a/modules/mono/utils/path_utils.cpp b/modules/mono/utils/path_utils.cpp
index eb0ba8c700..93d44628ac 100644
--- a/modules/mono/utils/path_utils.cpp
+++ b/modules/mono/utils/path_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -136,7 +136,7 @@ String realpath(const String &p_path) {
}
String join(const String &p_a, const String &p_b) {
- if (p_a.empty()) {
+ if (p_a.is_empty()) {
return p_b;
}
@@ -165,7 +165,7 @@ String relative_to_impl(const String &p_path, const String &p_relative_to) {
} else {
String base_dir = p_relative_to.get_base_dir();
- if (base_dir.length() <= 2 && (base_dir.empty() || base_dir.ends_with(":"))) {
+ if (base_dir.length() <= 2 && (base_dir.is_empty() || base_dir.ends_with(":"))) {
return p_path;
}
@@ -194,5 +194,4 @@ String relative_to(const String &p_path, const String &p_relative_to) {
return relative_to_impl(path_abs_norm, relative_to_abs_norm);
}
-
} // namespace path
diff --git a/modules/mono/utils/path_utils.h b/modules/mono/utils/path_utils.h
index 458d1bb849..82b8f95f49 100644
--- a/modules/mono/utils/path_utils.h
+++ b/modules/mono/utils/path_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -56,7 +56,6 @@ String abspath(const String &p_path);
String realpath(const String &p_path);
String relative_to(const String &p_path, const String &p_relative_to);
-
} // namespace path
#endif // PATH_UTILS_H
diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp
index 65da4328f6..43de77005e 100644
--- a/modules/mono/utils/string_utils.cpp
+++ b/modules/mono/utils/string_utils.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
@@ -84,7 +84,6 @@ int sfind(const String &p_text, int p_from) {
return -1;
}
-
} // namespace
String sformat(const String &p_text, const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5) {
diff --git a/modules/mono/utils/string_utils.h b/modules/mono/utils/string_utils.h
index 99f3548f31..3290cb38b9 100644
--- a/modules/mono/utils/string_utils.h
+++ b/modules/mono/utils/string_utils.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */