Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

669 rader
29 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright © 2017—2020 Sam Hocevar <sam@hocevar.net>
  5. // © 2009—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
  6. //
  7. // Lol Engine is free software. It comes without any warranty, to
  8. // the extent permitted by applicable law. You can redistribute it
  9. // and/or modify it under the terms of the Do What the Fuck You Want
  10. // to Public License, Version 2, as published by the WTFPL Task Force.
  11. // See http://www.wtfpl.net/ for more details.
  12. //
  13. #pragma once
  14. extern "C" {
  15. #include "3rdparty/lua/lua.h"
  16. #include "3rdparty/lua/lualib.h"
  17. #include "3rdparty/lua/lauxlib.h"
  18. }
  19. #include <vector> // std::vector
  20. #include <string> // std::string
  21. #include <cstdlib> // tolower
  22. //
  23. // Base Lua class for Lua script loading
  24. //
  25. namespace lol
  26. {
  27. //-----------------------------------------------------------------------------
  28. namespace Lolua
  29. {
  30. //-----------------------------------------------------------------------------
  31. typedef luaL_Reg ClassMethod;
  32. typedef struct ClassVar
  33. {
  34. const char *name;
  35. lua_CFunction get;
  36. lua_CFunction set;
  37. } ClassVar;
  38. //-----------------------------------------------------------------------------
  39. class Object
  40. {
  41. public:
  42. //-----------------------------------------------------------------------------
  43. struct Library
  44. {
  45. typedef struct ClassVarStr
  46. {
  47. ClassVarStr() { }
  48. ClassVarStr(std::string const &var_name, lua_CFunction get, lua_CFunction set)
  49. {
  50. m_get_name = std::string("Get") + var_name;
  51. m_set_name = std::string("Set") + var_name;
  52. m_get = get;
  53. m_set = set;
  54. }
  55. std::string m_get_name = "";
  56. std::string m_set_name = "";
  57. lua_CFunction m_get = nullptr;
  58. lua_CFunction m_set = nullptr;
  59. } ClassVarStr;
  60. Library(std::string const &class_name,
  61. std::vector<ClassMethod> const& statics,
  62. std::vector<ClassMethod> const& methods,
  63. std::vector<ClassVar> const& variables)
  64. {
  65. m_class_name = class_name;
  66. m_static_name = class_name + "_lib";
  67. m_method_name = class_name + "_inst";
  68. m_statics = statics;
  69. if (m_statics.empty()
  70. || m_statics.back().name != nullptr
  71. || m_statics.back().func != nullptr)
  72. m_statics.push_back({ nullptr, nullptr });
  73. m_methods = methods;
  74. if (m_methods.empty()
  75. || m_methods.back().name != nullptr
  76. || m_methods.back().func != nullptr)
  77. m_methods.push_back({ nullptr, nullptr });
  78. for (ClassVar const& cv : variables)
  79. {
  80. if (cv.name && cv.get && cv.set)
  81. {
  82. m_variables.push_back({ cv.name, cv.get, cv.set });
  83. }
  84. }
  85. if (m_variables.empty()
  86. || variables.back().name != nullptr
  87. || variables.back().get != nullptr
  88. || variables.back().set != nullptr)
  89. m_variables.push_back(ClassVarStr());
  90. }
  91. std::string m_class_name = "";
  92. std::string m_static_name = "";
  93. std::string m_method_name = "";
  94. std::vector<ClassMethod> m_statics;
  95. std::vector<ClassMethod> m_methods;
  96. std::vector<ClassVarStr> m_variables;
  97. };
  98. public:
  99. Object() { }
  100. virtual ~Object() { }
  101. static Object* New(lua_State* l, int arg_nb)
  102. {
  103. UNUSED(l);
  104. UNUSED(arg_nb);
  105. ASSERT(false);
  106. return nullptr;
  107. }
  108. static const Library* GetLib() { ASSERT(false); return nullptr; }
  109. };
  110. //-----------------------------------------------------------------------------
  111. // Class available to link C++ class to Lua methods
  112. //--
  113. class ObjectHelper
  114. {
  115. private:
  116. //-------------------------------------------------------------------------
  117. ObjectHelper() { }
  118. virtual ~ObjectHelper() { }
  119. public:
  120. //-------------------------------------------------------------------------
  121. template <typename TLuaClass>
  122. static void Register(lua_State *l)
  123. {
  124. //Default statics
  125. static const luaL_Reg default_statics[]
  126. {
  127. { "New", New<TLuaClass> },
  128. { "Store", Store<TLuaClass> },
  129. { "__gc", Del<TLuaClass> },
  130. { "__tostring", ToString<TLuaClass> },
  131. { "__add", OpAdd<TLuaClass> },
  132. { "__sub", OpSubstract<TLuaClass> },
  133. { "__mul", OpMultiply<TLuaClass> },
  134. { "__div", OpDivide<TLuaClass> },
  135. { "__mod", OpModulo<TLuaClass> },
  136. { "__unm", OpUnaryNeg<TLuaClass> },
  137. { "__concat", OpConcat<TLuaClass> },
  138. { "__eq", CmpEqual<TLuaClass> },
  139. { "__lt", CmpLessThan<TLuaClass> },
  140. { "__le", CmpLessEqual<TLuaClass> },
  141. { NULL, NULL }
  142. };
  143. //Create Static metatable
  144. luaL_newmetatable(l, GetStaticName<TLuaClass>());
  145. //Register default statics and template one
  146. luaL_setfuncs(l, default_statics, 0);
  147. luaL_setfuncs(l, GetStaticMethods<TLuaClass>(), 0);
  148. //Push metatable on stack
  149. lua_pushvalue(l, -1);
  150. //Set the "__index" field of the metatable to point to itself, pops the stack
  151. lua_setfield(l, -1, "__index");
  152. //Set it global to validate the operation
  153. lua_setglobal(l, GetObjectName<TLuaClass>());
  154. //Repeat all the operations for instance metatable
  155. luaL_newmetatable(l, GetMethodName<TLuaClass>());
  156. luaL_setfuncs(l, GetInstanceMethods<TLuaClass>(), 0);
  157. lua_pushvalue(l, -1);
  158. lua_setfield(l, -1, "__index");
  159. //Create variables Get/Set
  160. const std::vector<Object::Library::ClassVarStr>& variables = GetVariables<TLuaClass>();
  161. for (const Object::Library::ClassVarStr& var : variables)
  162. {
  163. if (!var.m_get || !var.m_set)
  164. continue;
  165. //Add getter
  166. lua_pushcfunction(l, var.m_get);
  167. lua_setfield(l, -2, var.m_get_name.c_str());
  168. //Add setter
  169. lua_pushcfunction(l, var.m_set);
  170. lua_setfield(l, -2, var.m_set_name.c_str());
  171. }
  172. //Don't set it to global, but pop the stack to hide the metatable
  173. lua_pop(l, 1);
  174. }
  175. private:
  176. //-------------------------------------------------------------------------
  177. template <typename TLuaClass>
  178. static const Object::Library* GetLibrary()
  179. {
  180. const Object::Library* lib = TLuaClass::GetLib();
  181. ASSERT(lib);
  182. return lib;
  183. }
  184. public:
  185. //-------------------------------------------------------------------------
  186. template <typename TLuaClass>
  187. static const char* GetObjectName() { return GetLibrary<TLuaClass>()->m_class_name.c_str(); }
  188. template <typename TLuaClass>
  189. static const char* GetStaticName() { return GetLibrary<TLuaClass>()->m_static_name.c_str(); }
  190. template <typename TLuaClass>
  191. static const char* GetMethodName() { return GetLibrary<TLuaClass>()->m_method_name.c_str(); }
  192. template <typename TLuaClass>
  193. static const ClassMethod* GetStaticMethods() { return GetLibrary<TLuaClass>()->m_statics.data(); }
  194. template <typename TLuaClass>
  195. static const ClassMethod* GetInstanceMethods() { return GetLibrary<TLuaClass>()->m_methods.data(); }
  196. template <typename TLuaClass>
  197. static const std::vector<Object::Library::ClassVarStr>& GetVariables() { return GetLibrary<TLuaClass>()->m_variables; }
  198. protected:
  199. //-------------------------------------------------------------------------
  200. template <typename TLuaClass>
  201. static int New(lua_State* l)
  202. {
  203. //Number of arguments
  204. int n_args = lua_gettop(l);
  205. //Create user data
  206. TLuaClass** data = (TLuaClass**)lua_newuserdata(l, sizeof(TLuaClass*));
  207. *data = TLuaClass::New(l, n_args);
  208. //Retrieve instance table
  209. luaL_getmetatable(l, GetMethodName<TLuaClass>());
  210. //Set metatable to instance
  211. lua_setmetatable(l, -2);
  212. //Return 1 so Lua will get the UserData and clean the stack.
  213. return 1;
  214. }
  215. //-------------------------------------------------------------------------
  216. template <typename TLuaClass> static int Store(lua_State * l);
  217. template <typename TLuaClass> static int Del(lua_State * l);
  218. //-------------------------------------------------------------------------
  219. template <typename TLuaClass> static int ToString(lua_State* l) { UNUSED(l); ASSERT(false); return 0; }
  220. template <typename TLuaClass> static int OpAdd(lua_State* l) { UNUSED(l); ASSERT(false); return 0; }
  221. template <typename TLuaClass> static int OpSubstract(lua_State* l) { UNUSED(l); ASSERT(false); return 0; }
  222. template <typename TLuaClass> static int OpMultiply(lua_State* l) { UNUSED(l); ASSERT(false); return 0; }
  223. template <typename TLuaClass> static int OpDivide(lua_State* l) { UNUSED(l); ASSERT(false); return 0; }
  224. template <typename TLuaClass> static int OpModulo(lua_State* l) { UNUSED(l); ASSERT(false); return 0; }
  225. template <typename TLuaClass> static int OpUnaryNeg(lua_State* l) { UNUSED(l); ASSERT(false); return 0; }
  226. template <typename TLuaClass> static int OpConcat(lua_State* l) { UNUSED(l); ASSERT(false); return 0; }
  227. template <typename TLuaClass> static int CmpEqual(lua_State* l) { UNUSED(l); ASSERT(false); return 0; }
  228. template <typename TLuaClass> static int CmpLessThan(lua_State* l) { UNUSED(l); ASSERT(false); return 0; }
  229. template <typename TLuaClass> static int CmpLessEqual(lua_State* l) { UNUSED(l); ASSERT(false); return 0; }
  230. };
  231. //-----------------------------------------------------------------------------
  232. class Function
  233. {
  234. public:
  235. Function(lua_State* l, const char* name, int(*function)(lua_State*))
  236. {
  237. lua_pushcfunction(l, function);
  238. lua_setglobal(l, name);
  239. }
  240. };
  241. //-----------------------------------------------------------------------------
  242. // Stack: Main class that encapsulates everything -----------------------------
  243. //-----------------------------------------------------------------------------
  244. class Stack
  245. {
  246. //-------------------------------------------------------------------------
  247. public:
  248. static Stack Begin(lua_State* state, int32_t start_index = 1)
  249. {
  250. return Stack(state, start_index);
  251. }
  252. //-------------------------------------------------------------------------
  253. void SetIndex(int32_t index)
  254. {
  255. m_index = index;
  256. }
  257. //-------------------------------------------------------------------------
  258. int32_t End()
  259. {
  260. return m_result;
  261. }
  262. //-------------------------------------------------------------------------
  263. protected:
  264. Stack(lua_State* l, int32_t start_index = 1)
  265. {
  266. m_state = l;
  267. m_index = start_index;
  268. }
  269. public:
  270. virtual ~Stack() { }
  271. protected:
  272. int32_t GetArgs()
  273. {
  274. return lua_gettop(m_state);
  275. }
  276. public:
  277. //-------------------------------------------------------------------------
  278. //The encapsulating struct for pointers
  279. template<typename T>
  280. struct Ptr
  281. {
  282. public:
  283. T* m_value = nullptr;
  284. bool m_throw_error = false;
  285. //---------------------------------------------------------------------
  286. //m_value: Your stored value
  287. //throw_error: If true, lua will throw an error if the value get fails
  288. Ptr(T* value, bool throw_error = false)
  289. {
  290. m_value = value;
  291. m_throw_error = throw_error;
  292. }
  293. Ptr(const T*& value) { m_value = value; }
  294. inline operator T*() { return m_value; }
  295. inline T* operator ->() { return m_value; }
  296. inline Ptr<T>& operator=(T const*& value) { m_value = value; return *this; }
  297. };
  298. private:
  299. bool AllowGet(bool is_optional, bool value_validity)
  300. {
  301. bool is_nil = lua_isnil(m_state, m_index);
  302. if (!is_optional || (!is_nil && value_validity))
  303. {
  304. ASSERT(!is_nil); /* touky: should it assert, though ? */
  305. return true;
  306. }
  307. return false;
  308. }
  309. public:
  310. //-------------------------------------------------------------------------
  311. template<typename T> T Get() { return Get(InnerDefault<T>(), false); }
  312. template<typename T> T Get(T default_value) { return Get(default_value, true); }
  313. template<typename E> SafeEnum<E> GetEnum() { return GetEnum(InnerDefaultSafeEnum<E>(), false); }
  314. template<typename E> SafeEnum<E> GetEnum(SafeEnum<E> default_value) { return GetEnum(default_value, true); }
  315. template<typename P> Ptr<P> GetPtr() { return GetPtr(InnerDefaultPtr<P>(), false); }
  316. template<typename P> Ptr<P> GetPtr(Ptr<P> default_value) { return GetPtr(default_value, true); }
  317. private:
  318. //-------------------------------------------------------------------------
  319. template<typename T> T Get(T default_value, bool is_optional)
  320. {
  321. if (AllowGet(is_optional, InnerIsValid<T>()))
  322. return InnerGet(default_value);
  323. return default_value;
  324. }
  325. template<typename E> SafeEnum<E> GetEnum(SafeEnum<E> default_value, bool is_optional)
  326. {
  327. if (AllowGet(is_optional, InnerIsValidSafeEnum<E>()))
  328. return InnerGetSafeEnum(default_value);
  329. return default_value;
  330. }
  331. template<typename P> Ptr<P> GetPtr(Ptr<P> default_value, bool is_optional)
  332. {
  333. if (AllowGet(is_optional, InnerIsValidPtr<P>()))
  334. return InnerGetPtr(default_value);
  335. return default_value;
  336. }
  337. public:
  338. //-------------------------------------------------------------------------
  339. template<typename T> Stack& operator<<(T value) { m_result += InnerPush<T>(value); return *this; }
  340. template<typename E> Stack& operator<<(SafeEnum<E> value) { m_result += InnerPushSafeEnum<E>(value); return *this; }
  341. template<typename P> Stack& operator<<(Ptr<P> value) { m_result += InnerPushPtr<P>(value); return *this; }
  342. protected:
  343. //-------------------------------------------------------------------------
  344. #define INNER_ERROR "Your type is not implemented. For pointers, use LuaPtr<MyType>()"
  345. template<typename T> T InnerDefault() { return T(0); }
  346. template<typename T> bool InnerIsValid() { ASSERT(false, INNER_ERROR); return false; }
  347. template<typename T> T InnerGet(T value) { UNUSED(value); ASSERT(false, INNER_ERROR); return InnerDefault<T>(); }
  348. template<typename T> int InnerPush(T value) { UNUSED(value); ASSERT(false, INNER_ERROR); return 0; }
  349. #ifndef INNER_SAFE_ENUM
  350. // Gets the value for the given enum type.
  351. template<class T> static inline T FindValue(std::string const& name)
  352. {
  353. std::string needle = tolower(name);
  354. for (int i = 0; i < T::Max; ++i)
  355. if (tolower(T(i).tostring()).find(needle) != std::string::npos)
  356. return T(i);
  357. return T::Max;
  358. }
  359. template<typename E> SafeEnum<E> InnerDefaultSafeEnum() { return SafeEnum<E>(); }
  360. template<typename E> bool InnerIsValidSafeEnum() { return InnerIsValid<std::string>(); }
  361. template<typename E> SafeEnum<E> InnerGetSafeEnum(SafeEnum<E> value) { return FindValue<SafeEnum<E> >(InnerGet<std::string>(value.tostring())); }
  362. template<typename E> int InnerPushSafeEnum(SafeEnum<E> value) { return InnerPush<std::string>(value.tostring()); }
  363. #endif //STACK_STRING
  364. #ifndef INNER_PTR
  365. template<typename P> inline Ptr<P> InnerDefaultPtr() { return Ptr<P>(nullptr); }
  366. template<typename P> inline bool InnerIsValidPtr() { return !!lua_isuserdata(m_state, m_index); }
  367. template<typename P> inline Ptr<P> InnerGetPtr(Ptr<P> value)
  368. {
  369. P** obj = static_cast<P**>(value.m_throw_error
  370. ? luaL_checkudata(m_state, m_index++, ObjectHelper::GetMethodName<P>())
  371. : luaL_testudata(m_state, m_index++, ObjectHelper::GetMethodName<P>()) );
  372. return Ptr<P>(obj ? *obj : value.m_value);
  373. }
  374. template<typename P> inline int InnerPushPtr(Ptr<P> value)
  375. {
  376. P** data = (P**)lua_newuserdata(m_state, sizeof(P*));
  377. *data = value.m_value;
  378. return 1;
  379. }
  380. #endif //STACK_STRING
  381. //-------------------------------------------------------------------------
  382. private:
  383. lua_State* m_state = nullptr;
  384. int32_t m_index = 1;
  385. int32_t m_result = 0;
  386. };
  387. //-----------------------------------------------------------------------------
  388. #define /***/ LOLUA_VAR_1(a00) auto v00 = s.a00;
  389. #define /***/ LOLUA_VAR_2(a00, a01) LOLUA_VAR_1(a00) auto v01 = s.a01;
  390. #define /***/ LOLUA_VAR_3(a00, a01, a02) LOLUA_VAR_2(a00, a01) auto v02 = s.a02;
  391. #define /***/ LOLUA_VAR_4(a00, a01, a02, a03) LOLUA_VAR_3(a00, a01, a02) auto v03 = s.a03;
  392. #define /***/ LOLUA_VAR_5(a00, a01, a02, a03, a04) LOLUA_VAR_4(a00, a01, a02, a03) auto v04 = s.a04;
  393. #define /***/ LOLUA_VAR_6(a00, a01, a02, a03, a04, a05) LOLUA_VAR_5(a00, a01, a02, a03, a04) auto v05 = s.a05;
  394. #define /***/ LOLUA_VAR_7(a00, a01, a02, a03, a04, a05, a06) LOLUA_VAR_6(a00, a01, a02, a03, a04, a05) auto v06 = s.a06;
  395. #define /***/ LOLUA_VAR_8(a00, a01, a02, a03, a04, a05, a06, a07) LOLUA_VAR_7(a00, a01, a02, a03, a04, a05, a06) auto v07 = s.a07;
  396. #define /***/ LOLUA_VAR_9(a00, a01, a02, a03, a04, a05, a06, a07, a08) LOLUA_VAR_8(a00, a01, a02, a03, a04, a05, a06, a07) auto v08 = s.a08;
  397. #define /**/ LOLUA_VAR_10(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09) LOLUA_VAR_9(a00, a01, a02, a03, a04, a05, a06, a07, a08) auto v09 = s.a09;
  398. #define /**/ LOLUA_VAR_11(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09, a10) LOLUA_VAR_10(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09) auto v10 = s.a10;
  399. #define /**/ LOLUA_VAR_12(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09, a10, a11) LOLUA_VAR_11(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09) auto v11 = s.a11;
  400. //-----------------------------------------------------------------------------
  401. #define /***/ LOLUA_ARG_1(a00) v00
  402. #define /***/ LOLUA_ARG_2(a00, a01) LOLUA_ARG_1(a00), v01
  403. #define /***/ LOLUA_ARG_3(a00, a01, a02) LOLUA_ARG_2(a00, a01), v02
  404. #define /***/ LOLUA_ARG_4(a00, a01, a02, a03) LOLUA_ARG_3(a00, a01, a02), v03
  405. #define /***/ LOLUA_ARG_5(a00, a01, a02, a03, a04) LOLUA_ARG_4(a00, a01, a02, a03), v04
  406. #define /***/ LOLUA_ARG_6(a00, a01, a02, a03, a04, a05) LOLUA_ARG_5(a00, a01, a02, a03, a04), v05
  407. #define /***/ LOLUA_ARG_7(a00, a01, a02, a03, a04, a05, a06) LOLUA_ARG_6(a00, a01, a02, a03, a04, a05), v06
  408. #define /***/ LOLUA_ARG_8(a00, a01, a02, a03, a04, a05, a06, a07) LOLUA_ARG_7(a00, a01, a02, a03, a04, a05, a06), v07
  409. #define /***/ LOLUA_ARG_9(a00, a01, a02, a03, a04, a05, a06, a07, a08) LOLUA_ARG_8(a00, a01, a02, a03, a04, a05, a06, a07), v08
  410. #define /**/ LOLUA_ARG_10(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09) LOLUA_ARG_9(a00, a01, a02, a03, a04, a05, a06, a07, a08), v09
  411. #define /**/ LOLUA_ARG_11(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09, a10) LOLUA_ARG_10(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09), v10
  412. #define /**/ LOLUA_ARG_12(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09, a10, a11) LOLUA_ARG_11(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09), v11
  413. //-----------------------------------------------------------------------------
  414. //-----------------------------------------------------------------------------
  415. #define LOLUA_DECLARE_BEGIN(LUA_FUNC_NAME, INSTANCE_GET) \
  416. static int LUA_FUNC_NAME(lua_State* l) \
  417. { \
  418. auto s = Lolua::Stack::Begin(l); \
  419. auto o = s.INSTANCE_GET;
  420. #define LOLUA_DECLARE_VARS(...) \
  421. LOL_CALL(LOL_CAT(LOLUA_VAR_, LOL_CALL(LOL_COUNT_TO_12, (__VA_ARGS__))), (__VA_ARGS__));
  422. #define LOLUA_DECLARE_CALL(INSTANCE_CALL, ...) \
  423. o->INSTANCE_CALL(LOL_CALL(LOL_CAT(LOLUA_ARG_, LOL_CALL(LOL_COUNT_TO_12, (__VA_ARGS__))), (__VA_ARGS__)));
  424. #define LOLUA_DECLARE_CALL_VOID(INSTANCE_CALL) \
  425. o->INSTANCE_CALL();
  426. #define LOLUA_DECLARE_END \
  427. return s.End(); \
  428. }
  429. //-----------------------------------------------------------------------------
  430. #define LOLUA_DECLARE_VOID_METHOD_VOID(LUA_FUNC_NAME, INSTANCE_GET, INSTANCE_CALL, ...) \
  431. LOLUA_DECLARE_BEGIN(LUA_FUNC_NAME, INSTANCE_GET); \
  432. LOLUA_DECLARE_CALL_VOID(INSTANCE_CALL) \
  433. LOLUA_DECLARE_END
  434. #define LOLUA_DECLARE_VOID_METHOD_ARGS(LUA_FUNC_NAME, INSTANCE_GET, INSTANCE_CALL, ...) \
  435. LOLUA_DECLARE_BEGIN(LUA_FUNC_NAME, INSTANCE_GET); \
  436. LOLUA_DECLARE_VARS(__VA_ARGS__) \
  437. LOLUA_DECLARE_CALL(INSTANCE_CALL, __VA_ARGS__) \
  438. LOLUA_DECLARE_END
  439. //-----------------------------------------------------------------------------
  440. #define LOLUA_DECLARE_RETURN_METHOD_ARGS(LUA_FUNC_NAME, INSTANCE_GET, INSTANCE_CALL, ...) \
  441. static int LUA_FUNC_NAME(lua_State* l) \
  442. { \
  443. auto s = Lolua::Stack::Begin(l); \
  444. auto o = s.INSTANCE_GET; \
  445. LOL_CALL(LOL_CAT(LOLUA_VAR_, LOL_CALL(LOL_COUNT_TO_12, (__VA_ARGS__))), (__VA_ARGS__)) \
  446. s << o->INSTANCE_CALL(LOL_CALL(LOL_CAT(LOLUA_ARG_, LOL_CALL(LOL_COUNT_TO_12, (__VA_ARGS__))), (__VA_ARGS__))); \
  447. return s.End(); \
  448. }
  449. //-----------------------------------------------------------------------------
  450. #ifndef REGION_STACK_VAR
  451. #ifndef STACK_BOOL
  452. template<> inline bool Stack::InnerIsValid<bool>() { return lua_isboolean(m_state, m_index); }
  453. template<> inline bool Stack::InnerGet<bool>(bool value) { UNUSED(value); return !!lua_toboolean(m_state, m_index++); }
  454. template<> inline int Stack::InnerPush<bool>(bool value) { lua_pushboolean(m_state, value); return 1; }
  455. #endif // STACK_BOOL
  456. //-----------------------------------------------------------------------------
  457. #ifndef STACK_CHAR_CONST
  458. template<> inline bool Stack::InnerIsValid<char const*>() { return !!lua_isstring(m_state, m_index); }
  459. template<> inline char const* Stack::InnerGet<char const*>(char const* value) { UNUSED(value); return lua_tostring(m_state, m_index++); }
  460. template<> inline int Stack::InnerPush<char const*>(char const* value) { lua_pushstring(m_state, value); return 1; }
  461. #endif // STACK_CHAR_CONST
  462. //-----------------------------------------------------------------------------
  463. #ifndef STACK_STRING
  464. template<> inline std::string Stack::InnerDefault<std::string>() { return ""; }
  465. template<> inline bool Stack::InnerIsValid<std::string>() { return InnerIsValid<char const*>(); }
  466. template<> inline std::string Stack::InnerGet<std::string>(std::string value) { return std::string(InnerGet<char const*>(value.c_str())); }
  467. template<> inline int Stack::InnerPush<std::string>(std::string value) { return InnerPush<char const*>(value.c_str()); }
  468. #endif //STACK_STRING
  469. //-----------------------------------------------------------------------------
  470. #ifndef STACK_STRING
  471. template<> inline bool Stack::InnerIsValid<double>() { return !!lua_isnumber(m_state, m_index); }
  472. template<> inline double Stack::InnerGet<double>(double value) { UNUSED(value); return lua_tonumber(m_state, m_index++); }
  473. template<> inline int Stack::InnerPush<double>(double value) { lua_pushnumber(m_state, value); return 1; }
  474. #endif //STACK_STRING
  475. //-----------------------------------------------------------------------------
  476. #ifndef STACK_FLOAT
  477. template<> inline bool Stack::InnerIsValid<float>() { return InnerIsValid<double>(); }
  478. template<> inline float Stack::InnerGet<float>(float value) { return (float)InnerGet<double>((double)value); }
  479. template<> inline int Stack::InnerPush<float>(float value) { return InnerPush<double>((double)value); }
  480. #endif //STACK_FLOAT
  481. //-----------------------------------------------------------------------------
  482. #ifndef STACK_INT64
  483. template<> inline bool Stack::InnerIsValid<int64_t>() { return !!lua_isnumber(m_state, m_index); }
  484. template<> inline int64_t Stack::InnerGet<int64_t>(int64_t value) { UNUSED(value); return lua_tointeger(m_state, m_index++); }
  485. template<> inline int Stack::InnerPush<int64_t>(int64_t value) { lua_pushinteger(m_state, value); return 1; }
  486. #endif //STACK_INT64
  487. //-----------------------------------------------------------------------------
  488. #ifndef STACK_UINT64
  489. template<> inline bool Stack::InnerIsValid<uint64_t>() { return !!lua_isnumber(m_state, m_index); }
  490. template<> inline uint64_t Stack::InnerGet<uint64_t>(uint64_t value) { UNUSED(value); return (uint64_t)lua_tointeger(m_state, m_index++); }
  491. template<> inline int Stack::InnerPush<uint64_t>(uint64_t value) { lua_pushinteger(m_state, (lua_Unsigned)value); return 1; }
  492. #endif //STACK_UINT64
  493. //-----------------------------------------------------------------------------
  494. #ifndef STACK_INT32
  495. template<> inline bool Stack::InnerIsValid<int32_t>() { return !!lua_isnumber(m_state, m_index); }
  496. template<> inline int32_t Stack::InnerGet<int32_t>(int32_t value) { UNUSED(value); return (int32_t)lua_tointeger(m_state, m_index++); }
  497. template<> inline int Stack::InnerPush<int32_t>(int32_t value) { lua_pushinteger(m_state, (lua_Integer)value); return 1; }
  498. #endif // STACK_INT32
  499. //-----------------------------------------------------------------------------
  500. #ifndef STACK_UINT32
  501. template<> inline bool Stack::InnerIsValid<uint32_t>() { return !!lua_isnumber(m_state, m_index); }
  502. template<> inline uint32_t Stack::InnerGet<uint32_t>(uint32_t value) { UNUSED(value); return (uint32_t)(lua_Unsigned)lua_tointeger(m_state, m_index++); }
  503. template<> inline int Stack::InnerPush<uint32_t>(uint32_t value) { lua_pushinteger(m_state, (lua_Unsigned)value); return 1; }
  504. #endif //STACK_UINT32
  505. //-----------------------------------------------------------------------------
  506. #ifndef STACK_VEC2
  507. template<> inline bool Stack::InnerIsValid<vec2>() { return InnerIsValid<float>(); }
  508. template<> inline vec2 Stack::InnerGet<vec2>(vec2 value) { return vec2(InnerGet<float>(value.x), Get<float>(value.y, true)); }
  509. template<> inline int Stack::InnerPush<vec2>(vec2 value) { return (InnerPush<float>(value.x) + InnerPush<float>(value.y)); }
  510. #endif //STACK_VEC2
  511. //-----------------------------------------------------------------------------
  512. #ifndef STACK_VEC3
  513. template<> inline bool Stack::InnerIsValid<vec3>() { return InnerIsValid<float>(); }
  514. template<> inline vec3 Stack::InnerGet<vec3>(vec3 value) { return vec3(InnerGet<float>(value.x), Get<float>(value.y, true), Get<float>(value.z, true)); }
  515. template<> inline int Stack::InnerPush<vec3>(vec3 value) { return (InnerPush<float>(value.x) + InnerPush<float>(value.y) + InnerPush<float>(value.z)); }
  516. #endif //STACK_VEC3
  517. //-----------------------------------------------------------------------------
  518. #ifndef STACK_VEC4
  519. template<> inline bool Stack::InnerIsValid<vec4>() { return InnerIsValid<float>(); }
  520. template<> inline vec4 Stack::InnerGet<vec4>(vec4 value) { return vec4(InnerGet<float>(value.x), Get<float>(value.y, true), Get<float>(value.z, true), Get<float>(value.w, true)); }
  521. template<> inline int Stack::InnerPush<vec4>(vec4 value) { return (InnerPush<float>(value.x) + InnerPush<float>(value.y) + InnerPush<float>(value.z) + InnerPush<float>(value.w)); }
  522. #endif // STACK_VEC4
  523. #endif //REGION_STACK_VAR
  524. //-----------------------------------------------------------------------------
  525. class Loader
  526. {
  527. friend class ObjectHelper;
  528. public:
  529. Loader();
  530. virtual ~Loader();
  531. bool ExecLuaFile(std::string const &lua);
  532. bool ExecLuaCode(std::string const &lua);
  533. //-------------------------------------------------------------------------
  534. #define DECLARE_LOADER_GET(T0, T1, GET_NAME) \
  535. template<typename T0> \
  536. T1 GET_NAME(std::string const &name) \
  537. { \
  538. lua_getglobal(m_lua_state, name.c_str()); \
  539. auto stack = Lolua::Stack::Begin(m_lua_state, -1); \
  540. auto result = stack.GET_NAME<T0>(); \
  541. lua_pop(m_lua_state, 1); \
  542. return result; \
  543. }
  544. DECLARE_LOADER_GET(T, T, Get);
  545. DECLARE_LOADER_GET(E, SafeEnum<E>, GetEnum);
  546. DECLARE_LOADER_GET(P, P*, GetPtr);
  547. #undef DECLARE_LOADER_GET
  548. protected:
  549. lua_State* GetLuaState();
  550. static void Store(lua_State* l, Loader* loader);
  551. static void Release(lua_State* l, Loader* loader);
  552. static void StoreObject(lua_State* l, Object* obj);
  553. //Virtual Store lua object ------------------------------------------------
  554. virtual void Store(Object* obj) { UNUSED(obj); }
  555. private:
  556. lua_State* m_lua_state;
  557. };
  558. //-----------------------------------------------------------------------------
  559. // ObjectHelper member implementations that require VarPtr
  560. template <typename TLuaClass>
  561. int ObjectHelper::Store(lua_State * l)
  562. {
  563. auto stack = Lolua::Stack::Begin(l);
  564. TLuaClass* obj = stack.GetPtr<TLuaClass>();
  565. ASSERT(obj);
  566. Loader::StoreObject(l, obj);
  567. return 0;
  568. }
  569. template <typename TLuaClass>
  570. int ObjectHelper::Del(lua_State * l)
  571. {
  572. auto stack = Lolua::Stack::Begin(l);
  573. TLuaClass* obj = stack.GetPtr<TLuaClass>();
  574. ASSERT(obj);
  575. delete obj;
  576. return 0;
  577. }
  578. } /* namespace Lolua */
  579. //TYPEDEFS
  580. typedef Lolua::Function LuaFunction;
  581. typedef Lolua::ObjectHelper LuaObjectHelper;
  582. typedef Lolua::Object LuaObject;
  583. typedef Lolua::Object::Library LuaObjectLibrary;
  584. typedef Lolua::Loader LuaLoader;
  585. typedef Lolua::Stack LuaStack;
  586. template <typename P> using LuaPtr = Lolua::Stack::Ptr<P>;
  587. } /* namespace lol */