Created
December 5, 2015 19:00
-
-
Save bagobor/361b1b9a226974984072 to your computer and use it in GitHub Desktop.
lua chunk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <string> | |
#include <lua/lua.hpp> | |
#include <luabind/luabind.hpp> | |
#include <luabind/detail/policy.hpp> | |
#include <luabind/out_value_policy.hpp> | |
#include <luabind/operator.hpp> | |
class lua_chunk { | |
public: | |
lua_chunk(lua_State* L, const std::string& script) { | |
lua_chunk::L = L; | |
compile(script); | |
} | |
lua_chunk(lua_State* L) { | |
lua_chunk::L = L; | |
} | |
bool compile(const std::string& script) { | |
is_compiled = false; | |
//luaL_loadstring(L, script.c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) | |
const int res = luaL_loadstring(L, script.c_str()); | |
if (res != LUA_OK) { | |
const char *msg = lua_tostring(L, -1); | |
errors = msg ? msg : "unknown error"; | |
//switch (res) | |
//{ | |
//case LUA_ERRSYNTAX: | |
// break; | |
//case LUA_ERRFILE: | |
// break; | |
//default : | |
// break; | |
//} | |
return false; | |
} | |
is_compiled = true; | |
using namespace luabind; | |
chunk = object(from_stack(L, -1)); | |
//lua_pop(L, 1); | |
for (int index = 1;;++index) { // find _ENV upvalue, then use it index to changing chunk ENV for reEVAL. | |
auto upv = luabind::getupvalue(chunk, index); | |
auto name = std::get<0>(upv); | |
static std::string _ENV_NAME = "_ENV"; | |
if (!name) break; | |
if (name == _ENV_NAME) { | |
ENV_index = index; | |
break; | |
} | |
// std::cout << name << std::endl; | |
} | |
//is_compiled = true; | |
return is_compiled; | |
} | |
const std::string& get_errors() const { return errors; } | |
luabind::object run(luabind::object env) { | |
using namespace luabind; | |
if (!is_compiled) return object(); | |
if (env) { | |
setupvalue(chunk, 1, env); | |
} | |
else { | |
object _G = rawget(globals(L), "_G"); | |
setupvalue(chunk, 1, _G); | |
} | |
luabind::function<luabind::object> chunk_func = chunk; | |
return chunk_func(); | |
} | |
luabind::object new_instance() { | |
using namespace luabind; | |
object oldEnv = rawget(globals(L), "_G"); | |
object newEnv = newtable(L); | |
object newEnvMeta = newtable(L); | |
settable(newEnvMeta, "__index", oldEnv); | |
setmetatable(newEnv, newEnvMeta); | |
run(newEnv); | |
return newEnv; | |
} | |
std::string errors; | |
bool is_compiled = false; | |
//luabind::function<luabind::object> chunk; | |
private: | |
luabind::object chunk; | |
int ENV_index = -1; | |
lua_State* L; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment