Globals.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Script/LuaBinder.h>
  6. #include <AnKi/Script/ScriptManager.h>
  7. #include <AnKi/Util/CVarSet.h>
  8. namespace anki {
  9. static CVar* findCVar(CString name)
  10. {
  11. CVar* foundCVar = nullptr;
  12. CString prefix = "cvar";
  13. const PtrSize pos = name.find(prefix);
  14. if(name.getLength() > prefix.getLength() && pos == 0)
  15. {
  16. // Possibly a CVAR
  17. CString cvarName = name.getBegin() + prefix.getLength();
  18. CVarSet::getSingleton().iterateCVars([&](CVar& cvar) -> Bool {
  19. ScriptString cvarName2 = cvar.getName();
  20. cvarName2.replaceAll(".", "");
  21. if(cvarName == cvarName2)
  22. {
  23. foundCVar = &cvar;
  24. return true;
  25. }
  26. return false;
  27. });
  28. }
  29. return foundCVar;
  30. }
  31. static inline int pwrap__newindex(lua_State* l)
  32. {
  33. if(LuaBinder::checkArgsCount(l, 3))
  34. {
  35. return -1;
  36. }
  37. const Char* varName_;
  38. if(LuaBinder::checkString(l, 2, varName_))
  39. {
  40. return -1;
  41. }
  42. CString varName(varName_);
  43. CVar* cvar = findCVar(varName);
  44. if(cvar)
  45. {
  46. // Found
  47. #define ANKI_CVAR_NUMERIC_TYPE(type) \
  48. case CVarValueType::kNumeric##type: \
  49. { \
  50. type val; \
  51. if(LuaBinder::checkNumber(l, 3, val)) \
  52. { \
  53. return -1; \
  54. } \
  55. static_cast<NumericCVar<type>&>(*cvar) = val; \
  56. } \
  57. break;
  58. switch(cvar->getValueType())
  59. {
  60. case CVarValueType::kString:
  61. {
  62. const Char* val;
  63. if(LuaBinder::checkString(l, 3, val))
  64. {
  65. return -1;
  66. }
  67. static_cast<StringCVar&>(*cvar) = val;
  68. }
  69. break;
  70. case CVarValueType::kBool:
  71. {
  72. I32 val;
  73. if(LuaBinder::checkNumber(l, 3, val))
  74. {
  75. return -1;
  76. }
  77. static_cast<BoolCVar&>(*cvar) = val;
  78. }
  79. break;
  80. ANKI_CVAR_NUMERIC_TYPE(U8)
  81. ANKI_CVAR_NUMERIC_TYPE(U16)
  82. ANKI_CVAR_NUMERIC_TYPE(U32)
  83. ANKI_CVAR_NUMERIC_TYPE(PtrSize)
  84. ANKI_CVAR_NUMERIC_TYPE(F32)
  85. ANKI_CVAR_NUMERIC_TYPE(F64)
  86. default:
  87. ANKI_ASSERT(0);
  88. }
  89. #undef ANKI_CVAR_NUMERIC_TYPE
  90. }
  91. else
  92. {
  93. ANKI_SCRIPT_LOGE("Global variable not found: %s", varName.cstr());
  94. return -1;
  95. }
  96. return 0;
  97. }
  98. static int wrap__newindex(lua_State* l)
  99. {
  100. const int res = pwrap__newindex(l);
  101. if(res >= 0)
  102. {
  103. return res;
  104. }
  105. lua_error(l);
  106. return 0;
  107. }
  108. static inline int pwrap__index(lua_State* l)
  109. {
  110. if(LuaBinder::checkArgsCount(l, 2))
  111. {
  112. return -1;
  113. }
  114. const Char* varName_;
  115. if(LuaBinder::checkString(l, 2, varName_))
  116. {
  117. return -1;
  118. }
  119. CString varName(varName_);
  120. CVar* cvar = findCVar(varName);
  121. if(cvar)
  122. {
  123. // Found
  124. #define ANKI_CVAR_NUMERIC_TYPE(type) \
  125. case CVarValueType::kNumeric##type: \
  126. { \
  127. lua_pushnumber(l, lua_Number(static_cast<NumericCVar<type>&>(*cvar))); \
  128. } \
  129. break;
  130. switch(cvar->getValueType())
  131. {
  132. case CVarValueType::kString:
  133. {
  134. lua_pushstring(l, CString(static_cast<StringCVar&>(*cvar)).cstr());
  135. }
  136. break;
  137. case CVarValueType::kBool:
  138. {
  139. lua_pushnumber(l, static_cast<BoolCVar&>(*cvar));
  140. }
  141. break;
  142. ANKI_CVAR_NUMERIC_TYPE(U8)
  143. ANKI_CVAR_NUMERIC_TYPE(U16)
  144. ANKI_CVAR_NUMERIC_TYPE(U32)
  145. ANKI_CVAR_NUMERIC_TYPE(PtrSize)
  146. ANKI_CVAR_NUMERIC_TYPE(F32)
  147. ANKI_CVAR_NUMERIC_TYPE(F64)
  148. default:
  149. ANKI_ASSERT(0);
  150. }
  151. #undef ANKI_CVAR_NUMERIC_TYPE
  152. }
  153. else
  154. {
  155. ANKI_SCRIPT_LOGE("Global variable not found: %s", varName.cstr());
  156. return -1;
  157. }
  158. return 1;
  159. }
  160. static int wrap__index(lua_State* l)
  161. {
  162. const int res = pwrap__index(l);
  163. if(res >= 0)
  164. {
  165. return res;
  166. }
  167. lua_error(l);
  168. return 0;
  169. }
  170. void wrapModuleGlobals(lua_State* l)
  171. {
  172. lua_newtable(l); // push table
  173. lua_newtable(l); // push meta_table
  174. lua_pushcfunction(l, wrap__index); // push func
  175. lua_setfield(l, -2, "__index"); // meta_table[__index] = stack[-2] and pop func
  176. lua_pushcfunction(l, wrap__newindex); // push func
  177. lua_setfield(l, -2, "__newindex"); // meta_table[__newindex] = stack[-2] and pop func
  178. lua_setmetatable(l, -2); // setmetatable(table, meta_table) and pop meta_table
  179. lua_setglobal(l, "g"); // setglobal(table, "g") and pop table
  180. lua_settop(l, 0);
  181. }
  182. } // namespace anki