make wesnothd::send_to_many( .., pred, ...) a template

this is faster than the boost::function version. (also note that it's
still possible to pass a  boost::function to wesnothd::send_to_many)
This commit is contained in:
gfgtdf 2015-06-09 18:06:17 +02:00
parent f891446818
commit 15698bbea6
4 changed files with 48 additions and 28 deletions

View file

@ -25,7 +25,6 @@
#include <sstream>
#include <iomanip>
#include <boost/bind.hpp>
static lg::log_domain log_server("server");
#define ERR_GAME LOG_STREAM(err, log_server)
@ -1355,16 +1354,30 @@ void game::send_data(simple_wml::document& data,
{
wesnothd::send_to_many(data, all_game_users(), exclude, packet_type);
}
namespace {
struct is_on_team_helper
{
const wesnothd::game& game_;
const simple_wml::string_span& team_;
is_on_team_helper(const wesnothd::game& game, const simple_wml::string_span& team)
: game_(game)
, team_(team)
{
}
bool operator ()(network::connection user) const
{
return game_.is_on_team(team_, user);
}
};
}
void game::send_data_team(simple_wml::document& data,
const simple_wml::string_span& team,
const network::connection exclude,
std::string packet_type) const
{
DBG_GAME << __func__ << "...\n";
wesnothd::send_to_many(data, players_,
boost::bind(&game::is_on_team, this, boost::ref(team), _1),
exclude, packet_type);
wesnothd::send_to_many(data, players_, is_on_team_helper(*this, team), exclude, packet_type);
}

View file

@ -226,6 +226,11 @@ public:
void require_random(const simple_wml::document &data, const player_map::iterator user);
void reset_last_synced_context_id() { last_synced_context_id_ = -1; }
/**
* Function which returns true iff 'player' is on 'team'.
* AI controlled sides are not considered on a team.
*/
bool is_on_team(const simple_wml::string_span& team, const network::connection player) const;
private:
//forbidden operations
game(const game&);
@ -285,11 +290,6 @@ private:
bool observers_can_chat() const { return true; }
bool is_legal_command(const simple_wml::node& command, const player_map::const_iterator user);
/**
* Function which returns true iff 'player' is on 'team'.
* AI controlled sides are not considered on a team.
*/
bool is_on_team(const simple_wml::string_span& team, const network::connection player) const;
/**
* Checks whether a user has the same IP as members of this game.
* If observer is true it only checks against players.

View file

@ -72,23 +72,4 @@ void send_to_many(simple_wml::document& data, const connection_vector& vec,
}
}
void send_to_many(simple_wml::document& data, const connection_vector& vec,
boost::function<bool (network::connection)> pred,
const network::connection exclude, std::string packet_type)
{
if (packet_type.empty())
packet_type = data.root().first_child().to_string();
try {
simple_wml::string_span s = data.output_compressed();
for(connection_vector::const_iterator i = vec.begin(); i != vec.end(); ++i) {
if ((*i != exclude) && pred(*i)) {
network::send_raw_data(s.begin(), s.size(), *i, packet_type);
}
}
} catch (simple_wml::error& e) {
WRN_CONFIG << __func__ << ": simple_wml error: " << e.message << std::endl;
}
}
} //end namespace wesnothd

View file

@ -21,6 +21,7 @@
#include "simple_wml.hpp"
#include "utils/boost_function_guarded.hpp"
#include "../log.hpp"
namespace wesnothd {
@ -67,11 +68,36 @@ void send_to_many(simple_wml::document& data,
* @param exclude if nonzero, do not send to this player
* @param packet_type the packet type, if empty the root node name is used
*/
/*
void send_to_many(simple_wml::document& data,
const connection_vector& vec,
boost::function<bool (network::connection)> pred,
const network::connection exclude = 0,
std::string packet_type = "");
*/
template<typename TFilter>
void send_to_many(simple_wml::document& data,
const connection_vector& vec,
const TFilter& pred,
const network::connection exclude = 0,
std::string packet_type = "")
{
if (packet_type.empty()) {
packet_type = data.root().first_child().to_string();
}
try {
simple_wml::string_span s = data.output_compressed();
for(connection_vector::const_iterator i = vec.begin(); i != vec.end(); ++i) {
if ((*i != exclude) && pred(*i)) {
network::send_raw_data(s.begin(), s.size(), *i, packet_type);
}
}
} catch (simple_wml::error& e) {
LOG_STREAM(warn, log_config) << __func__ << ": simple_wml error: " << e.message << std::endl;
}
}
} //end namespace wesnothd
#endif