50 #include <boost/range/adaptors.hpp>
57 #define DBG_LUA LOG_STREAM(debug, log_scripting_lua)
58 #define LOG_LUA LOG_STREAM(info, log_scripting_lua)
59 #define WRN_LUA LOG_STREAM(warn, log_scripting_lua)
60 #define ERR_LUA LOG_STREAM(err, log_scripting_lua)
65 lua_getglobal(L,
"print");
69 std::stringstream
line;
79 lua_pushstring(L,
line.str().c_str());
83 lua_pushstring(L,
"No plugins available.\n");
91 unsigned int delay =
static_cast<unsigned int>(luaL_checkinteger(L, 1));
99 lua_getglobal(
mState,
"wesnoth");
101 lua_setfield(
mState, -2,
"delay");
106 lua_setglobal(
mState,
"describe_plugins");
118 if (lua_status(T_) == LUA_OK) {
119 return "not started";
124 switch (lua_status(T_)) {
135 return started_ ? (lua_status(T_) == LUA_YIELD) : (lua_status(T_) == LUA_OK);
147 lua_rawget(L, LUA_REGISTRYINDEX);
148 if (!lua_istable(L,-1)) {
153 lua_pushinteger(L, lua_rawlen(L, -1) + 1);
155 lua_State * T = lua_newthread(L);
159 lua_rawset(L, LUA_REGISTRYINDEX);
169 DBG_LUA <<
"created thread: status = " << lua_status(T) << (lua_status(T) == LUA_OK ?
" == OK" :
" == ?");
170 DBG_LUA <<
"loading script from string:\n<<\n" << prog <<
"\n>>";
173 int errcode = luaL_loadstring(T, prog.c_str());
174 if (errcode != LUA_OK) {
175 const char * err_str = lua_tostring(T, -1);
176 std::string
msg = err_str ? err_str :
"null string";
178 std::string context =
"When parsing a string to a lua thread, ";
180 if (errcode == LUA_ERRSYNTAX) {
181 context +=
" a syntax error";
182 }
else if(errcode == LUA_ERRMEM){
183 context +=
" a memory error";
185 context +=
" an unknown error";
191 throw game::lua_error(
"Error when executing a script to make a lua thread.");
193 if (!lua_isfunction(T, -1)) {
194 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)) );
205 lua_pushstring(T, file.c_str());
208 throw game::lua_error(
"Error when executing a file to make a lua thread.");
210 if (!lua_isfunction(T, -1)) {
211 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)) );
227 static int impl_context_backend(lua_State * L, std::shared_ptr<lua_context_backend> backend, std::string req_name)
229 if (!backend->valid) {
230 luaL_error(L ,
"Error, you tried to use an invalid context object in a lua thread");
237 backend->requests.push_back(evt);
243 if (!backend->valid) {
244 luaL_error(L ,
"Error, you tried to use an invalid context object in a lua thread");
250 luaL_argerror(L, 1,
"Error, tried to parse a config but some fields were invalid");
268 for (std::size_t
i = 0;
i < queue.size(); ++
i) {
270 lua_pushstring(T_, queue[
i].name.c_str());
271 lua_rawseti(T_, -2, 1);
273 lua_rawseti(T_, -2, 2);
274 lua_rawseti(T_, -2,
i+1);
278 auto this_context_backend = std::make_shared<lua_context_backend>();
280 for (
const std::string & key : ctxt.
callbacks_ | boost::adaptors::map_keys ) {
281 lua_pushstring(T_, key.c_str());
283 lua_settable(T_, -3);
288 lua_pushstring(T_,
"name");
289 lua_pushstring(T_, ctxt.
name_.c_str());
290 lua_settable(T_, -3);
291 for (
const plugins_context::accessor_list::value_type & v : ctxt.
accessors_) {
292 const std::string & key = v.first;
294 lua_pushstring(T_, key.c_str());
296 lua_settable(T_, -3);
301 lua_resume(T_,
nullptr, 3, &numres);
305 this_context_backend->valid =
false;
307 if (lua_status(T_) != LUA_YIELD) {
308 LOG_LUA <<
"Thread status = '" << lua_status(T_) <<
"'";
309 if (lua_status(T_) != LUA_OK) {
310 std::stringstream ss;
311 ss <<
"encountered a";
312 switch(lua_status(T_)) {
320 ss <<
" error-handler ";
326 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()
Definitions for the interface to Wesnoth Markup Language (WML).
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.