50 #include <boost/range/adaptors.hpp>
58 #define DBG_LUA LOG_STREAM(debug, log_scripting_lua)
59 #define LOG_LUA LOG_STREAM(info, log_scripting_lua)
60 #define WRN_LUA LOG_STREAM(warn, log_scripting_lua)
61 #define ERR_LUA LOG_STREAM(err, log_scripting_lua)
66 lua_getglobal(L,
"print");
70 std::stringstream
line;
80 lua_pushstring(L,
line.str().c_str());
84 lua_pushstring(L,
"No plugins available.\n");
92 unsigned int delay =
static_cast<unsigned int>(luaL_checkinteger(L, 1));
100 lua_getglobal(
mState,
"wesnoth");
102 lua_setfield(
mState, -2,
"delay");
107 lua_setglobal(
mState,
"describe_plugins");
119 if (lua_status(T_) == LUA_OK) {
120 return "not started";
125 switch (lua_status(T_)) {
136 return started_ ? (lua_status(T_) == LUA_YIELD) : (lua_status(T_) == LUA_OK);
148 lua_rawget(L, LUA_REGISTRYINDEX);
149 if (!lua_istable(L,-1)) {
154 lua_pushinteger(L, lua_rawlen(L, -1) + 1);
156 lua_State * T = lua_newthread(L);
160 lua_rawset(L, LUA_REGISTRYINDEX);
170 DBG_LUA <<
"created thread: status = " << lua_status(T) << (lua_status(T) == LUA_OK ?
" == OK" :
" == ?");
171 DBG_LUA <<
"loading script from string:\n<<\n" << prog <<
"\n>>";
174 int errcode = luaL_loadstring(T, prog.c_str());
175 if (errcode != LUA_OK) {
176 const char * err_str = lua_tostring(T, -1);
177 std::string
msg = err_str ? err_str :
"null string";
179 std::string context =
"When parsing a string to a lua thread, ";
181 if (errcode == LUA_ERRSYNTAX) {
182 context +=
" a syntax error";
183 }
else if(errcode == LUA_ERRMEM){
184 context +=
" a memory error";
186 context +=
" an unknown error";
192 throw game::lua_error(
"Error when executing a script to make a lua thread.");
194 if (!lua_isfunction(T, -1)) {
195 throw game::lua_error(std::string(
"Error when executing a script to make a lua thread -- function was not produced, found a ") + lua_typename(T, lua_type(T, -1)) );
206 lua_pushstring(T, file.c_str());
209 throw game::lua_error(
"Error when executing a file to make a lua thread.");
211 if (!lua_isfunction(T, -1)) {
212 throw game::lua_error(std::string(
"Error when executing a file to make a lua thread -- function was not produced, found a ") + lua_typename(T, lua_type(T, -1)) );
228 static int impl_context_backend(lua_State * L, std::shared_ptr<lua_context_backend> backend, std::string req_name)
230 if (!backend->valid) {
231 luaL_error(L ,
"Error, you tried to use an invalid context object in a lua thread");
238 backend->requests.push_back(evt);
244 if (!backend->valid) {
245 luaL_error(L ,
"Error, you tried to use an invalid context object in a lua thread");
251 luaL_argerror(L, 1,
"Error, tried to parse a config but some fields were invalid");
269 for (std::size_t
i = 0;
i < queue.size(); ++
i) {
271 lua_pushstring(T_, queue[
i].name.c_str());
272 lua_rawseti(T_, -2, 1);
274 lua_rawseti(T_, -2, 2);
275 lua_rawseti(T_, -2,
i+1);
279 auto this_context_backend = std::make_shared<lua_context_backend>();
281 for (
const std::string & key : ctxt.
callbacks_ | boost::adaptors::map_keys ) {
282 lua_pushstring(T_, key.c_str());
284 lua_settable(T_, -3);
289 lua_pushstring(T_,
"name");
290 lua_pushstring(T_, ctxt.
name_.c_str());
291 lua_settable(T_, -3);
292 for (
const plugins_context::accessor_list::value_type & v : ctxt.
accessors_) {
293 const std::string & key = v.first;
295 lua_pushstring(T_, key.c_str());
297 lua_settable(T_, -3);
302 lua_resume(T_,
nullptr, 3, &numres);
306 this_context_backend->valid =
false;
308 if (lua_status(T_) != LUA_YIELD) {
309 LOG_LUA <<
"Thread status = '" << lua_status(T_) <<
"'";
310 if (lua_status(T_) != LUA_OK) {
311 std::stringstream ss;
312 ss <<
"encountered a";
313 switch(lua_status(T_)) {
321 ss <<
" error-handler ";
327 ss <<
"error:\n" << lua_tostring(T_, -1) <<
"\n";
static lua_State * get_new_thread(lua_State *L)
static lg::log_domain log_scripting_lua("scripting/lua")
static int intf_describe_plugins(lua_State *L)
static int impl_context_accessor(lua_State *L, std::shared_ptr< lua_context_backend > backend, plugins_context::accessor_function func)
static char * v_threadtableKey
static void *const threadtableKey
static int intf_delay(lua_State *L)
static int impl_context_backend(lua_State *L, std::shared_ptr< lua_context_backend > backend, std::string req_name)
request_list run_script(const plugins_context &ctxt, const std::vector< plugins_manager::event > &queue)
thread(const thread &)=delete
thread * load_script_from_string(const std::string &)
std::vector< std::function< bool(void)> > request_list
thread * load_script_from_file(const std::string &)
A config object defines a single node in a WML file, with access to child nodes.
virtual void log_error(char const *msg, char const *context="Lua error")
Error reporting mechanisms, used by virtual methods protected_call and load_string.
bool protected_call(int nArgs, int nRets, error_handler)
std::function< config(config)> accessor_function
std::string get_name(std::size_t idx)
static plugins_manager * get()
Standard logging facilities (interface).
void luaW_pushconfig(lua_State *L, const config &cfg)
Converts a config object to a Lua table pushed at the top of the stack.
config luaW_checkconfig(lua_State *L, int index)
Converts an optional table or vconfig to a config object.
bool luaW_toconfig(lua_State *L, int index, config &cfg)
Converts an optional table or vconfig to a config object.
void line(int from_x, int from_y, int to_x, int to_y)
Draw a line.
void push_function(lua_State *L, const lua_function &f)
Pushes a std::function wrapper object onto the stack.
int load_file(lua_State *L)
Loads a Lua file and pushes the contents on the stack.
std::string register_table(lua_State *L)
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Error used to report an error in a lua script or in the lua interpreter.
std::vector< plugins_manager::event > requests
static std::string get_string(enum_type key)
Converts a enum to its string equivalent.