LuaBinder.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. #ifndef ANKI_SCRIPT_LUA_BINDER_H
  2. #define ANKI_SCRIPT_LUA_BINDER_H
  3. #include "anki/util/Assert.h"
  4. #include "anki/util/StdTypes.h"
  5. #include "anki/util/Allocator.h"
  6. #include <lua.hpp>
  7. #ifndef ANKI_LUA_HPP
  8. # error "Wrong LUA header included"
  9. #endif
  10. #include <functional>
  11. namespace anki {
  12. //==============================================================================
  13. // Flags
  14. enum BinderFlag: U8
  15. {
  16. NONE = 0,
  17. TRANFER_OWNERSHIP = 1 ///< Transfer owneship to LUA garbage collector
  18. };
  19. inline BinderFlag operator|(BinderFlag a, BinderFlag b)
  20. {
  21. typedef std::underlying_type<BinderFlag>::type Int;
  22. return static_cast<BinderFlag>(static_cast<Int>(a) | static_cast<Int>(b));
  23. }
  24. inline BinderFlag operator&(BinderFlag a, BinderFlag b)
  25. {
  26. typedef std::underlying_type<BinderFlag>::type Int;
  27. return static_cast<BinderFlag>(static_cast<Int>(a) & static_cast<Int>(b));
  28. }
  29. /// Lua binder class. A wrapper on top of LUA
  30. class LuaBinder
  31. {
  32. public:
  33. template<typename T>
  34. using Allocator = HeapAllocator<T>;
  35. LuaBinder();
  36. ~LuaBinder();
  37. /// @name Accessors
  38. /// {
  39. lua_State* _getLuaState()
  40. {
  41. return m_l;
  42. }
  43. Allocator<U8> _getAllocator() const
  44. {
  45. return m_alloc;
  46. }
  47. /// }
  48. /// Expose a variable to the lua state
  49. template<typename T>
  50. void exposeVariable(const char* name, T* y);
  51. /// Evaluate a file
  52. void evalFile(const char* filename);
  53. /// Evaluate a string
  54. void evalString(const char* str);
  55. /// For debugging purposes
  56. static void stackDump(lua_State* l);
  57. private:
  58. Allocator<U8> m_alloc;
  59. lua_State* m_l = nullptr;
  60. };
  61. /// Internal lua stuff
  62. namespace detail {
  63. //==============================================================================
  64. /// lua userdata
  65. class UserData
  66. {
  67. public:
  68. void* m_ptr = nullptr;
  69. Bool8 m_gc = false; ///< Garbage collection on?
  70. };
  71. //==============================================================================
  72. /// Class identification
  73. template<typename Class>
  74. struct ClassProxy
  75. {
  76. static const char* NAME; ///< Used to check the signature of the user data
  77. static void setName(const char* name)
  78. {
  79. ANKI_ASSERT(NAME == nullptr && "Class already wrapped elsewhere");
  80. NAME = name;
  81. }
  82. static const char* getName()
  83. {
  84. ANKI_ASSERT(NAME != nullptr && "Class not wrapped");
  85. return NAME;
  86. }
  87. };
  88. template<typename Class>
  89. const char* ClassProxy<Class>::NAME = nullptr;
  90. //==============================================================================
  91. /// Make sure that the arguments match the argsCount number
  92. void checkArgsCount(lua_State* l, I argsCount);
  93. /// Create a new LUA class
  94. void createClass(lua_State* l, const char* className);
  95. /// Add new function in a class that it's already in the stack
  96. void pushCFunctionMethod(lua_State* l, const char* name,
  97. lua_CFunction luafunc);
  98. /// Add a new static function in the class
  99. void pushCFunctionStatic(lua_State* l, const char* className,
  100. const char* name, lua_CFunction luafunc);
  101. //==============================================================================
  102. /// Used mainly to push a method's return value to the stack
  103. template<typename Class, BinderFlag flags>
  104. struct PushStack
  105. {
  106. void operator()(lua_State* l, Class& x)
  107. {
  108. UserData* d = (UserData*)lua_newuserdata(l, sizeof(UserData));
  109. luaL_setmetatable(l, ClassProxy<Class>::getName());
  110. LuaBinder* binder = (LuaBinder*)lua_getuserdata(l);
  111. ANKI_ASSERT(binder);
  112. LuaBinder::Allocator<U8> alloc = binder->_getAllocator();
  113. d->m_ptr = alloc.template newInstance<Class>(x);
  114. d->m_gc = true;
  115. }
  116. };
  117. // Specialization ref
  118. template<typename Class, BinderFlag flags>
  119. struct PushStack<Class&, flags>
  120. {
  121. void operator()(lua_State* l, Class& x)
  122. {
  123. UserData* d = (UserData*)lua_newuserdata(l, sizeof(UserData));
  124. luaL_setmetatable(l, ClassProxy<Class>::getName());
  125. d->m_ptr = &x;
  126. d->m_gc = (flags & BinderFlag::TRANFER_OWNERSHIP) != BinderFlag::NONE;
  127. }
  128. };
  129. // Specialization const ref
  130. template<typename Class, BinderFlag flags>
  131. struct PushStack<const Class&, flags>
  132. {
  133. void operator()(lua_State* l, const Class& x)
  134. {
  135. UserData* d = (UserData*)lua_newuserdata(l, sizeof(UserData));
  136. luaL_setmetatable(l, ClassProxy<Class>::getName());
  137. d->m_ptr = &const_cast<Class&>(x);
  138. d->m_gc = (flags & BinderFlag::TRANFER_OWNERSHIP) != BinderFlag::NONE;
  139. }
  140. };
  141. // Specialization ptr
  142. template<typename Class, BinderFlag flags>
  143. struct PushStack<Class*, flags>
  144. {
  145. void operator()(lua_State* l, Class* x)
  146. {
  147. UserData* d = (UserData*)lua_newuserdata(l, sizeof(UserData));
  148. luaL_setmetatable(l, ClassProxy<Class>::getName());
  149. d->m_ptr = x;
  150. d->m_gc = (flags & BinderFlag::TRANFER_OWNERSHIP) != BinderFlag::NONE;
  151. }
  152. };
  153. // Specialization const ptr
  154. template<typename Class, BinderFlag flags>
  155. struct PushStack<const Class*, flags>
  156. {
  157. void operator()(lua_State* l, Class* x)
  158. {
  159. UserData* d = (UserData*)lua_newuserdata(l, sizeof(UserData));
  160. luaL_setmetatable(l, ClassProxy<Class>::getName());
  161. d->m_ptr = const_cast<Class*>(x);
  162. d->m_gc = (flags & BinderFlag::TRANFER_OWNERSHIP) != BinderFlag::NONE;
  163. }
  164. };
  165. // Specialization const char*
  166. template<BinderFlag flags>
  167. struct PushStack<const char*, flags>
  168. {
  169. void operator()(lua_State* l, const char* x)
  170. {
  171. lua_pushstring(l, x);
  172. }
  173. };
  174. #define ANKI_PUSH_STACK_TEMPLATE_SPECIALIZATION(Type_, luafunc_) \
  175. template<BinderFlag flags> \
  176. struct PushStack<Type_, flags> \
  177. { \
  178. void operator()(lua_State* l, Type_ x) \
  179. { \
  180. luafunc_(l, x); \
  181. } \
  182. };
  183. ANKI_PUSH_STACK_TEMPLATE_SPECIALIZATION(I8, lua_pushnumber)
  184. ANKI_PUSH_STACK_TEMPLATE_SPECIALIZATION(I16, lua_pushnumber)
  185. ANKI_PUSH_STACK_TEMPLATE_SPECIALIZATION(I32, lua_pushnumber)
  186. ANKI_PUSH_STACK_TEMPLATE_SPECIALIZATION(I64, lua_pushnumber)
  187. ANKI_PUSH_STACK_TEMPLATE_SPECIALIZATION(U8, lua_pushnumber)
  188. ANKI_PUSH_STACK_TEMPLATE_SPECIALIZATION(U16, lua_pushnumber)
  189. ANKI_PUSH_STACK_TEMPLATE_SPECIALIZATION(U32, lua_pushnumber)
  190. ANKI_PUSH_STACK_TEMPLATE_SPECIALIZATION(U64, lua_pushnumber)
  191. ANKI_PUSH_STACK_TEMPLATE_SPECIALIZATION(F64, lua_pushnumber)
  192. ANKI_PUSH_STACK_TEMPLATE_SPECIALIZATION(F32, lua_pushnumber)
  193. ANKI_PUSH_STACK_TEMPLATE_SPECIALIZATION(Bool, lua_pushnumber)
  194. //==============================================================================
  195. /// Used to get the function arguments from the stack
  196. template<typename Class, I stackIndex>
  197. struct StackGet
  198. {
  199. Class operator()(lua_State* l)
  200. {
  201. UserData* udata = (UserData*)luaL_checkudata(l, stackIndex,
  202. ClassProxy<Class>::getName());
  203. const Class* a = reinterpret_cast<const Class*>(udata->m_ptr);
  204. return Class(*a);
  205. }
  206. };
  207. // Specialization const ref
  208. template<typename Class, I stackIndex>
  209. struct StackGet<const Class&, stackIndex>
  210. {
  211. const Class& operator()(lua_State* l)
  212. {
  213. UserData* udata = (UserData*)luaL_checkudata(l, stackIndex,
  214. ClassProxy<Class>::getName());
  215. const Class* a = reinterpret_cast<const Class*>(udata->m_ptr);
  216. return *a;
  217. }
  218. };
  219. // Specialization ref
  220. template<typename Class, I stackIndex>
  221. struct StackGet<Class&, stackIndex>
  222. {
  223. Class& operator()(lua_State* l)
  224. {
  225. UserData* udata = (UserData*)luaL_checkudata(l, stackIndex,
  226. ClassProxy<Class>::getName());
  227. Class* a = reinterpret_cast<Class*>(udata->m_ptr);
  228. return *a;
  229. }
  230. };
  231. // Specialization const ptr
  232. template<typename Class, I stackIndex>
  233. struct StackGet<const Class*, stackIndex>
  234. {
  235. const Class* operator()(lua_State* l)
  236. {
  237. UserData* udata = (UserData*)luaL_checkudata(l, stackIndex,
  238. ClassProxy<Class>::getName());
  239. const Class* a = reinterpret_cast<const Class*>(udata->m_ptr);
  240. return a;
  241. }
  242. };
  243. // Specialization ptr
  244. template<typename Class, I stackIndex>
  245. struct StackGet<Class*, stackIndex>
  246. {
  247. Class* operator()(lua_State* l)
  248. {
  249. UserData* udata = (UserData*)luaL_checkudata(l, stackIndex,
  250. ClassProxy<Class>::getName());
  251. Class* a = reinterpret_cast<Class*>(udata->m_ptr);
  252. return a;
  253. }
  254. };
  255. #define ANKI_STACK_GET_TEMPLATE_SPECIALIZATION(Type_, luafunc_) \
  256. template<I stackIndex> \
  257. struct StackGet<Type_, stackIndex> \
  258. { \
  259. Type_ operator()(lua_State* l) \
  260. { \
  261. return luafunc_(l, stackIndex); \
  262. } \
  263. }; \
  264. template<I stackIndex> \
  265. struct StackGet<Type_&&, stackIndex> \
  266. { \
  267. Type_ operator()(lua_State* l) \
  268. { \
  269. return luafunc_(l, stackIndex); \
  270. } \
  271. }; \
  272. template<I stackIndex> \
  273. struct StackGet<Type_&, stackIndex> \
  274. { \
  275. Type_ operator()(lua_State* l) \
  276. { \
  277. return luafunc_(l, stackIndex); \
  278. } \
  279. }; \
  280. template<I stackIndex> \
  281. struct StackGet<Type_*, stackIndex> \
  282. { \
  283. Type_ operator()(lua_State* l) \
  284. { \
  285. return luafunc_(l, stackIndex); \
  286. } \
  287. };
  288. ANKI_STACK_GET_TEMPLATE_SPECIALIZATION(F32, luaL_checknumber)
  289. ANKI_STACK_GET_TEMPLATE_SPECIALIZATION(F64, luaL_checknumber)
  290. ANKI_STACK_GET_TEMPLATE_SPECIALIZATION(I8, luaL_checkinteger)
  291. ANKI_STACK_GET_TEMPLATE_SPECIALIZATION(I16, luaL_checkinteger)
  292. ANKI_STACK_GET_TEMPLATE_SPECIALIZATION(I32, luaL_checkinteger)
  293. ANKI_STACK_GET_TEMPLATE_SPECIALIZATION(I64, luaL_checkinteger)
  294. ANKI_STACK_GET_TEMPLATE_SPECIALIZATION(U8, luaL_checkunsigned)
  295. ANKI_STACK_GET_TEMPLATE_SPECIALIZATION(U16, luaL_checkunsigned)
  296. ANKI_STACK_GET_TEMPLATE_SPECIALIZATION(U32, luaL_checkunsigned)
  297. ANKI_STACK_GET_TEMPLATE_SPECIALIZATION(U64, luaL_checkunsigned)
  298. ANKI_STACK_GET_TEMPLATE_SPECIALIZATION(const char*, luaL_checkstring)
  299. ANKI_STACK_GET_TEMPLATE_SPECIALIZATION(Bool, luaL_checkunsigned)
  300. //==============================================================================
  301. /// Call a function
  302. template<typename T, BinderFlag flags>
  303. struct CallFunction;
  304. // R (_1)
  305. template<typename TReturn, typename Arg0, BinderFlag flags>
  306. struct CallFunction<TReturn (*)(Arg0), flags>
  307. {
  308. int operator()(lua_State* l, TReturn (*func)(Arg0))
  309. {
  310. TReturn out = (*func)(StackGet<Arg0, 1>()(l));
  311. PushStack<TReturn, flags> ps;
  312. ps(l, out);
  313. return 1;
  314. }
  315. };
  316. // R (_1, _2)
  317. template<typename TReturn, typename Arg0, typename Arg1, BinderFlag flags>
  318. struct CallFunction<TReturn (*)(Arg0, Arg1), flags>
  319. {
  320. int operator()(lua_State* l, TReturn (*func)(Arg0, Arg1))
  321. {
  322. TReturn out = (*func)(StackGet<Arg0, 1>()(l),
  323. StackGet<Arg1, 2>()(l));
  324. PushStack<TReturn, flags> ps;
  325. ps(l, out);
  326. return 1;
  327. }
  328. };
  329. // R (_1, _2, _3)
  330. template<typename TReturn, typename Arg0, typename Arg1, typename Arg2,
  331. BinderFlag flags>
  332. struct CallFunction<TReturn (*)(Arg0, Arg1, Arg2), flags>
  333. {
  334. int operator()(lua_State* l, TReturn (*func)(Arg0, Arg1, Arg2))
  335. {
  336. TReturn out = (*func)(StackGet<Arg0, 1>()(l),
  337. StackGet<Arg1, 2>()(l), StackGet<Arg2, 3>()(l));
  338. PushStack<TReturn, flags> ps;
  339. ps(l, out);
  340. return 1;
  341. }
  342. };
  343. // void (_1)
  344. template<typename Arg0, BinderFlag flags>
  345. struct CallFunction<void (*)(Arg0), flags>
  346. {
  347. int operator()(lua_State* l, void (*func)(Arg0))
  348. {
  349. (*func)(StackGet<Arg0, 1>()(l));
  350. return 0;
  351. }
  352. };
  353. // void (_1, _2)
  354. template<typename Arg0, typename Arg1, BinderFlag flags>
  355. struct CallFunction<void (*)(Arg0, Arg1), flags>
  356. {
  357. int operator()(lua_State* l, void (*func)(Arg0, Arg1))
  358. {
  359. (*func)(StackGet<Arg0, 1>()(l), StackGet<Arg1, 2>()(l));
  360. return 0;
  361. }
  362. };
  363. // void (_1, _2, _3)
  364. template<typename Arg0, typename Arg1, typename Arg2, BinderFlag flags>
  365. struct CallFunction<void (*)(Arg0, Arg1, Arg2), flags>
  366. {
  367. int operator()(lua_State* l, void (*func)(Arg0, Arg1, Arg2))
  368. {
  369. (*func)(StackGet<Arg0, 1>()(l), StackGet<Arg1, 2>()(l),
  370. StackGet<Arg2, 3>()(l));
  371. return 0;
  372. }
  373. };
  374. // void (_1, _2, _3, _4)
  375. template<typename Arg0, typename Arg1, typename Arg2, typename Arg3,
  376. BinderFlag flags>
  377. struct CallFunction<void (*)(Arg0, Arg1, Arg2, Arg3), flags>
  378. {
  379. int operator()(lua_State* l, void (*func)(Arg0, Arg1, Arg2, Arg3))
  380. {
  381. (*func)(StackGet<Arg0, 1>()(l), StackGet<Arg1, 2>()(l),
  382. StackGet<Arg2, 3>()(l), StackGet<Arg3, 4>()(l));
  383. return 0;
  384. }
  385. };
  386. // R (void)
  387. template<typename TReturn, BinderFlag flags>
  388. struct CallFunction<TReturn (*)(void), flags>
  389. {
  390. int operator()(lua_State* l, TReturn (*func)(void))
  391. {
  392. TReturn out = (*func)();
  393. PushStack<TReturn, flags> ps;
  394. ps(l, out);
  395. return 1;
  396. }
  397. };
  398. // void (void)
  399. template<BinderFlag flags>
  400. struct CallFunction<void (*)(void), flags>
  401. {
  402. int operator()(lua_State* /*l*/, void (*func)(void))
  403. {
  404. (*func)();
  405. return 0;
  406. }
  407. };
  408. //==============================================================================
  409. /// Call constructor
  410. template<typename Class, typename... Args>
  411. struct CallConstructor;
  412. // none
  413. template<typename Class>
  414. struct CallConstructor<Class>
  415. {
  416. Class* operator()(lua_State* l)
  417. {
  418. LuaBinder* binder = (LuaBinder*)lua_getuserdata(l);
  419. ANKI_ASSERT(binder);
  420. LuaBinder::Allocator<U8> alloc = binder->_getAllocator();
  421. return alloc.template newInstance<Class>();
  422. }
  423. };
  424. // _1
  425. template<typename Class, typename Arg0>
  426. struct CallConstructor<Class, Arg0>
  427. {
  428. Class* operator()(lua_State* l)
  429. {
  430. LuaBinder* binder = (LuaBinder*)lua_getuserdata(l);
  431. ANKI_ASSERT(binder);
  432. LuaBinder::Allocator<U8> alloc = binder->_getAllocator();
  433. return alloc.template newInstance<Class>(StackGet<Arg0, 1>()(l));
  434. }
  435. };
  436. // _1, _2
  437. template<typename Class, typename Arg0, typename Arg1>
  438. struct CallConstructor<Class, Arg0, Arg1>
  439. {
  440. Class* operator()(lua_State* l)
  441. {
  442. LuaBinder* binder = (LuaBinder*)lua_getuserdata(l);
  443. ANKI_ASSERT(binder);
  444. LuaBinder::Allocator<U8> alloc = binder->_getAllocator();
  445. return alloc.template newInstance<Class>(StackGet<Arg0, 1>()(l),
  446. StackGet<Arg1, 2>()(l));
  447. }
  448. };
  449. // _1, _2, _3
  450. template<typename Class, typename Arg0, typename Arg1, typename Arg2>
  451. struct CallConstructor<Class, Arg0, Arg1, Arg2>
  452. {
  453. Class* operator()(lua_State* l)
  454. {
  455. LuaBinder* binder = (LuaBinder*)lua_getuserdata(l);
  456. ANKI_ASSERT(binder);
  457. LuaBinder::Allocator<U8> alloc = binder->_getAllocator();
  458. return alloc.template newInstance<Class>(StackGet<Arg0, 1>()(l),
  459. StackGet<Arg1, 2>()(l), StackGet<Arg2, 3>()(l));
  460. }
  461. };
  462. // _1, _2, _3, _4
  463. template<typename Class, typename Arg0, typename Arg1, typename Arg2,
  464. typename Arg3>
  465. struct CallConstructor<Class, Arg0, Arg1, Arg2, Arg3>
  466. {
  467. Class* operator()(lua_State* l)
  468. {
  469. LuaBinder* binder = (LuaBinder*)lua_getuserdata(l);
  470. ANKI_ASSERT(binder);
  471. LuaBinder::Allocator<U8> alloc = binder->_getAllocator();
  472. return alloc.template newInstance<Class>(StackGet<Arg0, 1>()(l),
  473. StackGet<Arg1, 2>()(l), StackGet<Arg2, 3>()(l),
  474. StackGet<Arg3, 4>()(l));
  475. }
  476. };
  477. //==============================================================================
  478. /// Make a method function. Used like this:
  479. /// @code
  480. /// Foo foo; // An instance
  481. /// MethodFunctionalizer<decltype(&Foo::bar), &Foo::bar>::func(&foo, 123);
  482. /// // Equivelent of:
  483. /// foo.bar(123);
  484. /// @endcode
  485. template <typename T, T> struct MethodFunctionalizer;
  486. template <typename T, typename R, typename ...Args, R (T::* mf)(Args...)>
  487. struct MethodFunctionalizer<R (T::*)(Args...), mf>
  488. {
  489. static R func(T* obj, Args&&... args)
  490. {
  491. return (obj->*mf)(std::forward<Args>(args)...);
  492. }
  493. };
  494. template <typename T, typename R, typename ...Args, R (T::* mf)(Args...) const>
  495. struct MethodFunctionalizer<R (T::*)(Args...) const, mf>
  496. {
  497. static R func(const T* obj, Args&&... args)
  498. {
  499. return (obj->*mf)(std::forward<Args>(args)...);
  500. }
  501. };
  502. //==============================================================================
  503. /// Signature for constructor
  504. template<typename Class, typename... Args>
  505. struct ConstructorSignature
  506. {
  507. static int luafunc(lua_State* l)
  508. {
  509. checkArgsCount(l, sizeof...(Args));
  510. UserData* d = (UserData*)lua_newuserdata(l, sizeof(UserData));
  511. luaL_setmetatable(l, ClassProxy<Class>::getName());
  512. d->m_ptr = CallConstructor<Class, Args...>()(l);
  513. d->m_gc = true;
  514. return 1;
  515. }
  516. };
  517. //==============================================================================
  518. /// Destructor signature
  519. template<typename Class>
  520. struct DestructorSignature
  521. {
  522. static int luafunc(lua_State* l)
  523. {
  524. checkArgsCount(l, 1);
  525. UserData* d = (UserData*)luaL_checkudata(l, 1,
  526. ClassProxy<Class>::getName());
  527. if(d->m_gc)
  528. {
  529. Class* obj = reinterpret_cast<Class*>(d->m_ptr);
  530. LuaBinder* binder = (LuaBinder*)lua_getuserdata(l);
  531. ANKI_ASSERT(binder);
  532. LuaBinder::Allocator<U8> alloc = binder->_getAllocator();
  533. alloc.deleteInstance(obj);
  534. }
  535. return 0;
  536. }
  537. };
  538. //==============================================================================
  539. /// Function signature
  540. template<BinderFlag flags, typename T, T>
  541. struct FunctionSignature;
  542. template<BinderFlag flags, typename TReturn, typename... TArgs,
  543. TReturn (*f)(TArgs...)>
  544. struct FunctionSignature<flags, TReturn (*)(TArgs...), f>
  545. {
  546. static int luafunc(lua_State* l)
  547. {
  548. checkArgsCount(l, sizeof...(TArgs));
  549. CallFunction<decltype(f), flags> cf;
  550. return cf(l, f);
  551. }
  552. };
  553. } // end namespace detail
  554. //==============================================================================
  555. // Macros
  556. /// Don't use it directly
  557. #define ANKI_LUA_DESTRUCTOR() \
  558. detail::pushCFunctionMethod(l_, "__gc", \
  559. &detail::DestructorSignature<Class>::luafunc);
  560. /// Start wrapping a class. Don't add a destructor (if for example the class
  561. /// has a private derstructor)
  562. #define ANKI_LUA_CLASS_BEGIN_NO_DESTRUCTOR(luaBinder_, Class_) { \
  563. typedef Class_ Class; \
  564. lua_State* l_ = luaBinder_._getLuaState(); \
  565. detail::ClassProxy<Class>::setName(#Class_); \
  566. detail::createClass(l_, detail::ClassProxy<Class>::getName());
  567. /// Start wrapping a class
  568. #define ANKI_LUA_CLASS_BEGIN(luaBinder_, Class_) \
  569. ANKI_LUA_CLASS_BEGIN_NO_DESTRUCTOR(luaBinder_, Class_) \
  570. ANKI_LUA_DESTRUCTOR()
  571. /// End wrapping a class
  572. #define ANKI_LUA_CLASS_END() lua_settop(l_, 0); }
  573. /// Define a constructor. Call it from lua @code a = Foo.new(...) @endcode.
  574. #define ANKI_LUA_CONSTRUCTOR(...) \
  575. detail::pushCFunctionStatic(l_, \
  576. detail::ClassProxy<Class>::getName(), "new", \
  577. &detail::ConstructorSignature<Class, __VA_ARGS__>::luafunc);
  578. /// Define an empty constructor. Call it from lua @code a = Foo.new() @endcode.
  579. #define ANKI_LUA_EMPTY_CONSTRUCTOR() \
  580. detail::pushCFunctionStatic(l_, \
  581. detail::ClassProxy<Class>::getName(), "new", \
  582. &detail::ConstructorSignature<Class>::luafunc);
  583. /// Define a static method with flags
  584. #define ANKI_LUA_STATIC_METHOD_DETAIL( \
  585. name_, SMethodType_, smethodPtr_, flags_) \
  586. detail::pushCFunctionStatic(l_, \
  587. detail::ClassProxy<Class>::getName(), name_, \
  588. (&detail::FunctionSignature<flags_, \
  589. SMethodType_, smethodPtr_>::luafunc));
  590. /// Define a static method no flags
  591. #define ANKI_LUA_STATIC_METHOD(name_, smethodPtr_) \
  592. ANKI_LUA_STATIC_METHOD_DETAIL(name_, decltype(smethodPtr_), smethodPtr_, \
  593. BinderFlag::NONE)
  594. /// Define a function as method with flags
  595. #define ANKI_LUA_FUNCTION_AS_METHOD_DETAIL( \
  596. name_, FuncType_, funcPtr_, flags_) \
  597. detail::pushCFunctionMethod(l_, name_, \
  598. (&detail::FunctionSignature<flags_, FuncType_, \
  599. funcPtr_>::luafunc));
  600. /// Define a function as method no flags
  601. #define ANKI_LUA_FUNCTION_AS_METHOD(name_, funcPtr_) \
  602. ANKI_LUA_FUNCTION_AS_METHOD_DETAIL( \
  603. name_, decltype(funcPtr_), funcPtr_, BinderFlag::NONE)
  604. /// Define a method with flags
  605. #define ANKI_LUA_METHOD_DETAIL(name_, MethodType_, methodPtr_, flags_) \
  606. ANKI_LUA_FUNCTION_AS_METHOD_DETAIL(name_, \
  607. decltype(&detail::MethodFunctionalizer< \
  608. MethodType_, methodPtr_>::func), \
  609. (&detail::MethodFunctionalizer<MethodType_, methodPtr_>::func), \
  610. flags_)
  611. /// Define a method no flags
  612. #define ANKI_LUA_METHOD(name_, methodPtr_) \
  613. ANKI_LUA_METHOD_DETAIL(name_, decltype(methodPtr_), \
  614. methodPtr_, BinderFlag::NONE)
  615. //==============================================================================
  616. template<typename T>
  617. void LuaBinder::exposeVariable(const char* name, T* y)
  618. {
  619. using namespace detail;
  620. UserData* d = (UserData*)lua_newuserdata(m_l, sizeof(UserData));
  621. d->m_ptr = y;
  622. d->m_gc = false;
  623. luaL_setmetatable(m_l, ClassProxy<T>::getName());
  624. lua_setglobal(m_l, name);
  625. }
  626. } // end namespace anki
  627. #endif