LuaBinder.h 16 KB

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