Beispiel #1
0
void LuaUtils::ParseCommandOptions(lua_State* L, const char* caller,
                                   int index, Command& cmd)
{
	if (lua_isnumber(L, index)) {
		cmd.options = (unsigned char)lua_tonumber(L, index);
	}
	else if (lua_istable(L, index)) {
		const int optionTable = index;
		for (lua_pushnil(L); lua_next(L, optionTable) != 0; lua_pop(L, 1)) {
			if (lua_israwnumber(L, -2)) { // avoid 'n'
				if (!lua_isstring(L, -1)) {
					luaL_error(L, "%s(): bad option table entry", caller);
				}
				const string value = lua_tostring(L, -1);
				if (value == "right") {
					cmd.options |= RIGHT_MOUSE_KEY;
				} else if (value == "alt") {
					cmd.options |= ALT_KEY;
				} else if (value == "ctrl") {
					cmd.options |= CONTROL_KEY;
				} else if (value == "shift") {
					cmd.options |= SHIFT_KEY;
				} else if (value == "meta") {
					cmd.options |= META_KEY;
				}
			}
		}
	}
	else {
		luaL_error(L, "%s(): bad options", caller);
	}
}
Beispiel #2
0
Command LuaUtils::ParseCommand(lua_State* L, const char* caller, int idIndex)
{
	// cmdID
	if (!lua_isnumber(L, idIndex)) {
		luaL_error(L, "%s(): bad command ID", caller);
	}
	const int id = lua_toint(L, idIndex);
	Command cmd(id);

	// params
	const int paramTable = (idIndex + 1);
	if (!lua_istable(L, paramTable)) {
		luaL_error(L, "%s(): bad param table", caller);
	}
	for (lua_pushnil(L); lua_next(L, paramTable) != 0; lua_pop(L, 1)) {
		if (lua_israwnumber(L, -2)) { // avoid 'n'
			if (!lua_isnumber(L, -1)) {
				luaL_error(L, "%s(): bad param table entry", caller);
			}
			const float value = lua_tofloat(L, -1);
			cmd.PushParam(value);
		}
	}

	// options
	ParseCommandOptions(L, caller, (idIndex + 2), cmd);

	// XXX should do some sanity checking?

	return cmd;
}
Beispiel #3
0
void LuaUtils::ParseCommandTable(lua_State* L, const char* caller,
                                 int table, Command& cmd)
{
    // cmdID
    lua_rawgeti(L, table, 1);
    if (!lua_isnumber(L, -1)) {
        luaL_error(L, "%s(): bad command ID", caller);
    }
    cmd.id = lua_toint(L, -1);
    lua_pop(L, 1);

    // params
    lua_rawgeti(L, table, 2);
    if (!lua_istable(L, -1)) {
        luaL_error(L, "%s(): bad param table", caller);
    }
    const int paramTable = lua_gettop(L);
    for (lua_pushnil(L); lua_next(L, paramTable) != 0; lua_pop(L, 1)) {
        if (lua_israwnumber(L, -2)) { // avoid 'n'
            if (!lua_isnumber(L, -1)) {
                luaL_error(L, "%s(): bad param table entry", caller);
            }
            const float value = lua_tofloat(L, -1);
            cmd.params.push_back(value);
        }
    }
    lua_pop(L, 1);

    // options
    lua_rawgeti(L, table, 3);
    ParseCommandOptions(L, caller, lua_gettop(L), cmd);
    lua_pop(L, 1);

    // NOTE: should do some sanity checking?
}
Beispiel #4
0
int LuaUtils::Echo(lua_State* L)
{
    // copied from lua/src/lib/lbaselib.c
    string msg = "";
    const int args = lua_gettop(L); // number of arguments

    lua_getglobal(L, "tostring");

    for (int i = 1; i <= args; i++) {
        const char *s;
        lua_pushvalue(L, -1);     // function to be called
        lua_pushvalue(L, i);      // value to print
        lua_call(L, 1, 1);
        s = lua_tostring(L, -1);  // get result
        if (s == NULL) {
            return luaL_error(L, "`tostring' must return a string to `print'");
        }
        if (i > 1) {
            msg += ", ";
        }
        msg += s;
        lua_pop(L, 1);            // pop result
    }
    logOutput.Print(msg);

    if ((args != 1) || !lua_istable(L, 1)) {
        return 0;
    }

    // print solo tables (array style)
    msg = "TABLE: ";
    bool first = true;
    const int table = 1;
    for (lua_pushnil(L); lua_next(L, table) != 0; lua_pop(L, 1)) {
        if (lua_israwnumber(L, -2)) {  // only numeric keys
            const char *s;
            lua_pushvalue(L, -3);     // function to be called
            lua_pushvalue(L, -2	);    // value to print
            lua_call(L, 1, 1);
            s = lua_tostring(L, -1);  // get result
            if (s == NULL) {
                return luaL_error(L, "`tostring' must return a string to `print'");
            }
            if (!first) {
                msg += ", ";
            }
            msg += s;
            first = false;
            lua_pop(L, 1);            // pop result
        }
    }
    logOutput.Print(msg);

    return 0;
}
Beispiel #5
0
bool LuaTable::GetKeys(vector<int>& data) const
{
	if (!PushTable()) {
		return false;
	}
	const int table = lua_gettop(L);
	for (lua_pushnil(L); lua_next(L, table) != 0; lua_pop(L, 1)) {
		if (lua_israwnumber(L, -2)) {
			const int value = lua_toint(L, -2);
			data.push_back(value);
		}
	}
	std::sort(data.begin(), data.end());
	return true;
}
Beispiel #6
0
bool LuaTable::GetMap(map<int, string>& data) const
{
	if (!PushTable()) {
		return false;
	}
	const int table = lua_gettop(L);
	for (lua_pushnil(L); lua_next(L, table) != 0; lua_pop(L, 1)) {
		if (lua_israwnumber(L, -2) && lua_isstring(L, -1)) {
			const int    key   = lua_toint(L, -2);
			const string value = lua_tostring(L, -1);
			data[key] = value;
		}
	}
	return true;
}
Beispiel #7
0
static std::string getprintf_msg(lua_State* L, int index)
{
	// copied from lua/src/lib/lbaselib.c
	string msg = "";
	const int args = lua_gettop(L); // number of arguments

	lua_getglobal(L, "tostring");

	for (int i = index; i <= args; i++) {
		const char* s;
		lua_pushvalue(L, -1);     // function to be called
		lua_pushvalue(L, i);      // value to print
		lua_call(L, 1, 1);
		s = lua_tostring(L, -1);  // get result
		if (i > index) {
			msg += ", ";
		}
		msg += s;
		lua_pop(L, 1);            // pop result
	}

	if ((args != index) || !lua_istable(L, index)) {
		return msg;
	}

	// print solo tables (array style)
	msg = "TABLE: ";
	bool first = true;
	for (lua_pushnil(L); lua_next(L, index) != 0; lua_pop(L, 1)) {
		if (lua_israwnumber(L, -2)) {  // only numeric keys
			const char *s;
			lua_pushvalue(L, -3);    // function to be called
			lua_pushvalue(L, -2);    // value to print
			lua_call(L, 1, 1);
			s = lua_tostring(L, -1);  // get result
			if (!first) {
				msg += ", ";
			}
			msg += s;
			first = false;
			lua_pop(L, 1);            // pop result
		}
	}

	return msg;
}
Beispiel #8
0
/*-
	Logs a msg to the logfile / console
	@param loglevel loglevel that will be used for the message
	@param msg string to be logged
	@fn Spring.Log(string logsection, int loglevel, ...)
	@fn Spring.Log(string logsection, string loglevel, ...)
*/
int LuaUtils::Log(lua_State* L)
{
	const int args = lua_gettop(L); // number of arguments
	if (args < 2)
		return luaL_error(L, "Incorrect arguments to Spring.Log(logsection, loglevel, ...)");
	if (args < 3)
		return 0;

	const std::string section = luaL_checkstring(L, 1);

	int loglevel;
	if (lua_israwnumber(L, 2)) {
		loglevel = lua_tonumber(L, 2);
	}
	else if (lua_israwstring(L, 2)) {
		std::string loglvlstr = lua_tostring(L, 2);
		StringToLowerInPlace(loglvlstr);
		if (loglvlstr == "debug") {
			loglevel = LOG_LEVEL_DEBUG;
		}
		else if (loglvlstr == "info") {
			loglevel = LOG_LEVEL_INFO;
		}
		else if (loglvlstr == "warning") {
			loglevel = LOG_LEVEL_WARNING;
		}
		else if (loglvlstr == "error") {
			loglevel = LOG_LEVEL_ERROR;
		}
		else if (loglvlstr == "fatal") {
			loglevel = LOG_LEVEL_FATAL;
		}
		else {
			return luaL_error(L, "Incorrect arguments to Spring.Log(logsection, loglevel, ...)");
		}
	}
	else {
		return luaL_error(L, "Incorrect arguments to Spring.Log(logsection, loglevel, ...)");
	}

	const std::string msg = getprintf_msg(L, 3);
	LOG_SI(section.c_str(), loglevel, "%s", msg.c_str());
	return 0;
}
Beispiel #9
0
int LuaUtils::ParseFacing(lua_State* L, const char* caller, int index)
{
	if (lua_israwnumber(L, index)) {
		return std::max(0, std::min(3, lua_toint(L, index)));
	}
	else if (lua_israwstring(L, index)) {
		const string dir = StringToLower(lua_tostring(L, index));
		if (dir == "s") { return 0; }
		if (dir == "e") { return 1; }
		if (dir == "n") { return 2; }
		if (dir == "w") { return 3; }
		if (dir == "south") { return 0; }
		if (dir == "east")  { return 1; }
		if (dir == "north") { return 2; }
		if (dir == "west")  { return 3; }
		luaL_error(L, "%s(): bad facing string", caller);
	}
	luaL_error(L, "%s(): bad facing parameter", caller);
	return 0;
}
void CLuaRules::CreateRulesParams(lua_State* L, const char* caller, int offset,
		                              vector<float>& params,
		                              map<string, int>& paramsMap)
{
	const int table = offset + 1;
	if (!lua_istable(L, table)) {
		luaL_error(L, "Incorrect arguments to %s()", caller);
	}

	params.clear();
	paramsMap.clear();

	for (int i = 1; /* no test */; i++) {
		lua_rawgeti(L, table, i);
		if (lua_isnil(L, -1)) {
			lua_pop(L, 1);
			return;
		}
		else if (lua_israwnumber(L, -1)) {
			const float value = lua_tofloat(L, -1);
			params.push_back(value);
		}
		else if (lua_istable(L, -1)) {
			lua_pushnil(L);
			if (lua_next(L, -2)) {
				if (lua_israwstring(L, -2) && lua_isnumber(L, -1)) {
					const string name = lua_tostring(L, -2);
					const float value = lua_tonumber(L, -1);
					paramsMap[name] = params.size();
					params.push_back(value);
				}
				lua_pop(L, 2);
			}
		}
		lua_pop(L, 1);
	}

	return;
}
void CLuaRules::SetRulesParam(lua_State* L, const char* caller, int offset,
                              vector<float>& params,
		                          map<string, int>& paramsMap)
{
	const int index = offset + 1;
	const int valIndex = offset + 2;
	int pIndex = -1;

	if (lua_israwnumber(L, index)) {
		pIndex = lua_toint(L, index) - 1;
	}
	else if (lua_israwstring(L, index)) {
		const string pName = lua_tostring(L, index);
		map<string, int>::const_iterator it = paramsMap.find(pName);
		if (it != paramsMap.end()) {
			pIndex = it->second;
		}
		else {
			// create a new parameter
			pIndex = params.size();
			paramsMap[pName] = params.size();
			params.push_back(0.0f); // dummy value
		}
	}
	else {
		luaL_error(L, "Incorrect arguments to %s()", caller);
	}

	if ((pIndex < 0) || (pIndex >= (int)params.size())) {
		return;
	}

	if (!lua_isnumber(L, valIndex)) {
		luaL_error(L, "Incorrect arguments to %s()", caller);
	}
	params[pIndex] = lua_tofloat(L, valIndex);
	return;
}
Beispiel #12
0
void LuaMaterial::Parse(
	lua_State* L,
	const int tableIdx,
	std::function<void(lua_State*, int, LuaMatShader&)> ParseShader,
	std::function<void(lua_State*, int, LuaMatTexture&)> ParseTexture,
	std::function<GLuint(lua_State*, int)> ParseDisplayList
) {
	for (lua_pushnil(L); lua_next(L, tableIdx) != 0; lua_pop(L, 1)) {
		if (!lua_israwstring(L, -2))
			continue;

		const std::string key = StringToLower(lua_tostring(L, -2));

		// uniforms
		if (key.find("uniforms") != std::string::npos) {
			if (!lua_istable(L, -1))
				continue;

			if (key.find("standard") != std::string::npos) {
				uniforms[LuaMatShader::LUASHADER_PASS_FWD].Parse(L, lua_gettop(L));
				continue;
			}
			if (key.find("deferred") != std::string::npos) {
				uniforms[LuaMatShader::LUASHADER_PASS_DFR].Parse(L, lua_gettop(L));
				continue;
			}

			// fallback
			uniforms[LuaMatShader::LUASHADER_PASS_FWD].Parse(L, lua_gettop(L));
			continue;
		}

		// shaders
		if (key.find("shader") != std::string::npos) {
			if (key.find("standard") != std::string::npos) {
				ParseShader(L, -1, shaders[LuaMatShader::LUASHADER_PASS_FWD]);
				continue;
			}
			if (key.find("deferred") != std::string::npos) {
				ParseShader(L, -1, shaders[LuaMatShader::LUASHADER_PASS_DFR]);
				continue;
			}

			// fallback
			ParseShader(L, -1, shaders[LuaMatShader::LUASHADER_PASS_FWD]);
			continue;
		}

		// textures
		if (key.substr(0, 7) == "texunit") {
			if (key.size() < 8)
				continue;

			if (key[7] == 's') {
				// "texunits" = {[0] = string|table, ...}
				if (!lua_istable(L, -1))
					continue;

				const int texTable = lua_gettop(L);

				for (lua_pushnil(L); lua_next(L, texTable) != 0; lua_pop(L, 1)) {
					if (!lua_israwnumber(L, -2))
						continue;

					const unsigned int texUnit = lua_toint(L, -2);

					if (texUnit >= LuaMatTexture::maxTexUnits)
						continue;

					ParseTexture(L, -1, textures[texUnit]);
				}
			} else {
				// "texunitX" = string|table
				const unsigned int texUnit = atoi(key.c_str() + 7);

				if (texUnit >= LuaMatTexture::maxTexUnits)
					continue;

				ParseTexture(L, -1, textures[texUnit]);
			}

			continue;
		}

		// dlists
		if (key == "prelist") {
			preList = ParseDisplayList(L, -1);
			continue;
		}
		if (key == "postlist") {
			postList = ParseDisplayList(L, -1);
			continue;
		}

		// misc
		if (key == "order") {
			order = luaL_checkint(L, -1);
			continue;
		}
		if (key == "culling") {
			if (lua_isnumber(L, -1))
				cullingMode = (GLenum)lua_tonumber(L, -1);

			continue;
		}

		if (key == "usecamera") {
			useCamera = lua_isboolean(L, -1) && lua_toboolean(L, -1);
			continue;
		}

		LOG_L(L_WARNING, "LuaMaterial: incorrect key \"%s\"", key.c_str());
	}
}