init project
This commit is contained in:
commit
821ea7eed0
16 changed files with 950 additions and 0 deletions
154
src/lua/loader.cpp
Normal file
154
src/lua/loader.cpp
Normal file
|
@ -0,0 +1,154 @@
|
|||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <lua/loader.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
LuaLoader::LuaLoader() : L(luaL_newstate()) {
|
||||
luaL_openlibs(L);
|
||||
AddLuaPath("./?.lua");
|
||||
AddCPath("./?.so");
|
||||
AddCPath("./?.dylib");
|
||||
}
|
||||
|
||||
void LuaLoader::AddLuaPath(const std::string& new_path) {
|
||||
lua_getglobal(L, "package");
|
||||
lua_getfield(L, -1, "path");
|
||||
lua_pushstring(L, (std::string(";") + new_path).data());
|
||||
lua_concat(L, 2);
|
||||
lua_setfield(L, -2, "path");
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
void LuaLoader::AddCPath(const std::string& new_path) {
|
||||
lua_getglobal(L, "package");
|
||||
lua_getfield(L, -1, "cpath");
|
||||
lua_pushstring(L, (std::string(";") + new_path).data());
|
||||
lua_concat(L, 2);
|
||||
lua_setfield(L, -2, "cpath");
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
void LuaLoader::LoadImpl(const std::string& name) {
|
||||
lua_getglobal(L, "require");
|
||||
lua_pushstring(L, name.data());
|
||||
|
||||
if (lua_pcall(L, 1, 1, 0) != LUA_OK) {
|
||||
std::cerr << "Error call script: " << name.data() << std::endl;
|
||||
std::cerr << lua_tostring(L, -1) << std::endl;
|
||||
throw std::logic_error("Error call script: " + name);
|
||||
}
|
||||
|
||||
ParseRequire();
|
||||
ParseImport();
|
||||
}
|
||||
|
||||
void LuaLoader::LoadToGlobal(const std::string& name) {
|
||||
LoadImpl(name);
|
||||
lua_setglobal(L, name.data());
|
||||
}
|
||||
|
||||
std::vector<std::string> LuaLoader::GetListScripts(const std::string& lua_module) const {
|
||||
std::vector<std::string> result;
|
||||
|
||||
lua_getglobal(L, lua_module.data());
|
||||
lua_pushnil(L);
|
||||
|
||||
while (lua_next(L, -2) != 0) {
|
||||
if (!lua_isfunction(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
result.push_back(lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void LuaLoader::ForEachByStringArray(std::function<void(const std::string&)> callback) {
|
||||
if (lua_isnil(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lua_isstring(L, -1)) {
|
||||
callback(lua_tostring(L, -1));
|
||||
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
} else if (lua_istable(L, -1)) {
|
||||
lua_pushnil(L);
|
||||
|
||||
while (lua_next(L, -2) != 0) {
|
||||
if (!lua_isstring(L, -1)) {
|
||||
throw std::logic_error("Error in for each by string array");
|
||||
}
|
||||
|
||||
callback(lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
throw std::logic_error("Error in parse requires ");
|
||||
}
|
||||
|
||||
void LuaLoader::ParseRequire() {
|
||||
if (!lua_istable(L, -1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getfield(L, -1, "require");
|
||||
|
||||
ForEachByStringArray(
|
||||
[this](const std::string& new_module_name) { LoadToGlobal(new_module_name); });
|
||||
}
|
||||
|
||||
void LuaLoader::Import(const std::string& name, const std::string& field, int table) {
|
||||
LoadImpl(name);
|
||||
lua_getfield(L, -1, field.data());
|
||||
lua_setfield(L, table, field.data());
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
void LuaLoader::ParseImport() {
|
||||
if (!lua_istable(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getfield(L, -1, "import");
|
||||
|
||||
ForEachByStringArray([this, table = lua_absindex(L, -2)](const std::string& new_module_name) {
|
||||
int dot_position = new_module_name.find(".");
|
||||
|
||||
if (dot_position == std::string::npos) {
|
||||
throw std::logic_error("Can't find dot in import");
|
||||
}
|
||||
|
||||
Import(new_module_name.substr(0, dot_position), new_module_name.substr(dot_position + 1),
|
||||
table);
|
||||
});
|
||||
}
|
||||
|
||||
void LuaLoader::Call(const std::string& lua_module, const std::string& function) {
|
||||
lua_getglobal(L, lua_module.data());
|
||||
lua_getfield(L, -1, function.data());
|
||||
|
||||
if (lua_pcall(L, 0, 0, 0) != LUA_OK) {
|
||||
std::cout << "Error in call " << lua_module << "." << function << std::endl;
|
||||
std::cerr << lua_tostring(L, -1) << std::endl;
|
||||
throw std::logic_error("Error in call " + lua_module + "." + function);
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
LuaLoader::~LuaLoader() {
|
||||
lua_close(L);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue