method_bind.h 28 KB

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