Skip to content

Commit

Permalink
move config, vconfig, tstring and helper functions to lua_common
Browse files Browse the repository at this point in the history
Probably lua_common should be split up further, it's a bit
crowded
  • Loading branch information
cbeck88 committed Nov 25, 2014
1 parent b1be437 commit 7e3b4aa
Show file tree
Hide file tree
Showing 8 changed files with 383 additions and 371 deletions.
1 change: 1 addition & 0 deletions src/ai/lua/lua_object.hpp
Expand Up @@ -26,6 +26,7 @@
#include "../../map_location.hpp"
#include "../../resources.hpp"
#include "../../scripting/lua_api.hpp"
#include "../../scripting/lua_common.hpp"
#include "../../terrain_filter.hpp"
#include "../../variable.hpp"
#include "../default/contexts.hpp"
Expand Down
1 change: 1 addition & 0 deletions src/scripting/application_lua_kernel.cpp
Expand Up @@ -30,6 +30,7 @@
#include "log.hpp"
#include "lua/lua.h"
#include "scripting/lua_api.hpp"
#include "scripting/lua_common.hpp"
#include "scripting/lua_game_launcher.hpp"
#include "scripting/lua_kernel_base.hpp"
#include "scripting/lua_types.hpp"
Expand Down
290 changes: 1 addition & 289 deletions src/scripting/lua_api.cpp
Expand Up @@ -26,6 +26,7 @@
#include "log.hpp"
#include "map_location.hpp" // for map_location
#include "resources.hpp"
#include "scripting/lua_common.hpp"
#include "tstring.hpp"
#include "unit.hpp"
#include "unit_map.hpp"
Expand All @@ -51,263 +52,6 @@ void chat_message(std::string const &caption, std::string const &msg)
events::chat_handler::MESSAGE_PUBLIC, false);
}

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);
}

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);
}


namespace {
struct luaW_pushscalar_visitor : boost::static_visitor<>
{
lua_State *L;
luaW_pushscalar_visitor(lua_State *l): L(l) {}

void operator()(boost::blank const &) const
{ lua_pushnil(L); }
void operator()(bool b) const
{ lua_pushboolean(L, b); }
void operator()(int i) const
{ lua_pushinteger(L, i); }
void operator()(unsigned long long ull) const
{ lua_pushnumber(L, ull); }
void operator()(double d) const
{ lua_pushnumber(L, d); }
void operator()(std::string const &s) const
{ lua_pushstring(L, s.c_str()); }
void operator()(t_string const &s) const
{ luaW_pushtstring(L, s); }
};
}//unnamed namespace for luaW_pushscalar_visitor

void luaW_pushscalar(lua_State *L, config::attribute_value const &v)
{
v.apply_visitor(luaW_pushscalar_visitor(L));
}

bool luaW_hasmetatable(lua_State *L
, int index
, luatypekey key)
{
if (!lua_getmetatable(L, index))
return false;
lua_pushlightuserdata(L, key);
lua_rawget(L, LUA_REGISTRYINDEX);
bool ok = lua_rawequal(L, -1, -2) == 1;
lua_pop(L, 2);
return ok;
}

bool luaW_totstring(lua_State *L, int index, t_string &str)
{
switch (lua_type(L, index)) {
case LUA_TBOOLEAN:
str = lua_toboolean(L, index) ? "yes" : "no";
break;
case LUA_TNUMBER:
case LUA_TSTRING:
str = lua_tostring(L, index);
break;
case LUA_TUSERDATA:
{
if (!luaW_hasmetatable(L, index, tstringKey)) return false;
str = *static_cast<t_string *>(lua_touserdata(L, index));
break;
}
default:
return false;
}
return true;
}

t_string luaW_checktstring(lua_State *L, int index)
{
t_string result;
if (!luaW_totstring(L, index, result))
luaL_typerror(L, index, "translatable string");
return result;
}

void luaW_filltable(lua_State *L, config const &cfg)
{
if (!lua_checkstack(L, LUA_MINSTACK))
return;

int k = 1;
BOOST_FOREACH(const config::any_child &ch, cfg.all_children_range())
{
lua_createtable(L, 2, 0);
lua_pushstring(L, ch.key.c_str());
lua_rawseti(L, -2, 1);
lua_newtable(L);
luaW_filltable(L, ch.cfg);
lua_rawseti(L, -2, 2);
lua_rawseti(L, -2, k++);
}
BOOST_FOREACH(const config::attribute &attr, cfg.attribute_range())
{
luaW_pushscalar(L, attr.second);
lua_setfield(L, -2, attr.first.c_str());
}
}

