add tod_manager, lua kernel to filter context

this allows to remove the resources:: links from the filter
implementations
This commit is contained in:
Chris Beck 2014-12-23 01:34:24 -05:00
parent f33ca48bbf
commit 0fce6e7c68
6 changed files with 103 additions and 76 deletions

View file

@ -169,6 +169,8 @@ public:
void change_display_context(const display_context * dc);
const display_context & get_disp_context() const { return *dc_; }
virtual const tod_manager & get_tod_man() const; //!< This is implemented properly in game_display. The display:: impl could be pure virtual here but we decide not to.
virtual const game_data * get_game_data() const { return NULL; }
virtual game_lua_kernel * get_lua_kernel() const { return NULL; } //!< TODO: display should not work as a filter context, this was only done for expedience so that the unit animation code can have a convenient and correct filter context readily available. a more correct solution is most likely to pass it a filter context from unit_animator when it needs to be matched. (it's not possible to store filter contexts with animations, because animations are cached across scenarios.) Note that after these lines which return NULL, unit filters used in animations will not be able to make use of wml variables or lua scripting (but the latter was a bad idea anyways because it would be slow to constantly recompile the script.)
void reset_halo_manager();
void reset_halo_manager(halo::manager & hm);

View file

@ -16,7 +16,8 @@
*
* This class is an abstract base class which represents a display context
* (game map, units, and teams) together with a TOD manager. This, plus
* a lua kernel (currently a singleton) is sufficient to evaluate filters.
* the game data (WML variables) and a lua kernel (currently a singleton)
* is sufficient to evaluate filters.
*
**/
@ -27,6 +28,8 @@
class display_context;
class tod_manager;
class game_data;
class game_lua_kernel;
class filter_context {
public:
@ -34,6 +37,8 @@ public:
virtual const display_context & get_disp_context() const = 0;
virtual const tod_manager & get_tod_man() const = 0;
virtual const game_data * get_game_data() const = 0;
virtual game_lua_kernel * get_lua_kernel() const = 0;
// Dtor

View file

@ -61,6 +61,8 @@ public:
virtual const display_context & get_disp_context() const { return board_; }
virtual const tod_manager & get_tod_man() const { return tod_manager_; }
virtual const game_data * get_game_data() const { return &gamedata_; }
virtual game_lua_kernel * get_lua_kernel() const { return lua_kernel_.get(); }
/// Checks to see if a leader at @a leader_loc could recruit somewhere.
bool can_recruit_from(const map_location& leader_loc, int side) const;

View file

@ -87,14 +87,20 @@ public:
ignore_units_filter_context(const filter_context & fc)
: dc_(fc.get_disp_context())
, tod_(&fc.get_tod_man())
, gd_(fc.get_game_data())
, lk_(fc.get_lua_kernel())
{}
const display_context & get_disp_context() const { return dc_; }
const tod_manager & get_tod_man() const { return *tod_; }
const game_data * get_game_data() const { return gd_; }
game_lua_kernel * get_lua_kernel() const { return lk_; }
private:
const ignore_units_display_context dc_;
const tod_manager * tod_;
const game_data * gd_;
game_lua_kernel * lk_;
};
void teleport_group::get_teleport_pair(

View file

@ -23,7 +23,6 @@
#include "game_data.hpp"
#include "log.hpp"
#include "map.hpp"
#include "resources.hpp"
#include "side_filter.hpp"
#include "team.hpp"
#include "terrain_filter.hpp"
@ -141,22 +140,24 @@ 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")) {
try
{
variable_access_const vi = resources::gamedata->get_variable_access_read(cfg_["find_in"]);
if (const game_data * gd = fc_->get_game_data()) {
try
{
variable_access_const vi = gd->get_variable_access_read(cfg_["find_in"]);
bool found = false;
BOOST_FOREACH(const config &cfg, vi.as_array()) {
if (map_location(cfg, NULL) == loc) {
found = true;
break;
bool found = false;
BOOST_FOREACH(const config &cfg, vi.as_array()) {
if (map_location(cfg, NULL) == loc) {
found = true;
break;
}
}
if (!found) return false;
}
catch(const invalid_variablename_exception&)
{
return false;
}
if (!found) return false;
}
catch(const invalid_variablename_exception&)
{
return false;
}
}
}
@ -433,19 +434,20 @@ 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
try
{
variable_access_const vi = resources::gamedata->get_variable_access_read(cfg_["find_in"]);
BOOST_FOREACH(const config& cfg, vi.as_array())
if (const game_data * gd = fc_->get_game_data()) {
try
{
map_location test_loc(cfg, NULL);
match_set.insert(test_loc);
variable_access_const vi = gd->get_variable_access_read(cfg_["find_in"]);
BOOST_FOREACH(const config& cfg, vi.as_array())
{
map_location test_loc(cfg, NULL);
match_set.insert(test_loc);
}
}
catch(const invalid_variablename_exception&)
{
//Do nothing
}
}
catch(const invalid_variablename_exception&)
{
//Do nothing
}
} else
@ -468,22 +470,24 @@ 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
try
{
std::set<map_location> findin_locs;
variable_access_const vi = resources::gamedata->get_variable_access_read(cfg_["find_in"]);
BOOST_FOREACH(const config& cfg, vi.as_array())
if (const game_data * gd = fc_->get_game_data()) {
try
{
map_location test_loc(cfg, NULL);
if (match_set.count(test_loc)) {
findin_locs.insert(test_loc);
std::set<map_location> findin_locs;
variable_access_const vi = gd->get_variable_access_read(cfg_["find_in"]);
BOOST_FOREACH(const config& cfg, vi.as_array())
{
map_location test_loc(cfg, NULL);
if (match_set.count(test_loc)) {
findin_locs.insert(test_loc);
}
}
match_set.swap(findin_locs);
}
catch(const invalid_variablename_exception&)
{
match_set.clear();
}
match_set.swap(findin_locs);
}
catch(const invalid_variablename_exception&)
{
match_set.clear();
}
} else
@ -511,19 +515,21 @@ void terrain_filter::get_locations(std::set<map_location>& locs, bool with_borde
//use content of find_in as starting set
try
{
variable_access_const vi = resources::gamedata->get_variable_access_read(cfg_["find_in"]);
BOOST_FOREACH(const config& cfg, vi.as_array())
if (const game_data * gd = fc_->get_game_data()) {
try
{
map_location test_loc(cfg, NULL);
if (area.count(test_loc) != 0)
match_set.insert(test_loc);
variable_access_const vi = gd->get_variable_access_read(cfg_["find_in"]);
BOOST_FOREACH(const config& cfg, vi.as_array())
{
map_location test_loc(cfg, NULL);
if (area.count(test_loc) != 0)
match_set.insert(test_loc);
}
}
catch(const invalid_variablename_exception&)
{
match_set.clear();
}
}
catch(const invalid_variablename_exception&)
{
match_set.clear();
}
} else
@ -539,19 +545,21 @@ void terrain_filter::get_locations(std::set<map_location>& locs, bool with_borde
const std::set<map_location>& area = fc_->get_tod_man().get_area_by_id(cfg_["area"]);
//use content of find_in as starting set
try
{
variable_access_const vi = resources::gamedata->get_variable_access_read(cfg_["find_in"]);
if (const game_data * gd = fc_->get_game_data()) {
try
{
variable_access_const vi = gd->get_variable_access_read(cfg_["find_in"]);
BOOST_FOREACH(const config &cfg, vi.as_array()) {
map_location test_loc(cfg, NULL);
if (area.count(test_loc) != 0 && xy_set.count(test_loc) != 0)
match_set.insert(test_loc);
BOOST_FOREACH(const config &cfg, vi.as_array()) {
map_location test_loc(cfg, NULL);
if (area.count(test_loc) != 0 && xy_set.count(test_loc) != 0)
match_set.insert(test_loc);
}
}
catch(const invalid_variablename_exception&)
{
//Do nothing
}
}
catch(const invalid_variablename_exception&)
{
//Do nothing
}
}

View file

@ -24,11 +24,11 @@
#include "make_enum.hpp"
#include "map.hpp"
#include "map_location.hpp"
#include "resources.hpp" //Needed for lua kernel pointer
#include "scripting/game_lua_kernel.hpp" //Needed for lua kernel
#include "side_filter.hpp"
#include "team.hpp"
#include "terrain_filter.hpp"
#include "tod_manager.hpp"
#include "unit.hpp"
#include "unit_formula_manager.hpp"
#include "unit_map.hpp"
@ -578,24 +578,26 @@ bool basic_unit_filter_impl::internal_matches_filter(const unit & u, const map_l
if (!cfg_find_in_.blank()) {
// Allow filtering by searching a stored variable of units
try
{
variable_access_const vi = resources::gamedata->get_variable_access_read(cfg_find_in_);
bool found_id = false;
BOOST_FOREACH(const config& c, vi.as_array())
if (const game_data * gd = fc_.get_game_data()) {
try
{
if(c["id"] == u.id())
found_id = true;
variable_access_const vi = gd->get_variable_access_read(cfg_find_in_);
bool found_id = false;
BOOST_FOREACH(const config& c, vi.as_array())
{
if(c["id"] == u.id())
found_id = true;
}
if(!found_id)
{
return false;
}
}
if(!found_id)
catch(const invalid_variablename_exception&)
{
return false;
}
}
catch(const invalid_variablename_exception&)
{
return false;
}
}
if (!cfg_formula_.blank()) {
if (!u.formula_manager().matches_filter(cfg_formula_, loc, u)) {
@ -604,8 +606,10 @@ bool basic_unit_filter_impl::internal_matches_filter(const unit & u, const map_l
}
if (!cfg_lua_function_.blank()) {
bool b = resources::lua_kernel->run_filter(cfg_lua_function_.str().c_str(), u);
if (!b) return false;
if (game_lua_kernel * lk = fc_.get_lua_kernel()) {
bool b = lk->run_filter(cfg_lua_function_.str().c_str(), u);
if (!b) return false;
}
}
return true;