ScriptController.inl 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #include "ScriptController.h"
  2. namespace gameplay
  3. {
  4. // Helper macros.
  5. #define SCRIPT_EXECUTE_FUNCTION_PARAM(type, checkfunc) \
  6. va_list list; \
  7. va_start(list, args); \
  8. executeFunctionHelper(1, func, args, list); \
  9. type value = (type)checkfunc(_lua, -1); \
  10. lua_pop(_lua, -1); \
  11. va_end(list); \
  12. return value;
  13. template<typename T> T ScriptController::executeFunction(const char* func, const char* args, ...)
  14. {
  15. GP_ERROR("Unsupported type!");
  16. }
  17. template<> void ScriptController::executeFunction<void>(const char* func, const char* args, ...)
  18. {
  19. va_list list;
  20. va_start(list, args);
  21. executeFunctionHelper(0, func, args, list);
  22. va_end(list);
  23. }
  24. template<> bool ScriptController::executeFunction<bool>(const char* func, const char* args, ...)
  25. {
  26. SCRIPT_EXECUTE_FUNCTION_PARAM(bool, luaCheckBool);
  27. }
  28. template<> char ScriptController::executeFunction<char>(const char* func, const char* args, ...)
  29. {
  30. SCRIPT_EXECUTE_FUNCTION_PARAM(char, luaL_checkint);
  31. }
  32. template<> short ScriptController::executeFunction<short>(const char* func, const char* args, ...)
  33. {
  34. SCRIPT_EXECUTE_FUNCTION_PARAM(short, luaL_checkint);
  35. }
  36. template<> int ScriptController::executeFunction<int>(const char* func, const char* args, ...)
  37. {
  38. SCRIPT_EXECUTE_FUNCTION_PARAM(int, luaL_checkint);
  39. }
  40. template<> long ScriptController::executeFunction<long>(const char* func, const char* args, ...)
  41. {
  42. SCRIPT_EXECUTE_FUNCTION_PARAM(long, luaL_checklong);
  43. }
  44. template<> unsigned char ScriptController::executeFunction<unsigned char>(const char* func, const char* args, ...)
  45. {
  46. SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned char, luaL_checkunsigned);
  47. }
  48. template<> unsigned short ScriptController::executeFunction<unsigned short>(const char* func, const char* args, ...)
  49. {
  50. SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned short, luaL_checkunsigned);
  51. }
  52. template<> unsigned int ScriptController::executeFunction<unsigned int>(const char* func, const char* args, ...)
  53. {
  54. SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned int, luaL_checkunsigned);
  55. }
  56. template<> unsigned long ScriptController::executeFunction<unsigned long>(const char* func, const char* args, ...)
  57. {
  58. SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned long, luaL_checkunsigned);
  59. }
  60. template<> float ScriptController::executeFunction<float>(const char* func, const char* args, ...)
  61. {
  62. SCRIPT_EXECUTE_FUNCTION_PARAM(float, luaL_checknumber);
  63. }
  64. template<> double ScriptController::executeFunction<double>(const char* func, const char* args, ...)
  65. {
  66. SCRIPT_EXECUTE_FUNCTION_PARAM(double, luaL_checknumber);
  67. }
  68. template<> std::string ScriptController::executeFunction<std::string>(const char* func, const char* args, ...)
  69. {
  70. SCRIPT_EXECUTE_FUNCTION_PARAM(std::string, luaL_checkstring);
  71. }
  72. template<typename T> T* ScriptController::executeFunction(const Type& type, const char* func, const char* args, ...)
  73. {
  74. va_list list;
  75. va_start(list, args);
  76. executeFunctionHelper(1, func, args, list);
  77. T* value = (T*)*((T**)luaL_checkudata(_lua, -1, type.type));
  78. lua_pop(_lua, -1);
  79. va_end(list);
  80. return value;
  81. }
  82. template<typename T>T* ScriptController::getObjectPointer(int index, const char* type, bool nonNull)
  83. {
  84. if (lua_type(_lua, index) == LUA_TNIL)
  85. {
  86. if (nonNull)
  87. {
  88. GP_ERROR("Attempting to pass NULL for required non-NULL parameter at index %d (likely a reference or by-value parameter).", index);
  89. }
  90. return NULL;
  91. }
  92. void* p = lua_touserdata(_lua, index);
  93. if (p != NULL)
  94. {
  95. if (lua_getmetatable(_lua, index))
  96. {
  97. // Check if it matches the type's metatable.
  98. luaL_getmetatable(_lua, type);
  99. if (lua_rawequal(_lua, -1, -2))
  100. {
  101. lua_pop(_lua, 2);
  102. T* ptr = (T*)((ScriptController::LuaObject*)p)->instance;
  103. if (ptr == NULL && nonNull)
  104. {
  105. GP_ERROR("Attempting to pass NULL for required non-NULL parameter at index %d (likely a reference or by-value parameter).", index);
  106. }
  107. return ptr;
  108. }
  109. lua_pop(_lua, 1);
  110. // Check if it matches any of the derived types' metatables.
  111. const std::vector<std::string>& types = _hierarchy[type];
  112. for (unsigned int i = 0, count = types.size(); i < count; i++)
  113. {
  114. luaL_getmetatable(_lua, types[i].c_str());
  115. if (lua_rawequal(_lua, -1, -2))
  116. {
  117. lua_pop(_lua, 2);
  118. T* ptr = (T*)((ScriptController::LuaObject*)p)->instance;
  119. if (ptr == NULL && nonNull)
  120. {
  121. GP_ERROR("Attempting to pass NULL for required non-NULL parameter at index %d (likely a reference or by-value parameter).", index);
  122. }
  123. return ptr;
  124. }
  125. lua_pop(_lua, 1);
  126. }
  127. lua_pop(_lua, 1);
  128. }
  129. }
  130. if (nonNull)
  131. {
  132. GP_ERROR("Failed to retrieve a valid object pointer of type '%s' for parameter %d.", type, index);
  133. }
  134. return NULL;
  135. }
  136. template<typename T>T* ScriptController::getObjectPointer(const char* type, const char* name)
  137. {
  138. lua_getglobal(_lua, name);
  139. void* userdata = luaL_checkudata(_lua, -1, type);
  140. std::string msg = std::string("'") + std::string(type) + std::string("' expected.");
  141. luaL_argcheck(_lua, userdata != NULL, 1, msg.c_str());
  142. return (T*)((ScriptController::LuaObject*)userdata)->instance;
  143. }
  144. template<typename T>void ScriptController::setPointer(const char* type, const char* name, T* v)
  145. {
  146. ScriptController::LuaObject* object = (ScriptController::LuaObject*)lua_newuserdata(state, sizeof(ScriptController::LuaObject));
  147. object->instance = (void*)v;
  148. object->owns = false;
  149. luaL_getmetatable(state, type);
  150. lua_setmetatable(state, -2);
  151. lua_setglobal(_lua, name);
  152. }
  153. }