Skip to content

Commit

Permalink
add access to tables via unit.variables
Browse files Browse the repository at this point in the history
unit.variables now uses the same functionality as
wesnoth.get/set_variable (just for the unit variable instead of the game
variables) which makes it possible to access table values. Its also
posible to access subvariables as
unit.variables["list1[2].list2.length"]
  • Loading branch information
gfgtdf committed Oct 8, 2015
1 parent f224e2a commit a77fada
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 86 deletions.
94 changes: 8 additions & 86 deletions src/scripting/game_lua_kernel.cpp
Expand Up @@ -454,8 +454,9 @@ static int impl_unit_variables_get(lua_State *L)
if (!u) return luaL_argerror(L, 1, "unknown unit");
char const *m = luaL_checkstring(L, 2);
return_cfgref_attrib("__cfg", u->variables());
luaW_pushscalar(L, u->variables()[m]);
return 1;

variable_access_const v(m, u->variables());
return LuaW_pushvariable(L, v) ? 1 : 0;
}
/**
* Gets the attacks of a unit (__index metamethod).
Expand Down Expand Up @@ -652,29 +653,8 @@ static int impl_unit_variables_set(lua_State *L)
u->variables() = luaW_checkconfig(L, 3);
return 0;
}
config::attribute_value &v = u->variables()[m];
switch (lua_type(L, 3)) {
case LUA_TNIL:
u->variables().remove_attribute(m);
break;
case LUA_TBOOLEAN:
v = luaW_toboolean(L, 3);
break;
case LUA_TNUMBER:
v = lua_tonumber(L, 3);
break;
case LUA_TSTRING:
v = lua_tostring(L, 3);
break;
case LUA_TUSERDATA:
if (t_string * t_str = static_cast<t_string *> (luaL_testudata(L, 3, tstringKey))) {
v = *t_str;
break;
}
// no break
default:
return luaL_typerror(L, 3, "WML scalar");
}
variable_access_create v(m, u->variables());
LuaW_checkvariable(L, v, 3);
return 0;
}

Expand Down Expand Up @@ -988,30 +968,7 @@ int game_lua_kernel::intf_get_variable(lua_State *L)
{
char const *m = luaL_checkstring(L, 1);
variable_access_const v = gamedata().get_variable_access_read(m);
try
{
if(v.exists_as_attribute())
{
luaW_pushscalar(L, v.as_scalar());
return 1;
}
else if(v.exists_as_container())
{
lua_newtable(L);
if (luaW_toboolean(L, 2))
luaW_filltable(L, v.as_container());
return 1;
}
else
{
return 0;
}
}
catch (const invalid_variablename_exception&)
{
//TODO: pop table
return 0;
}
return LuaW_pushvariable(L, v) ? 1 : 0;
}

/**
Expand All @@ -1027,43 +984,8 @@ int game_lua_kernel::intf_set_variable(lua_State *L)
gamedata().clear_variable(m);
return 0;
}
int variabletype = lua_type(L, 2);
try
{
variable_access_create v = gamedata().get_variable_access_write(m);
switch (variabletype) {
case LUA_TBOOLEAN:
v.as_scalar() = luaW_toboolean(L, 2);
break;
case LUA_TNUMBER:
v.as_scalar() = lua_tonumber(L, 2);
break;
case LUA_TSTRING:
v.as_scalar() = lua_tostring(L, 2);
break;
case LUA_TUSERDATA:
if (t_string * t_str = static_cast<t_string*> (luaL_testudata(L, 2, tstringKey))) {
v.as_scalar() = *t_str;
break;
}
// no break
case LUA_TTABLE:
{
config &cfg = v.as_container();
cfg.clear();
if (luaW_toconfig(L, 2, cfg))
break;
// no break
}
default:
return luaL_typerror(L, 2, "WML table or scalar");
}
}
catch (const invalid_variablename_exception&)
{
std::string msg = "invalid variable name '" + m + "' for type '" + lua_typename(L, variabletype) + "'";
return luaL_argerror(L, 1, msg.c_str());
}
variable_access_create v = gamedata().get_variable_access_write(m);
LuaW_checkvariable(L, v, 2);
return 0;
}

Expand Down
77 changes: 77 additions & 0 deletions src/scripting/lua_common.cpp
Expand Up @@ -30,6 +30,7 @@
#include "scripting/lua_types.hpp" // for gettextKey, tstringKey, etc
#include "tstring.hpp" // for t_string
#include "variable.hpp" // for vconfig
#include "log.hpp"

#include <boost/foreach.hpp>
#include <cstring>
Expand All @@ -46,6 +47,11 @@ static const char * vconfigpairsKey = "vconfig pairs";
static const char * vconfigipairsKey = "vconfig ipairs";
const char * tstringKey = "translatable string";

static lg::log_domain log_scripting_lua("scripting/lua");
#define LOG_LUA LOG_STREAM(info, log_scripting_lua)
#define WRN_LUA LOG_STREAM(warn, log_scripting_lua)
#define ERR_LUA LOG_STREAM(err, log_scripting_lua)

namespace lua_common {

/**
Expand Down Expand Up @@ -697,3 +703,74 @@ bool luaW_toboolean(lua_State *L, int n)
{
return lua_toboolean(L,n) != 0;
}

bool LuaW_pushvariable(lua_State *L, variable_access_const& v)
{
try
{
if(v.exists_as_attribute())
{
luaW_pushscalar(L, v.as_scalar());
return true;
}
else if(v.exists_as_container())
{
lua_newtable(L);
if (luaW_toboolean(L, 2))
luaW_filltable(L, v.as_container());
return true;
}
else
{
return false;
}
}
catch (const invalid_variablename_exception&)
{
WRN_LUA << v.get_error_message();
return false;
}
}

bool LuaW_checkvariable(lua_State *L, variable_access_create& v, int n)
{
int variabletype = lua_type(L, n);
try
{
switch (variabletype) {
case LUA_TBOOLEAN:
v.as_scalar() = luaW_toboolean(L, n);
return true;
case LUA_TNUMBER:
v.as_scalar() = lua_tonumber(L, n);
return true;
case LUA_TSTRING:
v.as_scalar() = lua_tostring(L, n);
return true;
case LUA_TUSERDATA:
if (t_string * t_str = static_cast<t_string*> (luaL_testudata(L, n, tstringKey))) {
v.as_scalar() = *t_str;
return true;
}
goto default_explicit;
case LUA_TTABLE:
{
config &cfg = v.as_container();
cfg.clear();
if (luaW_toconfig(L, n, cfg)) {
return true;
}
// no break
}
default:
default_explicit:
return luaL_typerror(L, n, "WML table or scalar") != 0;

}
}
catch (const invalid_variablename_exception&)
{
WRN_LUA << v.get_error_message() << " when attempting to write a '" << lua_typename(L, variabletype) << "'\n";
return false;
}
}
7 changes: 7 additions & 0 deletions src/scripting/lua_common.hpp
Expand Up @@ -26,6 +26,7 @@ class vconfig;

#include "config.hpp"
#include "scripting/lua_types.hpp"
#include "variable_info.hpp"

namespace lua_common {
int intf_textdomain(lua_State *L);
Expand Down Expand Up @@ -117,6 +118,12 @@ bool luaW_getglobal(lua_State *L, ...);

bool luaW_toboolean(lua_State *L, int n);


bool LuaW_pushvariable(lua_State *L, variable_access_const& v);

bool LuaW_checkvariable(lua_State *L, variable_access_create& v, int n);


#define return_tstring_attrib(name, accessor) \
if (strcmp(m, name) == 0) { \
luaW_pushtstring(L, accessor); \
Expand Down

0 comments on commit a77fada

Please sign in to comment.