diff --git a/src/unit_animation.cpp b/src/unit_animation.cpp index 9e6df5b17c20..7702944dbf41 100644 --- a/src/unit_animation.cpp +++ b/src/unit_animation.cpp @@ -328,11 +328,11 @@ unit_animation::unit_animation(const config& cfg,const std::string& frame_string directions_.push_back(d); } BOOST_FOREACH(const config &filter, cfg.child_range("filter")) { - unit_filter_.push_back(filter); + unit_filter_.push_back(unit_filter(vconfig(filter), game_display::get_singleton())); } BOOST_FOREACH(const config &filter, cfg.child_range("filter_second")) { - secondary_unit_filter_.push_back(filter); + secondary_unit_filter_.push_back(unit_filter(vconfig(filter), game_display::get_singleton())); } std::vector value_str = utils::split(cfg["value"]); @@ -402,18 +402,18 @@ int unit_animation::matches(const display &disp, const map_location& loc,const m result ++; } } - std::vector::const_iterator myitor; + std::vector::const_iterator myitor; for(myitor = unit_filter_.begin(); myitor != unit_filter_.end(); ++myitor) { - if (!unit_filter(vconfig(*myitor), &disp).matches(*my_unit, loc)) return MATCH_FAIL; //TODO: Precalculate these + if (!myitor->matches(*my_unit, loc)) return MATCH_FAIL; ++result; } if(!secondary_unit_filter_.empty()) { unit_map::const_iterator unit; for(unit=disp.get_units().begin() ; unit != disp.get_units().end() ; ++unit) { if (unit->get_location() == second_loc) { - std::vector::const_iterator second_itor; + std::vector::const_iterator second_itor; for(second_itor = secondary_unit_filter_.begin(); second_itor != secondary_unit_filter_.end(); ++second_itor) { - if (!unit_filter(vconfig(*second_itor), &disp).matches(*unit, second_loc)) return MATCH_FAIL; //TODO: Precalculate these + if (!second_itor->matches(*unit, second_loc)) return MATCH_FAIL; result++; } @@ -1148,16 +1148,18 @@ std::ostream& operator << (std::ostream& outstream, const unit_animation& u_anim if (u_animation.unit_filter_.size() > 0) { std::cout << "[filter]\n"; - BOOST_FOREACH(const config cfg, u_animation.unit_filter_) { - std::cout << cfg.debug(); - } + //BOOST_FOREACH(const config cfg, u_animation.unit_filter_) { + // std::cout << cfg.debug(); + //} + std::cout << "TODO: create debugging output for unit filters"; std::cout << "[/filter]\n"; } if (u_animation.secondary_unit_filter_.size() > 0) { std::cout << "[filter_second]\n"; - BOOST_FOREACH(const config cfg, u_animation.secondary_unit_filter_) { - std::cout << cfg.debug(); - } + //BOOST_FOREACH(const config cfg, u_animation.secondary_unit_filter_) { + // std::cout << cfg.debug(); + //} + std::cout << "TODO: create debugging output for unit filters"; std::cout << "[/filter_second]\n"; } if (u_animation.primary_attack_filter_.size() > 0) { diff --git a/src/unit_animation.hpp b/src/unit_animation.hpp index 6450ee346f6b..09435f0b48a7 100644 --- a/src/unit_animation.hpp +++ b/src/unit_animation.hpp @@ -17,6 +17,7 @@ #include "animated.hpp" #include "config.hpp" #include "halo.hpp" +#include "unit_filter.hpp" #include "unit_frame.hpp" #include "unit_ptr.hpp" @@ -126,8 +127,8 @@ class unit_animation }; t_translation::t_list terrain_types_; - std::vector unit_filter_; - std::vector secondary_unit_filter_; + std::vector unit_filter_; + std::vector secondary_unit_filter_; std::vector directions_; int frequency_; int base_score_; diff --git a/src/unit_filter.cpp b/src/unit_filter.cpp index 42e864749df9..c8b98c2cbfef 100644 --- a/src/unit_filter.cpp +++ b/src/unit_filter.cpp @@ -34,7 +34,9 @@ #include #include +#include #include +#include #include //needed for boost::in_place to initialize optionals #include @@ -51,7 +53,7 @@ bool unit_filter::matches(const unit & u) const { /// Forward declare the "construct" method which constructs an appropriate filter impl -static unit_filter_abstract_impl * construct(const vconfig & vcfg, const filter_context & fc, bool flat_tod); +static boost::shared_ptr construct(const vconfig & vcfg, const filter_context & fc, bool flat_tod); /// Null unit filter is built when the input config is null class null_unit_filter_impl : public unit_filter_abstract_impl { @@ -271,12 +273,12 @@ class basic_unit_filter_impl : public unit_filter_abstract_impl { * */ -static unit_filter_abstract_impl * construct(const vconfig & vcfg, const filter_context & fc, bool flat_tod) +static boost::shared_ptr construct(const vconfig & vcfg, const filter_context & fc, bool flat_tod) { if (vcfg.null()) { - return new null_unit_filter_impl(); + return boost::make_shared (); } - return new basic_unit_filter_impl(vcfg, fc, flat_tod); + return boost::make_shared(vcfg, fc, flat_tod); //TODO: Add more efficient implementations for special cases } @@ -288,7 +290,7 @@ unit_filter::unit_filter(const vconfig & vcfg, const filter_context * fc, bool f if (!fc) { assert(false && "attempt to instantiate a unit filter with a null filter context!"); } - impl_.reset(construct(vcfg, *fc, flat_tod)); + impl_ = construct(vcfg, *fc, flat_tod); } /** Begin implementations of filter impl's diff --git a/src/unit_filter.hpp b/src/unit_filter.hpp index 08f366962fc8..830f3f693b80 100644 --- a/src/unit_filter.hpp +++ b/src/unit_filter.hpp @@ -23,7 +23,10 @@ * these to speed up repeated application of the filter. */ -#include +#ifndef INCLUDED_UNIT_FILTER_HPP_ +#define INCLUDED_UNIT_FILTER_HPP_ + +#include class filter_context; class unit; @@ -40,6 +43,16 @@ class unit_filter { public: unit_filter(const vconfig & cfg, const filter_context * fc, bool use_flat_tod = false); //!< Constructs a unit filter from a config and a context. This function should give the most efficient implementation available. + // Copy and Swap Idiom for the interface -- does not copy the underlying impl + unit_filter(const unit_filter & o ) : impl_(o.impl_) {} + void swap(unit_filter & o) { + impl_.swap(o.impl_); + } + unit_filter & operator=(unit_filter o) { + swap(o); + return *this; + } + bool matches(const unit & u, const map_location & loc) const { return impl_->matches(u,loc); } @@ -56,5 +69,7 @@ class unit_filter { return matches(u); } private: - boost::scoped_ptr impl_; + boost::shared_ptr impl_; }; + +#endif