#include "XLua.h" #include "XDefine.h" #include XLua::XLua() : mLuaState(nullptr) { register_handlers(); register_handlers2(); } XLua::~XLua() { } bool XLua::init() { if (nullptr != mLuaState) return false; mLuaState = luaL_newstate(); _CHECK_VALUE_RETURN_BOOL_(nullptr != mLuaState); luaL_openlibs(mLuaState); return true; } void XLua::release() { close(); delete this; } bool XLua::loadFile(const char* file, bool isRun /* = true */) { _CHECK_VALUE_RETURN_BOOL_(nullptr != file); _CHECK_VALUE_RETURN_BOOL_(nullptr != mLuaState); if (isRun) return 0 == luaL_dofile(mLuaState, file); else return 0 == luaL_loadfile(mLuaState, file); } bool XLua::runFile() { return 0 == lua_pcall(mLuaState, 0, LUA_MULTRET, 0); } bool XLua::getLuaVariableChar(const char* name, char& outValue) { assert(nullptr != mLuaState); _CHECK_VALUE_RETURN_BOOL_(nullptr != name); if (0 == lua_getglobal(mLuaState, name)) return false; const char* value = lua_tostring(mLuaState, -1); assert(strlen(value) > 0); outValue = value[0]; lua_pop(mLuaState, -1); return true; } bool XLua::getLuaVariableBool(const char* name, bool& outValue) { assert(nullptr != mLuaState); _CHECK_VALUE_RETURN_BOOL_(nullptr != name); if (0 == lua_getglobal(mLuaState, name)) return false; outValue = 0 == lua_toboolean(mLuaState, -1) ? false : true; lua_pop(mLuaState, -1); return true; } bool XLua::getLuaVariableShort(const char* name, short& outValue) { assert(nullptr != mLuaState); _CHECK_VALUE_RETURN_BOOL_(nullptr != name); if (0 == lua_getglobal(mLuaState, name)) return false; outValue = (short)lua_tointeger(mLuaState, -1); lua_pop(mLuaState, -1); return true; } bool XLua::getLuaVariableInt(const char* name, int& outValue) { assert(nullptr != mLuaState); _CHECK_VALUE_RETURN_BOOL_(nullptr != name); if (0 == lua_getglobal(mLuaState, name)) return false; outValue = (int)lua_tointeger(mLuaState, -1); lua_pop(mLuaState, -1); return true; } bool XLua::getLuaVariableInt64(const char* name, long long& outValue) { assert(nullptr != mLuaState); _CHECK_VALUE_RETURN_BOOL_(nullptr != name); if (0 == lua_getglobal(mLuaState, name)) return false; outValue = lua_tointeger(mLuaState, -1); lua_pop(mLuaState, -1); return true; } bool XLua::getLuaVariableFloat(const char* name, float& outValue) { assert(nullptr != mLuaState); _CHECK_VALUE_RETURN_BOOL_(nullptr != name); if (0 == lua_getglobal(mLuaState, name)) return false; outValue = (float)lua_tonumber(mLuaState, -1); lua_pop(mLuaState, -1); return true; } bool XLua::getLuaVariableDouble(const char* name, double& outValue) { assert(nullptr != mLuaState); _CHECK_VALUE_RETURN_BOOL_(nullptr != name); if (0 == lua_getglobal(mLuaState, name)) return false; outValue = (double)lua_tonumber(mLuaState, -1); lua_pop(mLuaState, -1); return true; } bool XLua::getLuaVariableString(const char* name, size_t bufLen, char* outValue) { assert(nullptr != mLuaState); _CHECK_VALUE_RETURN_BOOL_(nullptr != name); assert(bufLen > 0); assert(nullptr != outValue); if (0 == bufLen || nullptr == outValue) return false; if (0 == lua_getglobal(mLuaState, name)) return false; const char* str = lua_tostring(mLuaState, -1); if (nullptr == str) return false; lua_pop(mLuaState, -1); size_t len = strlen(str); if (len > bufLen) return false; memset(outValue, 0, bufLen); memcpy(outValue, str, len); return true; } bool XLua::callFunction(const char* funName, unsigned int retValueCount, IXLuaParamCallback* callback) { assert(nullptr != mLuaState); _CHECK_VALUE_RETURN_BOOL_(nullptr != funName); if (0 == lua_getglobal(mLuaState, funName)) return false; if (!lua_isfunction(mLuaState, -1)) { lua_pop(mLuaState, 1); return false; } unsigned int paramCount = 0; if (nullptr != callback) { paramCount = callback->pushParam(this); } if (LUA_OK != lua_pcall(mLuaState, paramCount, retValueCount, 0)) { // 弹出错误信息 const char* errMsg = lua_tostring(mLuaState, -1); lua_pop(mLuaState, 1); return false; } // 获取返回值 if (nullptr != callback && retValueCount > 0) { callback->getReturnValues(retValueCount, this); } // 清理栈 lua_pop(mLuaState, retValueCount); return true; } void XLua::close() { if (nullptr == mLuaState) return; lua_close(mLuaState); mLuaState = nullptr; } void XLua::process(const std::type_info& type, const void* data) { auto it = handlers.find(std::type_index(type)); if (it != handlers.end()) { it->second(data); } } void XLua::getValue(unsigned int retValueCount, unsigned int index, const std::type_info& type, void* data) { if (nullptr == mLuaState) return; int i = index - retValueCount - 1; auto it = handlers2.find(std::type_index(type)); if (it != handlers2.end()) { it->second(i, data); } } void XLua::register_handlers() { register_process([this](const int& v) { lua_pushinteger(mLuaState, v); }); register_process([this](const unsigned int& v) { lua_pushinteger(mLuaState, v); }); register_process([this](const char& v) { lua_pushinteger(mLuaState, v); }); register_process([this](const unsigned char& v) { lua_pushinteger(mLuaState, v); }); register_process([this](const short& v) { lua_pushinteger(mLuaState, v); }); register_process([this](const unsigned short& v) { lua_pushinteger(mLuaState, v); }); register_process([this](const long& v) { lua_pushinteger(mLuaState, v); }); register_process([this](const unsigned long& v) { lua_pushinteger(mLuaState, v); }); register_process([this](const long long& v) { lua_pushinteger(mLuaState, v); }); register_process([this](const unsigned long long& v) { lua_pushinteger(mLuaState, v); }); register_process([this](const float& v) { lua_pushnumber(mLuaState, v); }); register_process([this](const double& v) { lua_pushnumber(mLuaState, v); }); register_process([this](const bool& v) { lua_pushboolean(mLuaState, v); }); register_process([this](const char* v) { lua_pushstring(mLuaState, v); }); register_process([this](const char* v) { lua_pushstring(mLuaState, v); }); } void XLua::register_handlers2() { register_process2([this](int index, int& v) { v = lua_tointeger(mLuaState, index); }); register_process2([this](int index, unsigned int& v) { v = lua_tointeger(mLuaState, index); }); register_process2([this](int index, char& v) { v = lua_tointeger(mLuaState, index); }); register_process2([this](int index, unsigned char& v) { v = lua_tointeger(mLuaState, index); }); register_process2([this](int index, short& v) { v = lua_tointeger(mLuaState, index); }); register_process2([this](int index, unsigned short& v) { v = lua_tointeger(mLuaState, index); }); register_process2([this](int index, long& v) { v = lua_tointeger(mLuaState, index); }); register_process2([this](int index, unsigned long& v) { v = lua_tointeger(mLuaState, index); }); register_process2([this](int index, long long& v) { v = lua_tointeger(mLuaState, index); }); register_process2([this](int index, unsigned long long& v) { v = lua_tointeger(mLuaState, index); }); register_process2([this](int index, float& v) { v = lua_tonumber(mLuaState, index); }); register_process2([this](int index, double& v) { v = lua_tonumber(mLuaState, index); }); register_process2([this](int index, bool& v) { v = lua_toboolean(mLuaState, index); }); register_process2([this](int index, char*& v) { //const char* str = lua_tostring(mLuaState, index); v = (char*)(lua_tostring(mLuaState, index)); }); register_process2([this](int index, IXLuaValueObject& v) { if (!lua_istable(mLuaState, -1)) { lua_pop(mLuaState, 1); v.setCount(0); return; } readTableValues(v, -1); }); } void XLua::readTableValues(IXLuaValueObject& obj, int index) { lua_len(mLuaState, -1); int len = lua_tointeger(mLuaState, -1); lua_pop(mLuaState, 1); if(-1 == index) obj.setCount(len); if (len <= 0) return; for (int i = 1; i <= len; ++i) { lua_rawgeti(mLuaState, -1, i); // 如果又是表 if (lua_istable(mLuaState, -1)) { readTableValues(obj, i); } else { switch (lua_type(mLuaState, -1)) { case LUA_TNUMBER: if (lua_isinteger(mLuaState, -1)) { obj.setValue(index - 1, i - 1, lua_tointeger(mLuaState, -1)); } else { obj.setValue(index - 1, i - 1, lua_tonumber(mLuaState, -1)); } break; case LUA_TSTRING: obj.setValue(index - 1, i - 1, lua_tostring(mLuaState, -1)); break; case LUA_TBOOLEAN: obj.setValue(index - 1, i - 1, 1 == lua_toboolean(mLuaState, -1) ? true : false); break; } } lua_pop(mLuaState, 1); } }