method_bind.h 28 KB

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