From a91cb9ad0b27e50c7b74f0ed8e3ad6ba927d74c5 Mon Sep 17 00:00:00 2001 From: gfgtdf Date: Mon, 14 Mar 2016 14:41:53 +0100 Subject: [PATCH] add limit=n parameter to standard unit filters and specially to wesnoth.get_units --- src/config.hpp | 3 +++ src/unit_filter.cpp | 23 +++++++++++++++++++---- src/unit_filter.hpp | 5 +++-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/config.hpp b/src/config.hpp index ea39911063c9..6e819bf55209 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -406,6 +406,9 @@ class config const_child_itors child_range(const std::string& key) const; unsigned child_count(const std::string &key) const; unsigned all_children_count() const; + /** Note: this function also counts the 'blank' attributes, so it might return more than one might expect */ + unsigned attribute_count() const + { return values.size(); } /** * Determine whether a config has a child or not. diff --git a/src/unit_filter.cpp b/src/unit_filter.cpp index c9e7d758495a..2157c69d367a 100644 --- a/src/unit_filter.cpp +++ b/src/unit_filter.cpp @@ -77,10 +77,14 @@ class null_unit_filter_impl : public unit_filter_abstract_impl { virtual bool matches(const unit & /*u*/, const map_location & /*loc*/, const unit *) const { return true; } - virtual std::vector all_matches_on_map() const { + virtual std::vector all_matches_on_map(unsigned max_matches) const { std::vector ret; BOOST_FOREACH(const unit & u, fc_.get_disp_context().units()) { + --max_matches; ret.push_back(&u); + if(max_matches == 0) { + return ret; + } } return ret; } @@ -153,7 +157,7 @@ class basic_unit_filter_impl : public unit_filter_abstract_impl { } virtual bool matches(const unit & u, const map_location & loc, const unit * u2) const; - virtual std::vector all_matches_on_map() const; + virtual std::vector all_matches_on_map(unsigned max_matches) const; virtual unit_const_ptr first_match_on_map() const; virtual ~basic_unit_filter_impl() {} @@ -174,7 +178,10 @@ 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()) { + if (vcfg.empty()) { + return boost::make_shared (fc); + } + if (vcfg.get_config().attribute_count() == 1 && vcfg.get_config().all_children_count() == 0 && vcfg.has_attribute("limit")) { return boost::make_shared (fc); } return boost::make_shared(vcfg, fc, flat_tod); @@ -185,7 +192,11 @@ static boost::shared_ptr construct(const vconfig & vc * unit_filter::unit_filter acts as a factory, selecting the appropriate implementation class */ unit_filter::unit_filter(const vconfig & vcfg, const filter_context * fc, bool flat_tod) + : max_matches_(static_cast(-1)) { + if(vcfg) { + max_matches_ = vcfg["limit"].to_unsigned(max_matches_); + } if (!fc) { assert(false && "attempt to instantiate a unit filter with a null filter context!"); } @@ -539,10 +550,14 @@ 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 basic_unit_filter_impl::all_matches_on_map(unsigned max_matches) const { std::vector ret; BOOST_FOREACH(const unit & u, fc_.get_disp_context().units()) { if (matches(u, u.get_location(), NULL)) { + if(max_matches == 0) { + return ret; + } + --max_matches; ret.push_back(&u); } } diff --git a/src/unit_filter.hpp b/src/unit_filter.hpp index 6254b7d168a3..eef40ecc2a80 100644 --- a/src/unit_filter.hpp +++ b/src/unit_filter.hpp @@ -39,7 +39,7 @@ struct map_location; class unit_filter_abstract_impl { public: virtual bool matches(const unit & u, const map_location & loc, const unit * u2 = NULL) const = 0; - virtual std::vector all_matches_on_map() const = 0; + virtual std::vector all_matches_on_map(unsigned max_matches) const = 0; virtual unit_const_ptr first_match_on_map() const = 0; virtual ~unit_filter_abstract_impl() {} }; @@ -89,7 +89,7 @@ class unit_filter { } std::vector all_matches_on_map() const { - return impl_->all_matches_on_map(); + return impl_->all_matches_on_map(max_matches_); } unit_const_ptr first_match_on_map() const { @@ -97,6 +97,7 @@ class unit_filter { } private: boost::shared_ptr impl_; + unsigned max_matches_; }; #endif