LuaBinder.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. // Copyright (C) 2009-2021, 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/Util/Logger.h>
  7. #include <AnKi/Util/Tracer.h>
  8. namespace anki
  9. {
  10. // Forward
  11. #define ANKI_SCRIPT_CALL_WRAP(x_) void wrapModule##x_(lua_State*)
  12. ANKI_SCRIPT_CALL_WRAP(Logger);
  13. ANKI_SCRIPT_CALL_WRAP(Math);
  14. ANKI_SCRIPT_CALL_WRAP(Renderer);
  15. ANKI_SCRIPT_CALL_WRAP(Scene);
  16. #undef ANKI_SCRIPT_CALL_WRAP
  17. static void wrapModules(lua_State* l)
  18. {
  19. #define ANKI_SCRIPT_CALL_WRAP(x_) wrapModule##x_(l)
  20. ANKI_SCRIPT_CALL_WRAP(Logger);
  21. ANKI_SCRIPT_CALL_WRAP(Math);
  22. ANKI_SCRIPT_CALL_WRAP(Renderer);
  23. ANKI_SCRIPT_CALL_WRAP(Scene);
  24. #undef ANKI_SCRIPT_CALL_WRAP
  25. }
  26. static int luaPanic(lua_State* l)
  27. {
  28. ANKI_SCRIPT_LOGF("Lua panic attack: %s", lua_tostring(l, -1));
  29. return 0;
  30. }
  31. LuaBinder::LuaBinder()
  32. {
  33. }
  34. LuaBinder::~LuaBinder()
  35. {
  36. if(m_l)
  37. {
  38. lua_close(m_l);
  39. }
  40. m_userDataSigToDataInfo.destroy(m_alloc);
  41. }
  42. Error LuaBinder::init(ScriptAllocator alloc, LuaBinderOtherSystems* otherSystems)
  43. {
  44. ANKI_ASSERT(otherSystems);
  45. m_otherSystems = otherSystems;
  46. m_alloc = alloc;
  47. m_l = lua_newstate(luaAllocCallback, this);
  48. luaL_openlibs(m_l);
  49. lua_atpanic(m_l, &luaPanic);
  50. wrapModules(m_l);
  51. return Error::NONE;
  52. }
  53. void* LuaBinder::luaAllocCallback(void* userData, void* ptr, PtrSize osize, PtrSize nsize)
  54. {
  55. ANKI_ASSERT(userData);
  56. #if 1
  57. LuaBinder& binder = *reinterpret_cast<LuaBinder*>(userData);
  58. void* out = nullptr;
  59. if(nsize == 0)
  60. {
  61. if(ptr != nullptr)
  62. {
  63. binder.m_alloc.getMemoryPool().free(ptr);
  64. }
  65. }
  66. else
  67. {
  68. // Should be doing something like realloc
  69. if(ptr == nullptr)
  70. {
  71. out = binder.m_alloc.getMemoryPool().allocate(nsize, 16);
  72. }
  73. else if(nsize <= osize)
  74. {
  75. out = ptr;
  76. }
  77. else
  78. {
  79. // realloc
  80. out = binder.m_alloc.getMemoryPool().allocate(nsize, 16);
  81. memcpy(out, ptr, osize);
  82. binder.m_alloc.getMemoryPool().free(ptr);
  83. }
  84. }
  85. #else
  86. void* out = nullptr;
  87. if(nsize == 0)
  88. {
  89. free(ptr);
  90. }
  91. else
  92. {
  93. out = realloc(ptr, nsize);
  94. }
  95. #endif
  96. return out;
  97. }
  98. Error LuaBinder::evalString(lua_State* state, const CString& str)
  99. {
  100. ANKI_TRACE_SCOPED_EVENT(LUA_EXEC);
  101. Error err = Error::NONE;
  102. int e = luaL_dostring(state, &str[0]);
  103. if(e)
  104. {
  105. ANKI_SCRIPT_LOGE("%s", lua_tostring(state, -1));
  106. lua_pop(state, 1);
  107. err = Error::USER_DATA;
  108. }
  109. garbageCollect(state);
  110. return err;
  111. }
  112. void LuaBinder::createClass(lua_State* l, const LuaUserDataTypeInfo* typeInfo)
  113. {
  114. ANKI_ASSERT(typeInfo);
  115. lua_newtable(l); // push new table
  116. lua_setglobal(l, typeInfo->m_typeName); // pop and make global
  117. luaL_newmetatable(l, typeInfo->m_typeName); // push
  118. lua_pushstring(l, "__index"); // push
  119. lua_pushvalue(l, -2); // pushes copy of the metatable
  120. lua_settable(l, -3); // pop*2: metatable.__index = metatable
  121. // After all these the metatable is in the top of tha stack
  122. // Now, store the typeInfo
  123. void* ud;
  124. lua_getallocf(l, &ud);
  125. ANKI_ASSERT(ud);
  126. LuaBinder& binder = *static_cast<LuaBinder*>(ud);
  127. binder.m_userDataSigToDataInfo.emplace(binder.m_alloc, typeInfo->m_signature, typeInfo);
  128. }
  129. void LuaBinder::pushLuaCFuncMethod(lua_State* l, const char* name, lua_CFunction luafunc)
  130. {
  131. lua_pushstring(l, name);
  132. lua_pushcfunction(l, luafunc);
  133. lua_settable(l, -3);
  134. }
  135. void LuaBinder::pushLuaCFuncStaticMethod(lua_State* l, const char* className, const char* name, lua_CFunction luafunc)
  136. {
  137. lua_getglobal(l, className); // push
  138. lua_pushcfunction(l, luafunc); // push
  139. lua_setfield(l, -2, name); // pop global
  140. lua_pop(l, 1); // pop cfunc
  141. }
  142. void LuaBinder::pushLuaCFunc(lua_State* l, const char* name, lua_CFunction luafunc)
  143. {
  144. lua_register(l, name, luafunc);
  145. }
  146. Error LuaBinder::checkNumberInternal(lua_State* l, I32 stackIdx, lua_Number& number)
  147. {
  148. Error err = Error::NONE;
  149. lua_Number lnum;
  150. int isnum;
  151. lnum = lua_tonumberx(l, stackIdx, &isnum);
  152. if(isnum)
  153. {
  154. number = lnum;
  155. }
  156. else
  157. {
  158. err = Error::USER_DATA;
  159. lua_pushfstring(l, "Number expected. Got %s", luaL_typename(l, stackIdx));
  160. }
  161. return err;
  162. }
  163. Error LuaBinder::checkString(lua_State* l, I32 stackIdx, const char*& out)
  164. {
  165. Error err = Error::NONE;
  166. const char* s = lua_tolstring(l, stackIdx, nullptr);
  167. if(s != nullptr)
  168. {
  169. out = s;
  170. }
  171. else
  172. {
  173. err = Error::USER_DATA;
  174. lua_pushfstring(l, "String expected. Got %s", luaL_typename(l, stackIdx));
  175. }
  176. return err;
  177. }
  178. Error LuaBinder::checkUserData(lua_State* l, I32 stackIdx, const LuaUserDataTypeInfo& typeInfo, LuaUserData*& out)
  179. {
  180. Error err = Error::NONE;
  181. void* p = lua_touserdata(l, stackIdx);
  182. if(p != nullptr)
  183. {
  184. out = reinterpret_cast<LuaUserData*>(p);
  185. if(out->getSig() == typeInfo.m_signature)
  186. {
  187. // Check using a LUA method again
  188. ANKI_ASSERT(luaL_testudata(l, stackIdx, typeInfo.m_typeName) != nullptr
  189. && "ANKI type check passes but LUA's type check failed");
  190. }
  191. else
  192. {
  193. // It's not the correct user data
  194. err = Error::USER_DATA;
  195. }
  196. }
  197. else
  198. {
  199. // It's not user data
  200. err = Error::USER_DATA;
  201. }
  202. if(err)
  203. {
  204. lua_pushfstring(l, "Userdata of %s expected. Got %s", typeInfo.m_typeName, luaL_typename(l, stackIdx));
  205. }
  206. return err;
  207. }
  208. Error LuaBinder::checkArgsCount(lua_State* l, I argsCount)
  209. {
  210. const I actualArgsCount = lua_gettop(l);
  211. if(argsCount != actualArgsCount)
  212. {
  213. lua_pushfstring(l, "Expecting %d arguments, got %d", argsCount, actualArgsCount);
  214. return Error::USER_DATA;
  215. }
  216. return Error::NONE;
  217. }
  218. void* LuaBinder::luaAlloc(lua_State* l, size_t size, U32 alignment)
  219. {
  220. void* ud;
  221. lua_getallocf(l, &ud);
  222. ANKI_ASSERT(ud);
  223. LuaBinder* binder = static_cast<LuaBinder*>(ud);
  224. return binder->m_alloc.getMemoryPool().allocate(size, alignment);
  225. }
  226. void LuaBinder::luaFree(lua_State* l, void* ptr)
  227. {
  228. void* ud;
  229. lua_getallocf(l, &ud);
  230. ANKI_ASSERT(ud);
  231. LuaBinder* binder = static_cast<LuaBinder*>(ud);
  232. binder->m_alloc.getMemoryPool().free(ptr);
  233. }
  234. void LuaBinder::serializeGlobals(lua_State* l, LuaBinderSerializeGlobalsCallback& callback)
  235. {
  236. ANKI_ASSERT(l);
  237. lua_pushglobaltable(l);
  238. lua_pushnil(l);
  239. while(lua_next(l, -2) != 0)
  240. {
  241. // Get type of key and value
  242. I keyType = lua_type(l, -2);
  243. I valueType = lua_type(l, -1);
  244. // Only string keys
  245. if(keyType != LUA_TSTRING)
  246. {
  247. lua_pop(l, 1);
  248. continue;
  249. }
  250. CString keyString = lua_tostring(l, -2);
  251. if(keyString.isEmpty() || keyString.getLength() == 0 || keyString[0] == '_')
  252. {
  253. lua_pop(l, 1);
  254. continue;
  255. }
  256. switch(valueType)
  257. {
  258. case LUA_TNUMBER:
  259. {
  260. // Write name
  261. callback.write(keyString.cstr(), keyString.getLength() + 1);
  262. // Write type
  263. U32 type = LUA_TNUMBER;
  264. callback.write(&type, sizeof(type));
  265. // Write value
  266. F64 val = lua_tonumber(l, -1);
  267. callback.write(&val, sizeof(val));
  268. break;
  269. }
  270. case LUA_TSTRING:
  271. {
  272. // Write name
  273. callback.write(keyString.cstr(), keyString.getLength() + 1);
  274. // Write type
  275. U32 type = LUA_TSTRING;
  276. callback.write(&type, sizeof(type));
  277. // Write str len
  278. CString val = lua_tostring(l, -1);
  279. callback.write(val.cstr(), val.getLength() + 1);
  280. break;
  281. }
  282. case LUA_TUSERDATA:
  283. {
  284. LuaUserData* ud = static_cast<LuaUserData*>(lua_touserdata(l, -1));
  285. ANKI_ASSERT(ud);
  286. LuaUserDataSerializeCallback cb = ud->getDataTypeInfo().m_serializeCallback;
  287. if(cb)
  288. {
  289. Array<U8, 256> buff;
  290. PtrSize dumpSize;
  291. cb(*ud, nullptr, dumpSize);
  292. if(dumpSize <= buff.getSize())
  293. {
  294. cb(*ud, &buff[0], dumpSize);
  295. }
  296. else
  297. {
  298. ANKI_ASSERT(!"TODO");
  299. }
  300. // Write name
  301. callback.write(keyString.cstr(), keyString.getLength() + 1);
  302. // Write type
  303. U32 type = LUA_TUSERDATA;
  304. callback.write(&type, sizeof(type));
  305. // Write sig
  306. callback.write(&ud->getDataTypeInfo().m_signature, sizeof(ud->getDataTypeInfo().m_signature));
  307. // Write data
  308. PtrSize size = dumpSize;
  309. callback.write(&size, sizeof(size));
  310. callback.write(&buff[0], dumpSize);
  311. }
  312. else
  313. {
  314. ANKI_SCRIPT_LOGW("Can't serialize variable %s. No callback provided", keyString.cstr());
  315. }
  316. break;
  317. }
  318. }
  319. lua_pop(l, 1);
  320. }
  321. }
  322. void LuaBinder::deserializeGlobals(lua_State* l, const void* data, PtrSize dataSize)
  323. {
  324. ANKI_ASSERT(dataSize > 0 && data);
  325. const U8* ptr = static_cast<const U8*>(data);
  326. const U8* end = ptr + dataSize;
  327. while(ptr < end)
  328. {
  329. // Get name
  330. CString name = reinterpret_cast<const char*>(ptr);
  331. U32 len = name.getLength();
  332. ANKI_ASSERT(len > 0);
  333. ptr += len + 1;
  334. // Get type
  335. I type = *reinterpret_cast<const U32*>(ptr);
  336. ptr += sizeof(U32);
  337. switch(type)
  338. {
  339. case LUA_TNUMBER:
  340. {
  341. const F64 val = *reinterpret_cast<const F64*>(ptr);
  342. ptr += sizeof(F64);
  343. lua_pushnumber(l, val);
  344. lua_setglobal(l, name.cstr());
  345. break;
  346. }
  347. case LUA_TSTRING:
  348. {
  349. CString val = reinterpret_cast<const char*>(ptr);
  350. const U len = val.getLength();
  351. ptr += len + 1;
  352. ANKI_ASSERT(len > 0);
  353. lua_pushstring(l, val.cstr());
  354. lua_setglobal(l, name.cstr());
  355. break;
  356. }
  357. case LUA_TUSERDATA:
  358. {
  359. // Get sig
  360. const I64 sig = *reinterpret_cast<const I64*>(ptr);
  361. ptr += sizeof(sig);
  362. // Get input data size
  363. const PtrSize dataSize = *reinterpret_cast<const PtrSize*>(ptr);
  364. ptr += sizeof(dataSize);
  365. // Get the type info
  366. void* ud;
  367. lua_getallocf(l, &ud);
  368. ANKI_ASSERT(ud);
  369. LuaBinder& binder = *static_cast<LuaBinder*>(ud);
  370. auto it = binder.m_userDataSigToDataInfo.find(sig);
  371. ANKI_ASSERT(it != binder.m_userDataSigToDataInfo.getEnd());
  372. const LuaUserDataTypeInfo* typeInfo = *it;
  373. // Create user data
  374. LuaUserData* userData = static_cast<LuaUserData*>(lua_newuserdata(l, typeInfo->m_structureSize));
  375. userData->initGarbageCollected(typeInfo);
  376. ANKI_ASSERT(typeInfo->m_deserializeCallback);
  377. typeInfo->m_deserializeCallback(ptr, *userData);
  378. ptr += dataSize;
  379. luaL_setmetatable(l, typeInfo->m_typeName);
  380. lua_setglobal(l, name.cstr());
  381. break;
  382. }
  383. }
  384. }
  385. }
  386. } // end namespace anki