3737#include < godot_cpp/core/type_info.hpp>
3838
3939#include < array>
40+ #include < functional>
4041
4142namespace godot {
4243
@@ -208,6 +209,26 @@ void call_with_ptr_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const,
208209 PtrToArg<R>::encode ((p_instance->*p_method)(PtrToArg<P>::convert (p_args[Is])...), r_ret);
209210}
210211
212+ template <typename T, typename ... P, size_t ... Is>
213+ void call_with_ptr_args_helper (T *p_instance, std::function<void (T &, P...)> &p_method, const GDExtensionConstTypePtr *p_args, IndexSequence<Is...>) {
214+ p_method (*p_instance, PtrToArg<P>::convert (p_args[Is])...);
215+ }
216+
217+ template <typename T, typename ... P, size_t ... Is>
218+ void call_with_ptr_argsc_helper (T *p_instance, std::function<void (const T &, P...)> &p_method, const GDExtensionConstTypePtr *p_args, IndexSequence<Is...>) {
219+ p_method (*p_instance, PtrToArg<P>::convert (p_args[Is])...);
220+ }
221+
222+ template <typename T, typename R, typename ... P, size_t ... Is>
223+ void call_with_ptr_args_ret_helper (T *p_instance, std::function<R (T &, P...)> &p_method, const GDExtensionConstTypePtr *p_args, void *r_ret, IndexSequence<Is...>) {
224+ PtrToArg<R>::encode (p_method (*p_instance, PtrToArg<P>::convert (p_args[Is])...), r_ret);
225+ }
226+
227+ template <typename T, typename R, typename ... P, size_t ... Is>
228+ void call_with_ptr_args_retc_helper (T *p_instance, std::function<R (const T &, P...)> &p_method, const GDExtensionConstTypePtr *p_args, void *r_ret, IndexSequence<Is...>) {
229+ PtrToArg<R>::encode (p_method (*p_instance, PtrToArg<P>::convert (p_args[Is])...), r_ret);
230+ }
231+
211232template <typename T, typename ... P>
212233void call_with_ptr_args (T *p_instance, void (T::*p_method)(P...), const GDExtensionConstTypePtr *p_args, void * /* ret*/ ) {
213234 call_with_ptr_args_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof ...(P)>{});
@@ -228,6 +249,26 @@ void call_with_ptr_args(T *p_instance, R (T::*p_method)(P...) const, const GDExt
228249 call_with_ptr_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof ...(P)>{});
229250}
230251
252+ template <typename T, typename ... P>
253+ void call_with_ptr_args (T *p_instance, std::function<void (T &, P...)> &p_method, const GDExtensionConstTypePtr *p_args, void * /* ret*/ ) {
254+ call_with_ptr_args_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof ...(P)>{});
255+ }
256+
257+ template <typename T, typename ... P>
258+ void call_with_ptr_args (T *p_instance, std::function<void (const T &, P...)> &p_method, const GDExtensionConstTypePtr *p_args, void * /* ret*/ ) {
259+ call_with_ptr_argsc_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof ...(P)>{});
260+ }
261+
262+ template <typename T, typename R, typename ... P>
263+ void call_with_ptr_args (T *p_instance, std::function<R (T &, P...)> &p_method, const GDExtensionConstTypePtr *p_args, void *r_ret) {
264+ call_with_ptr_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof ...(P)>{});
265+ }
266+
267+ template <typename T, typename R, typename ... P>
268+ void call_with_ptr_args (T *p_instance, std::function<R (const T &, P...)> &p_method, const GDExtensionConstTypePtr *p_args, void *r_ret) {
269+ call_with_ptr_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof ...(P)>{});
270+ }
271+
231272template <typename T, typename ... P, size_t ... Is>
232273void call_with_variant_args_helper (T *p_instance, void (T::*p_method)(P...), const Variant **p_args, GDExtensionCallError &r_error, IndexSequence<Is...>) {
233274 r_error.error = GDEXTENSION_CALL_OK;
@@ -470,6 +511,248 @@ void call_with_variant_args_retc_dv(T *p_instance, R (T::*p_method)(P...) const,
470511 call_with_variant_args_retc_helper (p_instance, p_method, argsp.data (), r_ret, r_error, BuildIndexSequence<sizeof ...(P)>{});
471512}
472513
514+ template <typename T, typename ... P, size_t ... Is>
515+ void call_with_variant_args_helper (T *p_instance, std::function<void (const T &, P...)> &p_method, const Variant **p_args, GDExtensionCallError &r_error, IndexSequence<Is...>) {
516+ r_error.error = GDEXTENSION_CALL_OK;
517+
518+ #ifdef DEBUG_METHODS_ENABLED
519+ (p_instance->*p_method)(VariantCasterAndValidate<P>::cast (p_args, Is, r_error)...);
520+ #else
521+ (p_instance->*p_method)(VariantCaster<P>::cast (*p_args[Is])...);
522+ #endif
523+ (void )(p_args); // Avoid warning.
524+ }
525+
526+ template <typename T, typename ... P, size_t ... Is>
527+ void call_with_variant_argsc_helper (T *p_instance, std::function<void (const T &, P...)> &p_method, const Variant **p_args, GDExtensionCallError &r_error, IndexSequence<Is...>) {
528+ r_error.error = GDEXTENSION_CALL_OK;
529+
530+ #ifdef DEBUG_METHODS_ENABLED
531+ (p_instance->*p_method)(VariantCasterAndValidate<P>::cast (p_args, Is, r_error)...);
532+ #else
533+ (p_instance->*p_method)(VariantCaster<P>::cast (*p_args[Is])...);
534+ #endif
535+ (void )(p_args); // Avoid warning.
536+ }
537+
538+ template <typename T, typename R, typename ... P, size_t ... Is>
539+ void call_with_variant_args_ret_helper (T *p_instance, std::function<R (T &, P...)> &p_method, const Variant **p_args, Variant &r_ret, GDExtensionCallError &r_error, IndexSequence<Is...>) {
540+ r_error.error = GDEXTENSION_CALL_OK;
541+
542+ #ifdef DEBUG_METHODS_ENABLED
543+ r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast (p_args, Is, r_error)...);
544+ #else
545+ r_ret = (p_instance->*p_method)(VariantCaster<P>::cast (*p_args[Is])...);
546+ #endif
547+ (void )p_args; // Avoid warning.
548+ }
549+
550+ template <typename T, typename R, typename ... P, size_t ... Is>
551+ void call_with_variant_args_retc_helper (T *p_instance, std::function<R (const T &, P...)> &p_method, const Variant **p_args, Variant &r_ret, GDExtensionCallError &r_error, IndexSequence<Is...>) {
552+ r_error.error = GDEXTENSION_CALL_OK;
553+
554+ #ifdef DEBUG_METHODS_ENABLED
555+ r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast (p_args, Is, r_error)...);
556+ #else
557+ r_ret = (p_instance->*p_method)(VariantCaster<P>::cast (*p_args[Is])...);
558+ #endif
559+ (void )p_args; // Avoid warning.
560+ }
561+
562+ template <typename T, typename ... P>
563+ void call_with_variant_args (T *p_instance, std::function<void (T &, P...)> &p_method, const Variant **p_args, int p_argcount, GDExtensionCallError &r_error) {
564+ #ifdef DEBUG_ENABLED
565+ if ((size_t )p_argcount > sizeof ...(P)) {
566+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
567+ r_error.expected = (int32_t )sizeof ...(P);
568+ return ;
569+ }
570+
571+ if ((size_t )p_argcount < sizeof ...(P)) {
572+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
573+ r_error.expected = (int32_t )sizeof ...(P);
574+ return ;
575+ }
576+ #endif
577+ call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof ...(P)>{});
578+ }
579+
580+ template <typename T, typename R, typename ... P>
581+ void call_with_variant_args_ret (T *p_instance, std::function<R (T &, P...)> &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error) {
582+ #ifdef DEBUG_ENABLED
583+ if ((size_t )p_argcount > sizeof ...(P)) {
584+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
585+ r_error.expected = (int32_t )sizeof ...(P);
586+ return ;
587+ }
588+
589+ if ((size_t )p_argcount < sizeof ...(P)) {
590+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
591+ r_error.expected = (int32_t )sizeof ...(P);
592+ return ;
593+ }
594+ #endif
595+ call_with_variant_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof ...(P)>{});
596+ }
597+
598+ template <typename T, typename R, typename ... P>
599+ void call_with_variant_args_retc (T *p_instance, std::function<R (const T &, P...)> &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error) {
600+ #ifdef DEBUG_ENABLED
601+ if ((size_t )p_argcount > sizeof ...(P)) {
602+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
603+ r_error.expected = (int32_t )sizeof ...(P);
604+ return ;
605+ }
606+
607+ if ((size_t )p_argcount < sizeof ...(P)) {
608+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
609+ r_error.expected = (int32_t )sizeof ...(P);
610+ return ;
611+ }
612+ #endif
613+ call_with_variant_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof ...(P)>{});
614+ }
615+
616+ template <typename T, typename ... P>
617+ void call_with_variant_args_dv (T *p_instance, std::function<void (T &, P...)> &p_method, const GDExtensionConstVariantPtr *p_args, int p_argcount, GDExtensionCallError &r_error, const LocalVector<Variant> &default_values) {
618+ #ifdef DEBUG_ENABLED
619+ if ((size_t )p_argcount > sizeof ...(P)) {
620+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
621+ r_error.expected = (int32_t )sizeof ...(P);
622+ return ;
623+ }
624+ #endif
625+
626+ int32_t missing = (int32_t )sizeof ...(P) - (int32_t )p_argcount;
627+
628+ int32_t dvs = (int32_t )default_values.size ();
629+ #ifdef DEBUG_ENABLED
630+ if (missing > dvs) {
631+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
632+ r_error.expected = (int32_t )sizeof ...(P);
633+ return ;
634+ }
635+ #endif
636+
637+ Variant args[sizeof ...(P) == 0 ? 1 : sizeof ...(P)]; // Avoid zero sized array.
638+ std::array<const Variant *, sizeof ...(P)> argsp;
639+ for (int32_t i = 0 ; i < (int32_t )sizeof ...(P); i++) {
640+ if (i < p_argcount) {
641+ args[i] = Variant (p_args[i]);
642+ } else {
643+ args[i] = default_values[i - p_argcount + (dvs - missing)];
644+ }
645+ argsp[i] = &args[i];
646+ }
647+
648+ call_with_variant_args_helper (p_instance, p_method, argsp.data (), r_error, BuildIndexSequence<sizeof ...(P)>{});
649+ }
650+
651+ template <typename T, typename ... P>
652+ void call_with_variant_argsc_dv (T *p_instance, std::function<void (const T &, P...)> &p_method, const GDExtensionConstVariantPtr *p_args, int p_argcount, GDExtensionCallError &r_error, const LocalVector<Variant> &default_values) {
653+ #ifdef DEBUG_ENABLED
654+ if ((size_t )p_argcount > sizeof ...(P)) {
655+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
656+ r_error.expected = (int32_t )sizeof ...(P);
657+ return ;
658+ }
659+ #endif
660+
661+ int32_t missing = (int32_t )sizeof ...(P) - (int32_t )p_argcount;
662+
663+ int32_t dvs = (int32_t )default_values.size ();
664+ #ifdef DEBUG_ENABLED
665+ if (missing > dvs) {
666+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
667+ r_error.expected = (int32_t )sizeof ...(P);
668+ return ;
669+ }
670+ #endif
671+
672+ Variant args[sizeof ...(P) == 0 ? 1 : sizeof ...(P)]; // Avoid zero sized array.
673+ std::array<const Variant *, sizeof ...(P)> argsp;
674+ for (int32_t i = 0 ; i < (int32_t )sizeof ...(P); i++) {
675+ if (i < p_argcount) {
676+ args[i] = Variant (p_args[i]);
677+ } else {
678+ args[i] = default_values[i - p_argcount + (dvs - missing)];
679+ }
680+ argsp[i] = &args[i];
681+ }
682+
683+ call_with_variant_argsc_helper (p_instance, p_method, argsp.data (), r_error, BuildIndexSequence<sizeof ...(P)>{});
684+ }
685+
686+ template <typename T, typename R, typename ... P>
687+ void call_with_variant_args_ret_dv (T *p_instance, std::function<R (T &, P...)> &p_method, const GDExtensionConstVariantPtr *p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error, const LocalVector<Variant> &default_values) {
688+ #ifdef DEBUG_ENABLED
689+ if ((size_t )p_argcount > sizeof ...(P)) {
690+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
691+ r_error.expected = (int32_t )sizeof ...(P);
692+ return ;
693+ }
694+ #endif
695+
696+ int32_t missing = (int32_t )sizeof ...(P) - (int32_t )p_argcount;
697+
698+ int32_t dvs = (int32_t )default_values.size ();
699+ #ifdef DEBUG_ENABLED
700+ if (missing > dvs) {
701+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
702+ r_error.expected = (int32_t )sizeof ...(P);
703+ return ;
704+ }
705+ #endif
706+
707+ Variant args[sizeof ...(P) == 0 ? 1 : sizeof ...(P)]; // Avoid zero sized array.
708+ std::array<const Variant *, sizeof ...(P)> argsp;
709+ for (int32_t i = 0 ; i < (int32_t )sizeof ...(P); i++) {
710+ if (i < p_argcount) {
711+ args[i] = Variant (p_args[i]);
712+ } else {
713+ args[i] = default_values[i - p_argcount + (dvs - missing)];
714+ }
715+ argsp[i] = &args[i];
716+ }
717+
718+ call_with_variant_args_ret_helper (p_instance, p_method, argsp.data (), r_ret, r_error, BuildIndexSequence<sizeof ...(P)>{});
719+ }
720+
721+ template <typename T, typename R, typename ... P>
722+ void call_with_variant_args_retc_dv (T *p_instance, std::function<R (const T &, P...)> &p_method, const GDExtensionConstVariantPtr *p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error, const LocalVector<Variant> &default_values) {
723+ #ifdef DEBUG_ENABLED
724+ if ((size_t )p_argcount > sizeof ...(P)) {
725+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
726+ r_error.expected = (int32_t )sizeof ...(P);
727+ return ;
728+ }
729+ #endif
730+
731+ int32_t missing = (int32_t )sizeof ...(P) - (int32_t )p_argcount;
732+
733+ int32_t dvs = (int32_t )default_values.size ();
734+ #ifdef DEBUG_ENABLED
735+ if (missing > dvs) {
736+ r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
737+ r_error.expected = (int32_t )sizeof ...(P);
738+ return ;
739+ }
740+ #endif
741+
742+ Variant args[sizeof ...(P) == 0 ? 1 : sizeof ...(P)]; // Avoid zero sized array.
743+ std::array<const Variant *, sizeof ...(P)> argsp;
744+ for (int32_t i = 0 ; i < (int32_t )sizeof ...(P); i++) {
745+ if (i < p_argcount) {
746+ args[i] = Variant (p_args[i]);
747+ } else {
748+ args[i] = default_values[i - p_argcount + (dvs - missing)];
749+ }
750+ argsp[i] = &args[i];
751+ }
752+
753+ call_with_variant_args_retc_helper (p_instance, p_method, argsp.data (), r_ret, r_error, BuildIndexSequence<sizeof ...(P)>{});
754+ }
755+
473756// GCC raises "parameter 'p_args' set but not used" when P = {},
474757// it's not clever enough to treat other P values as making this branch valid.
475758#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
0 commit comments