method_bind.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. /**************************************************************************/
  2. /* method_bind.h */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #pragma once
  31. #include "core/variant/binder_common.h"
  32. VARIANT_BITFIELD_CAST(MethodFlags)
  33. // some helpers
  34. class MethodBind {
  35. int method_id;
  36. uint32_t hint_flags = METHOD_FLAGS_DEFAULT;
  37. StringName name;
  38. StringName instance_class;
  39. Vector<Variant> default_arguments;
  40. int default_argument_count = 0;
  41. int argument_count = 0;
  42. bool _static = false;
  43. bool _const = false;
  44. bool _returns = false;
  45. bool _returns_raw_obj_ptr = false;
  46. protected:
  47. Variant::Type *argument_types = nullptr;
  48. #ifdef DEBUG_METHODS_ENABLED
  49. Vector<StringName> arg_names;
  50. #endif
  51. void _set_const(bool p_const);
  52. void _set_static(bool p_static);
  53. void _set_returns(bool p_returns);
  54. virtual Variant::Type _gen_argument_type(int p_arg) const = 0;
  55. virtual PropertyInfo _gen_argument_type_info(int p_arg) const = 0;
  56. void _generate_argument_types(int p_count);
  57. void set_argument_count(int p_count) { argument_count = p_count; }
  58. public:
  59. _FORCE_INLINE_ const Vector<Variant> &get_default_arguments() const { return default_arguments; }
  60. _FORCE_INLINE_ int get_default_argument_count() const { return default_argument_count; }
  61. _FORCE_INLINE_ Variant has_default_argument(int p_arg) const {
  62. int idx = p_arg - (argument_count - default_arguments.size());
  63. if (idx < 0 || idx >= default_arguments.size()) {
  64. return false;
  65. } else {
  66. return true;
  67. }
  68. }
  69. _FORCE_INLINE_ Variant get_default_argument(int p_arg) const {
  70. int idx = p_arg - (argument_count - default_arguments.size());
  71. if (idx < 0 || idx >= default_arguments.size()) {
  72. return Variant();
  73. } else {
  74. return default_arguments[idx];
  75. }
  76. }
  77. _FORCE_INLINE_ Variant::Type get_argument_type(int p_argument) const {
  78. ERR_FAIL_COND_V(p_argument < -1 || p_argument >= argument_count, Variant::NIL);
  79. return argument_types[p_argument + 1];
  80. }
  81. PropertyInfo get_argument_info(int p_argument) const;
  82. PropertyInfo get_return_info() const;
  83. #ifdef DEBUG_METHODS_ENABLED
  84. void set_argument_names(const Vector<StringName> &p_names); // Set by ClassDB, can't be inferred otherwise.
  85. Vector<StringName> get_argument_names() const;
  86. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const = 0;
  87. #endif
  88. void set_hint_flags(uint32_t p_hint) { hint_flags = p_hint; }
  89. uint32_t get_hint_flags() const { return hint_flags | (is_const() ? METHOD_FLAG_CONST : 0) | (is_vararg() ? METHOD_FLAG_VARARG : 0) | (is_static() ? METHOD_FLAG_STATIC : 0); }
  90. _FORCE_INLINE_ StringName get_instance_class() const { return instance_class; }
  91. _FORCE_INLINE_ void set_instance_class(const StringName &p_class) { instance_class = p_class; }
  92. _FORCE_INLINE_ int get_argument_count() const { return argument_count; }
  93. #ifdef TOOLS_ENABLED
  94. virtual bool is_valid() const { return true; }
  95. #endif
  96. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const = 0;
  97. virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const = 0;
  98. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const = 0;
  99. StringName get_name() const;
  100. void set_name(const StringName &p_name);
  101. _FORCE_INLINE_ int get_method_id() const { return method_id; }
  102. _FORCE_INLINE_ bool is_const() const { return _const; }
  103. _FORCE_INLINE_ bool is_static() const { return _static; }
  104. _FORCE_INLINE_ bool has_return() const { return _returns; }
  105. virtual bool is_vararg() const { return false; }
  106. _FORCE_INLINE_ bool is_return_type_raw_object_ptr() { return _returns_raw_obj_ptr; }
  107. _FORCE_INLINE_ void set_return_type_is_raw_object_ptr(bool p_returns_raw_obj) { _returns_raw_obj_ptr = p_returns_raw_obj; }
  108. void set_default_arguments(const Vector<Variant> &p_defargs);
  109. uint32_t get_hash() const;
  110. MethodBind();
  111. virtual ~MethodBind();
  112. };
  113. // MethodBindVarArg base CRTP
  114. template <typename Derived, typename T, typename R, bool should_returns>
  115. class MethodBindVarArgBase : public MethodBind {
  116. protected:
  117. R(T::*method)
  118. (const Variant **, int, Callable::CallError &);
  119. MethodInfo method_info;
  120. public:
  121. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  122. if (p_arg < 0) {
  123. return _gen_return_type_info();
  124. } else if (p_arg < method_info.arguments.size()) {
  125. return method_info.arguments[p_arg];
  126. } else {
  127. return PropertyInfo(Variant::NIL, "arg_" + itos(p_arg), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT);
  128. }
  129. }
  130. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  131. return _gen_argument_type_info(p_arg).type;
  132. }
  133. #ifdef DEBUG_METHODS_ENABLED
  134. virtual GodotTypeInfo::Metadata get_argument_meta(int) const override {
  135. return GodotTypeInfo::METADATA_NONE;
  136. }
  137. #endif
  138. virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
  139. ERR_FAIL_MSG("Validated call can't be used with vararg methods. This is a bug.");
  140. }
  141. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  142. ERR_FAIL_MSG("ptrcall can't be used with vararg methods. This is a bug.");
  143. }
  144. virtual bool is_const() const { return false; }
  145. virtual bool is_vararg() const override { return true; }
  146. MethodBindVarArgBase(
  147. R (T::*p_method)(const Variant **, int, Callable::CallError &),
  148. const MethodInfo &p_method_info,
  149. bool p_return_nil_is_variant) :
  150. method(p_method), method_info(p_method_info) {
  151. set_argument_count(method_info.arguments.size());
  152. Variant::Type *at = memnew_arr(Variant::Type, method_info.arguments.size() + 1);
  153. at[0] = _gen_return_type_info().type;
  154. if (method_info.arguments.size()) {
  155. #ifdef DEBUG_METHODS_ENABLED
  156. Vector<StringName> names;
  157. names.resize(method_info.arguments.size());
  158. #endif
  159. for (int64_t i = 0; i < method_info.arguments.size(); ++i) {
  160. at[i + 1] = method_info.arguments[i].type;
  161. #ifdef DEBUG_METHODS_ENABLED
  162. names.write[i] = method_info.arguments[i].name;
  163. #endif
  164. }
  165. #ifdef DEBUG_METHODS_ENABLED
  166. set_argument_names(names);
  167. #endif
  168. }
  169. argument_types = at;
  170. if (p_return_nil_is_variant) {
  171. method_info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
  172. }
  173. _set_returns(should_returns);
  174. }
  175. private:
  176. PropertyInfo _gen_return_type_info() const {
  177. return Derived::_gen_return_type_info_impl();
  178. }
  179. };
  180. // variadic, no return
  181. template <typename T>
  182. class MethodBindVarArgT : public MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false> {
  183. friend class MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false>;
  184. public:
  185. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  186. #ifdef TOOLS_ENABLED
  187. ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == MethodBind::get_instance_class(), Variant(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
  188. #endif
  189. (static_cast<T *>(p_object)->*MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false>::method)(p_args, p_arg_count, r_error);
  190. return {};
  191. }
  192. MethodBindVarArgT(
  193. void (T::*p_method)(const Variant **, int, Callable::CallError &),
  194. const MethodInfo &p_method_info,
  195. bool p_return_nil_is_variant) :
  196. MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false>(p_method, p_method_info, p_return_nil_is_variant) {
  197. }
  198. private:
  199. static PropertyInfo _gen_return_type_info_impl() {
  200. return {};
  201. }
  202. };
  203. template <typename T>
  204. MethodBind *create_vararg_method_bind(void (T::*p_method)(const Variant **, int, Callable::CallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
  205. MethodBind *a = memnew((MethodBindVarArgT<T>)(p_method, p_info, p_return_nil_is_variant));
  206. a->set_instance_class(T::get_class_static());
  207. return a;
  208. }
  209. // variadic, return
  210. template <typename T, typename R>
  211. class MethodBindVarArgTR : public MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true> {
  212. friend class MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true>;
  213. public:
  214. #if defined(SANITIZERS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
  215. // Workaround GH-66343 raised only with UBSAN, seems to be a false positive.
  216. #pragma GCC diagnostic push
  217. #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
  218. #endif
  219. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  220. #ifdef TOOLS_ENABLED
  221. ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == MethodBind::get_instance_class(), Variant(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
  222. #endif
  223. return (static_cast<T *>(p_object)->*MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true>::method)(p_args, p_arg_count, r_error);
  224. }
  225. #if defined(SANITIZERS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
  226. #pragma GCC diagnostic pop
  227. #endif
  228. MethodBindVarArgTR(
  229. R (T::*p_method)(const Variant **, int, Callable::CallError &),
  230. const MethodInfo &p_info,
  231. bool p_return_nil_is_variant) :
  232. MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true>(p_method, p_info, p_return_nil_is_variant) {
  233. }
  234. private:
  235. static PropertyInfo _gen_return_type_info_impl() {
  236. return GetTypeInfo<R>::get_class_info();
  237. }
  238. };
  239. template <typename T, typename R>
  240. MethodBind *create_vararg_method_bind(R (T::*p_method)(const Variant **, int, Callable::CallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
  241. MethodBind *a = memnew((MethodBindVarArgTR<T, R>)(p_method, p_info, p_return_nil_is_variant));
  242. a->set_instance_class(T::get_class_static());
  243. return a;
  244. }
  245. /**** VARIADIC TEMPLATES ****/
  246. #ifndef TYPED_METHOD_BIND
  247. class __UnexistingClass;
  248. #define MB_T __UnexistingClass
  249. #else
  250. #define MB_T T
  251. #endif
  252. // no return, not const
  253. #ifdef TYPED_METHOD_BIND
  254. template <typename T, typename... P>
  255. #else
  256. template <typename... P>
  257. #endif
  258. class MethodBindT : public MethodBind {
  259. void (MB_T::*method)(P...);
  260. protected:
  261. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  262. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  263. return call_get_argument_type<P...>(p_arg);
  264. } else {
  265. return Variant::NIL;
  266. }
  267. }
  268. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  269. PropertyInfo pi;
  270. call_get_argument_type_info<P...>(p_arg, pi);
  271. return pi;
  272. }
  273. public:
  274. #ifdef DEBUG_METHODS_ENABLED
  275. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  276. return call_get_argument_metadata<P...>(p_arg);
  277. }
  278. #endif
  279. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  280. #ifdef TOOLS_ENABLED
  281. ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), Variant(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
  282. #endif
  283. #ifdef TYPED_METHOD_BIND
  284. call_with_variant_args_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
  285. #else
  286. call_with_variant_args_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
  287. #endif
  288. return Variant();
  289. }
  290. virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
  291. #ifdef TOOLS_ENABLED
  292. ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
  293. #endif
  294. #ifdef TYPED_METHOD_BIND
  295. call_with_validated_object_instance_args(static_cast<T *>(p_object), method, p_args);
  296. #else
  297. call_with_validated_object_instance_args(reinterpret_cast<MB_T *>(p_object), method, p_args);
  298. #endif
  299. }
  300. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  301. #ifdef TOOLS_ENABLED
  302. ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
  303. #endif
  304. #ifdef TYPED_METHOD_BIND
  305. call_with_ptr_args<T, P...>(static_cast<T *>(p_object), method, p_args);
  306. #else
  307. call_with_ptr_args<MB_T, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args);
  308. #endif
  309. }
  310. MethodBindT(void (MB_T::*p_method)(P...)) {
  311. method = p_method;
  312. _generate_argument_types(sizeof...(P));
  313. set_argument_count(sizeof...(P));
  314. }
  315. };
  316. template <typename T, typename... P>
  317. MethodBind *create_method_bind(void (T::*p_method)(P...)) {
  318. #ifdef TYPED_METHOD_BIND
  319. MethodBind *a = memnew((MethodBindT<T, P...>)(p_method));
  320. #else
  321. MethodBind *a = memnew((MethodBindT<P...>)(reinterpret_cast<void (MB_T::*)(P...)>(p_method)));
  322. #endif
  323. a->set_instance_class(T::get_class_static());
  324. return a;
  325. }
  326. // no return, const
  327. #ifdef TYPED_METHOD_BIND
  328. template <typename T, typename... P>
  329. #else
  330. template <typename... P>
  331. #endif
  332. class MethodBindTC : public MethodBind {
  333. void (MB_T::*method)(P...) const;
  334. protected:
  335. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  336. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  337. return call_get_argument_type<P...>(p_arg);
  338. } else {
  339. return Variant::NIL;
  340. }
  341. }
  342. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  343. PropertyInfo pi;
  344. call_get_argument_type_info<P...>(p_arg, pi);
  345. return pi;
  346. }
  347. public:
  348. #ifdef DEBUG_METHODS_ENABLED
  349. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  350. return call_get_argument_metadata<P...>(p_arg);
  351. }
  352. #endif
  353. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  354. #ifdef TOOLS_ENABLED
  355. ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), Variant(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
  356. #endif
  357. #ifdef TYPED_METHOD_BIND
  358. call_with_variant_argsc_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
  359. #else
  360. call_with_variant_argsc_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
  361. #endif
  362. return Variant();
  363. }
  364. virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
  365. #ifdef TOOLS_ENABLED
  366. ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
  367. #endif
  368. #ifdef TYPED_METHOD_BIND
  369. call_with_validated_object_instance_argsc(static_cast<T *>(p_object), method, p_args);
  370. #else
  371. call_with_validated_object_instance_argsc(reinterpret_cast<MB_T *>(p_object), method, p_args);
  372. #endif
  373. }
  374. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  375. #ifdef TOOLS_ENABLED
  376. ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
  377. #endif
  378. #ifdef TYPED_METHOD_BIND
  379. call_with_ptr_argsc<T, P...>(static_cast<T *>(p_object), method, p_args);
  380. #else
  381. call_with_ptr_argsc<MB_T, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args);
  382. #endif
  383. }
  384. MethodBindTC(void (MB_T::*p_method)(P...) const) {
  385. method = p_method;
  386. _set_const(true);
  387. _generate_argument_types(sizeof...(P));
  388. set_argument_count(sizeof...(P));
  389. }
  390. };
  391. template <typename T, typename... P>
  392. MethodBind *create_method_bind(void (T::*p_method)(P...) const) {
  393. #ifdef TYPED_METHOD_BIND
  394. MethodBind *a = memnew((MethodBindTC<T, P...>)(p_method));
  395. #else
  396. MethodBind *a = memnew((MethodBindTC<P...>)(reinterpret_cast<void (MB_T::*)(P...) const>(p_method)));
  397. #endif
  398. a->set_instance_class(T::get_class_static());
  399. return a;
  400. }
  401. // return, not const
  402. #ifdef TYPED_METHOD_BIND
  403. template <typename T, typename R, typename... P>
  404. #else
  405. template <typename R, typename... P>
  406. #endif
  407. class MethodBindTR : public MethodBind {
  408. R(MB_T::*method)
  409. (P...);
  410. protected:
  411. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  412. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  413. return call_get_argument_type<P...>(p_arg);
  414. } else {
  415. return GetTypeInfo<R>::VARIANT_TYPE;
  416. }
  417. }
  418. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  419. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  420. PropertyInfo pi;
  421. call_get_argument_type_info<P...>(p_arg, pi);
  422. return pi;
  423. } else {
  424. return GetTypeInfo<R>::get_class_info();
  425. }
  426. }
  427. public:
  428. #ifdef DEBUG_METHODS_ENABLED
  429. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  430. if (p_arg >= 0) {
  431. return call_get_argument_metadata<P...>(p_arg);
  432. } else {
  433. return GetTypeInfo<R>::METADATA;
  434. }
  435. }
  436. #endif
  437. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  438. Variant ret;
  439. #ifdef TOOLS_ENABLED
  440. ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), ret, vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
  441. #endif
  442. #ifdef TYPED_METHOD_BIND
  443. call_with_variant_args_ret_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
  444. #else
  445. call_with_variant_args_ret_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
  446. #endif
  447. return ret;
  448. }
  449. virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
  450. #ifdef TOOLS_ENABLED
  451. ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
  452. #endif
  453. #ifdef TYPED_METHOD_BIND
  454. call_with_validated_object_instance_args_ret(static_cast<T *>(p_object), method, p_args, r_ret);
  455. #else
  456. call_with_validated_object_instance_args_ret(reinterpret_cast<MB_T *>(p_object), method, p_args, r_ret);
  457. #endif
  458. }
  459. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  460. #ifdef TOOLS_ENABLED
  461. ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
  462. #endif
  463. #ifdef TYPED_METHOD_BIND
  464. call_with_ptr_args_ret<T, R, P...>(static_cast<T *>(p_object), method, p_args, r_ret);
  465. #else
  466. call_with_ptr_args_ret<MB_T, R, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args, r_ret);
  467. #endif
  468. }
  469. MethodBindTR(R (MB_T::*p_method)(P...)) {
  470. method = p_method;
  471. _set_returns(true);
  472. _generate_argument_types(sizeof...(P));
  473. set_argument_count(sizeof...(P));
  474. }
  475. };
  476. template <typename T, typename R, typename... P>
  477. MethodBind *create_method_bind(R (T::*p_method)(P...)) {
  478. #ifdef TYPED_METHOD_BIND
  479. MethodBind *a = memnew((MethodBindTR<T, R, P...>)(p_method));
  480. #else
  481. MethodBind *a = memnew((MethodBindTR<R, P...>)(reinterpret_cast<R (MB_T::*)(P...)>(p_method)));
  482. #endif
  483. a->set_instance_class(T::get_class_static());
  484. return a;
  485. }
  486. // return, const
  487. #ifdef TYPED_METHOD_BIND
  488. template <typename T, typename R, typename... P>
  489. #else
  490. template <typename R, typename... P>
  491. #endif
  492. class MethodBindTRC : public MethodBind {
  493. R(MB_T::*method)
  494. (P...) const;
  495. protected:
  496. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  497. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  498. return call_get_argument_type<P...>(p_arg);
  499. } else {
  500. return GetTypeInfo<R>::VARIANT_TYPE;
  501. }
  502. }
  503. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  504. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  505. PropertyInfo pi;
  506. call_get_argument_type_info<P...>(p_arg, pi);
  507. return pi;
  508. } else {
  509. return GetTypeInfo<R>::get_class_info();
  510. }
  511. }
  512. public:
  513. #ifdef DEBUG_METHODS_ENABLED
  514. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  515. if (p_arg >= 0) {
  516. return call_get_argument_metadata<P...>(p_arg);
  517. } else {
  518. return GetTypeInfo<R>::METADATA;
  519. }
  520. }
  521. #endif
  522. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  523. Variant ret;
  524. #ifdef TOOLS_ENABLED
  525. ERR_FAIL_COND_V_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), ret, vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
  526. #endif
  527. #ifdef TYPED_METHOD_BIND
  528. call_with_variant_args_retc_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
  529. #else
  530. call_with_variant_args_retc_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
  531. #endif
  532. return ret;
  533. }
  534. virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
  535. #ifdef TOOLS_ENABLED
  536. ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
  537. #endif
  538. #ifdef TYPED_METHOD_BIND
  539. call_with_validated_object_instance_args_retc(static_cast<T *>(p_object), method, p_args, r_ret);
  540. #else
  541. call_with_validated_object_instance_args_retc(reinterpret_cast<MB_T *>(p_object), method, p_args, r_ret);
  542. #endif
  543. }
  544. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  545. #ifdef TOOLS_ENABLED
  546. ERR_FAIL_COND_MSG(p_object && p_object->is_extension_placeholder() && p_object->get_class_name() == get_instance_class(), vformat("Cannot call method bind '%s' on placeholder instance.", MethodBind::get_name()));
  547. #endif
  548. #ifdef TYPED_METHOD_BIND
  549. call_with_ptr_args_retc<T, R, P...>(static_cast<T *>(p_object), method, p_args, r_ret);
  550. #else
  551. call_with_ptr_args_retc<MB_T, R, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args, r_ret);
  552. #endif
  553. }
  554. MethodBindTRC(R (MB_T::*p_method)(P...) const) {
  555. method = p_method;
  556. _set_returns(true);
  557. _set_const(true);
  558. _generate_argument_types(sizeof...(P));
  559. set_argument_count(sizeof...(P));
  560. }
  561. };
  562. template <typename T, typename R, typename... P>
  563. MethodBind *create_method_bind(R (T::*p_method)(P...) const) {
  564. #ifdef TYPED_METHOD_BIND
  565. MethodBind *a = memnew((MethodBindTRC<T, R, P...>)(p_method));
  566. #else
  567. MethodBind *a = memnew((MethodBindTRC<R, P...>)(reinterpret_cast<R (MB_T::*)(P...) const>(p_method)));
  568. #endif
  569. a->set_instance_class(T::get_class_static());
  570. return a;
  571. }
  572. /* STATIC BINDS */
  573. // no return
  574. template <typename... P>
  575. class MethodBindTS : public MethodBind {
  576. void (*function)(P...);
  577. protected:
  578. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  579. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  580. return call_get_argument_type<P...>(p_arg);
  581. } else {
  582. return Variant::NIL;
  583. }
  584. }
  585. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  586. PropertyInfo pi;
  587. call_get_argument_type_info<P...>(p_arg, pi);
  588. return pi;
  589. }
  590. public:
  591. #ifdef DEBUG_METHODS_ENABLED
  592. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  593. return call_get_argument_metadata<P...>(p_arg);
  594. }
  595. #endif
  596. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  597. (void)p_object; // unused
  598. call_with_variant_args_static_dv(function, p_args, p_arg_count, r_error, get_default_arguments());
  599. return Variant();
  600. }
  601. virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
  602. call_with_validated_variant_args_static_method(function, p_args);
  603. }
  604. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  605. (void)p_object;
  606. (void)r_ret;
  607. call_with_ptr_args_static_method(function, p_args);
  608. }
  609. MethodBindTS(void (*p_function)(P...)) {
  610. function = p_function;
  611. _generate_argument_types(sizeof...(P));
  612. set_argument_count(sizeof...(P));
  613. _set_static(true);
  614. }
  615. };
  616. template <typename... P>
  617. MethodBind *create_static_method_bind(void (*p_method)(P...)) {
  618. MethodBind *a = memnew((MethodBindTS<P...>)(p_method));
  619. return a;
  620. }
  621. // return
  622. template <typename R, typename... P>
  623. class MethodBindTRS : public MethodBind {
  624. R(*function)
  625. (P...);
  626. protected:
  627. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  628. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  629. return call_get_argument_type<P...>(p_arg);
  630. } else {
  631. return GetTypeInfo<R>::VARIANT_TYPE;
  632. }
  633. }
  634. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  635. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  636. PropertyInfo pi;
  637. call_get_argument_type_info<P...>(p_arg, pi);
  638. return pi;
  639. } else {
  640. return GetTypeInfo<R>::get_class_info();
  641. }
  642. }
  643. public:
  644. #ifdef DEBUG_METHODS_ENABLED
  645. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  646. if (p_arg >= 0) {
  647. return call_get_argument_metadata<P...>(p_arg);
  648. } else {
  649. return GetTypeInfo<R>::METADATA;
  650. }
  651. }
  652. #endif
  653. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  654. Variant ret;
  655. call_with_variant_args_static_ret_dv(function, p_args, p_arg_count, ret, r_error, get_default_arguments());
  656. return ret;
  657. }
  658. virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
  659. call_with_validated_variant_args_static_method_ret(function, p_args, r_ret);
  660. }
  661. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  662. (void)p_object;
  663. call_with_ptr_args_static_method_ret(function, p_args, r_ret);
  664. }
  665. MethodBindTRS(R (*p_function)(P...)) {
  666. function = p_function;
  667. _generate_argument_types(sizeof...(P));
  668. set_argument_count(sizeof...(P));
  669. _set_static(true);
  670. _set_returns(true);
  671. }
  672. };
  673. template <typename R, typename... P>
  674. MethodBind *create_static_method_bind(R (*p_method)(P...)) {
  675. MethodBind *a = memnew((MethodBindTRS<R, P...>)(p_method));
  676. return a;
  677. }