wesnoth-cvs-commits
[Top][All Lists]
Advanced

[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();
 
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]