diff --git a/src/gui/dialogs/lobby/data.cpp b/src/gui/dialogs/lobby/data.cpp index a911a537a3f..bafb0637f76 100644 --- a/src/gui/dialogs/lobby/data.cpp +++ b/src/gui/dialogs/lobby/data.cpp @@ -367,48 +367,12 @@ const char* game_info::display_status_string() const } } -game_filter_stack::game_filter_stack() : filters_() +bool game_info::match_string_filter(const std::string& filter) const { -} - -game_filter_stack::~game_filter_stack() -{ - for(auto f : filters_) { - delete f; - } -} - -void game_filter_stack::append(game_filter_base* f) -{ - filters_.push_back(f); -} - -void game_filter_stack::clear() -{ - for(auto f : filters_) { - delete f; - } - - filters_.clear(); -} - -bool game_filter_and_stack::match(const game_info& game) const -{ - for(auto f : filters_) { - if(!f->match(game)) { - return false; - } - } - - return true; -} - -bool game_filter_general_string_part::match(const game_info& game) const -{ - const std::string& s1 = game.map_info; - const std::string& s2 = game.name; - return std::search(s1.begin(), s1.end(), value_.begin(), value_.end(), + const std::string& s1 = map_info; + const std::string& s2 = name; + return std::search(s1.begin(), s1.end(), filter.begin(), filter.end(), chars_equal_insensitive) != s1.end() - || std::search(s2.begin(), s2.end(), value_.begin(), value_.end(), + || std::search(s2.begin(), s2.end(), filter.begin(), filter.end(), chars_equal_insensitive) != s2.end(); } diff --git a/src/gui/dialogs/lobby/data.hpp b/src/gui/dialogs/lobby/data.hpp index d76e4a72d2a..8a822027a0b 100644 --- a/src/gui/dialogs/lobby/data.hpp +++ b/src/gui/dialogs/lobby/data.hpp @@ -185,93 +185,8 @@ struct game_info game_display_status display_status; const char* display_status_string() const; -}; -class game_filter_base -{ -public: - virtual ~game_filter_base() - { - } - virtual bool match(const game_info& game) const = 0; - bool operator()(const game_info& game) const - { - return match(game); - } -}; - -template -class game_filter_not : public game_filter_base -{ -public: - explicit game_filter_not(const T& t) : t(t) - { - } - bool match(const game_info& game) const - { - return !t.match(game); - } - T t; -}; - -class game_filter_stack : public game_filter_base -{ -public: - game_filter_stack(); - virtual ~game_filter_stack(); - - /** - * Takes ownership - */ - void append(game_filter_base* f); - - void clear(); - - bool empty() const - { - return filters_.empty(); - } - -protected: - std::vector filters_; -}; - -class game_filter_and_stack : public game_filter_stack -{ -public: - bool match(const game_info& game) const; -}; - -template > -class game_filter_value : public game_filter_base -{ -public: - explicit game_filter_value(const T& value) : member_(member), value_(value) - { - } - - bool match(const game_info& game) const - { - return OP()(game.*member_, value_); - } - -private: - T game_info::*member_; - T value_; -}; - -class game_filter_general_string_part : public game_filter_base -{ -public: - explicit game_filter_general_string_part(const std::string& value) - : value_(value) - { - } - - bool match(const game_info& game) const; - -private: - std::string value_; + bool match_string_filter(const std::string& filter) const; }; #endif diff --git a/src/gui/dialogs/lobby/info.cpp b/src/gui/dialogs/lobby/info.cpp index d54d89e0473..b569f9ca001 100644 --- a/src/gui/dialogs/lobby/info.cpp +++ b/src/gui/dialogs/lobby/info.cpp @@ -46,7 +46,7 @@ lobby_info::lobby_info(const config& game_config, twesnothd_connection& wesnothd , users_() , users_sorted_() , whispers_() - , game_filter_() + , game_filters_() , game_filter_invert_(false) , games_visibility_() , wesnothd_connection_(wesnothd_connection) @@ -299,14 +299,14 @@ const std::vector& lobby_info::games_filtered() const return games_filtered_; } -void lobby_info::add_game_filter(game_filter_base* f) +void lobby_info::add_game_filter(game_filter_func func) { - game_filter_.append(f); + game_filters_.push_back(func); } void lobby_info::clear_game_filter() { - game_filter_.clear(); + game_filters_.clear(); } void lobby_info::set_game_filter_invert(bool value) @@ -332,7 +332,11 @@ void lobby_info::apply_game_filter() for(auto g : games_) { game_info& gi = *g; - bool show = game_filter_.match(gi); + bool show = true; + for(const auto& filter_func : game_filters_) { + if(!(show = filter_func(gi))) break; + } + if(game_filter_invert_) { show = !show; } diff --git a/src/gui/dialogs/lobby/info.hpp b/src/gui/dialogs/lobby/info.hpp index be31f29c2d2..f2c45ccb9ac 100644 --- a/src/gui/dialogs/lobby/info.hpp +++ b/src/gui/dialogs/lobby/info.hpp @@ -33,6 +33,8 @@ public: typedef std::map game_info_map; + using game_filter_func = std::function; + /** * Process a full gamelist. Current info is discarded. */ @@ -55,7 +57,7 @@ public: } void clear_game_filter(); - void add_game_filter(game_filter_base* f); + void add_game_filter(game_filter_func func); void set_game_filter_invert(bool value); void apply_game_filter(); @@ -110,7 +112,7 @@ private: std::vector users_; std::vector users_sorted_; std::map whispers_; - game_filter_and_stack game_filter_; + std::vector game_filters_; bool game_filter_invert_; std::vector games_visibility_; twesnothd_connection& wesnothd_connection_; diff --git a/src/gui/dialogs/lobby/lobby.cpp b/src/gui/dialogs/lobby/lobby.cpp index 7aa4a2f2d1a..b4f1c9d7deb 100644 --- a/src/gui/dialogs/lobby/lobby.cpp +++ b/src/gui/dialogs/lobby/lobby.cpp @@ -1660,25 +1660,31 @@ void tlobby_main::game_filter_reload() { lobby_info_.clear_game_filter(); - for(const auto & s : utils::split(filter_text_->get_value(), ' ')) - { - lobby_info_.add_game_filter(new game_filter_general_string_part(s)); + for(const auto& s : utils::split(filter_text_->get_value(), ' ')) { + lobby_info_.add_game_filter([s](const game_info& info)->bool { + return info.match_string_filter(s); + }); } + // TODO: make changing friend/ignore lists trigger a refresh if(filter_friends_->get_value()) { - lobby_info_.add_game_filter( - new game_filter_value(true)); + lobby_info_.add_game_filter([](const game_info& info)->bool { + return info.has_friends == true; + }); } + if(filter_ignored_->get_value()) { - lobby_info_.add_game_filter( - new game_filter_value(false)); + lobby_info_.add_game_filter([](const game_info& info)->bool { + return info.has_ignored == false; + }); } + if(filter_slots_->get_value()) { - lobby_info_.add_game_filter( - new game_filter_value >(0)); + lobby_info_.add_game_filter([](const game_info& info)->bool { + return info.vacant_slots > 0; + }); } + lobby_info_.set_game_filter_invert(filter_invert_->get_value_bool()); }