You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

436 lines
8.8 KiB

#include "XLua.h"
#include "XDefine.h"
#include <string.h>
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)) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
const char* errMsg = lua_tostring(mLuaState, -1);
lua_pop(mLuaState, 1);
return false;
}
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ֵ
if (nullptr != callback && retValueCount > 0) {
callback->getReturnValues(retValueCount, this);
}
// <20><><EFBFBD><EFBFBD>ջ
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<int>([this](const int& v) {
lua_pushinteger(mLuaState, v);
});
register_process<unsigned int>([this](const unsigned int& v) {
lua_pushinteger(mLuaState, v);
});
register_process<char>([this](const char& v) {
lua_pushinteger(mLuaState, v);
});
register_process<unsigned char>([this](const unsigned char& v) {
lua_pushinteger(mLuaState, v);
});
register_process<short>([this](const short& v) {
lua_pushinteger(mLuaState, v);
});
register_process<unsigned short>([this](const unsigned short& v) {
lua_pushinteger(mLuaState, v);
});
register_process<long>([this](const long& v) {
lua_pushinteger(mLuaState, v);
});
register_process<unsigned long>([this](const unsigned long& v) {
lua_pushinteger(mLuaState, v);
});
register_process<long long>([this](const long long& v) {
lua_pushinteger(mLuaState, v);
});
register_process<unsigned long long>([this](const unsigned long long& v) {
lua_pushinteger(mLuaState, v);
});
register_process<float>([this](const float& v) {
lua_pushnumber(mLuaState, v);
});
register_process<double>([this](const double& v) {
lua_pushnumber(mLuaState, v);
});
register_process<bool>([this](const bool& v) {
lua_pushboolean(mLuaState, v);
});
register_process<char*>([this](const char* v) {
lua_pushstring(mLuaState, v);
});
register_process<const char*>([this](const char* v) {
lua_pushstring(mLuaState, v);
});
}
void XLua::register_handlers2() {
register_process2<int>([this](int index, int& v) {
v = lua_tointeger(mLuaState, index);
});
register_process2<unsigned int>([this](int index, unsigned int& v) {
v = lua_tointeger(mLuaState, index);
});
register_process2<char>([this](int index, char& v) {
v = lua_tointeger(mLuaState, index);
});
register_process2<unsigned char>([this](int index, unsigned char& v) {
v = lua_tointeger(mLuaState, index);
});
register_process2<short>([this](int index, short& v) {
v = lua_tointeger(mLuaState, index);
});
register_process2<unsigned short>([this](int index, unsigned short& v) {
v = lua_tointeger(mLuaState, index);
});
register_process2<long>([this](int index, long& v) {
v = lua_tointeger(mLuaState, index);
});
register_process2<unsigned long>([this](int index, unsigned long& v) {
v = lua_tointeger(mLuaState, index);
});
register_process2<long long>([this](int index, long long& v) {
v = lua_tointeger(mLuaState, index);
});
register_process2<unsigned long long>([this](int index, unsigned long long& v) {
v = lua_tointeger(mLuaState, index);
});
register_process2<float>([this](int index, float& v) {
v = lua_tonumber(mLuaState, index);
});
register_process2<double>([this](int index, double& v) {
v = lua_tonumber(mLuaState, index);
});
register_process2<bool>([this](int index, bool& v) {
v = lua_toboolean(mLuaState, index);
});
register_process2<char*>([this](int index, char*& v) {
//const char* str = lua_tostring(mLuaState, index);
v = (char*)(lua_tostring(mLuaState, index));
});
register_process2<IXLuaValueObject>([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);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DZ<EFBFBD>
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);
}
}