Author: grzywacz
Date: Wed Feb 4 22:48:16 2009
New Revision: 32608
URL: http://svn.gna.org/viewcvs/wesnoth?rev=32608&view=rev
Log:
Optimized handling of friends/ignores lists.
These are now backed by a set, instead of doing string operations on
preferences. This resolves the problem of very high CPU usage
in multiplayer lobby when friend/ignore lists are long.
Added:
trunk/src/tests/test_serialization.cpp
Modified:
trunk/src/CMakeLists.txt
trunk/src/Makefile.am
trunk/src/SConscript
trunk/src/game_preferences.cpp
trunk/src/game_preferences.hpp
trunk/src/game_preferences_display.cpp
trunk/src/menu_events.cpp
trunk/src/serialization/string_utils.cpp
trunk/src/serialization/string_utils.hpp
Modified: trunk/src/CMakeLists.txt
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/CMakeLists.txt?rev=32608&r1=32607&r2=32608&view=diff
==============================================================================
--- trunk/src/CMakeLists.txt (original)
+++ trunk/src/CMakeLists.txt Wed Feb 4 22:48:16 2009
@@ -476,6 +476,7 @@
tests/test_policy.cpp
tests/test_team.cpp
tests/test_util.cpp
+ tests/test_serialization.cpp
tests/test_version.cpp
tests/gui/test_save_dialog.cpp
tests/gui/test_drop_target.cpp
Modified: trunk/src/Makefile.am
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/Makefile.am?rev=32608&r1=32607&r2=32608&view=diff
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Wed Feb 4 22:48:16 2009
@@ -289,6 +289,7 @@
tests/test_policy.cpp \
tests/test_team.cpp \
tests/test_util.cpp \
+ tests/test_serialization.cpp \
tests/test_version.cpp \
tests/gui/test_save_dialog.cpp \
tests/gui/test_drop_target.cpp \
Modified: trunk/src/SConscript
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/SConscript?rev=32608&r1=32607&r2=32608&view=diff
==============================================================================
--- trunk/src/SConscript (original)
+++ trunk/src/SConscript Wed Feb 4 22:48:16 2009
@@ -371,6 +371,7 @@
tests/test_policy.cpp
tests/test_team.cpp
tests/test_util.cpp
+ tests/test_serialization.cpp
tests/test_version.cpp
tests/gui/test_drop_target.cpp
tests/gui/test_save_dialog.cpp
Modified: trunk/src/game_preferences.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/game_preferences.cpp?rev=32608&r1=32607&r2=32608&view=diff
==============================================================================
--- trunk/src/game_preferences.cpp (original)
+++ trunk/src/game_preferences.cpp Wed Feb 4 22:48:16 2009
@@ -39,19 +39,10 @@
std::map<std::string, std::vector<std::string> > history_map;
const unsigned max_history_saved = 50;
-/** Add a nick to the specified relation setting. */
-void add_relation(const std::string& nick, const std::string& relation) {
- std::vector<std::string> r = utils::split(preferences::get(relation));
- r.push_back(nick);
- preferences::set(relation, utils::join(r));
-}
-
-/** Remove a nick from the specified relation setting. */
-void remove_relation(const std::string& nick, const std::string& relation) {
- std::vector<std::string> r = utils::split(preferences::get(relation));
- r.erase(std::remove(r.begin(), r.end(), nick), r.end());
- preferences::set(relation, utils::join(r));
-}
+std::set<std::string> friends;
+std::set<std::string> ignores;
+bool friends_initialized = false;
+bool ignores_initialized = false;
} // anon namespace
@@ -149,32 +140,58 @@
set_ping_timeout(network::ping_timeout);
}
-std::string get_friends() {
- return preferences::get("friends");
-}
-
-std::string get_ignores() {
- return preferences::get("ignores");
+const std::set<std::string> & get_friends() {
+ if(!friends_initialized) {
+ std::vector<std::string> names =
utils::split(preferences::get("friends"));
+ std::set<std::string> tmp(names.begin(), names.end());
+ friends.swap(tmp);
+
+ friends_initialized = true;
+ }
+
+ return friends;
+}
+
+const std::set<std::string> & get_ignores() {
+ if(!ignores_initialized) {
+ std::vector<std::string> names =
utils::split(preferences::get("ignores"));
+ std::set<std::string> tmp(names.begin(), names.end());
+ ignores.swap(tmp);
+
+ ignores_initialized = true;
+ }
+
+ return ignores;
}
bool add_friend(const std::string& nick) {
if (!utils::isvalid_wildcard(nick)) return false;
- add_relation(nick, "friends");
+ friends.insert(nick);
+ preferences::set("friends", utils::join(friends));
return true;
}
bool add_ignore(const std::string& nick) {
if (!utils::isvalid_wildcard(nick)) return false;
- add_relation(nick, "ignores");
+ ignores.insert(nick);
+ preferences::set("ignores", utils::join(ignores));
return true;
}
void remove_friend(const std::string& nick) {
- remove_relation(nick, "friends");
+ std::set<std::string>::iterator i = friends.find(nick);
+ if(i != friends.end()) {
+ friends.erase(i);
+ preferences::set("friends", utils::join(friends));
+ }
}
void remove_ignore(const std::string& nick) {
- remove_relation(nick, "ignores");
+ std::set<std::string>::iterator i = ignores.find(nick);
+ if(i != ignores.end()) {
+ ignores.erase(i);
+ preferences::set("ignores", utils::join(ignores));
+ }
}
void clear_friends() {
@@ -186,21 +203,11 @@
}
bool is_friend(const std::string& nick) {
- const std::vector<std::string>& friends = utils::split(get_friends());
- foreach(const std::string& var, friends) {
- if(utils::wildcard_string_match(nick, var))
- return true;
- }
- return false;
+ return friends.find(nick) != friends.end();
}
bool is_ignored(const std::string& nick) {
- const std::vector<std::string>& ignores = utils::split(get_ignores());
- foreach(const std::string& var, ignores) {
- if(utils::wildcard_string_match(nick, var))
- return true;
- }
- return false;
+ return ignores.find(nick) != ignores.end();
}
bool show_lobby_join(const std::string& sender, const std::string& message) {
Modified: trunk/src/game_preferences.hpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/game_preferences.hpp?rev=32608&r1=32607&r2=32608&view=diff
==============================================================================
--- trunk/src/game_preferences.hpp (original)
+++ trunk/src/game_preferences.hpp Wed Feb 4 22:48:16 2009
@@ -42,8 +42,8 @@
void _set_lobby_joins(int show);
enum { SHOW_NONE, SHOW_FRIENDS, SHOW_ALL };
- std::string get_friends();
- std::string get_ignores();
+ const std::set<std::string> & get_friends();
+ const std::set<std::string> & get_ignores();
bool add_friend(const std::string& nick);
bool add_ignore(const std::string& nick);
void remove_friend(const std::string& nick);
Modified: trunk/src/game_preferences_display.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/game_preferences_display.cpp?rev=32608&r1=32607&r2=32608&view=diff
==============================================================================
--- trunk/src/game_preferences_display.cpp (original)
+++ trunk/src/game_preferences_display.cpp Wed Feb 4 22:48:16 2009
@@ -993,12 +993,14 @@
void preferences_dialog::set_friends_menu()
{
- const std::vector<std::string>& friends =
utils::split(preferences::get_friends());
- const std::vector<std::string>& ignores =
utils::split(preferences::get_ignores());
+ const std::set<std::string>& friends = preferences::get_friends();
+ const std::set<std::string>& ignores = preferences::get_ignores();
+
std::vector<std::string> friends_items;
std::vector<std::string> friends_names;
std::string const imgpre = IMAGE_PREFIX + std::string("misc/status-");
- std::vector<std::string>::const_iterator i;
+
+ std::set<std::string>::const_iterator i;
for (i = friends.begin(); i != friends.end(); ++i)
{
friends_items.push_back(imgpre + "friend.png" + COLUMN_SEPARATOR
Modified: trunk/src/menu_events.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/menu_events.cpp?rev=32608&r1=32607&r2=32608&view=diff
==============================================================================
--- trunk/src/menu_events.cpp (original)
+++ trunk/src/menu_events.cpp Wed Feb 4 22:48:16 2009
@@ -2449,14 +2449,17 @@
chat_command_handler cch(*this, allies_only);
cch.dispatch(cmd);
}
+
void chat_command_handler::do_emote()
{
chat_handler_.send_chat_message("/me " + get_data(),
allies_only_);
}
+
void chat_command_handler::do_network_send()
{
chat_handler_.send_command(get_cmd(), get_data());
}
+
void chat_command_handler::do_whisper()
{
if (get_data(1).empty()) return command_failed_need_arg(1);
@@ -2471,6 +2474,7 @@
cwhisper["message"], game_display::MESSAGE_PRIVATE);
network::send_data(data, 0, true);
}
+
void chat_command_handler::do_log()
{
chat_handler_.change_logging(get_data());
@@ -2479,10 +2483,10 @@
void chat_command_handler::do_ignore()
{
if (get_arg(1).empty()) {
- const std::string& tmp = preferences::get_ignores();
- print("ignores list", tmp.empty() ? "(empty)" : tmp);
+ const std::set<std::string>& tmp =
preferences::get_ignores();
+ print("ignores list", tmp.empty() ? "(empty)" :
utils::join(tmp));
} else {
- for(int i = 1;!get_arg(i).empty();i++){
+ for(int i = 1; !get_arg(i).empty(); i++){
if (preferences::add_ignore(get_arg(i))) {
print("ignore", _("Added to ignore
list: ") + get_arg(i));
} else {
@@ -2491,11 +2495,12 @@
}
}
}
+
void chat_command_handler::do_friend()
{
if (get_arg(1).empty()) {
- const std::string& tmp = preferences::get_friends();
- print("friends list", tmp.empty() ? "(empty)" : tmp);
+ const std::set<std::string>& tmp =
preferences::get_friends();
+ print("friends list", tmp.empty() ? "(empty)" :
utils::join(tmp));
} else {
for(int i = 1;!get_arg(i).empty();i++){
if (preferences::add_friend(get_arg(i))) {
@@ -2506,6 +2511,7 @@
}
}
}
+
void chat_command_handler::do_remove()
{
for(int i = 1;!get_arg(i).empty();i++){
@@ -2514,19 +2520,25 @@
print("list", _("Removed from list: ") + get_arg(i));
}
}
+
void chat_command_handler::do_display()
{
- const std::string& text_friend = preferences::get_friends();
- const std::string& text_ignore = preferences::get_ignores();
- if (!text_friend.empty()) {
- print("friends list", text_friend);
- }
- if (!text_ignore.empty()) {
- print("ignores list", text_ignore);
- } else if (text_friend.empty()) {
+ const std::set<std::string> & friends =
preferences::get_friends();
+ const std::set<std::string> & ignores =
preferences::get_ignores();
+
+ if (!friends.empty()) {
+ print("friends list", utils::join(friends));
+ }
+
+ if (!ignores.empty()) {
+ print("ignores list", utils::join(ignores));
+ }
+
+ if (friends.empty() && ignores.empty()) {
print("list", _("There are no players on your friends
or ignore list."));
}
}
+
void chat_command_handler::do_version() {
print("version", game_config::revision);
}
Modified: trunk/src/serialization/string_utils.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/serialization/string_utils.cpp?rev=32608&r1=32607&r2=32608&view=diff
==============================================================================
--- trunk/src/serialization/string_utils.cpp (original)
+++ trunk/src/serialization/string_utils.cpp Wed Feb 4 22:48:16 2009
@@ -390,18 +390,6 @@
return matches;
}
-std::string join(std::vector< std::string > const &v, char c)
-{
- std::stringstream str;
- for(std::vector< std::string >::const_iterator i = v.begin(); i !=
v.end(); ++i) {
- str << *i;
- if (i + 1 != v.end())
- str << c;
- }
-
- return str.str();
-}
-
std::vector< std::string > quoted_split(std::string const &val, char c, int
flags, char quote)
{
std::vector<std::string> res;
Modified: trunk/src/serialization/string_utils.hpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/serialization/string_utils.hpp?rev=32608&r1=32607&r2=32608&view=diff
==============================================================================
--- trunk/src/serialization/string_utils.hpp (original)
+++ trunk/src/serialization/string_utils.hpp Wed Feb 4 22:48:16 2009
@@ -20,8 +20,10 @@
#include <algorithm>
#include <map>
+#include <sstream>
#include <string>
#include <vector>
+#include <boost/utility.hpp>
#include "../tstring.hpp"
#include "../util.hpp"
@@ -77,7 +79,18 @@
const char separator = 0 , std::string const &left="(",
std::string const &right=")",int flags = REMOVE_EMPTY | STRIP_SPACES);
-std::string join(std::vector< std::string > const &v, char c = ',');
+template <typename T>
+std::string join(T const &v, char c = ',')
+{
+ std::stringstream str;
+ for(typename T::const_iterator i = v.begin(); i != v.end(); ++i) {
+ str << *i;
+ if (boost::next(i) != v.end())
+ str << c;
+ }
+
+ return str.str();
+}
/**
* This function is identical to split(), except it does not split
Added: trunk/src/tests/test_serialization.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/tests/test_serialization.cpp?rev=32608&view=auto
==============================================================================
--- trunk/src/tests/test_serialization.cpp (added)
+++ trunk/src/tests/test_serialization.cpp Wed Feb 4 22:48:16 2009
@@ -1,0 +1,36 @@
+/* $Id$ */
+/*
+ Copyright (C) 2009 by Karol Nowak <[email protected]>
+ Part of the Battle for Wesnoth Project http://www.wesnoth.org/
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2
+ or at your option any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY.
+
+ See the COPYING file for more details.
+*/
+#include <vector>
+#include <string>
+#include "serialization/string_utils.hpp"
+#include <boost/test/auto_unit_test.hpp>
+
+BOOST_AUTO_TEST_CASE( utils_join_test )
+{
+ BOOST_MESSAGE( "Starting utils::join test!" );
+
+ std::vector<std::string> fruit;
+
+ BOOST_CHECK( utils::join(fruit) == "" );
+
+ fruit.push_back("apples");
+
+ BOOST_CHECK( utils::join(fruit) == "apples" );
+
+ fruit.push_back("oranges");
+ fruit.push_back("lemons");
+
+ BOOST_CHECK( utils::join(fruit) == "apples,oranges,lemons" );
+}
+
_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits