binder_common.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. /*************************************************************************/
  2. /* binder_common.h */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
  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 BINDER_COMMON_H
  31. #define BINDER_COMMON_H
  32. #include "core/object/object.h"
  33. #include "core/templates/list.h"
  34. #include "core/templates/simple_type.h"
  35. #include "core/typedefs.h"
  36. #include "core/variant/method_ptrcall.h"
  37. #include "core/variant/type_info.h"
  38. #include "core/variant/variant.h"
  39. #include "core/variant/variant_internal.h"
  40. #include <stdio.h>
  41. template <class T>
  42. struct VariantCaster {
  43. static _FORCE_INLINE_ T cast(const Variant &p_variant) {
  44. return p_variant;
  45. }
  46. };
  47. template <class T>
  48. struct VariantCaster<T &> {
  49. static _FORCE_INLINE_ T cast(const Variant &p_variant) {
  50. return p_variant;
  51. }
  52. };
  53. template <class T>
  54. struct VariantCaster<const T &> {
  55. static _FORCE_INLINE_ T cast(const Variant &p_variant) {
  56. return p_variant;
  57. }
  58. };
  59. #define VARIANT_ENUM_CAST(m_enum) \
  60. MAKE_ENUM_TYPE_INFO(m_enum) \
  61. template <> \
  62. struct VariantCaster<m_enum> { \
  63. static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \
  64. return (m_enum)p_variant.operator int(); \
  65. } \
  66. }; \
  67. template <> \
  68. struct PtrToArg<m_enum> { \
  69. _FORCE_INLINE_ static m_enum convert(const void *p_ptr) { \
  70. return m_enum(*reinterpret_cast<const int *>(p_ptr)); \
  71. } \
  72. _FORCE_INLINE_ static void encode(m_enum p_val, const void *p_ptr) { \
  73. *(int *)p_ptr = p_val; \
  74. } \
  75. };
  76. // Object enum casts must go here
  77. VARIANT_ENUM_CAST(Object::ConnectFlags);
  78. VARIANT_ENUM_CAST(Vector3::Axis);
  79. VARIANT_ENUM_CAST(Error);
  80. VARIANT_ENUM_CAST(Side);
  81. VARIANT_ENUM_CAST(Corner);
  82. VARIANT_ENUM_CAST(Orientation);
  83. VARIANT_ENUM_CAST(HAlign);
  84. VARIANT_ENUM_CAST(VAlign);
  85. VARIANT_ENUM_CAST(PropertyHint);
  86. VARIANT_ENUM_CAST(PropertyUsageFlags);
  87. VARIANT_ENUM_CAST(Variant::Type);
  88. VARIANT_ENUM_CAST(Variant::Operator);
  89. template <>
  90. struct VariantCaster<char32_t> {
  91. static _FORCE_INLINE_ char32_t cast(const Variant &p_variant) {
  92. return (char32_t)p_variant.operator int();
  93. }
  94. };
  95. template <>
  96. struct PtrToArg<char32_t> {
  97. _FORCE_INLINE_ static char32_t convert(const void *p_ptr) {
  98. return char32_t(*reinterpret_cast<const int *>(p_ptr));
  99. }
  100. _FORCE_INLINE_ static void encode(char32_t p_val, const void *p_ptr) {
  101. *(int *)p_ptr = p_val;
  102. }
  103. };
  104. template <typename T>
  105. struct VariantObjectClassChecker {
  106. static _FORCE_INLINE_ bool check(const Variant &p_variant) {
  107. return true;
  108. }
  109. };
  110. template <>
  111. struct VariantObjectClassChecker<Node *> {
  112. static _FORCE_INLINE_ bool check(const Variant &p_variant) {
  113. Object *obj = p_variant;
  114. Node *node = p_variant;
  115. return node || !obj;
  116. }
  117. };
  118. template <>
  119. struct VariantObjectClassChecker<Control *> {
  120. static _FORCE_INLINE_ bool check(const Variant &p_variant) {
  121. Object *obj = p_variant;
  122. Control *control = p_variant;
  123. return control || !obj;
  124. }
  125. };
  126. #ifdef DEBUG_METHODS_ENABLED
  127. template <class T>
  128. struct VariantCasterAndValidate {
  129. static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
  130. Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
  131. if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
  132. !VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
  133. r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
  134. r_error.argument = p_arg_idx;
  135. r_error.expected = argtype;
  136. }
  137. return VariantCaster<T>::cast(*p_args[p_arg_idx]);
  138. }
  139. };
  140. template <class T>
  141. struct VariantCasterAndValidate<T &> {
  142. static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
  143. Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
  144. if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
  145. !VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
  146. r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
  147. r_error.argument = p_arg_idx;
  148. r_error.expected = argtype;
  149. }
  150. return VariantCaster<T>::cast(*p_args[p_arg_idx]);
  151. }
  152. };
  153. template <class T>
  154. struct VariantCasterAndValidate<const T &> {
  155. static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
  156. Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
  157. if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
  158. !VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
  159. r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
  160. r_error.argument = p_arg_idx;
  161. r_error.expected = argtype;
  162. }
  163. return VariantCaster<T>::cast(*p_args[p_arg_idx]);
  164. }
  165. };
  166. #endif // DEBUG_METHODS_ENABLED
  167. template <class T, class... P, size_t... Is>
  168. void call_with_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
  169. r_error.error = Callable::CallError::CALL_OK;
  170. #ifdef DEBUG_METHODS_ENABLED
  171. (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  172. #else
  173. (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  174. #endif
  175. (void)(p_args); //avoid warning
  176. }
  177. template <class T, class... P, size_t... Is>
  178. void call_with_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
  179. r_error.error = Callable::CallError::CALL_OK;
  180. #ifdef DEBUG_METHODS_ENABLED
  181. (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  182. #else
  183. (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  184. #endif
  185. (void)(p_args); //avoid warning
  186. }
  187. template <class T, class... P, size_t... Is>
  188. void call_with_ptr_args_helper(T *p_instance, void (T::*p_method)(P...), const void **p_args, IndexSequence<Is...>) {
  189. (p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
  190. }
  191. template <class T, class... P, size_t... Is>
  192. void call_with_ptr_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const void **p_args, IndexSequence<Is...>) {
  193. (p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
  194. }
  195. template <class T, class R, class... P, size_t... Is>
  196. void call_with_ptr_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
  197. PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
  198. }
  199. template <class T, class R, class... P, size_t... Is>
  200. void call_with_ptr_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const void **p_args, void *r_ret, IndexSequence<Is...>) {
  201. PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
  202. }
  203. template <class T, class R, class... P, size_t... Is>
  204. void call_with_ptr_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
  205. PtrToArg<R>::encode(p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...), r_ret);
  206. }
  207. template <class T, class... P, size_t... Is>
  208. void call_with_validated_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) {
  209. (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
  210. }
  211. template <class T, class... P, size_t... Is>
  212. void call_with_validated_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, IndexSequence<Is...>) {
  213. (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
  214. }
  215. template <class T, class R, class... P, size_t... Is>
  216. void call_with_validated_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
  217. VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
  218. }
  219. template <class T, class R, class... P, size_t... Is>
  220. void call_with_validated_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
  221. VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
  222. }
  223. template <class T, class R, class... P, size_t... Is>
  224. void call_with_validated_variant_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
  225. VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
  226. }
  227. template <class T, class... P>
  228. void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
  229. #ifdef DEBUG_METHODS_ENABLED
  230. if ((size_t)p_argcount > sizeof...(P)) {
  231. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  232. r_error.argument = sizeof...(P);
  233. return;
  234. }
  235. if ((size_t)p_argcount < sizeof...(P)) {
  236. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  237. r_error.argument = sizeof...(P);
  238. return;
  239. }
  240. #endif
  241. call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
  242. }
  243. template <class T, class... P>
  244. void call_with_variant_args_dv(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error, const Vector<Variant> &default_values) {
  245. #ifdef DEBUG_ENABLED
  246. if ((size_t)p_argcount > sizeof...(P)) {
  247. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  248. r_error.argument = sizeof...(P);
  249. return;
  250. }
  251. #endif
  252. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  253. int32_t dvs = default_values.size();
  254. #ifdef DEBUG_ENABLED
  255. if (missing > dvs) {
  256. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  257. r_error.argument = sizeof...(P);
  258. return;
  259. }
  260. #endif
  261. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  262. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  263. if (i < p_argcount) {
  264. args[i] = p_args[i];
  265. } else {
  266. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  267. }
  268. }
  269. call_with_variant_args_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
  270. }
  271. template <class T, class... P>
  272. void call_with_variant_argsc(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
  273. #ifdef DEBUG_METHODS_ENABLED
  274. if ((size_t)p_argcount > sizeof...(P)) {
  275. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  276. r_error.argument = sizeof...(P);
  277. return;
  278. }
  279. if ((size_t)p_argcount < sizeof...(P)) {
  280. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  281. r_error.argument = sizeof...(P);
  282. return;
  283. }
  284. #endif
  285. call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
  286. }
  287. template <class T, class... P>
  288. void call_with_variant_argsc_dv(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Callable::CallError &r_error, const Vector<Variant> &default_values) {
  289. #ifdef DEBUG_ENABLED
  290. if ((size_t)p_argcount > sizeof...(P)) {
  291. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  292. r_error.argument = sizeof...(P);
  293. return;
  294. }
  295. #endif
  296. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  297. int32_t dvs = default_values.size();
  298. #ifdef DEBUG_ENABLED
  299. if (missing > dvs) {
  300. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  301. r_error.argument = sizeof...(P);
  302. return;
  303. }
  304. #endif
  305. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  306. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  307. if (i < p_argcount) {
  308. args[i] = p_args[i];
  309. } else {
  310. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  311. }
  312. }
  313. call_with_variant_argsc_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
  314. }
  315. template <class T, class R, class... P>
  316. void call_with_variant_args_ret_dv(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) {
  317. #ifdef DEBUG_ENABLED
  318. if ((size_t)p_argcount > sizeof...(P)) {
  319. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  320. r_error.argument = sizeof...(P);
  321. return;
  322. }
  323. #endif
  324. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  325. int32_t dvs = default_values.size();
  326. #ifdef DEBUG_ENABLED
  327. if (missing > dvs) {
  328. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  329. r_error.argument = sizeof...(P);
  330. return;
  331. }
  332. #endif
  333. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  334. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  335. if (i < p_argcount) {
  336. args[i] = p_args[i];
  337. } else {
  338. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  339. }
  340. }
  341. call_with_variant_args_ret_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  342. }
  343. template <class T, class R, class... P>
  344. void call_with_variant_args_retc_dv(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) {
  345. #ifdef DEBUG_ENABLED
  346. if ((size_t)p_argcount > sizeof...(P)) {
  347. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  348. r_error.argument = sizeof...(P);
  349. return;
  350. }
  351. #endif
  352. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  353. int32_t dvs = default_values.size();
  354. #ifdef DEBUG_ENABLED
  355. if (missing > dvs) {
  356. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  357. r_error.argument = sizeof...(P);
  358. return;
  359. }
  360. #endif
  361. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  362. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  363. if (i < p_argcount) {
  364. args[i] = p_args[i];
  365. } else {
  366. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  367. }
  368. }
  369. call_with_variant_args_retc_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  370. }
  371. template <class T, class... P>
  372. void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...), const void **p_args) {
  373. call_with_ptr_args_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  374. }
  375. template <class T, class... P>
  376. void call_with_ptr_argsc(T *p_instance, void (T::*p_method)(P...) const, const void **p_args) {
  377. call_with_ptr_argsc_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  378. }
  379. template <class T, class R, class... P>
  380. void call_with_ptr_args_ret(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret) {
  381. call_with_ptr_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  382. }
  383. template <class T, class R, class... P>
  384. void call_with_ptr_args_retc(T *p_instance, R (T::*p_method)(P...) const, const void **p_args, void *r_ret) {
  385. call_with_ptr_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  386. }
  387. template <class T, class R, class... P>
  388. void call_with_ptr_args_static_retc(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret) {
  389. call_with_ptr_args_static_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  390. }
  391. template <class T, class... P>
  392. void call_with_validated_variant_args(Variant *base, void (T::*p_method)(P...), const Variant **p_args) {
  393. call_with_validated_variant_args_helper<T, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  394. }
  395. template <class T, class R, class... P>
  396. void call_with_validated_variant_args_ret(Variant *base, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret) {
  397. call_with_validated_variant_args_ret_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  398. }
  399. template <class T, class R, class... P>
  400. void call_with_validated_variant_args_retc(Variant *base, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret) {
  401. call_with_validated_variant_args_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  402. }
  403. template <class T, class R, class... P>
  404. void call_with_validated_variant_args_static_retc(Variant *base, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret) {
  405. call_with_validated_variant_args_static_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  406. }
  407. // GCC raises "parameter 'p_args' set but not used" when P = {},
  408. // it's not clever enough to treat other P values as making this branch valid.
  409. #if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
  410. #pragma GCC diagnostic push
  411. #pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
  412. #endif
  413. #ifdef DEBUG_METHODS_ENABLED
  414. template <class Q>
  415. void call_get_argument_type_helper(int p_arg, int &index, Variant::Type &type) {
  416. if (p_arg == index) {
  417. type = GetTypeInfo<Q>::VARIANT_TYPE;
  418. }
  419. index++;
  420. }
  421. template <class... P>
  422. Variant::Type call_get_argument_type(int p_arg) {
  423. Variant::Type type = Variant::NIL;
  424. int index = 0;
  425. // I think rocket science is simpler than modern C++.
  426. using expand_type = int[];
  427. expand_type a{ 0, (call_get_argument_type_helper<P>(p_arg, index, type), 0)... };
  428. (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
  429. (void)index; // Suppress GCC warning.
  430. return type;
  431. }
  432. template <class Q>
  433. void call_get_argument_type_info_helper(int p_arg, int &index, PropertyInfo &info) {
  434. if (p_arg == index) {
  435. info = GetTypeInfo<Q>::get_class_info();
  436. }
  437. index++;
  438. }
  439. template <class... P>
  440. void call_get_argument_type_info(int p_arg, PropertyInfo &info) {
  441. int index = 0;
  442. // I think rocket science is simpler than modern C++.
  443. using expand_type = int[];
  444. expand_type a{ 0, (call_get_argument_type_info_helper<P>(p_arg, index, info), 0)... };
  445. (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
  446. (void)index; // Suppress GCC warning.
  447. }
  448. template <class Q>
  449. void call_get_argument_metadata_helper(int p_arg, int &index, GodotTypeInfo::Metadata &md) {
  450. if (p_arg == index) {
  451. md = GetTypeInfo<Q>::METADATA;
  452. }
  453. index++;
  454. }
  455. template <class... P>
  456. GodotTypeInfo::Metadata call_get_argument_metadata(int p_arg) {
  457. GodotTypeInfo::Metadata md = GodotTypeInfo::METADATA_NONE;
  458. int index = 0;
  459. // I think rocket science is simpler than modern C++.
  460. using expand_type = int[];
  461. expand_type a{ 0, (call_get_argument_metadata_helper<P>(p_arg, index, md), 0)... };
  462. (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
  463. (void)index;
  464. return md;
  465. }
  466. #else
  467. template <class... P>
  468. Variant::Type call_get_argument_type(int p_arg) {
  469. return Variant::NIL;
  470. }
  471. #endif // DEBUG_METHODS_ENABLED
  472. //////////////////////
  473. template <class T, class R, class... P, size_t... Is>
  474. void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
  475. r_error.error = Callable::CallError::CALL_OK;
  476. #ifdef DEBUG_METHODS_ENABLED
  477. r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  478. #else
  479. r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  480. #endif
  481. }
  482. template <class T, class R, class... P>
  483. void call_with_variant_args_ret(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
  484. #ifdef DEBUG_METHODS_ENABLED
  485. if ((size_t)p_argcount > sizeof...(P)) {
  486. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  487. r_error.argument = sizeof...(P);
  488. return;
  489. }
  490. if ((size_t)p_argcount < sizeof...(P)) {
  491. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  492. r_error.argument = sizeof...(P);
  493. return;
  494. }
  495. #endif
  496. call_with_variant_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  497. }
  498. template <class T, class R, class... P, size_t... Is>
  499. void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
  500. r_error.error = Callable::CallError::CALL_OK;
  501. #ifdef DEBUG_METHODS_ENABLED
  502. r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  503. #else
  504. r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  505. #endif
  506. (void)p_args;
  507. }
  508. template <class T, class R, class... P>
  509. void call_with_variant_args_retc(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
  510. #ifdef DEBUG_METHODS_ENABLED
  511. if ((size_t)p_argcount > sizeof...(P)) {
  512. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  513. r_error.argument = sizeof...(P);
  514. return;
  515. }
  516. if ((size_t)p_argcount < sizeof...(P)) {
  517. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  518. r_error.argument = sizeof...(P);
  519. return;
  520. }
  521. #endif
  522. call_with_variant_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  523. }
  524. template <class T, class R, class... P, size_t... Is>
  525. void call_with_variant_args_retc_static_helper(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
  526. r_error.error = Callable::CallError::CALL_OK;
  527. #ifdef DEBUG_METHODS_ENABLED
  528. r_ret = (p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  529. #else
  530. r_ret = (p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...);
  531. #endif
  532. (void)p_args;
  533. }
  534. template <class T, class R, class... P>
  535. void call_with_variant_args_retc_static_helper_dv(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &default_values, Callable::CallError &r_error) {
  536. #ifdef DEBUG_ENABLED
  537. if ((size_t)p_argcount > sizeof...(P)) {
  538. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  539. r_error.argument = sizeof...(P);
  540. return;
  541. }
  542. #endif
  543. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  544. int32_t dvs = default_values.size();
  545. #ifdef DEBUG_ENABLED
  546. if (missing > dvs) {
  547. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  548. r_error.argument = sizeof...(P);
  549. return;
  550. }
  551. #endif
  552. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  553. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  554. if (i < p_argcount) {
  555. args[i] = p_args[i];
  556. } else {
  557. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  558. }
  559. }
  560. call_with_variant_args_retc_static_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  561. }
  562. #if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
  563. #pragma GCC diagnostic pop
  564. #endif
  565. #endif // BINDER_COMMON_H