diff --git a/src/scripting/game_lua_kernel.cpp b/src/scripting/game_lua_kernel.cpp index 0ca4b57c3dff..27d6cffeae46 100644 --- a/src/scripting/game_lua_kernel.cpp +++ b/src/scripting/game_lua_kernel.cpp @@ -483,8 +483,8 @@ static int impl_unit_variables_set(lua_State *L) v = lua_tostring(L, 3); break; case LUA_TUSERDATA: - if (luaW_hasmetatable(L, 3, tstringKey)) { - v = *static_cast(lua_touserdata(L, 3)); + if (t_string * t_str = static_cast (luaL_testudata(L, 3, tstringKey))) { + v = *t_str; break; } // no break @@ -777,8 +777,8 @@ int game_lua_kernel::intf_set_variable(lua_State *L) v.as_scalar() = lua_tostring(L, 2); break; case LUA_TUSERDATA: - if (luaW_hasmetatable(L, 2, tstringKey)) { - v.as_scalar() = *static_cast(lua_touserdata(L, 2)); + if (t_string * t_str = static_cast (luaL_testudata(L, 2, tstringKey))) { + v.as_scalar() = *t_str; break; } // no break diff --git a/src/scripting/lua_common.cpp b/src/scripting/lua_common.cpp index 8b8c5c25f259..b6e88c330891 100644 --- a/src/scripting/lua_common.cpp +++ b/src/scripting/lua_common.cpp @@ -39,6 +39,10 @@ #include // for operator new #include // for string, basic_string +static const char * gettextKey = "gettext"; +static const char * vconfigKey = "vconfig"; +const char * tstringKey = "translatable string"; + namespace lua_common { /** @@ -65,13 +69,11 @@ int intf_textdomain(lua_State *L) { size_t l; char const *m = luaL_checklstring(L, 1, &l); + void *p = lua_newuserdata(L, l + 1); memcpy(p, m, l + 1); - lua_pushlightuserdata(L - , gettextKey); - lua_rawget(L, LUA_REGISTRYINDEX); - lua_setmetatable(L, -2); + luaL_setmetatable(L, gettextKey); return 1; } @@ -108,17 +110,12 @@ static int impl_tstring_concat(lua_State *L) { // Create a new t_string. t_string *t = new(lua_newuserdata(L, sizeof(t_string))) t_string; - - lua_pushlightuserdata(L - , tstringKey); - - lua_rawget(L, LUA_REGISTRYINDEX); + luaL_setmetatable(L, tstringKey); // Append both arguments to t. tstring_concat_aux(L, *t, 1); tstring_concat_aux(L, *t, 2); - lua_setmetatable(L, -2); return 1; } @@ -159,15 +156,11 @@ static int impl_vconfig_get(lua_State *L) unsigned pos = lua_tointeger(L, 2) - 1; if (pos >= len) return 0; std::advance(i, pos); + lua_createtable(L, 2, 0); lua_pushstring(L, i.get_key().c_str()); lua_rawseti(L, -2, 1); - new(lua_newuserdata(L, sizeof(vconfig))) vconfig(i.get_child()); - lua_pushlightuserdata(L - , vconfigKey); - - lua_rawget(L, LUA_REGISTRYINDEX); - lua_setmetatable(L, -2); + luaW_pushvconfig(L, vconfig(i.get_child())); lua_rawseti(L, -2, 2); return 1; } @@ -254,14 +247,16 @@ int intf_tovconfig(lua_State *L) */ std::string register_gettext_metatable(lua_State *L) { - lua_pushlightuserdata(L - , gettextKey); - lua_createtable(L, 0, 2); - lua_pushcfunction(L, lua_common::impl_gettext); - lua_setfield(L, -2, "__call"); + luaL_newmetatable(L, gettextKey); + + static luaL_Reg const callbacks[] = { + { "__call", &impl_gettext}, + { NULL, NULL } + }; + luaL_setfuncs(L, callbacks, 0); + lua_pushstring(L, "message domain"); lua_setfield(L, -2, "__metatable"); - lua_rawset(L, LUA_REGISTRYINDEX); return "Adding gettext metatable...\n"; } @@ -271,18 +266,18 @@ std::string register_gettext_metatable(lua_State *L) */ std::string register_tstring_metatable(lua_State *L) { - lua_pushlightuserdata(L - , tstringKey); - lua_createtable(L, 0, 4); - lua_pushcfunction(L, impl_tstring_concat); - lua_setfield(L, -2, "__concat"); - lua_pushcfunction(L, impl_tstring_collect); - lua_setfield(L, -2, "__gc"); - lua_pushcfunction(L, impl_tstring_tostring); - lua_setfield(L, -2, "__tostring"); + luaL_newmetatable(L, tstringKey); + + static luaL_Reg const callbacks[] = { + { "__concat", &impl_tstring_concat}, + { "__gc", &impl_tstring_collect}, + { "__tostring", &impl_tstring_tostring}, + { NULL, NULL } + }; + luaL_setfuncs(L, callbacks, 0); + lua_pushstring(L, "translatable string"); lua_setfield(L, -2, "__metatable"); - lua_rawset(L, LUA_REGISTRYINDEX); return "Adding tstring metatable...\n"; } @@ -292,18 +287,18 @@ std::string register_tstring_metatable(lua_State *L) */ std::string register_vconfig_metatable(lua_State *L) { - lua_pushlightuserdata(L - , vconfigKey); - lua_createtable(L, 0, 4); - lua_pushcfunction(L, impl_vconfig_collect); - lua_setfield(L, -2, "__gc"); - lua_pushcfunction(L, impl_vconfig_get); - lua_setfield(L, -2, "__index"); - lua_pushcfunction(L, impl_vconfig_size); - lua_setfield(L, -2, "__len"); + luaL_newmetatable(L, vconfigKey); + + static luaL_Reg const callbacks[] = { + { "__gc", &impl_vconfig_collect}, + { "__index", &impl_vconfig_get}, + { "__len", &impl_vconfig_size}, + { NULL, NULL } + }; + luaL_setfuncs(L, callbacks, 0); + lua_pushstring(L, "wml object"); lua_setfield(L, -2, "__metatable"); - lua_rawset(L, LUA_REGISTRYINDEX); return "Adding vconfig metatable...\n"; } @@ -313,21 +308,13 @@ std::string register_vconfig_metatable(lua_State *L) void luaW_pushvconfig(lua_State *L, vconfig const &cfg) { new(lua_newuserdata(L, sizeof(vconfig))) vconfig(cfg); - lua_pushlightuserdata(L - , vconfigKey); - - lua_rawget(L, LUA_REGISTRYINDEX); - lua_setmetatable(L, -2); + luaL_setmetatable(L, vconfigKey); } void luaW_pushtstring(lua_State *L, t_string const &v) { new(lua_newuserdata(L, sizeof(t_string))) t_string(v); - lua_pushlightuserdata(L - , tstringKey); - - lua_rawget(L, LUA_REGISTRYINDEX); - lua_setmetatable(L, -2); + luaL_setmetatable(L, tstringKey); } @@ -384,9 +371,12 @@ bool luaW_totstring(lua_State *L, int index, t_string &str) break; case LUA_TUSERDATA: { - if (!luaW_hasmetatable(L, index, tstringKey)) return false; - str = *static_cast(lua_touserdata(L, index)); - break; + if (t_string * tstr = static_cast (luaL_checkudata(L, index, tstringKey))) { + str = *tstr; + break; + } else { + return false; + } } default: return false; @@ -437,7 +427,7 @@ void luaW_pushconfig(lua_State *L, config const &cfg) #define return_misformed() \ do { lua_settop(L, initial_top); return false; } while (0) -bool luaW_toconfig(lua_State *L, int index, config &cfg, int tstring_meta) +bool luaW_toconfig(lua_State *L, int index, config &cfg) { if (!lua_checkstack(L, LUA_MINSTACK)) return false; @@ -453,10 +443,12 @@ bool luaW_toconfig(lua_State *L, int index, config &cfg, int tstring_meta) break; case LUA_TUSERDATA: { - if (!luaW_hasmetatable(L, index, vconfigKey)) + if (vconfig * ptr = static_cast (luaL_checkudata(L, index, vconfigKey))) { + cfg = ptr->get_parsed_config(); + return true; + } else { return false; - cfg = static_cast(lua_touserdata(L, index))->get_parsed_config(); - return true; + } } case LUA_TNONE: case LUA_TNIL: @@ -465,15 +457,6 @@ bool luaW_toconfig(lua_State *L, int index, config &cfg, int tstring_meta) return false; } - // Get t_string's metatable, so that it can be used later to detect t_string object. - if (!tstring_meta) { - lua_pushlightuserdata(L - , tstringKey); - - lua_rawget(L, LUA_REGISTRYINDEX); - tstring_meta = initial_top + 1; - } - // First convert the children (integer indices). for (int i = 1, i_end = lua_rawlen(L, index); i <= i_end; ++i) { @@ -483,7 +466,7 @@ bool luaW_toconfig(lua_State *L, int index, config &cfg, int tstring_meta) char const *m = lua_tostring(L, -1); if (!m) return_misformed(); lua_rawgeti(L, -2, 2); - if (!luaW_toconfig(L, -1, cfg.add_child(m), tstring_meta)) + if (!luaW_toconfig(L, -1, cfg.add_child(m))) return_misformed(); lua_pop(L, 3); } @@ -506,12 +489,12 @@ bool luaW_toconfig(lua_State *L, int index, config &cfg, int tstring_meta) break; case LUA_TUSERDATA: { - if (!lua_getmetatable(L, -1)) return_misformed(); - bool tstr = lua_rawequal(L, -1, tstring_meta) != 0; - lua_pop(L, 1); - if (!tstr) return_misformed(); - v = *static_cast(lua_touserdata(L, -1)); - break; + if (t_string * tptr = static_cast(luaL_testudata(L, -1, tstringKey))) { + v = *tptr; + break; + } else { + return_misformed(); + } } default: return_misformed(); @@ -546,10 +529,11 @@ bool luaW_tovconfig(lua_State *L, int index, vconfig &vcfg) break; } case LUA_TUSERDATA: - if (!luaW_hasmetatable(L, index, vconfigKey)) + if (vconfig * ptr = static_cast (luaL_testudata(L, index, vconfigKey))) { + vcfg = *ptr; + } else { return false; - vcfg = *static_cast(lua_touserdata(L, index)); - break; + } case LUA_TNONE: case LUA_TNIL: break; diff --git a/src/scripting/lua_common.hpp b/src/scripting/lua_common.hpp index c53a3dbbdc98..750103ae7519 100644 --- a/src/scripting/lua_common.hpp +++ b/src/scripting/lua_common.hpp @@ -34,7 +34,9 @@ namespace lua_common { std::string register_gettext_metatable(lua_State *L); std::string register_tstring_metatable(lua_State *L); std::string register_vconfig_metatable(lua_State *L); + } +extern const char * tstringKey; /** * Pushes a vconfig on the top of the stack. @@ -86,7 +88,7 @@ void luaW_pushconfig(lua_State *L, config const &cfg); * @note If the table has holes in the integer keys or floating-point keys, * some keys will be ignored and the error will go undetected. */ -bool luaW_toconfig(lua_State *L, int index, config &cfg, int tstring_meta = 0); +bool luaW_toconfig(lua_State *L, int index, config &cfg); /** * Converts an optional table or vconfig to a config object. diff --git a/src/scripting/lua_gui2.cpp b/src/scripting/lua_gui2.cpp index 5744f2c73c5c..4933ba35221b 100644 --- a/src/scripting/lua_gui2.cpp +++ b/src/scripting/lua_gui2.cpp @@ -54,6 +54,8 @@ static lg::log_domain log_scripting_lua("scripting/lua"); #define ERR_LUA LOG_STREAM(err, log_scripting_lua) +static const char * dlgclbkKey = "dialog callback"; + namespace { struct scoped_dialog { @@ -75,7 +77,7 @@ namespace { scoped_dialog::scoped_dialog(lua_State *l, gui2::twindow *w) : L(l), prev(current), window(w), callbacks() { - lua_pushlightuserdata(L + lua_pushstring(L , dlgclbkKey); lua_createtable(L, 1, 0); lua_pushvalue(L, -2); @@ -89,7 +91,7 @@ namespace { { delete window; current = prev; - lua_pushlightuserdata(L + lua_pushstring(L , dlgclbkKey); lua_pushvalue(L, -1); lua_rawget(L, LUA_REGISTRYINDEX); @@ -305,7 +307,7 @@ namespace { // helpers of intf_set_dialog_callback() cb = i->second; } lua_State *L = scoped_dialog::current->L; - lua_pushlightuserdata(L + lua_pushstring(L , dlgclbkKey); lua_rawget(L, LUA_REGISTRYINDEX); lua_rawgeti(L, -1, cb); @@ -337,7 +339,7 @@ int intf_set_dialog_callback(lua_State *L) scoped_dialog::callback_map::iterator i = m.find(w); if (i != m.end()) { - lua_pushlightuserdata(L + lua_pushstring(L , dlgclbkKey); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushnil(L); @@ -374,7 +376,7 @@ int intf_set_dialog_callback(lua_State *L) else return luaL_argerror(L, lua_gettop(L), "unsupported widget"); - lua_pushlightuserdata(L + lua_pushstring(L , dlgclbkKey); lua_rawget(L, LUA_REGISTRYINDEX); int n = lua_rawlen(L, -1) + 1; diff --git a/src/scripting/lua_types.cpp b/src/scripting/lua_types.cpp index 340cd1677af1..66320d6dfa05 100644 --- a/src/scripting/lua_types.cpp +++ b/src/scripting/lua_types.cpp @@ -15,29 +15,21 @@ #include "lua_types.hpp" /* Dummy pointer for getting unique keys for Lua's registry. */ -static char const v_dlgclbkKey = 0; static char const v_executeKey = 0; static char const v_getsideKey = 0; -static char const v_gettextKey = 0; static char const v_gettypeKey = 0; static char const v_getraceKey = 0; static char const v_getunitKey = 0; -static char const v_tstringKey = 0; static char const v_unitvarKey = 0; static char const v_ustatusKey = 0; -static char const v_vconfigKey = 0; static char const v_currentscriptKey = 0; -luatypekey const dlgclbkKey = static_cast(const_cast(&v_dlgclbkKey)); luatypekey const executeKey = static_cast(const_cast(&v_executeKey)); luatypekey const getsideKey = static_cast(const_cast(&v_getsideKey)); -luatypekey const gettextKey = static_cast(const_cast(&v_gettextKey)); luatypekey const gettypeKey = static_cast(const_cast(&v_gettypeKey)); luatypekey const getraceKey = static_cast(const_cast(&v_getraceKey)); luatypekey const getunitKey = static_cast(const_cast(&v_getunitKey)); -luatypekey const tstringKey = static_cast(const_cast(&v_tstringKey)); luatypekey const unitvarKey = static_cast(const_cast(&v_unitvarKey)); luatypekey const ustatusKey = static_cast(const_cast(&v_ustatusKey)); -luatypekey const vconfigKey = static_cast(const_cast(&v_vconfigKey)); luatypekey const currentscriptKey = static_cast(const_cast(&v_currentscriptKey)); diff --git a/src/scripting/lua_types.hpp b/src/scripting/lua_types.hpp index a3a9b3d2b5d7..5cf905588b5b 100644 --- a/src/scripting/lua_types.hpp +++ b/src/scripting/lua_types.hpp @@ -19,17 +19,13 @@ typedef void* luatypekey; // i dont want to cast to void* each time .... // a drawback is, that these are now normal static variables wich are initialised at initialisation time (so you shoudn't use these at/before initialisation time). -extern luatypekey const dlgclbkKey; extern luatypekey const executeKey; extern luatypekey const getsideKey; -extern luatypekey const gettextKey; extern luatypekey const gettypeKey; extern luatypekey const getraceKey; extern luatypekey const getunitKey; -extern luatypekey const tstringKey; extern luatypekey const unitvarKey; extern luatypekey const ustatusKey; -extern luatypekey const vconfigKey; extern luatypekey const currentscriptKey; #endif