@@ -2348,9 +2348,17 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
23482348
23492349 int method_bind_count = 0 ;
23502350 for (const MethodInterface &imethod : itype.methods ) {
2351- Error method_err = _generate_cs_method (itype, imethod, method_bind_count, output);
2351+ Error method_err = _generate_cs_method (itype, imethod, method_bind_count, output, false );
23522352 ERR_FAIL_COND_V_MSG (method_err != OK, method_err,
23532353 " Failed to generate method '" + imethod.name + " ' for class '" + itype.name + " '." );
2354+ if (imethod.is_internal ) {
2355+ // No need to generate span overloads for internal methods.
2356+ continue ;
2357+ }
2358+
2359+ method_err = _generate_cs_method (itype, imethod, method_bind_count, output, true );
2360+ ERR_FAIL_COND_V_MSG (method_err != OK, method_err,
2361+ " Failed to generate span overload method '" + imethod.name + " ' for class '" + itype.name + " '." );
23542362 }
23552363
23562364 // Signals
@@ -2776,7 +2784,7 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
27762784 return OK;
27772785}
27782786
2779- Error BindingsGenerator::_generate_cs_method (const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::MethodInterface &p_imethod, int &p_method_bind_count, StringBuilder &p_output) {
2787+ Error BindingsGenerator::_generate_cs_method (const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::MethodInterface &p_imethod, int &p_method_bind_count, StringBuilder &p_output, bool p_use_span ) {
27802788 const TypeInterface *return_type = _get_type_or_singleton_or_null (p_imethod.return_type );
27812789 ERR_FAIL_NULL_V_MSG (return_type, ERR_BUG, " Return type '" + p_imethod.return_type .cname + " ' was not found." );
27822790
@@ -2789,6 +2797,35 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
27892797 " ' from the editor API. Core API cannot have dependencies on the editor API." );
27902798 }
27912799
2800+ if (p_imethod.is_virtual && p_use_span) {
2801+ return OK;
2802+ }
2803+
2804+ bool has_span_argument = false ;
2805+
2806+ if (p_use_span) {
2807+ if (p_imethod.is_vararg ) {
2808+ has_span_argument = true ;
2809+ } else {
2810+ for (const ArgumentInterface &iarg : p_imethod.arguments ) {
2811+ const TypeInterface *arg_type = _get_type_or_singleton_or_null (iarg.type );
2812+ ERR_FAIL_NULL_V_MSG (arg_type, ERR_BUG, " Argument type '" + iarg.type .cname + " ' was not found." );
2813+
2814+ if (arg_type->is_span_compatible ) {
2815+ has_span_argument = true ;
2816+ break ;
2817+ }
2818+ }
2819+ }
2820+
2821+ if (has_span_argument) {
2822+ // Span overloads use the same method bind as the array overloads.
2823+ // Since both overloads are generated one after the other, we can decrease the count here
2824+ // to ensure the span overload uses the same method bind.
2825+ p_method_bind_count--;
2826+ }
2827+ }
2828+
27922829 String method_bind_field = CS_STATIC_FIELD_METHOD_BIND_PREFIX + itos (p_method_bind_count);
27932830
27942831 String arguments_sig;
@@ -2835,6 +2872,8 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
28352872
28362873 String arg_cs_type = arg_type->cs_type + _get_generic_type_parameters (*arg_type, iarg.type .generic_type_parameters );
28372874
2875+ bool use_span_for_arg = p_use_span && arg_type->is_span_compatible ;
2876+
28382877 // Add the current arguments to the signature
28392878 // If the argument has a default value which is not a constant, we will make it Nullable
28402879 {
@@ -2846,7 +2885,11 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
28462885 arguments_sig += " Nullable<" ;
28472886 }
28482887
2849- arguments_sig += arg_cs_type;
2888+ if (use_span_for_arg) {
2889+ arguments_sig += arg_type->c_type_in ;
2890+ } else {
2891+ arguments_sig += arg_cs_type;
2892+ }
28502893
28512894 if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL) {
28522895 arguments_sig += " > " ;
@@ -2856,7 +2899,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
28562899
28572900 arguments_sig += iarg.name ;
28582901
2859- if (!p_imethod.is_compat && iarg.default_argument .size ()) {
2902+ if (!p_use_span && ! p_imethod.is_compat && iarg.default_argument .size ()) {
28602903 if (iarg.def_param_mode != ArgumentInterface::CONSTANT) {
28612904 arguments_sig += " = null" ;
28622905 } else {
@@ -2867,7 +2910,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
28672910
28682911 icall_params += " , " ;
28692912
2870- if (iarg.default_argument .size () && iarg.def_param_mode != ArgumentInterface::CONSTANT) {
2913+ if (iarg.default_argument .size () && iarg.def_param_mode != ArgumentInterface::CONSTANT && !use_span_for_arg ) {
28712914 // The default value of an argument must be constant. Otherwise we make it Nullable and do the following:
28722915 // Type arg_in = arg.HasValue ? arg.Value : <non-const default value>;
28732916 String arg_or_defval_local = iarg.name ;
@@ -2927,14 +2970,18 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
29272970 cs_in_expr_is_unsafe |= arg_type->cs_in_expr_is_unsafe ;
29282971 }
29292972
2973+ if (p_use_span && !has_span_argument) {
2974+ return OK;
2975+ }
2976+
29302977 // Collect caller name for MethodBind
29312978 if (p_imethod.is_vararg ) {
29322979 icall_params += " , (godot_string_name)MethodName." + p_imethod.proxy_name + " .NativeValue" ;
29332980 }
29342981
29352982 // Generate method
29362983 {
2937- if (!p_imethod.is_virtual && !p_imethod.requires_object_call ) {
2984+ if (!p_imethod.is_virtual && !p_imethod.requires_object_call && !p_use_span ) {
29382985 p_output << MEMBER_BEGIN " [DebuggerBrowsable(DebuggerBrowsableState.Never)]\n "
29392986 << INDENT1 " private static readonly IntPtr " << method_bind_field << " = " ;
29402987
@@ -4734,13 +4781,14 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
47344781 itype = TypeInterface ();
47354782 itype.name = " VarArg" ;
47364783 itype.cname = itype.name ;
4737- itype.proxy_name = " Variant[] " ;
4784+ itype.proxy_name = " ReadOnlySpan< Variant> " ;
47384785 itype.cs_type = " params Variant[]" ;
4739- itype.cs_in_expr = " %0 ?? Array.Empty<Variant>() " ;
4786+ itype.cs_in_expr = " %0" ;
47404787 // c_type, c_in and c_arg_in are hard-coded in the generator.
47414788 // c_out and c_type_out are not applicable to VarArg.
47424789 itype.c_arg_in = " &%s_in" ;
4743- itype.c_type_in = " Variant[]" ;
4790+ itype.c_type_in = " ReadOnlySpan<Variant>" ;
4791+ itype.is_span_compatible = true ;
47444792 builtin_types.insert (itype.cname , itype);
47454793
47464794#define INSERT_ARRAY_FULL (m_name, m_type, m_managed_type, m_proxy_t ) \
@@ -4754,9 +4802,10 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
47544802 itype.c_out = " %5return " C_METHOD_MONOARRAY_FROM (m_type) " (%1);\n " ; \
47554803 itype.c_arg_in = " &%s_in" ; \
47564804 itype.c_type = #m_managed_type; \
4757- itype.c_type_in = itype. proxy_name ; \
4805+ itype.c_type_in = " ReadOnlySpan< " # m_proxy_t " > " ; \
47584806 itype.c_type_out = itype.proxy_name ; \
47594807 itype.c_type_is_disposable_struct = true ; \
4808+ itype.is_span_compatible = true ; \
47604809 builtin_types.insert (itype.name , itype); \
47614810 }
47624811
0 commit comments