LuaCallWrapper.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. * LuaCallWrapper.h, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #pragma once
  11. #include "api/Registry.h"
  12. #include "LuaStack.h"
  13. namespace scripting
  14. {
  15. namespace detail
  16. {
  17. template<int ...>
  18. struct Seq {};
  19. template<int N, int ...S>
  20. struct Gens : Gens<N-1, N-1, S...> {};
  21. template<int ...S>
  22. struct Gens<0, S...>
  23. {
  24. typedef Seq<S...> type;
  25. };
  26. template <typename R, typename ... Args>
  27. class LuaArgumentsTuple
  28. {
  29. public:
  30. using TupleData = std::tuple<Args ...>;
  31. using Functor = R(*)(Args ...);
  32. TupleData args;
  33. Functor f;
  34. LuaArgumentsTuple(Functor _f)
  35. :f(_f),
  36. args()
  37. {
  38. }
  39. STRONG_INLINE int invoke(lua_State * L)
  40. {
  41. return callFunc(L, typename Gens<sizeof...(Args)>::type());
  42. }
  43. private:
  44. template<int ...N>
  45. int callFunc(lua_State * L, Seq<N...>)
  46. {
  47. LuaStack S(L);
  48. bool ok[sizeof...(Args)] = {(S.tryGet(N+1, std::get<N>(args)))...};
  49. if(std::count(std::begin(ok), std::end(ok), false) > 0)
  50. return S.retVoid();
  51. R ret = f(std::get<N>(args) ...);
  52. S.clear();
  53. S.push(ret);
  54. return 1;
  55. }
  56. };
  57. class LuaFunctionInvoker
  58. {
  59. public:
  60. template<typename R, typename ... Args>
  61. static STRONG_INLINE int invoke(lua_State * L, R(*f)(Args ...))
  62. {
  63. LuaArgumentsTuple<R, Args ...> args(f);
  64. return args.invoke(L);
  65. }
  66. };
  67. }
  68. template <typename F, F f>
  69. class LuaFunctionWrapper
  70. {
  71. public:
  72. static int invoke(lua_State * L)
  73. {
  74. return detail::LuaFunctionInvoker::invoke(L, f);
  75. }
  76. };
  77. //TODO: this should be the only one wrapper type
  78. //
  79. template <typename U, typename M, M m>
  80. class LuaMethodWrapper
  81. {
  82. };
  83. template <typename U, typename T, typename R, R(T:: * method)()const>
  84. class LuaMethodWrapper <U, R(T:: *)()const, method>
  85. {
  86. public:
  87. static int invoke(lua_State * L)
  88. {
  89. LuaStack S(L);
  90. const U * obj = nullptr;
  91. if(!S.tryGet(1,obj))
  92. return S.retVoid();
  93. static auto functor = std::mem_fn(method);
  94. S.clear();
  95. S.push(functor(obj));
  96. return S.retPushed();
  97. }
  98. };
  99. template <typename U, typename T, typename R, R(T:: * method)()>
  100. class LuaMethodWrapper <U, R(T:: *)(), method>
  101. {
  102. public:
  103. static int invoke(lua_State * L)
  104. {
  105. LuaStack S(L);
  106. U * obj = nullptr;
  107. if(!S.tryGet(1,obj))
  108. return S.retVoid();
  109. static auto functor = std::mem_fn(method);
  110. S.clear();
  111. S.push(functor(obj));
  112. return S.retPushed();
  113. }
  114. };
  115. template <typename U, typename T, void(T:: * method)()const>
  116. class LuaMethodWrapper <U, void(T:: *)()const, method>
  117. {
  118. public:
  119. static int invoke(lua_State * L)
  120. {
  121. LuaStack S(L);
  122. const U * obj = nullptr;
  123. if(!S.tryGet(1,obj))
  124. return S.retVoid();
  125. static auto functor = std::mem_fn(method);
  126. S.clear();
  127. functor(obj);
  128. return 0;
  129. }
  130. };
  131. template <typename U, typename T, void(T:: * method)()>
  132. class LuaMethodWrapper <U, void(T:: *)(), method>
  133. {
  134. public:
  135. static int invoke(lua_State * L)
  136. {
  137. LuaStack S(L);
  138. U * obj = nullptr;
  139. if(!S.tryGet(1,obj))
  140. return S.retVoid();
  141. static auto functor = std::mem_fn(method);
  142. S.clear();
  143. functor(obj);
  144. return 0;
  145. }
  146. };
  147. template <typename U, typename T, typename R, typename P1, R(T:: * method)(P1)const>
  148. class LuaMethodWrapper <U, R(T:: *)(P1)const, method>
  149. {
  150. public:
  151. static int invoke(lua_State * L)
  152. {
  153. LuaStack S(L);
  154. const U * obj = nullptr;
  155. if(!S.tryGet(1,obj))
  156. return S.retVoid();
  157. P1 p1;
  158. if(!S.tryGet(2, p1))
  159. return S.retVoid();
  160. static auto functor = std::mem_fn(method);
  161. S.clear();
  162. S.push(functor(obj, p1));
  163. return S.retPushed();
  164. }
  165. };
  166. template <typename U, typename T, typename R, typename P1, R(T:: * method)(P1)>
  167. class LuaMethodWrapper <U, R(T:: *)(P1), method>
  168. {
  169. public:
  170. static int invoke(lua_State * L)
  171. {
  172. LuaStack S(L);
  173. U * obj = nullptr;
  174. if(!S.tryGet(1,obj))
  175. return S.retVoid();
  176. P1 p1;
  177. if(!S.tryGet(2, p1))
  178. return S.retVoid();
  179. static auto functor = std::mem_fn(method);
  180. S.clear();
  181. S.push(functor(obj, p1));
  182. return S.retPushed();
  183. }
  184. };
  185. template <typename U, typename T, typename P1, void(T:: * method)(P1)const>
  186. class LuaMethodWrapper <U, void(T:: *)(P1)const, method>
  187. {
  188. public:
  189. static int invoke(lua_State * L)
  190. {
  191. LuaStack S(L);
  192. const U * obj = nullptr;
  193. if(!S.tryGet(1,obj))
  194. return S.retVoid();
  195. P1 p1;
  196. if(!S.tryGet(2, p1))
  197. return S.retVoid();
  198. static auto functor = std::mem_fn(method);
  199. S.clear();
  200. functor(obj, p1);
  201. return 0;
  202. }
  203. };
  204. template <typename U, typename T, typename P1, void(T:: * method)(P1)>
  205. class LuaMethodWrapper <U, void(T:: *)(P1), method>
  206. {
  207. public:
  208. static int invoke(lua_State * L)
  209. {
  210. LuaStack S(L);
  211. U * obj = nullptr;
  212. if(!S.tryGet(1,obj))
  213. return S.retVoid();
  214. P1 p1;
  215. if(!S.tryGet(2, p1))
  216. return S.retVoid();
  217. static auto functor = std::mem_fn(method);
  218. S.clear();
  219. functor(obj, p1);
  220. return 0;
  221. }
  222. };
  223. template <typename U, typename T, typename R, typename P1, typename P2, R(T:: * method)(P1, P2)const>
  224. class LuaMethodWrapper <U, R(T:: *)(P1, P2)const, method>
  225. {
  226. public:
  227. static int invoke(lua_State * L)
  228. {
  229. LuaStack S(L);
  230. const U * obj = nullptr;
  231. if(!S.tryGet(1, obj))
  232. return S.retVoid();
  233. P1 p1;
  234. if(!S.tryGet(2, p1))
  235. return S.retVoid();
  236. P2 p2;
  237. if(!S.tryGet(3, p2))
  238. return S.retVoid();
  239. static auto functor = std::mem_fn(method);
  240. S.clear();
  241. S.push(functor(obj, p1, p2));
  242. return S.retPushed();
  243. }
  244. };
  245. template <typename U, typename T, typename P1, typename P2, void(T:: * method)(P1, P2)const>
  246. class LuaMethodWrapper <U, void(T:: *)(P1, P2)const, method>
  247. {
  248. public:
  249. static int invoke(lua_State * L)
  250. {
  251. LuaStack S(L);
  252. const U * obj = nullptr;
  253. if(!S.tryGet(1, obj))
  254. return S.retVoid();
  255. P1 p1;
  256. if(!S.tryGet(2, p1))
  257. return S.retVoid();
  258. P2 p2;
  259. if(!S.tryGet(3, p2))
  260. return S.retVoid();
  261. static auto functor = std::mem_fn(method);
  262. S.clear();
  263. functor(obj, p1, p2);
  264. return 0;
  265. }
  266. };
  267. }