You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

648 lines
28 KiB

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