method_bind.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751
  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 <class Derived, class T, class 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 <class 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. (static_cast<T *>(p_object)->*MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false>::method)(p_args, p_arg_count, r_error);
  188. return {};
  189. }
  190. MethodBindVarArgT(
  191. void (T::*p_method)(const Variant **, int, Callable::CallError &),
  192. const MethodInfo &p_method_info,
  193. bool p_return_nil_is_variant) :
  194. MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false>(p_method, p_method_info, p_return_nil_is_variant) {
  195. }
  196. private:
  197. static PropertyInfo _gen_return_type_info_impl() {
  198. return {};
  199. }
  200. };
  201. template <class T>
  202. MethodBind *create_vararg_method_bind(void (T::*p_method)(const Variant **, int, Callable::CallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
  203. MethodBind *a = memnew((MethodBindVarArgT<T>)(p_method, p_info, p_return_nil_is_variant));
  204. a->set_instance_class(T::get_class_static());
  205. return a;
  206. }
  207. // variadic, return
  208. template <class T, class R>
  209. class MethodBindVarArgTR : public MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true> {
  210. friend class MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true>;
  211. public:
  212. #if defined(SANITIZERS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
  213. // Workaround GH-66343 raised only with UBSAN, seems to be a false positive.
  214. #pragma GCC diagnostic push
  215. #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
  216. #endif
  217. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  218. return (static_cast<T *>(p_object)->*MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true>::method)(p_args, p_arg_count, r_error);
  219. }
  220. #if defined(SANITIZERS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
  221. #pragma GCC diagnostic pop
  222. #endif
  223. MethodBindVarArgTR(
  224. R (T::*p_method)(const Variant **, int, Callable::CallError &),
  225. const MethodInfo &p_info,
  226. bool p_return_nil_is_variant) :
  227. MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true>(p_method, p_info, p_return_nil_is_variant) {
  228. }
  229. private:
  230. static PropertyInfo _gen_return_type_info_impl() {
  231. return GetTypeInfo<R>::get_class_info();
  232. }
  233. };
  234. template <class T, class R>
  235. MethodBind *create_vararg_method_bind(R (T::*p_method)(const Variant **, int, Callable::CallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
  236. MethodBind *a = memnew((MethodBindVarArgTR<T, R>)(p_method, p_info, p_return_nil_is_variant));
  237. a->set_instance_class(T::get_class_static());
  238. return a;
  239. }
  240. /**** VARIADIC TEMPLATES ****/
  241. #ifndef TYPED_METHOD_BIND
  242. class __UnexistingClass;
  243. #define MB_T __UnexistingClass
  244. #else
  245. #define MB_T T
  246. #endif
  247. // no return, not const
  248. #ifdef TYPED_METHOD_BIND
  249. template <class T, class... P>
  250. #else
  251. template <class... P>
  252. #endif
  253. class MethodBindT : public MethodBind {
  254. void (MB_T::*method)(P...);
  255. protected:
  256. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  257. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  258. return call_get_argument_type<P...>(p_arg);
  259. } else {
  260. return Variant::NIL;
  261. }
  262. }
  263. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  264. PropertyInfo pi;
  265. call_get_argument_type_info<P...>(p_arg, pi);
  266. return pi;
  267. }
  268. public:
  269. #ifdef DEBUG_METHODS_ENABLED
  270. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  271. return call_get_argument_metadata<P...>(p_arg);
  272. }
  273. #endif
  274. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  275. #ifdef TYPED_METHOD_BIND
  276. call_with_variant_args_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
  277. #else
  278. call_with_variant_args_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
  279. #endif
  280. return Variant();
  281. }
  282. virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
  283. #ifdef TYPED_METHOD_BIND
  284. call_with_validated_object_instance_args(static_cast<T *>(p_object), method, p_args);
  285. #else
  286. call_with_validated_object_instance_args(reinterpret_cast<MB_T *>(p_object), method, p_args);
  287. #endif
  288. }
  289. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  290. #ifdef TYPED_METHOD_BIND
  291. call_with_ptr_args<T, P...>(static_cast<T *>(p_object), method, p_args);
  292. #else
  293. call_with_ptr_args<MB_T, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args);
  294. #endif
  295. }
  296. MethodBindT(void (MB_T::*p_method)(P...)) {
  297. method = p_method;
  298. _generate_argument_types(sizeof...(P));
  299. set_argument_count(sizeof...(P));
  300. }
  301. };
  302. template <class T, class... P>
  303. MethodBind *create_method_bind(void (T::*p_method)(P...)) {
  304. #ifdef TYPED_METHOD_BIND
  305. MethodBind *a = memnew((MethodBindT<T, P...>)(p_method));
  306. #else
  307. MethodBind *a = memnew((MethodBindT<P...>)(reinterpret_cast<void (MB_T::*)(P...)>(p_method)));
  308. #endif
  309. a->set_instance_class(T::get_class_static());
  310. return a;
  311. }
  312. // no return, const
  313. #ifdef TYPED_METHOD_BIND
  314. template <class T, class... P>
  315. #else
  316. template <class... P>
  317. #endif
  318. class MethodBindTC : public MethodBind {
  319. void (MB_T::*method)(P...) const;
  320. protected:
  321. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  322. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  323. return call_get_argument_type<P...>(p_arg);
  324. } else {
  325. return Variant::NIL;
  326. }
  327. }
  328. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  329. PropertyInfo pi;
  330. call_get_argument_type_info<P...>(p_arg, pi);
  331. return pi;
  332. }
  333. public:
  334. #ifdef DEBUG_METHODS_ENABLED
  335. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  336. return call_get_argument_metadata<P...>(p_arg);
  337. }
  338. #endif
  339. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  340. #ifdef TYPED_METHOD_BIND
  341. call_with_variant_argsc_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
  342. #else
  343. call_with_variant_argsc_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
  344. #endif
  345. return Variant();
  346. }
  347. virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
  348. #ifdef TYPED_METHOD_BIND
  349. call_with_validated_object_instance_argsc(static_cast<T *>(p_object), method, p_args);
  350. #else
  351. call_with_validated_object_instance_argsc(reinterpret_cast<MB_T *>(p_object), method, p_args);
  352. #endif
  353. }
  354. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  355. #ifdef TYPED_METHOD_BIND
  356. call_with_ptr_argsc<T, P...>(static_cast<T *>(p_object), method, p_args);
  357. #else
  358. call_with_ptr_argsc<MB_T, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args);
  359. #endif
  360. }
  361. MethodBindTC(void (MB_T::*p_method)(P...) const) {
  362. method = p_method;
  363. _set_const(true);
  364. _generate_argument_types(sizeof...(P));
  365. set_argument_count(sizeof...(P));
  366. }
  367. };
  368. template <class T, class... P>
  369. MethodBind *create_method_bind(void (T::*p_method)(P...) const) {
  370. #ifdef TYPED_METHOD_BIND
  371. MethodBind *a = memnew((MethodBindTC<T, P...>)(p_method));
  372. #else
  373. MethodBind *a = memnew((MethodBindTC<P...>)(reinterpret_cast<void (MB_T::*)(P...) const>(p_method)));
  374. #endif
  375. a->set_instance_class(T::get_class_static());
  376. return a;
  377. }
  378. // return, not const
  379. #ifdef TYPED_METHOD_BIND
  380. template <class T, class R, class... P>
  381. #else
  382. template <class R, class... P>
  383. #endif
  384. class MethodBindTR : public MethodBind {
  385. R(MB_T::*method)
  386. (P...);
  387. protected:
  388. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  389. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  390. return call_get_argument_type<P...>(p_arg);
  391. } else {
  392. return GetTypeInfo<R>::VARIANT_TYPE;
  393. }
  394. }
  395. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  396. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  397. PropertyInfo pi;
  398. call_get_argument_type_info<P...>(p_arg, pi);
  399. return pi;
  400. } else {
  401. return GetTypeInfo<R>::get_class_info();
  402. }
  403. }
  404. public:
  405. #ifdef DEBUG_METHODS_ENABLED
  406. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  407. if (p_arg >= 0) {
  408. return call_get_argument_metadata<P...>(p_arg);
  409. } else {
  410. return GetTypeInfo<R>::METADATA;
  411. }
  412. }
  413. #endif
  414. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  415. Variant ret;
  416. #ifdef TYPED_METHOD_BIND
  417. call_with_variant_args_ret_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
  418. #else
  419. call_with_variant_args_ret_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
  420. #endif
  421. return ret;
  422. }
  423. virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
  424. #ifdef TYPED_METHOD_BIND
  425. call_with_validated_object_instance_args_ret(static_cast<T *>(p_object), method, p_args, r_ret);
  426. #else
  427. call_with_validated_object_instance_args_ret(reinterpret_cast<MB_T *>(p_object), method, p_args, r_ret);
  428. #endif
  429. }
  430. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  431. #ifdef TYPED_METHOD_BIND
  432. call_with_ptr_args_ret<T, R, P...>(static_cast<T *>(p_object), method, p_args, r_ret);
  433. #else
  434. call_with_ptr_args_ret<MB_T, R, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args, r_ret);
  435. #endif
  436. }
  437. MethodBindTR(R (MB_T::*p_method)(P...)) {
  438. method = p_method;
  439. _set_returns(true);
  440. _generate_argument_types(sizeof...(P));
  441. set_argument_count(sizeof...(P));
  442. }
  443. };
  444. template <class T, class R, class... P>
  445. MethodBind *create_method_bind(R (T::*p_method)(P...)) {
  446. #ifdef TYPED_METHOD_BIND
  447. MethodBind *a = memnew((MethodBindTR<T, R, P...>)(p_method));
  448. #else
  449. MethodBind *a = memnew((MethodBindTR<R, P...>)(reinterpret_cast<R (MB_T::*)(P...)>(p_method)));
  450. #endif
  451. a->set_instance_class(T::get_class_static());
  452. return a;
  453. }
  454. // return, const
  455. #ifdef TYPED_METHOD_BIND
  456. template <class T, class R, class... P>
  457. #else
  458. template <class R, class... P>
  459. #endif
  460. class MethodBindTRC : public MethodBind {
  461. R(MB_T::*method)
  462. (P...) const;
  463. protected:
  464. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  465. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  466. return call_get_argument_type<P...>(p_arg);
  467. } else {
  468. return GetTypeInfo<R>::VARIANT_TYPE;
  469. }
  470. }
  471. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  472. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  473. PropertyInfo pi;
  474. call_get_argument_type_info<P...>(p_arg, pi);
  475. return pi;
  476. } else {
  477. return GetTypeInfo<R>::get_class_info();
  478. }
  479. }
  480. public:
  481. #ifdef DEBUG_METHODS_ENABLED
  482. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  483. if (p_arg >= 0) {
  484. return call_get_argument_metadata<P...>(p_arg);
  485. } else {
  486. return GetTypeInfo<R>::METADATA;
  487. }
  488. }
  489. #endif
  490. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  491. Variant ret;
  492. #ifdef TYPED_METHOD_BIND
  493. call_with_variant_args_retc_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
  494. #else
  495. call_with_variant_args_retc_dv(reinterpret_cast<MB_T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
  496. #endif
  497. return ret;
  498. }
  499. virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
  500. #ifdef TYPED_METHOD_BIND
  501. call_with_validated_object_instance_args_retc(static_cast<T *>(p_object), method, p_args, r_ret);
  502. #else
  503. call_with_validated_object_instance_args_retc(reinterpret_cast<MB_T *>(p_object), method, p_args, r_ret);
  504. #endif
  505. }
  506. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  507. #ifdef TYPED_METHOD_BIND
  508. call_with_ptr_args_retc<T, R, P...>(static_cast<T *>(p_object), method, p_args, r_ret);
  509. #else
  510. call_with_ptr_args_retc<MB_T, R, P...>(reinterpret_cast<MB_T *>(p_object), method, p_args, r_ret);
  511. #endif
  512. }
  513. MethodBindTRC(R (MB_T::*p_method)(P...) const) {
  514. method = p_method;
  515. _set_returns(true);
  516. _set_const(true);
  517. _generate_argument_types(sizeof...(P));
  518. set_argument_count(sizeof...(P));
  519. }
  520. };
  521. template <class T, class R, class... P>
  522. MethodBind *create_method_bind(R (T::*p_method)(P...) const) {
  523. #ifdef TYPED_METHOD_BIND
  524. MethodBind *a = memnew((MethodBindTRC<T, R, P...>)(p_method));
  525. #else
  526. MethodBind *a = memnew((MethodBindTRC<R, P...>)(reinterpret_cast<R (MB_T::*)(P...) const>(p_method)));
  527. #endif
  528. a->set_instance_class(T::get_class_static());
  529. return a;
  530. }
  531. /* STATIC BINDS */
  532. // no return
  533. template <class... P>
  534. class MethodBindTS : public MethodBind {
  535. void (*function)(P...);
  536. protected:
  537. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  538. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  539. return call_get_argument_type<P...>(p_arg);
  540. } else {
  541. return Variant::NIL;
  542. }
  543. }
  544. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  545. PropertyInfo pi;
  546. call_get_argument_type_info<P...>(p_arg, pi);
  547. return pi;
  548. }
  549. public:
  550. #ifdef DEBUG_METHODS_ENABLED
  551. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  552. return call_get_argument_metadata<P...>(p_arg);
  553. }
  554. #endif
  555. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  556. (void)p_object; // unused
  557. call_with_variant_args_static_dv(function, p_args, p_arg_count, r_error, get_default_arguments());
  558. return Variant();
  559. }
  560. virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
  561. call_with_validated_variant_args_static_method(function, p_args);
  562. }
  563. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  564. (void)p_object;
  565. (void)r_ret;
  566. call_with_ptr_args_static_method(function, p_args);
  567. }
  568. MethodBindTS(void (*p_function)(P...)) {
  569. function = p_function;
  570. _generate_argument_types(sizeof...(P));
  571. set_argument_count(sizeof...(P));
  572. _set_static(true);
  573. }
  574. };
  575. template <class... P>
  576. MethodBind *create_static_method_bind(void (*p_method)(P...)) {
  577. MethodBind *a = memnew((MethodBindTS<P...>)(p_method));
  578. return a;
  579. }
  580. // return
  581. template <class R, class... P>
  582. class MethodBindTRS : public MethodBind {
  583. R(*function)
  584. (P...);
  585. protected:
  586. virtual Variant::Type _gen_argument_type(int p_arg) const override {
  587. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  588. return call_get_argument_type<P...>(p_arg);
  589. } else {
  590. return GetTypeInfo<R>::VARIANT_TYPE;
  591. }
  592. }
  593. virtual PropertyInfo _gen_argument_type_info(int p_arg) const override {
  594. if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
  595. PropertyInfo pi;
  596. call_get_argument_type_info<P...>(p_arg, pi);
  597. return pi;
  598. } else {
  599. return GetTypeInfo<R>::get_class_info();
  600. }
  601. }
  602. public:
  603. #ifdef DEBUG_METHODS_ENABLED
  604. virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override {
  605. if (p_arg >= 0) {
  606. return call_get_argument_metadata<P...>(p_arg);
  607. } else {
  608. return GetTypeInfo<R>::METADATA;
  609. }
  610. }
  611. #endif
  612. virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override {
  613. Variant ret;
  614. call_with_variant_args_static_ret_dv(function, p_args, p_arg_count, ret, r_error, get_default_arguments());
  615. return ret;
  616. }
  617. virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override {
  618. call_with_validated_variant_args_static_method_ret(function, p_args, r_ret);
  619. }
  620. virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override {
  621. (void)p_object;
  622. call_with_ptr_args_static_method_ret(function, p_args, r_ret);
  623. }
  624. MethodBindTRS(R (*p_function)(P...)) {
  625. function = p_function;
  626. _generate_argument_types(sizeof...(P));
  627. set_argument_count(sizeof...(P));
  628. _set_static(true);
  629. _set_returns(true);
  630. }
  631. };
  632. template <class R, class... P>
  633. MethodBind *create_static_method_bind(R (*p_method)(P...)) {
  634. MethodBind *a = memnew((MethodBindTRS<R, P...>)(p_method));
  635. return a;
  636. }
  637. #endif // METHOD_BIND_H