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.

1054 lines
33 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 "lua/lua.hpp"
  14. //#include "lua/luawrapper.hpp"
  15. #pragma once
  16. namespace lol
  17. {
  18. typedef lua_State LuaState;
  19. //-----------------------------------------------------------------------------
  20. namespace Lolua
  21. {
  22. //-----------------------------------------------------------------------------
  23. typedef luaL_Reg ClassMethod;
  24. typedef struct ClassVar
  25. {
  26. const char *name;
  27. lua_CFunction get;
  28. lua_CFunction set;
  29. } ClassVar;
  30. //-----------------------------------------------------------------------------
  31. struct ObjectLib
  32. {
  33. typedef struct ClassVarStr
  34. {
  35. ClassVarStr() { }
  36. ClassVarStr(String var_name, lua_CFunction get, lua_CFunction set)
  37. {
  38. m_get_name = String("Get") + var_name;
  39. m_set_name = String("Set") + var_name;
  40. m_get = get;
  41. m_set = set;
  42. }
  43. String m_get_name = "";
  44. String m_set_name = "";
  45. lua_CFunction m_get = nullptr;
  46. lua_CFunction m_set = nullptr;
  47. } ClassVarStr;
  48. ObjectLib(String class_name,
  49. array<ClassMethod> const& statics,
  50. array<ClassMethod> const& methods,
  51. array<ClassVar> const& variables)
  52. {
  53. m_class_name = class_name;
  54. m_static_name = class_name + "_lib";
  55. m_method_name = class_name + "_inst";
  56. m_statics = statics;
  57. if (m_statics.count() == 0
  58. || m_statics.last().name != nullptr
  59. || m_statics.last().func != nullptr)
  60. m_statics.push({ nullptr, nullptr });
  61. m_methods = methods;
  62. if (m_methods.count() == 0
  63. || m_methods.last().name != nullptr
  64. || m_methods.last().func != nullptr)
  65. m_methods.push({ nullptr, nullptr });
  66. for (ClassVar const& cv : variables)
  67. {
  68. if (cv.name && cv.get && cv.set)
  69. {
  70. m_variables.push({ cv.name, cv.get, cv.set });
  71. }
  72. }
  73. if (m_variables.count() == 0
  74. || variables.last().name != nullptr
  75. || variables.last().get != nullptr
  76. || variables.last().set != nullptr)
  77. m_variables.push(ClassVarStr());
  78. }
  79. String m_class_name = "";
  80. String m_static_name = "";
  81. String m_method_name = "";
  82. array<ClassMethod> m_statics;
  83. array<ClassMethod> m_methods;
  84. array<ClassVarStr> m_variables;
  85. };
  86. //-----------------------------------------------------------------------------
  87. class Object
  88. {
  89. public:
  90. Object() { }
  91. virtual ~Object() { }
  92. static Object* New(LuaState* l, int arg_nb)
  93. {
  94. UNUSED(l);
  95. UNUSED(arg_nb);
  96. ASSERT(false);
  97. return nullptr;
  98. }
  99. static const ObjectLib* GetLib() { ASSERT(false); return nullptr; }
  100. };
  101. //-----------------------------------------------------------------------------
  102. // Class available to link C++ class to Lua methods
  103. //--
  104. class ObjectDef
  105. {
  106. public:
  107. //-------------------------------------------------------------------------
  108. ObjectDef() { }
  109. virtual ~ObjectDef() { }
  110. //-------------------------------------------------------------------------
  111. template <typename TLuaClass>
  112. static void Register(LuaState *l)
  113. {
  114. //Default statics
  115. static const luaL_Reg default_statics[]
  116. {
  117. { "New", New<TLuaClass> },
  118. { "Store", Store<TLuaClass> },
  119. { "__gc", Del<TLuaClass> },
  120. { NULL, NULL }
  121. };
  122. //TODO: Touky: Implement that
  123. //__tostring : ToString
  124. //__add : Addition(+)
  125. //__sub : Subtraction(-)
  126. //__mul : Multiplication(*)
  127. //__div : Division(/ )
  128. //__mod : Modulos(%)
  129. //__unm : Unary - , used for negation on numbers
  130. //__concat : Concatenation(..)
  131. //__eq : Equality(== )
  132. //__lt : Less than(<)
  133. //__le : Less than or equal to(<= )
  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<ObjectLib::ClassVarStr>& variables = GetVariables<TLuaClass>();
  152. for (const ObjectLib::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. template <typename TLuaClass>
  168. static const ObjectLib* GetLib()
  169. {
  170. const ObjectLib* lib = TLuaClass::GetLib();
  171. ASSERT(lib);
  172. return lib;
  173. }
  174. public:
  175. template <typename TLuaClass>
  176. static const char* GetObjectName() { return GetLib<TLuaClass>()->m_class_name.C(); }
  177. template <typename TLuaClass>
  178. static const char* GetStaticName() { return GetLib<TLuaClass>()->m_static_name.C(); }
  179. template <typename TLuaClass>
  180. static const char* GetMethodName() { return GetLib<TLuaClass>()->m_method_name.C(); }
  181. template <typename TLuaClass>
  182. static const ClassMethod* GetStaticMethods() { return GetLib<TLuaClass>()->m_statics.data(); }
  183. template <typename TLuaClass>
  184. static const ClassMethod* GetInstanceMethods() { return GetLib<TLuaClass>()->m_methods.data(); }
  185. template <typename TLuaClass>
  186. static const array<ObjectLib::ClassVarStr>& GetVariables() { return GetLib<TLuaClass>()->m_variables; }
  187. protected:
  188. //-------------------------------------------------------------------------
  189. template <typename TLuaClass>
  190. static int New(LuaState* l)
  191. {
  192. //Number of arguments
  193. int n_args = lua_gettop(l);
  194. //Create user data
  195. TLuaClass** data = (TLuaClass**)lua_newuserdata(l, sizeof(TLuaClass*));
  196. *data = TLuaClass::New(l, n_args);
  197. //Retrieve instance table
  198. luaL_getmetatable(l, GetMethodName<TLuaClass>());
  199. //Set metatable to instance
  200. lua_setmetatable(l, -2);
  201. //Return 1 so Lua will get the UserData and clean the stack.
  202. return 1;
  203. }
  204. //-------------------------------------------------------------------------
  205. template <typename TLuaClass> static int Store(LuaState * l);
  206. template <typename TLuaClass> static int Del(LuaState * l);
  207. };
  208. //-----------------------------------------------------------------------------
  209. class Function
  210. {
  211. public:
  212. Function(LuaState* l, const char* name, int(*function)(LuaState*))
  213. {
  214. lua_pushcfunction(l, function);
  215. lua_setglobal(l, name);
  216. }
  217. };
  218. //-----------------------------------------------------------------------------
  219. template<typename T>
  220. class VarPtr
  221. {
  222. protected:
  223. T* m_value = nullptr;
  224. bool m_optional = false;
  225. public:
  226. VarPtr(bool optional = false)
  227. {
  228. m_optional = optional;
  229. }
  230. VarPtr(T* value, bool optional = false)
  231. : VarPtr(optional)
  232. {
  233. m_value = value;
  234. }
  235. VarPtr(LuaState* l, int& index, bool optional = false)
  236. : VarPtr(optional)
  237. {
  238. GetInc(l, index);
  239. }
  240. VarPtr(T* value, LuaState* l, int& index, bool optional = false)
  241. : VarPtr(value, optional)
  242. {
  243. GetInc(l, index);
  244. }
  245. inline T* operator ()() { return m_value; }
  246. inline T* operator ->() { return m_value; }
  247. inline T* operator=(T* value) { m_value = value; }
  248. inline T* GetValue() { return m_value; }
  249. inline bool IsValid(LuaState* l, int index)
  250. {
  251. return InnerIsValid(l, index);
  252. }
  253. inline bool IsOptional()
  254. {
  255. return m_optional;
  256. }
  257. private:
  258. inline void GetInc(LuaState* l, int& index)
  259. {
  260. bool is_nil = lua_isnil(l, index);
  261. if (!m_optional || (!is_nil && InnerIsValid(l, index)))
  262. {
  263. ASSERT(!is_nil);
  264. InnerGet(l, index);
  265. }
  266. }
  267. public:
  268. inline void Get(LuaState* l, int index)
  269. {
  270. int idx = index;
  271. GetInc(l, idx);
  272. }
  273. inline int Return(LuaState* l)
  274. {
  275. InnerPush(l);
  276. return 1;
  277. }
  278. protected:
  279. virtual bool InnerIsValid(LuaState* l, int index)
  280. {
  281. return !!lua_isuserdata(l, index);
  282. }
  283. virtual void InnerGet(LuaState* l, int& index)
  284. {
  285. T** obj = static_cast<T**>(luaL_checkudata(l, index++, ObjectDef::GetMethodName<T>()));
  286. m_value = obj ? *obj : nullptr;
  287. }
  288. void InnerPush(LuaState* l)
  289. {
  290. T** data = (T**)lua_newuserdata(l, sizeof(T*));
  291. *data = m_value;
  292. }
  293. };
  294. //-----------------------------------------------------------------------------
  295. /* TODO: FIX THAT TOUKY !!
  296. template<typename T>
  297. class VarPtrLight
  298. {
  299. public:
  300. VarPtrLight(bool optional = false) : VarPtr(optional) { }
  301. VarPtrLight(T* value, bool optional = false) : VarPtr(value, optional) { }
  302. VarPtrLight(LuaState* l, int& index, bool optional = false) : VarPtr(l, index, optional) { }
  303. VarPtrLight(T* value, LuaState* l, int& index, bool optional = false) : VarPtr(value, l, index, optional) { }
  304. protected:
  305. virtual void InnerGet(LuaState* l, int& index)
  306. {
  307. T** obj = static_cast<T**>(luaL_testudata(l, index++, ObjectDef::GetMethodName<T>()));
  308. m_value = obj ? *obj : nullptr;
  309. }
  310. };
  311. */
  312. //-----------------------------------------------------------------------------
  313. template<typename T>
  314. class Var
  315. {
  316. protected:
  317. bool m_optional = false;
  318. T m_value;
  319. public:
  320. Var(bool optional = false)
  321. {
  322. m_optional = optional;
  323. InnerInit();
  324. }
  325. Var(T value, bool optional = false)
  326. {
  327. m_optional = optional;
  328. m_value = value;
  329. }
  330. Var(LuaState* l, int& index, bool optional = false)
  331. {
  332. m_optional = optional;
  333. GetInc(l, index);
  334. }
  335. Var(T value, LuaState* l, int& index, bool optional = false)
  336. {
  337. m_optional = optional;
  338. m_value = value;
  339. GetInc(l, index);
  340. }
  341. inline operator T() { return m_value; }
  342. inline T& operator ()() { return m_value; }
  343. inline T& GetValue() { return m_value; }
  344. inline bool IsValid(LuaState* l, int index)
  345. {
  346. return InnerIsValid(l, index);
  347. }
  348. inline bool IsOptional()
  349. {
  350. return m_optional;
  351. }
  352. private:
  353. void GetInc(LuaState* l, int& index)
  354. {
  355. bool is_nil = lua_isnil(l, index);
  356. if (!m_optional || (!is_nil && InnerIsValid(l, index)))
  357. {
  358. ASSERT(!is_nil);
  359. InnerGet(l, index);
  360. }
  361. }
  362. public:
  363. inline void Get(LuaState* l, int index)
  364. {
  365. int idx = index;
  366. GetInc(l, idx);
  367. }
  368. inline int Return(LuaState* l)
  369. {
  370. return InnerPush(l);
  371. }
  372. inline Var<T>& operator-(const T& value) { m_value - value; return *this; }
  373. inline Var<T>& operator+(const T& value) { m_value + value; return *this; }
  374. inline Var<T>& operator*(const T& value) { m_value * value; return *this; }
  375. inline Var<T>& operator/(const T& value) { m_value / value; return *this; }
  376. inline Var<T>& operator=(const T& value) { m_value = value; return *this; }
  377. inline Var<T>& operator-=(const T& value) { m_value -= value; return *this; }
  378. inline Var<T>& operator+=(const T& value) { m_value += value; return *this; }
  379. inline Var<T>& operator*=(const T& value) { m_value *= value; return *this; }
  380. inline Var<T>& operator/=(const T& value) { m_value /= value; return *this; }
  381. inline Var<T>& operator-(const Var<T>& o) { m_value - o.m_value; return *this; }
  382. inline Var<T>& operator+(const Var<T>& o) { m_value + o.m_value; return *this; }
  383. inline Var<T>& operator*(const Var<T>& o) { m_value * o.m_value; return *this; }
  384. inline Var<T>& operator/(const Var<T>& o) { m_value / o.m_value; return *this; }
  385. inline Var<T>& operator=(const Var<T>& o) { m_value = o.m_value; return *this; }
  386. inline Var<T>& operator-=(const Var<T>& o) { m_value -= o.m_value; return *this; }
  387. inline Var<T>& operator+=(const Var<T>& o) { m_value += o.m_value; return *this; }
  388. inline Var<T>& operator*=(const Var<T>& o) { m_value *= o.m_value; return *this; }
  389. inline Var<T>& operator/=(const Var<T>& o) { m_value /= o.m_value; return *this; }
  390. inline bool operator==(const T& value) { return m_value == value; }
  391. inline bool operator!=(const T& value) { return m_value != value; }
  392. inline bool operator==(const Var<T>& o) { return m_value == o.m_value; }
  393. inline bool operator!=(const Var<T>& o) { return m_value != o.m_value; }
  394. protected:
  395. void InnerInit() { m_value = T(0); }
  396. bool InnerIsValid(LuaState* l, int index) { UNUSED(l); UNUSED(index); ASSERT(false); return false; }
  397. void InnerGet(LuaState* l, int& index) { UNUSED(l); UNUSED(index); ASSERT(false); }
  398. int InnerPush(LuaState* l) { UNUSED(l); ASSERT(false); return 0; }
  399. };
  400. //-----------------------------------------------------------------------------
  401. template<> inline bool Var<bool>::InnerIsValid(LuaState* l, int index)
  402. {
  403. return lua_isboolean(l, index);
  404. }
  405. template<> inline void Var<bool>::InnerGet(LuaState* l, int& index)
  406. {
  407. m_value = !!lua_toboolean(l, index++);
  408. }
  409. template<> inline int Var<bool>::InnerPush(LuaState* l)
  410. {
  411. lua_pushboolean(l, m_value);
  412. return 1;
  413. }
  414. //-----------------------------------------------------------------------------
  415. template<> inline bool Var<char const*>::InnerIsValid(LuaState* l, int index)
  416. {
  417. return !!lua_isstring(l, index);
  418. }
  419. template<> inline void Var<char const*>::InnerGet(LuaState* l, int& index)
  420. {
  421. m_value = lua_tostring(l, index++);
  422. }
  423. template<> inline int Var<char const*>::InnerPush(LuaState* l)
  424. {
  425. lua_pushstring(l, m_value);
  426. return 1;
  427. }
  428. //-----------------------------------------------------------------------------
  429. template<> inline void Var<String>::InnerInit()
  430. {
  431. m_value = String();
  432. }
  433. template<> inline bool Var<String>::InnerIsValid(LuaState* l, int index)
  434. {
  435. Var<char const*> v;
  436. return v.IsValid(l, index);
  437. }
  438. template<> inline void Var<String>::InnerGet(LuaState* l, int& index)
  439. {
  440. Var<char const*> v(l, index);
  441. m_value = v();
  442. }
  443. template<> inline int Var<String>::InnerPush(LuaState* l)
  444. {
  445. Var<char const*> v;
  446. v = m_value.C();
  447. return v.Return(l);
  448. }
  449. //-----------------------------------------------------------------------------
  450. template<> inline bool Var<double>::InnerIsValid(LuaState* l, int index)
  451. {
  452. return !!lua_isnumber(l, index);
  453. }
  454. template<> inline void Var<double>::InnerGet(LuaState* l, int& index)
  455. {
  456. m_value = lua_tonumber(l, index++);
  457. }
  458. template<> inline int Var<double>::InnerPush(LuaState* l)
  459. {
  460. lua_pushnumber(l, m_value);
  461. return 1;
  462. }
  463. //-----------------------------------------------------------------------------
  464. template<> inline bool Var<float>::InnerIsValid(LuaState* l, int index)
  465. {
  466. Var<double> v;
  467. return v.IsValid(l, index);
  468. }
  469. template<> inline void Var<float>::InnerGet(LuaState* l, int& index)
  470. {
  471. Var<double> v(l, index);
  472. m_value = (float)v();
  473. }
  474. template<> inline int Var<float>::InnerPush(LuaState* l)
  475. {
  476. Var<double> v = (double)m_value;
  477. return v.Return(l);
  478. }
  479. #if 0
  480. //-----------------------------------------------------------------------------
  481. template<> inline bool Var<int64_t>::InnerIsValid(LuaState* l, int index)
  482. {
  483. return !!lua_isnumber(l, index);
  484. }
  485. template<> inline void Var<int64_t>::InnerGet(LuaState* l, int& index)
  486. {
  487. m_value = lua_tointeger(l, index++);
  488. }
  489. template<> inline int Var<int64_t>::InnerPush(LuaState* l)
  490. {
  491. lua_pushinteger(l, m_value);
  492. return 1;
  493. }
  494. #endif
  495. //-----------------------------------------------------------------------------
  496. template<> inline bool Var<int32_t>::InnerIsValid(LuaState* l, int index)
  497. {
  498. Var<int64_t> v;
  499. return v.IsValid(l, index);
  500. }
  501. template<> inline void Var<int32_t>::InnerGet(LuaState* l, int& index)
  502. {
  503. Var<int64_t> v(l, index);
  504. m_value = (int32_t)v();
  505. }
  506. template<> inline int Var<int32_t>::InnerPush(LuaState* l)
  507. {
  508. Var<int64_t> v = (int64_t)m_value;
  509. return v.Return(l);
  510. }
  511. //-----------------------------------------------------------------------------
  512. template<> inline bool Var<uint32_t>::InnerIsValid(LuaState* l, int index)
  513. {
  514. return !!lua_isnumber(l, index);
  515. }
  516. template<> inline void Var<uint32_t>::InnerGet(LuaState* l, int& index)
  517. {
  518. m_value = (uint32_t)(lua_Unsigned)lua_tointeger(l, index++);
  519. }
  520. template<> inline int Var<uint32_t>::InnerPush(LuaState* l)
  521. {
  522. lua_pushinteger(l, (lua_Integer)m_value);
  523. return 1;
  524. }
  525. #if 0
  526. //-----------------------------------------------------------------------------
  527. template<> inline bool Var<uint64_t>::InnerIsValid(LuaState* l, int index)
  528. {
  529. Var<uint32_t> v;
  530. return v.IsValid(l, index);
  531. }
  532. template<> inline void Var<uint64_t>::InnerGet(LuaState* l, int& index)
  533. {
  534. Var<uint32_t> v(l, index);
  535. m_value = (uint64_t)v();
  536. }
  537. template<> inline int Var<uint64_t>::InnerPush(LuaState* l)
  538. {
  539. Var<uint32_t> v = (uint32_t)m_value;
  540. return v.Return(l);
  541. }
  542. #endif
  543. //-----------------------------------------------------------------------------
  544. template<> inline bool Var<vec2>::InnerIsValid(LuaState* l, int index)
  545. {
  546. Var<float> x;
  547. return x.IsValid(l, index);
  548. }
  549. template<> inline void Var<vec2>::InnerGet(LuaState* l, int& index)
  550. {
  551. Var<float> x(l, index);
  552. Var<float> y(x(), l, index, true);
  553. m_value = vec2(x, y);
  554. }
  555. template<> inline int Var<vec2>::InnerPush(LuaState* l)
  556. {
  557. Var<float> x = m_value.x;
  558. Var<float> y = m_value.y;
  559. return (x.Return(l) + y.Return(l));
  560. }
  561. //-----------------------------------------------------------------------------
  562. template<> inline bool Var<vec3>::InnerIsValid(LuaState* l, int index)
  563. {
  564. Var<float> x;
  565. return x.IsValid(l, index);
  566. }
  567. template<> inline void Var<vec3>::InnerGet(LuaState* l, int& index)
  568. {
  569. Var<float> x(l, index);
  570. Var<float> y(x(), l, index, true);
  571. Var<float> z(x(), l, index, true);
  572. m_value = vec3(x, y, z);
  573. }
  574. template<> inline int Var<vec3>::InnerPush(LuaState* l)
  575. {
  576. Var<float> x = m_value.x;
  577. Var<float> y = m_value.y;
  578. Var<float> z = m_value.z;
  579. return (x.Return(l) + y.Return(l) + z.Return(l));
  580. }
  581. //-----------------------------------------------------------------------------
  582. template<> inline bool Var<vec4>::InnerIsValid(LuaState* l, int index)
  583. {
  584. Var<float> x;
  585. return x.IsValid(l, index);
  586. }
  587. template<> inline void Var<vec4>::InnerGet(LuaState* l, int& index)
  588. {
  589. Var<float> x(l, index);
  590. Var<float> y(x(), l, index, true);
  591. Var<float> z(x(), l, index, true);
  592. Var<float> w(x(), l, index, true);
  593. m_value = vec4(x, y, z, w);
  594. }
  595. template<> inline int Var<vec4>::InnerPush(LuaState* l)
  596. {
  597. Var<float> x = m_value.x;
  598. Var<float> y = m_value.y;
  599. Var<float> z = m_value.z;
  600. Var<float> w = m_value.w;
  601. return (x.Return(l) + y.Return(l) + z.Return(l) + w.Return(l));
  602. }
  603. //-----------------------------------------------------------------------------
  604. class VarColor
  605. {
  606. protected:
  607. Var<vec4> m_value;
  608. public:
  609. VarColor(bool optional = false)
  610. {
  611. m_value = Var<vec4>(optional);
  612. InnerInit();
  613. }
  614. VarColor(vec4 value, bool optional = false)
  615. {
  616. m_value = Var<vec4>(value, optional);
  617. }
  618. VarColor(LuaState* l, int& index, bool optional = false)
  619. : VarColor(optional)
  620. {
  621. GetInc(l, index);
  622. }
  623. VarColor(vec4 value, LuaState* l, int& index, bool optional = false)
  624. : VarColor(value, optional)
  625. {
  626. GetInc(l, index);
  627. }
  628. inline operator vec4() { return m_value; }
  629. inline vec4& operator ()() { return m_value(); }
  630. inline vec4& GetValue() { return m_value.GetValue(); }
  631. inline bool IsValid(LuaState* l, int index)
  632. {
  633. return InnerIsValid(l, index);
  634. }
  635. inline bool IsOptional()
  636. {
  637. return m_value.IsOptional();
  638. }
  639. private:
  640. void GetInc(LuaState* l, int& index)
  641. {
  642. bool is_nil = lua_isnil(l, index);
  643. if (!m_value.IsOptional() || (!is_nil && InnerIsValid(l, index)))
  644. {
  645. ASSERT(!is_nil);
  646. InnerGet(l, index);
  647. }
  648. }
  649. public:
  650. inline void Get(LuaState* l, int index)
  651. {
  652. int idx = index;
  653. GetInc(l, idx);
  654. }
  655. inline int Return(LuaState* l)
  656. {
  657. return InnerPush(l);
  658. }
  659. inline VarColor& operator-(const vec4& value) { m_value - value; return *this; }
  660. inline VarColor& operator+(const vec4& value) { m_value + value; return *this; }
  661. inline VarColor& operator*(const vec4& value) { m_value * value; return *this; }
  662. inline VarColor& operator/(const vec4& value) { m_value / value; return *this; }
  663. inline VarColor& operator=(const vec4& value) { m_value = value; return *this; }
  664. inline VarColor& operator-=(const vec4& value) { m_value -= value; return *this; }
  665. inline VarColor& operator+=(const vec4& value) { m_value += value; return *this; }
  666. inline VarColor& operator*=(const vec4& value) { m_value *= value; return *this; }
  667. inline VarColor& operator/=(const vec4& value) { m_value /= value; return *this; }
  668. inline VarColor& operator-(const Var<vec4>& o) { m_value - o; return *this; }
  669. inline VarColor& operator+(const Var<vec4>& o) { m_value + o; return *this; }
  670. inline VarColor& operator*(const Var<vec4>& o) { m_value * o; return *this; }
  671. inline VarColor& operator/(const Var<vec4>& o) { m_value / o; return *this; }
  672. inline VarColor& operator=(const Var<vec4>& o) { m_value = o; return *this; }
  673. inline VarColor& operator-=(const Var<vec4>& o) { m_value -= o; return *this; }
  674. inline VarColor& operator+=(const Var<vec4>& o) { m_value += o; return *this; }
  675. inline VarColor& operator*=(const Var<vec4>& o) { m_value *= o; return *this; }
  676. inline VarColor& operator/=(const Var<vec4>& o) { m_value /= o; return *this; }
  677. inline bool operator==(const vec4& value) { return m_value == value; }
  678. inline bool operator!=(const vec4& value) { return m_value != value; }
  679. inline bool operator==(const Var<vec4>& o) { return m_value == o; }
  680. inline bool operator!=(const Var<vec4>& o) { return m_value != o; }
  681. inline VarColor& operator-(const VarColor& v) { m_value - v.m_value; return *this; }
  682. inline VarColor& operator+(const VarColor& v) { m_value + v.m_value; return *this; }
  683. inline VarColor& operator*(const VarColor& v) { m_value * v.m_value; return *this; }
  684. inline VarColor& operator/(const VarColor& v) { m_value / v.m_value; return *this; }
  685. inline VarColor& operator=(const VarColor& v) { m_value = v.m_value; return *this; }
  686. inline VarColor& operator-=(const VarColor& v) { m_value -= v.m_value; return *this; }
  687. inline VarColor& operator+=(const VarColor& v) { m_value += v.m_value; return *this; }
  688. inline VarColor& operator*=(const VarColor& v) { m_value *= v.m_value; return *this; }
  689. inline VarColor& operator/=(const VarColor& v) { m_value /= v.m_value; return *this; }
  690. inline bool operator==(const VarColor& v) { return m_value == v.m_value; }
  691. inline bool operator!=(const VarColor& v) { return m_value != v.m_value; }
  692. protected:
  693. void InnerInit()
  694. {
  695. m_value = vec4::zero;
  696. }
  697. bool InnerIsValid(LuaState* l, int index)
  698. {
  699. Var<String> s;
  700. return m_value.IsValid(l, index) || s.IsValid(l, index);
  701. }
  702. void InnerGet(LuaState* l, int& index)
  703. {
  704. //Try vec4 first
  705. if (m_value.IsValid(l, index))
  706. {
  707. m_value.Get(l, index);
  708. }
  709. else
  710. {
  711. Var<String> c(l, index);
  712. *this = Color::C8BppHexString(c);
  713. }
  714. }
  715. int InnerPush(LuaState* l)
  716. {
  717. Var<String> c = Color::HexString8Bpp(m_value);
  718. return c.Return(l);
  719. }
  720. };
  721. //-----------------------------------------------------------------------------
  722. template<typename E>
  723. class VarEnum
  724. {
  725. protected:
  726. SafeEnum<E> m_value;
  727. bool m_optional = false;
  728. public:
  729. VarEnum(bool optional = false)
  730. {
  731. m_optional = optional;
  732. InnerInit();
  733. }
  734. VarEnum(SafeEnum<E> value, bool optional = false)
  735. : VarEnum(optional)
  736. {
  737. m_value = value;
  738. }
  739. VarEnum(LuaState* l, int& index, bool optional = false)
  740. : VarEnum(optional)
  741. {
  742. GetInc(l, index);
  743. }
  744. VarEnum(SafeEnum<E> value, LuaState* l, int& index, bool optional = false)
  745. : VarEnum(value, optional)
  746. {
  747. GetInc(l, index);
  748. }
  749. inline operator SafeEnum<E>() { return m_value; }
  750. inline SafeEnum<E>& operator ()() { return m_value; }
  751. inline SafeEnum<E>& GetValue() { return m_value; }
  752. inline bool IsValid(LuaState* l, int index)
  753. {
  754. return InnerIsValid(l, index);
  755. }
  756. inline bool IsOptional()
  757. {
  758. return m_optional;
  759. }
  760. private:
  761. void GetInc(LuaState* l, int& index)
  762. {
  763. bool is_nil = lua_isnil(l, index);
  764. if (!m_optional || (!is_nil && InnerIsValid(l, index)))
  765. {
  766. ASSERT(!is_nil);
  767. InnerGet(l, index);
  768. }
  769. }
  770. public:
  771. inline void Get(LuaState* l, int index)
  772. {
  773. int idx = index;
  774. GetInc(l, idx);
  775. }
  776. inline int Return(LuaState* l)
  777. {
  778. return InnerPush(l);
  779. }
  780. inline VarEnum<E>& operator-(const SafeEnum<E>& value) { m_value - value; return *this; }
  781. inline VarEnum<E>& operator+(const SafeEnum<E>& value) { m_value + value; return *this; }
  782. inline VarEnum<E>& operator*(const SafeEnum<E>& value) { m_value * value; return *this; }
  783. inline VarEnum<E>& operator/(const SafeEnum<E>& value) { m_value / value; return *this; }
  784. inline VarEnum<E>& operator=(const SafeEnum<E>& value) { m_value = value; return *this; }
  785. inline VarEnum<E>& operator-=(const SafeEnum<E>& value) { m_value -= value; return *this; }
  786. inline VarEnum<E>& operator+=(const SafeEnum<E>& value) { m_value += value; return *this; }
  787. inline VarEnum<E>& operator*=(const SafeEnum<E>& value) { m_value *= value; return *this; }
  788. inline VarEnum<E>& operator/=(const SafeEnum<E>& value) { m_value /= value; return *this; }
  789. inline bool operator==(const SafeEnum<E>& value) { return m_value == value; }
  790. inline bool operator!=(const SafeEnum<E>& value) { return m_value != value; }
  791. inline VarEnum<E>& operator-(const VarEnum<E>& v) { m_value - v.m_value; return *this; }
  792. inline VarEnum<E>& operator+(const VarEnum<E>& v) { m_value + v.m_value; return *this; }
  793. inline VarEnum<E>& operator*(const VarEnum<E>& v) { m_value * v.m_value; return *this; }
  794. inline VarEnum<E>& operator/(const VarEnum<E>& v) { m_value / v.m_value; return *this; }
  795. inline VarEnum<E>& operator=(const VarEnum<E>& v) { m_value = v.m_value; return *this; }
  796. inline VarEnum<E>& operator-=(const VarEnum<E>& v) { m_value -= v.m_value; return *this; }
  797. inline VarEnum<E>& operator+=(const VarEnum<E>& v) { m_value += v.m_value; return *this; }
  798. inline VarEnum<E>& operator*=(const VarEnum<E>& v) { m_value *= v.m_value; return *this; }
  799. inline VarEnum<E>& operator/=(const VarEnum<E>& v) { m_value /= v.m_value; return *this; }
  800. inline bool operator==(const VarEnum<E>& v) { return m_value == v.m_value; }
  801. inline bool operator!=(const VarEnum<E>& v) { return m_value != v.m_value; }
  802. protected:
  803. void InnerInit()
  804. {
  805. m_value = SafeEnum<E>(0);
  806. }
  807. bool InnerIsValid(LuaState* l, int index)
  808. {
  809. Var<String> s;
  810. return s.IsValid(l, index);
  811. }
  812. void InnerGet(LuaState* l, int& index)
  813. {
  814. Var<String> c(l, index);
  815. *this = FindValue<SafeEnum<E> >(c);
  816. }
  817. int InnerPush(LuaState* l)
  818. {
  819. Var<String> s = this->GetValue().ToString();
  820. return s.Return(l);
  821. }
  822. };
  823. //-----------------------------------------------------------------------------
  824. class Stack
  825. {
  826. public:
  827. Stack(LuaState* l, int32_t start_index = 1)
  828. {
  829. m_state = l;
  830. m_index = start_index;
  831. }
  832. virtual ~Stack() { }
  833. inline operator int32_t() { return m_result; }
  834. int32_t GetArgs()
  835. {
  836. return lua_gettop(m_state);
  837. }
  838. //-------------------------------------------------------------------------
  839. template<typename T>
  840. Stack& operator>>(T& var)
  841. {
  842. var = T(var.GetValue(), m_state, m_index, var.IsOptional());
  843. return *this;
  844. }
  845. /*
  846. template<typename T>
  847. Stack& operator>>(Var<T>& var)
  848. {
  849. var = Var<T>(var.GetValue(), m_state, m_index, var.IsOptional());
  850. return *this;
  851. }
  852. template<typename T>
  853. Stack& operator>>(Var<T>& var)
  854. {
  855. var = Var<T>(var.GetValue(), m_state, m_index, var.IsOptional());
  856. return *this;
  857. }
  858. template<typename T>
  859. Stack& operator>>(VarPtr<T>& var)
  860. {
  861. var = VarPtr<T>(m_state, m_index);
  862. return *this;
  863. }
  864. */
  865. /*
  866. template<typename T>
  867. Stack& operator>>(T& var)
  868. {
  869. Var<T> ret(m_state, m_index);
  870. var = ret.GetValue();
  871. return *this;
  872. }
  873. template<typename T>
  874. Stack& operator>>(VarPtrLight<T>& var)
  875. {
  876. var = VarPtrLight<T>(m_state, m_index);
  877. return *this;
  878. }
  879. */
  880. //-------------------------------------------------------------------------
  881. template<typename T>
  882. Stack& operator<<(T& var)
  883. {
  884. m_result += var.Return(m_state);
  885. return *this;
  886. }
  887. /*
  888. template<typename T>
  889. Stack& operator<<(T& var)
  890. {
  891. Var<T> ret(var, false);
  892. m_result += ret.Return(m_state);
  893. return *this;
  894. }
  895. template<typename T>
  896. Stack& operator<<(VarPtr<T>& var)
  897. {
  898. m_result += var.Return(m_state);
  899. return *this;
  900. }
  901. template<typename T>
  902. Stack& operator<<(VarPtrLight<T>& var)
  903. {
  904. m_result += var.Return(m_state);
  905. return *this;
  906. }
  907. */
  908. private:
  909. LuaState* m_state = nullptr;
  910. int32_t m_index = 1;
  911. int32_t m_result = 0;
  912. };
  913. //-----------------------------------------------------------------------------
  914. class Loader
  915. {
  916. friend class ObjectDef;
  917. public:
  918. Loader();
  919. virtual ~Loader();
  920. bool ExecLuaFile(String const &lua);
  921. bool ExecLuaCode(String const &lua);
  922. template<typename T>
  923. T GetVar(String const &name)
  924. {
  925. lua_getglobal(m_lua_state, name.C());
  926. Var<T> var; var.Get(m_lua_state, -1);
  927. lua_pop(m_lua_state, 1);
  928. return var;
  929. }
  930. template<typename T>
  931. T* GetPtr(String const &name)
  932. {
  933. lua_getglobal(m_lua_state, name.C());
  934. VarPtr<T> var; var.Get(m_lua_state, -1);
  935. lua_pop(m_lua_state, 1);
  936. return var();
  937. }
  938. protected:
  939. LuaState* GetLuaState();
  940. static void Store(LuaState* l, Loader* loader);
  941. static Loader *Find(LuaState* l);
  942. static void Release(LuaState* l, Loader* loader);
  943. static void StoreObject(LuaState* l, Object* obj);
  944. //Virtual Store lua object ------------------------------------------------
  945. virtual void Store(Object* obj) { UNUSED(obj); }
  946. private:
  947. LuaState* m_lua_state;
  948. };
  949. //-----------------------------------------------------------------------------
  950. // ObjectDef member implementations that require VarPtr
  951. template <typename TLuaClass>
  952. int ObjectDef::Store(LuaState * l)
  953. {
  954. VarPtr<TLuaClass> obj;
  955. obj.Get(l, 1);
  956. ASSERT(obj());
  957. Loader::StoreObject(l, obj());
  958. return 0;
  959. }
  960. template <typename TLuaClass>
  961. int ObjectDef::Del(LuaState * l)
  962. {
  963. VarPtr<TLuaClass> obj;
  964. obj.Get(l, 1);
  965. ASSERT(obj());
  966. delete obj();
  967. return 0;
  968. }
  969. } /* namespace Lolua */
  970. typedef Lolua::Function LuaFunction;
  971. typedef Lolua::ObjectDef LuaObjectDef;
  972. typedef Lolua::Object LuaObject;
  973. typedef Lolua::ObjectLib LuaObjectLib;
  974. typedef Lolua::Loader LuaLoader;
  975. typedef Lolua::Var<bool> LuaBool;
  976. typedef Lolua::Var<char const*> LuaCharPtr;
  977. typedef Lolua::Var<String> LuaString;
  978. typedef Lolua::Var<double> LuaDouble;
  979. typedef Lolua::Var<float> LuaFloat;
  980. typedef Lolua::Var<int64_t> LuaInt64;
  981. typedef Lolua::Var<int32_t> LuaInt32;
  982. typedef Lolua::Var<uint32_t> LuaUInt32;
  983. typedef Lolua::Var<uint64_t> LuaUInt64;
  984. typedef Lolua::Var<vec2> LuaVec2;
  985. typedef Lolua::Var<vec3> LuaVec3;
  986. typedef Lolua::Var<vec4> LuaVec4;
  987. typedef Lolua::VarColor LuaColor;
  988. typedef Lolua::Stack LuaStack;
  989. } /* namespace lol */