Added visitors for converting config attributes.
(Partial fix for bug #16363.) This brings the profile footprint of pushing units to Lua tables from 15% to 5%.
This commit is contained in:
parent
ac99cc5f9d
commit
419cf84a9d
3 changed files with 49 additions and 7 deletions
|
@ -113,15 +113,28 @@ double config::attribute_value::to_double(double def) const
|
|||
return def;
|
||||
}
|
||||
|
||||
struct config_attribute_str_visitor : boost::static_visitor<std::string>
|
||||
{
|
||||
std::string operator()(boost::blank const &) const
|
||||
{ return std::string(); }
|
||||
std::string operator()(bool b) const
|
||||
{
|
||||
static std::string s_yes("yes"), s_no("no");
|
||||
return b ? s_yes : s_no;
|
||||
}
|
||||
std::string operator()(int i) const
|
||||
{ return str_cast(i); }
|
||||
std::string operator()(double d) const
|
||||
{ return str_cast(d); }
|
||||
std::string operator()(std::string const &s) const
|
||||
{ return s; }
|
||||
std::string operator()(t_string const &s) const
|
||||
{ return s.str(); }
|
||||
};
|
||||
|
||||
std::string config::attribute_value::str() const
|
||||
{
|
||||
static std::string s_yes("yes"), s_no("no");
|
||||
if (const std::string *p = boost::get<const std::string>(&value)) return *p;
|
||||
if (const t_string *p = boost::get<const t_string>(&value)) return p->str();
|
||||
if (const bool *p = boost::get<const bool>(&value)) return *p ? s_yes : s_no;
|
||||
if (const int *p = boost::get<const int>(&value)) return str_cast(*p);
|
||||
if (const double *p = boost::get<const double>(&value)) return str_cast(*p);
|
||||
return std::string();
|
||||
return boost::apply_visitor(config_attribute_str_visitor(), value);
|
||||
}
|
||||
|
||||
t_string config::attribute_value::t_str() const
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
typedef std::map<std::string, t_string> string_map;
|
||||
|
||||
class config;
|
||||
struct lua_State;
|
||||
|
||||
bool operator==(const config &, const config &);
|
||||
inline bool operator!=(const config &a, const config &b) { return !operator==(a, b); }
|
||||
|
@ -199,6 +200,7 @@ public:
|
|||
{ return !operator==(other); }
|
||||
|
||||
friend std::ostream& operator<<(std::ostream &os, const attribute_value &v);
|
||||
friend void luaW_pushscalar(lua_State *, const attribute_value &);
|
||||
};
|
||||
|
||||
typedef std::map<std::string, attribute_value> attribute_map;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
#include "scripting/lua.hpp"
|
||||
#include "scripting/lua_api.hpp"
|
||||
|
@ -138,6 +139,32 @@ static void luaW_pushtstring(lua_State *L, t_string const &v)
|
|||
lua_setmetatable(L, -2);
|
||||
}
|
||||
|
||||
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()(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); }
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a string into a Lua object pushed at the top of the stack.
|
||||
*/
|
||||
void luaW_pushscalar(lua_State *L, config::attribute_value const &v)
|
||||
{
|
||||
boost::apply_visitor(luaW_pushscalar_visitor(L), v.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string into a Lua object pushed at the top of the stack.
|
||||
* Boolean ("yes"/"no") and numbers are detected and typed accordingly.
|
||||
|
|
Loading…
Add table
Reference in a new issue