[Method Bind] Add support for default argument values and static method binding. Sync headers.
parent
24e4aeb2c6
commit
031a83b0ea
|
@ -8290,7 +8290,7 @@
|
|||
"hash": 3,
|
||||
"arguments": [
|
||||
{
|
||||
"name": "phi",
|
||||
"name": "angle",
|
||||
"type": "float"
|
||||
}
|
||||
]
|
||||
|
@ -9779,11 +9779,11 @@
|
|||
"hash": 3,
|
||||
"arguments": [
|
||||
{
|
||||
"name": "by_axis",
|
||||
"name": "axis",
|
||||
"type": "Vector3"
|
||||
},
|
||||
{
|
||||
"name": "phi",
|
||||
"name": "angle",
|
||||
"type": "float"
|
||||
}
|
||||
]
|
||||
|
@ -10557,7 +10557,7 @@
|
|||
"hash": 3,
|
||||
"arguments": [
|
||||
{
|
||||
"name": "phi",
|
||||
"name": "angle",
|
||||
"type": "float"
|
||||
}
|
||||
]
|
||||
|
@ -11997,7 +11997,7 @@
|
|||
"type": "Vector3"
|
||||
},
|
||||
{
|
||||
"name": "phi",
|
||||
"name": "angle",
|
||||
"type": "float"
|
||||
}
|
||||
]
|
||||
|
@ -12212,7 +12212,7 @@
|
|||
"type": "Vector3"
|
||||
},
|
||||
{
|
||||
"name": "phi",
|
||||
"name": "angle",
|
||||
"type": "float"
|
||||
}
|
||||
]
|
||||
|
@ -12372,7 +12372,7 @@
|
|||
"type": "Vector3"
|
||||
},
|
||||
{
|
||||
"name": "phi",
|
||||
"name": "angle",
|
||||
"type": "float"
|
||||
}
|
||||
]
|
||||
|
@ -30002,56 +30002,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "set_start_node",
|
||||
"is_const": false,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 134188166,
|
||||
"arguments": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "StringName"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "get_start_node",
|
||||
"is_const": true,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 135338183,
|
||||
"return_value": {
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "set_end_node",
|
||||
"is_const": false,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 134188166,
|
||||
"arguments": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "StringName"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "get_end_node",
|
||||
"is_const": true,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 135338183,
|
||||
"return_value": {
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "set_graph_offset",
|
||||
"is_const": false,
|
||||
|
@ -120220,6 +120170,156 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "MissingNode",
|
||||
"is_refcounted": false,
|
||||
"is_instantiable": true,
|
||||
"inherits": "Node",
|
||||
"api_type": "core",
|
||||
"methods": [
|
||||
{
|
||||
"name": "set_original_class",
|
||||
"is_const": false,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 134188166,
|
||||
"arguments": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "String"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "get_original_class",
|
||||
"is_const": true,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 135338183,
|
||||
"return_value": {
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "set_recording_properties",
|
||||
"is_const": false,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 134188166,
|
||||
"arguments": [
|
||||
{
|
||||
"name": "enable",
|
||||
"type": "bool"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "is_recording_properties",
|
||||
"is_const": true,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 135338183,
|
||||
"return_value": {
|
||||
"type": "bool"
|
||||
}
|
||||
}
|
||||
],
|
||||
"properties": [
|
||||
{
|
||||
"type": "String",
|
||||
"name": "original_class",
|
||||
"setter": "set_original_class",
|
||||
"getter": "get_original_class",
|
||||
"index": -1
|
||||
},
|
||||
{
|
||||
"type": "bool",
|
||||
"name": "recording_properties",
|
||||
"setter": "set_recording_properties",
|
||||
"getter": "is_recording_properties",
|
||||
"index": -1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "MissingResource",
|
||||
"is_refcounted": true,
|
||||
"is_instantiable": true,
|
||||
"inherits": "Resource",
|
||||
"api_type": "core",
|
||||
"methods": [
|
||||
{
|
||||
"name": "set_original_class",
|
||||
"is_const": false,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 134188166,
|
||||
"arguments": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "String"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "get_original_class",
|
||||
"is_const": true,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 135338183,
|
||||
"return_value": {
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "set_recording_properties",
|
||||
"is_const": false,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 134188166,
|
||||
"arguments": [
|
||||
{
|
||||
"name": "enable",
|
||||
"type": "bool"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "is_recording_properties",
|
||||
"is_const": true,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 135338183,
|
||||
"return_value": {
|
||||
"type": "bool"
|
||||
}
|
||||
}
|
||||
],
|
||||
"properties": [
|
||||
{
|
||||
"type": "String",
|
||||
"name": "original_class",
|
||||
"setter": "set_original_class",
|
||||
"getter": "get_original_class",
|
||||
"index": -1
|
||||
},
|
||||
{
|
||||
"type": "bool",
|
||||
"name": "recording_properties",
|
||||
"setter": "set_recording_properties",
|
||||
"getter": "is_recording_properties",
|
||||
"index": -1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "MobileVRInterface",
|
||||
"is_refcounted": true,
|
||||
|
@ -124876,7 +124976,14 @@
|
|||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 134152229
|
||||
"hash": 133279208,
|
||||
"arguments": [
|
||||
{
|
||||
"name": "on_thread",
|
||||
"type": "bool",
|
||||
"default_value": "true"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"signals": [
|
||||
|
@ -130865,6 +130972,24 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "is_process_running",
|
||||
"is_const": true,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 135374120,
|
||||
"return_value": {
|
||||
"type": "bool"
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"name": "pid",
|
||||
"type": "int",
|
||||
"meta": "int32"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "get_process_id",
|
||||
"is_const": true,
|
||||
|
@ -151227,6 +151352,206 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PlaceholderCubemap",
|
||||
"is_refcounted": true,
|
||||
"is_instantiable": true,
|
||||
"inherits": "PlaceholderTextureLayered",
|
||||
"api_type": "core"
|
||||
},
|
||||
{
|
||||
"name": "PlaceholderCubemapArray",
|
||||
"is_refcounted": true,
|
||||
"is_instantiable": true,
|
||||
"inherits": "PlaceholderTextureLayered",
|
||||
"api_type": "core"
|
||||
},
|
||||
{
|
||||
"name": "PlaceholderMaterial",
|
||||
"is_refcounted": true,
|
||||
"is_instantiable": true,
|
||||
"inherits": "Material",
|
||||
"api_type": "core"
|
||||
},
|
||||
{
|
||||
"name": "PlaceholderMesh",
|
||||
"is_refcounted": true,
|
||||
"is_instantiable": true,
|
||||
"inherits": "Mesh",
|
||||
"api_type": "core",
|
||||
"methods": [
|
||||
{
|
||||
"name": "set_aabb",
|
||||
"is_const": false,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 134188166,
|
||||
"arguments": [
|
||||
{
|
||||
"name": "aabb",
|
||||
"type": "AABB"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"properties": [
|
||||
{
|
||||
"type": "AABB",
|
||||
"name": "aabb",
|
||||
"setter": "set_aabb",
|
||||
"getter": "get_aabb",
|
||||
"index": -1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PlaceholderTexture2D",
|
||||
"is_refcounted": true,
|
||||
"is_instantiable": true,
|
||||
"inherits": "Texture2D",
|
||||
"api_type": "core",
|
||||
"methods": [
|
||||
{
|
||||
"name": "set_size",
|
||||
"is_const": false,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 134188166,
|
||||
"arguments": [
|
||||
{
|
||||
"name": "size",
|
||||
"type": "Vector2"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"properties": [
|
||||
{
|
||||
"type": "Vector2i",
|
||||
"name": "size",
|
||||
"setter": "set_size",
|
||||
"getter": "get_size",
|
||||
"index": -1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PlaceholderTexture2DArray",
|
||||
"is_refcounted": true,
|
||||
"is_instantiable": true,
|
||||
"inherits": "PlaceholderTextureLayered",
|
||||
"api_type": "core"
|
||||
},
|
||||
{
|
||||
"name": "PlaceholderTexture3D",
|
||||
"is_refcounted": true,
|
||||
"is_instantiable": true,
|
||||
"inherits": "Texture3D",
|
||||
"api_type": "core",
|
||||
"methods": [
|
||||
{
|
||||
"name": "set_size",
|
||||
"is_const": false,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 134188166,
|
||||
"arguments": [
|
||||
{
|
||||
"name": "size",
|
||||
"type": "Vector3i"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "get_size",
|
||||
"is_const": true,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 135338183,
|
||||
"return_value": {
|
||||
"type": "Vector3i"
|
||||
}
|
||||
}
|
||||
],
|
||||
"properties": [
|
||||
{
|
||||
"type": "Vector3i",
|
||||
"name": "size",
|
||||
"setter": "set_size",
|
||||
"getter": "get_size",
|
||||
"index": -1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PlaceholderTextureLayered",
|
||||
"is_refcounted": true,
|
||||
"is_instantiable": false,
|
||||
"inherits": "TextureLayered",
|
||||
"api_type": "core",
|
||||
"methods": [
|
||||
{
|
||||
"name": "set_size",
|
||||
"is_const": false,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 134188166,
|
||||
"arguments": [
|
||||
{
|
||||
"name": "size",
|
||||
"type": "Vector2i"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "get_size",
|
||||
"is_const": true,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 135338183,
|
||||
"return_value": {
|
||||
"type": "Vector2i"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "set_layers",
|
||||
"is_const": false,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 134188166,
|
||||
"arguments": [
|
||||
{
|
||||
"name": "layers",
|
||||
"type": "int",
|
||||
"meta": "int32"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"properties": [
|
||||
{
|
||||
"type": "Vector2i",
|
||||
"name": "size",
|
||||
"setter": "set_size",
|
||||
"getter": "get_size",
|
||||
"index": -1
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "layers",
|
||||
"setter": "set_layers",
|
||||
"getter": "get_layers",
|
||||
"index": -1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PlaneMesh",
|
||||
"is_refcounted": true,
|
||||
|
@ -176586,6 +176911,17 @@
|
|||
"type": "enum::RenderingDevice.DeviceType"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "get_video_adapter_api_version",
|
||||
"is_const": true,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
"is_virtual": false,
|
||||
"hash": 135338183,
|
||||
"return_value": {
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "make_sphere_mesh",
|
||||
"is_const": false,
|
||||
|
@ -215014,6 +215350,13 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "TextServerFallback",
|
||||
"is_refcounted": true,
|
||||
"is_instantiable": true,
|
||||
"inherits": "TextServerExtension",
|
||||
"api_type": "core"
|
||||
},
|
||||
{
|
||||
"name": "TextServerManager",
|
||||
"is_refcounted": false,
|
||||
|
@ -223084,7 +223427,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"name": "get_datetime_dict_from_string",
|
||||
"name": "get_datetime_dict_from_datetime_string",
|
||||
"is_const": true,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
|
@ -223105,7 +223448,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"name": "get_datetime_string_from_dict",
|
||||
"name": "get_datetime_string_from_datetime_dict",
|
||||
"is_const": true,
|
||||
"is_vararg": false,
|
||||
"is_static": false,
|
||||
|
|
|
@ -440,6 +440,118 @@ GDNativeExtensionClassMethodArgumentMetadata call_get_argument_metadata(int p_ar
|
|||
return md;
|
||||
}
|
||||
|
||||
template <class... P, size_t... Is>
|
||||
void call_with_variant_args_static(void (*p_method)(P...), const Variant **p_args, GDNativeCallError &r_error, IndexSequence<Is...>) {
|
||||
r_error.error = GDNATIVE_CALL_OK;
|
||||
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
(p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
|
||||
#else
|
||||
(p_method)(VariantCaster<P>::cast(*p_args[Is])...);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class... P>
|
||||
void call_with_variant_args_static_dv(void (*p_method)(P...), const GDNativeVariantPtr *p_args, int p_argcount, GDNativeCallError &r_error, const std::vector<Variant> &default_values) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if ((size_t)p_argcount > sizeof...(P)) {
|
||||
r_error.error = GDNATIVE_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_error.argument = sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
|
||||
|
||||
int32_t dvs = default_values.size();
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (missing > dvs) {
|
||||
r_error.error = GDNATIVE_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.argument = sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
Variant args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; // Avoid zero sized array.
|
||||
std::array<const Variant *, sizeof...(P)> argsp;
|
||||
for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
|
||||
if (i < p_argcount) {
|
||||
args[i] = Variant(p_args[i]);
|
||||
} else {
|
||||
args[i] = default_values[i - p_argcount + (dvs - missing)];
|
||||
}
|
||||
argsp[i] = &args[i];
|
||||
}
|
||||
|
||||
call_with_variant_args_static(p_method, argsp.data(), r_error, BuildIndexSequence<sizeof...(P)>{});
|
||||
}
|
||||
|
||||
template <class... P, size_t... Is>
|
||||
void call_with_ptr_args_static_method_helper(void (*p_method)(P...), const GDNativeTypePtr *p_args, IndexSequence<Is...>) {
|
||||
p_method(PtrToArg<P>::convert(p_args[Is])...);
|
||||
}
|
||||
|
||||
template <class... P>
|
||||
void call_with_ptr_args_static_method(void (*p_method)(P...), const GDNativeTypePtr *p_args) {
|
||||
call_with_ptr_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
|
||||
}
|
||||
|
||||
template <class R, class... P, size_t... Is>
|
||||
void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, Variant &r_ret, GDNativeCallError &r_error, IndexSequence<Is...>) {
|
||||
r_error.error = GDNATIVE_CALL_OK;
|
||||
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
r_ret = (p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
|
||||
#else
|
||||
r_ret = (p_method)(VariantCaster<P>::cast(*p_args[Is])...);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class R, class... P>
|
||||
void call_with_variant_args_static_ret_dv(R (*p_method)(P...), const GDNativeVariantPtr *p_args, int p_argcount, Variant &r_ret, GDNativeCallError &r_error, const std::vector<Variant> &default_values) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if ((size_t)p_argcount > sizeof...(P)) {
|
||||
r_error.error = GDNATIVE_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_error.argument = sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
|
||||
|
||||
int32_t dvs = default_values.size();
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (missing > dvs) {
|
||||
r_error.error = GDNATIVE_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.argument = sizeof...(P);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
Variant args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; // Avoid zero sized array.
|
||||
std::array<const Variant *, sizeof...(P)> argsp;
|
||||
for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
|
||||
if (i < p_argcount) {
|
||||
args[i] = Variant(p_args[i]);
|
||||
} else {
|
||||
args[i] = default_values[i - p_argcount + (dvs - missing)];
|
||||
}
|
||||
argsp[i] = &args[i];
|
||||
}
|
||||
|
||||
call_with_variant_args_static_ret(p_method, argsp.data(), r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
|
||||
}
|
||||
|
||||
template <class R, class... P, size_t... Is>
|
||||
void call_with_ptr_args_static_method_ret_helper(R (*p_method)(P...), const GDNativeTypePtr *p_args, void *r_ret, IndexSequence<Is...>) {
|
||||
PtrToArg<R>::encode(p_method(PtrToArg<P>::convert(p_args[Is])...), r_ret);
|
||||
}
|
||||
|
||||
template <class R, class... P>
|
||||
void call_with_ptr_args_static_method_ret(R (*p_method)(P...), const GDNativeTypePtr *p_args, void *r_ret) {
|
||||
call_with_ptr_args_static_method_ret_helper<R, P...>(p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
|
||||
namespace godot {
|
||||
|
||||
#define DEFVAL(m_defval) (m_defval)
|
||||
|
||||
struct MethodDefinition {
|
||||
const char *name = nullptr;
|
||||
std::list<std::string> args;
|
||||
|
@ -101,10 +103,15 @@ public:
|
|||
template <class T>
|
||||
static void register_class();
|
||||
|
||||
template <class N, class M>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method);
|
||||
template <class N, class M, typename... VarArgs>
|
||||
static MethodBind *bind_method(N p_method_name, M p_method, VarArgs... p_args);
|
||||
|
||||
template <class N, class M, typename... VarArgs>
|
||||
static MethodBind *bind_static_method(const char *p_class, N p_method_name, M p_method, VarArgs... p_args);
|
||||
|
||||
template <class M>
|
||||
static MethodBind *bind_vararg_method(uint32_t p_flags, const char *p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const std::vector<Variant> &p_default_args = std::vector<Variant>{}, bool p_return_nil_is_variant = true);
|
||||
|
||||
static void add_property_group(const char *p_class, const char *p_name, const char *p_prefix);
|
||||
static void add_property_subgroup(const char *p_class, const char *p_name, const char *p_prefix);
|
||||
static void add_property(const char *p_class, const PropertyInfo &p_pinfo, const char *p_setter, const char *p_getter, int p_index = -1);
|
||||
|
@ -172,11 +179,27 @@ void ClassDB::register_class() {
|
|||
initialize_class(classes[cl.name]);
|
||||
}
|
||||
|
||||
template <class N, class M>
|
||||
MethodBind *ClassDB::bind_method(N p_method_name, M p_method) {
|
||||
template <class N, class M, typename... VarArgs>
|
||||
MethodBind *ClassDB::bind_method(N p_method_name, M p_method, VarArgs... p_args) {
|
||||
Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
|
||||
const Variant *argptrs[sizeof...(p_args) + 1];
|
||||
for (uint32_t i = 0; i < sizeof...(p_args); i++) {
|
||||
argptrs[i] = &args[i];
|
||||
}
|
||||
MethodBind *bind = create_method_bind(p_method);
|
||||
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const void **)argptrs, sizeof...(p_args));
|
||||
}
|
||||
|
||||
return bind_methodfi(0, bind, p_method_name, nullptr, 0);
|
||||
template <class N, class M, typename... VarArgs>
|
||||
MethodBind *ClassDB::bind_static_method(const char *p_class, N p_method_name, M p_method, VarArgs... p_args) {
|
||||
Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
|
||||
const Variant *argptrs[sizeof...(p_args) + 1];
|
||||
for (uint32_t i = 0; i < sizeof...(p_args); i++) {
|
||||
argptrs[i] = &args[i];
|
||||
}
|
||||
MethodBind *bind = create_static_method_bind(p_method);
|
||||
bind->set_instance_class(p_class);
|
||||
return bind_methodfi(0, bind, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const void **)argptrs, sizeof...(p_args));
|
||||
}
|
||||
|
||||
template <class M>
|
||||
|
|
|
@ -53,8 +53,10 @@ class MethodBind {
|
|||
int argument_count = 0;
|
||||
uint32_t hint_flags = METHOD_FLAGS_DEFAULT;
|
||||
|
||||
bool _static = false;
|
||||
bool _is_const = false;
|
||||
bool _has_return = false;
|
||||
bool _vararg = false;
|
||||
|
||||
std::vector<std::string> argument_names;
|
||||
GDNativeVariantType *argument_types = nullptr;
|
||||
|
@ -66,6 +68,8 @@ protected:
|
|||
void generate_argument_types(int p_count);
|
||||
void set_const(bool p_const);
|
||||
void set_return(bool p_return);
|
||||
void set_static(bool p_static);
|
||||
void set_vararg(bool p_vararg);
|
||||
void set_argument_count(int p_count);
|
||||
|
||||
public:
|
||||
|
@ -96,8 +100,10 @@ public:
|
|||
|
||||
_FORCE_INLINE_ int get_argument_count() const { return argument_count; };
|
||||
_FORCE_INLINE_ bool is_const() const { return _is_const; }
|
||||
_FORCE_INLINE_ bool is_static() const { return _static; }
|
||||
_FORCE_INLINE_ bool is_vararg() const { return _vararg; }
|
||||
_FORCE_INLINE_ bool has_return() const { return _has_return; }
|
||||
_FORCE_INLINE_ uint32_t get_hint_flags() const { return hint_flags; }
|
||||
_FORCE_INLINE_ uint32_t get_hint_flags() const { return hint_flags | (is_const() ? GDNATIVE_EXTENSION_METHOD_FLAG_CONST : 0) | (is_vararg() ? GDNATIVE_EXTENSION_METHOD_FLAG_VARARG : 0) | (is_static() ? GDNATIVE_EXTENSION_METHOD_FLAG_STATIC : 0); }
|
||||
_FORCE_INLINE_ void set_hint_flags(uint32_t p_hint_flags) { hint_flags = p_hint_flags; }
|
||||
void set_argument_names(const std::vector<std::string> &p_names);
|
||||
std::vector<std::string> get_argument_names() const;
|
||||
|
@ -155,15 +161,13 @@ public:
|
|||
ERR_FAIL(); // Can't call.
|
||||
}
|
||||
|
||||
virtual bool is_const() const { return false; }
|
||||
|
||||
virtual bool is_vararg() const { return true; }
|
||||
|
||||
MethodBindVarArgBase(
|
||||
R (T::*p_method)(const Variant **, GDNativeInt, GDNativeCallError &),
|
||||
const MethodInfo &p_method_info,
|
||||
bool p_return_nil_is_variant) :
|
||||
method(p_method), method_info(p_method_info) {
|
||||
set_vararg(true);
|
||||
set_const(true);
|
||||
set_argument_count(method_info.arguments.size());
|
||||
if (method_info.arguments.size()) {
|
||||
std::vector<std::string> names;
|
||||
|
@ -572,6 +576,138 @@ MethodBind *create_method_bind(R (T::*p_method)(P...) const) {
|
|||
return a;
|
||||
}
|
||||
|
||||
// STATIC BINDS
|
||||
|
||||
// no return
|
||||
|
||||
template <class... P>
|
||||
class MethodBindTS : public MethodBind {
|
||||
void (*function)(P...);
|
||||
|
||||
protected:
|
||||
// GCC raises warnings in the case P = {} as the comparison is always false...
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wlogical-op"
|
||||
#endif
|
||||
virtual GDNativeVariantType gen_argument_type(int p_arg) const {
|
||||
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
|
||||
return call_get_argument_type<P...>(p_arg);
|
||||
} else {
|
||||
return GDNATIVE_VARIANT_TYPE_NIL;
|
||||
}
|
||||
}
|
||||
|
||||
virtual GDNativePropertyInfo gen_argument_type_info(int p_arg) const {
|
||||
GDNativePropertyInfo pi;
|
||||
call_get_argument_type_info<P...>(p_arg, pi);
|
||||
return pi;
|
||||
}
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual GDNativeExtensionClassMethodArgumentMetadata get_argument_metadata(int p_arg) const {
|
||||
return call_get_argument_metadata<P...>(p_arg);
|
||||
}
|
||||
|
||||
virtual Variant call(GDExtensionClassInstancePtr p_object, const GDNativeVariantPtr *p_args, const GDNativeInt p_arg_count, GDNativeCallError &r_error) const {
|
||||
(void)p_object; // unused
|
||||
call_with_variant_args_static_dv(function, p_args, p_arg_count, r_error, get_default_arguments());
|
||||
return Variant();
|
||||
}
|
||||
|
||||
virtual void ptrcall(GDExtensionClassInstancePtr p_object, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret) const {
|
||||
(void)p_object;
|
||||
(void)r_ret;
|
||||
call_with_ptr_args_static_method(function, p_args);
|
||||
}
|
||||
|
||||
MethodBindTS(void (*p_function)(P...)) {
|
||||
function = p_function;
|
||||
generate_argument_types(sizeof...(P));
|
||||
set_argument_count(sizeof...(P));
|
||||
set_static(true);
|
||||
}
|
||||
};
|
||||
|
||||
template <class... P>
|
||||
MethodBind *create_static_method_bind(void (*p_method)(P...)) {
|
||||
MethodBind *a = memnew((MethodBindTS<P...>)(p_method));
|
||||
return a;
|
||||
}
|
||||
|
||||
// return
|
||||
|
||||
template <class R, class... P>
|
||||
class MethodBindTRS : public MethodBind {
|
||||
R(*function)
|
||||
(P...);
|
||||
|
||||
protected:
|
||||
// GCC raises warnings in the case P = {} as the comparison is always false...
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wlogical-op"
|
||||
#endif
|
||||
virtual GDNativeVariantType gen_argument_type(int p_arg) const {
|
||||
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
|
||||
return call_get_argument_type<P...>(p_arg);
|
||||
} else {
|
||||
return GetTypeInfo<R>::VARIANT_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
virtual GDNativePropertyInfo gen_argument_type_info(int p_arg) const {
|
||||
if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
|
||||
GDNativePropertyInfo pi;
|
||||
call_get_argument_type_info<P...>(p_arg, pi);
|
||||
return pi;
|
||||
} else {
|
||||
return GetTypeInfo<R>::get_class_info();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual GDNativeExtensionClassMethodArgumentMetadata get_argument_metadata(int p_arg) const {
|
||||
if (p_arg >= 0) {
|
||||
return call_get_argument_metadata<P...>(p_arg);
|
||||
} else {
|
||||
return GetTypeInfo<R>::METADATA;
|
||||
}
|
||||
}
|
||||
|
||||
virtual Variant call(GDExtensionClassInstancePtr p_object, const GDNativeVariantPtr *p_args, const GDNativeInt p_arg_count, GDNativeCallError &r_error) const {
|
||||
Variant ret;
|
||||
call_with_variant_args_static_ret_dv(function, p_args, p_arg_count, ret, r_error, get_default_arguments());
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual void ptrcall(GDExtensionClassInstancePtr p_object, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret) const {
|
||||
(void)p_object;
|
||||
call_with_ptr_args_static_method_ret(function, p_args, r_ret);
|
||||
}
|
||||
|
||||
MethodBindTRS(R (*p_function)(P...)) {
|
||||
function = p_function;
|
||||
generate_argument_types(sizeof...(P));
|
||||
set_argument_count(sizeof...(P));
|
||||
set_static(true);
|
||||
set_return(true);
|
||||
}
|
||||
};
|
||||
|
||||
template <class R, class... P>
|
||||
MethodBind *create_static_method_bind(R (*p_method)(P...)) {
|
||||
MethodBind *a = memnew((MethodBindTRS<R, P...>)(p_method));
|
||||
return a;
|
||||
}
|
||||
|
||||
} // namespace godot
|
||||
|
||||
#endif // ! GODOT_CPP_METHOD_BIND_HPP
|
||||
|
|
|
@ -117,20 +117,20 @@ struct MethodInfo {
|
|||
|
||||
template <class... Args>
|
||||
MethodInfo::MethodInfo(const char *p_name, const Args &...args) :
|
||||
name(p_name), flags(METHOD_FLAG_NORMAL) {
|
||||
name(p_name), flags(GDNATIVE_EXTENSION_METHOD_FLAG_NORMAL) {
|
||||
arguments = { args... };
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
MethodInfo::MethodInfo(Variant::Type ret, const char *p_name, const Args &...args) :
|
||||
name(p_name), flags(METHOD_FLAG_NORMAL) {
|
||||
name(p_name), flags(GDNATIVE_EXTENSION_METHOD_FLAG_NORMAL) {
|
||||
return_val.type = ret;
|
||||
arguments = { args... };
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
MethodInfo::MethodInfo(const PropertyInfo &p_ret, const char *p_name, const Args &...args) :
|
||||
name(p_name), return_val(p_ret), flags(METHOD_FLAG_NORMAL) {
|
||||
name(p_name), return_val(p_ret), flags(GDNATIVE_EXTENSION_METHOD_FLAG_NORMAL) {
|
||||
arguments = { args... };
|
||||
}
|
||||
|
||||
|
|
|
@ -169,6 +169,16 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const M
|
|||
|
||||
p_bind->set_argument_names(args);
|
||||
|
||||
std::vector<Variant> defvals;
|
||||
|
||||
defvals.resize(p_defcount);
|
||||
for (int i = 0; i < p_defcount; i++) {
|
||||
defvals[i] = *static_cast<const Variant *>(p_defs[i]);
|
||||
}
|
||||
|
||||
p_bind->set_default_arguments(defvals);
|
||||
p_bind->set_hint_flags(p_flags);
|
||||
|
||||
// register our method bind within our plugin
|
||||
type.method_map[method_name.name] = p_bind;
|
||||
|
||||
|
@ -179,19 +189,27 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const M
|
|||
}
|
||||
|
||||
void ClassDB::bind_method_godot(const char *p_class_name, MethodBind *p_method) {
|
||||
std::vector<GDNativeVariantPtr> def_args;
|
||||
const std::vector<Variant> &def_args_val = p_method->get_default_arguments();
|
||||
|
||||
def_args.resize(def_args_val.size());
|
||||
for (int i = 0; i < def_args_val.size(); i++) {
|
||||
def_args[i] = (GDNativeVariantPtr)&def_args_val[i];
|
||||
}
|
||||
|
||||
GDNativeExtensionClassMethodInfo method_info = {
|
||||
p_method->get_name(), // const char *name;
|
||||
p_method, // void *method_userdata;
|
||||
MethodBind::bind_call, // GDNativeExtensionClassMethodCall call_func;
|
||||
MethodBind::bind_ptrcall, // GDNativeExtensionClassMethodPtrCall ptrcall_func;
|
||||
GDNATIVE_EXTENSION_METHOD_FLAGS_DEFAULT, //uint32_t method_flags; /* GDNativeExtensionClassMethodFlags */
|
||||
p_method->get_hint_flags(), // uint32_t method_flags; /* GDNativeExtensionClassMethodFlags */
|
||||
(uint32_t)p_method->get_argument_count(), // uint32_t argument_count;
|
||||
(GDNativeBool)p_method->has_return(), // GDNativeBool has_return_value;
|
||||
MethodBind::bind_get_argument_type, //(GDNativeExtensionClassMethodGetArgumentType) get_argument_type_func;
|
||||
MethodBind::bind_get_argument_info, // GDNativeExtensionClassMethodGetArgumentInfo get_argument_info_func; /* name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies. */
|
||||
MethodBind::bind_get_argument_metadata, // GDNativeExtensionClassMethodGetArgumentMetadata get_argument_metadata_func;
|
||||
p_method->get_hint_flags(), //uint32_t default_argument_count;
|
||||
nullptr, //GDNativeVariantPtr *default_arguments;
|
||||
(uint32_t)p_method->get_default_argument_count(), // uint32_t default_argument_count;
|
||||
def_args.data(), // GDNativeVariantPtr *default_arguments;
|
||||
};
|
||||
internal::gdn_interface->classdb_register_extension_class_method(internal::library, p_class_name, &method_info);
|
||||
}
|
||||
|
|
|
@ -52,6 +52,14 @@ void MethodBind::set_return(bool p_return) {
|
|||
_has_return = p_return;
|
||||
}
|
||||
|
||||
void MethodBind::set_static(bool p_static) {
|
||||
_static = p_static;
|
||||
}
|
||||
|
||||
void MethodBind::set_vararg(bool p_vararg) {
|
||||
_vararg = p_vararg;
|
||||
}
|
||||
|
||||
void MethodBind::set_argument_names(const std::vector<std::string> &p_names) {
|
||||
argument_names = p_names;
|
||||
}
|
||||
|
|
|
@ -33,22 +33,22 @@
|
|||
namespace godot {
|
||||
|
||||
MethodInfo::MethodInfo() :
|
||||
flags(METHOD_FLAG_NORMAL) {}
|
||||
flags(GDNATIVE_EXTENSION_METHOD_FLAG_NORMAL) {}
|
||||
|
||||
MethodInfo::MethodInfo(const char *p_name) :
|
||||
name(p_name), flags(METHOD_FLAG_NORMAL) {}
|
||||
name(p_name), flags(GDNATIVE_EXTENSION_METHOD_FLAG_NORMAL) {}
|
||||
|
||||
MethodInfo::MethodInfo(Variant::Type ret) :
|
||||
flags(METHOD_FLAG_NORMAL) {
|
||||
flags(GDNATIVE_EXTENSION_METHOD_FLAG_NORMAL) {
|
||||
return_val.type = ret;
|
||||
}
|
||||
|
||||
MethodInfo::MethodInfo(Variant::Type ret, const char *p_name) :
|
||||
name(p_name), flags(METHOD_FLAG_NORMAL) {
|
||||
name(p_name), flags(GDNATIVE_EXTENSION_METHOD_FLAG_NORMAL) {
|
||||
return_val.type = ret;
|
||||
}
|
||||
|
||||
MethodInfo::MethodInfo(const PropertyInfo &p_ret, const char *p_name) :
|
||||
name(p_name), return_val(p_ret), flags(METHOD_FLAG_NORMAL) {}
|
||||
name(p_name), return_val(p_ret), flags(GDNATIVE_EXTENSION_METHOD_FLAG_NORMAL) {}
|
||||
|
||||
} // namespace godot
|
||||
|
|
|
@ -2,29 +2,46 @@ extends Node
|
|||
|
||||
func _ready():
|
||||
# Bind signals
|
||||
prints("Signal bind")
|
||||
$Button.button_up.connect($Example.emit_custom_signal.bind("Button", 42))
|
||||
|
||||
prints("")
|
||||
|
||||
# Call static methods.
|
||||
prints("Static method calls")
|
||||
prints(" static (109)", Example.test_static(9, 100));
|
||||
Example.test_static2();
|
||||
|
||||
# Call methods.
|
||||
prints("Instance method calls")
|
||||
$Example.simple_func()
|
||||
($Example as Example).simple_const_func() # Force use of ptrcall
|
||||
prints(" returned", $Example.return_something("some string"))
|
||||
prints(" returned const", $Example.return_something_const())
|
||||
prints(" returned ref", $Example.return_extended_ref())
|
||||
|
||||
prints("VarArg method calls")
|
||||
var ref = ExampleRef.new()
|
||||
prints(" sending ref: ", ref.get_instance_id(), "returned ref: ", $Example.extended_ref_checks(ref).get_instance_id())
|
||||
prints(" vararg args", $Example.varargs_func("some", "arguments", "to", "test"))
|
||||
prints(" vararg_nv ret", $Example.varargs_func_nv("some", "arguments", "to", "test"))
|
||||
$Example.varargs_func_void("some", "arguments", "to", "test")
|
||||
|
||||
prints("Method calls with default values")
|
||||
prints(" defval (300)", $Example.def_args())
|
||||
prints(" defval (250)", $Example.def_args(50))
|
||||
prints(" defval (150)", $Example.def_args(50, 100))
|
||||
|
||||
prints("Array and Dictionary")
|
||||
prints(" test array", $Example.test_array())
|
||||
prints(" test dictionary", $Example.test_dictionary())
|
||||
|
||||
# Use properties.
|
||||
prints("Properties")
|
||||
prints(" custom position is", $Example.group_subgroup_custom_position)
|
||||
$Example.group_subgroup_custom_position = Vector2(50, 50)
|
||||
prints(" custom position now is", $Example.group_subgroup_custom_position)
|
||||
|
||||
# Get constants
|
||||
prints("Constnts")
|
||||
prints(" FIRST", $Example.FIRST)
|
||||
prints(" ANSWER_TO_EVERYTHING", $Example.ANSWER_TO_EVERYTHING)
|
||||
prints(" CONSTANT_WITHOUT_ENUM", $Example.CONSTANT_WITHOUT_ENUM)
|
||||
|
|
|
@ -46,6 +46,18 @@ ExampleRef::~ExampleRef() {
|
|||
UtilityFunctions::print("ExampleRef destroyed.");
|
||||
}
|
||||
|
||||
int Example::test_static(int p_a, int p_b) {
|
||||
return p_a + p_b;
|
||||
}
|
||||
|
||||
void Example::test_static2() {
|
||||
UtilityFunctions::print(" void static");
|
||||
}
|
||||
|
||||
int Example::def_args(int p_a, int p_b) {
|
||||
return p_a + p_b;
|
||||
}
|
||||
|
||||
void Example::_bind_methods() {
|
||||
// Methods.
|
||||
ClassDB::bind_method(D_METHOD("simple_func"), &Example::simple_func);
|
||||
|
@ -58,6 +70,11 @@ void Example::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("test_array"), &Example::test_array);
|
||||
ClassDB::bind_method(D_METHOD("test_dictionary"), &Example::test_dictionary);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("def_args", "a", "b"), &Example::def_args, DEFVAL(100), DEFVAL(200));
|
||||
|
||||
ClassDB::bind_static_method("Example", D_METHOD("test_static", "a", "b"), &Example::test_static);
|
||||
ClassDB::bind_static_method("Example", D_METHOD("test_static2"), &Example::test_static2);
|
||||
|
||||
{
|
||||
MethodInfo mi;
|
||||
mi.arguments.push_back(PropertyInfo(Variant::STRING, "some_argument"));
|
||||
|
|
|
@ -90,6 +90,7 @@ public:
|
|||
int varargs_func_nv(const Variant **args, GDNativeInt arg_count, GDNativeCallError &error);
|
||||
void varargs_func_void(const Variant **args, GDNativeInt arg_count, GDNativeCallError &error);
|
||||
void emit_custom_signal(const String &name, int value);
|
||||
int def_args(int p_a = 100, int p_b = 200);
|
||||
|
||||
Array test_array() const;
|
||||
Dictionary test_dictionary() const;
|
||||
|
@ -98,6 +99,10 @@ public:
|
|||
void set_custom_position(const Vector2 &pos);
|
||||
Vector2 get_custom_position() const;
|
||||
|
||||
// Static method.
|
||||
static int test_static(int p_a, int p_b);
|
||||
static void test_static2();
|
||||
|
||||
// Virtual function override (no need to bind manually).
|
||||
virtual bool _has_point(const Vector2 &point) const override;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue