summaryrefslogtreecommitdiff
path: root/modules/mono
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono')
-rw-r--r--modules/mono/config.py42
-rw-r--r--modules/mono/csharp_script.cpp39
-rw-r--r--modules/mono/editor/bindings_generator.cpp169
-rw-r--r--modules/mono/editor/bindings_generator.h43
-rw-r--r--modules/mono/mono_reg_utils.py2
-rw-r--r--modules/mono/utils/mono_reg_utils.cpp2
6 files changed, 172 insertions, 125 deletions
diff --git a/modules/mono/config.py b/modules/mono/config.py
index 831d849ea6..18d9c67795 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -59,9 +59,6 @@ def configure(env):
mono_lib_names = ['mono-2.0-sgen', 'monosgen-2.0']
if env['platform'] == 'windows':
- if mono_static:
- raise RuntimeError('mono-static: Not supported on Windows')
-
if bits == '32':
if os.getenv('MONO32_PREFIX'):
mono_root = os.getenv('MONO32_PREFIX')
@@ -81,24 +78,41 @@ def configure(env):
env.Append(LIBPATH=mono_lib_path)
env.Append(CPPPATH=os.path.join(mono_root, 'include', 'mono-2.0'))
- mono_lib_name = find_file_in_dir(mono_lib_path, mono_lib_names, extension='.lib')
+ if mono_static:
+ lib_suffix = Environment()['LIBSUFFIX']
+ mono_static_lib_name = 'libmono-static-sgen'
- if not mono_lib_name:
- raise RuntimeError('Could not find mono library in: ' + mono_lib_path)
+ if not os.path.isfile(os.path.join(mono_lib_path, mono_static_lib_name + lib_suffix)):
+ raise RuntimeError('Could not find static mono library in: ' + mono_lib_path)
- if os.getenv('VCINSTALLDIR'):
- env.Append(LINKFLAGS=mono_lib_name + Environment()['LIBSUFFIX'])
+ if env.msvc:
+ env.Append(LINKFLAGS=mono_static_lib_name + lib_suffix)
+
+ env.Append(LINKFLAGS='Mincore' + lib_suffix)
+ env.Append(LINKFLAGS='msvcrt' + lib_suffix)
+ env.Append(LINKFLAGS='LIBCMT' + lib_suffix)
+ env.Append(LINKFLAGS='Psapi' + lib_suffix)
+ else:
+ env.Append(LIBS=mono_static_lib_name)
else:
- env.Append(LIBS=mono_lib_name)
+ mono_lib_name = find_file_in_dir(mono_lib_path, mono_lib_names, extension='.lib')
+
+ if not mono_lib_name:
+ raise RuntimeError('Could not find mono library in: ' + mono_lib_path)
+
+ if env.msvc:
+ env.Append(LINKFLAGS=mono_lib_name + Environment()['LIBSUFFIX'])
+ else:
+ env.Append(LIBS=mono_lib_name)
- mono_bin_path = os.path.join(mono_root, 'bin')
+ mono_bin_path = os.path.join(mono_root, 'bin')
- mono_dll_name = find_file_in_dir(mono_bin_path, mono_lib_names, extension='.dll')
+ mono_dll_name = find_file_in_dir(mono_bin_path, mono_lib_names, extension='.dll')
- if not mono_dll_name:
- raise RuntimeError('Could not find mono shared library in: ' + mono_bin_path)
+ if not mono_dll_name:
+ raise RuntimeError('Could not find mono shared library in: ' + mono_bin_path)
- copy_file(mono_bin_path, 'bin', mono_dll_name + '.dll')
+ copy_file(mono_bin_path, 'bin', mono_dll_name + '.dll')
copy_file(os.path.join(mono_lib_path, 'mono', '4.5'), assemblies_output_dir, 'mscorlib.dll')
else:
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 1d0afa7f2d..adc5f16f92 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -1954,8 +1954,12 @@ Variant CSharpScript::_new(const Variant **p_args, int p_argcount, Variant::Call
ScriptInstance *CSharpScript::instance_create(Object *p_this) {
- if (!valid)
- return NULL;
+ if (!script_class) {
+ ERR_EXPLAIN("Cannot find class " + name + " for script " + get_path());
+ ERR_FAIL_V(NULL);
+ }
+
+ ERR_FAIL_COND_V(!valid, NULL);
if (!tool && !ScriptServer::is_scripting_enabled()) {
#ifdef TOOLS_ENABLED
@@ -2045,20 +2049,15 @@ Error CSharpScript::reload(bool p_keep_state) {
if (project_assembly) {
script_class = project_assembly->get_object_derived_class(name);
- if (!script_class) {
- ERR_PRINTS("Cannot find class " + name + " for script " + get_path());
- }
+ valid = script_class != NULL;
+
+ if (script_class) {
#ifdef DEBUG_ENABLED
- else if (OS::get_singleton()->is_stdout_verbose()) {
OS::get_singleton()->print(String("Found class " + script_class->get_namespace() + "." +
script_class->get_name() + " for script " + get_path() + "\n")
.utf8());
- }
#endif
- valid = script_class != NULL;
-
- if (script_class) {
tool = script_class->has_attribute(CACHED_CLASS(ToolAttribute));
native = GDMonoUtils::get_class_native_base(script_class);
@@ -2288,7 +2287,9 @@ RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p
CRASH_COND(mono_domain_get() == NULL);
#endif
-#else
+#endif
+
+#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint() && mono_domain_get() == NULL) {
CRASH_COND(Thread::get_caller_id() == Thread::get_main_id());
@@ -2297,14 +2298,20 @@ RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p
// because this may be called by one of the editor's worker threads.
// Attach this thread temporarily to reload the script.
- MonoThread *mono_thread = mono_thread_attach(SCRIPTS_DOMAIN);
- CRASH_COND(mono_thread == NULL);
+ if (SCRIPTS_DOMAIN) {
+ MonoThread *mono_thread = mono_thread_attach(SCRIPTS_DOMAIN);
+ CRASH_COND(mono_thread == NULL);
+ script->reload();
+ mono_thread_detach(mono_thread);
+ }
+
+ } else { // just reload it normally
+#endif
script->reload();
- mono_thread_detach(mono_thread);
- } else // just reload it normally
+#ifdef TOOLS_ENABLED
+ }
#endif
- script->reload();
if (r_error)
*r_error = OK;
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index a210b8e480..4c598d4f37 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -248,14 +248,14 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) {
if (imethod.is_virtual)
continue;
- const TypeInterface *return_type = _get_type_by_name_or_placeholder(imethod.return_type);
+ const TypeInterface *return_type = _get_type_or_placeholder(imethod.return_type);
String im_sig;
String im_unique_sig;
if (p_itype.is_object_type) {
im_sig += "IntPtr " CS_PARAM_METHODBIND ", ";
- im_unique_sig += imethod.return_type.operator String() + ",IntPtr,IntPtr";
+ im_unique_sig += imethod.return_type.cname.operator String() + ",IntPtr,IntPtr";
}
im_sig += "IntPtr " CS_PARAM_INSTANCE;
@@ -263,7 +263,7 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) {
// Get arguments information
int i = 0;
for (const List<ArgumentInterface>::Element *F = imethod.arguments.front(); F; F = F->next()) {
- const TypeInterface *arg_type = _get_type_by_name_or_placeholder(F->get().type);
+ const TypeInterface *arg_type = _get_type_or_placeholder(F->get().type);
im_sig += ", ";
im_sig += arg_type->im_type_in;
@@ -730,7 +730,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
}
output.push_back(INDENT1 "public ");
- bool is_abstract = !ClassDB::can_instance(itype.name) && ClassDB::is_class_enabled(itype.name); // can_instance returns true if there's a constructor and the class is not 'disabled'
+ bool is_abstract = itype.is_object_type && !ClassDB::can_instance(itype.name) && ClassDB::is_class_enabled(itype.name); // can_instance returns true if there's a constructor and the class is not 'disabled'
output.push_back(itype.is_singleton ? "static class " : (is_abstract ? "abstract class " : "class "));
output.push_back(itype.proxy_name);
@@ -1069,12 +1069,12 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
}
if (getter && setter) {
- ERR_FAIL_COND_V(getter->return_type != setter->arguments.back()->get().type, ERR_BUG);
+ ERR_FAIL_COND_V(getter->return_type.cname != setter->arguments.back()->get().type.cname, ERR_BUG);
}
- StringName proptype_name = getter ? getter->return_type : setter->arguments.back()->get().type;
+ const TypeReference &proptype_name = getter ? getter->return_type : setter->arguments.back()->get().type;
- const TypeInterface *prop_itype = _get_type_by_name_or_null(proptype_name);
+ const TypeInterface *prop_itype = _get_type_or_null(proptype_name);
ERR_FAIL_NULL_V(prop_itype, ERR_BUG); // Property type not found
String prop_proxy_name = escape_csharp_keyword(snake_to_pascal_case(p_iprop.cname));
@@ -1122,9 +1122,9 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
p_output.push_back(getter->proxy_name + "(");
if (p_iprop.index != -1) {
const ArgumentInterface &idx_arg = getter->arguments.front()->get();
- if (idx_arg.type != name_cache.type_int) {
+ if (idx_arg.type.cname != name_cache.type_int) {
// Assume the index parameter is an enum
- const TypeInterface *idx_arg_type = _get_type_by_name_or_null(idx_arg.type);
+ const TypeInterface *idx_arg_type = _get_type_or_null(idx_arg.type);
CRASH_COND(idx_arg_type == NULL);
p_output.push_back("(" + idx_arg_type->proxy_name + ")" + itos(p_iprop.index));
} else {
@@ -1139,9 +1139,9 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
p_output.push_back(setter->proxy_name + "(");
if (p_iprop.index != -1) {
const ArgumentInterface &idx_arg = setter->arguments.front()->get();
- if (idx_arg.type != name_cache.type_int) {
+ if (idx_arg.type.cname != name_cache.type_int) {
// Assume the index parameter is an enum
- const TypeInterface *idx_arg_type = _get_type_by_name_or_null(idx_arg.type);
+ const TypeInterface *idx_arg_type = _get_type_or_null(idx_arg.type);
CRASH_COND(idx_arg_type == NULL);
p_output.push_back("(" + idx_arg_type->proxy_name + ")" + itos(p_iprop.index) + ", ");
} else {
@@ -1158,7 +1158,7 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::MethodInterface &p_imethod, int &p_method_bind_count, List<String> &p_output) {
- const TypeInterface *return_type = _get_type_by_name_or_placeholder(p_imethod.return_type);
+ const TypeInterface *return_type = _get_type_or_placeholder(p_imethod.return_type);
String method_bind_field = "method_bind_" + itos(p_method_bind_count);
@@ -1175,7 +1175,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
// Retrieve information from the arguments
for (const List<ArgumentInterface>::Element *F = p_imethod.arguments.front(); F; F = F->next()) {
const ArgumentInterface &iarg = F->get();
- const TypeInterface *arg_type = _get_type_by_name_or_placeholder(iarg.type);
+ const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type);
// Add the current arguments to the signature
// If the argument has a default value which is not a constant, we will make it Nullable
@@ -1328,21 +1328,19 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
const InternalCall *im_icall = match->value();
String im_call = im_icall->editor_only ? BINDINGS_CLASS_NATIVECALLS_EDITOR : BINDINGS_CLASS_NATIVECALLS;
- im_call += "." + im_icall->name + "(" + icall_params + ");\n";
+ im_call += "." + im_icall->name + "(" + icall_params + ")";
if (p_imethod.arguments.size())
p_output.push_back(cs_in_statements);
if (return_type->cname == name_cache.type_void) {
- p_output.push_back(im_call);
+ p_output.push_back(im_call + ";\n");
} else if (return_type->cs_out.empty()) {
- p_output.push_back("return " + im_call);
+ p_output.push_back("return " + im_call + ";\n");
} else {
- p_output.push_back(return_type->im_type_out);
- p_output.push_back(" " LOCAL_RET " = ");
- p_output.push_back(im_call);
p_output.push_back(INDENT3);
- p_output.push_back(sformat(return_type->cs_out, LOCAL_RET) + "\n");
+ p_output.push_back(sformat(return_type->cs_out, im_call, return_type->cs_type, return_type->im_type_out));
+ p_output.push_back("\n");
}
p_output.push_back(CLOSE_BLOCK_L2);
@@ -1540,9 +1538,9 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
if (p_imethod.is_virtual)
return OK; // Ignore
- bool ret_void = p_imethod.return_type == name_cache.type_void;
+ bool ret_void = p_imethod.return_type.cname == name_cache.type_void;
- const TypeInterface *return_type = _get_type_by_name_or_placeholder(p_imethod.return_type);
+ const TypeInterface *return_type = _get_type_or_placeholder(p_imethod.return_type);
String argc_str = itos(p_imethod.arguments.size());
@@ -1554,7 +1552,7 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
int i = 0;
for (const List<ArgumentInterface>::Element *F = p_imethod.arguments.front(); F; F = F->next()) {
const ArgumentInterface &iarg = F->get();
- const TypeInterface *arg_type = _get_type_by_name_or_placeholder(iarg.type);
+ const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type);
String c_param_name = "arg" + itos(i + 1);
@@ -1695,42 +1693,49 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
return OK;
}
-const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_by_name_or_null(const StringName &p_cname) {
+const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_null(const TypeReference &p_typeref) {
- const Map<StringName, TypeInterface>::Element *builtin_type_match = builtin_types.find(p_cname);
+ const Map<StringName, TypeInterface>::Element *builtin_type_match = builtin_types.find(p_typeref.cname);
if (builtin_type_match)
return &builtin_type_match->get();
- const OrderedHashMap<StringName, TypeInterface>::Element obj_type_match = obj_types.find(p_cname);
+ const OrderedHashMap<StringName, TypeInterface>::Element obj_type_match = obj_types.find(p_typeref.cname);
if (obj_type_match)
return &obj_type_match.get();
- const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(p_cname);
+ if (p_typeref.is_enum) {
+ const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(p_typeref.cname);
- if (enum_match)
- return &enum_match->get();
+ if (enum_match)
+ return &enum_match->get();
+
+ // Enum not found. Most likely because none of its constants were bound, so it's empty. That's fine. Use int instead.
+ const Map<StringName, TypeInterface>::Element *int_match = builtin_types.find(name_cache.type_int);
+ ERR_FAIL_NULL_V(int_match, NULL);
+ return &int_match->get();
+ }
return NULL;
}
-const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_by_name_or_placeholder(const StringName &p_cname) {
+const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_placeholder(const TypeReference &p_typeref) {
- const TypeInterface *found = _get_type_by_name_or_null(p_cname);
+ const TypeInterface *found = _get_type_or_null(p_typeref);
if (found)
return found;
- ERR_PRINTS(String() + "Type not found. Creating placeholder: " + p_cname.operator String());
+ ERR_PRINTS(String() + "Type not found. Creating placeholder: " + p_typeref.cname.operator String());
- const Map<StringName, TypeInterface>::Element *match = placeholder_types.find(p_cname);
+ const Map<StringName, TypeInterface>::Element *match = placeholder_types.find(p_typeref.cname);
if (match)
return &match->get();
TypeInterface placeholder;
- TypeInterface::create_placeholder_type(placeholder, p_cname);
+ TypeInterface::create_placeholder_type(placeholder, p_typeref.cname);
return &placeholder_types.insert(placeholder.cname, placeholder)->get();
}
@@ -1874,7 +1879,7 @@ void BindingsGenerator::_populate_object_type_interfaces() {
// The method Object.free is registered as a virtual method, but without the virtual flag.
// This is because this method is not supposed to be overridden, but called.
// We assume the return type is void.
- imethod.return_type = name_cache.type_void;
+ imethod.return_type.cname = name_cache.type_void;
// Actually, more methods like this may be added in the future,
// which could actually will return something different.
@@ -1889,21 +1894,22 @@ void BindingsGenerator::_populate_object_type_interfaces() {
} else {
ERR_PRINTS("Missing MethodBind for non-virtual method: " + itype.name + "." + imethod.name);
}
- } else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { // TODO redundant?
- imethod.return_type = return_info.class_name;
+ } else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ imethod.return_type.cname = return_info.class_name;
+ imethod.return_type.is_enum = true;
} else if (return_info.class_name != StringName()) {
- imethod.return_type = return_info.class_name;
+ imethod.return_type.cname = return_info.class_name;
} else if (return_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
- imethod.return_type = return_info.hint_string;
+ imethod.return_type.cname = return_info.hint_string;
} else if (return_info.type == Variant::NIL && return_info.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
- imethod.return_type = name_cache.type_Variant;
+ imethod.return_type.cname = name_cache.type_Variant;
} else if (return_info.type == Variant::NIL) {
- imethod.return_type = name_cache.type_void;
+ imethod.return_type.cname = name_cache.type_void;
} else {
- imethod.return_type = Variant::get_type_name(return_info.type);
+ imethod.return_type.cname = Variant::get_type_name(return_info.type);
}
- if (!itype.requires_collections && imethod.return_type == name_cache.type_Dictionary)
+ if (!itype.requires_collections && imethod.return_type.cname == name_cache.type_Dictionary)
itype.requires_collections = true;
for (int i = 0; i < argc; i++) {
@@ -1912,21 +1918,22 @@ void BindingsGenerator::_populate_object_type_interfaces() {
ArgumentInterface iarg;
iarg.name = arginfo.name;
- if (arginfo.type == Variant::INT && arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { // TODO redundant?
- iarg.type = arginfo.class_name;
+ if (arginfo.type == Variant::INT && arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ iarg.type.cname = arginfo.class_name;
+ iarg.type.is_enum = true;
} else if (arginfo.class_name != StringName()) {
- iarg.type = arginfo.class_name;
+ iarg.type.cname = arginfo.class_name;
} else if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
- iarg.type = arginfo.hint_string;
+ iarg.type.cname = arginfo.hint_string;
} else if (arginfo.type == Variant::NIL) {
- iarg.type = name_cache.type_Variant;
+ iarg.type.cname = name_cache.type_Variant;
} else {
- iarg.type = Variant::get_type_name(arginfo.type);
+ iarg.type.cname = Variant::get_type_name(arginfo.type);
}
iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name));
- if (!itype.requires_collections && iarg.type == name_cache.type_Dictionary)
+ if (!itype.requires_collections && iarg.type.cname == name_cache.type_Dictionary)
itype.requires_collections = true;
if (m && m->has_default_argument(i)) {
@@ -1938,7 +1945,7 @@ void BindingsGenerator::_populate_object_type_interfaces() {
if (imethod.is_vararg) {
ArgumentInterface ivararg;
- ivararg.type = name_cache.type_VarArg;
+ ivararg.type.cname = name_cache.type_VarArg;
ivararg.name = "@args";
imethod.add_argument(ivararg);
}
@@ -2023,17 +2030,11 @@ void BindingsGenerator::_populate_object_type_interfaces() {
itype.enums.push_back(ienum);
TypeInterface enum_itype;
+ enum_itype.is_enum = true;
enum_itype.name = itype.name + "." + String(*k);
enum_itype.cname = StringName(enum_itype.name);
enum_itype.proxy_name = itype.proxy_name + "." + enum_proxy_name;
- enum_itype.c_arg_in = "&%s";
- enum_itype.c_type = "int";
- enum_itype.c_type_in = "int";
- enum_itype.c_type_out = "int";
- enum_itype.cs_type = enum_itype.proxy_name;
- enum_itype.im_type_in = enum_itype.proxy_name;
- enum_itype.im_type_out = enum_itype.proxy_name;
- enum_itype.class_doc = &EditorHelp::get_doc_data()->class_list[enum_itype.proxy_name];
+ TypeInterface::postsetup_enum_type(enum_itype);
enum_types.insert(enum_itype.cname, enum_itype);
}
@@ -2068,7 +2069,7 @@ void BindingsGenerator::_default_argument_from_variant(const Variant &p_val, Arg
switch (p_val.get_type()) {
case Variant::NIL:
- if (ClassDB::class_exists(r_iarg.type)) {
+ if (ClassDB::class_exists(r_iarg.type.cname)) {
// Object type
r_iarg.default_argument = "null";
} else {
@@ -2081,7 +2082,7 @@ void BindingsGenerator::_default_argument_from_variant(const Variant &p_val, Arg
r_iarg.default_argument = bool(p_val) ? "true" : "false";
break;
case Variant::INT:
- if (r_iarg.type != name_cache.type_int) {
+ if (r_iarg.type.cname != name_cache.type_int) {
r_iarg.default_argument = "(%s)" + r_iarg.default_argument;
}
break;
@@ -2142,7 +2143,7 @@ void BindingsGenerator::_default_argument_from_variant(const Variant &p_val, Arg
default: {}
}
- if (r_iarg.def_param_mode == ArgumentInterface::CONSTANT && r_iarg.type == name_cache.type_Variant && r_iarg.default_argument != "null")
+ if (r_iarg.def_param_mode == ArgumentInterface::CONSTANT && r_iarg.type.cname == name_cache.type_Variant && r_iarg.default_argument != "null")
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF;
}
@@ -2161,7 +2162,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.c_arg_in = "&%s_in"; \
itype.c_type_in = m_type_in; \
itype.cs_in = "ref %s"; \
- itype.cs_out = "return (" #m_type ")%0;"; \
+ itype.cs_out = "return (%1)%0;"; \
itype.im_type_out = "object"; \
builtin_types.insert(itype.cname, itype); \
}
@@ -2256,7 +2257,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.c_type_out = itype.c_type + "*";
itype.cs_type = itype.proxy_name;
itype.cs_in = "NodePath." CS_SMETHOD_GETINSTANCE "(%0)";
- itype.cs_out = "return new NodePath(%0);";
+ itype.cs_out = "return new %1(%0);";
itype.im_type_in = "IntPtr";
itype.im_type_out = "IntPtr";
_populate_builtin_type(itype, Variant::NODE_PATH);
@@ -2279,7 +2280,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
itype.c_type_out = itype.c_type + "*";
itype.cs_type = itype.proxy_name;
itype.cs_in = "RID." CS_SMETHOD_GETINSTANCE "(%0)";
- itype.cs_out = "return new RID(%0);";
+ itype.cs_out = "return new %1(%0);";
itype.im_type_in = "IntPtr";
itype.im_type_out = "IntPtr";
_populate_builtin_type(itype, Variant::_RID);
@@ -2408,11 +2409,11 @@ void BindingsGenerator::_populate_builtin_type(TypeInterface &r_itype, Variant::
iarg.name = pi.name;
if (pi.type == Variant::NIL)
- iarg.type = name_cache.type_Variant;
+ iarg.type.cname = name_cache.type_Variant;
else
- iarg.type = Variant::get_type_name(pi.type);
+ iarg.type.cname = Variant::get_type_name(pi.type);
- if (!r_itype.requires_collections && iarg.type == name_cache.type_Dictionary)
+ if (!r_itype.requires_collections && iarg.type.cname == name_cache.type_Dictionary)
r_itype.requires_collections = true;
if ((mi.default_arguments.size() - mi.arguments.size() + i) >= 0)
@@ -2423,12 +2424,12 @@ void BindingsGenerator::_populate_builtin_type(TypeInterface &r_itype, Variant::
if (mi.return_val.type == Variant::NIL) {
if (mi.return_val.name != "")
- imethod.return_type = name_cache.type_Variant;
+ imethod.return_type.cname = name_cache.type_Variant;
} else {
- imethod.return_type = Variant::get_type_name(mi.return_val.type);
+ imethod.return_type.cname = Variant::get_type_name(mi.return_val.type);
}
- if (!r_itype.requires_collections && imethod.return_type == name_cache.type_Dictionary)
+ if (!r_itype.requires_collections && imethod.return_type.cname == name_cache.type_Dictionary)
r_itype.requires_collections = true;
if (r_itype.class_doc) {
@@ -2494,13 +2495,11 @@ void BindingsGenerator::_populate_global_constants() {
EnumInterface &ienum = E->get();
TypeInterface enum_itype;
- enum_itype = TypeInterface::create_value_type(ienum.cname);
- enum_itype.c_arg_in = "&%s";
- enum_itype.c_type = "int";
- enum_itype.c_type_in = "int";
- enum_itype.c_type_out = "int";
- enum_itype.im_type_in = enum_itype.name;
- enum_itype.im_type_out = enum_itype.name;
+ enum_itype.is_enum = true;
+ enum_itype.name = ienum.cname.operator String();
+ enum_itype.cname = ienum.cname;
+ enum_itype.proxy_name = enum_itype.name;
+ TypeInterface::postsetup_enum_type(enum_itype);
enum_types.insert(enum_itype.cname, enum_itype);
ienum.prefix = _determine_enum_prefix(ienum);
@@ -2521,15 +2520,13 @@ void BindingsGenerator::_populate_global_constants() {
hardcoded_enums.push_back("Vector3.Axis");
for (List<StringName>::Element *E = hardcoded_enums.front(); E; E = E->next()) {
// These enums are not generated and must be written manually (e.g.: Vector3.Axis)
- // Here, we are assuming core types do not begin with underscore
+ // Here, we assume core types do not begin with underscore
TypeInterface enum_itype;
- enum_itype = TypeInterface::create_value_type(E->get());
- enum_itype.c_arg_in = "&%s";
- enum_itype.c_type = "int";
- enum_itype.c_type_in = "int";
- enum_itype.c_type_out = "int";
- enum_itype.im_type_in = enum_itype.name;
- enum_itype.im_type_out = enum_itype.name;
+ enum_itype.is_enum = true;
+ enum_itype.name = E->get().operator String();
+ enum_itype.cname = E->get();
+ enum_itype.proxy_name = enum_itype.name;
+ TypeInterface::postsetup_enum_type(enum_itype);
enum_types.insert(enum_itype.cname, enum_itype);
}
}
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index f6194139af..5b33a0e53f 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -81,6 +81,15 @@ class BindingsGenerator {
const DocData::PropertyDoc *prop_doc;
};
+ struct TypeReference {
+ StringName cname;
+ bool is_enum;
+
+ TypeReference() {
+ is_enum = false;
+ }
+ };
+
struct ArgumentInterface {
enum DefaultParamMode {
CONSTANT,
@@ -88,7 +97,8 @@ class BindingsGenerator {
NULLABLE_REF
};
- StringName type;
+ TypeReference type;
+
String name;
String default_argument;
DefaultParamMode def_param_mode;
@@ -110,7 +120,7 @@ class BindingsGenerator {
/**
* [TypeInterface::name] of the return type
*/
- StringName return_type;
+ TypeReference return_type;
/**
* Determines if the method has a variable number of arguments (VarArg)
@@ -146,7 +156,7 @@ class BindingsGenerator {
}
MethodInterface() {
- return_type = BindingsGenerator::get_singleton()->name_cache.type_void;
+ return_type.cname = BindingsGenerator::get_singleton()->name_cache.type_void;
is_vararg = false;
is_virtual = false;
requires_object_call = false;
@@ -175,6 +185,7 @@ class BindingsGenerator {
ClassDB::APIType api_type;
+ bool is_enum;
bool is_object_type;
bool is_singleton;
bool is_reference;
@@ -276,7 +287,9 @@ class BindingsGenerator {
* One or more statements that determine how a variable of this type is returned from a method.
* It must contain the return statement(s).
* Formatting elements:
- * %0 or %s: name of the variable to be returned
+ * %0: internal method call statement
+ * %1: [cs_type] of the return type
+ * %2: [im_type_out] of the return type
*/
String cs_out;
@@ -293,8 +306,6 @@ class BindingsGenerator {
/**
* Type used for the return type of internal call methods.
- * If [cs_out] is not empty and the method return type is not void,
- * it is also used for the type of the return variable.
*/
String im_type_out;
@@ -379,10 +390,24 @@ class BindingsGenerator {
r_itype.im_type_out = r_itype.proxy_name;
}
+ static void postsetup_enum_type(TypeInterface &r_enum_itype) {
+ r_enum_itype.c_arg_in = "&%s";
+ r_enum_itype.c_type = "int";
+ r_enum_itype.c_type_in = "int";
+ r_enum_itype.c_type_out = "int";
+ r_enum_itype.cs_type = r_enum_itype.proxy_name;
+ r_enum_itype.cs_in = "(int)%s";
+ r_enum_itype.cs_out = "return (%1)%0;";
+ r_enum_itype.im_type_in = "int";
+ r_enum_itype.im_type_out = "int";
+ r_enum_itype.class_doc = &EditorHelp::get_doc_data()->class_list[r_enum_itype.proxy_name];
+ }
+
TypeInterface() {
api_type = ClassDB::API_NONE;
+ is_enum = false;
is_object_type = false;
is_singleton = false;
is_reference = false;
@@ -492,6 +517,8 @@ class BindingsGenerator {
return "Ref";
else if (p_type.is_object_type)
return "Obj";
+ else if (p_type.is_enum)
+ return "int";
return p_type.name;
}
@@ -501,8 +528,8 @@ class BindingsGenerator {
void _generate_header_icalls();
void _generate_method_icalls(const TypeInterface &p_itype);
- const TypeInterface *_get_type_by_name_or_null(const StringName &p_cname);
- const TypeInterface *_get_type_by_name_or_placeholder(const StringName &p_cname);
+ const TypeInterface *_get_type_or_null(const TypeReference &p_typeref);
+ const TypeInterface *_get_type_or_placeholder(const TypeReference &p_typeref);
void _default_argument_from_variant(const Variant &p_val, ArgumentInterface &r_iarg);
void _populate_builtin_type(TypeInterface &r_itype, Variant::Type vtype);
diff --git a/modules/mono/mono_reg_utils.py b/modules/mono/mono_reg_utils.py
index 8ddddb3a24..9c188d07a7 100644
--- a/modules/mono/mono_reg_utils.py
+++ b/modules/mono/mono_reg_utils.py
@@ -75,7 +75,7 @@ def find_msbuild_tools_path_reg():
vswhere = os.getenv('PROGRAMFILES')
vswhere += r'\Microsoft Visual Studio\Installer\vswhere.exe'
- vswhere_args = ['-latest', '-requires', 'Microsoft.Component.MSBuild']
+ vswhere_args = ['-latest', '-products', '*', '-requires', 'Microsoft.Component.MSBuild']
try:
lines = subprocess.check_output([vswhere] + vswhere_args).splitlines()
diff --git a/modules/mono/utils/mono_reg_utils.cpp b/modules/mono/utils/mono_reg_utils.cpp
index 9bb8da8ac0..7b23cd7579 100644
--- a/modules/mono/utils/mono_reg_utils.cpp
+++ b/modules/mono/utils/mono_reg_utils.cpp
@@ -174,6 +174,8 @@ String find_msbuild_tools_path() {
List<String> vswhere_args;
vswhere_args.push_back("-latest");
+ vswhere_args.push_back("-products");
+ vswhere_args.push_back("*");
vswhere_args.push_back("-requires");
vswhere_args.push_back("Microsoft.Component.MSBuild");