Skip to content

Commit

Permalink
add game_data::get_variable_accesss method.
Browse files Browse the repository at this point in the history
  • Loading branch information
gfgtdf committed Jun 29, 2014
1 parent 02b20dd commit 16938d3
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 57 deletions.
42 changes: 36 additions & 6 deletions src/game_data.cpp
Expand Up @@ -113,12 +113,12 @@ game_data::game_data(const game_data& data)

config::attribute_value &game_data::get_variable(const std::string& key)
{
return variable_info(key, true, variable_info::TYPE_SCALAR).as_scalar();
return get_variable_access(key, true, variable_info::TYPE_SCALAR).as_scalar();
}

config::attribute_value game_data::get_variable_const(const std::string &key) const
{
variable_info to_get(key, false, variable_info::TYPE_SCALAR);
variable_info to_get = get_variable_access(key, false, variable_info::TYPE_SCALAR);
if (!to_get.is_valid)
{
config::attribute_value &to_return = temporaries_[key];
Expand All @@ -133,7 +133,7 @@ config::attribute_value game_data::get_variable_const(const std::string &key) co

config& game_data::get_variable_cfg(const std::string& key)
{
return variable_info(key, true, variable_info::TYPE_CONTAINER).as_container();
return get_variable_access(key, true, variable_info::TYPE_CONTAINER).as_container();
}

void game_data::set_variable(const std::string& key, const t_string& value)
Expand All @@ -143,13 +143,13 @@ void game_data::set_variable(const std::string& key, const t_string& value)

config& game_data::add_variable_cfg(const std::string& key, const config& value)
{
variable_info to_add(key, true, variable_info::TYPE_ARRAY);
variable_info to_add = get_variable_access(key, true, variable_info::TYPE_ARRAY);
return to_add.vars->add_child(to_add.key, value);
}

void game_data::clear_variable_cfg(const std::string& varname)
{
variable_info to_clear(varname, false, variable_info::TYPE_CONTAINER);
variable_info to_clear = get_variable_access(varname, false, variable_info::TYPE_CONTAINER);
if(!to_clear.is_valid) return;
if(to_clear.explicit_index) {
to_clear.vars->remove_child(to_clear.key, to_clear.index);
Expand All @@ -160,7 +160,7 @@ void game_data::clear_variable_cfg(const std::string& varname)

void game_data::clear_variable(const std::string& varname)
{
variable_info to_clear(varname, false);
variable_info to_clear = get_variable_access(varname, false);
if(!to_clear.is_valid) return;
if(to_clear.explicit_index) {
to_clear.vars->remove_child(to_clear.key, to_clear.index);
Expand Down Expand Up @@ -234,3 +234,33 @@ game_data* game_data::operator=(const game_data* info)
}
return this ;
}

namespace {
bool recursive_activation = false;

} // end anonymous namespace

void game_data::activate_scope_variable(std::string var_name) const
{

if(recursive_activation)
return;
const std::string::iterator itor = std::find(var_name.begin(),var_name.end(),'.');
if(itor != var_name.end()) {
var_name.erase(itor, var_name.end());
}
std::vector<scoped_wml_variable*>::const_reverse_iterator rit;
for(
rit = scoped_variables.rbegin();
rit != scoped_variables.rend();
++rit) {
if((**rit).name() == var_name) {
recursive_activation = true;
if(!(**rit).activated()) {
(**rit).activate();
}
recursive_activation = false;
break;
}
}
}
11 changes: 11 additions & 0 deletions src/game_data.hpp
Expand Up @@ -22,6 +22,7 @@
#include "game_events/wmi_container.hpp"
#include "map_location.hpp"
#include "simple_rng.hpp"
#include "variable.hpp"

#include <boost/shared_ptr.hpp>

Expand Down Expand Up @@ -58,6 +59,16 @@ class game_data : public variable_set {
void set_variable(const std::string& varname, const t_string& value);
config& add_variable_cfg(const std::string& varname, const config& value=config());

void activate_scope_variable(std::string var_name) const;

variable_info get_variable_access(const std::string& varname, bool force_valid=true,
variable_info::TYPE validation_type = variable_info::TYPE_UNSPECIFIED) const
{
assert(this != NULL);
activate_scope_variable(varname);
return variable_info(const_cast<config&>(variables_), varname, force_valid, validation_type);
}

void clear_variable(const std::string& varname);
void clear_variable_cfg(const std::string& varname); // Clears only the config children

Expand Down
12 changes: 6 additions & 6 deletions src/game_events/action_wml.cpp
Expand Up @@ -2047,7 +2047,7 @@ WML_HANDLER_FUNCTION(set_variable, /*event_info*/, cfg)

std::string joined_string;

variable_info vi(array_name, true, variable_info::TYPE_ARRAY);
variable_info vi = resources::gamedata->get_variable_access(array_name, true, variable_info::TYPE_ARRAY);
bool first = true;
BOOST_FOREACH(const config &cfg, vi.as_array())
{
Expand All @@ -2065,7 +2065,7 @@ WML_HANDLER_FUNCTION(set_variable, /*event_info*/, cfg)
WML_HANDLER_FUNCTION(set_variables, /*event_info*/, cfg)
{
const t_string& name = cfg["name"];
variable_info dest(name, true, variable_info::TYPE_CONTAINER);
variable_info dest = resources::gamedata->get_variable_access(name, true, variable_info::TYPE_CONTAINER);
if(name.empty()) {
ERR_NG << "trying to set a variable with an empty name:\n" << cfg.get_config().debug();
return;
Expand Down Expand Up @@ -2098,7 +2098,7 @@ WML_HANDLER_FUNCTION(set_variables, /*event_info*/, cfg)

if(cfg.has_attribute("to_variable"))
{
variable_info tovar(cfg["to_variable"], false, variable_info::TYPE_CONTAINER);
variable_info tovar = resources::gamedata->get_variable_access(cfg["to_variable"], false, variable_info::TYPE_CONTAINER);
if(tovar.is_valid) {
if(tovar.explicit_index) {
data.add_child(dest.key, tovar.as_container());
Expand Down Expand Up @@ -2222,7 +2222,7 @@ WML_HANDLER_FUNCTION(store_relative_dir, /*event_info*/, cfg)
std::string variable = cfg["variable"];
map_location::RELATIVE_DIR_MODE mode = static_cast<map_location::RELATIVE_DIR_MODE> (cfg["mode"].to_int(0));

variable_info store(variable, true, variable_info::TYPE_SCALAR );
variable_info store = resources::gamedata->get_variable_access(variable, true, variable_info::TYPE_SCALAR );

store.as_scalar() = map_location::write_direction(src.get_relative_dir(dst,mode));
}
Expand Down Expand Up @@ -2252,7 +2252,7 @@ WML_HANDLER_FUNCTION(store_rotate_map_location, /*event_info*/, cfg)
std::string variable = cfg["variable"];
int angle = cfg["angle"].to_int(1);

variable_info store(variable, true, variable_info::TYPE_CONTAINER );
variable_info store = resources::gamedata->get_variable_access(variable, true, variable_info::TYPE_CONTAINER );

dst.rotate_right_around_center(src,angle).write(store.as_container());
}
Expand All @@ -2273,7 +2273,7 @@ WML_HANDLER_FUNCTION(store_time_of_day, /*event_info*/, cfg)
variable = "time_of_day";
}

variable_info store(variable, true, variable_info::TYPE_CONTAINER);
variable_info store = resources::gamedata->get_variable_access(variable, true, variable_info::TYPE_CONTAINER);

tod.write(store.as_container());
}
Expand Down
6 changes: 3 additions & 3 deletions src/scripting/lua.cpp
Expand Up @@ -990,12 +990,12 @@ static int intf_fire_event(lua_State *L)
static int intf_get_variable(lua_State *L)
{
char const *m = luaL_checkstring(L, 1);
variable_info v(m, false, variable_info::TYPE_SCALAR);
variable_info v = resources::gamedata->get_variable_access(m, false, variable_info::TYPE_SCALAR);
if (v.is_valid) {
luaW_pushscalar(L, v.as_scalar());
return 1;
} else {
variable_info w(m, false, variable_info::TYPE_CONTAINER);
variable_info w = resources::gamedata->get_variable_access(m, false, variable_info::TYPE_CONTAINER);
if (w.is_valid) {
lua_newtable(L);
if (lua_toboolean(L, 2))
Expand All @@ -1020,7 +1020,7 @@ static int intf_set_variable(lua_State *L)
return 0;
}

variable_info v(m);
variable_info v = resources::gamedata->get_variable_access(m);
switch (lua_type(L, 2)) {
case LUA_TBOOLEAN:
v.as_scalar() = luaW_toboolean(L, 2);
Expand Down
11 changes: 6 additions & 5 deletions src/terrain_filter.cpp
Expand Up @@ -18,6 +18,7 @@

#include "config.hpp"
#include "game_board.hpp"
#include "game_data.hpp"
#include "log.hpp"
#include "map.hpp"
#include "resources.hpp"
Expand Down Expand Up @@ -130,7 +131,7 @@ bool terrain_filter::match_internal(const map_location& loc, const bool ignore_x
}
//allow filtering by searching a stored variable of locations
if(cfg_.has_attribute("find_in")) {
variable_info vi(cfg_["find_in"], false, variable_info::TYPE_CONTAINER);
variable_info vi = resources::gamedata->get_variable_access(cfg_["find_in"], false, variable_info::TYPE_CONTAINER);
if(!vi.is_valid) return false;
if(vi.explicit_index) {
if(map_location(vi.as_container(),NULL) != loc) {
Expand Down Expand Up @@ -415,7 +416,7 @@ void terrain_filter::get_locations(std::set<map_location>& locs, bool with_borde
&& !cfg_.has_attribute("area") ) {

//use content of find_in as starting set
variable_info vi(cfg_["find_in"], false, variable_info::TYPE_CONTAINER);
variable_info vi = resources::gamedata->get_variable_access(cfg_["find_in"], false, variable_info::TYPE_CONTAINER);
if(vi.is_valid) {
if(vi.explicit_index) {
map_location test_loc(vi.as_container(),NULL);
Expand Down Expand Up @@ -448,7 +449,7 @@ void terrain_filter::get_locations(std::set<map_location>& locs, bool with_borde
match_set.insert(xy_vector.begin(), xy_vector.end());

// remove any locations not found in the specified variable
variable_info vi(cfg_["find_in"], false, variable_info::TYPE_CONTAINER);
variable_info vi = resources::gamedata->get_variable_access(cfg_["find_in"], false, variable_info::TYPE_CONTAINER);
if(!vi.is_valid) {
match_set.clear();
} else if(vi.explicit_index) {
Expand Down Expand Up @@ -494,7 +495,7 @@ void terrain_filter::get_locations(std::set<map_location>& locs, bool with_borde
const std::set<map_location>& area = resources::tod_manager->get_area_by_id(cfg_["area"]);

//use content of find_in as starting set
variable_info vi(cfg_["find_in"], false, variable_info::TYPE_CONTAINER);
variable_info vi = resources::gamedata->get_variable_access(cfg_["find_in"], false, variable_info::TYPE_CONTAINER);
if(!vi.is_valid) {
match_set.clear(); //TODO not needed
} else if(vi.explicit_index) {
Expand Down Expand Up @@ -522,7 +523,7 @@ void terrain_filter::get_locations(std::set<map_location>& locs, bool with_borde
const std::set<map_location>& area = resources::tod_manager->get_area_by_id(cfg_["area"]);

//use content of find_in as starting set
variable_info vi(cfg_["find_in"], false, variable_info::TYPE_CONTAINER);
variable_info vi = resources::gamedata->get_variable_access(cfg_["find_in"], false, variable_info::TYPE_CONTAINER);
if(vi.is_valid) {
if(vi.explicit_index) {
map_location test_loc(vi.as_container(),NULL);
Expand Down
3 changes: 2 additions & 1 deletion src/unit.cpp
Expand Up @@ -22,6 +22,7 @@

#include "formula_string_utils.hpp" // for vgettext
#include "game_board.hpp" // for game_board
#include "game_data.hpp"
#include "game_config.hpp" // for add_color_info, etc
#include "game_errors.hpp" // for game_error
#include "game_events/handlers.hpp" // for add_events
Expand Down Expand Up @@ -1648,7 +1649,7 @@ bool unit::internal_matches_filter(const vconfig& cfg, const map_location& loc,
config::attribute_value cfg_find_in = cfg["find_in"];
if (!cfg_find_in.blank()) {
// Allow filtering by searching a stored variable of units
variable_info vi(cfg_find_in, false, variable_info::TYPE_CONTAINER);
variable_info vi = resources::gamedata->get_variable_access(cfg_find_in, false, variable_info::TYPE_CONTAINER);
if(!vi.is_valid) return false;
if(vi.explicit_index) {
config::const_child_iterator i = vi.vars->child_range(vi.key).first;
Expand Down
41 changes: 7 additions & 34 deletions src/variable.cpp
Expand Up @@ -138,7 +138,7 @@ config vconfig::get_parsed_config() const
throw recursion_error("vconfig::get_parsed_config() infinite recursion detected, aborting");
}
try {
variable_info vinfo(vname, false, variable_info::TYPE_CONTAINER);
variable_info vinfo = resources::gamedata->get_variable_access(vname, false, variable_info::TYPE_CONTAINER);
if(!vinfo.is_valid) {
res.add_child(name); //add empty tag
} else if(vinfo.explicit_index) {
Expand Down Expand Up @@ -181,7 +181,7 @@ vconfig::child_list vconfig::get_children(const std::string& key) const
} else if (child.key == "insert_tag") {
vconfig insert_cfg(child.cfg);
if(insert_cfg["name"] == key) {
variable_info vinfo(insert_cfg["variable"], false, variable_info::TYPE_CONTAINER);
variable_info vinfo = resources::gamedata->get_variable_access(insert_cfg["variable"], false, variable_info::TYPE_CONTAINER);
if(!vinfo.is_valid) {
//push back an empty tag
res.push_back(empty_vconfig());
Expand Down Expand Up @@ -217,7 +217,7 @@ vconfig vconfig::child(const std::string& key) const
{
vconfig insert_cfg(ins);
if(insert_cfg["name"] == key) {
variable_info vinfo(insert_cfg["variable"], false, variable_info::TYPE_CONTAINER);
variable_info vinfo = resources::gamedata->get_variable_access(insert_cfg["variable"], false, variable_info::TYPE_CONTAINER);
if(!vinfo.is_valid) {
return empty_vconfig();
}
Expand Down Expand Up @@ -285,7 +285,7 @@ vconfig::all_children_iterator& vconfig::all_children_iterator::operator++()
{
if (inner_index_ >= 0 && i_->key == "insert_tag")
{
variable_info vinfo(vconfig(i_->cfg)["variable"], false, variable_info::TYPE_CONTAINER);
variable_info vinfo = resources::gamedata->get_variable_access(vconfig(i_->cfg)["variable"], false, variable_info::TYPE_CONTAINER);
if(vinfo.is_valid && !vinfo.explicit_index) {
variable_info::array_range range = vinfo.as_array();
if (++inner_index_ < std::distance(range.first, range.second)) {
Expand Down Expand Up @@ -330,7 +330,7 @@ vconfig vconfig::all_children_iterator::get_child() const
{
if (inner_index_ >= 0 && i_->key == "insert_tag")
{
variable_info vinfo(vconfig(i_->cfg)["variable"], false, variable_info::TYPE_CONTAINER);
variable_info vinfo = resources::gamedata->get_variable_access(vconfig(i_->cfg)["variable"], false, variable_info::TYPE_CONTAINER);
if(!vinfo.is_valid) {
return empty_vconfig();
} else if(inner_index_ == 0) {
Expand Down Expand Up @@ -442,33 +442,8 @@ void scoped_recall_unit::activate()
}
}

namespace {
bool recursive_activation = false;

/** Turns on any auto-stored variables */
void activate_scope_variable(std::string var_name)
{
if(recursive_activation)
return;
const std::string::iterator itor = std::find(var_name.begin(),var_name.end(),'.');
if(itor != var_name.end()) {
var_name.erase(itor, var_name.end());
}
std::vector<scoped_wml_variable*>::reverse_iterator rit;
for(rit = resources::gamedata->scoped_variables.rbegin(); rit != resources::gamedata->scoped_variables.rend(); ++rit) {
if((**rit).name() == var_name) {
recursive_activation = true;
if(!(**rit).activated()) {
(**rit).activate();
}
recursive_activation = false;
break;
}
}
}
} // end anonymous namespace

variable_info::variable_info(const std::string& varname,
variable_info::variable_info(config& source, const std::string& varname,
bool force_valid, TYPE validation_type) :
vartype(validation_type),
is_valid(false),
Expand All @@ -477,10 +452,8 @@ variable_info::variable_info(const std::string& varname,
index(0),
vars(NULL)
{
assert(repos != NULL);
activate_scope_variable(varname);

vars = &resources::gamedata->variables_;
vars = &source;//&resources::gamedata->variables_;
key = varname;
std::string::const_iterator itor = std::find(key.begin(),key.end(),'.');
int dot_index = key.find('.');
Expand Down
3 changes: 1 addition & 2 deletions src/variable.hpp
Expand Up @@ -223,7 +223,7 @@ struct variable_info
TYPE_CONTAINER, //a Container is a specific index of an Array (contains Scalars)
TYPE_UNSPECIFIED };

variable_info(const std::string& varname, bool force_valid=true,
variable_info(config& source, const std::string& varname, bool force_valid=true,
TYPE validation_type=TYPE_UNSPECIFIED);

TYPE vartype; //default is TYPE_UNSPECIFIED
Expand All @@ -232,7 +232,6 @@ struct variable_info
bool explicit_index; //true if query ended in [...] specifier
size_t index; //the index of the child
config *vars; //the containing node in game_data s variables

/**
* Results: after deciding the desired type, these methods can retrieve the result
* Note: first you should force_valid or check is_valid, otherwise these may fail
Expand Down

0 comments on commit 16938d3

Please sign in to comment.