|
|
想要查看内容赶紧注册登陆吧!
您需要 登录 才可以下载或查看,没有账号?立即注册
x
头文件
- #pragma once
- extern "C"
- {
- #include <luajit/src/lua.h>
- #include <luajit/src/lualib.h>
- #include <luajit/src/lauxlib.h>
- #include <luajit/src/luajit.h>
- }
- class ScriptVM
- {
- public:
- ScriptVM();
- ~ScriptVM();
- bool Init();
- void Destroy();
- void ExecuteScriptFile(const char* sScriptName, bool bForceReload = false, bool bAssertOnError = true);
- //void ExecuteScript(const char* sScript, bool bAssertOnError = true);
- protected:
- bool LoadFileToBuffer(const std::string& path, std::vector<uint8_t>& buffer);
- private:
- lua_State* m_pLua;
- };
复制代码
源文件
- #include "pch.h"
- #include "script_vm.h"
- static int wrap_exceptions(lua_State* L, lua_CFunction f)
- {
- try
- {
- return f(L); // Call wrapped function and return result.
- }
- catch (const char* s)
- {
- // Catch and convert exceptions.
- lua_pushstring(L, s);
- }
- catch (std::exception& e)
- {
- lua_pushstring(L, e.what());
- }
- catch (...)
- {
- lua_pushliteral(L, "caught (...)");
- }
- return lua_error(L); // Rethrow as a Lua error.
- }
- static void error_msg(bool bUseAssert, const char* pacFmt, ...)
- {
- //#if defined(_DEBUG)
- char acTemp[2048];
- va_list args;
- va_start(args, pacFmt);
- vsprintf_s(acTemp, pacFmt, args);
- va_end(args);
- if (bUseAssert)
- {
- assert(acTemp);
- }
- //#endif
- }
- void report_last_error(lua_State* pLua, bool bUseAssert)
- {
- lua_getglobal(pLua, "_ALERT");
- error_msg(bUseAssert, "%s\n", lua_tostring(pLua, -2));
- error_msg(bUseAssert, "%s\n", lua_tostring(pLua, -1));
- lua_pop(pLua, 2); /* remove error_msg message and _ALERT */
- }
- std::string& std_string_format(std::string& _str, const char* _Format, ...)
- {
- std::string tmp;
- va_list marker = NULL;
- va_start(marker, _Format);
- size_t num_of_chars = _vscprintf(_Format, marker);
- if (num_of_chars > tmp.capacity())
- {
- tmp.resize(num_of_chars + 1);
- }
- vsprintf_s((char*)tmp.data(), tmp.capacity(), _Format, marker);
- va_end(marker);
- _str = tmp.c_str();
- return _str;
- }
- ScriptVM::ScriptVM()
- {
- }
- ScriptVM::~ScriptVM()
- {
- }
- int PrintStringList(lua_State* pLuaState)
- {
- luaJIT_setmode(pLuaState, -1, LUAJIT_MODE_ALLFUNC | LUAJIT_MODE_ALLSUBFUNC | LUAJIT_MODE_ON);
- // Get the number of strings
- int iStringCount = lua_gettop(pLuaState);
- // Loop through each string and print it, followed by a newline
- for (int iCurrStringIndex = 1; iCurrStringIndex <= iStringCount; ++iCurrStringIndex)
- {
- // First make sure that the current parameter on the stack is a string
- if (!lua_isstring(pLuaState, 1))
- {
- // If not, print an error
- lua_error(pLuaState);
- }
- else
- {
- // Otherwise, print a tab, the string, and finally a newline
- printf("\t");
- printf(lua_tostring(pLuaState, iCurrStringIndex));
- printf("\n");
- }
- }
- // Return zero, as this function does not return any results
- return 0;
- }
- bool ScriptVM::Init()
- {
- m_pLua = luaL_newstate();
- lua_cpcall(m_pLua, luaopen_base, 0);
- lua_cpcall(m_pLua, luaopen_io, 0);
- lua_cpcall(m_pLua, luaopen_string, 0);
- lua_cpcall(m_pLua, luaopen_table, 0);
- lua_cpcall(m_pLua, luaopen_math, 0);
- lua_cpcall(m_pLua, luaopen_debug, 0);
- lua_cpcall(m_pLua, luaopen_os, 0);
- lua_cpcall(m_pLua, luaopen_package, 0);
- //luaopen_base(m_pLua);
- //luaopen_io(m_pLua);
- //luaopen_table(m_pLua);
- //luaopen_math(m_pLua);
- //luaopen_string(m_pLua);
- //luaopen_debug(m_pLua);
- //tolua_open_binding(m_pLua);
- //lua_setgcthreshold(m_pLua, 200); //200k garbage collection threshold
- lua_register(m_pLua, "PrintStringList", PrintStringList);
- //lua_register(m_pLua, "dofile", OverrideDofile);
- // 添加 LuaJIT 的支持
- lua_pushlightuserdata(m_pLua, (void*)wrap_exceptions);
- luaJIT_setmode(m_pLua, 0, LUAJIT_MODE_ENGINE | LUAJIT_MODE_ON);
- return true;
- }
- void ScriptVM::Destroy()
- {
- lua_close(m_pLua);
- }
- bool ScriptVM::LoadFileToBuffer(const std::string& path, std::vector<uint8_t>& buffer)
- {
- std::ifstream file(path, std::ios::binary | std::ios::ate);
- if (!file.is_open())
- return false;
- std::streamsize size = file.tellg();
- if (size <= 0)
- return false;
- buffer.resize(static_cast<size_t>(size));
- file.seekg(0, std::ios::beg);
- if (!file.read(reinterpret_cast<char*>(buffer.data()), size))
- return false;
- return true;
- }
-
- void ScriptVM::ExecuteScriptFile(const char* sScriptName, bool bForceReload /* = false*/, bool bAssertOnError /*= true*/)
- {
- // 添加 LuaJIT 的支持
- luaJIT_setmode(m_pLua, -1, LUAJIT_MODE_ALLFUNC | LUAJIT_MODE_ALLSUBFUNC | LUAJIT_MODE_ON);
-
- int nSize1 = lua_gettop(m_pLua);
- //get chunk name as modified script name
- std::string sChunkName(sScriptName);
- for (unsigned int i = 0; i < sChunkName.length(); i++)
- {
- if (sChunkName[i] == '/' || sChunkName[i] == '.')
- sChunkName[i] = '_';
- }
-
- //get the chunk global
- lua_getglobal(m_pLua, sChunkName.c_str());
- if (bForceReload || !lua_isfunction(m_pLua, -1))//if force reload or not found
- {
- //load it first
- std::vector<uint8_t> Buffer;
- if (LoadFileToBuffer(sScriptName, Buffer))
- {
- luaL_loadbuffer(m_pLua, (char*)Buffer.data(), Buffer.size(), sScriptName);
-
- // luaL_loadfile(m_pLua, sScriptName);
- lua_setglobal(m_pLua, sChunkName.c_str());
- lua_getglobal(m_pLua, sChunkName.c_str());
- }
- else
- goto failed;
- }
-
- if (lua_pcall(m_pLua, 0, 0, 0) != 0)
- {
- error_msg(bAssertOnError, "error executing script file %s: ", sScriptName);
- report_last_error(m_pLua, bAssertOnError);
- }
-
- failed:
- lua_settop(m_pLua, nSize1);
- }
- //
- // void ScriptVM::ExecuteScript(const char* sScript, bool bAssertOnError)
- // {
- // // 添加 LuaJIT 的支持
- // luaJIT_setmode(m_pLua, -1, LUAJIT_MODE_ALLFUNC | LUAJIT_MODE_ALLSUBFUNC | LUAJIT_MODE_ON);
- //
- // int status = luaL_loadbuffer(m_pLua, sScript, strlen(sScript), sScript);
- //
- // if (status)
- // {
- // //report_last_error(m_pLua, bAssertOnError);
- // }
- // else
- // {
- // status = lua_pcall(m_pLua, 0, LUA_MULTRET, 0); /* call main */
- //
- // //if (status)
- // // report_last_error(m_pLua, bAssertOnError);
- // }
- // }
- //
- // bool ScriptVM::ExecuteScriptFunc(const std::vector<const char*>& modules, const char* func, bool bAllowNonexist, const char* sig, ...)
- // {
- // // 添加 LuaJIT 的支持
- // luaJIT_setmode(m_pLua, -1, LUAJIT_MODE_ALLFUNC | LUAJIT_MODE_ALLSUBFUNC | LUAJIT_MODE_ON);
- //
- // bool bIsSuccess = false;
- //
- // //PROFILE("ExecuteScriptFunc");
- //
- // int nSize1 = lua_gettop(m_pLua);
- //
- // //debug
- //
- // #if DEBUG_STACK
- // printf("debug lua: stack size before ExecuteScriptFunc = %d\n", nSize1);
- // #endif
- //
- // va_list vl;
- // int narg, nres; /* number of arguments and results */
- // va_start(vl, sig);
- //
- // //get the actual function
- // if (modules.empty()) //func is global
- // {
- // lua_getglobal(m_pLua, func);
- //
- // if (!lua_isfunction(m_pLua, -1))
- // {
- // if (!bAllowNonexist)
- // error_msg(true, "ExecuteScriptFunc: Invalid function name: %s\n", func);
- //
- // goto failed;
- // }
- // }
- // else
- // {
- //
- // //trace down the modules
- //
- // std::vector<const char*>::const_iterator it = modules.begin();
- //
- // //get the global module name or the actual function name if there is no module
- //
- // lua_getglobal(m_pLua, *it);
- //
- // if (!lua_istable(m_pLua, -1))
- //
- // {
- //
- // if (!bAllowNonexist)
- //
- // error_msg(true, "ExecuteScriptFunc: Invalid table name: %s\n", *it);
- //
- // goto failed;
- //
- // }
- //
- //
- //
- // for (++it; it != modules.end(); ++it)
- //
- // {
- //
- // lua_pushstring(m_pLua, *it);
- //
- // lua_gettable(m_pLua, -2);
- //
- // if (!lua_istable(m_pLua, -1))
- //
- // {
- //
- // if (!bAllowNonexist)
- //
- // error_msg(true, "ExecuteScriptFunc: Invalid table name: %s\n", *it);
- //
- // goto failed;
- //
- // }
- //
- // }
- //
- // //get the func
- //
- // lua_pushstring(m_pLua, func);
- //
- // lua_gettable(m_pLua, -2);
- //
- // if (!lua_isfunction(m_pLua, -1))
- //
- // {
- //
- // if (!bAllowNonexist)
- //
- // error_msg(true, "ExecuteScriptFunc: Invalid function name: %s\n", func);
- //
- // goto failed;
- //
- // }
- //
- // }
- //
- //
- //
- // /* push arguments */
- //
- // narg = 0;
- //
- // while (*sig) { /* push arguments */
- //
- // switch (*sig++) {
- //
- // case 'd': /* double argument */
- //
- // case 'f': /* float argument */ // NieXu: Treat float as double, same as printf()
- //
- // lua_pushnumber(m_pLua, va_arg(vl, double));
- //
- // break;
- //
- // case 'i': /* int argument */
- //
- // lua_pushnumber(m_pLua, va_arg(vl, int));
- //
- // break;
- //
- // case 's': /* string argument */
- //
- // lua_pushstring(m_pLua, va_arg(vl, char*));
- //
- // break;
- //
- // case 'b': /* boolean argument */
- //
- // lua_pushboolean(m_pLua, va_arg(vl, bool));
- //
- // break;
- //
- // case 'u': /* light user data */
- //
- // lua_pushlightuserdata(m_pLua, va_arg(vl, void*));
- //
- // break;
- //
- // case 't': /* type user data */
- //
- // {
- //
- // void* pData = va_arg(vl, void*);
- //
- // const char* sType = va_arg(vl, const char*);
- //
- // tolua_pushusertype(m_pLua, pData, sType);
- //
- // break;
- //
- // }
- //
- //
- //
- // case '>':
- //
- // goto endwhile;
- //
- // default:
- //
- // error_msg(true, "invalid option (%c)\n", *(sig - 1));
- //
- // goto failed;
- //
- // }
- //
- // narg++;
- //
- // luaL_checkstack(m_pLua, 1, "too many arguments");
- //
- // }endwhile:
- //
- // /* do the call */
- //
- // nres = strlen(sig); /* number of expected results */
- //
- // if (lua_pcall(m_pLua, narg, nres, 0) != 0) /* do the call */
- //
- // {
- //
- // report_last_error(m_pLua, true);
- //
- // goto failed;
- //
- // }
- //
- // /* retrieve results */
- //
- // nres = -nres; /* stack index of first result */
- //
- // while (*sig)
- //
- // { /* get results */
- //
- // switch (*sig++)
- //
- // {
- //
- // case 'd': /* double result */
- //
- // if (!lua_isnumber(m_pLua, nres))
- //
- // error_msg(true, "wrong result type,function name: %s\n", func);
- //
- // *va_arg(vl, double*) = lua_tonumber(m_pLua, nres);
- //
- // break;
- //
- // case 'f': /* float result */
- //
- // if (!lua_isnumber(m_pLua, nres))
- //
- // error_msg(true, "wrong result type,function name: %s\n", func);
- //
- // *va_arg(vl, float*) = (float)lua_tonumber(m_pLua, nres);
- //
- // break;
- //
- // case 'i': /* int result */
- //
- // if (!lua_isnumber(m_pLua, nres))
- //
- // error_msg(true, "wrong result type,function name: %s\n", func);
- //
- // *va_arg(vl, int*) = (int)lua_tonumber(m_pLua, nres);
- //
- // break;
- //
- // case 's': /* string result */
- //
- // if (!lua_isstring(m_pLua, nres))
- //
- // error_msg(true, "wrong result type,function name: %s\n", func);
- //
- // *va_arg(vl, std::string*) = lua_tostring(m_pLua, nres);
- //
- // break;
- //
- // case 'b': /* boolean argument */
- //
- // if (!lua_isboolean(m_pLua, nres))
- //
- // error_msg(true, "wrong result type,function name: %s\n", func);
- //
- // *va_arg(vl, bool*) = (0 != lua_toboolean(m_pLua, nres));
- //
- // break;
- //
- // case 'u': /* light user data */
- //
- // if (!lua_isuserdata(m_pLua, nres))
- //
- // error_msg(true, "wrong result type,function name: %s\n", func);
- //
- // *va_arg(vl, void**) = lua_touserdata(m_pLua, nres);
- //
- // break;
- //
- // default:
- //
- // error_msg(true, "invalid option (%c)\n", *(sig - 1));
- //
- // }
- //
- // nres++;
- //
- // }
- //
- //
- //
- // bIsSuccess = true;
- //
- // failed:
- //
- // va_end(vl);
- //
- // //clear the stack
- //
- // lua_settop(m_pLua, nSize1);
- //
- //
- //
- // #if DEBUG_STACK
- //
- // //debug
- //
- // int nSize2 = lua_gettop(m_pLua);
- //
- // printf("debug lua: stack size after ExecuteScriptFunc = %d\n", nSize2);
- //
- // if (nSize1 != nSize2)
- //
- // stackDump(m_pLua);
- //
- // #endif
- //
- // return bIsSuccess;
- // }
复制代码
|
|