| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  | proto = """
 | 
					
						
							|  |  |  | #define GDVIRTUAL$VER($RET m_name $ARG) \\ | 
					
						
							|  |  |  | StringName _gdvirtual_##m_name##_sn = #m_name;\\ | 
					
						
							| 
									
										
										
										
											2021-11-24 10:22:12 +01:00
										 |  |  | mutable bool _gdvirtual_##m_name##_initialized = false;\\ | 
					
						
							| 
									
										
										
										
											2022-12-07 12:11:28 +01:00
										 |  |  | mutable GDExtensionClassCallVirtual _gdvirtual_##m_name = nullptr;\\ | 
					
						
							| 
									
										
										
										
											2022-03-10 08:17:38 +01:00
										 |  |  | template<bool required>\\ | 
					
						
							| 
									
										
										
										
											2021-08-23 14:53:27 -03:00
										 |  |  | _FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\ | 
					
						
							| 
									
										
										
										
											2022-09-28 15:57:59 +03:00
										 |  |  | 	ScriptInstance *_script_instance = ((Object*)(this))->get_script_instance();\\ | 
					
						
							|  |  |  | 	if (_script_instance) {\\ | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  | 		Callable::CallError ce; \\ | 
					
						
							|  |  |  | 		$CALLSIARGS\\ | 
					
						
							| 
									
										
										
										
											2022-09-28 15:57:59 +03:00
										 |  |  | 		$CALLSIBEGIN_script_instance->callp(_gdvirtual_##m_name##_sn, $CALLSIARGPASS, ce);\\ | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  | 		if (ce.error == Callable::CallError::CALL_OK) {\\ | 
					
						
							|  |  |  | 			$CALLSIRET\\ | 
					
						
							|  |  |  | 			return true;\\ | 
					
						
							|  |  |  | 		}    \\ | 
					
						
							|  |  |  | 	}\\ | 
					
						
							| 
									
										
										
										
											2021-11-24 10:22:12 +01:00
										 |  |  |     if (unlikely(_get_extension() && !_gdvirtual_##m_name##_initialized)) {\\ | 
					
						
							| 
									
										
										
										
											2022-12-07 12:11:28 +01:00
										 |  |  |         /* TODO: C-style cast because GDExtensionStringNamePtr's const qualifier is broken (see https://github.com/godotengine/godot/pull/67751) */\\ | 
					
						
							|  |  |  |         _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, (GDExtensionStringNamePtr)&_gdvirtual_##m_name##_sn) : (GDExtensionClassCallVirtual) nullptr;\\ | 
					
						
							| 
									
										
										
										
											2021-11-24 10:22:12 +01:00
										 |  |  |         _gdvirtual_##m_name##_initialized = true;\\ | 
					
						
							|  |  |  |     }\\ | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  | 	if (_gdvirtual_##m_name) {\\ | 
					
						
							|  |  |  | 		$CALLPTRARGS\\ | 
					
						
							|  |  |  | 		$CALLPTRRETDEF\\ | 
					
						
							|  |  |  | 		_gdvirtual_##m_name(_get_extension_instance(),$CALLPTRARGPASS,$CALLPTRRETPASS);\\ | 
					
						
							|  |  |  | 		$CALLPTRRET\\ | 
					
						
							|  |  |  | 		return true;\\ | 
					
						
							|  |  |  | 	}\\ | 
					
						
							| 
									
										
										
										
											2022-03-10 08:17:38 +01:00
										 |  |  | 	\\ | 
					
						
							|  |  |  | 	if (required) {\\ | 
					
						
							| 
									
										
										
										
											2022-03-31 14:06:10 +02:00
										 |  |  | 	        ERR_PRINT_ONCE("Required virtual method " + get_class() + "::" + #m_name + " must be overridden before calling.");\\ | 
					
						
							| 
									
										
										
										
											2022-03-14 15:52:03 +01:00
										 |  |  | 	        $RVOID\\ | 
					
						
							| 
									
										
										
										
											2022-03-10 08:17:38 +01:00
										 |  |  |     }\\ | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  | \\ | 
					
						
							|  |  |  |     return false;\\ | 
					
						
							|  |  |  | }\\ | 
					
						
							| 
									
										
										
										
											2021-08-26 01:44:01 +08:00
										 |  |  | _FORCE_INLINE_ bool _gdvirtual_##m_name##_overridden() const { \\ | 
					
						
							| 
									
										
										
										
											2022-09-28 15:57:59 +03:00
										 |  |  | 	ScriptInstance *_script_instance = ((Object*)(this))->get_script_instance();\\ | 
					
						
							|  |  |  | 	if (_script_instance) {\\ | 
					
						
							|  |  |  | 	    return _script_instance->has_method(_gdvirtual_##m_name##_sn);\\ | 
					
						
							| 
									
										
										
										
											2021-08-21 22:52:44 -03:00
										 |  |  | 	}\\ | 
					
						
							| 
									
										
										
										
											2021-11-24 10:22:12 +01:00
										 |  |  |     if (unlikely(_get_extension() && !_gdvirtual_##m_name##_initialized)) {\\ | 
					
						
							| 
									
										
										
										
											2022-12-07 12:11:28 +01:00
										 |  |  |         /* TODO: C-style cast because GDExtensionStringNamePtr's const qualifier is broken (see https://github.com/godotengine/godot/pull/67751) */\\ | 
					
						
							|  |  |  |         _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, (GDExtensionStringNamePtr)&_gdvirtual_##m_name##_sn) : (GDExtensionClassCallVirtual) nullptr;\\ | 
					
						
							| 
									
										
										
										
											2021-11-24 10:22:12 +01:00
										 |  |  |         _gdvirtual_##m_name##_initialized = true;\\ | 
					
						
							|  |  |  |     }\\ | 
					
						
							| 
									
										
										
										
											2021-08-21 22:52:44 -03:00
										 |  |  | 	if (_gdvirtual_##m_name) {\\ | 
					
						
							|  |  |  | 	    return true;\\ | 
					
						
							|  |  |  | 	}\\ | 
					
						
							|  |  |  | 	return false;\\ | 
					
						
							|  |  |  | }\\ | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  | \\ | 
					
						
							|  |  |  | _FORCE_INLINE_ static MethodInfo _gdvirtual_##m_name##_get_method_info() { \\ | 
					
						
							|  |  |  |     MethodInfo method_info;\\ | 
					
						
							|  |  |  |     method_info.name = #m_name;\\ | 
					
						
							|  |  |  |     method_info.flags = METHOD_FLAG_VIRTUAL;\\ | 
					
						
							|  |  |  |     $FILL_METHOD_INFO\\ | 
					
						
							|  |  |  |     return method_info;\\ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def generate_version(argcount, const=False, returns=False): | 
					
						
							|  |  |  |     s = proto | 
					
						
							|  |  |  |     sproto = str(argcount) | 
					
						
							|  |  |  |     method_info = "" | 
					
						
							|  |  |  |     if returns: | 
					
						
							|  |  |  |         sproto += "R" | 
					
						
							|  |  |  |         s = s.replace("$RET", "m_ret, ") | 
					
						
							| 
									
										
										
										
											2022-03-14 15:52:03 +01:00
										 |  |  |         s = s.replace("$RVOID", "(void)r_ret;")  # If required, may lead to uninitialized errors | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  |         s = s.replace("$CALLPTRRETDEF", "PtrToArg<m_ret>::EncodeT ret;") | 
					
						
							|  |  |  |         method_info += "\tmethod_info.return_val = GetTypeInfo<m_ret>::get_class_info();\\\n" | 
					
						
							| 
									
										
										
										
											2023-01-25 03:51:32 +01:00
										 |  |  |         method_info += "\tmethod_info.return_val_metadata = GetTypeInfo<m_ret>::METADATA;\\\n" | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  |     else: | 
					
						
							|  |  |  |         s = s.replace("$RET", "") | 
					
						
							| 
									
										
										
										
											2022-03-14 15:52:03 +01:00
										 |  |  |         s = s.replace("$RVOID", "") | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  |         s = s.replace("$CALLPTRRETDEF", "") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if const: | 
					
						
							|  |  |  |         sproto += "C" | 
					
						
							|  |  |  |         s = s.replace("$CONST", "const") | 
					
						
							|  |  |  |         method_info += "\tmethod_info.flags|=METHOD_FLAG_CONST;\\\n" | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         s = s.replace("$CONST", "") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s = s.replace("$VER", sproto) | 
					
						
							|  |  |  |     argtext = "" | 
					
						
							|  |  |  |     callargtext = "" | 
					
						
							|  |  |  |     callsiargs = "" | 
					
						
							|  |  |  |     callsiargptrs = "" | 
					
						
							|  |  |  |     callptrargsptr = "" | 
					
						
							|  |  |  |     if argcount > 0: | 
					
						
							|  |  |  |         argtext += ", " | 
					
						
							|  |  |  |         callsiargs = "Variant vargs[" + str(argcount) + "]={" | 
					
						
							|  |  |  |         callsiargptrs = "\t\tconst Variant *vargptrs[" + str(argcount) + "]={" | 
					
						
							| 
									
										
										
										
											2022-12-07 12:11:28 +01:00
										 |  |  |         callptrargsptr = "\t\tGDExtensionConstTypePtr argptrs[" + str(argcount) + "]={" | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  |     callptrargs = "" | 
					
						
							|  |  |  |     for i in range(argcount): | 
					
						
							|  |  |  |         if i > 0: | 
					
						
							|  |  |  |             argtext += ", " | 
					
						
							|  |  |  |             callargtext += ", " | 
					
						
							|  |  |  |             callsiargs += ", " | 
					
						
							|  |  |  |             callsiargptrs += ", " | 
					
						
							|  |  |  |             callptrargs += "\t\t" | 
					
						
							|  |  |  |             callptrargsptr += ", " | 
					
						
							|  |  |  |         argtext += "m_type" + str(i + 1) | 
					
						
							| 
									
										
										
										
											2021-08-21 22:52:44 -03:00
										 |  |  |         callargtext += "m_type" + str(i + 1) + " arg" + str(i + 1) | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  |         callsiargs += "Variant(arg" + str(i + 1) + ")" | 
					
						
							|  |  |  |         callsiargptrs += "&vargs[" + str(i) + "]" | 
					
						
							|  |  |  |         callptrargs += ( | 
					
						
							|  |  |  |             "PtrToArg<m_type" + str(i + 1) + ">::EncodeT argval" + str(i + 1) + " = arg" + str(i + 1) + ";\\\n" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         callptrargsptr += "&argval" + str(i + 1) | 
					
						
							|  |  |  |         method_info += "\tmethod_info.arguments.push_back(GetTypeInfo<m_type" + str(i + 1) + ">::get_class_info());\\\n" | 
					
						
							| 
									
										
										
										
											2023-01-25 03:51:32 +01:00
										 |  |  |         method_info += ( | 
					
						
							|  |  |  |             "\tmethod_info.arguments_metadata.push_back(GetTypeInfo<m_type" + str(i + 1) + ">::METADATA);\\\n" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if argcount: | 
					
						
							|  |  |  |         callsiargs += "};\\\n" | 
					
						
							|  |  |  |         callsiargptrs += "};\\\n" | 
					
						
							|  |  |  |         s = s.replace("$CALLSIARGS", callsiargs + callsiargptrs) | 
					
						
							|  |  |  |         s = s.replace("$CALLSIARGPASS", "(const Variant **)vargptrs," + str(argcount)) | 
					
						
							|  |  |  |         callptrargsptr += "};\\\n" | 
					
						
							|  |  |  |         s = s.replace("$CALLPTRARGS", callptrargs + callptrargsptr) | 
					
						
							| 
									
										
										
										
											2022-12-07 12:11:28 +01:00
										 |  |  |         s = s.replace("$CALLPTRARGPASS", "reinterpret_cast<GDExtensionConstTypePtr*>(argptrs)") | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  |     else: | 
					
						
							|  |  |  |         s = s.replace("$CALLSIARGS", "") | 
					
						
							|  |  |  |         s = s.replace("$CALLSIARGPASS", "nullptr, 0") | 
					
						
							|  |  |  |         s = s.replace("$CALLPTRARGS", "") | 
					
						
							|  |  |  |         s = s.replace("$CALLPTRARGPASS", "nullptr") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if returns: | 
					
						
							|  |  |  |         if argcount > 0: | 
					
						
							|  |  |  |             callargtext += "," | 
					
						
							| 
									
										
										
										
											2021-08-21 22:52:44 -03:00
										 |  |  |         callargtext += " m_ret& r_ret" | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  |         s = s.replace("$CALLSIBEGIN", "Variant ret = ") | 
					
						
							| 
									
										
										
										
											2022-02-03 15:03:51 +02:00
										 |  |  |         s = s.replace("$CALLSIRET", "r_ret = VariantCaster<m_ret>::cast(ret);") | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  |         s = s.replace("$CALLPTRRETPASS", "&ret") | 
					
						
							| 
									
										
										
										
											2022-02-03 15:03:51 +02:00
										 |  |  |         s = s.replace("$CALLPTRRET", "r_ret = (m_ret)ret;") | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  |     else: | 
					
						
							|  |  |  |         s = s.replace("$CALLSIBEGIN", "") | 
					
						
							|  |  |  |         s = s.replace("$CALLSIRET", "") | 
					
						
							|  |  |  |         s = s.replace("$CALLPTRRETPASS", "nullptr") | 
					
						
							|  |  |  |         s = s.replace("$CALLPTRRET", "") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s = s.replace("$ARG", argtext) | 
					
						
							|  |  |  |     s = s.replace("$CALLARGS", callargtext) | 
					
						
							|  |  |  |     s = s.replace("$FILL_METHOD_INFO", method_info) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return s | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def run(target, source, env): | 
					
						
							|  |  |  |     max_versions = 12 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     txt = """
 | 
					
						
							|  |  |  | #ifndef GDVIRTUAL_GEN_H | 
					
						
							|  |  |  | #define GDVIRTUAL_GEN_H | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-06 21:02:52 +02:00
										 |  |  | #include "core/object/script_instance.h" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-19 12:58:49 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for i in range(max_versions + 1): | 
					
						
							|  |  |  |         txt += "/* " + str(i) + " Arguments */\n\n" | 
					
						
							|  |  |  |         txt += generate_version(i, False, False) | 
					
						
							|  |  |  |         txt += generate_version(i, False, True) | 
					
						
							|  |  |  |         txt += generate_version(i, True, False) | 
					
						
							|  |  |  |         txt += generate_version(i, True, True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     txt += "#endif" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with open(target[0], "w") as f: | 
					
						
							|  |  |  |         f.write(txt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							|  |  |  |     from platform_methods import subprocess_main | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     subprocess_main(globals()) |