From cab475796578c881b078781a58b61395b8a39bd5 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Wed, 14 Apr 2021 17:08:02 +0800 Subject: [PATCH] add luaengine.* --- a8/luaengine.cc | 168 ++++++++++++++++++++++++++++++++++++++++++++++++ a8/luaengine.h | 40 ++++++++++++ a8/pyengine.cc | 2 - 3 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 a8/luaengine.cc create mode 100755 a8/luaengine.h diff --git a/a8/luaengine.cc b/a8/luaengine.cc new file mode 100644 index 0000000..c44297c --- /dev/null +++ b/a8/luaengine.cc @@ -0,0 +1,168 @@ +#include +#include + +#ifdef A8_USE_LUA + +extern "C" +{ +#include +#include +#include +}; + +namespace a8 +{ + LuaEngine::LuaEngine() + { + lua_state_ = luaL_newstate(); + if (!lua_state_) { + abort(); + } + luaL_openlibs(lua_state_); + } + + LuaEngine::~LuaEngine() + { + if (lua_state_) { + lua_close(lua_state_); + lua_state_ = nullptr; + } + } + + bool LuaEngine::LoadModule(const std::string& module_name) + { + std::string real_filename = lua_path_ + module_name; + a8::ReplaceString(real_filename, ".", "/"); + real_filename = real_filename + ".lua"; + int ret = luaL_loadfile(lua_state_, real_filename.c_str()) + || lua_pcall(lua_state_, 0, 1, 0); + if (ret != 0){ + std::string errormsg = lua_tostring(lua_state_, -1); + lua_pop(lua_state_, 1); + OnScriptError(errormsg); + return false; + } + std::string module_varname = "module_" + module_name; + a8::ReplaceString(module_varname, ".", "_"); + if (lua_istable(lua_state_, -1)) { + lua_setglobal(lua_state_, module_varname.c_str()); + return true; + } else { + OnScriptError("返回值不是table"); + return false; + } + } + + bool LuaEngine::LoadString(const std::string& str) + { + int ret = luaL_loadstring(lua_state_, str.c_str()) + || lua_pcall(lua_state_, 0, 0, 0); + if (ret != 0){ + std::string errormsg = lua_tostring(lua_state_, -1); + lua_pop(lua_state_, 1); + OnScriptError(errormsg); + return false; + } + return true; + } + + std::tuple LuaEngine::CallGlobalFunc(const char* func_name, + std::initializer_list args) + { + a8::XValue result; + bool ret = CallLuaFunc(NULL, func_name, args, result); + return std::make_tuple(ret, result); + } + + std::tuple LuaEngine::CallModuleFunc(const char* module_name, + const char* func_name, + std::initializer_list args) + { + a8::XValue result; + bool ret = CallLuaFunc(module_name, func_name, args, result); + return std::make_tuple(ret, result); + } + + bool LuaEngine::CallLuaFunc(const char* module_name, + const char* func_name, + std::initializer_list& args, + a8::XValue& result) + { + if (module_name) { //call module function + std::string module_varname = std::string("module_") + module_name; + a8::ReplaceString(module_varname, ".", "_"); + lua_getglobal(lua_state_, module_varname.c_str()); + if (!lua_istable(lua_state_, -1)) { + OnScriptError(a8::Format("%s不是一个table", {module_name})); + lua_pop(lua_state_, 1); + return false; + } + lua_getfield(lua_state_, -1, func_name); + if (!lua_isfunction(lua_state_, -1)) { + OnScriptError(a8::Format("%s函数找不到", {func_name})); + lua_pop(lua_state_, 2); + return false; + } + } else { // call global function + lua_getglobal(lua_state_, func_name); + if (!lua_isfunction(lua_state_, -1)) { + OnScriptError(a8::Format("%s函数找不到", {func_name})); + lua_pop(lua_state_, 1); + return false; + } + } + for (auto &arg : args) { + switch(arg.Type()){ + case XVT_INT: + lua_pushnumber(lua_state_, arg.GetInt()); + break; + case XVT_UINT: + lua_pushnumber(lua_state_, arg.GetUInt()); + break; + case XVT_FLOAT: + lua_pushnumber(lua_state_, arg.GetDouble()); + break; + case XVT_INT64: + lua_pushstring(lua_state_, arg.GetString().c_str()); + break; + case XVT_UINT64: + lua_pushstring(lua_state_, arg.GetString().c_str()); + break; + case XVT_STRING: + lua_pushstring(lua_state_, arg.GetString().c_str()); + break; + default: + abort(); + break; + } + } + if (lua_pcall(lua_state_, args.size(), 1, 0) == 0){ + switch(lua_type(lua_state_, -1)){ + case LUA_TBOOLEAN: + result.Set(lua_toboolean(lua_state_, -1) ? 1 : 0); + break; + case LUA_TNUMBER: + result.Set(lua_tonumber(lua_state_, -1)); + break; + case LUA_TSTRING: + result.Set(lua_tostring(lua_state_, -1)); + break; + } + lua_pop(lua_state_, module_name ? 2 : 1); + return true; + } else { + std::string errmsg(lua_tostring(lua_state_, -1)); + lua_pop(lua_state_, module_name ? 2 : 1); + OnScriptError(errmsg); + return false; + } + } + + void LuaEngine::OnScriptError(const std::string& errormsg) + { + last_error_msg_ = errormsg; + } + +} + +#endif diff --git a/a8/luaengine.h b/a8/luaengine.h new file mode 100755 index 0000000..ae6e2d0 --- /dev/null +++ b/a8/luaengine.h @@ -0,0 +1,40 @@ +#ifndef A8_LUAENGINE_H +#define A8_LUAENGINE_H + +struct lua_State; +namespace a8 +{ + + class LuaEngine + { + public: + + LuaEngine(); + ~LuaEngine(); + bool LoadModule(const std::string& module_name); + bool LoadString(const std::string& str); + std::tuple CallGlobalFunc(const char* func_name, + std::initializer_list args); + std::tuple CallModuleFunc(const char* module_name, + const char* func_name, + std::initializer_list args); + std::string GetErrorMsg() { return last_error_msg_; }; + + private: + + bool CallLuaFunc(const char* module_name, + const char* func_name, + std::initializer_list& args, + a8::XValue& result); + void OnScriptError(const std::string& errmsg); + + private: + lua_State* lua_state_ = nullptr; + std::string lua_path_; + std::string last_error_msg_; + + }; + +} + +#endif diff --git a/a8/pyengine.cc b/a8/pyengine.cc index 58526d5..f88f548 100644 --- a/a8/pyengine.cc +++ b/a8/pyengine.cc @@ -1,7 +1,5 @@ #include -#include - #include #include