|
|
#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);
|
|
|
}
|
|
|
}
|
|
|
|