|
|
@@ -153,329 +153,15 @@ static bool getNestedVariable(lua_State* lua, const char* name, int script = 0)
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-void ScriptUtil::registerLibrary(const char* name, const luaL_Reg* functions)
|
|
|
-{
|
|
|
- ScriptController* sc = Game::getInstance()->getScriptController();
|
|
|
- lua_newtable(sc->_lua);
|
|
|
-
|
|
|
- // Go through the list of functions and add them to the table.
|
|
|
- const luaL_Reg* iter = functions;
|
|
|
- for (; iter && iter->name; iter++)
|
|
|
- {
|
|
|
- lua_pushcfunction(sc->_lua, iter->func);
|
|
|
- lua_setfield(sc->_lua, -2, iter->name);
|
|
|
- }
|
|
|
-
|
|
|
- lua_setglobal(sc->_lua, name);
|
|
|
-}
|
|
|
-
|
|
|
-void ScriptUtil::registerConstantBool(const std::string& name, bool value, const std::vector<std::string>& scopePath)
|
|
|
-{
|
|
|
- ScriptController* sc = Game::getInstance()->getScriptController();
|
|
|
-
|
|
|
- // If the constant is within a scope, get the correct parent
|
|
|
- // table on the stack before setting its value.
|
|
|
- if (!scopePath.empty())
|
|
|
- {
|
|
|
- lua_getglobal(sc->_lua, scopePath[0].c_str());
|
|
|
- for (unsigned int i = 1; i < scopePath.size(); i++)
|
|
|
- {
|
|
|
- lua_pushstring(sc->_lua, scopePath[i].c_str());
|
|
|
- lua_gettable(sc->_lua, -2);
|
|
|
- }
|
|
|
-
|
|
|
- // Add the constant to the parent table.
|
|
|
- lua_pushboolean(sc->_lua, value);
|
|
|
- lua_setfield(sc->_lua, -2, name.c_str());
|
|
|
-
|
|
|
- // Pop all the parent tables off the stack.
|
|
|
- int size = (int)scopePath.size();
|
|
|
- lua_pop(sc->_lua, size);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // TODO: Currently unsupported (we don't parse for this yet).
|
|
|
- // If the constant is global, add it to the global table.
|
|
|
- lua_pushboolean(sc->_lua, value);
|
|
|
- lua_pushvalue(sc->_lua, -1);
|
|
|
- lua_setglobal(sc->_lua, name.c_str());
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void ScriptUtil::registerConstantNumber(const std::string& name, double value, const std::vector<std::string>& scopePath)
|
|
|
-{
|
|
|
- ScriptController* sc = Game::getInstance()->getScriptController();
|
|
|
-
|
|
|
- // If the constant is within a scope, get the correct parent
|
|
|
- // table on the stack before setting its value.
|
|
|
- if (!scopePath.empty())
|
|
|
- {
|
|
|
- lua_getglobal(sc->_lua, scopePath[0].c_str());
|
|
|
- for (unsigned int i = 1; i < scopePath.size(); i++)
|
|
|
- {
|
|
|
- lua_pushstring(sc->_lua, scopePath[i].c_str());
|
|
|
- lua_gettable(sc->_lua, -2);
|
|
|
- }
|
|
|
-
|
|
|
- // Add the constant to the parent table.
|
|
|
- lua_pushnumber(sc->_lua, value);
|
|
|
- lua_setfield(sc->_lua, -2, name.c_str());
|
|
|
-
|
|
|
- // Pop all the parent tables off the stack.
|
|
|
- int size = (int)scopePath.size();
|
|
|
- lua_pop(sc->_lua, size);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // TODO: Currently unsupported (we don't parse for this yet).
|
|
|
- // If the constant is global, add it to the global table.
|
|
|
- lua_pushnumber(sc->_lua, value);
|
|
|
- lua_pushvalue(sc->_lua, -1);
|
|
|
- lua_setglobal(sc->_lua, name.c_str());
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void ScriptUtil::registerConstantString(const std::string& name, const std::string& value, const std::vector<std::string>& scopePath)
|
|
|
-{
|
|
|
- ScriptController* sc = Game::getInstance()->getScriptController();
|
|
|
-
|
|
|
- // If the constant is within a scope, get the correct parent
|
|
|
- // table on the stack before setting its value.
|
|
|
- if (!scopePath.empty())
|
|
|
- {
|
|
|
- lua_getglobal(sc->_lua, scopePath[0].c_str());
|
|
|
- for (unsigned int i = 1; i < scopePath.size(); i++)
|
|
|
- {
|
|
|
- lua_pushstring(sc->_lua, scopePath[i].c_str());
|
|
|
- lua_gettable(sc->_lua, -2);
|
|
|
- }
|
|
|
-
|
|
|
- // Add the constant to the parent table.
|
|
|
- lua_pushstring(sc->_lua, value.c_str());
|
|
|
- lua_setfield(sc->_lua, -2, name.c_str());
|
|
|
-
|
|
|
- // Pop all the parent tables off the stack.
|
|
|
- int size = (int)scopePath.size();
|
|
|
- lua_pop(sc->_lua, size);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // TODO: Currently unsupported (we don't parse for this yet).
|
|
|
- // If the constant is global, add it to the global table.
|
|
|
- lua_pushstring(sc->_lua, value.c_str());
|
|
|
- lua_pushvalue(sc->_lua, -1);
|
|
|
- lua_setglobal(sc->_lua, name.c_str());
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void ScriptUtil::registerEnumValue(int enumValue, const std::string& enumValueString, const std::vector<std::string>& scopePath)
|
|
|
-{
|
|
|
- ScriptController* sc = Game::getInstance()->getScriptController();
|
|
|
-
|
|
|
- // If the constant is within a scope, get the correct parent
|
|
|
- // table on the stack before setting its value.
|
|
|
- if (!scopePath.empty())
|
|
|
- {
|
|
|
- lua_getglobal(sc->_lua, scopePath[0].c_str());
|
|
|
- for (unsigned int i = 1; i < scopePath.size(); i++)
|
|
|
- {
|
|
|
- lua_pushstring(sc->_lua, scopePath[i].c_str());
|
|
|
- lua_gettable(sc->_lua, -2);
|
|
|
- }
|
|
|
-
|
|
|
- // Add the enum value to the parent table.
|
|
|
- lua_pushnumber(sc->_lua, enumValue);
|
|
|
- lua_setfield(sc->_lua, -2, enumValueString.c_str());
|
|
|
-
|
|
|
- // Pop all the parent tables off the stack.
|
|
|
- int size = (int)scopePath.size();
|
|
|
- lua_pop(sc->_lua, size);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // TODO: Currently unsupported (we don't parse for this yet).
|
|
|
- // If the constant is global, add it to the global table.
|
|
|
- lua_pushnumber(sc->_lua, enumValue);
|
|
|
- lua_pushvalue(sc->_lua, -1);
|
|
|
- lua_setglobal(sc->_lua, enumValueString.c_str());
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void ScriptUtil::registerClass(const char* name, const luaL_Reg* members, lua_CFunction newFunction,
|
|
|
- lua_CFunction deleteFunction, const luaL_Reg* statics, const std::vector<std::string>& scopePath)
|
|
|
-{
|
|
|
- ScriptController* sc = Game::getInstance()->getScriptController();
|
|
|
-
|
|
|
- // If the type is an inner type, get the correct parent
|
|
|
- // table on the stack before creating the table for the class.
|
|
|
- if (!scopePath.empty())
|
|
|
- {
|
|
|
- std::string tablename = name;
|
|
|
-
|
|
|
- // Strip off the scope path part of the name.
|
|
|
- lua_getglobal(sc->_lua, scopePath[0].c_str());
|
|
|
- std::size_t index = tablename.find(scopePath[0]);
|
|
|
- if (index != std::string::npos)
|
|
|
- tablename = tablename.substr(index + scopePath[0].size());
|
|
|
-
|
|
|
- for (unsigned int i = 1; i < scopePath.size(); i++)
|
|
|
- {
|
|
|
- lua_pushstring(sc->_lua, scopePath[i].c_str());
|
|
|
- lua_gettable(sc->_lua, -2);
|
|
|
-
|
|
|
- index = tablename.find(scopePath[i]);
|
|
|
- if (index != std::string::npos)
|
|
|
- tablename = tablename.substr(index + scopePath[i].size());
|
|
|
- }
|
|
|
-
|
|
|
- lua_pushstring(sc->_lua, tablename.c_str());
|
|
|
- lua_newtable(sc->_lua);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // If the type is not an inner type, set it as a global table.
|
|
|
- lua_newtable(sc->_lua);
|
|
|
- lua_pushvalue(sc->_lua, -1);
|
|
|
- lua_setglobal(sc->_lua, name);
|
|
|
- }
|
|
|
-
|
|
|
- // Create the metatable and populate it with the member functions.
|
|
|
- lua_pushliteral(sc->_lua, "__metatable");
|
|
|
- luaL_newmetatable(sc->_lua, name);
|
|
|
- if (members)
|
|
|
- luaL_setfuncs(sc->_lua, members, 0);
|
|
|
- lua_pushstring(sc->_lua, "__index");
|
|
|
- lua_pushvalue(sc->_lua, -2);
|
|
|
- lua_settable(sc->_lua, -3);
|
|
|
-
|
|
|
- // Add the delete function if it was specified.
|
|
|
- if (deleteFunction)
|
|
|
- {
|
|
|
- lua_pushstring(sc->_lua, "__gc");
|
|
|
- lua_pushcfunction(sc->_lua, deleteFunction);
|
|
|
- lua_settable(sc->_lua, -3);
|
|
|
- }
|
|
|
-
|
|
|
- // Set the metatable on the main table.
|
|
|
- lua_settable(sc->_lua, -3);
|
|
|
-
|
|
|
- // Populate the main table with the static functions.
|
|
|
- if (statics)
|
|
|
- luaL_setfuncs(sc->_lua, statics, 0);
|
|
|
-
|
|
|
- // Set the new function(s) for the class.
|
|
|
- if (newFunction)
|
|
|
- {
|
|
|
- lua_pushliteral(sc->_lua, "new");
|
|
|
- lua_pushcfunction(sc->_lua, newFunction);
|
|
|
- lua_settable(sc->_lua, -3);
|
|
|
- }
|
|
|
-
|
|
|
- // Set the table we just created within the correct parent table.
|
|
|
- if (!scopePath.empty())
|
|
|
- {
|
|
|
- lua_settable(sc->_lua, -3);
|
|
|
-
|
|
|
- // Pop all the parent tables off the stack.
|
|
|
- int size = (int)scopePath.size();
|
|
|
- lua_pop(sc->_lua, size);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // Pop the main table off the stack.
|
|
|
- lua_pop(sc->_lua, 1);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void ScriptUtil::registerFunction(const char* luaFunction, lua_CFunction cppFunction)
|
|
|
-{
|
|
|
- lua_pushcfunction(Game::getInstance()->getScriptController()->_lua, cppFunction);
|
|
|
- lua_setglobal(Game::getInstance()->getScriptController()->_lua, luaFunction);
|
|
|
-}
|
|
|
-
|
|
|
-void ScriptUtil::setGlobalHierarchyPair(const std::string& base, const std::string& derived)
|
|
|
-{
|
|
|
- Game::getInstance()->getScriptController()->_hierarchy[base].push_back(derived);
|
|
|
-}
|
|
|
-
|
|
|
-ScriptUtil::LuaArray<bool> ScriptUtil::getBoolPointer(int index)
|
|
|
-{
|
|
|
- GENERATE_LUA_GET_POINTER(bool, luaCheckBool);
|
|
|
-}
|
|
|
-
|
|
|
-ScriptUtil::LuaArray<short> ScriptUtil::getShortPointer(int index)
|
|
|
-{
|
|
|
- GENERATE_LUA_GET_POINTER(short, (short)luaL_checkint);
|
|
|
-}
|
|
|
-
|
|
|
-ScriptUtil::LuaArray<int> ScriptUtil::getIntPointer(int index)
|
|
|
-{
|
|
|
- GENERATE_LUA_GET_POINTER(int, (int)luaL_checkint);
|
|
|
-}
|
|
|
-
|
|
|
-ScriptUtil::LuaArray<long> ScriptUtil::getLongPointer(int index)
|
|
|
-{
|
|
|
- GENERATE_LUA_GET_POINTER(long, (long)luaL_checkint);
|
|
|
-}
|
|
|
-
|
|
|
-ScriptUtil::LuaArray<unsigned char> ScriptUtil::getUnsignedCharPointer(int index)
|
|
|
-{
|
|
|
- GENERATE_LUA_GET_POINTER(unsigned char, (unsigned char)luaL_checkunsigned);
|
|
|
-}
|
|
|
-
|
|
|
-ScriptUtil::LuaArray<unsigned short> ScriptUtil::getUnsignedShortPointer(int index)
|
|
|
-{
|
|
|
- GENERATE_LUA_GET_POINTER(unsigned short, (unsigned short)luaL_checkunsigned);
|
|
|
-}
|
|
|
-
|
|
|
-ScriptUtil::LuaArray<unsigned int> ScriptUtil::getUnsignedIntPointer(int index)
|
|
|
-{
|
|
|
- GENERATE_LUA_GET_POINTER(unsigned int, (unsigned int)luaL_checkunsigned);
|
|
|
-}
|
|
|
-
|
|
|
-ScriptUtil::LuaArray<unsigned long> ScriptUtil::getUnsignedLongPointer(int index)
|
|
|
-{
|
|
|
- GENERATE_LUA_GET_POINTER(unsigned long, (unsigned long)luaL_checkunsigned);
|
|
|
-}
|
|
|
-
|
|
|
-ScriptUtil::LuaArray<float> ScriptUtil::getFloatPointer(int index)
|
|
|
-{
|
|
|
- GENERATE_LUA_GET_POINTER(float, (float)luaL_checknumber);
|
|
|
-}
|
|
|
-
|
|
|
-ScriptUtil::LuaArray<double> ScriptUtil::getDoublePointer(int index)
|
|
|
-{
|
|
|
- GENERATE_LUA_GET_POINTER(double, (double)luaL_checknumber);
|
|
|
-}
|
|
|
-
|
|
|
-const char* ScriptUtil::getString(int index, bool isStdString)
|
|
|
+Script* ScriptController::loadScript(const char* path, Script::Scope scope, bool forceReload)
|
|
|
{
|
|
|
- if (lua_type(Game::getInstance()->getScriptController()->_lua, index) == LUA_TSTRING)
|
|
|
- return luaL_checkstring(Game::getInstance()->getScriptController()->_lua, index);
|
|
|
- else if (lua_type(Game::getInstance()->getScriptController()->_lua, index) == LUA_TNIL && !isStdString)
|
|
|
- return NULL;
|
|
|
- else
|
|
|
- {
|
|
|
- GP_ERROR("Invalid string parameter (index = %d).", index);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
-}
|
|
|
+ GP_ASSERT(path);
|
|
|
|
|
|
-bool ScriptUtil::luaCheckBool(lua_State* state, int n)
|
|
|
-{
|
|
|
- if (!lua_isboolean(state, n))
|
|
|
+ if (scope == Script::GLOBAL || scope == Script::PRIVATE_SHARED)
|
|
|
{
|
|
|
- const char* msg = lua_pushfstring(state, "%s expected, got %s", lua_typename(state, LUA_TBOOLEAN), luaL_typename(state, n));
|
|
|
- luaL_argerror(state, n, msg);
|
|
|
- return false;
|
|
|
+ // Check if a script with the same path is already loaded
|
|
|
}
|
|
|
- return (lua_toboolean(state, n) != 0);
|
|
|
-}
|
|
|
-
|
|
|
|
|
|
-bool ScriptController::loadScript(const char* path, bool forceReload)
|
|
|
-{
|
|
|
- GP_ASSERT(path);
|
|
|
std::set<std::string>::iterator iter = _loadedScripts.find(path);
|
|
|
if (iter == _loadedScripts.end() || forceReload)
|
|
|
{
|
|
|
@@ -581,46 +267,6 @@ void ScriptController::unloadScript(int id)
|
|
|
// Can we test this with manual GC and breaking on gameplay object constructors that were delcared local (even global??) to the script?
|
|
|
}
|
|
|
|
|
|
-std::string ScriptController::loadUrl(const char* url, int* scriptId)
|
|
|
-{
|
|
|
- GP_ASSERT(url);
|
|
|
-
|
|
|
- int sid = 0;
|
|
|
-
|
|
|
- bool isolated = url[0] == '+';
|
|
|
-
|
|
|
- std::string script;
|
|
|
- std::string func;
|
|
|
- parseUrl(isolated ? url + 1 : url, &script, &func);
|
|
|
-
|
|
|
- // Ensure the script is loaded
|
|
|
- if (script.length() > 0)
|
|
|
- {
|
|
|
- if (isolated)
|
|
|
- sid = Game::getInstance()->getScriptController()->loadScriptIsolated(script.c_str());
|
|
|
- else
|
|
|
- sid = Game::getInstance()->getScriptController()->loadScript(script.c_str()) ? 0 : -1;
|
|
|
- }
|
|
|
-
|
|
|
- if (scriptId)
|
|
|
- *scriptId = sid;
|
|
|
-
|
|
|
- // Return the function name.
|
|
|
- return func;
|
|
|
-}
|
|
|
-
|
|
|
-void ScriptController::parseUrl(const char* url, std::string* script, std::string* function)
|
|
|
-{
|
|
|
- std::string p1, p2;
|
|
|
- splitURL(url, &p1, &p2);
|
|
|
- if (function->length() == 0)
|
|
|
- {
|
|
|
- // The url doesn't reference a script, only a function
|
|
|
- *function = *script;
|
|
|
- *script = "";
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
bool ScriptController::getBool(const char* name, bool defaultValue, int script)
|
|
|
{
|
|
|
PUSH_NESTED_VARIABLE(name, defaultValue, script);
|
|
|
@@ -1159,309 +805,628 @@ void ScriptController::executeFunctionHelper(int resultCount, const char* func,
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- argumentCount++;
|
|
|
- luaL_checkstack(_lua, 1, "Too many arguments.");
|
|
|
- }
|
|
|
- }
|
|
|
+ argumentCount++;
|
|
|
+ luaL_checkstack(_lua, 1, "Too many arguments.");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ _envStack.push_back(script);
|
|
|
+
|
|
|
+ // Perform the function call.
|
|
|
+ if (lua_pcall(_lua, argumentCount, resultCount, 0) != 0)
|
|
|
+ GP_WARN("Failed to call function '%s' with error '%s'.", func, lua_tostring(_lua, -1));
|
|
|
+
|
|
|
+ _envStack.pop_back();
|
|
|
+}
|
|
|
+
|
|
|
+int ScriptController::convert(lua_State* state)
|
|
|
+{
|
|
|
+ // Get the number of parameters.
|
|
|
+ int paramCount = lua_gettop(state);
|
|
|
+ // Attempt to match the parameters to a valid binding.
|
|
|
+ switch (paramCount)
|
|
|
+ {
|
|
|
+ case 2:
|
|
|
+ {
|
|
|
+ if (lua_type(state, 1) == LUA_TUSERDATA && lua_type(state, 2) == LUA_TSTRING )
|
|
|
+ {
|
|
|
+ // Get parameter 2
|
|
|
+ const char* param2 = ScriptUtil::getString(2, false);
|
|
|
+ if (param2 != NULL)
|
|
|
+ {
|
|
|
+ luaL_getmetatable(state, param2);
|
|
|
+ lua_setmetatable(state, -3);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ lua_pushstring(state, "lua_convert - Failed to match the given parameters to a valid function signature.");
|
|
|
+ lua_error(state);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ {
|
|
|
+ lua_pushstring(state, "Invalid number of parameters (expected 2).");
|
|
|
+ lua_error(state);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+// Helper macros.
|
|
|
+#define SCRIPT_EXECUTE_FUNCTION_NO_PARAM(type, checkfunc) \
|
|
|
+ int top = lua_gettop(_lua); \
|
|
|
+ executeFunctionHelper(1, func, NULL, NULL); \
|
|
|
+ type value = (type)checkfunc(_lua, -1); \
|
|
|
+ lua_pop(_lua, -1); \
|
|
|
+ lua_settop(_lua, top); \
|
|
|
+ return value;
|
|
|
+
|
|
|
+#define SCRIPT_EXECUTE_FUNCTION_PARAM(type, checkfunc) \
|
|
|
+ int top = lua_gettop(_lua); \
|
|
|
+ va_list list; \
|
|
|
+ va_start(list, args); \
|
|
|
+ executeFunctionHelper(1, func, args, &list); \
|
|
|
+ type value = (type)checkfunc(_lua, -1); \
|
|
|
+ lua_pop(_lua, -1); \
|
|
|
+ va_end(list); \
|
|
|
+ lua_settop(_lua, top); \
|
|
|
+ return value;
|
|
|
+
|
|
|
+#define SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(type, checkfunc) \
|
|
|
+ int top = lua_gettop(_lua); \
|
|
|
+ executeFunctionHelper(1, func, args, list, script); \
|
|
|
+ type value = (type)checkfunc(_lua, -1); \
|
|
|
+ lua_pop(_lua, -1); \
|
|
|
+ lua_settop(_lua, top); \
|
|
|
+ return value;
|
|
|
+
|
|
|
+template<> void ScriptController::executeFunction<void>(const char* func)
|
|
|
+{
|
|
|
+ int top = lua_gettop(_lua);
|
|
|
+ executeFunctionHelper(0, func, NULL, NULL);
|
|
|
+ lua_settop(_lua, top);
|
|
|
+}
|
|
|
+
|
|
|
+template<> bool ScriptController::executeFunction<bool>(const char* func)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_NO_PARAM(bool, ScriptUtil::luaCheckBool);
|
|
|
+}
|
|
|
+
|
|
|
+template<> char ScriptController::executeFunction<char>(const char* func)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_NO_PARAM(char, luaL_checkint);
|
|
|
+}
|
|
|
+
|
|
|
+template<> short ScriptController::executeFunction<short>(const char* func)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_NO_PARAM(short, luaL_checkint);
|
|
|
+}
|
|
|
+
|
|
|
+template<> int ScriptController::executeFunction<int>(const char* func)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_NO_PARAM(int, luaL_checkint);
|
|
|
+}
|
|
|
+
|
|
|
+template<> long ScriptController::executeFunction<long>(const char* func)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_NO_PARAM(long, luaL_checklong);
|
|
|
+}
|
|
|
+
|
|
|
+template<> unsigned char ScriptController::executeFunction<unsigned char>(const char* func)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_NO_PARAM(unsigned char, luaL_checkunsigned);
|
|
|
+}
|
|
|
+
|
|
|
+template<> unsigned short ScriptController::executeFunction<unsigned short>(const char* func)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_NO_PARAM(unsigned short, luaL_checkunsigned);
|
|
|
+}
|
|
|
+
|
|
|
+template<> unsigned int ScriptController::executeFunction<unsigned int>(const char* func)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_NO_PARAM(unsigned int, luaL_checkunsigned);
|
|
|
+}
|
|
|
+
|
|
|
+template<> unsigned long ScriptController::executeFunction<unsigned long>(const char* func)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_NO_PARAM(unsigned long, luaL_checkunsigned);
|
|
|
+}
|
|
|
+
|
|
|
+template<> float ScriptController::executeFunction<float>(const char* func)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_NO_PARAM(float, luaL_checknumber);
|
|
|
+}
|
|
|
+
|
|
|
+template<> double ScriptController::executeFunction<double>(const char* func)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_NO_PARAM(double, luaL_checknumber);
|
|
|
+}
|
|
|
+
|
|
|
+template<> std::string ScriptController::executeFunction<std::string>(const char* func)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_NO_PARAM(std::string, luaL_checkstring);
|
|
|
+}
|
|
|
+
|
|
|
+/** Template specialization. */
|
|
|
+template<> void ScriptController::executeFunction<void>(const char* func, const char* args, ...)
|
|
|
+{
|
|
|
+ int top = lua_gettop(_lua);
|
|
|
+ va_list list;
|
|
|
+ va_start(list, args);
|
|
|
+ executeFunctionHelper(0, func, args, &list);
|
|
|
+ va_end(list);
|
|
|
+ lua_settop(_lua, top);
|
|
|
+}
|
|
|
+
|
|
|
+/** Template specialization. */
|
|
|
+template<> bool ScriptController::executeFunction<bool>(const char* func, const char* args, ...)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM(bool, ScriptUtil::luaCheckBool);
|
|
|
+}
|
|
|
+
|
|
|
+/** Template specialization. */
|
|
|
+template<> char ScriptController::executeFunction<char>(const char* func, const char* args, ...)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM(char, luaL_checkint);
|
|
|
+}
|
|
|
+
|
|
|
+/** Template specialization. */
|
|
|
+template<> short ScriptController::executeFunction<short>(const char* func, const char* args, ...)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM(short, luaL_checkint);
|
|
|
+}
|
|
|
+
|
|
|
+/** Template specialization. */
|
|
|
+template<> int ScriptController::executeFunction<int>(const char* func, const char* args, ...)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM(int, luaL_checkint);
|
|
|
+}
|
|
|
+
|
|
|
+/** Template specialization. */
|
|
|
+template<> long ScriptController::executeFunction<long>(const char* func, const char* args, ...)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM(long, luaL_checklong);
|
|
|
+}
|
|
|
+
|
|
|
+/** Template specialization. */
|
|
|
+template<> unsigned char ScriptController::executeFunction<unsigned char>(const char* func, const char* args, ...)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned char, luaL_checkunsigned);
|
|
|
+}
|
|
|
+
|
|
|
+/** Template specialization. */
|
|
|
+template<> unsigned short ScriptController::executeFunction<unsigned short>(const char* func, const char* args, ...)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned short, luaL_checkunsigned);
|
|
|
+}
|
|
|
+
|
|
|
+/** Template specialization. */
|
|
|
+template<> unsigned int ScriptController::executeFunction<unsigned int>(const char* func, const char* args, ...)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned int, luaL_checkunsigned);
|
|
|
+}
|
|
|
+
|
|
|
+/** Template specialization. */
|
|
|
+template<> unsigned long ScriptController::executeFunction<unsigned long>(const char* func, const char* args, ...)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned long, luaL_checkunsigned);
|
|
|
+}
|
|
|
+
|
|
|
+/** Template specialization. */
|
|
|
+template<> float ScriptController::executeFunction<float>(const char* func, const char* args, ...)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM(float, luaL_checknumber);
|
|
|
+}
|
|
|
|
|
|
- _envStack.push_back(script);
|
|
|
+/** Template specialization. */
|
|
|
+template<> double ScriptController::executeFunction<double>(const char* func, const char* args, ...)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM(double, luaL_checknumber);
|
|
|
+}
|
|
|
|
|
|
- // Perform the function call.
|
|
|
- if (lua_pcall(_lua, argumentCount, resultCount, 0) != 0)
|
|
|
- GP_WARN("Failed to call function '%s' with error '%s'.", func, lua_tostring(_lua, -1));
|
|
|
+/** Template specialization. */
|
|
|
+template<> std::string ScriptController::executeFunction<std::string>(const char* func, const char* args, ...)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM(std::string, luaL_checkstring);
|
|
|
+}
|
|
|
|
|
|
- _envStack.pop_back();
|
|
|
+/** Template specialization. */
|
|
|
+template<> void ScriptController::executeFunction<void>(const char* func, const char* args, va_list* list, int script)
|
|
|
+{
|
|
|
+ executeFunctionHelper(0, func, args, list, script);
|
|
|
}
|
|
|
|
|
|
-int ScriptController::convert(lua_State* state)
|
|
|
+/** Template specialization. */
|
|
|
+template<> bool ScriptController::executeFunction<bool>(const char* func, const char* args, va_list* list, int script)
|
|
|
{
|
|
|
- // Get the number of parameters.
|
|
|
- int paramCount = lua_gettop(state);
|
|
|
- // Attempt to match the parameters to a valid binding.
|
|
|
- switch (paramCount)
|
|
|
- {
|
|
|
- case 2:
|
|
|
- {
|
|
|
- if (lua_type(state, 1) == LUA_TUSERDATA && lua_type(state, 2) == LUA_TSTRING )
|
|
|
- {
|
|
|
- // Get parameter 2
|
|
|
- const char* param2 = ScriptUtil::getString(2, false);
|
|
|
- if (param2 != NULL)
|
|
|
- {
|
|
|
- luaL_getmetatable(state, param2);
|
|
|
- lua_setmetatable(state, -3);
|
|
|
- }
|
|
|
- return 0;
|
|
|
- }
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(bool, ScriptUtil::luaCheckBool);
|
|
|
+}
|
|
|
|
|
|
- lua_pushstring(state, "lua_convert - Failed to match the given parameters to a valid function signature.");
|
|
|
- lua_error(state);
|
|
|
- break;
|
|
|
- }
|
|
|
- default:
|
|
|
- {
|
|
|
- lua_pushstring(state, "Invalid number of parameters (expected 2).");
|
|
|
- lua_error(state);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- return 0;
|
|
|
+/** Template specialization. */
|
|
|
+template<> char ScriptController::executeFunction<char>(const char* func, const char* args, va_list* list, int script)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(char, luaL_checkint);
|
|
|
}
|
|
|
|
|
|
-// Helper macros.
|
|
|
-#define SCRIPT_EXECUTE_FUNCTION_NO_PARAM(type, checkfunc) \
|
|
|
- int top = lua_gettop(_lua); \
|
|
|
- executeFunctionHelper(1, func, NULL, NULL); \
|
|
|
- type value = (type)checkfunc(_lua, -1); \
|
|
|
- lua_pop(_lua, -1); \
|
|
|
- lua_settop(_lua, top); \
|
|
|
- return value;
|
|
|
+/** Template specialization. */
|
|
|
+template<> short ScriptController::executeFunction<short>(const char* func, const char* args, va_list* list, int script)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(short, luaL_checkint);
|
|
|
+}
|
|
|
|
|
|
-#define SCRIPT_EXECUTE_FUNCTION_PARAM(type, checkfunc) \
|
|
|
- int top = lua_gettop(_lua); \
|
|
|
- va_list list; \
|
|
|
- va_start(list, args); \
|
|
|
- executeFunctionHelper(1, func, args, &list); \
|
|
|
- type value = (type)checkfunc(_lua, -1); \
|
|
|
- lua_pop(_lua, -1); \
|
|
|
- va_end(list); \
|
|
|
- lua_settop(_lua, top); \
|
|
|
- return value;
|
|
|
+/** Template specialization. */
|
|
|
+template<> int ScriptController::executeFunction<int>(const char* func, const char* args, va_list* list, int script)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(int, luaL_checkint);
|
|
|
+}
|
|
|
|
|
|
-#define SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(type, checkfunc) \
|
|
|
- int top = lua_gettop(_lua); \
|
|
|
- executeFunctionHelper(1, func, args, list, script); \
|
|
|
- type value = (type)checkfunc(_lua, -1); \
|
|
|
- lua_pop(_lua, -1); \
|
|
|
- lua_settop(_lua, top); \
|
|
|
- return value;
|
|
|
+/** Template specialization. */
|
|
|
+template<> long ScriptController::executeFunction<long>(const char* func, const char* args, va_list* list, int script)
|
|
|
+{
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(long, luaL_checklong);
|
|
|
+}
|
|
|
|
|
|
-template<> void ScriptController::executeFunction<void>(const char* func)
|
|
|
+/** Template specialization. */
|
|
|
+template<> unsigned char ScriptController::executeFunction<unsigned char>(const char* func, const char* args, va_list* list, int script)
|
|
|
{
|
|
|
- int top = lua_gettop(_lua);
|
|
|
- executeFunctionHelper(0, func, NULL, NULL);
|
|
|
- lua_settop(_lua, top);
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(unsigned char, luaL_checkunsigned);
|
|
|
}
|
|
|
|
|
|
-template<> bool ScriptController::executeFunction<bool>(const char* func)
|
|
|
+/** Template specialization. */
|
|
|
+template<> unsigned short ScriptController::executeFunction<unsigned short>(const char* func, const char* args, va_list* list, int script)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_NO_PARAM(bool, ScriptUtil::luaCheckBool);
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(unsigned short, luaL_checkunsigned);
|
|
|
}
|
|
|
|
|
|
-template<> char ScriptController::executeFunction<char>(const char* func)
|
|
|
+/** Template specialization. */
|
|
|
+template<> unsigned int ScriptController::executeFunction<unsigned int>(const char* func, const char* args, va_list* list, int script)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_NO_PARAM(char, luaL_checkint);
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(unsigned int, luaL_checkunsigned);
|
|
|
}
|
|
|
|
|
|
-template<> short ScriptController::executeFunction<short>(const char* func)
|
|
|
+/** Template specialization. */
|
|
|
+template<> unsigned long ScriptController::executeFunction<unsigned long>(const char* func, const char* args, va_list* list, int script)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_NO_PARAM(short, luaL_checkint);
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(unsigned long, luaL_checkunsigned);
|
|
|
}
|
|
|
|
|
|
-template<> int ScriptController::executeFunction<int>(const char* func)
|
|
|
+/** Template specialization. */
|
|
|
+template<> float ScriptController::executeFunction<float>(const char* func, const char* args, va_list* list, int script)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_NO_PARAM(int, luaL_checkint);
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(float, luaL_checknumber);
|
|
|
}
|
|
|
|
|
|
-template<> long ScriptController::executeFunction<long>(const char* func)
|
|
|
+/** Template specialization. */
|
|
|
+template<> double ScriptController::executeFunction<double>(const char* func, const char* args, va_list* list, int script)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_NO_PARAM(long, luaL_checklong);
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(double, luaL_checknumber);
|
|
|
}
|
|
|
|
|
|
-template<> unsigned char ScriptController::executeFunction<unsigned char>(const char* func)
|
|
|
+/** Template specialization. */
|
|
|
+template<> std::string ScriptController::executeFunction<std::string>(const char* func, const char* args, va_list* list, int script)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_NO_PARAM(unsigned char, luaL_checkunsigned);
|
|
|
+ SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(std::string, luaL_checkstring);
|
|
|
}
|
|
|
|
|
|
-template<> unsigned short ScriptController::executeFunction<unsigned short>(const char* func)
|
|
|
+void ScriptUtil::registerLibrary(const char* name, const luaL_Reg* functions)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_NO_PARAM(unsigned short, luaL_checkunsigned);
|
|
|
+ ScriptController* sc = Game::getInstance()->getScriptController();
|
|
|
+ lua_newtable(sc->_lua);
|
|
|
+
|
|
|
+ // Go through the list of functions and add them to the table.
|
|
|
+ const luaL_Reg* iter = functions;
|
|
|
+ for (; iter && iter->name; iter++)
|
|
|
+ {
|
|
|
+ lua_pushcfunction(sc->_lua, iter->func);
|
|
|
+ lua_setfield(sc->_lua, -2, iter->name);
|
|
|
+ }
|
|
|
+
|
|
|
+ lua_setglobal(sc->_lua, name);
|
|
|
}
|
|
|
|
|
|
-template<> unsigned int ScriptController::executeFunction<unsigned int>(const char* func)
|
|
|
+void ScriptUtil::registerConstantBool(const std::string& name, bool value, const std::vector<std::string>& scopePath)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_NO_PARAM(unsigned int, luaL_checkunsigned);
|
|
|
+ ScriptController* sc = Game::getInstance()->getScriptController();
|
|
|
+
|
|
|
+ // If the constant is within a scope, get the correct parent
|
|
|
+ // table on the stack before setting its value.
|
|
|
+ if (!scopePath.empty())
|
|
|
+ {
|
|
|
+ lua_getglobal(sc->_lua, scopePath[0].c_str());
|
|
|
+ for (unsigned int i = 1; i < scopePath.size(); i++)
|
|
|
+ {
|
|
|
+ lua_pushstring(sc->_lua, scopePath[i].c_str());
|
|
|
+ lua_gettable(sc->_lua, -2);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Add the constant to the parent table.
|
|
|
+ lua_pushboolean(sc->_lua, value);
|
|
|
+ lua_setfield(sc->_lua, -2, name.c_str());
|
|
|
+
|
|
|
+ // Pop all the parent tables off the stack.
|
|
|
+ int size = (int)scopePath.size();
|
|
|
+ lua_pop(sc->_lua, size);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // TODO: Currently unsupported (we don't parse for this yet).
|
|
|
+ // If the constant is global, add it to the global table.
|
|
|
+ lua_pushboolean(sc->_lua, value);
|
|
|
+ lua_pushvalue(sc->_lua, -1);
|
|
|
+ lua_setglobal(sc->_lua, name.c_str());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-template<> unsigned long ScriptController::executeFunction<unsigned long>(const char* func)
|
|
|
+void ScriptUtil::registerConstantNumber(const std::string& name, double value, const std::vector<std::string>& scopePath)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_NO_PARAM(unsigned long, luaL_checkunsigned);
|
|
|
+ ScriptController* sc = Game::getInstance()->getScriptController();
|
|
|
+
|
|
|
+ // If the constant is within a scope, get the correct parent
|
|
|
+ // table on the stack before setting its value.
|
|
|
+ if (!scopePath.empty())
|
|
|
+ {
|
|
|
+ lua_getglobal(sc->_lua, scopePath[0].c_str());
|
|
|
+ for (unsigned int i = 1; i < scopePath.size(); i++)
|
|
|
+ {
|
|
|
+ lua_pushstring(sc->_lua, scopePath[i].c_str());
|
|
|
+ lua_gettable(sc->_lua, -2);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Add the constant to the parent table.
|
|
|
+ lua_pushnumber(sc->_lua, value);
|
|
|
+ lua_setfield(sc->_lua, -2, name.c_str());
|
|
|
+
|
|
|
+ // Pop all the parent tables off the stack.
|
|
|
+ int size = (int)scopePath.size();
|
|
|
+ lua_pop(sc->_lua, size);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // TODO: Currently unsupported (we don't parse for this yet).
|
|
|
+ // If the constant is global, add it to the global table.
|
|
|
+ lua_pushnumber(sc->_lua, value);
|
|
|
+ lua_pushvalue(sc->_lua, -1);
|
|
|
+ lua_setglobal(sc->_lua, name.c_str());
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void ScriptUtil::registerConstantString(const std::string& name, const std::string& value, const std::vector<std::string>& scopePath)
|
|
|
+{
|
|
|
+ ScriptController* sc = Game::getInstance()->getScriptController();
|
|
|
+
|
|
|
+ // If the constant is within a scope, get the correct parent
|
|
|
+ // table on the stack before setting its value.
|
|
|
+ if (!scopePath.empty())
|
|
|
+ {
|
|
|
+ lua_getglobal(sc->_lua, scopePath[0].c_str());
|
|
|
+ for (unsigned int i = 1; i < scopePath.size(); i++)
|
|
|
+ {
|
|
|
+ lua_pushstring(sc->_lua, scopePath[i].c_str());
|
|
|
+ lua_gettable(sc->_lua, -2);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Add the constant to the parent table.
|
|
|
+ lua_pushstring(sc->_lua, value.c_str());
|
|
|
+ lua_setfield(sc->_lua, -2, name.c_str());
|
|
|
+
|
|
|
+ // Pop all the parent tables off the stack.
|
|
|
+ int size = (int)scopePath.size();
|
|
|
+ lua_pop(sc->_lua, size);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // TODO: Currently unsupported (we don't parse for this yet).
|
|
|
+ // If the constant is global, add it to the global table.
|
|
|
+ lua_pushstring(sc->_lua, value.c_str());
|
|
|
+ lua_pushvalue(sc->_lua, -1);
|
|
|
+ lua_setglobal(sc->_lua, name.c_str());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-template<> float ScriptController::executeFunction<float>(const char* func)
|
|
|
+void ScriptUtil::registerEnumValue(int enumValue, const std::string& enumValueString, const std::vector<std::string>& scopePath)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_NO_PARAM(float, luaL_checknumber);
|
|
|
-}
|
|
|
+ ScriptController* sc = Game::getInstance()->getScriptController();
|
|
|
|
|
|
-template<> double ScriptController::executeFunction<double>(const char* func)
|
|
|
-{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_NO_PARAM(double, luaL_checknumber);
|
|
|
-}
|
|
|
+ // If the constant is within a scope, get the correct parent
|
|
|
+ // table on the stack before setting its value.
|
|
|
+ if (!scopePath.empty())
|
|
|
+ {
|
|
|
+ lua_getglobal(sc->_lua, scopePath[0].c_str());
|
|
|
+ for (unsigned int i = 1; i < scopePath.size(); i++)
|
|
|
+ {
|
|
|
+ lua_pushstring(sc->_lua, scopePath[i].c_str());
|
|
|
+ lua_gettable(sc->_lua, -2);
|
|
|
+ }
|
|
|
|
|
|
-template<> std::string ScriptController::executeFunction<std::string>(const char* func)
|
|
|
-{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_NO_PARAM(std::string, luaL_checkstring);
|
|
|
-}
|
|
|
+ // Add the enum value to the parent table.
|
|
|
+ lua_pushnumber(sc->_lua, enumValue);
|
|
|
+ lua_setfield(sc->_lua, -2, enumValueString.c_str());
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> void ScriptController::executeFunction<void>(const char* func, const char* args, ...)
|
|
|
-{
|
|
|
- int top = lua_gettop(_lua);
|
|
|
- va_list list;
|
|
|
- va_start(list, args);
|
|
|
- executeFunctionHelper(0, func, args, &list);
|
|
|
- va_end(list);
|
|
|
- lua_settop(_lua, top);
|
|
|
+ // Pop all the parent tables off the stack.
|
|
|
+ int size = (int)scopePath.size();
|
|
|
+ lua_pop(sc->_lua, size);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // TODO: Currently unsupported (we don't parse for this yet).
|
|
|
+ // If the constant is global, add it to the global table.
|
|
|
+ lua_pushnumber(sc->_lua, enumValue);
|
|
|
+ lua_pushvalue(sc->_lua, -1);
|
|
|
+ lua_setglobal(sc->_lua, enumValueString.c_str());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> bool ScriptController::executeFunction<bool>(const char* func, const char* args, ...)
|
|
|
+void ScriptUtil::registerClass(const char* name, const luaL_Reg* members, lua_CFunction newFunction,
|
|
|
+ lua_CFunction deleteFunction, const luaL_Reg* statics, const std::vector<std::string>& scopePath)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM(bool, ScriptUtil::luaCheckBool);
|
|
|
-}
|
|
|
+ ScriptController* sc = Game::getInstance()->getScriptController();
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> char ScriptController::executeFunction<char>(const char* func, const char* args, ...)
|
|
|
-{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM(char, luaL_checkint);
|
|
|
-}
|
|
|
+ // If the type is an inner type, get the correct parent
|
|
|
+ // table on the stack before creating the table for the class.
|
|
|
+ if (!scopePath.empty())
|
|
|
+ {
|
|
|
+ std::string tablename = name;
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> short ScriptController::executeFunction<short>(const char* func, const char* args, ...)
|
|
|
-{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM(short, luaL_checkint);
|
|
|
-}
|
|
|
+ // Strip off the scope path part of the name.
|
|
|
+ lua_getglobal(sc->_lua, scopePath[0].c_str());
|
|
|
+ std::size_t index = tablename.find(scopePath[0]);
|
|
|
+ if (index != std::string::npos)
|
|
|
+ tablename = tablename.substr(index + scopePath[0].size());
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> int ScriptController::executeFunction<int>(const char* func, const char* args, ...)
|
|
|
-{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM(int, luaL_checkint);
|
|
|
-}
|
|
|
+ for (unsigned int i = 1; i < scopePath.size(); i++)
|
|
|
+ {
|
|
|
+ lua_pushstring(sc->_lua, scopePath[i].c_str());
|
|
|
+ lua_gettable(sc->_lua, -2);
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> long ScriptController::executeFunction<long>(const char* func, const char* args, ...)
|
|
|
-{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM(long, luaL_checklong);
|
|
|
-}
|
|
|
+ index = tablename.find(scopePath[i]);
|
|
|
+ if (index != std::string::npos)
|
|
|
+ tablename = tablename.substr(index + scopePath[i].size());
|
|
|
+ }
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> unsigned char ScriptController::executeFunction<unsigned char>(const char* func, const char* args, ...)
|
|
|
-{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned char, luaL_checkunsigned);
|
|
|
-}
|
|
|
+ lua_pushstring(sc->_lua, tablename.c_str());
|
|
|
+ lua_newtable(sc->_lua);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // If the type is not an inner type, set it as a global table.
|
|
|
+ lua_newtable(sc->_lua);
|
|
|
+ lua_pushvalue(sc->_lua, -1);
|
|
|
+ lua_setglobal(sc->_lua, name);
|
|
|
+ }
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> unsigned short ScriptController::executeFunction<unsigned short>(const char* func, const char* args, ...)
|
|
|
-{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned short, luaL_checkunsigned);
|
|
|
-}
|
|
|
+ // Create the metatable and populate it with the member functions.
|
|
|
+ lua_pushliteral(sc->_lua, "__metatable");
|
|
|
+ luaL_newmetatable(sc->_lua, name);
|
|
|
+ if (members)
|
|
|
+ luaL_setfuncs(sc->_lua, members, 0);
|
|
|
+ lua_pushstring(sc->_lua, "__index");
|
|
|
+ lua_pushvalue(sc->_lua, -2);
|
|
|
+ lua_settable(sc->_lua, -3);
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> unsigned int ScriptController::executeFunction<unsigned int>(const char* func, const char* args, ...)
|
|
|
-{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned int, luaL_checkunsigned);
|
|
|
-}
|
|
|
+ // Add the delete function if it was specified.
|
|
|
+ if (deleteFunction)
|
|
|
+ {
|
|
|
+ lua_pushstring(sc->_lua, "__gc");
|
|
|
+ lua_pushcfunction(sc->_lua, deleteFunction);
|
|
|
+ lua_settable(sc->_lua, -3);
|
|
|
+ }
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> unsigned long ScriptController::executeFunction<unsigned long>(const char* func, const char* args, ...)
|
|
|
-{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM(unsigned long, luaL_checkunsigned);
|
|
|
-}
|
|
|
+ // Set the metatable on the main table.
|
|
|
+ lua_settable(sc->_lua, -3);
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> float ScriptController::executeFunction<float>(const char* func, const char* args, ...)
|
|
|
-{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM(float, luaL_checknumber);
|
|
|
-}
|
|
|
+ // Populate the main table with the static functions.
|
|
|
+ if (statics)
|
|
|
+ luaL_setfuncs(sc->_lua, statics, 0);
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> double ScriptController::executeFunction<double>(const char* func, const char* args, ...)
|
|
|
-{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM(double, luaL_checknumber);
|
|
|
+ // Set the new function(s) for the class.
|
|
|
+ if (newFunction)
|
|
|
+ {
|
|
|
+ lua_pushliteral(sc->_lua, "new");
|
|
|
+ lua_pushcfunction(sc->_lua, newFunction);
|
|
|
+ lua_settable(sc->_lua, -3);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Set the table we just created within the correct parent table.
|
|
|
+ if (!scopePath.empty())
|
|
|
+ {
|
|
|
+ lua_settable(sc->_lua, -3);
|
|
|
+
|
|
|
+ // Pop all the parent tables off the stack.
|
|
|
+ int size = (int)scopePath.size();
|
|
|
+ lua_pop(sc->_lua, size);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Pop the main table off the stack.
|
|
|
+ lua_pop(sc->_lua, 1);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> std::string ScriptController::executeFunction<std::string>(const char* func, const char* args, ...)
|
|
|
+void ScriptUtil::registerFunction(const char* luaFunction, lua_CFunction cppFunction)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM(std::string, luaL_checkstring);
|
|
|
+ lua_pushcfunction(Game::getInstance()->getScriptController()->_lua, cppFunction);
|
|
|
+ lua_setglobal(Game::getInstance()->getScriptController()->_lua, luaFunction);
|
|
|
}
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> void ScriptController::executeFunction<void>(const char* func, const char* args, va_list* list, int script)
|
|
|
+void ScriptUtil::setGlobalHierarchyPair(const std::string& base, const std::string& derived)
|
|
|
{
|
|
|
- executeFunctionHelper(0, func, args, list, script);
|
|
|
+ Game::getInstance()->getScriptController()->_hierarchy[base].push_back(derived);
|
|
|
}
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> bool ScriptController::executeFunction<bool>(const char* func, const char* args, va_list* list, int script)
|
|
|
+ScriptUtil::LuaArray<bool> ScriptUtil::getBoolPointer(int index)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(bool, ScriptUtil::luaCheckBool);
|
|
|
+ GENERATE_LUA_GET_POINTER(bool, luaCheckBool);
|
|
|
}
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> char ScriptController::executeFunction<char>(const char* func, const char* args, va_list* list, int script)
|
|
|
+ScriptUtil::LuaArray<short> ScriptUtil::getShortPointer(int index)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(char, luaL_checkint);
|
|
|
+ GENERATE_LUA_GET_POINTER(short, (short)luaL_checkint);
|
|
|
}
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> short ScriptController::executeFunction<short>(const char* func, const char* args, va_list* list, int script)
|
|
|
+ScriptUtil::LuaArray<int> ScriptUtil::getIntPointer(int index)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(short, luaL_checkint);
|
|
|
+ GENERATE_LUA_GET_POINTER(int, (int)luaL_checkint);
|
|
|
}
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> int ScriptController::executeFunction<int>(const char* func, const char* args, va_list* list, int script)
|
|
|
+ScriptUtil::LuaArray<long> ScriptUtil::getLongPointer(int index)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(int, luaL_checkint);
|
|
|
+ GENERATE_LUA_GET_POINTER(long, (long)luaL_checkint);
|
|
|
}
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> long ScriptController::executeFunction<long>(const char* func, const char* args, va_list* list, int script)
|
|
|
+ScriptUtil::LuaArray<unsigned char> ScriptUtil::getUnsignedCharPointer(int index)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(long, luaL_checklong);
|
|
|
+ GENERATE_LUA_GET_POINTER(unsigned char, (unsigned char)luaL_checkunsigned);
|
|
|
}
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> unsigned char ScriptController::executeFunction<unsigned char>(const char* func, const char* args, va_list* list, int script)
|
|
|
+ScriptUtil::LuaArray<unsigned short> ScriptUtil::getUnsignedShortPointer(int index)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(unsigned char, luaL_checkunsigned);
|
|
|
+ GENERATE_LUA_GET_POINTER(unsigned short, (unsigned short)luaL_checkunsigned);
|
|
|
}
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> unsigned short ScriptController::executeFunction<unsigned short>(const char* func, const char* args, va_list* list, int script)
|
|
|
+ScriptUtil::LuaArray<unsigned int> ScriptUtil::getUnsignedIntPointer(int index)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(unsigned short, luaL_checkunsigned);
|
|
|
+ GENERATE_LUA_GET_POINTER(unsigned int, (unsigned int)luaL_checkunsigned);
|
|
|
}
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> unsigned int ScriptController::executeFunction<unsigned int>(const char* func, const char* args, va_list* list, int script)
|
|
|
+ScriptUtil::LuaArray<unsigned long> ScriptUtil::getUnsignedLongPointer(int index)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(unsigned int, luaL_checkunsigned);
|
|
|
+ GENERATE_LUA_GET_POINTER(unsigned long, (unsigned long)luaL_checkunsigned);
|
|
|
}
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> unsigned long ScriptController::executeFunction<unsigned long>(const char* func, const char* args, va_list* list, int script)
|
|
|
+ScriptUtil::LuaArray<float> ScriptUtil::getFloatPointer(int index)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(unsigned long, luaL_checkunsigned);
|
|
|
+ GENERATE_LUA_GET_POINTER(float, (float)luaL_checknumber);
|
|
|
}
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> float ScriptController::executeFunction<float>(const char* func, const char* args, va_list* list, int script)
|
|
|
+ScriptUtil::LuaArray<double> ScriptUtil::getDoublePointer(int index)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(float, luaL_checknumber);
|
|
|
+ GENERATE_LUA_GET_POINTER(double, (double)luaL_checknumber);
|
|
|
}
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> double ScriptController::executeFunction<double>(const char* func, const char* args, va_list* list, int script)
|
|
|
+const char* ScriptUtil::getString(int index, bool isStdString)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(double, luaL_checknumber);
|
|
|
+ if (lua_type(Game::getInstance()->getScriptController()->_lua, index) == LUA_TSTRING)
|
|
|
+ return luaL_checkstring(Game::getInstance()->getScriptController()->_lua, index);
|
|
|
+ else if (lua_type(Game::getInstance()->getScriptController()->_lua, index) == LUA_TNIL && !isStdString)
|
|
|
+ return NULL;
|
|
|
+ else
|
|
|
+ {
|
|
|
+ GP_ERROR("Invalid string parameter (index = %d).", index);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-/** Template specialization. */
|
|
|
-template<> std::string ScriptController::executeFunction<std::string>(const char* func, const char* args, va_list* list, int script)
|
|
|
+bool ScriptUtil::luaCheckBool(lua_State* state, int n)
|
|
|
{
|
|
|
- SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(std::string, luaL_checkstring);
|
|
|
+ if (!lua_isboolean(state, n))
|
|
|
+ {
|
|
|
+ const char* msg = lua_pushfstring(state, "%s expected, got %s", lua_typename(state, LUA_TBOOLEAN), luaL_typename(state, n));
|
|
|
+ luaL_argerror(state, n, msg);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return (lua_toboolean(state, n) != 0);
|
|
|
}
|
|
|
|
|
|
}
|