diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/gdscript/editor/gdscript_highlighter.cpp | 18 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_tokenizer.cpp | 2 | ||||
| -rw-r--r-- | modules/mono/SCsub | 3 | ||||
| -rw-r--r-- | modules/mono/editor/bindings_generator.cpp | 229 | ||||
| -rw-r--r-- | modules/mono/editor/bindings_generator.h | 29 | ||||
| -rw-r--r-- | modules/mono/editor/godotsharp_builds.cpp | 44 | ||||
| -rw-r--r-- | modules/mono/editor/godotsharp_editor.cpp | 33 | ||||
| -rw-r--r-- | modules/mono/editor/godotsharp_editor.h | 2 | ||||
| -rw-r--r-- | modules/mono/mono_gd/gd_mono_field.cpp | 316 | ||||
| -rw-r--r-- | modules/mono/mono_gd/gd_mono_header.h | 10 | ||||
| -rw-r--r-- | modules/mono/mono_gd/gd_mono_marshal.cpp | 317 | ||||
| -rw-r--r-- | modules/mono/mono_gd/gd_mono_marshal.h | 285 | ||||
| -rw-r--r-- | modules/mono/utils/macros.h | 9 | ||||
| -rw-r--r-- | modules/visual_script/visual_script.cpp | 20 | ||||
| -rw-r--r-- | modules/visual_script/visual_script.h | 1 | ||||
| -rw-r--r-- | modules/visual_script/visual_script_nodes.cpp | 14 | ||||
| -rw-r--r-- | modules/visual_script/visual_script_property_selector.cpp | 56 | ||||
| -rw-r--r-- | modules/websocket/lws_client.cpp | 4 | ||||
| -rw-r--r-- | modules/websocket/websocket_multiplayer.cpp | 2 | 
19 files changed, 937 insertions, 457 deletions
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index c199667270..e4aee842ba 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -72,6 +72,7 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_  	bool in_word = false;  	bool in_function_name = false;  	bool in_variable_declaration = false; +	bool in_function_args = false;  	bool in_member_variable = false;  	bool in_node_path = false;  	bool is_hex_notation = false; @@ -220,17 +221,24 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_  		}  		if (is_symbol) { -			in_function_name = false; -			in_member_variable = false; -			if (expect_type && str[j] != ' ' && str[j] != '\t' && str[j] != ':') { +			if (in_function_name) { +				in_function_args = true; +			} + +			if (in_function_args && str[j] == ')') { +				in_function_args = false; +			} + +			if (expect_type && prev_is_char) {  				expect_type = false;  			} +  			if (j > 0 && str[j] == '>' && str[j - 1] == '-') {  				expect_type = true;  			} -			if (in_variable_declaration || previous_text == "(" || previous_text == ",") { +			if (in_variable_declaration || in_function_args) {  				int k = j;  				// Skip space  				while (k < str.length() && (str[k] == '\t' || str[k] == ' ')) { @@ -244,6 +252,8 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_  			}  			in_variable_declaration = false; +			in_function_name = false; +			in_member_variable = false;  		}  		if (!in_node_path && in_region == -1 && str[j] == '$') { diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index 77e1b7290e..c37142b3c1 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -128,8 +128,8 @@ const char *GDScriptTokenizer::token_names[TK_MAX] = {  	"'.'",  	"'?'",  	"':'", -	"'->'",  	"'$'", +	"'->'",  	"'\\n'",  	"PI",  	"TAU", diff --git a/modules/mono/SCsub b/modules/mono/SCsub index e4691ee5c8..9a62b0fdc9 100644 --- a/modules/mono/SCsub +++ b/modules/mono/SCsub @@ -88,9 +88,6 @@ vars.Update(env_mono)  if env_mono['mono_glue']:      env_mono.Append(CPPDEFINES=['MONO_GLUE_ENABLED']) -if ARGUMENTS.get('yolo_copy', False): -    env_mono.Append(CPPDEFINES=['YOLO_COPY']) -  # Configure TLS checks  import tls_configure diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index bcf08026bc..710682d3aa 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -97,7 +97,7 @@  #define C_METHOD_MONOARRAY_TO(m_type) C_NS_MONOMARSHAL "::mono_array_to_" #m_type  #define C_METHOD_MONOARRAY_FROM(m_type) C_NS_MONOMARSHAL "::" #m_type "_to_mono_array" -#define BINDINGS_GENERATOR_VERSION UINT32_C(3) +#define BINDINGS_GENERATOR_VERSION UINT32_C(5)  const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN = "\t%0 %1_in = %1;\n"; @@ -173,23 +173,74 @@ static String snake_to_camel_case(const String &p_identifier, bool p_input_is_up  	return ret;  } -String BindingsGenerator::_determine_enum_prefix(const EnumInterface &p_ienum) { +int BindingsGenerator::_determine_enum_prefix(const EnumInterface &p_ienum) {  	CRASH_COND(p_ienum.constants.empty()); -	const List<ConstantInterface>::Element *front = p_ienum.constants.front(); -	int candidate_len = front->get().name.length(); +	const ConstantInterface &front_iconstant = p_ienum.constants.front()->get(); +	Vector<String> front_parts = front_iconstant.name.split("_", /* p_allow_empty: */ true); +	int candidate_len = front_parts.size() - 1; -	for (const List<ConstantInterface>::Element *E = front->next(); E; E = E->next()) { -		int j = 0; -		for (j = 0; j < candidate_len && j < E->get().name.length(); j++) { -			if (front->get().name[j] != E->get().name[j]) -				break; +	if (candidate_len == 0) +		return 0; + +	for (const List<ConstantInterface>::Element *E = p_ienum.constants.front()->next(); E; E = E->next()) { +		const ConstantInterface &iconstant = E->get(); + +		Vector<String> parts = iconstant.name.split("_", /* p_allow_empty: */ true); + +		int i; +		for (i = 0; i < candidate_len && i < parts.size(); i++) { +			if (front_parts[i] != parts[i]) { +				// HARDCODED: Some Flag enums have the prefix 'FLAG_' for everything except 'FLAGS_DEFAULT' (same for 'METHOD_FLAG_' and'METHOD_FLAGS_DEFAULT'). +				bool hardcoded_exc = (i == candidate_len - 1 && ((front_parts[i] == "FLAGS" && parts[i] == "FLAG") || (front_parts[i] == "FLAG" && parts[i] == "FLAGS"))); +				if (!hardcoded_exc) +					break; +			}  		} -		candidate_len = j; +		candidate_len = i; + +		if (candidate_len == 0) +			return 0;  	} -	return front->get().name.substr(0, candidate_len); +	return candidate_len; +} + +void BindingsGenerator::_apply_prefix_to_enum_constants(BindingsGenerator::EnumInterface &p_ienum, int p_prefix_length) { + +	if (p_prefix_length > 0) { +		for (List<ConstantInterface>::Element *E = p_ienum.constants.front(); E; E = E->next()) { +			int curr_prefix_length = p_prefix_length; + +			ConstantInterface &curr_const = E->get(); + +			String constant_name = curr_const.name; + +			Vector<String> parts = constant_name.split("_", /* p_allow_empty: */ true); + +			if (parts.size() <= curr_prefix_length) +				continue; + +			if (parts[curr_prefix_length][0] >= '0' && parts[curr_prefix_length][0] <= '9') { +				// The name of enum constants may begin with a numeric digit when strip from the enum prefix, +				// so we make the prefix for this constant one word shorter in those cases. +				for (curr_prefix_length = curr_prefix_length - 1; curr_prefix_length > 0; curr_prefix_length--) { +					if (parts[curr_prefix_length][0] < '0' || parts[curr_prefix_length][0] > '9') +						break; +				} +			} + +			constant_name = ""; +			for (int i = curr_prefix_length; i < parts.size(); i++) { +				if (i > curr_prefix_length) +					constant_name += "_"; +				constant_name += parts[i]; +			} + +			curr_const.proxy_name = snake_to_pascal_case(constant_name, true); +		} +	}  }  void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) { @@ -272,7 +323,7 @@ void BindingsGenerator::_generate_global_constants(List<String> &p_output) {  		}  		p_output.push_back(MEMBER_BEGIN "public const int "); -		p_output.push_back(iconstant.name); +		p_output.push_back(iconstant.proxy_name);  		p_output.push_back(" = ");  		p_output.push_back(itos(iconstant.value));  		p_output.push_back(";"); @@ -334,25 +385,8 @@ void BindingsGenerator::_generate_global_constants(List<String> &p_output) {  				p_output.push_back(INDENT2 "/// </summary>\n");  			} -			String constant_name = iconstant.name; - -			if (!ienum.prefix.empty() && constant_name.begins_with(ienum.prefix)) { -				constant_name = constant_name.substr(ienum.prefix.length(), constant_name.length()); -			} - -			if (constant_name[0] >= '0' && constant_name[0] <= '9') { -				// The name of enum constants may begin with a numeric digit when strip from the enum prefix, -				// so we make the prefix one word shorter in those cases. -				int i = 0; -				for (i = ienum.prefix.length() - 1; i >= 0; i--) { -					if (ienum.prefix[i] >= 'A' && ienum.prefix[i] <= 'Z') -						break; -				} -				constant_name = ienum.prefix.substr(i, ienum.prefix.length()) + constant_name; -			} -  			p_output.push_back(INDENT2); -			p_output.push_back(constant_name); +			p_output.push_back(iconstant.proxy_name);  			p_output.push_back(" = ");  			p_output.push_back(itos(iconstant.value));  			p_output.push_back(E != ienum.constants.back() ? ",\n" : "\n"); @@ -646,8 +680,11 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str  	List<String> output;  	output.push_back("using System;\n"); // IntPtr +	output.push_back("using System.Diagnostics;\n"); // DebuggerBrowsable +  	output.push_back("\n#pragma warning disable CS1591 // Disable warning: "  					 "'Missing XML comment for publicly visible type or member'\n"); +  	output.push_back("\nnamespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK);  	const DocData::ClassDoc *class_doc = itype.class_doc; @@ -717,7 +754,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str  			}  			output.push_back(MEMBER_BEGIN "public const int "); -			output.push_back(iconstant.name); +			output.push_back(iconstant.proxy_name);  			output.push_back(" = ");  			output.push_back(itos(iconstant.value));  			output.push_back(";"); @@ -757,25 +794,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str  					output.push_back(INDENT3 "/// </summary>\n");  				} -				String constant_name = iconstant.name; - -				if (!ienum.prefix.empty() && constant_name.begins_with(ienum.prefix)) { -					constant_name = constant_name.substr(ienum.prefix.length(), constant_name.length()); -				} - -				if (constant_name[0] >= '0' && constant_name[0] <= '9') { -					// The name of enum constants may begin with a numeric digit when strip from the enum prefix, -					// so we make the prefix one word shorter in those cases. -					int i = 0; -					for (i = ienum.prefix.length() - 1; i >= 0; i--) { -						if (ienum.prefix[i] >= 'A' && ienum.prefix[i] <= 'Z') -							break; -					} -					constant_name = ienum.prefix.substr(i, ienum.prefix.length()) + constant_name; -				} -  				output.push_back(INDENT3); -				output.push_back(constant_name); +				output.push_back(iconstant.proxy_name);  				output.push_back(" = ");  				output.push_back(itos(iconstant.value));  				output.push_back(E != ienum.constants.back() ? ",\n" : "\n"); @@ -1086,7 +1106,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf  	// Generate method  	{  		if (!p_imethod.is_virtual && !p_imethod.requires_object_call) { -			p_output.push_back(MEMBER_BEGIN "private static IntPtr "); +			p_output.push_back(MEMBER_BEGIN "[DebuggerBrowsable(DebuggerBrowsableState.Never)]" MEMBER_BEGIN "private static IntPtr ");  			p_output.push_back(method_bind_field + " = Object." ICALL_GET_METHODBIND "(" BINDINGS_NATIVE_NAME_FIELD ", \"");  			p_output.push_back(p_imethod.name);  			p_output.push_back("\");\n"); @@ -1843,11 +1863,13 @@ void BindingsGenerator::_populate_object_type_interfaces() {  			EnumInterface ienum(enum_proxy_cname);  			const List<StringName> &constants = enum_map.get(*k);  			for (const List<StringName>::Element *E = constants.front(); E; E = E->next()) { -				int *value = class_info->constant_map.getptr(E->get()); +				const StringName &constant_cname = E->get(); +				String constant_name = constant_cname.operator String(); +				int *value = class_info->constant_map.getptr(constant_cname);  				ERR_FAIL_NULL(value); -				constant_list.erase(E->get().operator String()); +				constant_list.erase(constant_name); -				ConstantInterface iconstant(snake_to_pascal_case(E->get(), true), *value); +				ConstantInterface iconstant(constant_name, snake_to_pascal_case(constant_name, true), *value);  				iconstant.const_doc = NULL;  				for (int i = 0; i < itype.class_doc->constants.size(); i++) { @@ -1862,7 +1884,9 @@ void BindingsGenerator::_populate_object_type_interfaces() {  				ienum.constants.push_back(iconstant);  			} -			ienum.prefix = _determine_enum_prefix(ienum); +			int prefix_length = _determine_enum_prefix(ienum); + +			_apply_prefix_to_enum_constants(ienum, prefix_length);  			itype.enums.push_back(ienum); @@ -1876,10 +1900,11 @@ void BindingsGenerator::_populate_object_type_interfaces() {  		}  		for (const List<String>::Element *E = constant_list.front(); E; E = E->next()) { -			int *value = class_info->constant_map.getptr(E->get()); +			const String &constant_name = E->get(); +			int *value = class_info->constant_map.getptr(StringName(E->get()));  			ERR_FAIL_NULL(value); -			ConstantInterface iconstant(snake_to_pascal_case(E->get(), true), *value); +			ConstantInterface iconstant(constant_name, snake_to_pascal_case(constant_name, true), *value);  			iconstant.const_doc = NULL;  			for (int i = 0; i < itype.class_doc->constants.size(); i++) { @@ -1990,18 +2015,18 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {  	TypeInterface itype; -#define INSERT_STRUCT_TYPE(m_type, m_type_in)                                                         \ -	{                                                                                                 \ -		itype = TypeInterface::create_value_type(String(#m_type));                                    \ -		itype.c_in = "\tMARSHALLED_IN(" #m_type ", %1, %1_in);\n";                                    \ -		itype.c_out = "\tMARSHALLED_OUT(" #m_type ", %1, ret_out)\n"                                  \ -					  "\treturn mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(%2), ret_out);\n"; \ -		itype.c_arg_in = "&%s_in";                                                                    \ -		itype.c_type_in = m_type_in;                                                                  \ -		itype.cs_in = "ref %s";                                                                       \ -		itype.cs_out = "return (%1)%0;";                                                              \ -		itype.im_type_out = "object";                                                                 \ -		builtin_types.insert(itype.cname, itype);                                                     \ +#define INSERT_STRUCT_TYPE(m_type, m_type_in)                          \ +	{                                                                  \ +		itype = TypeInterface::create_value_type(String(#m_type));     \ +		itype.c_in = "\t%0 %1_in = MARSHALLED_IN(" #m_type ", %1);\n"; \ +		itype.c_out = "\treturn MARSHALLED_OUT(" #m_type ", %1);\n";   \ +		itype.c_arg_in = "&%s_in";                                     \ +		itype.c_type_in = "GDMonoMarshal::M_" #m_type "*";             \ +		itype.c_type_out = "GDMonoMarshal::M_" #m_type;                \ +		itype.cs_in = "ref %s";                                        \ +		itype.cs_out = "return (%1)%0;";                               \ +		itype.im_type_out = itype.cs_type;                             \ +		builtin_types.insert(itype.cname, itype);                      \  	}  	INSERT_STRUCT_TYPE(Vector2, "real_t*") @@ -2019,26 +2044,31 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {  	// bool  	itype = TypeInterface::create_value_type(String("bool")); -	itype.c_arg_in = "&%s_in"; -	// /* MonoBoolean <---> bool -	itype.c_in = "\t%0 %1_in = (%0)%1;\n"; -	itype.c_out = "\treturn (%0)%1;\n"; -	itype.c_type = "bool"; -	// */ -	itype.c_type_in = "MonoBoolean"; -	itype.c_type_out = itype.c_type_in; + +	{ +		// MonoBoolean <---> bool +		itype.c_in = "\t%0 %1_in = (%0)%1;\n"; +		itype.c_out = "\treturn (%0)%1;\n"; +		itype.c_type = "bool"; +		itype.c_type_in = "MonoBoolean"; +		itype.c_type_out = itype.c_type_in; +		itype.c_arg_in = "&%s_in"; +	}  	itype.im_type_in = itype.name;  	itype.im_type_out = itype.name;  	builtin_types.insert(itype.cname, itype);  	// int +	// C interface is the same as that of enums. Remember to apply any +	// changes done here to TypeInterface::postsetup_enum_type as well  	itype = TypeInterface::create_value_type(String("int"));  	itype.c_arg_in = "&%s_in"; -	// /* ptrcall only supports int64_t and uint64_t -	itype.c_in = "\t%0 %1_in = (%0)%1;\n"; -	itype.c_out = "\treturn (%0)%1;\n"; -	itype.c_type = "int64_t"; -	// */ +	{ +		// The expected types for parameters and return value in ptrcall are 'int64_t' or 'uint64_t'. +		itype.c_in = "\t%0 %1_in = (%0)%1;\n"; +		itype.c_out = "\treturn (%0)%1;\n"; +		itype.c_type = "int64_t"; +	}  	itype.c_type_in = "int32_t";  	itype.c_type_out = itype.c_type_in;  	itype.im_type_in = itype.name; @@ -2047,21 +2077,22 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {  	// real_t  	itype = TypeInterface(); +	itype.name = "float"; // The name is always "float" in Variant, even with REAL_T_IS_DOUBLE. +	itype.cname = itype.name;  #ifdef REAL_T_IS_DOUBLE -	itype.name = "double"; +	itype.proxy_name = "double";  #else -	itype.name = "float"; +	itype.proxy_name = "float";  #endif -	itype.cname = itype.name; -	itype.proxy_name = itype.name; -	itype.c_arg_in = "&%s_in"; -	//* ptrcall only supports double -	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 = "real_t"; -	itype.c_type_out = "real_t"; +	{ +		// The expected type for parameters and return value in ptrcall is 'double'. +		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 = "real_t"; +		itype.c_type_out = "real_t"; +		itype.c_arg_in = "&%s_in"; +	}  	itype.cs_type = itype.proxy_name;  	itype.im_type_in = itype.proxy_name;  	itype.im_type_out = itype.proxy_name; @@ -2256,7 +2287,7 @@ void BindingsGenerator::_populate_global_constants() {  			int constant_value = GlobalConstants::get_global_constant_value(i);  			StringName enum_name = GlobalConstants::get_global_constant_enum(i); -			ConstantInterface iconstant(snake_to_pascal_case(constant_name, true), constant_value); +			ConstantInterface iconstant(constant_name, snake_to_pascal_case(constant_name, true), constant_value);  			iconstant.const_doc = const_doc;  			if (enum_name != StringName()) { @@ -2284,16 +2315,18 @@ void BindingsGenerator::_populate_global_constants() {  			TypeInterface::postsetup_enum_type(enum_itype);  			enum_types.insert(enum_itype.cname, enum_itype); -			ienum.prefix = _determine_enum_prefix(ienum); +			int prefix_length = _determine_enum_prefix(ienum); -			// HARDCODED +			// HARDCODED: The Error enum have the prefix 'ERR_' for everything except 'OK' and 'FAILED'.  			if (ienum.cname == name_cache.enum_Error) { -				if (!ienum.prefix.empty()) { // Just in case it ever changes +				if (prefix_length > 0) { // Just in case it ever changes  					ERR_PRINTS("Prefix for enum 'Error' is not empty");  				} -				ienum.prefix = "Err"; +				prefix_length = 1; // 'ERR_'  			} + +			_apply_prefix_to_enum_constants(ienum, prefix_length);  		}  	} diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index ad89255ba5..38cf99c294 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -43,20 +43,21 @@ class BindingsGenerator {  	struct ConstantInterface {  		String name; +		String proxy_name;  		int value;  		const DocData::ConstantDoc *const_doc;  		ConstantInterface() {} -		ConstantInterface(const String &p_name, int p_value) { +		ConstantInterface(const String &p_name, const String &p_proxy_name, int p_value) {  			name = p_name; +			proxy_name = p_proxy_name;  			value = p_value;  		}  	};  	struct EnumInterface {  		StringName cname; -		String prefix;  		List<ConstantInterface> constants;  		_FORCE_INLINE_ bool operator==(const EnumInterface &p_ienum) const { @@ -223,7 +224,7 @@ class BindingsGenerator {  		String c_in;  		/** -		 * Determines the name of the variable that will be passed as argument to a ptrcall. +		 * Determines the expression that will be passed as argument to ptrcall.  		 * By default the value equals the name of the parameter,  		 * this varies for types that require special manipulation via [c_in].  		 * Formatting elements: @@ -333,8 +334,6 @@ class BindingsGenerator {  			itype.proxy_name = itype.name;  			itype.c_type = itype.name; -			itype.c_type_in = "void*"; -			itype.c_type_out = "MonoObject*";  			itype.cs_type = itype.proxy_name;  			itype.im_type_in = "ref " + itype.proxy_name;  			itype.im_type_out = itype.proxy_name; @@ -385,10 +384,19 @@ class BindingsGenerator {  		}  		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"; +			// C interface is the same as that of 'int'. Remember to apply any +			// changes done here to the 'int' type interface as well + +			r_enum_itype.c_arg_in = "&%s_in"; +			{ +				// The expected types for parameters and return value in ptrcall are 'int64_t' or 'uint64_t'. +				r_enum_itype.c_in = "\t%0 %1_in = (%0)%1;\n"; +				r_enum_itype.c_out = "\treturn (%0)%1;\n"; +				r_enum_itype.c_type = "int64_t"; +			} +			r_enum_itype.c_type_in = "int32_t"; +			r_enum_itype.c_type_out = r_enum_itype.c_type_in; +  			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;"; @@ -513,7 +521,8 @@ class BindingsGenerator {  		return p_type.name;  	} -	String _determine_enum_prefix(const EnumInterface &p_ienum); +	int _determine_enum_prefix(const EnumInterface &p_ienum); +	void _apply_prefix_to_enum_constants(EnumInterface &p_ienum, int p_prefix_length);  	void _generate_method_icalls(const TypeInterface &p_itype); diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp index 8fe6e46b60..b504cfe712 100644 --- a/modules/mono/editor/godotsharp_builds.cpp +++ b/modules/mono/editor/godotsharp_builds.cpp @@ -306,6 +306,16 @@ String GodotSharpBuilds::_api_folder_name(APIAssembly::Type p_api_type) {  bool GodotSharpBuilds::make_api_sln(APIAssembly::Type p_api_type) {  	String api_name = p_api_type == APIAssembly::API_CORE ? API_ASSEMBLY_NAME : EDITOR_API_ASSEMBLY_NAME; + +	String editor_prebuilt_api_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir(); +	String res_assemblies_dir = GodotSharpDirs::get_res_assemblies_dir(); + +	if (FileAccess::exists(editor_prebuilt_api_dir.plus_file(api_name + ".dll"))) { +		EditorProgress pr("mono_copy_prebuilt_api_assembly", "Copying prebuilt " + api_name + " assembly...", 1); +		pr.step("Copying " + api_name + " assembly", 0); +		return GodotSharpBuilds::copy_api_assembly(editor_prebuilt_api_dir, res_assemblies_dir, api_name, p_api_type); +	} +  	String api_build_config = "Release";  	EditorProgress pr("mono_build_release_" + api_name, "Building " + api_name + " solution...", 3); @@ -357,7 +367,6 @@ bool GodotSharpBuilds::make_api_sln(APIAssembly::Type p_api_type) {  	// Copy the built assembly to the assemblies directory  	String api_assembly_dir = api_sln_dir.plus_file("bin").plus_file(api_build_config); -	String res_assemblies_dir = GodotSharpDirs::get_res_assemblies_dir();  	if (!GodotSharpBuilds::copy_api_assembly(api_assembly_dir, res_assemblies_dir, api_name, p_api_type))  		return false; @@ -369,36 +378,11 @@ bool GodotSharpBuilds::build_project_blocking(const String &p_config) {  	if (!FileAccess::exists(GodotSharpDirs::get_project_sln_path()))  		return true; // No solution to build -	String editor_prebuilt_api_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir(); -	String res_assemblies_dir = GodotSharpDirs::get_res_assemblies_dir(); - -	if (FileAccess::exists(editor_prebuilt_api_dir.plus_file(API_ASSEMBLY_NAME ".dll"))) { -		EditorProgress pr("mono_copy_prebuilt_api_assemblies", -				"Copying prebuilt " API_ASSEMBLY_NAME " assemblies...", 1); -		pr.step("Copying " API_ASSEMBLY_NAME " assembly", 0); - -		if (!GodotSharpBuilds::copy_api_assembly(editor_prebuilt_api_dir, res_assemblies_dir, -					API_ASSEMBLY_NAME, APIAssembly::API_CORE)) { -			return false; -		} -	} else { -		if (!GodotSharpBuilds::make_api_sln(APIAssembly::API_CORE)) -			return false; -	} - -	if (DirAccess::exists(editor_prebuilt_api_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"))) { -		EditorProgress pr("mono_copy_prebuilt_api_assemblies", -				"Copying prebuilt " EDITOR_API_ASSEMBLY_NAME " assemblies...", 1); -		pr.step("Copying " EDITOR_API_ASSEMBLY_NAME " assembly", 0); +	if (!GodotSharpBuilds::make_api_sln(APIAssembly::API_CORE)) +		return false; -		if (!GodotSharpBuilds::copy_api_assembly(editor_prebuilt_api_dir, res_assemblies_dir, -					EDITOR_API_ASSEMBLY_NAME, APIAssembly::API_EDITOR)) { -			return false; -		} -	} else { -		if (!GodotSharpBuilds::make_api_sln(APIAssembly::API_EDITOR)) -			return false; -	} +	if (!GodotSharpBuilds::make_api_sln(APIAssembly::API_EDITOR)) +		return false;  	EditorProgress pr("mono_project_debug_build", "Building project solution...", 1);  	pr.step("Building project solution", 0); diff --git a/modules/mono/editor/godotsharp_editor.cpp b/modules/mono/editor/godotsharp_editor.cpp index fca88a7164..9df4e10266 100644 --- a/modules/mono/editor/godotsharp_editor.cpp +++ b/modules/mono/editor/godotsharp_editor.cpp @@ -108,6 +108,33 @@ bool GodotSharpEditor::_create_project_solution() {  	return true;  } +void GodotSharpEditor::_make_api_solutions_if_needed() { +	// I'm sick entirely of ProgressDialog +	static bool recursion_guard = false; +	if (!recursion_guard) { +		recursion_guard = true; +		_make_api_solutions_if_needed_impl(); +		recursion_guard = false; +	} +} + +void GodotSharpEditor::_make_api_solutions_if_needed_impl() { +	// If the project has a solution and C# project make sure the API assemblies are present and up to date +	String res_assemblies_dir = GodotSharpDirs::get_res_assemblies_dir(); + +	if (!FileAccess::exists(res_assemblies_dir.plus_file(API_ASSEMBLY_NAME ".dll")) || +			GDMono::get_singleton()->metadata_is_api_assembly_invalidated(APIAssembly::API_CORE)) { +		if (!GodotSharpBuilds::make_api_sln(APIAssembly::API_CORE)) +			return; +	} + +	if (!FileAccess::exists(res_assemblies_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll")) || +			GDMono::get_singleton()->metadata_is_api_assembly_invalidated(APIAssembly::API_EDITOR)) { +		if (!GodotSharpBuilds::make_api_sln(APIAssembly::API_EDITOR)) +			return; // Redundant? I don't think so +	} +} +  void GodotSharpEditor::_remove_create_sln_menu_option() {  	menu_popup->remove_item(menu_popup->get_item_index(MENU_CREATE_SLN)); @@ -169,6 +196,7 @@ void GodotSharpEditor::_notification(int p_notification) {  void GodotSharpEditor::_bind_methods() {  	ClassDB::bind_method(D_METHOD("_create_project_solution"), &GodotSharpEditor::_create_project_solution); +	ClassDB::bind_method(D_METHOD("_make_api_solutions_if_needed"), &GodotSharpEditor::_make_api_solutions_if_needed);  	ClassDB::bind_method(D_METHOD("_remove_create_sln_menu_option"), &GodotSharpEditor::_remove_create_sln_menu_option);  	ClassDB::bind_method(D_METHOD("_toggle_about_dialog_on_start"), &GodotSharpEditor::_toggle_about_dialog_on_start);  	ClassDB::bind_method(D_METHOD("_menu_option_pressed", "id"), &GodotSharpEditor::_menu_option_pressed); @@ -390,7 +418,10 @@ GodotSharpEditor::GodotSharpEditor(EditorNode *p_editor) {  	String sln_path = GodotSharpDirs::get_project_sln_path();  	String csproj_path = GodotSharpDirs::get_project_csproj_path(); -	if (!FileAccess::exists(sln_path) || !FileAccess::exists(csproj_path)) { +	if (FileAccess::exists(sln_path) && FileAccess::exists(csproj_path)) { +		// We can't use EditorProgress here. It calls Main::iterarion() and the main loop is not initialized yet. +		call_deferred("_make_api_solutions_if_needed"); +	} else {  		bottom_panel_btn->hide();  		menu_popup->add_item(TTR("Create C# solution"), MENU_CREATE_SLN);  	} diff --git a/modules/mono/editor/godotsharp_editor.h b/modules/mono/editor/godotsharp_editor.h index 46b6bd5ebf..9fb0e40132 100644 --- a/modules/mono/editor/godotsharp_editor.h +++ b/modules/mono/editor/godotsharp_editor.h @@ -56,6 +56,8 @@ class GodotSharpEditor : public Node {  #endif  	bool _create_project_solution(); +	void _make_api_solutions_if_needed(); +	void _make_api_solutions_if_needed_impl();  	void _remove_create_sln_menu_option();  	void _show_about_dialog(); diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index d3a673dc1b..fe41722af0 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -40,65 +40,71 @@ 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_AND_BREAK(m_type)                \ -	{                                                    \ -		const m_type &val = p_value.operator ::m_type(); \ -		MARSHALLED_OUT(m_type, val, raw);                \ -		mono_field_set_value(p_object, mono_field, raw); \ -		break;                                           \ +#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_PRIMITIVE(m_type)                        \ -	{                                                     \ -		m_type val = p_value.operator m_type();           \ -		mono_field_set_value(p_object, mono_field, &val); \ -		break;                                            \ -	} - -#define SET_FROM_ARRAY_AND_BREAK(m_type)                                                       \ -	{                                                                                          \ -		MonoArray *managed = GDMonoMarshal::m_type##_to_mono_array(p_value.operator m_type()); \ -		mono_field_set_value(p_object, mono_field, &managed);                                  \ -		break;                                                                                 \ +#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: { -			SET_FROM_PRIMITIVE(bool); +			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: { -			SET_FROM_PRIMITIVE(signed char); +			int8_t val = p_value.operator signed char(); +			mono_field_set_value(p_object, mono_field, &val);  		} break;  		case MONO_TYPE_I2: { -			SET_FROM_PRIMITIVE(signed short); +			int16_t val = p_value.operator signed short(); +			mono_field_set_value(p_object, mono_field, &val);  		} break;  		case MONO_TYPE_I4: { -			SET_FROM_PRIMITIVE(signed int); +			int32_t val = p_value.operator signed int(); +			mono_field_set_value(p_object, mono_field, &val);  		} break;  		case MONO_TYPE_I8: { -			SET_FROM_PRIMITIVE(int64_t); +			int64_t val = p_value.operator int64_t(); +			mono_field_set_value(p_object, mono_field, &val);  		} break;  		case MONO_TYPE_U1: { -			SET_FROM_PRIMITIVE(unsigned char); +			uint8_t val = p_value.operator unsigned char(); +			mono_field_set_value(p_object, mono_field, &val);  		} break;  		case MONO_TYPE_U2: { -			SET_FROM_PRIMITIVE(unsigned short); +			uint16_t val = p_value.operator unsigned short(); +			mono_field_set_value(p_object, mono_field, &val);  		} break;  		case MONO_TYPE_U4: { -			SET_FROM_PRIMITIVE(unsigned int); +			uint32_t val = p_value.operator unsigned int(); +			mono_field_set_value(p_object, mono_field, &val);  		} break;  		case MONO_TYPE_U8: { -			SET_FROM_PRIMITIVE(uint64_t); +			uint64_t val = p_value.operator uint64_t(); +			mono_field_set_value(p_object, mono_field, &val);  		} break;  		case MONO_TYPE_R4: { -			SET_FROM_PRIMITIVE(float); +			float val = p_value.operator float(); +			mono_field_set_value(p_object, mono_field, &val);  		} break;  		case MONO_TYPE_R8: { -			SET_FROM_PRIMITIVE(double); +			double val = p_value.operator double(); +			mono_field_set_value(p_object, mono_field, &val);  		} break;  		case MONO_TYPE_STRING: { @@ -109,38 +115,115 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_  		case MONO_TYPE_VALUETYPE: {  			GDMonoClass *tclass = type.type_class; -			if (tclass == CACHED_CLASS(Vector2)) -				SET_FROM_STRUCT_AND_BREAK(Vector2); +			if (tclass == CACHED_CLASS(Vector2)) { +				SET_FROM_STRUCT(Vector2); +				break; +			} -			if (tclass == CACHED_CLASS(Rect2)) -				SET_FROM_STRUCT_AND_BREAK(Rect2); +			if (tclass == CACHED_CLASS(Rect2)) { +				SET_FROM_STRUCT(Rect2); +				break; +			} -			if (tclass == CACHED_CLASS(Transform2D)) -				SET_FROM_STRUCT_AND_BREAK(Transform2D); +			if (tclass == CACHED_CLASS(Transform2D)) { +				SET_FROM_STRUCT(Transform2D); +				break; +			} -			if (tclass == CACHED_CLASS(Vector3)) -				SET_FROM_STRUCT_AND_BREAK(Vector3); +			if (tclass == CACHED_CLASS(Vector3)) { +				SET_FROM_STRUCT(Vector3); +				break; +			} -			if (tclass == CACHED_CLASS(Basis)) -				SET_FROM_STRUCT_AND_BREAK(Basis); +			if (tclass == CACHED_CLASS(Basis)) { +				SET_FROM_STRUCT(Basis); +				break; +			} -			if (tclass == CACHED_CLASS(Quat)) -				SET_FROM_STRUCT_AND_BREAK(Quat); +			if (tclass == CACHED_CLASS(Quat)) { +				SET_FROM_STRUCT(Quat); +				break; +			} -			if (tclass == CACHED_CLASS(Transform)) -				SET_FROM_STRUCT_AND_BREAK(Transform); +			if (tclass == CACHED_CLASS(Transform)) { +				SET_FROM_STRUCT(Transform); +				break; +			} -			if (tclass == CACHED_CLASS(AABB)) -				SET_FROM_STRUCT_AND_BREAK(AABB); +			if (tclass == CACHED_CLASS(AABB)) { +				SET_FROM_STRUCT(AABB); +				break; +			} -			if (tclass == CACHED_CLASS(Color)) -				SET_FROM_STRUCT_AND_BREAK(Color); +			if (tclass == CACHED_CLASS(Color)) { +				SET_FROM_STRUCT(Color); +				break; +			} -			if (tclass == CACHED_CLASS(Plane)) -				SET_FROM_STRUCT_AND_BREAK(Plane); +			if (tclass == CACHED_CLASS(Plane)) { +				SET_FROM_STRUCT(Plane); +				break; +			} -			if (mono_class_is_enum(tclass->get_mono_ptr())) -				SET_FROM_PRIMITIVE(signed int); +			if (mono_class_is_enum(tclass->get_mono_ptr())) { +				MonoType *enum_basetype = mono_class_enum_basetype(tclass->get_mono_ptr()); +				switch (mono_type_get_type(enum_basetype)) { +					case MONO_TYPE_BOOLEAN: { +						MonoBoolean val = p_value.operator bool(); +						mono_field_set_value(p_object, mono_field, &val); +						break; +					} +					case MONO_TYPE_CHAR: { +						uint16_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); +						break; +					} +					case MONO_TYPE_I2: { +						int16_t val = p_value.operator signed short(); +						mono_field_set_value(p_object, mono_field, &val); +						break; +					} +					case MONO_TYPE_I4: { +						int32_t val = p_value.operator signed int(); +						mono_field_set_value(p_object, mono_field, &val); +						break; +					} +					case MONO_TYPE_I8: { +						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); +						break; +					} +					case MONO_TYPE_U2: { +						uint16_t val = p_value.operator unsigned short(); +						mono_field_set_value(p_object, mono_field, &val); +						break; +					} +					case MONO_TYPE_U4: { +						uint32_t val = p_value.operator unsigned int(); +						mono_field_set_value(p_object, mono_field, &val); +						break; +					} +					case MONO_TYPE_U8: { +						uint64_t val = p_value.operator uint64_t(); +						mono_field_set_value(p_object, mono_field, &val); +						break; +					} +					default: { +						ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed enum value of unmarshallable base type."); +						ERR_FAIL(); +					} +				} +			}  			ERR_EXPLAIN(String() + "Attempted to set the value of a field of unmarshallable type: " + tclass->get_name());  			ERR_FAIL(); @@ -150,29 +233,45 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_  		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_AND_BREAK(Array); +			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_AND_BREAK(PoolByteArray); +			if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) { +				SET_FROM_ARRAY(PoolByteArray); +				break; +			} -			if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) -				SET_FROM_ARRAY_AND_BREAK(PoolIntArray); +			if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) { +				SET_FROM_ARRAY(PoolIntArray); +				break; +			} -			if (array_type->eklass == REAL_T_MONOCLASS) -				SET_FROM_ARRAY_AND_BREAK(PoolRealArray); +			if (array_type->eklass == REAL_T_MONOCLASS) { +				SET_FROM_ARRAY(PoolRealArray); +				break; +			} -			if (array_type->eklass == CACHED_CLASS_RAW(String)) -				SET_FROM_ARRAY_AND_BREAK(PoolStringArray); +			if (array_type->eklass == CACHED_CLASS_RAW(String)) { +				SET_FROM_ARRAY(PoolStringArray); +				break; +			} -			if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) -				SET_FROM_ARRAY_AND_BREAK(PoolVector2Array); +			if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) { +				SET_FROM_ARRAY(PoolVector2Array); +				break; +			} -			if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) -				SET_FROM_ARRAY_AND_BREAK(PoolVector3Array); +			if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) { +				SET_FROM_ARRAY(PoolVector3Array); +				break; +			} -			if (array_type->eklass == CACHED_CLASS_RAW(Color)) -				SET_FROM_ARRAY_AND_BREAK(PoolColorArray); +			if (array_type->eklass == CACHED_CLASS_RAW(Color)) { +				SET_FROM_ARRAY(PoolColorArray); +				break; +			}  			ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed array of unmarshallable element type.");  			ERR_FAIL(); @@ -220,32 +319,56 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_  			// Variant  			switch (p_value.get_type()) {  				case Variant::BOOL: { -					SET_FROM_PRIMITIVE(bool); +					MonoBoolean val = p_value.operator bool(); +					mono_field_set_value(p_object, mono_field, &val);  				} break;  				case Variant::INT: { -					SET_FROM_PRIMITIVE(int); +					int32_t val = p_value.operator signed int(); +					mono_field_set_value(p_object, mono_field, &val);  				} break;  				case Variant::REAL: {  #ifdef REAL_T_IS_DOUBLE -					SET_FROM_PRIMITIVE(double); +					double val = p_value.operator double(); +					mono_field_set_value(p_object, mono_field, &val);  #else -					SET_FROM_PRIMITIVE(float); +					float val = p_value.operator float(); +					mono_field_set_value(p_object, mono_field, &val);  #endif  				} break;  				case Variant::STRING: {  					MonoString *mono_string = GDMonoMarshal::mono_string_from_godot(p_value);  					mono_field_set_value(p_object, mono_field, mono_string);  				} break; -				case Variant::VECTOR2: SET_FROM_STRUCT_AND_BREAK(Vector2); -				case Variant::RECT2: SET_FROM_STRUCT_AND_BREAK(Rect2); -				case Variant::VECTOR3: SET_FROM_STRUCT_AND_BREAK(Vector3); -				case Variant::TRANSFORM2D: SET_FROM_STRUCT_AND_BREAK(Transform2D); -				case Variant::PLANE: SET_FROM_STRUCT_AND_BREAK(Plane); -				case Variant::QUAT: SET_FROM_STRUCT_AND_BREAK(Quat); -				case Variant::AABB: SET_FROM_STRUCT_AND_BREAK(AABB); -				case Variant::BASIS: SET_FROM_STRUCT_AND_BREAK(Basis); -				case Variant::TRANSFORM: SET_FROM_STRUCT_AND_BREAK(Transform); -				case Variant::COLOR: SET_FROM_STRUCT_AND_BREAK(Color); +				case Variant::VECTOR2: { +					SET_FROM_STRUCT(Vector2); +				} break; +				case Variant::RECT2: { +					SET_FROM_STRUCT(Rect2); +				} break; +				case Variant::VECTOR3: { +					SET_FROM_STRUCT(Vector3); +				} break; +				case Variant::TRANSFORM2D: { +					SET_FROM_STRUCT(Transform2D); +				} break; +				case Variant::PLANE: { +					SET_FROM_STRUCT(Plane); +				} break; +				case Variant::QUAT: { +					SET_FROM_STRUCT(Quat); +				} break; +				case Variant::AABB: { +					SET_FROM_STRUCT(AABB); +				} break; +				case Variant::BASIS: { +					SET_FROM_STRUCT(Basis); +				} break; +				case Variant::TRANSFORM: { +					SET_FROM_STRUCT(Transform); +				} break; +				case Variant::COLOR: { +					SET_FROM_STRUCT(Color); +				} break;  				case Variant::NODE_PATH: {  					MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath());  					mono_field_set_value(p_object, mono_field, managed); @@ -267,14 +390,27 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_  					MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));  					mono_field_set_value(p_object, mono_field, managed);  				} break; -				case Variant::POOL_BYTE_ARRAY: SET_FROM_ARRAY_AND_BREAK(PoolByteArray); -				case Variant::POOL_INT_ARRAY: SET_FROM_ARRAY_AND_BREAK(PoolIntArray); -				case Variant::POOL_REAL_ARRAY: SET_FROM_ARRAY_AND_BREAK(PoolRealArray); -				case Variant::POOL_STRING_ARRAY: SET_FROM_ARRAY_AND_BREAK(PoolStringArray); -				case Variant::POOL_VECTOR2_ARRAY: SET_FROM_ARRAY_AND_BREAK(PoolVector2Array); -				case Variant::POOL_VECTOR3_ARRAY: SET_FROM_ARRAY_AND_BREAK(PoolVector3Array); -				case Variant::POOL_COLOR_ARRAY: SET_FROM_ARRAY_AND_BREAK(PoolColorArray); -#undef SET_FROM_ARRAY_AND_BREAK +				case Variant::POOL_BYTE_ARRAY: { +					SET_FROM_ARRAY(PoolByteArray); +				} break; +				case Variant::POOL_INT_ARRAY: { +					SET_FROM_ARRAY(PoolIntArray); +				} break; +				case Variant::POOL_REAL_ARRAY: { +					SET_FROM_ARRAY(PoolRealArray); +				} break; +				case Variant::POOL_STRING_ARRAY: { +					SET_FROM_ARRAY(PoolStringArray); +				} break; +				case Variant::POOL_VECTOR2_ARRAY: { +					SET_FROM_ARRAY(PoolVector2Array); +				} break; +				case Variant::POOL_VECTOR3_ARRAY: { +					SET_FROM_ARRAY(PoolVector3Array); +				} break; +				case Variant::POOL_COLOR_ARRAY: { +					SET_FROM_ARRAY(PoolColorArray); +				} break;  				default: break;  			}  		} break; @@ -312,8 +448,8 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_  		} break;  	} +#undef SET_FROM_ARRAY_AND_BREAK  #undef SET_FROM_STRUCT_AND_BREAK -#undef SET_FROM_PRIMITIVE  }  MonoObject *GDMonoField::get_value(MonoObject *p_object) { diff --git a/modules/mono/mono_gd/gd_mono_header.h b/modules/mono/mono_gd/gd_mono_header.h index 4f2efc7b92..51d0c9b356 100644 --- a/modules/mono/mono_gd/gd_mono_header.h +++ b/modules/mono/mono_gd/gd_mono_header.h @@ -55,14 +55,4 @@ struct ManagedType {  	}  }; -typedef union { -	uint32_t _uint32; -	float _float; -} mono_float; - -typedef union { -	uint64_t _uint64; -	float _double; -} mono_double; -  #endif // GD_MONO_HEADER_H diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index de91e71bab..2543f5dc47 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -35,20 +35,6 @@  namespace GDMonoMarshal { -#define RETURN_BOXED_STRUCT(m_t, m_var_in)                                    \ -	{                                                                         \ -		const m_t &m_in = m_var_in->operator ::m_t();                         \ -		MARSHALLED_OUT(m_t, m_in, raw);                                       \ -		return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(m_t), raw); \ -	} - -#define RETURN_UNBOXED_STRUCT(m_t, m_var_in)               \ -	{                                                      \ -		float *raw = (float *)mono_object_unbox(m_var_in); \ -		MARSHALLED_IN(m_t, raw, ret);                      \ -		return ret;                                        \ -	} -  Variant::Type managed_to_variant_type(const ManagedType &p_type) {  	switch (p_type.type_encoding) {  		case MONO_TYPE_BOOLEAN: @@ -252,16 +238,21 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty  			return BOX_BOOLEAN(val);  		} +		case MONO_TYPE_CHAR: { +			uint16_t val = p_var->operator unsigned short(); +			return BOX_UINT16(val); +		} +  		case MONO_TYPE_I1: { -			char val = p_var->operator signed char(); +			int8_t val = p_var->operator signed char();  			return BOX_INT8(val);  		}  		case MONO_TYPE_I2: { -			short val = p_var->operator signed short(); +			int16_t val = p_var->operator signed short();  			return BOX_INT16(val);  		}  		case MONO_TYPE_I4: { -			int val = p_var->operator signed int(); +			int32_t val = p_var->operator signed int();  			return BOX_INT32(val);  		}  		case MONO_TYPE_I8: { @@ -270,15 +261,15 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty  		}  		case MONO_TYPE_U1: { -			char val = p_var->operator unsigned char(); +			uint8_t val = p_var->operator unsigned char();  			return BOX_UINT8(val);  		}  		case MONO_TYPE_U2: { -			short val = p_var->operator unsigned short(); +			uint16_t val = p_var->operator unsigned short();  			return BOX_UINT16(val);  		}  		case MONO_TYPE_U4: { -			int val = p_var->operator unsigned int(); +			uint32_t val = p_var->operator unsigned int();  			return BOX_UINT32(val);  		}  		case MONO_TYPE_U8: { @@ -302,39 +293,105 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty  		case MONO_TYPE_VALUETYPE: {  			GDMonoClass *tclass = p_type.type_class; -			if (tclass == CACHED_CLASS(Vector2)) -				RETURN_BOXED_STRUCT(Vector2, p_var); +			if (tclass == 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 (tclass == CACHED_CLASS(Rect2)) -				RETURN_BOXED_STRUCT(Rect2, p_var); +			if (tclass == 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 (tclass == CACHED_CLASS(Transform2D)) -				RETURN_BOXED_STRUCT(Transform2D, p_var); +			if (tclass == 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 (tclass == CACHED_CLASS(Vector3)) -				RETURN_BOXED_STRUCT(Vector3, p_var); +			if (tclass == 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 (tclass == CACHED_CLASS(Basis)) -				RETURN_BOXED_STRUCT(Basis, p_var); +			if (tclass == 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 (tclass == CACHED_CLASS(Quat)) -				RETURN_BOXED_STRUCT(Quat, p_var); +			if (tclass == 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 (tclass == CACHED_CLASS(Transform)) -				RETURN_BOXED_STRUCT(Transform, p_var); +			if (tclass == 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 (tclass == CACHED_CLASS(AABB)) -				RETURN_BOXED_STRUCT(AABB, p_var); +			if (tclass == 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 (tclass == CACHED_CLASS(Color)) -				RETURN_BOXED_STRUCT(Color, p_var); +			if (tclass == 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); +			} -			if (tclass == CACHED_CLASS(Plane)) -				RETURN_BOXED_STRUCT(Plane, p_var); +			if (tclass == 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); +			}  			if (mono_class_is_enum(tclass->get_mono_ptr())) { -				int val = p_var->operator signed int(); -				return BOX_ENUM(tclass->get_mono_ptr(), val); +				MonoType *enum_basetype = mono_class_enum_basetype(tclass->get_mono_ptr()); +				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(); +						return BOX_ENUM(enum_baseclass, val); +					} +					case MONO_TYPE_CHAR: { +						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(); +						return BOX_ENUM(enum_baseclass, val); +					} +					case MONO_TYPE_I2: { +						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(); +						return BOX_ENUM(enum_baseclass, val); +					} +					case MONO_TYPE_I8: { +						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(); +						return BOX_ENUM(enum_baseclass, val); +					} +					case MONO_TYPE_U2: { +						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(); +						return BOX_ENUM(enum_baseclass, val); +					} +					case MONO_TYPE_U8: { +						uint64_t val = p_var->operator uint64_t(); +						return BOX_ENUM(enum_baseclass, val); +					} +					default: { +						ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed enum value of unmarshallable base type."); +						ERR_FAIL_V(NULL); +					} +				}  			}  		} break; @@ -402,7 +459,7 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty  					return BOX_BOOLEAN(val);  				}  				case Variant::INT: { -					int val = p_var->operator signed int(); +					int32_t val = p_var->operator signed int();  					return BOX_INT32(val);  				}  				case Variant::REAL: { @@ -416,33 +473,52 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty  				}  				case Variant::STRING:  					return (MonoObject *)mono_string_from_godot(p_var->operator String()); -				case Variant::VECTOR2: -					RETURN_BOXED_STRUCT(Vector2, p_var); -				case Variant::RECT2: -					RETURN_BOXED_STRUCT(Rect2, p_var); -				case Variant::VECTOR3: -					RETURN_BOXED_STRUCT(Vector3, p_var); -				case Variant::TRANSFORM2D: -					RETURN_BOXED_STRUCT(Transform2D, p_var); -				case Variant::PLANE: -					RETURN_BOXED_STRUCT(Plane, p_var); -				case Variant::QUAT: -					RETURN_BOXED_STRUCT(Quat, p_var); -				case Variant::AABB: -					RETURN_BOXED_STRUCT(AABB, p_var); -				case Variant::BASIS: -					RETURN_BOXED_STRUCT(Basis, p_var); -				case Variant::TRANSFORM: -					RETURN_BOXED_STRUCT(Transform, p_var); -				case Variant::COLOR: -					RETURN_BOXED_STRUCT(Color, p_var); +				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::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::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::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::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: { +				case Variant::OBJECT:  					return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *()); -				}  				case Variant::DICTIONARY:  					return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary));  				case Variant::ARRAY: @@ -512,6 +588,9 @@ Variant mono_object_to_variant(MonoObject *p_obj) {  		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: @@ -545,34 +624,34 @@ Variant mono_object_to_variant(MonoObject *p_obj) {  			GDMonoClass *tclass = type.type_class;  			if (tclass == CACHED_CLASS(Vector2)) -				RETURN_UNBOXED_STRUCT(Vector2, p_obj); +				return MARSHALLED_IN(Vector2, (GDMonoMarshal::M_Vector2 *)mono_object_unbox(p_obj));  			if (tclass == CACHED_CLASS(Rect2)) -				RETURN_UNBOXED_STRUCT(Rect2, p_obj); +				return MARSHALLED_IN(Rect2, (GDMonoMarshal::M_Rect2 *)mono_object_unbox(p_obj));  			if (tclass == CACHED_CLASS(Transform2D)) -				RETURN_UNBOXED_STRUCT(Transform2D, p_obj); +				return MARSHALLED_IN(Transform2D, (GDMonoMarshal::M_Transform2D *)mono_object_unbox(p_obj));  			if (tclass == CACHED_CLASS(Vector3)) -				RETURN_UNBOXED_STRUCT(Vector3, p_obj); +				return MARSHALLED_IN(Vector3, (GDMonoMarshal::M_Vector3 *)mono_object_unbox(p_obj));  			if (tclass == CACHED_CLASS(Basis)) -				RETURN_UNBOXED_STRUCT(Basis, p_obj); +				return MARSHALLED_IN(Basis, (GDMonoMarshal::M_Basis *)mono_object_unbox(p_obj));  			if (tclass == CACHED_CLASS(Quat)) -				RETURN_UNBOXED_STRUCT(Quat, p_obj); +				return MARSHALLED_IN(Quat, (GDMonoMarshal::M_Quat *)mono_object_unbox(p_obj));  			if (tclass == CACHED_CLASS(Transform)) -				RETURN_UNBOXED_STRUCT(Transform, p_obj); +				return MARSHALLED_IN(Transform, (GDMonoMarshal::M_Transform *)mono_object_unbox(p_obj));  			if (tclass == CACHED_CLASS(AABB)) -				RETURN_UNBOXED_STRUCT(AABB, p_obj); +				return MARSHALLED_IN(AABB, (GDMonoMarshal::M_AABB *)mono_object_unbox(p_obj));  			if (tclass == CACHED_CLASS(Color)) -				RETURN_UNBOXED_STRUCT(Color, p_obj); +				return MARSHALLED_IN(Color, (GDMonoMarshal::M_Color *)mono_object_unbox(p_obj));  			if (tclass == CACHED_CLASS(Plane)) -				RETURN_UNBOXED_STRUCT(Plane, p_obj); +				return MARSHALLED_IN(Plane, (GDMonoMarshal::M_Plane *)mono_object_unbox(p_obj));  			if (mono_class_is_enum(tclass->get_mono_ptr()))  				return unbox<int32_t>(p_obj); @@ -708,13 +787,13 @@ Array mono_array_to_Array(MonoArray *p_array) {  	return ret;  } -// TODO Optimize reading/writing from/to PoolArrays -  MonoArray *PoolIntArray_to_mono_array(const PoolIntArray &p_array) { +	PoolIntArray::Read r = p_array.read(); +  	MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int32_t), p_array.size());  	for (int i = 0; i < p_array.size(); i++) { -		mono_array_set(ret, int32_t, i, p_array[i]); +		mono_array_set(ret, int32_t, i, r[i]);  	}  	return ret; @@ -726,19 +805,22 @@ PoolIntArray mono_array_to_PoolIntArray(MonoArray *p_array) {  		return ret;  	int length = mono_array_length(p_array);  	ret.resize(length); +	PoolIntArray::Write w = ret.write(); +  	for (int i = 0; i < length; i++) { -		int32_t elem = mono_array_get(p_array, int32_t, i); -		ret.set(i, elem); +		w[i] = mono_array_get(p_array, int32_t, i);  	}  	return ret;  }  MonoArray *PoolByteArray_to_mono_array(const PoolByteArray &p_array) { +	PoolByteArray::Read r = p_array.read(); +  	MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(uint8_t), p_array.size());  	for (int i = 0; i < p_array.size(); i++) { -		mono_array_set(ret, uint8_t, i, p_array[i]); +		mono_array_set(ret, uint8_t, i, r[i]);  	}  	return ret; @@ -750,20 +832,22 @@ PoolByteArray mono_array_to_PoolByteArray(MonoArray *p_array) {  		return ret;  	int length = mono_array_length(p_array);  	ret.resize(length); +	PoolByteArray::Write w = ret.write();  	for (int i = 0; i < length; i++) { -		uint8_t elem = mono_array_get(p_array, uint8_t, i); -		ret.set(i, elem); +		w[i] = mono_array_get(p_array, uint8_t, i);  	}  	return ret;  }  MonoArray *PoolRealArray_to_mono_array(const PoolRealArray &p_array) { +	PoolRealArray::Read r = p_array.read(); +  	MonoArray *ret = mono_array_new(mono_domain_get(), REAL_T_MONOCLASS, p_array.size());  	for (int i = 0; i < p_array.size(); i++) { -		mono_array_set(ret, real_t, i, p_array[i]); +		mono_array_set(ret, real_t, i, r[i]);  	}  	return ret; @@ -775,20 +859,22 @@ PoolRealArray mono_array_to_PoolRealArray(MonoArray *p_array) {  		return ret;  	int length = mono_array_length(p_array);  	ret.resize(length); +	PoolRealArray::Write w = ret.write();  	for (int i = 0; i < length; i++) { -		real_t elem = mono_array_get(p_array, real_t, i); -		ret.set(i, elem); +		w[i] = mono_array_get(p_array, real_t, i);  	}  	return ret;  }  MonoArray *PoolStringArray_to_mono_array(const PoolStringArray &p_array) { +	PoolStringArray::Read r = p_array.read(); +  	MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), p_array.size());  	for (int i = 0; i < p_array.size(); i++) { -		MonoString *boxed = mono_string_from_godot(p_array[i]); +		MonoString *boxed = mono_string_from_godot(r[i]);  		mono_array_set(ret, MonoString *, i, boxed);  	} @@ -801,29 +887,24 @@ PoolStringArray mono_array_to_PoolStringArray(MonoArray *p_array) {  		return ret;  	int length = mono_array_length(p_array);  	ret.resize(length); +	PoolStringArray::Write w = ret.write();  	for (int i = 0; i < length; i++) {  		MonoString *elem = mono_array_get(p_array, MonoString *, i); -		ret.set(i, mono_string_to_godot(elem)); +		w[i] = mono_string_to_godot(elem);  	}  	return ret;  }  MonoArray *PoolColorArray_to_mono_array(const PoolColorArray &p_array) { +	PoolColorArray::Read r = p_array.read(); +  	MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Color), p_array.size());  	for (int i = 0; i < p_array.size(); i++) { -#ifdef YOLOCOPY -		mono_array_set(ret, Color, i, p_array[i]); -#else -		real_t *raw = (real_t *)mono_array_addr_with_size(ret, sizeof(real_t) * 4, i); -		const Color &elem = p_array[i]; -		raw[0] = elem.r; -		raw[1] = elem.g; -		raw[2] = elem.b; -		raw[3] = elem.a; -#endif +		M_Color *raw = (M_Color *)mono_array_addr_with_size(ret, sizeof(M_Color), i); +		*raw = MARSHALLED_OUT(Color, r[i]);  	}  	return ret; @@ -835,28 +916,23 @@ PoolColorArray mono_array_to_PoolColorArray(MonoArray *p_array) {  		return ret;  	int length = mono_array_length(p_array);  	ret.resize(length); +	PoolColorArray::Write w = ret.write();  	for (int i = 0; i < length; i++) { -		real_t *raw_elem = (real_t *)mono_array_addr_with_size(p_array, sizeof(real_t) * 4, i); -		MARSHALLED_IN(Color, raw_elem, elem); -		ret.set(i, elem); +		w[i] = MARSHALLED_IN(Color, (M_Color *)mono_array_addr_with_size(p_array, sizeof(M_Color), i));  	}  	return ret;  }  MonoArray *PoolVector2Array_to_mono_array(const PoolVector2Array &p_array) { +	PoolVector2Array::Read r = p_array.read(); +  	MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector2), p_array.size());  	for (int i = 0; i < p_array.size(); i++) { -#ifdef YOLOCOPY -		mono_array_set(ret, Vector2, i, p_array[i]); -#else -		real_t *raw = (real_t *)mono_array_addr_with_size(ret, sizeof(real_t) * 2, i); -		const Vector2 &elem = p_array[i]; -		raw[0] = elem.x; -		raw[1] = elem.y; -#endif +		M_Vector2 *raw = (M_Vector2 *)mono_array_addr_with_size(ret, sizeof(M_Vector2), i); +		*raw = MARSHALLED_OUT(Vector2, r[i]);  	}  	return ret; @@ -868,29 +944,23 @@ PoolVector2Array mono_array_to_PoolVector2Array(MonoArray *p_array) {  		return ret;  	int length = mono_array_length(p_array);  	ret.resize(length); +	PoolVector2Array::Write w = ret.write();  	for (int i = 0; i < length; i++) { -		real_t *raw_elem = (real_t *)mono_array_addr_with_size(p_array, sizeof(real_t) * 2, i); -		MARSHALLED_IN(Vector2, raw_elem, elem); -		ret.set(i, elem); +		w[i] = MARSHALLED_IN(Vector2, (M_Vector2 *)mono_array_addr_with_size(p_array, sizeof(M_Vector2), i));  	}  	return ret;  }  MonoArray *PoolVector3Array_to_mono_array(const PoolVector3Array &p_array) { +	PoolVector3Array::Read r = p_array.read(); +  	MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector3), p_array.size());  	for (int i = 0; i < p_array.size(); i++) { -#ifdef YOLOCOPY -		mono_array_set(ret, Vector3, i, p_array[i]); -#else -		real_t *raw = (real_t *)mono_array_addr_with_size(ret, sizeof(real_t) * 3, i); -		const Vector3 &elem = p_array[i]; -		raw[0] = elem.x; -		raw[1] = elem.y; -		raw[2] = elem.z; -#endif +		M_Vector3 *raw = (M_Vector3 *)mono_array_addr_with_size(ret, sizeof(M_Vector3), i); +		*raw = MARSHALLED_OUT(Vector3, r[i]);  	}  	return ret; @@ -902,11 +972,10 @@ PoolVector3Array mono_array_to_PoolVector3Array(MonoArray *p_array) {  		return ret;  	int length = mono_array_length(p_array);  	ret.resize(length); +	PoolVector3Array::Write w = ret.write();  	for (int i = 0; i < length; i++) { -		real_t *raw_elem = (real_t *)mono_array_addr_with_size(p_array, sizeof(real_t) * 3, i); -		MARSHALLED_IN(Vector3, raw_elem, elem); -		ret.set(i, elem); +		w[i] = MARSHALLED_IN(Vector3, (M_Vector3 *)mono_array_addr_with_size(p_array, sizeof(M_Vector3), i));  	}  	return ret; diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index cc0ab5fa05..4002f2a225 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -147,78 +147,271 @@ PoolVector2Array mono_array_to_PoolVector2Array(MonoArray *p_array);  MonoArray *PoolVector3Array_to_mono_array(const PoolVector3Array &p_array);  PoolVector3Array mono_array_to_PoolVector3Array(MonoArray *p_array); -#ifdef YOLO_COPY -#define MARSHALLED_OUT(m_t, m_in, m_out) m_t *m_out = (m_t *)&m_in; -#define MARSHALLED_IN(m_t, m_in, m_out) m_t m_out = *reinterpret_cast<m_t *>(m_in); +// Structures + +namespace InteropLayout { + +enum { +	MATCHES_float = (sizeof(float) == sizeof(uint32_t)), + +	MATCHES_double = (sizeof(double) == sizeof(uint64_t)), + +#ifdef REAL_T_IS_DOUBLE +	MATCHES_real_t = (sizeof(real_t) == sizeof(uint64_t)),  #else +	MATCHES_real_t = (sizeof(real_t) == sizeof(uint32_t)), +#endif -// Expects m_in to be of type float* +	MATCHES_Vector2 = (MATCHES_real_t && (sizeof(Vector2) == (sizeof(real_t) * 2)) && +					   offsetof(Vector2, x) == (sizeof(real_t) * 0) && +					   offsetof(Vector2, y) == (sizeof(real_t) * 1)), -#define MARSHALLED_OUT(m_t, m_in, m_out) MARSHALLED_OUT_##m_t(m_in, m_out) -#define MARSHALLED_IN(m_t, m_in, m_out) MARSHALLED_IN_##m_t(m_in, m_out) +	MATCHES_Rect2 = (MATCHES_Vector2 && (sizeof(Rect2) == (sizeof(Vector2) * 2)) && +					 offsetof(Rect2, position) == (sizeof(Vector2) * 0) && +					 offsetof(Rect2, size) == (sizeof(Vector2) * 1)), -// Vector2 +	MATCHES_Transform2D = (MATCHES_Vector2 && (sizeof(Transform2D) == (sizeof(Vector2) * 3))), // No field offset required, it stores an array -#define MARSHALLED_OUT_Vector2(m_in, m_out) real_t m_out[2] = { m_in.x, m_in.y }; -#define MARSHALLED_IN_Vector2(m_in, m_out) Vector2 m_out(m_in[0], m_in[1]); +	MATCHES_Vector3 = (MATCHES_real_t && (sizeof(Vector3) == (sizeof(real_t) * 3)) && +					   offsetof(Vector3, x) == (sizeof(real_t) * 0) && +					   offsetof(Vector3, y) == (sizeof(real_t) * 1) && +					   offsetof(Vector3, z) == (sizeof(real_t) * 2)), -// Rect2 +	MATCHES_Basis = (MATCHES_Vector3 && (sizeof(Basis) == (sizeof(Vector3) * 3))), // No field offset required, it stores an array -#define MARSHALLED_OUT_Rect2(m_in, m_out) real_t m_out[4] = { m_in.position.x, m_in.position.y, m_in.size.width, m_in.size.height }; -#define MARSHALLED_IN_Rect2(m_in, m_out) Rect2 m_out(m_in[0], m_in[1], m_in[2], m_in[3]); +	MATCHES_Quat = (MATCHES_real_t && (sizeof(Quat) == (sizeof(real_t) * 4)) && +					offsetof(Quat, x) == (sizeof(real_t) * 0) && +					offsetof(Quat, y) == (sizeof(real_t) * 1) && +					offsetof(Quat, z) == (sizeof(real_t) * 2) && +					offsetof(Quat, w) == (sizeof(real_t) * 3)), -// Transform2D +	MATCHES_Transform = (MATCHES_Basis && MATCHES_Vector3 && (sizeof(Transform) == (sizeof(Basis) + sizeof(Vector3))) && +						 offsetof(Transform, basis) == 0 && +						 offsetof(Transform, origin) == sizeof(Basis)), -#define MARSHALLED_OUT_Transform2D(m_in, m_out) real_t m_out[6] = { m_in[0].x, m_in[0].y, m_in[1].x, m_in[1].y, m_in[2].x, m_in[2].y }; -#define MARSHALLED_IN_Transform2D(m_in, m_out) Transform2D m_out(m_in[0], m_in[1], m_in[2], m_in[3], m_in[4], m_in[5]); +	MATCHES_AABB = (MATCHES_Vector3 && (sizeof(AABB) == (sizeof(Vector3) * 2)) && +					offsetof(AABB, position) == (sizeof(Vector3) * 0) && +					offsetof(AABB, size) == (sizeof(Vector3) * 1)), -// Vector3 +	MATCHES_Color = (MATCHES_float && (sizeof(Color) == (sizeof(float) * 4)) && +					 offsetof(Color, r) == (sizeof(float) * 0) && +					 offsetof(Color, g) == (sizeof(float) * 1) && +					 offsetof(Color, b) == (sizeof(float) * 2) && +					 offsetof(Color, a) == (sizeof(float) * 3)), + +	MATCHES_Plane = (MATCHES_Vector3 && MATCHES_real_t && (sizeof(Plane) == (sizeof(Vector3) + sizeof(real_t))) && +					 offsetof(Plane, normal) == 0 && +					 offsetof(Plane, d) == sizeof(Vector3)) +}; + +// In the future we may force this if we want to ref return these structs +#ifdef GD_MONO_FORCE_INTEROP_STRUCT_COPY +// Sometimes clang-format can be an ass +GD_STATIC_ASSERT(MATCHES_Vector2 &&MATCHES_Rect2 &&MATCHES_Transform2D &&MATCHES_Vector3 && +				MATCHES_Basis &&MATCHES_Quat &&MATCHES_Transform &&MATCHES_AABB &&MATCHES_Color &&MATCHES_Plane); +#endif -#define MARSHALLED_OUT_Vector3(m_in, m_out) real_t m_out[3] = { m_in.x, m_in.y, m_in.z }; -#define MARSHALLED_IN_Vector3(m_in, m_out) Vector3 m_out(m_in[0], m_in[1], m_in[2]); +} // namespace InteropLayout -// Basis +#pragma pack(push, 1) -#define MARSHALLED_OUT_Basis(m_in, m_out) real_t m_out[9] = { \ -	m_in[0].x, m_in[0].y, m_in[0].z,                          \ -	m_in[1].x, m_in[1].y, m_in[1].z,                          \ -	m_in[2].x, m_in[2].y, m_in[2].z                           \ +struct M_Vector2 { +	real_t x, y; + +	static _FORCE_INLINE_ Vector2 convert_to(const M_Vector2 &p_from) { +		return Vector2(p_from.x, p_from.y); +	} + +	static _FORCE_INLINE_ M_Vector2 convert_from(const Vector2 &p_from) { +		M_Vector2 ret = { p_from.x, p_from.y }; +		return ret; +	}  }; -#define MARSHALLED_IN_Basis(m_in, m_out) Basis m_out(m_in[0], m_in[1], m_in[2], m_in[3], m_in[4], m_in[5], m_in[6], m_in[7], m_in[8]); -// Quat +struct M_Rect2 { +	M_Vector2 position; +	M_Vector2 size; -#define MARSHALLED_OUT_Quat(m_in, m_out) real_t m_out[4] = { m_in.x, m_in.y, m_in.z, m_in.w }; -#define MARSHALLED_IN_Quat(m_in, m_out) Quat m_out(m_in[0], m_in[1], m_in[2], m_in[3]); +	static _FORCE_INLINE_ Rect2 convert_to(const M_Rect2 &p_from) { +		return Rect2(M_Vector2::convert_to(p_from.position), +				M_Vector2::convert_to(p_from.size)); +	} -// Transform +	static _FORCE_INLINE_ M_Rect2 convert_from(const Rect2 &p_from) { +		M_Rect2 ret = { M_Vector2::convert_from(p_from.position), M_Vector2::convert_from(p_from.size) }; +		return ret; +	} +}; -#define MARSHALLED_OUT_Transform(m_in, m_out) real_t m_out[12] = { \ -	m_in.basis[0].x, m_in.basis[0].y, m_in.basis[0].z,             \ -	m_in.basis[1].x, m_in.basis[1].y, m_in.basis[1].z,             \ -	m_in.basis[2].x, m_in.basis[2].y, m_in.basis[2].z,             \ -	m_in.origin.x, m_in.origin.y, m_in.origin.z                    \ +struct M_Transform2D { +	M_Vector2 elements[3]; + +	static _FORCE_INLINE_ Transform2D convert_to(const M_Transform2D &p_from) { +		return Transform2D(p_from.elements[0].x, p_from.elements[0].y, +				p_from.elements[1].x, p_from.elements[1].y, +				p_from.elements[2].x, p_from.elements[2].y); +	} + +	static _FORCE_INLINE_ M_Transform2D convert_from(const Transform2D &p_from) { +		M_Transform2D ret = { +			M_Vector2::convert_from(p_from.elements[0]), +			M_Vector2::convert_from(p_from.elements[1]), +			M_Vector2::convert_from(p_from.elements[2]) +		}; +		return ret; +	}  }; -#define MARSHALLED_IN_Transform(m_in, m_out) Transform m_out(                                   \ -		Basis(m_in[0], m_in[1], m_in[2], m_in[3], m_in[4], m_in[5], m_in[6], m_in[7], m_in[8]), \ -		Vector3(m_in[9], m_in[10], m_in[11])); -// AABB +struct M_Vector3 { +	real_t x, y, z; + +	static _FORCE_INLINE_ Vector3 convert_to(const M_Vector3 &p_from) { +		return Vector3(p_from.x, p_from.y, p_from.z); +	} -#define MARSHALLED_OUT_AABB(m_in, m_out) real_t m_out[6] = { m_in.position.x, m_in.position.y, m_in.position.z, m_in.size.x, m_in.size.y, m_in.size.z }; -#define MARSHALLED_IN_AABB(m_in, m_out) AABB m_out(Vector3(m_in[0], m_in[1], m_in[2]), Vector3(m_in[3], m_in[4], m_in[5])); +	static _FORCE_INLINE_ M_Vector3 convert_from(const Vector3 &p_from) { +		M_Vector3 ret = { p_from.x, p_from.y, p_from.z }; +		return ret; +	} +}; -// Color +struct M_Basis { +	M_Vector3 elements[3]; + +	static _FORCE_INLINE_ Basis convert_to(const M_Basis &p_from) { +		return Basis(M_Vector3::convert_to(p_from.elements[0]), +				M_Vector3::convert_to(p_from.elements[1]), +				M_Vector3::convert_to(p_from.elements[2])); +	} + +	static _FORCE_INLINE_ M_Basis convert_from(const Basis &p_from) { +		M_Basis ret = { +			M_Vector3::convert_from(p_from.elements[0]), +			M_Vector3::convert_from(p_from.elements[1]), +			M_Vector3::convert_from(p_from.elements[2]) +		}; +		return ret; +	} +}; -#define MARSHALLED_OUT_Color(m_in, m_out) real_t m_out[4] = { m_in.r, m_in.g, m_in.b, m_in.a }; -#define MARSHALLED_IN_Color(m_in, m_out) Color m_out(m_in[0], m_in[1], m_in[2], m_in[3]); +struct M_Quat { +	real_t x, y, z, w; -// Plane +	static _FORCE_INLINE_ Quat convert_to(const M_Quat &p_from) { +		return Quat(p_from.x, p_from.y, p_from.z, p_from.w); +	} -#define MARSHALLED_OUT_Plane(m_in, m_out) real_t m_out[4] = { m_in.normal.x, m_in.normal.y, m_in.normal.z, m_in.d }; -#define MARSHALLED_IN_Plane(m_in, m_out) Plane m_out(m_in[0], m_in[1], m_in[2], m_in[3]); +	static _FORCE_INLINE_ M_Quat convert_from(const Quat &p_from) { +		M_Quat ret = { p_from.x, p_from.y, p_from.z, p_from.w }; +		return ret; +	} +}; -#endif +struct M_Transform { +	M_Basis basis; +	M_Vector3 origin; + +	static _FORCE_INLINE_ Transform convert_to(const M_Transform &p_from) { +		return Transform(M_Basis::convert_to(p_from.basis), M_Vector3::convert_to(p_from.origin)); +	} + +	static _FORCE_INLINE_ M_Transform convert_from(const Transform &p_from) { +		M_Transform ret = { M_Basis::convert_from(p_from.basis), M_Vector3::convert_from(p_from.origin) }; +		return ret; +	} +}; + +struct M_AABB { +	M_Vector3 position; +	M_Vector3 size; + +	static _FORCE_INLINE_ AABB convert_to(const M_AABB &p_from) { +		return AABB(M_Vector3::convert_to(p_from.position), M_Vector3::convert_to(p_from.size)); +	} + +	static _FORCE_INLINE_ M_AABB convert_from(const AABB &p_from) { +		M_AABB ret = { M_Vector3::convert_from(p_from.position), M_Vector3::convert_from(p_from.size) }; +		return ret; +	} +}; + +struct M_Color { +	float r, g, b, a; + +	static _FORCE_INLINE_ Color convert_to(const M_Color &p_from) { +		return Color(p_from.r, p_from.g, p_from.b, p_from.a); +	} + +	static _FORCE_INLINE_ M_Color convert_from(const Color &p_from) { +		M_Color ret = { p_from.r, p_from.g, p_from.b, p_from.a }; +		return ret; +	} +}; + +struct M_Plane { +	M_Vector3 normal; +	real_t d; + +	static _FORCE_INLINE_ Plane convert_to(const M_Plane &p_from) { +		return Plane(M_Vector3::convert_to(p_from.normal), p_from.d); +	} + +	static _FORCE_INLINE_ M_Plane convert_from(const Plane &p_from) { +		M_Plane ret = { M_Vector3::convert_from(p_from.normal), p_from.d }; +		return ret; +	} +}; + +#pragma pack(pop) + +#define DECL_TYPE_MARSHAL_TEMPLATES(m_type)                                             \ +	template <int>                                                                      \ +	_FORCE_INLINE_ m_type marshalled_in_##m_type##_impl(const M_##m_type *p_from);      \ +                                                                                        \ +	template <>                                                                         \ +	_FORCE_INLINE_ m_type marshalled_in_##m_type##_impl<0>(const M_##m_type *p_from) {  \ +		return M_##m_type::convert_to(*p_from);                                         \ +	}                                                                                   \ +                                                                                        \ +	template <>                                                                         \ +	_FORCE_INLINE_ m_type marshalled_in_##m_type##_impl<1>(const M_##m_type *p_from) {  \ +		return *reinterpret_cast<const m_type *>(p_from);                               \ +	}                                                                                   \ +                                                                                        \ +	_FORCE_INLINE_ m_type marshalled_in_##m_type(const M_##m_type *p_from) {            \ +		return marshalled_in_##m_type##_impl<InteropLayout::MATCHES_##m_type>(p_from);  \ +	}                                                                                   \ +                                                                                        \ +	template <int>                                                                      \ +	_FORCE_INLINE_ M_##m_type marshalled_out_##m_type##_impl(const m_type &p_from);     \ +                                                                                        \ +	template <>                                                                         \ +	_FORCE_INLINE_ M_##m_type marshalled_out_##m_type##_impl<0>(const m_type &p_from) { \ +		return M_##m_type::convert_from(p_from);                                        \ +	}                                                                                   \ +                                                                                        \ +	template <>                                                                         \ +	_FORCE_INLINE_ M_##m_type marshalled_out_##m_type##_impl<1>(const m_type &p_from) { \ +		return *reinterpret_cast<const M_##m_type *>(&p_from);                          \ +	}                                                                                   \ +                                                                                        \ +	_FORCE_INLINE_ M_##m_type marshalled_out_##m_type(const m_type &p_from) {           \ +		return marshalled_out_##m_type##_impl<InteropLayout::MATCHES_##m_type>(p_from); \ +	} + +DECL_TYPE_MARSHAL_TEMPLATES(Vector2) +DECL_TYPE_MARSHAL_TEMPLATES(Rect2) +DECL_TYPE_MARSHAL_TEMPLATES(Transform2D) +DECL_TYPE_MARSHAL_TEMPLATES(Vector3) +DECL_TYPE_MARSHAL_TEMPLATES(Basis) +DECL_TYPE_MARSHAL_TEMPLATES(Quat) +DECL_TYPE_MARSHAL_TEMPLATES(Transform) +DECL_TYPE_MARSHAL_TEMPLATES(AABB) +DECL_TYPE_MARSHAL_TEMPLATES(Color) +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 diff --git a/modules/mono/utils/macros.h b/modules/mono/utils/macros.h index 337a86870e..40b47e8648 100644 --- a/modules/mono/utils/macros.h +++ b/modules/mono/utils/macros.h @@ -33,6 +33,15 @@  // noreturn +#if __cpp_static_assert +#define GD_STATIC_ASSERT(m_cond) static_assert((m_cond), "Condition '" #m_cond "' failed") +#else +#define _GD_STATIC_ASSERT_VARNAME_CONCAT_B(m_ignore, m_name) m_name +#define _GD_STATIC_ASSERT_VARNAME_CONCAT_A(m_a, m_b) GD_STATIC_ASSERT_VARNAME_CONCAT_B(hello there, m_a##m_b) +#define _GD_STATIC_ASSERT_VARNAME_CONCAT(m_a, m_b) GD_STATIC_ASSERT_VARNAME_CONCAT_A(m_a, m_b) +#define GD_STATIC_ASSERT(m_cond) typedef int GD_STATIC_ASSERT_VARNAME_CONCAT(godot_static_assert_, __COUNTER__)[((m_cond) ? 1 : -1)] +#endif +  #undef _NO_RETURN_  #ifdef __GNUC__ diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index ff97c21fd9..52a30baaec 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -48,20 +48,22 @@ bool VisualScriptNode::is_breakpoint() const {  void VisualScriptNode::_notification(int p_what) {  	if (p_what == NOTIFICATION_POSTINITIALIZE) { - -		int dvc = get_input_value_port_count(); -		for (int i = 0; i < dvc; i++) { -			Variant::Type expected = get_input_value_port_info(i).type; -			Variant::CallError ce; -			default_input_values.push_back(Variant::construct(expected, NULL, 0, ce, false)); -		} +		_update_input_ports();  	}  } -void VisualScriptNode::ports_changed_notify() { - +void VisualScriptNode::_update_input_ports() {  	default_input_values.resize(MAX(default_input_values.size(), get_input_value_port_count())); //let it grow as big as possible, we don't want to lose values on resize +	int port_count = get_input_value_port_count(); +	for (int i = 0; i < port_count; i++) { +		Variant::Type expected = get_input_value_port_info(i).type; +		Variant::CallError ce; +		set_default_input_value(i, Variant::construct(expected, NULL, 0, ce, false)); +	} +} +void VisualScriptNode::ports_changed_notify() { +	_update_input_ports();  	emit_signal("ports_changed");  } diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index ea99ce4970..bd666447a3 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -52,6 +52,7 @@ class VisualScriptNode : public Resource {  	Array _get_default_input_values() const;  	void validate_input_default_values(); +	void _update_input_ports();  protected:  	void _notification(int p_what); diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 865f93a148..99748af8a1 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -3708,18 +3708,18 @@ void register_visual_script_nodes() {  		for (List<MethodInfo>::Element *E = constructors.front(); E; E = E->next()) {  			if (E->get().arguments.size() > 0) { - -				String name = "functions/constructors/" + Variant::get_type_name(Variant::Type(i)) + " ( "; +				String name = "functions/constructors/" + Variant::get_type_name(Variant::Type(i)) + "(";  				for (int j = 0; j < E->get().arguments.size(); j++) { -					if (j > 0) +					if (j > 0) {  						name += ", "; -					if (E->get().arguments.size() == 1) +					} +					if (E->get().arguments.size() == 1) {  						name += Variant::get_type_name(E->get().arguments[j].type); -					else +					} else {  						name += E->get().arguments[j].name; +					}  				} -				name += ") "; - +				name += ")";  				VisualScriptLanguage::singleton->add_register_func(name, create_constructor_node);  				Pair<Variant::Type, MethodInfo> pair;  				pair.first = Variant::Type(i); diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp index d3637939c9..e5d12cb495 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/visual_script_property_selector.cpp @@ -304,31 +304,36 @@ void VisualScriptPropertySelector::_update_search() {  			continue;  		MethodInfo mi = E->get(); -		String desc = mi.name.capitalize() + " ("; +		String desc_arguments; +		if (mi.arguments.size() > 0) { +			desc_arguments = "("; +			for (int i = 0; i < mi.arguments.size(); i++) { + +				if (i > 0) { +					desc_arguments += ", "; +				} +				if (mi.arguments[i].type == Variant::NIL) { +					desc_arguments += "var"; +				} else if (mi.arguments[i].name.find(":") != -1) { +					desc_arguments += mi.arguments[i].name.get_slice(":", 1); +					mi.arguments[i].name = mi.arguments[i].name.get_slice(":", 0); +				} else { +					desc_arguments += Variant::get_type_name(mi.arguments[i].type); +				} +			} +			desc_arguments += ")"; +		} +		String desc_raw = mi.name + desc_arguments; +		String desc = desc_raw.capitalize().replace("( ", "(");  		if (search_box->get_text() != String() &&  				name.findn(search_box->get_text()) == -1 && -				desc.findn(search_box->get_text()) == -1) +				desc.findn(search_box->get_text()) == -1 && +				desc_raw.findn(search_box->get_text()) == -1) {  			continue; - -		TreeItem *item = search_options->create_item(category ? category : root); - -		for (int i = 0; i < mi.arguments.size(); i++) { - -			if (i > 0) -				desc += ", "; - -			if (mi.arguments[i].type == Variant::NIL) -				desc += "var"; -			else if (mi.arguments[i].name.find(":") != -1) { -				desc += mi.arguments[i].name.get_slice(":", 1); -				mi.arguments[i].name = mi.arguments[i].name.get_slice(":", 0); -			} else -				desc += Variant::get_type_name(mi.arguments[i].type);  		} -		desc += ")"; - +		TreeItem *item = search_options->create_item(category ? category : root);  		item->set_text(0, desc);  		item->set_icon(0, get_icon("MemberMethod", "EditorIcons"));  		item->set_metadata(0, name); @@ -414,11 +419,16 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt  			String basic_type = Variant::get_type_name(vnode_function_call->get_basic_type());  			type_name = basic_type.capitalize() + " ";  		} -		VisualScriptBuiltinFunc *vnode_builtin_function_call = Object::cast_to<VisualScriptBuiltinFunc>(*VisualScriptLanguage::singleton->create_node_from_name(E->get())); -		if (vnode_builtin_function_call != NULL) { -			type_name = "Builtin "; + +		Vector<String> desc = path[path.size() - 1].replace("(", "( ").replace(")", " )").replace(",", ", ").split(" "); +		for (size_t i = 0; i < desc.size(); i++) { +			desc.write[i] = desc[i].capitalize(); +			if (desc[i].ends_with(",")) { +				desc.write[i] = desc[i].replace(",", ", "); +			}  		} -		item->set_text(0, type_name + path[path.size() - 1].capitalize()); + +		item->set_text(0, type_name + String("").join(desc));  		item->set_icon(0, get_icon("VisualScript", "EditorIcons"));  		item->set_selectable(0, true);  		item->set_metadata(0, E->get()); diff --git a/modules/websocket/lws_client.cpp b/modules/websocket/lws_client.cpp index b3e5f6ffab..add3931b50 100644 --- a/modules/websocket/lws_client.cpp +++ b/modules/websocket/lws_client.cpp @@ -34,6 +34,10 @@  #include "core/io/stream_peer_ssl.h"  #include "tls/mbedtls/wrapper/include/openssl/ssl.h" +#if defined(MINGW_ENABLED) || defined(_MSC_VER) +#define strncpy strncpy_s +#endif +  Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocols) {  	ERR_FAIL_COND_V(context != NULL, FAILED); diff --git a/modules/websocket/websocket_multiplayer.cpp b/modules/websocket/websocket_multiplayer.cpp index b948c439df..873658559a 100644 --- a/modules/websocket/websocket_multiplayer.cpp +++ b/modules/websocket/websocket_multiplayer.cpp @@ -313,7 +313,7 @@ void WebSocketMultiplayerPeer::_process_multiplayer(Ref<WebSocketPeer> p_peer, u  		} else if (to < 0) {  			// All but one, for us if not excluded -			if (_peer_id != -p_peer_id) +			if (_peer_id != -(int32_t)p_peer_id)  				_store_pkt(from, to, in_buffer, data_size);  		} else {  |