游戏引擎加入lua
为了让游戏实现热更新,决定引入lua来开发游戏。游戏的主框架是c++,lua调用c++直接用tolua++就行了。lua的解析为了加快速度,我决定使用luajit,当然也可以实用luaC来做。
#pragma once
#include "base/Singleton.h"
#include "string"
extern "C" {
#include "external/luajit/include/lua.h"
#include "external/luajit/include/lualib.h"
#include "external/luajit/include/lauxlib.h"
}
namespace cloud
{
class LuaEngine: public Singleton<LuaEngine>
{
public:
DECLARE_SINGLETON_CREATE_DESTROY
LuaEngine();
~LuaEngine();
void addSearchPath(const char* path);
int executeScriptFile(const char* filename);
int executeString(const char *codes);
int executeFunction(int numArgs);
lua_State *getLuaState();
void addLuaLoader(lua_CFunction func);
int luaLoadBuffer(lua_State *L, const char *chunk, int chunkSize, const char *chunkName);
private:
int _callFromLua;
lua_State *_state;
};
}
#include "LuaEngine.h"
#include "string"
#include "base/fileUtils/FileUtils.h"
#include "base/EngineLog.h"
#include "base/script/lua_interface.h"
namespace cloud
{
int gameEngine_lua_loader(lua_State *L)
{
static const std::string BYTECODE_FILE_EXT = ".luac";
static const std::string NOT_BYTECODE_FILE_EXT = ".lua";
std::string filename(luaL_checkstring(L, 1));
size_t pos = filename.rfind(NOT_BYTECODE_FILE_EXT);
if (pos != std::string::npos)
{
filename = filename.substr(0, pos);
}
pos = filename.find_first_of(".");
while (pos != std::string::npos)
{
filename.replace(pos, 1, "/");
pos = filename.find_first_of(".");
}
// search file in package.path
unsigned char* chunk = nullptr;
size_t chunkSize = 0;
std::string chunkName;
FileUtils* utils = FileUtils::getInstance();
lua_getglobal(L, "package");
lua_getfield(L, -1, "path");
std::string searchpath(lua_tostring(L, -1));
lua_pop(L, 1);
size_t begin = 0;
size_t next = searchpath.find_first_of(";", 0);
do
{
if (next == std::string::npos)
next = searchpath.length();
std::string prefix = searchpath.substr(begin, next);
if (prefix[0] == '.' && prefix[1] == '/')
{
prefix = prefix.substr(2);
}
pos = prefix.find("?.lua");
chunkName = prefix.substr(0, pos) + filename + BYTECODE_FILE_EXT;
if (utils->isFileExist(chunkName.c_str()))
{
utils->readFile(chunkName.c_str(),&chunk,chunkSize);