[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Wesnoth-cvs-commits] wesnoth/src ai.cpp animated.cpp filechooser.cpp...
From: |
David White |
Subject: |
[Wesnoth-cvs-commits] wesnoth/src ai.cpp animated.cpp filechooser.cpp... |
Date: |
Sat, 26 Feb 2005 17:16:35 -0500 |
CVSROOT: /cvsroot/wesnoth
Module name: wesnoth
Branch:
Changes by: David White <address@hidden> 05/02/26 22:16:34
Modified files:
src : ai.cpp animated.cpp filechooser.cpp font.cpp
leader_list.cpp multiplayer.cpp
multiplayer_create.cpp multiplayer_ui.cpp
multiplayer_wait.cpp network.cpp
network_worker.cpp ai_interface.hpp network.hpp
network_worker.hpp
Log message:
change to network code to make receives threaded; changes to make the
game compile on VC++
CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/ai.cpp.diff?tr1=1.139&tr2=1.140&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/animated.cpp.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/filechooser.cpp.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/font.cpp.diff?tr1=1.104&tr2=1.105&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/leader_list.cpp.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/multiplayer.cpp.diff?tr1=1.139&tr2=1.140&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/multiplayer_create.cpp.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/multiplayer_ui.cpp.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/multiplayer_wait.cpp.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/network.cpp.diff?tr1=1.49&tr2=1.50&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/network_worker.cpp.diff?tr1=1.16&tr2=1.17&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/ai_interface.hpp.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/network.hpp.diff?tr1=1.21&tr2=1.22&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/network_worker.hpp.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
Patches:
Index: wesnoth/src/ai.cpp
diff -u wesnoth/src/ai.cpp:1.139 wesnoth/src/ai.cpp:1.140
--- wesnoth/src/ai.cpp:1.139 Sun Feb 20 22:04:29 2005
+++ wesnoth/src/ai.cpp Sat Feb 26 22:16:34 2005
@@ -1,4 +1,4 @@
-/* $Id: ai.cpp,v 1.139 2005/02/20 22:04:29 silene Exp $ */
+/* $Id: ai.cpp,v 1.140 2005/02/26 22:16:34 Sirp Exp $ */
/*
Copyright (C) 2003 by David White <address@hidden>
Part of the Battle for Wesnoth Project http://wesnoth.whitevine.net
@@ -351,7 +351,18 @@
}
}
-gamemap::location ai_interface::move_unit(location from, location to,
std::map<location,paths>& possible_moves)
+gamemap::location ai_interface::move_unit(location from, location to,
std::map<location,paths>& possible_moves)
+{
+ const location loc = move_unit_partial(from,to,possible_moves);
+ const unit_map::iterator u = info_.units.find(loc);
+ if(u != info_.units.end()) {
+ u->second.set_movement(0);
+ }
+
+ return loc;
+}
+
+gamemap::location ai_interface::move_unit_partial(location from, location to,
std::map<location,paths>& possible_moves)
{
LOG_AI << "ai_interface::move_unit " << (from.x + 1) << "," << (from.y
+ 1)
<< " -> " << (to.x + 1) << "," << (to.y + 1) << "\n";
@@ -373,7 +384,6 @@
if(from == to) {
LOG_AI << "moving unit at " << (from.x+1) << "," << (from.y+1)
<< " on spot. resetting moves\n";
- u_it->second.set_movement(0);
return to;
}
@@ -397,7 +407,9 @@
}
}
- if(rt != p.routes.end()) {
+ if(rt != p.routes.end()) {
+ current_unit.set_movement(rt->second.move_left);
+
std::vector<location> steps = rt->second.steps;
if(steps.empty() == false) {
@@ -420,7 +432,8 @@
}
}
- if(n != 6) {
+ if(n != 6) {
+ current_unit.set_movement(0);
//enter enemy ZoC, no movement left
break;
}
}
@@ -446,7 +459,6 @@
info_.units.erase(u_it);
}
- current_unit.set_movement(0);
info_.units.insert(std::pair<location,unit>(to,current_unit));
if(info_.map.is_village(to)) {
get_village(to,info_.teams,info_.team_num-1,info_.units);
@@ -1553,8 +1565,9 @@
for(std::map<std::string,int>::iterator j =
unit_movement_scores_.begin(); j != unit_movement_scores_.end(); ++j) {
const game_data::unit_type_map::const_iterator info =
gameinfo_.unit_types.find(j->first);
- if (info == gameinfo_.unit_types.end())
- continue;
+ if(info == gameinfo_.unit_types.end()) {
+ continue;
+ }
const int best_score = best_scores[info->second.usage()];
if(best_score > 0) {
Index: wesnoth/src/ai_interface.hpp
diff -u wesnoth/src/ai_interface.hpp:1.1 wesnoth/src/ai_interface.hpp:1.2
--- wesnoth/src/ai_interface.hpp:1.1 Sun Aug 29 11:48:34 2004
+++ wesnoth/src/ai_interface.hpp Sat Feb 26 22:16:34 2005
@@ -1,4 +1,4 @@
-/* $Id: ai_interface.hpp,v 1.1 2004/08/29 11:48:34 isaaccp Exp $ */
+/* $Id: ai_interface.hpp,v 1.2 2005/02/26 22:16:34 Sirp Exp $ */
/*
Copyright (C) 2003 by David White <address@hidden>
Part of the Battle for Wesnoth Project http://wesnoth.whitevine.net
@@ -98,7 +98,11 @@
///'from': the location of the unit being moved.
///'to': the location to be moved to. This must be a valid move for the
unit
///'possible_moves': the map of possible moves, as obtained from
'calculate_possible_moves'
- location move_unit(location from, location to,
std::map<location,paths>& possible_moves);
+ location move_unit(location from, location to,
std::map<location,paths>& possible_moves);
+
+ ///this function is identical to 'move_unit', except that the unit's
movement isn't set to 0
+ ///after the move is complete.
+ location move_unit_partial(location from, location t,
std::map<location,paths>& possible_moves);
///this function is used to calculate the moves units may possibly make.
///'possible_moves': a map which will be filled with the paths each
unit can take to
Index: wesnoth/src/animated.cpp
diff -u wesnoth/src/animated.cpp:1.1 wesnoth/src/animated.cpp:1.2
--- wesnoth/src/animated.cpp:1.1 Mon Feb 21 09:05:51 2005
+++ wesnoth/src/animated.cpp Sat Feb 26 22:16:34 2005
@@ -1,4 +1,4 @@
-/* $Id: animated.cpp,v 1.1 2005/02/21 09:05:51 silene Exp $ */
+/* $Id: animated.cpp,v 1.2 2005/02/26 22:16:34 Sirp Exp $ */
/*
Copyright (C) 2004 by Philippe Plantier <address@hidden>
Copyright (C) 2005 by Guillaume Melquiond <address@hidden>
@@ -11,6 +11,8 @@
See the COPYING file for more details.
*/
+
+#include "global.hpp"
//#include <string>
//#include <vector>
Index: wesnoth/src/filechooser.cpp
diff -u wesnoth/src/filechooser.cpp:1.2 wesnoth/src/filechooser.cpp:1.3
--- wesnoth/src/filechooser.cpp:1.2 Sun Dec 19 21:18:14 2004
+++ wesnoth/src/filechooser.cpp Sat Feb 26 22:16:34 2005
@@ -1,3 +1,5 @@
+#include "global.hpp"
+
#include "show_dialog.hpp"
#include "widgets/file_chooser.hpp"
#include <vector>
Index: wesnoth/src/font.cpp
diff -u wesnoth/src/font.cpp:1.104 wesnoth/src/font.cpp:1.105
--- wesnoth/src/font.cpp:1.104 Sat Feb 26 22:12:08 2005
+++ wesnoth/src/font.cpp Sat Feb 26 22:16:34 2005
@@ -1,4 +1,4 @@
-/* $Id: font.cpp,v 1.104 2005/02/26 22:12:08 gruikya Exp $ */
+/* $Id: font.cpp,v 1.105 2005/02/26 22:16:34 Sirp Exp $ */
/*
Copyright (C) 2003 by David White <address@hidden>
Part of the Battle for Wesnoth Project http://wesnoth.whitevine.net
@@ -752,121 +752,116 @@
return text;
}
+int line_width(const std::string line, int font_size, int style)
+{
+ const SDL_Color col = { 0, 0, 0, 0 };
+ text_surface s(line, font_size, col, style);
+ return s.width();
}
-namespace font {
-
- int line_width(const std::string line, int font_size, int style)
- {
- const SDL_Color col = { 0, 0, 0, 0 };
- text_surface s(line, font_size, col, style);
-
- return s.width();
- }
-
- std::string word_wrap_text(const std::string& unwrapped_text, int
font_size, int max_width)
- {
- //std::cerr << "Wrapping word " << unwrapped_text << "\n";
-
- std::string wrapped_text; // the final result
-
- size_t word_start_pos = 0;
- std::string cur_word; // including start-whitespace
- std::string cur_line; // the whole line so far
-
- for(size_t c = 0; c < unwrapped_text.length(); c++) {
+std::string word_wrap_text(const std::string& unwrapped_text, int font_size,
int max_width)
+{
+ //std::cerr << "Wrapping word " << unwrapped_text << "\n";
+
+ std::string wrapped_text; // the final result
- // Find the next word
- bool forced_line_break = false;
- if (c == unwrapped_text.length() - 1) {
- cur_word =
unwrapped_text.substr(word_start_pos, c + 1 - word_start_pos);
- word_start_pos = c + 1;
- } else if (unwrapped_text[c] == '\n') {
- cur_word =
unwrapped_text.substr(word_start_pos, c + 1 - word_start_pos);
- word_start_pos = c + 1;
- forced_line_break = true;
- } else if (unwrapped_text[c] == ' ') {
- cur_word =
unwrapped_text.substr(word_start_pos, c - word_start_pos);
- word_start_pos = c;
- } else {
- continue;
- }
+ size_t word_start_pos = 0;
+ std::string cur_word; // including start-whitespace
+ std::string cur_line; // the whole line so far
+
+ for(size_t c = 0; c < unwrapped_text.length(); c++) {
+
+ // Find the next word
+ bool forced_line_break = false;
+ if (c == unwrapped_text.length() - 1) {
+ cur_word = unwrapped_text.substr(word_start_pos, c + 1
- word_start_pos);
+ word_start_pos = c + 1;
+ } else if (unwrapped_text[c] == '\n') {
+ cur_word = unwrapped_text.substr(word_start_pos, c + 1
- word_start_pos);
+ word_start_pos = c + 1;
+ forced_line_break = true;
+ } else if (unwrapped_text[c] == ' ') {
+ cur_word = unwrapped_text.substr(word_start_pos, c -
word_start_pos);
+ word_start_pos = c;
+ } else {
+ continue;
+ }
- // Test if the line should be wrapped or not
- if (line_width(cur_line + cur_word, font_size) >
max_width) {
+ // Test if the line should be wrapped or not
+ if (line_width(cur_line + cur_word, font_size) > max_width) {
- if (line_width(cur_word, font_size) >
(max_width /*/ 2*/)) {
- // The last word is too big to fit in a
nice way, split it on a char basis
- std::vector<std::string> split_word =
split_utf8_string(cur_word);
-
- for (std::vector<std::string>::iterator
i = split_word.begin(); i != split_word.end(); ++i) {
- if (line_width(cur_line + *i,
font_size) > max_width) {
- wrapped_text +=
cur_line + '\n';
- cur_line = *i;
- } else {
- cur_line += *i;
- }
-
- }
-
- } else {
- // Split the line on a word basis
- wrapped_text += cur_line + '\n';
- cur_line = remove_first_space(cur_word);
+ if (line_width(cur_word, font_size) > (max_width /*/
2*/)) {
+ // The last word is too big to fit in a nice
way, split it on a char basis
+ std::vector<std::string> split_word =
split_utf8_string(cur_word);
+ for (std::vector<std::string>::iterator i =
split_word.begin(); i != split_word.end(); ++i) {
+ if (line_width(cur_line + *i,
font_size) > max_width) {
+ wrapped_text += cur_line + '\n';
+ cur_line = *i;
+ } else {
+ cur_line += *i;
+ }
+
}
+
} else {
- cur_line += cur_word;
- }
+ // Split the line on a word basis
+ wrapped_text += cur_line + '\n';
+ cur_line = remove_first_space(cur_word);
- if (forced_line_break) {
- wrapped_text += cur_line;
- cur_line = "";
- forced_line_break = false;
}
- }
-
- // Don't forget to add the text left in cur_line
- if (cur_line != "") {
- wrapped_text += cur_line + '\n';
+ } else {
+ cur_line += cur_word;
}
- return wrapped_text;
+ if (forced_line_break) {
+ wrapped_text += cur_line;
+ cur_line = "";
+ forced_line_break = false;
+ }
}
- std::string make_text_ellipsis(const std::string &text, int font_size,
int max_width)
- {
- static const std::string ellipsis = "...";
-
- if(line_width(text, font_size) <= max_width)
- return text;
- if(line_width(ellipsis, font_size) > max_width)
- return "";
-
- std::vector<std::string> characters = split_utf8_string(text);
- std::string current_substring = "";
+ // Don't forget to add the text left in cur_line
+ if (cur_line != "") {
+ wrapped_text += cur_line + '\n';
+ }
- for(std::vector<std::string>::const_iterator itor =
characters.begin(); itor != characters.end(); ++itor) {
- if (line_width(current_substring + *itor + ellipsis,
font_size ) > max_width) {
- return current_substring + ellipsis;
- }
-
- current_substring += *itor;
- }
+ return wrapped_text;
+}
- return text; // Should not happen
- }
+std::string make_text_ellipsis(const std::string &text, int font_size, int
max_width)
+{
+ static const std::string ellipsis = "...";
- SDL_Rect draw_wrapped_text(display* gui, const SDL_Rect& area, int
font_size,
- const SDL_Color& colour, const std::string& text,
- int x, int y, int max_width)
- {
- std::string wrapped_text = word_wrap_text(text, font_size,
max_width);
- return font::draw_text(gui, area, font_size, colour,
wrapped_text, x, y, false);
+ if(line_width(text, font_size) <= max_width)
+ return text;
+ if(line_width(ellipsis, font_size) > max_width)
+ return "";
+
+ std::vector<std::string> characters = split_utf8_string(text);
+ std::string current_substring = "";
+
+ for(std::vector<std::string>::const_iterator itor = characters.begin();
itor != characters.end(); ++itor) {
+ if (line_width(current_substring + *itor + ellipsis, font_size
) > max_width) {
+ return current_substring + ellipsis;
+ }
+
+ current_substring += *itor;
}
+ return text; // Should not happen
+}
+
+SDL_Rect draw_wrapped_text(display* gui, const SDL_Rect& area, int font_size,
+ const SDL_Color& colour, const std::string& text,
+ int x, int y, int max_width)
+{
+ std::string wrapped_text = word_wrap_text(text, font_size, max_width);
+ return font::draw_text(gui, area, font_size, colour, wrapped_text, x,
y, false);
+}
+
}
//floating labels
@@ -1232,7 +1227,9 @@
fontlist.back().present_codepoints.push_back(std::pair<size_t, size_t>(r1, r2));
}
- }
+ }
+
+ return true;
}
}
Index: wesnoth/src/leader_list.cpp
diff -u wesnoth/src/leader_list.cpp:1.4 wesnoth/src/leader_list.cpp:1.5
--- wesnoth/src/leader_list.cpp:1.4 Sat Feb 26 21:18:14 2005
+++ wesnoth/src/leader_list.cpp Sat Feb 26 22:16:34 2005
@@ -1,4 +1,4 @@
-/* $Id: leader_list.cpp,v 1.4 2005/02/26 21:18:14 gruikya Exp $ */
+/* $Id: leader_list.cpp,v 1.5 2005/02/26 22:16:34 Sirp Exp $ */
/*
Copyright (C)
Part of the Battle for Wesnoth Project http://www.wesnoth.org
@@ -10,7 +10,8 @@
See the COPYING file for more details.
*/
-
+
+#include "global.hpp"
#include "leader_list.hpp"
#include "wml_separators.hpp"
#include "serialization/string_utils.hpp"
Index: wesnoth/src/multiplayer.cpp
diff -u wesnoth/src/multiplayer.cpp:1.139 wesnoth/src/multiplayer.cpp:1.140
--- wesnoth/src/multiplayer.cpp:1.139 Thu Feb 24 23:39:35 2005
+++ wesnoth/src/multiplayer.cpp Sat Feb 26 22:16:34 2005
@@ -1,4 +1,4 @@
-/* $Id: multiplayer.cpp,v 1.139 2005/02/24 23:39:35 gruikya Exp $ */
+/* $Id: multiplayer.cpp,v 1.140 2005/02/26 22:16:34 Sirp Exp $ */
/*
Copyright (C)
Part of the Battle for Wesnoth Project http://www.wesnoth.org
@@ -10,7 +10,8 @@
See the COPYING file for more details.
*/
-
+
+#include "global.hpp"
#include "multiplayer.hpp"
#include "multiplayer_ui.hpp"
#include "multiplayer_connect.hpp"
Index: wesnoth/src/multiplayer_create.cpp
diff -u wesnoth/src/multiplayer_create.cpp:1.4
wesnoth/src/multiplayer_create.cpp:1.5
--- wesnoth/src/multiplayer_create.cpp:1.4 Sat Feb 26 19:50:00 2005
+++ wesnoth/src/multiplayer_create.cpp Sat Feb 26 22:16:34 2005
@@ -1,4 +1,4 @@
-/* $Id: multiplayer_create.cpp,v 1.4 2005/02/26 19:50:00 gruikya Exp $ */
+/* $Id: multiplayer_create.cpp,v 1.5 2005/02/26 22:16:34 Sirp Exp $ */
/*
Copyright (C)
Part of the Battle for Wesnoth Project http://www.wesnoth.org
@@ -10,7 +10,8 @@
See the COPYING file for more details.
*/
-
+
+#include "global.hpp"
#include "show_dialog.hpp"
#include "multiplayer_create.hpp"
#include "filesystem.hpp"
Index: wesnoth/src/multiplayer_ui.cpp
diff -u wesnoth/src/multiplayer_ui.cpp:1.5 wesnoth/src/multiplayer_ui.cpp:1.6
--- wesnoth/src/multiplayer_ui.cpp:1.5 Thu Feb 24 23:39:35 2005
+++ wesnoth/src/multiplayer_ui.cpp Sat Feb 26 22:16:34 2005
@@ -1,4 +1,4 @@
-/* $Id: multiplayer_ui.cpp,v 1.5 2005/02/24 23:39:35 gruikya Exp $ */
+/* $Id: multiplayer_ui.cpp,v 1.6 2005/02/26 22:16:34 Sirp Exp $ */
/*
Copyright (C)
Part of the Battle for Wesnoth Project http://www.wesnoth.org
@@ -10,7 +10,8 @@
See the COPYING file for more details.
*/
-
+
+#include "global.hpp"
#include "multiplayer_ui.hpp"
#include "network.hpp"
#include "preferences.hpp"
Index: wesnoth/src/multiplayer_wait.cpp
diff -u wesnoth/src/multiplayer_wait.cpp:1.5
wesnoth/src/multiplayer_wait.cpp:1.6
--- wesnoth/src/multiplayer_wait.cpp:1.5 Sat Feb 26 21:18:14 2005
+++ wesnoth/src/multiplayer_wait.cpp Sat Feb 26 22:16:34 2005
@@ -1,4 +1,4 @@
-/* $Id: multiplayer_wait.cpp,v 1.5 2005/02/26 21:18:14 gruikya Exp $ */
+/* $Id: multiplayer_wait.cpp,v 1.6 2005/02/26 22:16:34 Sirp Exp $ */
/*
Copyright (C)
Part of the Battle for Wesnoth Project http://www.wesnoth.org
@@ -10,6 +10,8 @@
See the COPYING file for more details.
*/
+
+#include "global.hpp"
#include "log.hpp"
#include "multiplayer_wait.hpp"
Index: wesnoth/src/network.cpp
diff -u wesnoth/src/network.cpp:1.49 wesnoth/src/network.cpp:1.50
--- wesnoth/src/network.cpp:1.49 Fri Dec 31 21:01:37 2004
+++ wesnoth/src/network.cpp Sat Feb 26 22:16:34 2005
@@ -92,7 +92,7 @@
if(sock) {
for(connection_map::const_iterator i = connections.begin(); i
!= connections.end(); ++i) {
if(i->second.sock == sock) {
- throw network::error("Error sending
data",i->first);
+ throw network::error("Socket error",i->first);
}
}
}
@@ -117,10 +117,6 @@
size_t upto;
};
-typedef std::map<network::connection,partial_buffer> partial_map;
-partial_map received_data;
-partial_map::const_iterator current_connection = received_data.end();
-
TCPsocket server_socket;
std::deque<network::connection> disconnection_queue;
@@ -386,8 +382,6 @@
schemas.erase(s);
bad_sockets.erase(s);
- received_data.erase(s);
- current_connection = received_data.end();
std::deque<network::connection>::iterator dqi =
std::find(disconnection_queue.begin(),disconnection_queue.end(),s);
if(dqi != disconnection_queue.end()) {
@@ -416,7 +410,28 @@
disconnection_queue.push_back(sock);
}
-connection receive_data(config& cfg, connection connection_num, int timeout)
+connection receive_data(config& cfg, connection connection_num, int timeout)
+{
+ int cur_ticks = SDL_GetTicks();
+ while(timeout >= 0) {
+ const connection res = receive_data(cfg,connection_num);
+ if(res != 0) {
+ return res;
+ }
+
+ if(timeout > 0) {
+ SDL_Delay(1);
+ }
+
+ const int ticks = SDL_GetTicks();
+ timeout -= maximum<int>(1,(ticks - cur_ticks));
+ cur_ticks = ticks;
+ }
+
+ return 0;
+}
+
+connection receive_data(config& cfg, connection connection_num)
{
if(!socket_set) {
return 0;
@@ -438,14 +453,9 @@
return 0;
}
- const int starting_ticks = SDL_GetTicks();
+ const int res = SDLNet_CheckSockets(socket_set,0);
- const int res = SDLNet_CheckSockets(socket_set,timeout);
- if(res <= 0) {
- return 0;
- }
-
- for(sockets_list::const_iterator i = sockets.begin(); i !=
sockets.end(); ++i) {
+ for(sockets_list::const_iterator i = sockets.begin(); res != 0 && i !=
sockets.end(); ++i) {
connection_details& details = get_connection_details(*i);
const TCPsocket sock = details.sock;
if(SDLNet_SocketReady(sock)) {
@@ -462,88 +472,41 @@
const int remote_handle = SDLNet_Read32(buf);
set_remote_handle(*i,remote_handle);
- break;
- }
-
-
- std::map<connection,partial_buffer>::iterator
part_received = received_data.find(*i);
- if(part_received == received_data.end()) {
- char num_buf[4];
- int len = SDLNet_TCP_Recv(sock,num_buf,4);
-
- if(len != 4) {
- throw error("Remote host
disconnected",*i);
- }
-
- details.received += len;
-
- len = SDLNet_Read32(num_buf);
-
- LOG_NW << "received packet length: " << len <<
"\n";
-
- if((len < 1) || (len > 10000000)) {
- WRN_NW << "bad length in network
packet. Throwing error\n";
- throw error("network error: bad length
data",*i);
- }
-
- part_received =
received_data.insert(std::pair<connection,partial_buffer>(*i,partial_buffer())).first;
- part_received->second.buf.resize(len);
-
- //make sure that this connection still has data
- const int res =
SDLNet_CheckSockets(socket_set,0);
- if(res <= 0 || !SDLNet_SocketReady(sock)) {
- WRN_NW << "packet has no data after
length. Throwing error\n";
- throw error("network error: received
wrong number of bytes: 0",*i);
- }
- }
-
- current_connection = part_received;
- partial_buffer& buf = part_received->second;
-
- const size_t expected = buf.buf.size() - buf.upto;
- const int nbytes =
SDLNet_TCP_Recv(sock,&buf.buf[buf.upto],expected);
- if(nbytes <= 0) {
- WRN_NW << "SDLNet_TCP_Recv returned " << nbytes
<< " error in socket\n";
- throw error("remote host disconnected",*i);
- }
-
- details.received += nbytes;
-
- buf.upto += nbytes;
- LOG_NW << "received " << nbytes << "=" << buf.upto <<
"/" << buf.buf.size() << "\n";
-
- if(buf.upto == buf.buf.size()) {
- current_connection = received_data.end();
- const std::string
buffer(buf.buf.begin(),buf.buf.end());
- received_data.erase(part_received);
//invalidates buf. don't use again
- if(buffer == "") {
- WRN_NW << "buffer from remote host is
empty\n";
- throw error("remote host closed
connection",*i);
- }
-
- if(buffer[buffer.size()-1] != 0) {
- WRN_NW << "buf not nul-delimited.
Network error\n";
- throw error("sanity check on incoming
data failed",*i);
- }
-
- const schema_map::iterator schema =
schemas.find(*i);
- wassert(schema != schemas.end());
-
-
cfg.read_compressed(buffer,schema->second.incoming);
-
-// std::cerr << "--- RECEIVED DATA from " <<
((int)*i) << ": '"
-// << cfg.write() << "'\n--- END
RECEIVED DATA\n";
-
-
- return *i;
- }
- }
- }
-
- const int time_taken = SDL_GetTicks() - starting_ticks;
- const int time_left = maximum<int>(0,timeout - time_taken);
-
- return receive_data(cfg,connection_num,time_left);
+ continue;
+ }
+
+ network_worker_pool::receive_data(sock);
+ SDLNet_TCP_DelSocket(socket_set,sock);
+ }
+ }
+
+ std::vector<char> buf;
+ TCPsocket sock = connection_num == 0 ? 0 : get_socket(connection_num);
+ sock = network_worker_pool::get_received_data(sock,buf);
+ if(sock == NULL) {
+ return 0;
+ }
+
+ SDLNet_TCP_AddSocket(socket_set,sock);
+
+ connection result = 0;
+ for(connection_map::const_iterator j = connections.begin(); j !=
connections.end(); ++j) {
+ if(j->second.sock == sock) {
+ result = j->first;
+ break;
+ }
+ }
+
+ if(result == 0) {
+ return result;
+ }
+
+ const schema_map::iterator schema = schemas.find(result);
+ wassert(schema != schemas.end());
+
+
cfg.read_compressed(std::string(buf.begin(),buf.end()),schema->second.incoming);
+
+ return result;
}
namespace {
@@ -646,10 +609,7 @@
std::pair<int,int> current_transfer_stats()
{
- if(current_connection == received_data.end())
- return std::pair<int,int>(-1,-1);
- else
- return
std::pair<int,int>(current_connection->second.upto,current_connection->second.buf.size());
+ return std::pair<int,int>(-1,-1);
}
} //end namespace network
Index: wesnoth/src/network.hpp
diff -u wesnoth/src/network.hpp:1.21 wesnoth/src/network.hpp:1.22
--- wesnoth/src/network.hpp:1.21 Thu Dec 9 19:52:46 2004
+++ wesnoth/src/network.hpp Sat Feb 26 22:16:34 2005
@@ -80,7 +80,8 @@
//received in cfg. Times out after timeout milliseconds. Returns
//the connection that data was received from, or 0 if timeout
//occurred. Throws error if an error occurred.
-connection receive_data(config& cfg, connection connection_num=0, int
timeout=0);
+connection receive_data(config& cfg, connection connection_num=0);
+connection receive_data(config& cfg, connection connection_num, int timeout);
//sets the default maximum number of bytes to send to a client at a time
void set_default_send_size(size_t send_size);
Index: wesnoth/src/network_worker.cpp
diff -u wesnoth/src/network_worker.cpp:1.16 wesnoth/src/network_worker.cpp:1.17
--- wesnoth/src/network_worker.cpp:1.16 Sun Feb 6 10:40:12 2005
+++ wesnoth/src/network_worker.cpp Sat Feb 26 22:16:34 2005
@@ -5,8 +5,10 @@
#include "network.hpp"
#include "thread.hpp"
#include "wassert.hpp"
-
-#include <cerrno>
+
+#include <algorithm>
+#include <cerrno>
+#include <deque>
#include <iostream>
#include <map>
#include <vector>
@@ -26,7 +28,19 @@
bool managed = false;
typedef std::vector< buffer * > buffer_set;
-buffer_set bufs;
+buffer_set bufs;
+
+//a queue of sockets that we are waiting to receive on
+typedef std::vector<TCPsocket> receive_list;
+receive_list pending_receives;
+
+//access to this variable isn't synchronized -- it's non-critical
+//and we don't want to pay the synchronization cost when it's rarely
+//cared about.
+std::pair<int,int> current_transfer_stats;
+
+typedef std::deque<buffer> received_queue;
+received_queue received_data_queue;
enum SOCKET_STATE { SOCKET_READY, SOCKET_LOCKED, SOCKET_ERROR };
typedef std::map<TCPsocket,SOCKET_STATE> socket_state_map;
@@ -35,13 +49,53 @@
threading::mutex* global_mutex = NULL;
threading::condition* cond = NULL;
-std::vector<threading::thread*> threads;
+std::vector<threading::thread*> threads;
+
+SOCKET_STATE receive_buf(TCPsocket sock, std::vector<char>& buf)
+{
+ char num_buf[4];
+ int len = SDLNet_TCP_Recv(sock,num_buf,4);
+
+ if(len != 4) {
+ return SOCKET_ERROR;
+ }
+
+ len = SDLNet_Read32(num_buf);
+
+ if(len < 1 || len > 100000000) {
+ return SOCKET_ERROR;
+ }
+
+ buf.resize(len);
+ char* beg = &buf[0];
+ const char* const end = beg + len;
+
+ current_transfer_stats.first = 0;
+ current_transfer_stats.second = len;
+
+ while(beg != end) {
+ const int len = SDLNet_TCP_Recv(sock,&buf[0],end - beg);
+ if(len <= 0) {
+ return SOCKET_ERROR;
+ }
+
+ beg += len;
+
+ current_transfer_stats.first = beg - &buf[0];
+ }
+
+ return SOCKET_READY;
+}
int process_queue(void* data)
{
LOG_NW << "thread started...\n";
for(;;) {
-
+
+ //if we find a socket to send data to, sent_buf will be
non-NULL. If we find a socket
+ //to receive data from, sent_buf will be NULL. 'sock' will
always refer to the socket
+ //that data is being sent to/received from
+ TCPsocket sock = NULL;
buffer *sent_buf = NULL;
{
@@ -54,54 +108,81 @@
socket_state_map::iterator lock_it =
sockets_locked.find((*itor)->sock);
wassert(lock_it !=
sockets_locked.end());
if(lock_it->second == SOCKET_READY) {
- lock_it->second = SOCKET_LOCKED;
+ sent_buf = *itor;
+ sock = sent_buf->sock;
+ bufs.erase(itor);
break;
}
+ }
+
+ if(sock == NULL) {
+ receive_list::iterator itor =
pending_receives.begin(), itor_end = pending_receives.end();
+ for(; itor != itor_end; ++itor) {
+ socket_state_map::iterator
lock_it = sockets_locked.find(*itor);
+ wassert(lock_it !=
sockets_locked.end());
+ if(lock_it->second ==
SOCKET_READY) {
+ sock = *itor;
+
pending_receives.erase(itor);
+ break;
+ }
+ }
+ }
+
+ if(sock != NULL) {
+ break;
}
- if(itor == itor_end) {
- if(managed == false) {
- LOG_NW << "worker thread
exiting...\n";
- return 0;
- }
-
- cond->wait(*global_mutex); //
temporarily release the mutex and wait for a buffer
- continue;
- } else {
- sent_buf = *itor;
- bufs.erase(itor);
- break; // a buffer has been found
+ if(managed == false) {
+ LOG_NW << "worker thread exiting...\n";
+ return 0;
}
+
+ cond->wait(*global_mutex); // temporarily
release the mutex and wait for a buffer
}
- }
+ }
+
+ wassert(sock);
LOG_NW << "thread found a buffer...\n";
- SOCKET_STATE result = SOCKET_READY;
-
- std::vector<char> &v = sent_buf->buf;
- for(size_t upto = 0, size = v.size(); result != SOCKET_ERROR &&
upto < size; ) {
- const int bytes_to_send = int(size - upto);
- const int res = SDLNet_TCP_Send(sent_buf->sock,
&v[upto], bytes_to_send);
- if(res < 0 || res != bytes_to_send && errno != EAGAIN) {
- result = SOCKET_ERROR;
- } else {
- upto += res;
- }
+ SOCKET_STATE result = SOCKET_READY;
+ std::vector<char> buf;
+
+ if(sent_buf != NULL) {
+ std::vector<char> &v = sent_buf->buf;
+ for(size_t upto = 0, size = v.size(); result !=
SOCKET_ERROR && upto < size; ) {
+ const int bytes_to_send = int(size - upto);
+ const int res = SDLNet_TCP_Send(sent_buf->sock,
&v[upto], bytes_to_send);
+ if(res < 0 || res != bytes_to_send && errno !=
EAGAIN) {
+ result = SOCKET_ERROR;
+ } else {
+ upto += res;
+ }
+ }
+
+ delete sent_buf;
+ sent_buf = NULL;
+
+ LOG_NW << "thread sent " << v.size() << " bytes of
data...\n";
+ } else {
+ result = receive_buf(sock,buf);
}
- LOG_NW << "thread sent " << v.size() << " bytes of data...\n";
-
{
const threading::lock lock(*global_mutex);
- socket_state_map::iterator lock_it =
sockets_locked.find(sent_buf->sock);
+ socket_state_map::iterator lock_it =
sockets_locked.find(sock);
wassert(lock_it != sockets_locked.end());
lock_it->second = result;
if(result == SOCKET_ERROR) {
++socket_errors;
+ }
+
+ //if we received data, add it to the queue
+ if(result == SOCKET_READY && buf.empty() == false) {
+ received_data_queue.push_back(buffer(sock));
+ received_data_queue.back().buf.swap(buf);
}
}
- delete sent_buf;
}
// unreachable
}
@@ -151,6 +232,40 @@
LOG_NW << "exiting manager::~manager()\n";
}
}
+
+void receive_data(TCPsocket sock)
+{
+ {
+ const threading::lock lock(*global_mutex);
+
+ pending_receives.push_back(sock);
+
sockets_locked.insert(std::pair<TCPsocket,SOCKET_STATE>(sock,SOCKET_READY));
+ }
+
+ cond->notify_one();
+}
+
+TCPsocket get_received_data(TCPsocket sock, std::vector<char>& buf)
+{
+ const threading::lock lock(*global_mutex);
+ received_queue::iterator itor = received_data_queue.begin();
+ if(sock != NULL) {
+ for(; itor != received_data_queue.end(); ++itor) {
+ if(itor->sock == sock) {
+ break;
+ }
+ }
+ }
+
+ if(itor == received_data_queue.end()) {
+ return NULL;
+ } else {
+ buf.swap(itor->buf);
+ const TCPsocket res = itor->sock;
+ received_data_queue.erase(itor);
+ return res;
+ }
+}
void queue_data(TCPsocket sock, std::vector<char>& buf)
{
@@ -182,7 +297,15 @@
else
new_bufs.push_back(*i);
}
- bufs.swap(new_bufs);
+ bufs.swap(new_bufs);
+
+ for(received_queue::iterator j = received_data_queue.begin(); j !=
received_data_queue.end(); ) {
+ if(j->sock == sock) {
+ j = received_data_queue.erase(j);
+ } else {
+ ++j;
+ }
+ }
}
}
@@ -194,7 +317,11 @@
SDL_Delay(10);
}
- const threading::lock lock(*global_mutex);
+ const threading::lock lock(*global_mutex);
+
+ if(first_time) {
+
pending_receives.erase(std::remove(pending_receives.begin(),pending_receives.end(),sock),pending_receives.end());
+ }
const socket_state_map::iterator lock_it =
sockets_locked.find(sock);
@@ -226,6 +353,11 @@
}
return 0;
+}
+
+std::pair<int,int> get_current_transfer_stats()
+{
+ return current_transfer_stats;
}
}
\ No newline at end of file
Index: wesnoth/src/network_worker.hpp
diff -u wesnoth/src/network_worker.hpp:1.1 wesnoth/src/network_worker.hpp:1.2
--- wesnoth/src/network_worker.hpp:1.1 Mon Oct 11 23:46:40 2004
+++ wesnoth/src/network_worker.hpp Sat Feb 26 22:16:34 2005
@@ -1,6 +1,7 @@
#ifndef NETWORK_WORKER_HPP_INCLUDED
#define NETWORK_WORKER_HPP_INCLUDED
-
+
+#include <map>
#include <vector>
#include "SDL_net.h"
@@ -19,11 +20,18 @@
bool active_;
};
+
+//function to asynchronously received data to the given socket
+void receive_data(TCPsocket sock);
+
+TCPsocket get_received_data(TCPsocket sock, std::vector<char>& buf);
void queue_data(TCPsocket sock, std::vector<char>& buf);
bool socket_locked(TCPsocket sock);
void close_socket(TCPsocket sock);
-TCPsocket detect_error();
+TCPsocket detect_error();
+
+std::pair<int,int> get_current_transfer_stats();
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Wesnoth-cvs-commits] wesnoth/src ai.cpp animated.cpp filechooser.cpp...,
David White <=