method_bind.h 24 KB

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