void luaW_pushconfig(lua_State *L, config const &cfg)
{
lua_newtable(L);
luaW_filltable(L, 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)
{
if (!lua_checkstack(L, LUA_MINSTACK))
return false;

// Get the absolute index of the table.
int initial_top = lua_gettop(L);
if (-initial_top <= index && index <= -1)
index = initial_top + index + 1;

switch (lua_type(L, index))
{
case LUA_TTABLE:
break;
case LUA_TUSERDATA:
{
if (!luaW_hasmetatable(L, index, vconfigKey))
return false;
cfg = static_cast<vconfig *>(lua_touserdata(L, index))->get_parsed_config();
return true;
}
case LUA_TNONE:
case LUA_TNIL:
return true;
default:
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)
{
lua_rawgeti(L, index, i);
if (!lua_istable(L, -1)) return_misformed();
lua_rawgeti(L, -1, 1);
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))
return_misformed();
lua_pop(L, 3);
}

// Then convert the attributes (string indices).
for (lua_pushnil(L); lua_next(L, index); lua_pop(L, 1))
{
if (lua_isnumber(L, -2)) continue;
if (!lua_isstring(L, -2)) return_misformed();
config::attribute_value &v = cfg[lua_tostring(L, -2)];
switch (lua_type(L, -1)) {
case LUA_TBOOLEAN:
v = luaW_toboolean(L, -1);
break;
case LUA_TNUMBER:
v = lua_tonumber(L, -1);
break;
case LUA_TSTRING:
v = lua_tostring(L, -1);
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<t_string *>(lua_touserdata(L, -1));
break;
}
default:
return_misformed();
}
}

lua_settop(L, initial_top);
return true;
}

#undef return_misformed


config luaW_checkconfig(lua_State *L, int index)
{
config result;
if (!luaW_toconfig(L, index, result))
luaL_typerror(L, index, "WML table");
return result;
}

bool luaW_tovconfig(lua_State *L, int index, vconfig &vcfg)
{
switch (lua_type(L, index))
{
case LUA_TTABLE:
{
config cfg;
bool ok = luaW_toconfig(L, index, cfg);
if (!ok) return false;
vcfg = vconfig(cfg, true);
break;
}
case LUA_TUSERDATA:
if (!luaW_hasmetatable(L, index, vconfigKey))
return false;
vcfg = *static_cast<vconfig *>(lua_touserdata(L, index));
break;
case LUA_TNONE:
case LUA_TNIL:
break;
default:
return false;
}
return true;
}

vconfig luaW_checkvconfig(lua_State *L, int index, bool allow_missing)
{
vconfig result = vconfig::unconstructed_vconfig();
if (!luaW_tovconfig(L, index, result) || (!allow_missing && result.null()))
luaL_typerror(L, index, "WML table");
return result;
}

#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable: 4706)
Expand Down Expand Up @@ -366,34 +110,6 @@ bool luaW_pcall(lua_State *L
return true;
}


#ifdef __GNUC__
__attribute__((sentinel))
#endif
bool luaW_getglobal(lua_State *L, ...)
{
lua_pushglobaltable(L);
va_list ap;
va_start(ap, L);
while (const char *s = va_arg(ap, const char *))
{
if (!lua_istable(L, -1)) goto discard;
lua_pushstring(L, s);
lua_rawget(L, -2);
lua_remove(L, -2);
}

if (lua_isnil(L, -1)) {
discard:
va_end(ap);
lua_pop(L, 1);
return false;
}
va_end(ap);
return true;
}


lua_unit::~lua_unit()
{
}
Expand Down Expand Up @@ -468,7 +184,3 @@ unit_ptr luaW_checkunit(lua_State *L, int index, bool only_on_map)
return u;
}

bool luaW_toboolean(lua_State *L, int n)
{
return lua_toboolean(L,n) != 0;
}

0 comments on commit 7e3b4aa

Please sign in to comment.