MP Lobby: refactored games filtering
This commit is contained in:
parent
9b782931bb
commit
95a2fb3a46
5 changed files with 36 additions and 145 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 T>
|
||||
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<game_filter_base*> filters_;
|
||||
};
|
||||
|
||||
class game_filter_and_stack : public game_filter_stack
|
||||
{
|
||||
public:
|
||||
bool match(const game_info& game) const;
|
||||
};
|
||||
|
||||
template <class T, T game_info::*member, class OP = std::equal_to<T> >
|
||||
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
|
||||
|
|
|
@ -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<game_info*>& 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;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ public:
|
|||
|
||||
typedef std::map<int, game_info*> game_info_map;
|
||||
|
||||
using game_filter_func = std::function<bool(const game_info&)>;
|
||||
|
||||
/**
|
||||
* 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<user_info> users_;
|
||||
std::vector<user_info*> users_sorted_;
|
||||
std::map<std::string, chat_log> whispers_;
|
||||
game_filter_and_stack game_filter_;
|
||||
std::vector<game_filter_func> game_filters_;
|
||||
bool game_filter_invert_;
|
||||
std::vector<bool> games_visibility_;
|
||||
twesnothd_connection& wesnothd_connection_;
|
||||
|
|
|
@ -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<bool, &game_info::has_friends>(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<bool, &game_info::has_ignored>(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<size_t,
|
||||
&game_info::vacant_slots,
|
||||
std::greater<size_t> >(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());
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue