ScriptController.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864
  1. #include "Base.h"
  2. #include "FileSystem.h"
  3. #include "ScriptController.h"
  4. #include "lua/lua_all_bindings.h"
  5. #define GENERATE_LUA_GET_POINTER(type, checkFunc) \
  6. ScriptController* sc = Game::getInstance()->getScriptController(); \
  7. /* Check that the parameter is the correct type. */ \
  8. if (!lua_istable(sc->_lua, index)) \
  9. { \
  10. if (lua_islightuserdata(sc->_lua, index)) \
  11. return (type*)lua_touserdata(sc->_lua, index); \
  12. lua_pushfstring(sc->_lua, "Expected a " #type " pointer (an array represented as a Lua table), got '%s' instead.", \
  13. luaL_typename(sc->_lua, index)); \
  14. lua_error(sc->_lua); \
  15. return NULL; \
  16. } \
  17. \
  18. /* Get the size of the array. */ \
  19. lua_len(sc->_lua, index); \
  20. int size = luaL_checkint(sc->_lua, -1); \
  21. if (size <= 0) \
  22. return NULL; \
  23. \
  24. /* Create an array to store the values. */ \
  25. type* values = (type*)malloc(sizeof(type)*size); \
  26. \
  27. /* Push the first key. */ \
  28. lua_pushnil(sc->_lua); \
  29. int i = 0; \
  30. for (; lua_next(sc->_lua, index) != 0 && i < size; i++) \
  31. { \
  32. values[i] = (checkFunc(sc->_lua, -1)); \
  33. \
  34. /* Remove the value we just retrieved, but leave the key for the next iteration. */ \
  35. lua_pop(sc->_lua, 1); \
  36. } \
  37. \
  38. return values
  39. namespace gameplay
  40. {
  41. void ScriptUtil::registerLibrary(const char* name, const luaL_Reg* functions)
  42. {
  43. ScriptController* sc = Game::getInstance()->getScriptController();
  44. lua_newtable(sc->_lua);
  45. // Go through the list of functions and add them to the table.
  46. const luaL_Reg* iter = functions;
  47. for (; iter && iter->name; iter++)
  48. {
  49. lua_pushcfunction(sc->_lua, iter->func);
  50. lua_setfield(sc->_lua, -2, iter->name);
  51. }
  52. lua_setglobal(sc->_lua, name);
  53. }
  54. void ScriptUtil::registerConstantBool(std::string name, bool value, std::vector<std::string> scopePath)
  55. {
  56. ScriptController* sc = Game::getInstance()->getScriptController();
  57. // If the constant is within a scope, get the correct parent
  58. // table on the stack before setting its value.
  59. if (scopePath.size() > 0)
  60. {
  61. lua_getglobal(sc->_lua, scopePath[0].c_str());
  62. for (unsigned int i = 1; i < scopePath.size(); i++)
  63. {
  64. lua_pushstring(sc->_lua, scopePath[i].c_str());
  65. lua_gettable(sc->_lua, -2);
  66. }
  67. // Add the constant to the parent table.
  68. lua_pushboolean(sc->_lua, value);
  69. lua_setfield(sc->_lua, -2, name.c_str());
  70. // Pop all the parent tables off the stack.
  71. int size = scopePath.size();
  72. lua_pop(sc->_lua, size);
  73. }
  74. else
  75. {
  76. // TODO: Currently unsupported (we don't parse for this yet).
  77. // If the constant is global, add it to the global table.
  78. lua_pushboolean(sc->_lua, value);
  79. lua_pushvalue(sc->_lua, -1);
  80. lua_setglobal(sc->_lua, name.c_str());
  81. }
  82. }
  83. void ScriptUtil::registerConstantNumber(std::string name, double value, std::vector<std::string> scopePath)
  84. {
  85. ScriptController* sc = Game::getInstance()->getScriptController();
  86. // If the constant is within a scope, get the correct parent
  87. // table on the stack before setting its value.
  88. if (scopePath.size() > 0)
  89. {
  90. lua_getglobal(sc->_lua, scopePath[0].c_str());
  91. for (unsigned int i = 1; i < scopePath.size(); i++)
  92. {
  93. lua_pushstring(sc->_lua, scopePath[i].c_str());
  94. lua_gettable(sc->_lua, -2);
  95. }
  96. // Add the constant to the parent table.
  97. lua_pushnumber(sc->_lua, value);
  98. lua_setfield(sc->_lua, -2, name.c_str());
  99. // Pop all the parent tables off the stack.
  100. int size = scopePath.size();
  101. lua_pop(sc->_lua, size);
  102. }
  103. else
  104. {
  105. // TODO: Currently unsupported (we don't parse for this yet).
  106. // If the constant is global, add it to the global table.
  107. lua_pushnumber(sc->_lua, value);
  108. lua_pushvalue(sc->_lua, -1);
  109. lua_setglobal(sc->_lua, name.c_str());
  110. }
  111. }
  112. void ScriptUtil::registerConstantString(std::string name, std::string value, std::vector<std::string> scopePath)
  113. {
  114. ScriptController* sc = Game::getInstance()->getScriptController();
  115. // If the constant is within a scope, get the correct parent
  116. // table on the stack before setting its value.
  117. if (scopePath.size() > 0)
  118. {
  119. lua_getglobal(sc->_lua, scopePath[0].c_str());
  120. for (unsigned int i = 1; i < scopePath.size(); i++)
  121. {
  122. lua_pushstring(sc->_lua, scopePath[i].c_str());
  123. lua_gettable(sc->_lua, -2);
  124. }
  125. // Add the constant to the parent table.
  126. lua_pushstring(sc->_lua, value.c_str());
  127. lua_setfield(sc->_lua, -2, name.c_str());
  128. // Pop all the parent tables off the stack.
  129. int size = scopePath.size();
  130. lua_pop(sc->_lua, size);
  131. }
  132. else
  133. {
  134. // TODO: Currently unsupported (we don't parse for this yet).
  135. // If the constant is global, add it to the global table.
  136. lua_pushstring(sc->_lua, value.c_str());
  137. lua_pushvalue(sc->_lua, -1);
  138. lua_setglobal(sc->_lua, name.c_str());
  139. }
  140. }
  141. void ScriptUtil::registerClass(const char* name, const luaL_Reg* members, lua_CFunction newFunction,
  142. lua_CFunction deleteFunction, const luaL_Reg* statics, std::vector<std::string> scopePath)
  143. {
  144. ScriptController* sc = Game::getInstance()->getScriptController();
  145. // If the type is an inner type, get the correct parent
  146. // table on the stack before creating the table for the class.
  147. if (scopePath.size() > 0)
  148. {
  149. std::string tablename = name;
  150. // Strip off the scope path part of the name.
  151. lua_getglobal(sc->_lua, scopePath[0].c_str());
  152. std::size_t index = tablename.find(scopePath[0]);
  153. if (index != tablename.npos)
  154. tablename = tablename.substr(index + scopePath[0].size());
  155. for (unsigned int i = 1; i < scopePath.size(); i++)
  156. {
  157. lua_pushstring(sc->_lua, scopePath[i].c_str());
  158. lua_gettable(sc->_lua, -2);
  159. index = tablename.find(scopePath[i]);
  160. if (index != tablename.npos)
  161. tablename = tablename.substr(index + scopePath[i].size());
  162. }
  163. lua_pushstring(sc->_lua, tablename.c_str());
  164. lua_newtable(sc->_lua);
  165. }
  166. else
  167. {
  168. // If the type is not an inner type, set it as a global table.
  169. lua_newtable(sc->_lua);
  170. lua_pushvalue(sc->_lua, -1);
  171. lua_setglobal(sc->_lua, name);
  172. }
  173. // Create the metatable and populate it with the member functions.
  174. lua_pushliteral(sc->_lua, "__metatable");
  175. luaL_newmetatable(sc->_lua, name);
  176. if (members)
  177. luaL_setfuncs(sc->_lua, members, 0);
  178. lua_pushstring(sc->_lua, "__index");
  179. lua_pushvalue(sc->_lua, -2);
  180. lua_settable(sc->_lua, -3);
  181. // Add the delete function if it was specified.
  182. if (deleteFunction)
  183. {
  184. lua_pushstring(sc->_lua, "__gc");
  185. lua_pushcfunction(sc->_lua, deleteFunction);
  186. lua_settable(sc->_lua, -3);
  187. }
  188. // Set the metatable on the main table.
  189. lua_settable(sc->_lua, -3);
  190. // Populate the main table with the static functions.
  191. if (statics)
  192. luaL_setfuncs(sc->_lua, statics, 0);
  193. // Set the new function(s) for the class.
  194. if (newFunction)
  195. {
  196. lua_pushliteral(sc->_lua, "new");
  197. lua_pushcfunction(sc->_lua, newFunction);
  198. lua_settable(sc->_lua, -3);
  199. }
  200. // Set the table we just created within the correct parent table.
  201. if (scopePath.size() > 0)
  202. {
  203. lua_settable(sc->_lua, -3);
  204. // Pop all the parent tables off the stack.
  205. int size = scopePath.size();
  206. lua_pop(sc->_lua, size);
  207. }
  208. else
  209. {
  210. // Pop the main table off the stack.
  211. lua_pop(sc->_lua, 1);
  212. }
  213. }
  214. void ScriptUtil::registerFunction(const char* luaFunction, lua_CFunction cppFunction)
  215. {
  216. lua_pushcfunction(Game::getInstance()->getScriptController()->_lua, cppFunction);
  217. lua_setglobal(Game::getInstance()->getScriptController()->_lua, luaFunction);
  218. }
  219. void ScriptUtil::setGlobalHierarchy(std::map<std::string, std::vector<std::string> > hierarchy)
  220. {
  221. Game::getInstance()->getScriptController()->_hierarchy = hierarchy;
  222. }
  223. bool* ScriptUtil::getBoolPointer(int index)
  224. {
  225. GENERATE_LUA_GET_POINTER(bool, luaCheckBool);
  226. }
  227. short* ScriptUtil::getShortPointer(int index)
  228. {
  229. GENERATE_LUA_GET_POINTER(short, (short)luaL_checkint);
  230. }
  231. int* ScriptUtil::getIntPointer(int index)
  232. {
  233. GENERATE_LUA_GET_POINTER(int, (int)luaL_checkint);
  234. }
  235. long* ScriptUtil::getLongPointer(int index)
  236. {
  237. GENERATE_LUA_GET_POINTER(long, (long)luaL_checkint);
  238. }
  239. unsigned char* ScriptUtil::getUnsignedCharPointer(int index)
  240. {
  241. GENERATE_LUA_GET_POINTER(unsigned char, (unsigned char)luaL_checkunsigned);
  242. }
  243. unsigned short* ScriptUtil::getUnsignedShortPointer(int index)
  244. {
  245. GENERATE_LUA_GET_POINTER(unsigned short, (unsigned short)luaL_checkunsigned);
  246. }
  247. unsigned int* ScriptUtil::getUnsignedIntPointer(int index)
  248. {
  249. GENERATE_LUA_GET_POINTER(unsigned int, (unsigned int)luaL_checkunsigned);
  250. }
  251. unsigned long* ScriptUtil::getUnsignedLongPointer(int index)
  252. {
  253. GENERATE_LUA_GET_POINTER(unsigned long, (unsigned long)luaL_checkunsigned);
  254. }
  255. float* ScriptUtil::getFloatPointer(int index)
  256. {
  257. GENERATE_LUA_GET_POINTER(float, (float)luaL_checknumber);
  258. }
  259. double* ScriptUtil::getDoublePointer(int index)
  260. {
  261. GENERATE_LUA_GET_POINTER(double, (double)luaL_checknumber);
  262. }
  263. const char* ScriptUtil::getString(int index, bool isStdString)
  264. {
  265. if (lua_type(Game::getInstance()->getScriptController()->_lua, index) == LUA_TSTRING)
  266. return luaL_checkstring(Game::getInstance()->getScriptController()->_lua, index);
  267. else if (lua_type(Game::getInstance()->getScriptController()->_lua, index) == LUA_TNIL && !isStdString)
  268. return NULL;
  269. else
  270. {
  271. GP_ERROR("Invalid string parameter (index = %d).", index);
  272. return NULL;
  273. }
  274. }
  275. bool ScriptUtil::luaCheckBool(lua_State* state, int n)
  276. {
  277. if (!lua_isboolean(state, n))
  278. {
  279. const char* msg = lua_pushfstring(state, "%s expected, got %s", lua_typename(state, LUA_TBOOLEAN), luaL_typename(state, n));
  280. luaL_argerror(state, n, msg);
  281. return false;
  282. }
  283. return (lua_toboolean(state, n) != 0);
  284. }
  285. void ScriptController::loadScript(const char* path)
  286. {
  287. const char* scriptContents = FileSystem::readAll(path);
  288. if (luaL_dostring(_lua, scriptContents))
  289. GP_ERROR("Failed to run Lua script with error: '%s'.", lua_tostring(_lua, -1));
  290. SAFE_DELETE_ARRAY(scriptContents);
  291. }
  292. bool ScriptController::getBool(const char* name)
  293. {
  294. lua_getglobal(_lua, name);
  295. return ScriptUtil::luaCheckBool(_lua, -1);
  296. }
  297. char ScriptController::getChar(const char* name)
  298. {
  299. lua_getglobal(_lua, name);
  300. return (char)luaL_checkint(_lua, -1);
  301. }
  302. short ScriptController::getShort(const char* name)
  303. {
  304. lua_getglobal(_lua, name);
  305. return (short)luaL_checkint(_lua, -1);
  306. }
  307. int ScriptController::getInt(const char* name)
  308. {
  309. lua_getglobal(_lua, name);
  310. return luaL_checkint(_lua, -1);
  311. }
  312. long ScriptController::getLong(const char* name)
  313. {
  314. lua_getglobal(_lua, name);
  315. return luaL_checklong(_lua, -1);
  316. }
  317. unsigned char ScriptController::getUnsignedChar(const char* name)
  318. {
  319. lua_getglobal(_lua, name);
  320. return (unsigned char)luaL_checkunsigned(_lua, -1);
  321. }
  322. unsigned short ScriptController::getUnsignedShort(const char* name)
  323. {
  324. lua_getglobal(_lua, name);
  325. return (unsigned short)luaL_checkunsigned(_lua, -1);
  326. }
  327. unsigned int ScriptController::getUnsignedInt(const char* name)
  328. {
  329. lua_getglobal(_lua, name);
  330. return (unsigned int)luaL_checkunsigned(_lua, -1);
  331. }
  332. unsigned long ScriptController::getUnsignedLong(const char* name)
  333. {
  334. lua_getglobal(_lua, name);
  335. return (unsigned long)luaL_checkunsigned(_lua, -1);
  336. }
  337. float ScriptController::getFloat(const char* name)
  338. {
  339. lua_getglobal(_lua, name);
  340. return (float)luaL_checknumber(_lua, -1);
  341. }
  342. double ScriptController::getDouble(const char* name)
  343. {
  344. lua_getglobal(_lua, name);
  345. return (double)luaL_checknumber(_lua, -1);
  346. }
  347. const char* ScriptController::getString(const char* name)
  348. {
  349. lua_getglobal(_lua, name);
  350. return luaL_checkstring(_lua, -1);
  351. }
  352. void ScriptController::setBool(const char* name, bool v)
  353. {
  354. lua_pushboolean(_lua, v);
  355. lua_setglobal(_lua, name);
  356. }
  357. void ScriptController::setChar(const char* name, char v)
  358. {
  359. lua_pushinteger(_lua, v);
  360. lua_setglobal(_lua, name);
  361. }
  362. void ScriptController::setShort(const char* name, short v)
  363. {
  364. lua_pushinteger(_lua, v);
  365. lua_setglobal(_lua, name);
  366. }
  367. void ScriptController::setInt(const char* name, int v)
  368. {
  369. lua_pushinteger(_lua, v);
  370. lua_setglobal(_lua, name);
  371. }
  372. void ScriptController::setLong(const char* name, long v)
  373. {
  374. lua_pushinteger(_lua, v);
  375. lua_setglobal(_lua, name);
  376. }
  377. void ScriptController::setUnsignedChar(const char* name, unsigned char v)
  378. {
  379. lua_pushunsigned(_lua, v);
  380. lua_setglobal(_lua, name);
  381. }
  382. void ScriptController::setUnsignedShort(const char* name, unsigned short v)
  383. {
  384. lua_pushunsigned(_lua, v);
  385. lua_setglobal(_lua, name);
  386. }
  387. void ScriptController::setUnsignedInt(const char* name, unsigned int v)
  388. {
  389. lua_pushunsigned(_lua, v);
  390. lua_setglobal(_lua, name);
  391. }
  392. void ScriptController::setUnsignedLong(const char* name, unsigned long v)
  393. {
  394. lua_pushunsigned(_lua, v);
  395. lua_setglobal(_lua, name);
  396. }
  397. void ScriptController::setFloat(const char* name, float v)
  398. {
  399. lua_pushnumber(_lua, v);
  400. lua_setglobal(_lua, name);
  401. }
  402. void ScriptController::setDouble(const char* name, double v)
  403. {
  404. lua_pushnumber(_lua, v);
  405. lua_setglobal(_lua, name);
  406. }
  407. void ScriptController::setString(const char* name, const char* v)
  408. {
  409. lua_pushstring(_lua, v);
  410. lua_setglobal(_lua, name);
  411. }
  412. ScriptController::ScriptController() : _lua(NULL)
  413. {
  414. memset(_callbacks, 0, sizeof(std::string*) * CALLBACK_COUNT);
  415. }
  416. ScriptController::~ScriptController()
  417. {
  418. }
  419. void ScriptController::initialize()
  420. {
  421. _lua = luaL_newstate();
  422. if (!_lua)
  423. GP_ERROR("Failed to initialize Lua scripting engine.");
  424. luaL_openlibs(_lua);
  425. lua_RegisterAllBindings();
  426. }
  427. void ScriptController::initializeGame()
  428. {
  429. if (_callbacks[INITIALIZE])
  430. {
  431. executeFunction<void>(_callbacks[INITIALIZE]->c_str());
  432. }
  433. }
  434. void ScriptController::finalize()
  435. {
  436. if (_lua)
  437. lua_close(_lua);
  438. }
  439. void ScriptController::finalizeGame()
  440. {
  441. if (_callbacks[FINALIZE])
  442. {
  443. executeFunction<void>(_callbacks[FINALIZE]->c_str());
  444. }
  445. }
  446. void ScriptController::update(float elapsedTime)
  447. {
  448. if (_callbacks[UPDATE])
  449. {
  450. executeFunction<void>(_callbacks[UPDATE]->c_str(), "f", elapsedTime);
  451. }
  452. }
  453. void ScriptController::render(float elapsedTime)
  454. {
  455. if (_callbacks[RENDER])
  456. {
  457. executeFunction<void>(_callbacks[RENDER]->c_str(), "f", elapsedTime);
  458. }
  459. }
  460. void ScriptController::keyEvent(Keyboard::KeyEvent evt, int key)
  461. {
  462. if (_callbacks[KEY_EVENT])
  463. {
  464. executeFunction<void>(_callbacks[KEY_EVENT]->c_str(), "[Keyboard::KeyEvent][Keyboard::Key]", evt, key);
  465. }
  466. }
  467. void ScriptController::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
  468. {
  469. if (_callbacks[TOUCH_EVENT])
  470. {
  471. executeFunction<void>(_callbacks[TOUCH_EVENT]->c_str(), "[Touch::TouchEvent]iiui", evt, x, y, contactIndex);
  472. }
  473. }
  474. bool ScriptController::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
  475. {
  476. if (_callbacks[MOUSE_EVENT])
  477. {
  478. return executeFunction<bool>(_callbacks[MOUSE_EVENT]->c_str(), "[Mouse::MouseEvent]iiii", evt, x, y, wheelDelta);
  479. }
  480. return false;
  481. }
  482. void ScriptController::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad)
  483. {
  484. if (_callbacks[GAMEPAD_EVENT])
  485. {
  486. executeFunction<void>(_callbacks[GAMEPAD_EVENT]->c_str(), "[Gamepad::GamepadEvent]<Gamepad>", evt, gamepad);
  487. }
  488. }
  489. void ScriptController::executeFunctionHelper(int resultCount, const char* func, const char* args, va_list* list)
  490. {
  491. if (func == NULL)
  492. {
  493. GP_ERROR("Lua function name must be non-null.");
  494. return;
  495. }
  496. const char* sig = args;
  497. int argumentCount = 0;
  498. lua_getglobal(_lua, func);
  499. // Push the arguments to the Lua stack if there are any.
  500. if (sig)
  501. {
  502. while (true)
  503. {
  504. if (!(*sig))
  505. break;
  506. switch(*sig++)
  507. {
  508. // Signed integers.
  509. case 'c':
  510. case 'h':
  511. case 'i':
  512. case 'l':
  513. lua_pushinteger(_lua, va_arg(*list, int));
  514. break;
  515. // Unsigned integers.
  516. case 'u':
  517. // Skip past the actual type (long, int, short, char).
  518. sig++;
  519. lua_pushunsigned(_lua, va_arg(*list, int));
  520. break;
  521. // Booleans.
  522. case 'b':
  523. lua_pushboolean(_lua, va_arg(*list, int));
  524. break;
  525. // Floating point numbers.
  526. case 'f':
  527. case 'd':
  528. lua_pushnumber(_lua, va_arg(*list, double));
  529. break;
  530. // Strings.
  531. case 's':
  532. lua_pushstring(_lua, va_arg(*list, char*));
  533. break;
  534. // Pointers.
  535. case 'p':
  536. lua_pushlightuserdata(_lua, va_arg(*list, void*));
  537. break;
  538. // Enums.
  539. case '[':
  540. {
  541. std::string type = sig;
  542. type = type.substr(0, type.find("]"));
  543. // Skip past the closing ']' (the semi-colon here is intentional-do not remove).
  544. while (*sig++ != ']');
  545. lua_pushstring(_lua, lua_stringFromEnumGlobal(type, va_arg(*list, int)));
  546. break;
  547. }
  548. // Object references/pointers (Lua userdata).
  549. case '<':
  550. {
  551. std::string type = sig;
  552. type = type.substr(0, type.find(">"));
  553. // Skip past the closing '>' (the semi-colon here is intentional-do not remove).
  554. while (*sig++ != '>');
  555. // Calculate the unique Lua type name.
  556. size_t i = type.find("::");
  557. while (i != type.npos)
  558. {
  559. // We use "" as the replacement here-this must match the preprocessor
  560. // define SCOPE_REPLACEMENT from the gameplay-luagen project.
  561. type.replace(i, 2, "");
  562. i = type.find("::");
  563. }
  564. void* ptr = va_arg(*list, void*);
  565. if (ptr == NULL)
  566. {
  567. lua_pushnil(_lua);
  568. }
  569. else
  570. {
  571. ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(_lua, sizeof(ScriptUtil::LuaObject));
  572. object->instance = ptr;
  573. object->owns = false;
  574. luaL_getmetatable(_lua, type.c_str());
  575. lua_setmetatable(_lua, -2);
  576. }
  577. break;
  578. }
  579. default:
  580. GP_ERROR("Invalid argument type '%d'.", *(sig - 1));
  581. }
  582. argumentCount++;
  583. luaL_checkstack(_lua, 1, "Too many arguments.");
  584. }
  585. }
  586. // Perform the function call.
  587. if (lua_pcall(_lua, argumentCount, resultCount, 0) != 0)
  588. GP_ERROR("Failed to call function '%s' with error '%s'.", func, lua_tostring(_lua, -1));
  589. }
  590. void ScriptController::registerCallback(ScriptCallback callback, std::string function)
  591. {
  592. SAFE_DELETE(_callbacks[callback]);
  593. _callbacks[callback] = new std::string(function);
  594. }
  595. ScriptController::ScriptCallback ScriptController::toCallback(const char* name)
  596. {
  597. if (strcmp(name, "initialize") == 0)
  598. return ScriptController::INITIALIZE;
  599. else if (strcmp(name, "update") == 0)
  600. return ScriptController::UPDATE;
  601. else if (strcmp(name, "render") == 0)
  602. return ScriptController::RENDER;
  603. else if (strcmp(name, "finalize") == 0)
  604. return ScriptController::FINALIZE;
  605. else if (strcmp(name, "keyEvent") == 0)
  606. return ScriptController::KEY_EVENT;
  607. else if (strcmp(name, "touchEvent") == 0)
  608. return ScriptController::TOUCH_EVENT;
  609. else if (strcmp(name, "mouseEvent") == 0)
  610. return ScriptController::MOUSE_EVENT;
  611. else if (strcmp(name, "gamepadEvent") == 0)
  612. return ScriptController::GAMEPAD_EVENT;
  613. else
  614. return ScriptController::INVALID_CALLBACK;
  615. }
  616. // Helper macros.
  617. #define SCRIPT_EXECUTE_FUNCTION_NO_PARAM(type, checkfunc) \
  618. executeFunctionHelper(1, func, NULL, NULL); \
  619. type value = (type)checkfunc(_lua, -1); \
  620. lua_pop(_lua, -1); \
  621. return value;
  622. #define SCRIPT_EXECUTE_FUNCTION_PARAM(type, checkfunc) \
  623. va_list list; \
  624. va_start(list, args); \
  625. executeFunctionHelper(1, func, args, &list); \
  626. type value = (type)checkfunc(_lua, -1); \
  627. lua_pop(_lua, -1); \
  628. va_end(list); \
  629. return value;
  630. template<> void ScriptController::executeFunction<void>(const char* func)
  631. {
  632. executeFunctionHelper(0, func, NULL, NULL);
  633. }
  634. template<> bool ScriptController::executeFunction<bool>(const char* func)
  635. {
  636. SCRIPT_EXECUTE_FUNCTION_NO_PARAM(bool, ScriptUtil::luaCheckBool);
  637. }
  638. template<> char ScriptController::executeFunction<char>(const char* func)
  639. {
  640. SCRIPT_EXECUTE_FUNCTION_NO_PARAM(char, luaL_checkint);
  641. }
  642. template<> short ScriptController::executeFunction<short>(const char* func)
  643. {
  644. SCRIPT_EXECUTE_FUNCTION_NO_PARAM(short, luaL_checkint);
  645. }
  646. template<> int ScriptController::executeFunction<int>(const char* func)
  647. {
  648. SCRIPT_EXECUTE_FUNCTION_NO_PARAM(int, luaL_checkint);
  649. }
  650. template<> long ScriptController::executeFunction<long>(const char* func)
  651. {
  652. SCRIPT_EXECUTE_FUNCTION_NO_PARAM(long, luaL_checklong);
  653. }
  654. template<> unsigned char ScriptController::executeFunction<unsigned char>(const char* func)
  655. {
  656. SCRIPT_EXECUTE_FUNCTION_NO_PARAM(unsigned char, luaL_checkunsigned);
  657. }
  658. template<> unsigned short ScriptController::executeFunction<unsigned short>(const char* func)
  659. {
  660. SCRIPT_EXECUTE_FUNCTION_NO_PARAM(unsigned short, luaL_checkunsigned);
  661. }
  662. template<> unsigned int ScriptController::executeFunction<unsigned int>(const char* func)
  663. {
  664. SCRIPT_EXECUTE_FUNCTION_NO_PARAM(unsigned int, luaL_checkunsigned);
  665. }
  666. template<> unsigned long ScriptController::executeFunction<unsigned long>(const char* func)
  667. {
  668. SCRIPT_EXECUTE_FUNCTION_NO_PARAM(unsigned long, luaL_checkunsigned);
  669. }
  670. template<> float ScriptController::executeFunction<float>(const char* func)
  671. {
  672. SCRIPT_EXECUTE_FUNCTION_NO_PARAM(float, luaL_checknumber);
  673. }
  674. template<> double ScriptController::executeFunction<double>(const char* func)
  675. {
  676. SCRIPT_EXECUTE_FUNCTION_NO_PARAM(double, luaL_checknumber);
  677. }
  678. template<> std::string ScriptController::executeFunction<std::string>(const char* func)
  679. {
  680. SCRIPT_EXECUTE_FUNCTION_NO_PARAM(std::string, luaL_checkstring);
  681. }
  682. template<> void ScriptController::executeFunction<void>(const char* func, const char* args, ...)
  683. {
  684. va_list list;
  685. va_start(list, args);
  686. executeFunctionHelper(0, func, args, &list);
  687. va_end(list);
  688. }
  689. template<> bool ScriptController::executeFunction<bool>(const char* func, const char* args, ...)
  690. {
  691. SCRIPT_EXECUTE_FUNCTION_PARAM(bool, ScriptUtil::luaCheckBool);
  692. }
  693. template<> char ScriptController::executeFunction<char>(const char* func, const char* args, ...)
  694. {
  695. SCRIPT_EXECUTE_FUNCTION_PARAM(char, luaL_checkint);
  696. }
  697. template<> short ScriptController::executeFunction<short>(const char* func, const char* args, ...)
  698. {
  699. SCRIPT_EXECUTE_FUNCTION_PARAM(short, luaL_checkint);
  700. }
  701. template<> int ScriptController::executeFunction<int>(const char* func, const char* args, ...)
  702. {
  703. SCRIPT_EXECUTE_FUNCTION_PARAM(int, luaL_checkint);
  704. }
  705. template<> long ScriptController::executeFunction<long>(const char* func, const char* args, ...)
  706. {
  707. SCRIPT_EXECUTE_FUNCTION_PARAM(long, luaL_checklong);
  708. }
  709. template<> unsigned char ScriptController::executeFunction<unsigned char>(const char* func, const char* args, ...)
  710. {
  711. SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned char, luaL_checkunsigned);
  712. }
  713. template<> unsigned short ScriptController::executeFunction<unsigned short>(const char* func, const char* args, ...)
  714. {
  715. SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned short, luaL_checkunsigned);
  716. }
  717. template<> unsigned int ScriptController::executeFunction<unsigned int>(const char* func, const char* args, ...)
  718. {
  719. SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned int, luaL_checkunsigned);
  720. }
  721. template<> unsigned long ScriptController::executeFunction<unsigned long>(const char* func, const char* args, ...)
  722. {
  723. SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned long, luaL_checkunsigned);
  724. }
  725. template<> float ScriptController::executeFunction<float>(const char* func, const char* args, ...)
  726. {
  727. SCRIPT_EXECUTE_FUNCTION_PARAM(float, luaL_checknumber);
  728. }
  729. template<> double ScriptController::executeFunction<double>(const char* func, const char* args, ...)
  730. {
  731. SCRIPT_EXECUTE_FUNCTION_PARAM(double, luaL_checknumber);
  732. }
  733. template<> std::string ScriptController::executeFunction<std::string>(const char* func, const char* args, ...)
  734. {
  735. SCRIPT_EXECUTE_FUNCTION_PARAM(std::string, luaL_checkstring);
  736. }
  737. }