binder_common.h 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915
  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/input/input_enums.h"
  33. #include "core/object/object.h"
  34. #include "core/os/keyboard.h"
  35. #include "core/templates/list.h"
  36. #include "core/templates/simple_type.h"
  37. #include "core/typedefs.h"
  38. #include "core/variant/method_ptrcall.h"
  39. #include "core/variant/type_info.h"
  40. #include "core/variant/variant.h"
  41. #include "core/variant/variant_internal.h"
  42. #include <stdio.h>
  43. template <class T>
  44. struct VariantCaster {
  45. static _FORCE_INLINE_ T cast(const Variant &p_variant) {
  46. return p_variant;
  47. }
  48. };
  49. template <class T>
  50. struct VariantCaster<T &> {
  51. static _FORCE_INLINE_ T cast(const Variant &p_variant) {
  52. return p_variant;
  53. }
  54. };
  55. template <class T>
  56. struct VariantCaster<const T &> {
  57. static _FORCE_INLINE_ T cast(const Variant &p_variant) {
  58. return p_variant;
  59. }
  60. };
  61. #define VARIANT_ENUM_CAST(m_enum) \
  62. MAKE_ENUM_TYPE_INFO(m_enum) \
  63. template <> \
  64. struct VariantCaster<m_enum> { \
  65. static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \
  66. return (m_enum)p_variant.operator int64_t(); \
  67. } \
  68. }; \
  69. template <> \
  70. struct PtrToArg<m_enum> { \
  71. _FORCE_INLINE_ static m_enum convert(const void *p_ptr) { \
  72. return m_enum(*reinterpret_cast<const int64_t *>(p_ptr)); \
  73. } \
  74. typedef int64_t EncodeT; \
  75. _FORCE_INLINE_ static void encode(m_enum p_val, const void *p_ptr) { \
  76. *(int64_t *)p_ptr = p_val; \
  77. } \
  78. };
  79. // Object enum casts must go here
  80. VARIANT_ENUM_CAST(Object::ConnectFlags);
  81. VARIANT_ENUM_CAST(Vector3::Axis);
  82. VARIANT_ENUM_CAST(Basis::EulerOrder);
  83. VARIANT_ENUM_CAST(Error);
  84. VARIANT_ENUM_CAST(Side);
  85. VARIANT_ENUM_CAST(ClockDirection);
  86. VARIANT_ENUM_CAST(Corner);
  87. VARIANT_ENUM_CAST(HatDir);
  88. VARIANT_ENUM_CAST(HatMask);
  89. VARIANT_ENUM_CAST(JoyAxis);
  90. VARIANT_ENUM_CAST(JoyButton);
  91. VARIANT_ENUM_CAST(Key);
  92. VARIANT_ENUM_CAST(KeyModifierMask);
  93. VARIANT_ENUM_CAST(MIDIMessage);
  94. VARIANT_ENUM_CAST(MouseButton);
  95. VARIANT_ENUM_CAST(Orientation);
  96. VARIANT_ENUM_CAST(HAlign);
  97. VARIANT_ENUM_CAST(VAlign);
  98. VARIANT_ENUM_CAST(InlineAlign);
  99. VARIANT_ENUM_CAST(PropertyHint);
  100. VARIANT_ENUM_CAST(PropertyUsageFlags);
  101. VARIANT_ENUM_CAST(Variant::Type);
  102. VARIANT_ENUM_CAST(Variant::Operator);
  103. template <>
  104. struct VariantCaster<char32_t> {
  105. static _FORCE_INLINE_ char32_t cast(const Variant &p_variant) {
  106. return (char32_t)p_variant.operator int();
  107. }
  108. };
  109. template <>
  110. struct PtrToArg<char32_t> {
  111. _FORCE_INLINE_ static char32_t convert(const void *p_ptr) {
  112. return char32_t(*reinterpret_cast<const int *>(p_ptr));
  113. }
  114. typedef int64_t EncodeT;
  115. _FORCE_INLINE_ static void encode(char32_t p_val, const void *p_ptr) {
  116. *(int *)p_ptr = p_val;
  117. }
  118. };
  119. template <typename T>
  120. struct VariantObjectClassChecker {
  121. static _FORCE_INLINE_ bool check(const Variant &p_variant) {
  122. return true;
  123. }
  124. };
  125. template <typename T>
  126. class Ref;
  127. template <typename T>
  128. struct VariantObjectClassChecker<const Ref<T> &> {
  129. static _FORCE_INLINE_ bool check(const Variant &p_variant) {
  130. Object *obj = p_variant;
  131. const Ref<T> node = p_variant;
  132. return node.ptr() || !obj;
  133. }
  134. };
  135. template <>
  136. struct VariantObjectClassChecker<Node *> {
  137. static _FORCE_INLINE_ bool check(const Variant &p_variant) {
  138. Object *obj = p_variant;
  139. Node *node = p_variant;
  140. return node || !obj;
  141. }
  142. };
  143. template <>
  144. struct VariantObjectClassChecker<Control *> {
  145. static _FORCE_INLINE_ bool check(const Variant &p_variant) {
  146. Object *obj = p_variant;
  147. Control *control = p_variant;
  148. return control || !obj;
  149. }
  150. };
  151. #ifdef DEBUG_METHODS_ENABLED
  152. template <class T>
  153. struct VariantCasterAndValidate {
  154. static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
  155. Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
  156. if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
  157. !VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
  158. r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
  159. r_error.argument = p_arg_idx;
  160. r_error.expected = argtype;
  161. }
  162. return VariantCaster<T>::cast(*p_args[p_arg_idx]);
  163. }
  164. };
  165. template <class T>
  166. struct VariantCasterAndValidate<T &> {
  167. static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
  168. Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
  169. if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
  170. !VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
  171. r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
  172. r_error.argument = p_arg_idx;
  173. r_error.expected = argtype;
  174. }
  175. return VariantCaster<T>::cast(*p_args[p_arg_idx]);
  176. }
  177. };
  178. template <class T>
  179. struct VariantCasterAndValidate<const T &> {
  180. static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
  181. Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
  182. if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
  183. !VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
  184. r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
  185. r_error.argument = p_arg_idx;
  186. r_error.expected = argtype;
  187. }
  188. return VariantCaster<T>::cast(*p_args[p_arg_idx]);
  189. }
  190. };
  191. #endif // DEBUG_METHODS_ENABLED
  192. template <class T, class... P, size_t... Is>
  193. void call_with_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
  194. r_error.error = Callable::CallError::CALL_OK;
  195. #ifdef DEBUG_METHODS_ENABLED
  196. (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  197. #else
  198. (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  199. #endif
  200. (void)(p_args); //avoid warning
  201. }
  202. template <class T, class... P, size_t... Is>
  203. 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...>) {
  204. r_error.error = Callable::CallError::CALL_OK;
  205. #ifdef DEBUG_METHODS_ENABLED
  206. (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  207. #else
  208. (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  209. #endif
  210. (void)(p_args); //avoid warning
  211. }
  212. template <class T, class... P, size_t... Is>
  213. void call_with_ptr_args_helper(T *p_instance, void (T::*p_method)(P...), const void **p_args, IndexSequence<Is...>) {
  214. (p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
  215. }
  216. template <class T, class... P, size_t... Is>
  217. void call_with_ptr_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const void **p_args, IndexSequence<Is...>) {
  218. (p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
  219. }
  220. template <class T, class R, class... P, size_t... Is>
  221. void call_with_ptr_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
  222. PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
  223. }
  224. template <class T, class R, class... P, size_t... Is>
  225. 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...>) {
  226. PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
  227. }
  228. template <class T, class... P, size_t... Is>
  229. void call_with_ptr_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const void **p_args, IndexSequence<Is...>) {
  230. p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...);
  231. }
  232. template <class T, class R, class... P, size_t... Is>
  233. 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...>) {
  234. PtrToArg<R>::encode(p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...), r_ret);
  235. }
  236. template <class R, class... P, size_t... Is>
  237. void call_with_ptr_args_static_method_ret_helper(R (*p_method)(P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
  238. PtrToArg<R>::encode(p_method(PtrToArg<P>::convert(p_args[Is])...), r_ret);
  239. }
  240. template <class... P, size_t... Is>
  241. void call_with_ptr_args_static_method_helper(void (*p_method)(P...), const void **p_args, IndexSequence<Is...>) {
  242. p_method(PtrToArg<P>::convert(p_args[Is])...);
  243. }
  244. template <class T, class... P, size_t... Is>
  245. void call_with_validated_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) {
  246. (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
  247. }
  248. template <class T, class... P, size_t... Is>
  249. void call_with_validated_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, IndexSequence<Is...>) {
  250. (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
  251. }
  252. template <class T, class R, class... P, size_t... Is>
  253. 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...>) {
  254. VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
  255. }
  256. template <class T, class R, class... P, size_t... Is>
  257. 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...>) {
  258. VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
  259. }
  260. template <class T, class R, class... P, size_t... Is>
  261. 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...>) {
  262. VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
  263. }
  264. template <class T, class... P, size_t... Is>
  265. void call_with_validated_variant_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, IndexSequence<Is...>) {
  266. p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
  267. }
  268. template <class R, class... P, size_t... Is>
  269. void call_with_validated_variant_args_static_method_ret_helper(R (*p_method)(P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
  270. VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
  271. }
  272. template <class... P, size_t... Is>
  273. void call_with_validated_variant_args_static_method_helper(void (*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) {
  274. p_method((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
  275. }
  276. template <class T, class... P>
  277. void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
  278. #ifdef DEBUG_METHODS_ENABLED
  279. if ((size_t)p_argcount > sizeof...(P)) {
  280. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  281. r_error.argument = sizeof...(P);
  282. return;
  283. }
  284. if ((size_t)p_argcount < sizeof...(P)) {
  285. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  286. r_error.argument = sizeof...(P);
  287. return;
  288. }
  289. #endif
  290. call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
  291. }
  292. template <class T, class... P>
  293. 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) {
  294. #ifdef DEBUG_ENABLED
  295. if ((size_t)p_argcount > sizeof...(P)) {
  296. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  297. r_error.argument = sizeof...(P);
  298. return;
  299. }
  300. #endif
  301. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  302. int32_t dvs = default_values.size();
  303. #ifdef DEBUG_ENABLED
  304. if (missing > dvs) {
  305. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  306. r_error.argument = sizeof...(P);
  307. return;
  308. }
  309. #endif
  310. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  311. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  312. if (i < p_argcount) {
  313. args[i] = p_args[i];
  314. } else {
  315. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  316. }
  317. }
  318. call_with_variant_args_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
  319. }
  320. template <class T, class... P>
  321. 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) {
  322. #ifdef DEBUG_METHODS_ENABLED
  323. if ((size_t)p_argcount > sizeof...(P)) {
  324. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  325. r_error.argument = sizeof...(P);
  326. return;
  327. }
  328. if ((size_t)p_argcount < sizeof...(P)) {
  329. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  330. r_error.argument = sizeof...(P);
  331. return;
  332. }
  333. #endif
  334. call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
  335. }
  336. template <class T, class... P>
  337. 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) {
  338. #ifdef DEBUG_ENABLED
  339. if ((size_t)p_argcount > sizeof...(P)) {
  340. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  341. r_error.argument = sizeof...(P);
  342. return;
  343. }
  344. #endif
  345. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  346. int32_t dvs = default_values.size();
  347. #ifdef DEBUG_ENABLED
  348. if (missing > dvs) {
  349. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  350. r_error.argument = sizeof...(P);
  351. return;
  352. }
  353. #endif
  354. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  355. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  356. if (i < p_argcount) {
  357. args[i] = p_args[i];
  358. } else {
  359. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  360. }
  361. }
  362. call_with_variant_argsc_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
  363. }
  364. template <class T, class R, class... P>
  365. 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) {
  366. #ifdef DEBUG_ENABLED
  367. if ((size_t)p_argcount > sizeof...(P)) {
  368. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  369. r_error.argument = sizeof...(P);
  370. return;
  371. }
  372. #endif
  373. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  374. int32_t dvs = default_values.size();
  375. #ifdef DEBUG_ENABLED
  376. if (missing > dvs) {
  377. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  378. r_error.argument = sizeof...(P);
  379. return;
  380. }
  381. #endif
  382. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  383. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  384. if (i < p_argcount) {
  385. args[i] = p_args[i];
  386. } else {
  387. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  388. }
  389. }
  390. call_with_variant_args_ret_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  391. }
  392. template <class T, class R, class... P>
  393. 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) {
  394. #ifdef DEBUG_ENABLED
  395. if ((size_t)p_argcount > sizeof...(P)) {
  396. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  397. r_error.argument = sizeof...(P);
  398. return;
  399. }
  400. #endif
  401. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  402. int32_t dvs = default_values.size();
  403. #ifdef DEBUG_ENABLED
  404. if (missing > dvs) {
  405. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  406. r_error.argument = sizeof...(P);
  407. return;
  408. }
  409. #endif
  410. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  411. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  412. if (i < p_argcount) {
  413. args[i] = p_args[i];
  414. } else {
  415. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  416. }
  417. }
  418. call_with_variant_args_retc_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  419. }
  420. template <class T, class... P>
  421. void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...), const void **p_args) {
  422. call_with_ptr_args_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  423. }
  424. template <class T, class... P>
  425. void call_with_ptr_argsc(T *p_instance, void (T::*p_method)(P...) const, const void **p_args) {
  426. call_with_ptr_argsc_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  427. }
  428. template <class T, class R, class... P>
  429. void call_with_ptr_args_ret(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret) {
  430. call_with_ptr_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  431. }
  432. template <class T, class R, class... P>
  433. void call_with_ptr_args_retc(T *p_instance, R (T::*p_method)(P...) const, const void **p_args, void *r_ret) {
  434. call_with_ptr_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  435. }
  436. template <class T, class... P>
  437. void call_with_ptr_args_static(T *p_instance, void (*p_method)(T *, P...), const void **p_args) {
  438. call_with_ptr_args_static_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  439. }
  440. template <class T, class R, class... P>
  441. void call_with_ptr_args_static_retc(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret) {
  442. call_with_ptr_args_static_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  443. }
  444. template <class R, class... P>
  445. void call_with_ptr_args_static_method_ret(R (*p_method)(P...), const void **p_args, void *r_ret) {
  446. call_with_ptr_args_static_method_ret_helper<R, P...>(p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  447. }
  448. template <class... P>
  449. void call_with_ptr_args_static_method(void (*p_method)(P...), const void **p_args) {
  450. call_with_ptr_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  451. }
  452. template <class T, class... P>
  453. void call_with_validated_variant_args(Variant *base, void (T::*p_method)(P...), const Variant **p_args) {
  454. call_with_validated_variant_args_helper<T, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  455. }
  456. template <class T, class R, class... P>
  457. void call_with_validated_variant_args_ret(Variant *base, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret) {
  458. call_with_validated_variant_args_ret_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  459. }
  460. template <class T, class R, class... P>
  461. void call_with_validated_variant_args_retc(Variant *base, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret) {
  462. call_with_validated_variant_args_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  463. }
  464. template <class T, class... P>
  465. void call_with_validated_variant_args_static(Variant *base, void (*p_method)(T *, P...), const Variant **p_args) {
  466. call_with_validated_variant_args_static_helper<T, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  467. }
  468. template <class T, class R, class... P>
  469. void call_with_validated_variant_args_static_retc(Variant *base, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret) {
  470. 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)>{});
  471. }
  472. template <class... P>
  473. void call_with_validated_variant_args_static_method(void (*p_method)(P...), const Variant **p_args) {
  474. call_with_validated_variant_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
  475. }
  476. template <class R, class... P>
  477. void call_with_validated_variant_args_static_method_ret(R (*p_method)(P...), const Variant **p_args, Variant *r_ret) {
  478. call_with_validated_variant_args_static_method_ret_helper<R, P...>(p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
  479. }
  480. // GCC raises "parameter 'p_args' set but not used" when P = {},
  481. // it's not clever enough to treat other P values as making this branch valid.
  482. #if defined(__GNUC__) && !defined(__clang__)
  483. #pragma GCC diagnostic push
  484. #pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
  485. #endif
  486. template <class Q>
  487. void call_get_argument_type_helper(int p_arg, int &index, Variant::Type &type) {
  488. if (p_arg == index) {
  489. type = GetTypeInfo<Q>::VARIANT_TYPE;
  490. }
  491. index++;
  492. }
  493. template <class... P>
  494. Variant::Type call_get_argument_type(int p_arg) {
  495. Variant::Type type = Variant::NIL;
  496. int index = 0;
  497. // I think rocket science is simpler than modern C++.
  498. using expand_type = int[];
  499. expand_type a{ 0, (call_get_argument_type_helper<P>(p_arg, index, type), 0)... };
  500. (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
  501. (void)index; // Suppress GCC warning.
  502. return type;
  503. }
  504. template <class Q>
  505. void call_get_argument_type_info_helper(int p_arg, int &index, PropertyInfo &info) {
  506. if (p_arg == index) {
  507. info = GetTypeInfo<Q>::get_class_info();
  508. }
  509. index++;
  510. }
  511. template <class... P>
  512. void call_get_argument_type_info(int p_arg, PropertyInfo &info) {
  513. int index = 0;
  514. // I think rocket science is simpler than modern C++.
  515. using expand_type = int[];
  516. expand_type a{ 0, (call_get_argument_type_info_helper<P>(p_arg, index, info), 0)... };
  517. (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
  518. (void)index; // Suppress GCC warning.
  519. }
  520. #ifdef DEBUG_METHODS_ENABLED
  521. template <class Q>
  522. void call_get_argument_metadata_helper(int p_arg, int &index, GodotTypeInfo::Metadata &md) {
  523. if (p_arg == index) {
  524. md = GetTypeInfo<Q>::METADATA;
  525. }
  526. index++;
  527. }
  528. template <class... P>
  529. GodotTypeInfo::Metadata call_get_argument_metadata(int p_arg) {
  530. GodotTypeInfo::Metadata md = GodotTypeInfo::METADATA_NONE;
  531. int index = 0;
  532. // I think rocket science is simpler than modern C++.
  533. using expand_type = int[];
  534. expand_type a{ 0, (call_get_argument_metadata_helper<P>(p_arg, index, md), 0)... };
  535. (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
  536. (void)index;
  537. return md;
  538. }
  539. #endif // DEBUG_METHODS_ENABLED
  540. //////////////////////
  541. template <class T, class R, class... P, size_t... Is>
  542. 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...>) {
  543. r_error.error = Callable::CallError::CALL_OK;
  544. #ifdef DEBUG_METHODS_ENABLED
  545. r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  546. #else
  547. r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  548. #endif
  549. }
  550. template <class R, class... P, size_t... Is>
  551. void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
  552. r_error.error = Callable::CallError::CALL_OK;
  553. #ifdef DEBUG_METHODS_ENABLED
  554. r_ret = (p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  555. #else
  556. r_ret = (p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  557. #endif
  558. }
  559. template <class... P, size_t... Is>
  560. void call_with_variant_args_static(void (*p_method)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
  561. r_error.error = Callable::CallError::CALL_OK;
  562. #ifdef DEBUG_METHODS_ENABLED
  563. (p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  564. #else
  565. (p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  566. #endif
  567. }
  568. template <class T, class R, class... P>
  569. 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) {
  570. #ifdef DEBUG_METHODS_ENABLED
  571. if ((size_t)p_argcount > sizeof...(P)) {
  572. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  573. r_error.argument = sizeof...(P);
  574. return;
  575. }
  576. if ((size_t)p_argcount < sizeof...(P)) {
  577. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  578. r_error.argument = sizeof...(P);
  579. return;
  580. }
  581. #endif
  582. call_with_variant_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  583. }
  584. template <class T, class R, class... P, size_t... Is>
  585. 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...>) {
  586. r_error.error = Callable::CallError::CALL_OK;
  587. #ifdef DEBUG_METHODS_ENABLED
  588. r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  589. #else
  590. r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
  591. #endif
  592. (void)p_args;
  593. }
  594. template <class R, class... P>
  595. void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
  596. #ifdef DEBUG_METHODS_ENABLED
  597. if ((size_t)p_argcount > sizeof...(P)) {
  598. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  599. r_error.argument = sizeof...(P);
  600. return;
  601. }
  602. if ((size_t)p_argcount < sizeof...(P)) {
  603. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  604. r_error.argument = sizeof...(P);
  605. return;
  606. }
  607. #endif
  608. call_with_variant_args_static_ret<R, P...>(p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  609. }
  610. template <class... P>
  611. void call_with_variant_args_static_ret(void (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
  612. #ifdef DEBUG_METHODS_ENABLED
  613. if ((size_t)p_argcount > sizeof...(P)) {
  614. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  615. r_error.argument = sizeof...(P);
  616. return;
  617. }
  618. if ((size_t)p_argcount < sizeof...(P)) {
  619. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  620. r_error.argument = sizeof...(P);
  621. return;
  622. }
  623. #endif
  624. call_with_variant_args_static<P...>(p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
  625. }
  626. template <class T, class R, class... P>
  627. 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) {
  628. #ifdef DEBUG_METHODS_ENABLED
  629. if ((size_t)p_argcount > sizeof...(P)) {
  630. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  631. r_error.argument = sizeof...(P);
  632. return;
  633. }
  634. if ((size_t)p_argcount < sizeof...(P)) {
  635. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  636. r_error.argument = sizeof...(P);
  637. return;
  638. }
  639. #endif
  640. call_with_variant_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  641. }
  642. template <class T, class R, class... P, size_t... Is>
  643. 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...>) {
  644. r_error.error = Callable::CallError::CALL_OK;
  645. #ifdef DEBUG_METHODS_ENABLED
  646. r_ret = (p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  647. #else
  648. r_ret = (p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...);
  649. #endif
  650. (void)p_args;
  651. }
  652. template <class T, class R, class... P>
  653. 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) {
  654. #ifdef DEBUG_ENABLED
  655. if ((size_t)p_argcount > sizeof...(P)) {
  656. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  657. r_error.argument = sizeof...(P);
  658. return;
  659. }
  660. #endif
  661. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  662. int32_t dvs = default_values.size();
  663. #ifdef DEBUG_ENABLED
  664. if (missing > dvs) {
  665. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  666. r_error.argument = sizeof...(P);
  667. return;
  668. }
  669. #endif
  670. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  671. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  672. if (i < p_argcount) {
  673. args[i] = p_args[i];
  674. } else {
  675. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  676. }
  677. }
  678. call_with_variant_args_retc_static_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  679. }
  680. template <class T, class... P, size_t... Is>
  681. void call_with_variant_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
  682. r_error.error = Callable::CallError::CALL_OK;
  683. #ifdef DEBUG_METHODS_ENABLED
  684. (p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
  685. #else
  686. (p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...);
  687. #endif
  688. (void)p_args;
  689. }
  690. template <class T, class... P>
  691. void call_with_variant_args_static_helper_dv(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, int p_argcount, const Vector<Variant> &default_values, Callable::CallError &r_error) {
  692. #ifdef DEBUG_ENABLED
  693. if ((size_t)p_argcount > sizeof...(P)) {
  694. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  695. r_error.argument = sizeof...(P);
  696. return;
  697. }
  698. #endif
  699. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  700. int32_t dvs = default_values.size();
  701. #ifdef DEBUG_ENABLED
  702. if (missing > dvs) {
  703. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  704. r_error.argument = sizeof...(P);
  705. return;
  706. }
  707. #endif
  708. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  709. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  710. if (i < p_argcount) {
  711. args[i] = p_args[i];
  712. } else {
  713. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  714. }
  715. }
  716. call_with_variant_args_static_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
  717. }
  718. template <class R, class... P>
  719. void call_with_variant_args_static_ret_dv(R (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) {
  720. #ifdef DEBUG_ENABLED
  721. if ((size_t)p_argcount > sizeof...(P)) {
  722. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  723. r_error.argument = sizeof...(P);
  724. return;
  725. }
  726. #endif
  727. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  728. int32_t dvs = default_values.size();
  729. #ifdef DEBUG_ENABLED
  730. if (missing > dvs) {
  731. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  732. r_error.argument = sizeof...(P);
  733. return;
  734. }
  735. #endif
  736. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  737. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  738. if (i < p_argcount) {
  739. args[i] = p_args[i];
  740. } else {
  741. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  742. }
  743. }
  744. call_with_variant_args_static_ret(p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
  745. }
  746. template <class... P>
  747. void call_with_variant_args_static_dv(void (*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error, const Vector<Variant> &default_values) {
  748. #ifdef DEBUG_ENABLED
  749. if ((size_t)p_argcount > sizeof...(P)) {
  750. r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  751. r_error.argument = sizeof...(P);
  752. return;
  753. }
  754. #endif
  755. int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
  756. int32_t dvs = default_values.size();
  757. #ifdef DEBUG_ENABLED
  758. if (missing > dvs) {
  759. r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  760. r_error.argument = sizeof...(P);
  761. return;
  762. }
  763. #endif
  764. const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
  765. for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
  766. if (i < p_argcount) {
  767. args[i] = p_args[i];
  768. } else {
  769. args[i] = &default_values[i - p_argcount + (dvs - missing)];
  770. }
  771. }
  772. call_with_variant_args_static(p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
  773. }
  774. #if defined(__GNUC__) && !defined(__clang__)
  775. #pragma GCC diagnostic pop
  776. #endif
  777. #endif // BINDER_COMMON_H