@@ -342,6 +342,100 @@ def generate_builtin_bindings(api, output_dir, build_config):
342
342
343
343
builtin_binds_file .write ("\n " .join (builtin_binds ))
344
344
345
+ # Craete a header to implement all builin class vararg methods and be included in `variant.hpp``.
346
+ builtin_vararg_methods_header = include_gen_folder / "builtin_vararg_methods.hpp"
347
+ builtin_vararg_methods_header .open ("w+" ).write (
348
+ generate_builtin_class_vararg_method_implements_header (api ["builtin_classes" ])
349
+ )
350
+
351
+ def generate_builtin_class_vararg_method_implements_header (builtin_classes ):
352
+ result = []
353
+
354
+ add_header ("builtin_vararg_methods.hpp" , result )
355
+
356
+ header_guard = "GODOT_CPP_BUILTIN_VARARG_METHODS_HPP"
357
+ result .append (f"#ifndef { header_guard } " )
358
+ result .append (f"#define { header_guard } " )
359
+ for builtin_api in builtin_classes :
360
+ if not "methods" in builtin_api :
361
+ continue
362
+ class_name = builtin_api ["name" ]
363
+ for method in builtin_api ["methods" ]:
364
+ if not method ["is_vararg" ]:
365
+ continue
366
+
367
+ need_return = "return_type" in method
368
+
369
+ result .append ("template<class... Args>" )
370
+ method_signature = ""
371
+ if need_return :
372
+ method_signature += f'{ correct_type (method ["return_type" ])} '
373
+ else :
374
+ method_signature += "void "
375
+
376
+ method_name = method ["name" ]
377
+ method_signature += f"{ class_name } ::{ method_name } ("
378
+
379
+ method_arguments = []
380
+ if "arguments" in method :
381
+ method_arguments = method ["arguments" ]
382
+
383
+ method_signature += make_function_parameters (
384
+ method_arguments , include_default = False , for_builtin = True , is_vararg = True
385
+ )
386
+
387
+ method_signature += ")"
388
+ if method ["is_const" ]:
389
+ method_signature += " const"
390
+
391
+ method_signature += "{"
392
+ result .append (method_signature )
393
+
394
+ arguments = []
395
+ if "arguments" in method :
396
+ for argument in method ["arguments" ]:
397
+ arguments .append (escape_identifier (argument ["name" ]))
398
+
399
+ need_return = "return_type" in method
400
+
401
+ variant_args = f"\t std::array<Variant, { len (arguments )} + sizeof...(Args)> variant_args = " + "{ { "
402
+ if len (arguments ) > 0 :
403
+ for i in range (len (arguments )):
404
+ if i > 0 :
405
+ variant_args += ", "
406
+ variant_args += f"Variant({ arguments [i ]} )"
407
+ variant_args += ", "
408
+ variant_args += "(Variant(args))... } };"
409
+ result .append (variant_args )
410
+ result .append (f"\t std::array<const Variant *, { len (arguments )} + sizeof...(Args)> call_args;" )
411
+ result .append (f"\t for (size_t i = 0; i < ({ len (arguments )} + sizeof...(Args)); ++i) " + "{" )
412
+ result .append ("\t \t call_args[i] = &variant_args[i];" )
413
+ result .append ("\t }" )
414
+
415
+ base = "(GDExtensionTypePtr)&opaque"
416
+ if "is_static" in method and method ["is_static" ]:
417
+ base = "nullptr"
418
+
419
+ ret = "nullptr"
420
+ if need_return :
421
+ ret = "&ret"
422
+ result .append (f'\t { correct_type (method ["return_type" ])} ret;' )
423
+
424
+ result .append (
425
+ f"\t _method_bindings.method_{ method_name } ({ base } , reinterpret_cast<GDExtensionConstTypePtr *>(call_args.data()), { ret } , { len (arguments )} + sizeof...(Args));"
426
+ )
427
+
428
+ if need_return :
429
+ result .append ("\t return ret;" )
430
+
431
+ result .append ("}" )
432
+ result .append ("" )
433
+
434
+ result .append ("" )
435
+ result .append (f"#endif // ! { header_guard } " )
436
+
437
+ return "\n " .join (result )
438
+
345
439
346
440
def generate_builtin_class_header (builtin_api , size , used_classes , fully_used_classes ):
347
441
result = []
0 commit comments