From daa48e0dce026992d13df55c28cc5518b4331c1e Mon Sep 17 00:00:00 2001 From: Chris Beck Date: Sat, 5 Jul 2014 02:21:07 -0400 Subject: [PATCH] add all_matches, first_match fcns to unit_filter, use at [object] --- src/game_events/action_wml.cpp | 16 ++++++------- src/unit_filter.cpp | 41 ++++++++++++++++++++++++++++++++-- src/unit_filter.hpp | 13 +++++++++++ 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/game_events/action_wml.cpp b/src/game_events/action_wml.cpp index 6516d04a6468..be820ed2af66 100644 --- a/src/game_events/action_wml.cpp +++ b/src/game_events/action_wml.cpp @@ -1410,6 +1410,9 @@ WML_HANDLER_FUNCTION(move_units_fake, /*event_info*/, cfg) WML_HANDLER_FUNCTION(object, event_info, cfg) { const vconfig & filter = cfg.child("filter"); + boost::optional ufilt; + if (!filter.null()) + ufilt = unit_filter(filter, resources::filter_con); std::string id = cfg["id"]; @@ -1422,13 +1425,10 @@ WML_HANDLER_FUNCTION(object, event_info, cfg) std::string text; map_location loc; - if(!filter.null()) { - const unit_filter ufilt(filter, resources::filter_con); - BOOST_FOREACH(const unit &u, *resources::units) { - if ( ufilt(u) ) { - loc = u.get_location(); - break; - } + if(ufilt) { + unit_const_ptr u_ptr = ufilt->first_match_on_map(); + if (u_ptr) { + loc = u_ptr->get_location(); } } @@ -1440,7 +1440,7 @@ WML_HANDLER_FUNCTION(object, event_info, cfg) std::string command_type = "then"; - if ( u != resources::units->end() && (filter.null() || unit_filter(filter, resources::filter_con).matches(*u)) ) + if ( u != resources::units->end() && (!ufilt || ufilt->matches(*u)) ) { ///@deprecated This can be removed (and a proper duration=level implemented) after 1.11.2 /// Don't forget to remove it from wmllint too! diff --git a/src/unit_filter.cpp b/src/unit_filter.cpp index c09668a8034d..c42bc75fa4c4 100644 --- a/src/unit_filter.cpp +++ b/src/unit_filter.cpp @@ -59,12 +59,27 @@ static boost::shared_ptr construct(const vconfig & vc /// Null unit filter is built when the input config is null class null_unit_filter_impl : public unit_filter_abstract_impl { public: - null_unit_filter_impl() {} + null_unit_filter_impl(const filter_context & fc) : fc_(fc) {} virtual bool matches(const unit & /*u*/, const map_location & /*loc*/) const { return true; } + virtual std::vector all_matches_on_map() const { + std::vector ret; + BOOST_FOREACH(const unit & u, fc_.get_disp_context().units()) { + ret.push_back(&u); + } + return ret; + } + + virtual unit_const_ptr first_match_on_map() const { + return fc_.get_disp_context().units().begin().get_shared_ptr(); + } + virtual ~null_unit_filter_impl() {} + +private: + const filter_context & fc_; }; /// This enum helps to evaluate conditional filters @@ -220,6 +235,8 @@ class basic_unit_filter_impl : public unit_filter_abstract_impl { } virtual bool matches(const unit & u, const map_location & loc) const; + virtual std::vector all_matches_on_map() const; + virtual unit_const_ptr first_match_on_map() const; virtual ~basic_unit_filter_impl() {} private: @@ -277,7 +294,7 @@ class basic_unit_filter_impl : public unit_filter_abstract_impl { static boost::shared_ptr construct(const vconfig & vcfg, const filter_context & fc, bool flat_tod) { if (vcfg.null()) { - return boost::make_shared (); + return boost::make_shared (fc); } return boost::make_shared(vcfg, fc, flat_tod); //TODO: Add more efficient implementations for special cases @@ -580,3 +597,23 @@ bool basic_unit_filter_impl::internal_matches_filter(const unit & u, const map_l return true; } + +std::vector basic_unit_filter_impl::all_matches_on_map() const { + std::vector ret; + BOOST_FOREACH(const unit & u, fc_.get_disp_context().units()) { + if (matches(u, u.get_location())) { + ret.push_back(&u); + } + } + return ret; +} + +unit_const_ptr basic_unit_filter_impl::first_match_on_map() const { + const unit_map & units = fc_.get_disp_context().units(); + for(unit_map::const_iterator u = units.begin(); u != units.end(); u++) { + if (matches(*u,u->get_location())) { + return u.get_shared_ptr(); + } + } + return unit_const_ptr(); +} diff --git a/src/unit_filter.hpp b/src/unit_filter.hpp index 66c06729cde7..52dca43aff4f 100644 --- a/src/unit_filter.hpp +++ b/src/unit_filter.hpp @@ -26,7 +26,10 @@ #ifndef INCLUDED_UNIT_FILTER_HPP_ #define INCLUDED_UNIT_FILTER_HPP_ +#include "unit_ptr.hpp" + #include +#include class filter_context; class unit; @@ -36,6 +39,8 @@ struct map_location; class unit_filter_abstract_impl { public: virtual bool matches(const unit & u, const map_location & loc) const = 0; + virtual std::vector all_matches_on_map() const = 0; + virtual unit_const_ptr first_match_on_map() const = 0; virtual ~unit_filter_abstract_impl() {} }; @@ -71,6 +76,14 @@ class unit_filter { bool operator()(const unit & u) const { return matches(u); } + + std::vector all_matches_on_map() const { + return impl_->all_matches_on_map(); + } + + unit_const_ptr first_match_on_map() const { + return impl_->first_match_on_map(); + } private: boost::shared_ptr impl_; };