Index: client/civclient.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/civclient.c,v retrieving revision 1.145 diff -u -r1.145 civclient.c --- client/civclient.c 2002/08/25 11:20:55 1.145 +++ client/civclient.c 2002/09/07 08:06:23 @@ -449,6 +449,14 @@ handle_start_turn(); break; + case PACKET_FREEZE_HINT: + handle_freeze_hint(); + break; + + case PACKET_THAW_HINT: + handle_thaw_hint(); + break; + default: freelog(LOG_ERROR, "Received unknown packet (type %d) from server!", type); /* Old clients (<= some 1.11.5-devel, capstr +1.11) used to exit() @@ -572,6 +580,23 @@ { bool connect_error = (client_state == CLIENT_PRE_GAME_STATE) && (newstate == CLIENT_PRE_GAME_STATE); + + /* + * We are currently ignoring the CLIENT_GAME_OVER_STATE state + * because the client hasen't been changed to take care of it. So it + * breaks the show-whole-map-at-the-end-of-the-game. Nevertheless + * the server is so kind and sends the client this information. And + * in the future the client can/should take advantage of this + * information. + * + * FIXME: audit all client code to that it copes with + * CLIENT_GAME_OVER_STATE and implement specific + * CLIENT_GAME_OVER_STATE actions like history browsing. Then remove + * the kludge below. + */ + if (newstate == CLIENT_GAME_OVER_STATE) { + newstate = CLIENT_GAME_RUNNING_STATE; + } if(client_state!=newstate) { Index: client/climisc.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/climisc.c,v retrieving revision 1.101 diff -u -r1.101 climisc.c --- client/climisc.c 2002/08/08 22:10:17 1.101 +++ client/climisc.c 2002/09/07 08:06:24 @@ -1192,6 +1192,8 @@ **************************************************************************/ void reports_freeze(void) { + freelog(LOG_DEBUG, "reports_freeze"); + meswin_freeze(); plrdlg_freeze(); report_dialogs_freeze(); @@ -1215,6 +1217,8 @@ **************************************************************************/ void reports_thaw(void) { + freelog(LOG_DEBUG, "reports_thaw"); + meswin_thaw(); plrdlg_thaw(); report_dialogs_thaw(); Index: client/packhand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v retrieving revision 1.252 diff -u -r1.252 packhand.c --- client/packhand.c 2002/08/25 11:20:55 1.252 +++ client/packhand.c 2002/09/07 08:06:26 @@ -289,8 +289,6 @@ free_intro_radar_sprites(); agents_game_start(); - } else if(get_client_state() == CLIENT_GAME_OVER_STATE) { - reports_thaw(); } } @@ -677,7 +675,6 @@ void handle_before_new_year(void) { clear_notify_window(); - reports_freeze(); /* * The local idea of the game turn is increased here since the * client will get unit updates (reset of move points for example) @@ -695,8 +692,6 @@ **************************************************************************/ void handle_start_turn(void) { - reports_thaw(); - agents_start_turn(); turn_done_sent = FALSE; @@ -1632,8 +1627,6 @@ { int i; - reports_freeze(); - tilespec_free_city_tiles(game.styles_count); ruleset_data_free(); @@ -2345,4 +2338,28 @@ fc_realloc(reports_thaw_requests, reports_thaw_requests_size * sizeof(int)); reports_thaw_requests[reports_thaw_requests_size - 1] = request_id; +} + +/************************************************************************** +... +**************************************************************************/ +void handle_freeze_hint(void) +{ + freelog(LOG_DEBUG, "handle_freeze_hint"); + + reports_freeze(); + + agents_freeze_hint(); +} + +/************************************************************************** +... +**************************************************************************/ +void handle_thaw_hint(void) +{ + freelog(LOG_DEBUG, "handle_thaw_hint"); + + reports_thaw(); + + agents_thaw_hint(); } Index: client/packhand.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/packhand.h,v retrieving revision 1.28 diff -u -r1.28 packhand.h --- client/packhand.h 2002/08/25 11:20:55 1.28 +++ client/packhand.h 2002/09/07 08:06:26 @@ -62,6 +62,8 @@ void handle_processing_started(void); void handle_processing_finished(void); void handle_start_turn(void); +void handle_freeze_hint(void); +void handle_thaw_hint(void); void notify_about_incoming_packet(struct connection *pc, int packet_type, int size); Index: client/agents/agents.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/agents/agents.c,v retrieving revision 1.16 diff -u -r1.16 agents.c --- client/agents/agents.c 2002/08/24 14:37:36 1.16 +++ client/agents/agents.c 2002/09/07 08:06:26 @@ -352,10 +352,27 @@ /*********************************************************************** Called from client/packhand.c. ***********************************************************************/ +void agents_freeze_hint(void) +{ + freelog(META_CALLBACKS_LOGLEVEL, "agents_freeze_hint()"); + freeze(); +} + +/*********************************************************************** + Called from client/packhand.c. +***********************************************************************/ +void agents_thaw_hint(void) +{ + freelog(META_CALLBACKS_LOGLEVEL, "agents_thaw_hint()"); + thaw(); +} + +/*********************************************************************** + Called from client/packhand.c. +***********************************************************************/ void agents_game_joined(void) { freelog(META_CALLBACKS_LOGLEVEL, "agents_game_joined()"); - freeze(); } /*********************************************************************** @@ -372,7 +389,6 @@ void agents_before_new_turn(void) { freelog(META_CALLBACKS_LOGLEVEL, "agents_before_new_turn()"); - freeze(); } /*********************************************************************** @@ -381,7 +397,6 @@ void agents_start_turn(void) { freelog(META_CALLBACKS_LOGLEVEL, "agents_start_turn()"); - thaw(); } /*********************************************************************** Index: client/agents/agents.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/agents/agents.h,v retrieving revision 1.4 diff -u -r1.4 agents.h --- client/agents/agents.h 2002/06/07 16:11:24 1.4 +++ client/agents/agents.h 2002/09/07 08:06:26 @@ -48,6 +48,8 @@ void agents_disconnect(void); void agents_processing_started(void); void agents_processing_finished(void); +void agents_freeze_hint(void); +void agents_thaw_hint(void); void agents_game_joined(void); void agents_game_start(void); void agents_before_new_turn(void); Index: common/capstr.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v retrieving revision 1.107 diff -u -r1.107 capstr.c --- common/capstr.c 2002/09/02 02:19:54 1.107 +++ common/capstr.c 2002/09/07 08:06:28 @@ -70,7 +70,7 @@ * are not directly related to the capability strings discussed here.) */ -#define CAPABILITY "+1.13.0 conn_info turn_founded unitbv" +#define CAPABILITY "+1.13.0 conn_info turn_founded unitbv +freeze_thaw" /* "+1.13.0" is protocol for 1.13.0 release. @@ -81,6 +81,8 @@ "unitbv" extends unit flags and roles from 32 to 64 maximum and transmits the information as a bitvector instead of an int. + + "freeze_thaw" uses PACKET_FREEZE_HINT/PACKET_THAW_HINT. */ void init_our_capability(void) Index: common/packets.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/packets.c,v retrieving revision 1.214 diff -u -r1.214 packets.c --- common/packets.c 2002/08/25 11:20:58 1.214 +++ common/packets.c 2002/09/07 08:06:31 @@ -409,6 +409,8 @@ case PACKET_PROCESSING_FINISHED: case PACKET_START_TURN: case PACKET_SELECT_NATION_OK: + case PACKET_FREEZE_HINT: + case PACKET_THAW_HINT: return receive_packet_generic_empty(pc); case PACKET_NEW_YEAR: Index: common/packets.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/packets.h,v retrieving revision 1.122 diff -u -r1.122 packets.h --- common/packets.h 2002/09/06 19:38:01 1.122 +++ common/packets.h 2002/09/07 08:06:31 @@ -126,6 +126,8 @@ PACKET_PLAYER_ATTRIBUTE_BLOCK, PACKET_START_TURN, PACKET_SELECT_NATION_OK, + PACKET_FREEZE_HINT, + PACKET_THAW_HINT, PACKET_LAST /* leave this last */ }; Index: doc/HACKING =================================================================== RCS file: /home/freeciv/CVS/freeciv/doc/HACKING,v retrieving revision 1.3 diff -u -r1.3 HACKING --- doc/HACKING 2002/07/13 16:07:45 1.3 +++ doc/HACKING 2002/09/07 08:06:32 @@ -241,6 +241,27 @@ sent some updates the client data structure will now hold other values. +The PACKET_FREEZE_HINT and PACKET_THAW_HINT packets serve two +purposes: + + - Packets send between these two packets may contain multiple + information packets which may cause multiple updates of some GUI + items. PACKET_FREEZE_HINT and PACKET_THAW_HINT can now be used to + freeze the GUI at the time PACKET_FREEZE_HINT is received and only + update the GUI after the PACKET_THAW_HINT packet is received. + + - Packets send between these two packets may contain contradicting + information which may confuse a client-side AI (agents for + example). So any updates send between these two packets are only + processed after the PACKET_THAW_HINT packet is received. + +The following areas are wrapped by PACKET_FREEZE_HINT and +PACKET_THAW_HINT: + + - the data send if a new game starts + - the data send to a reconnecting player + - the end turn activities + The Xaw client uses XtAppAddInput() to tell Xt to call the callback functions, when something happens on the client socket. The Gtk+ client uses a similar gdk_input_add() call. Index: server/srv_main.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v retrieving revision 1.94 diff -u -r1.94 srv_main.c --- server/srv_main.c 2002/09/01 03:43:48 1.94 +++ server/srv_main.c 2002/09/07 08:06:34 @@ -1358,11 +1358,13 @@ join_game_accept(pconn, TRUE); introduce_game_to_connection(pconn); if(server_state==RUN_GAME_STATE) { + send_packet_generic_empty(pconn, PACKET_FREEZE_HINT); send_rulesets(&pconn->self); send_all_info(&pconn->self); send_game_state(&pconn->self, CLIENT_GAME_RUNNING_STATE); send_player_info(NULL,NULL); send_diplomatic_meetings(pconn); + send_packet_generic_empty(pconn, PACKET_THAW_HINT); send_packet_generic_empty(pconn, PACKET_START_TURN); } if (game.auto_ai_toggle && pplayer->ai.control) { @@ -1678,6 +1680,14 @@ eot_timer = new_timer_start(TIMER_CPU, TIMER_ACTIVE); + /* + * This will freeze the reports and agents at the client. + * + * Do this before the body so that the PACKET_THAW_HINT packet is + * balanced. + */ + lsend_packet_generic_empty(&game.est_connections, PACKET_FREEZE_HINT); + while(server_state==RUN_GAME_STATE) { /* absolute beginning of a turn */ freelog(LOG_DEBUG, "Begin turn"); @@ -1695,6 +1705,11 @@ ai_start_turn(); send_start_turn_to_clients(); + /* + * This will thaw the reports and agents at the client. + */ + lsend_packet_generic_empty(&game.est_connections, PACKET_THAW_HINT); + /* Before sniff (human player activites), report time to now: */ freelog(LOG_VERBOSE, "End/start-turn server/ai activities: %g seconds", read_timer_seconds(eot_timer)); @@ -1724,12 +1739,19 @@ sanity_check(); #endif - before_end_year(); - /* This empties the client Messages window; put this before - everything else below, since otherwise any messages from - the following parts get wiped out before the user gets a - chance to see them. --dwp + /* + * This empties the client Messages window; put this before + * everything else below, since otherwise any messages from the + * following parts get wiped out before the user gets a chance to + * see them. --dwp */ + before_end_year(); + + /* + * This will freeze the reports and agents at the client. + */ + lsend_packet_generic_empty(&game.est_connections, PACKET_FREEZE_HINT); + freelog(LOG_DEBUG, "Season of native unrests"); summon_barbarians(); /* wild guess really, no idea where to put it, but I want to give them chance to move their units */ @@ -1763,6 +1785,11 @@ if (is_game_over()) server_state=GAME_OVER_STATE; } + + /* + * This will thaw the reports and agents at the client. + */ + lsend_packet_generic_empty(&game.est_connections, PACKET_THAW_HINT); } /**************************************************************************