LuaBinder.h 16 KB

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