method_bind.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  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. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const = 0;
  95. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const = 0;
  96. StringName get_name() const;
  97. void set_name(const StringName &p_name);
  98. _FORCE_INLINE_ int get_method_id() const { return method_id; }
  99. _FORCE_INLINE_ bool is_const() const { return _const; }
  100. _FORCE_INLINE_ bool is_static() const { return _static; }
  101. _FORCE_INLINE_ bool has_return() const { return _returns; }
  102. virtual bool is_vararg() const { return false; }
  103. _FORCE_INLINE_ bool is_return_type_raw_object_ptr() { return _returns_raw_obj_ptr; }
  104. _FORCE_INLINE_ void set_return_type_is_raw_object_ptr(bool p_returns_raw_obj) { _returns_raw_obj_ptr = p_returns_raw_obj; }
  105. void set_default_arguments(const Vector<Variant> &p_defargs);
  106. uint32_t get_hash() const;
  107. MethodBind();
  108. virtual ~MethodBind();
  109. };
  110. // MethodBindVarArg base CRTP
  111. template <class Derived, class T, class R, bool should_returns>
  112. class MethodBindVarArgBase : public MethodBind {
  113. protected:
  114. R(T::*method)
  115. (const Variant **, int, Callable::CallError &);
  116. MethodInfo method_info;
  117. public:
  118. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  119. if (p_arg < 0) {
  120. return _gen_return_type_info();
  121. } else if (p_arg < method_info.arguments.size()) {
  122. return method_info.arguments[p_arg];
  123. } else {
  124. return PropertyInfo(Variant::NIL, "arg_" + itos(p_arg), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT);
  125. }
  126. }
  127. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  128. return _gen_argument_type_info(p_arg).type;
  129. }
  130. #ifdef DEBUG_METHODS_ENABLED
  131. virtual GodotTypeInfo::Metadata get_argument_meta(int) const override {
  132. return GodotTypeInfo::METADATA_NONE;
  133. }
  134. #endif
  135. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  136. ERR_FAIL(); // Can't call.
  137. }
  138. virtual bool is_const() const { return false; }
  139. virtual bool is_vararg() const override { return true; }
  140. MethodBindVarArgBase(
  141. R (T::*p_method)(const Variant **, int, Callable::CallError &),
  142. const MethodInfo &p_method_info,
  143. bool p_return_nil_is_variant) :
  144. method(p_method), method_info(p_method_info) {
  145. set_argument_count(method_info.arguments.size());
  146. Variant::Type *at = memnew_arr(Variant::Type, method_info.arguments.size() + 1);
  147. at[0] = _gen_return_type_info().type;
  148. if (method_info.arguments.size()) {
  149. #ifdef DEBUG_METHODS_ENABLED
  150. Vector<StringName> names;
  151. names.resize(method_info.arguments.size());
  152. #endif
  153. for (int i = 0; i < method_info.arguments.size(); i++) {
  154. at[i + 1] = method_info.arguments[i].type;
  155. #ifdef DEBUG_METHODS_ENABLED
  156. names.write[i] = method_info.arguments[i].name;
  157. #endif
  158. }
  159. #ifdef DEBUG_METHODS_ENABLED
  160. set_argument_names(names);
  161. #endif
  162. }
  163. argument_types = at;
  164. if (p_return_nil_is_variant) {
  165. method_info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
  166. }
  167. _set_returns(should_returns);
  168. }
  169. private:
  170. PropertyInfo _gen_return_type_info() const {
  171. return Derived::_gen_return_type_info_impl();
  172. }
  173. };
  174. // variadic, no return
  175. template <class T>
  176. class MethodBindVarArgT : public MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false> {
  177. friend class MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false>;
  178. public:
  179. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  180. (static_cast<T *>(p_object)->*MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false>::method)(p_args, p_arg_count, r_error);
  181. return {};
  182. }
  183. MethodBindVarArgT(
  184. void (T::*p_method)(const Variant **, int, Callable::CallError &),
  185. const MethodInfo &p_method_info,
  186. bool p_return_nil_is_variant) :
  187. MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false>(p_method, p_method_info, p_return_nil_is_variant) {
  188. }
  189. private:
  190. static PropertyInfo _gen_return_type_info_impl() {
  191. return {};
  192. }
  193. };
  194. template <class T>
  195. MethodBind *create_vararg_method_bind(void (T::*p_method)(const Variant **, int, Callable::CallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
  196. MethodBind *a = memnew((MethodBindVarArgT<T>)(p_method, p_info, p_return_nil_is_variant));
  197. a->set_instance_class(T::get_class_static());
  198. return a;
  199. }
  200. // variadic, return
  201. template <class T, class R>
  202. class MethodBindVarArgTR : public MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true> {
  203. friend class MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true>;
  204. public:
  205. #if defined(SANITIZERS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
  206. // Workaround GH-66343 raised only with UBSAN, seems to be a false positive.
  207. #pragma GCC diagnostic push
  208. #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
  209. #endif
  210. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  211. return (static_cast<T *>(p_object)->*MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true>::method)(p_args, p_arg_count, r_error);
  212. }
  213. #if defined(SANITIZERS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
  214. #pragma GCC diagnostic pop
  215. #endif
  216. MethodBindVarArgTR(
  217. R (T::*p_method)(const Variant **, int, Callable::CallError &),
  218. const MethodInfo &p_info,
  219. bool p_return_nil_is_variant) :
  220. MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true>(p_method, p_info, p_return_nil_is_variant) {
  221. }
  222. private:
  223. static PropertyInfo _gen_return_type_info_impl() {
  224. return GetTypeInfo<R>::get_class_info();
  225. }
  226. };
  227. template <class T, class R>
  228. MethodBind *create_vararg_method_bind(R (T::*p_method)(const Variant **, int, Callable::CallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
  229. MethodBind *a = memnew((MethodBindVarArgTR<T, R>)(p_method, p_info, p_return_nil_is_variant));
  230. a->set_instance_class(T::get_class_static());
  231. return a;
  232. }
  233. /**** VARIADIC TEMPLATES ****/
  234. #ifndef TYPED_METHOD_BIND
  235. class __UnexistingClass;
  236. #define MB_T __UnexistingClass
  237. #else
  238. #define MB_T T
  239. #endif
  240. // no return, not const
  241. #ifdef TYPED_METHOD_BIND
  242. template <class T, class... P>
  243. #else
  244. template <class... P>
  245. #endif
  246. class MethodBindT : public MethodBind {
  247. void (MB_T::*method)(P...);
  248. protected:
  249. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  250. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  251. return call_get_argument_type<P...>(p_arg);
  252. } else {
  253. return Variant::NIL;
  254. }
  255. }
  256. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  257. PropertyInfo pi;
  258. call_get_argument_type_info<P...>(p_arg, pi);
  259. return pi;
  260. }
  261. public:
  262. #ifdef DEBUG_METHODS_ENABLED
  263. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  264. return call_get_argument_metadata<P...>(p_arg);
  265. }
  266. #endif
  267. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  268. #ifdef TYPED_METHOD_BIND
  269. call_with_variant_args_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
  270. #else
  271. call_with_variant_args_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
  272. #endif
  273. return Variant();
  274. }
  275. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  276. #ifdef TYPED_METHOD_BIND
  277. call_with_ptr_args<T, P...>(static_cast<T *>(p_object), method, p_args);
  278. #else
  279. call_with_ptr_args<MB_T, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args);
  280. #endif
  281. }
  282. MethodBindT(void (MB_T::*p_method)(P...)) {
  283. method = p_method;
  284. _generate_argument_types(sizeof...(P));
  285. set_argument_count(sizeof...(P));
  286. }
  287. };
  288. template <class T, class... P>
  289. MethodBind *create_method_bind(void (T::*p_method)(P...)) {
  290. #ifdef TYPED_METHOD_BIND
  291. MethodBind *a = memnew((MethodBindT<T, P...>)(p_method));
  292. #else
  293. MethodBind *a = memnew((MethodBindT<P...>)(reinterpret_cast<void (MB_T::*)(P...)>(p_method)));
  294. #endif
  295. a->set_instance_class(T::get_class_static());
  296. return a;
  297. }
  298. // no return, const
  299. #ifdef TYPED_METHOD_BIND
  300. template <class T, class... P>
  301. #else
  302. template <class... P>
  303. #endif
  304. class MethodBindTC : public MethodBind {
  305. void (MB_T::*method)(P...) const;
  306. protected:
  307. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  308. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  309. return call_get_argument_type<P...>(p_arg);
  310. } else {
  311. return Variant::NIL;
  312. }
  313. }
  314. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  315. PropertyInfo pi;
  316. call_get_argument_type_info<P...>(p_arg, pi);
  317. return pi;
  318. }
  319. public:
  320. #ifdef DEBUG_METHODS_ENABLED
  321. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  322. return call_get_argument_metadata<P...>(p_arg);
  323. }
  324. #endif
  325. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  326. #ifdef TYPED_METHOD_BIND
  327. call_with_variant_argsc_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
  328. #else
  329. call_with_variant_argsc_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
  330. #endif
  331. return Variant();
  332. }
  333. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  334. #ifdef TYPED_METHOD_BIND
  335. call_with_ptr_argsc<T, P...>(static_cast<T *>(p_object), method, p_args);
  336. #else
  337. call_with_ptr_argsc<MB_T, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args);
  338. #endif
  339. }
  340. MethodBindTC(void (MB_T::*p_method)(P...) const) {
  341. method = p_method;
  342. _set_const(true);
  343. _generate_argument_types(sizeof...(P));
  344. set_argument_count(sizeof...(P));
  345. }
  346. };
  347. template <class T, class... P>
  348. MethodBind *create_method_bind(void (T::*p_method)(P...) const) {
  349. #ifdef TYPED_METHOD_BIND
  350. MethodBind *a = memnew((MethodBindTC<T, P...>)(p_method));
  351. #else
  352. MethodBind *a = memnew((MethodBindTC<P...>)(reinterpret_cast<void (MB_T::*)(P...) const>(p_method)));
  353. #endif
  354. a->set_instance_class(T::get_class_static());
  355. return a;
  356. }
  357. // return, not const
  358. #ifdef TYPED_METHOD_BIND
  359. template <class T, class R, class... P>
  360. #else
  361. template <class R, class... P>
  362. #endif
  363. class MethodBindTR : public MethodBind {
  364. R(MB_T::*method)
  365. (P...);
  366. protected:
  367. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  368. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  369. return call_get_argument_type<P...>(p_arg);
  370. } else {
  371. return GetTypeInfo<R>::VARIANT_TYPE;
  372. }
  373. }
  374. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  375. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  376. PropertyInfo pi;
  377. call_get_argument_type_info<P...>(p_arg, pi);
  378. return pi;
  379. } else {
  380. return GetTypeInfo<R>::get_class_info();
  381. }
  382. }
  383. public:
  384. #ifdef DEBUG_METHODS_ENABLED
  385. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  386. if (p_arg >= 0) {
  387. return call_get_argument_metadata<P...>(p_arg);
  388. } else {
  389. return GetTypeInfo<R>::METADATA;
  390. }
  391. }
  392. #endif
  393. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  394. Variant ret;
  395. #ifdef TYPED_METHOD_BIND
  396. call_with_variant_args_ret_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
  397. #else
  398. call_with_variant_args_ret_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
  399. #endif
  400. return ret;
  401. }
  402. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  403. #ifdef TYPED_METHOD_BIND
  404. call_with_ptr_args_ret<T, R, P...>(static_cast<T *>(p_object), method, p_args, r_ret);
  405. #else
  406. call_with_ptr_args_ret<MB_T, R, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args, r_ret);
  407. #endif
  408. }
  409. MethodBindTR(R (MB_T::*p_method)(P...)) {
  410. method = p_method;
  411. _set_returns(true);
  412. _generate_argument_types(sizeof...(P));
  413. set_argument_count(sizeof...(P));
  414. }
  415. };
  416. template <class T, class R, class... P>
  417. MethodBind *create_method_bind(R (T::*p_method)(P...)) {
  418. #ifdef TYPED_METHOD_BIND
  419. MethodBind *a = memnew((MethodBindTR<T, R, P...>)(p_method));
  420. #else
  421. MethodBind *a = memnew((MethodBindTR<R, P...>)(reinterpret_cast<R (MB_T::*)(P...)>(p_method)));
  422. #endif
  423. a->set_instance_class(T::get_class_static());
  424. return a;
  425. }
  426. // return, const
  427. #ifdef TYPED_METHOD_BIND
  428. template <class T, class R, class... P>
  429. #else
  430. template <class R, class... P>
  431. #endif
  432. class MethodBindTRC : public MethodBind {
  433. R(MB_T::*method)
  434. (P...) const;
  435. protected:
  436. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  437. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  438. return call_get_argument_type<P...>(p_arg);
  439. } else {
  440. return GetTypeInfo<R>::VARIANT_TYPE;
  441. }
  442. }
  443. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  444. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  445. PropertyInfo pi;
  446. call_get_argument_type_info<P...>(p_arg, pi);
  447. return pi;
  448. } else {
  449. return GetTypeInfo<R>::get_class_info();
  450. }
  451. }
  452. public:
  453. #ifdef DEBUG_METHODS_ENABLED
  454. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  455. if (p_arg >= 0) {
  456. return call_get_argument_metadata<P...>(p_arg);
  457. } else {
  458. return GetTypeInfo<R>::METADATA;
  459. }
  460. }
  461. #endif
  462. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  463. Variant ret;
  464. #ifdef TYPED_METHOD_BIND
  465. call_with_variant_args_retc_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
  466. #else
  467. call_with_variant_args_retc_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
  468. #endif
  469. return ret;
  470. }
  471. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  472. #ifdef TYPED_METHOD_BIND
  473. call_with_ptr_args_retc<T, R, P...>(static_cast<T *>(p_object), method, p_args, r_ret);
  474. #else
  475. call_with_ptr_args_retc<MB_T, R, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args, r_ret);
  476. #endif
  477. }
  478. MethodBindTRC(R (MB_T::*p_method)(P...) const) {
  479. method = p_method;
  480. _set_returns(true);
  481. _set_const(true);
  482. _generate_argument_types(sizeof...(P));
  483. set_argument_count(sizeof...(P));
  484. }
  485. };
  486. template <class T, class R, class... P>
  487. MethodBind *create_method_bind(R (T::*p_method)(P...) const) {
  488. #ifdef TYPED_METHOD_BIND
  489. MethodBind *a = memnew((MethodBindTRC<T, R, P...>)(p_method));
  490. #else
  491. MethodBind *a = memnew((MethodBindTRC<R, P...>)(reinterpret_cast<R (MB_T::*)(P...) const>(p_method)));
  492. #endif
  493. a->set_instance_class(T::get_class_static());
  494. return a;
  495. }
  496. /* STATIC BINDS */
  497. // no return
  498. template <class... P>
  499. class MethodBindTS : public MethodBind {
  500. void (*function)(P...);
  501. protected:
  502. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  503. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  504. return call_get_argument_type<P...>(p_arg);
  505. } else {
  506. return Variant::NIL;
  507. }
  508. }
  509. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  510. PropertyInfo pi;
  511. call_get_argument_type_info<P...>(p_arg, pi);
  512. return pi;
  513. }
  514. public:
  515. #ifdef DEBUG_METHODS_ENABLED
  516. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  517. return call_get_argument_metadata<P...>(p_arg);
  518. }
  519. #endif
  520. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  521. (void)p_object; // unused
  522. call_with_variant_args_static_dv(function, p_args, p_arg_count, r_error, get_default_arguments());
  523. return Variant();
  524. }
  525. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  526. (void)p_object;
  527. (void)r_ret;
  528. call_with_ptr_args_static_method(function, p_args);
  529. }
  530. MethodBindTS(void (*p_function)(P...)) {
  531. function = p_function;
  532. _generate_argument_types(sizeof...(P));
  533. set_argument_count(sizeof...(P));
  534. _set_static(true);
  535. }
  536. };
  537. template <class... P>
  538. MethodBind *create_static_method_bind(void (*p_method)(P...)) {
  539. MethodBind *a = memnew((MethodBindTS<P...>)(p_method));
  540. return a;
  541. }
  542. // return
  543. template <class R, class... P>
  544. class MethodBindTRS : public MethodBind {
  545. R(*function)
  546. (P...);
  547. protected:
  548. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  549. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  550. return call_get_argument_type<P...>(p_arg);
  551. } else {
  552. return GetTypeInfo<R>::VARIANT_TYPE;
  553. }
  554. }
  555. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  556. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  557. PropertyInfo pi;
  558. call_get_argument_type_info<P...>(p_arg, pi);
  559. return pi;
  560. } else {
  561. return GetTypeInfo<R>::get_class_info();
  562. }
  563. }
  564. public:
  565. #ifdef DEBUG_METHODS_ENABLED
  566. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  567. if (p_arg >= 0) {
  568. return call_get_argument_metadata<P...>(p_arg);
  569. } else {
  570. return GetTypeInfo<R>::METADATA;
  571. }
  572. }
  573. #endif
  574. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  575. Variant ret;
  576. call_with_variant_args_static_ret_dv(function, p_args, p_arg_count, ret, r_error, get_default_arguments());
  577. return ret;
  578. }
  579. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  580. (void)p_object;
  581. call_with_ptr_args_static_method_ret(function, p_args, r_ret);
  582. }
  583. MethodBindTRS(R (*p_function)(P...)) {
  584. function = p_function;
  585. _generate_argument_types(sizeof...(P));
  586. set_argument_count(sizeof...(P));
  587. _set_static(true);
  588. _set_returns(true);
  589. }
  590. };
  591. template <class R, class... P>
  592. MethodBind *create_static_method_bind(R (*p_method)(P...)) {
  593. MethodBind *a = memnew((MethodBindTRS<R, P...>)(p_method));
  594. return a;
  595. }
  596. #endif // METHOD_BIND_H