[Freeciv-Dev] (PR#13638) Client hangs after meeting
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13638 >
This is an update of the PR#12219 patch that probably fixes the problem
for 2.0. I haven't tested it and don't plan to commit it unless it gets
some extensive testing.
-jason
? timer-2.0.diff
Index: client/civclient.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/civclient.c,v
retrieving revision 1.197.2.9
diff -p -u -r1.197.2.9 civclient.c
--- client/civclient.c 22 Feb 2005 00:00:32 -0000 1.197.2.9
+++ client/civclient.c 11 Aug 2005 01:52:43 -0000
@@ -20,6 +20,7 @@
#endif
#include <assert.h>
+#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
@@ -38,6 +39,7 @@
#include "packets.h"
#include "rand.h"
#include "support.h"
+#include "timing.h"
#include "version.h"
#include "agents.h"
@@ -87,8 +89,6 @@ bool auto_connect = FALSE; /* TRUE = ski
static enum client_states client_state = CLIENT_BOOT_STATE;
-int seconds_to_turndone;
-
/* TRUE if an end turn request is blocked by busy agents */
bool waiting_for_end_turn = FALSE;
@@ -604,16 +604,60 @@ bool client_is_observer(void)
return aconnection.established && aconnection.observer;
}
+/* Seconds_to_turndone is the number of seconds the server has told us
+ * are left. The timer tells exactly how much time has passed since the
+ * server gave us that data. */
+static double seconds_to_turndone = 0.0;
+static struct timer *turndone_timer;
+
+/* This value shows what value the timeout label is currently showing for
+ * the seconds-to-turndone. */
+static int seconds_shown_to_turndone;
+
+/**************************************************************************
+ Reset the number of seconds to turndone from an "authentic" source.
+
+ The seconds are taken as a double even though most callers will just
+ know an integer value.
+**************************************************************************/
+void set_seconds_to_turndone(double seconds)
+{
+ if (game.timeout > 0) {
+ seconds_to_turndone = seconds;
+ turndone_timer = renew_timer_start(turndone_timer, TIMER_USER,
+ TIMER_ACTIVE);
+
+ /* Maybe we should do an update_timeout_label here, but it doesn't
+ * seem to be necessary. */
+ seconds_shown_to_turndone = ceil(seconds) + 0.1;
+ }
+}
+
+/**************************************************************************
+ Return the number of seconds until turn-done. Don't call this unless
+ game.timeout != 0.
+**************************************************************************/
+int get_seconds_to_turndone(void)
+{
+ if (game.timeout > 0) {
+ return seconds_shown_to_turndone;
+ } else {
+ /* This shouldn't happen. */
+ return FC_INFINITY;
+ }
+}
+
/**************************************************************************
- This function should be called every 500ms. It lets the unit blink
- and update the timeout.
+ This function should be called at least once per second. It does various
+ updates (idle animations and timeout updates). It returns the number of
+ seconds until it should be called again.
**************************************************************************/
-void real_timer_callback(void)
+double real_timer_callback(void)
{
- static bool flip = FALSE;
+ double time_until_next_call = 1.0;
if (get_client_state() != CLIENT_GAME_RUNNING_STATE) {
- return;
+ return time_until_next_call;
}
if (game.player_ptr->is_connected && game.player_ptr->is_alive &&
@@ -635,18 +679,26 @@ void real_timer_callback(void)
}
}
- blink_active_unit();
+ if (get_unit_in_focus()) {
+ double blink_time = blink_active_unit();
- if (flip) {
- update_timeout_label();
- if (seconds_to_turndone > 0) {
- seconds_to_turndone--;
- } else {
- seconds_to_turndone = 0;
+ time_until_next_call = MIN(time_until_next_call, blink_time);
+ }
+
+ if (game.timeout > 0) {
+ double seconds = seconds_to_turndone - read_timer_seconds(turndone_timer);
+ int iseconds = ceil(seconds) + 0.1; /* Turn should end right on 0. */
+
+ if (iseconds < seconds_shown_to_turndone) {
+ seconds_shown_to_turndone = iseconds;
+ update_timeout_label();
}
+
+ time_until_next_call = MIN(time_until_next_call,
+ seconds - floor(seconds) + 0.001);
}
- flip = !flip;
+ return MAX(time_until_next_call, 0.0);
}
/**************************************************************************
Index: client/civclient.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/civclient.h,v
retrieving revision 1.35
diff -p -u -r1.35 civclient.h
--- client/civclient.h 29 Sep 2004 02:24:19 -0000 1.35
+++ client/civclient.h 11 Aug 2005 01:52:43 -0000
@@ -22,7 +22,7 @@
* called. TIMER_INTERVAL has to stay 500 because real_timer_callback
* also updates the timeout info.
*/
-#define TIMER_INTERVAL 500
+#define TIMER_INTERVAL (int)(real_timer_callback() * 1000)
void handle_packet_input(void *packet, int type);
@@ -52,11 +52,11 @@ extern bool auto_connect;
extern bool waiting_for_end_turn;
extern bool turn_done_sent;
-extern int seconds_to_turndone;
-
void wait_till_request_got_processed(int request_id);
bool client_is_observer(void);
-void real_timer_callback(void);
+void set_seconds_to_turndone(double seconds);
+int get_seconds_to_turndone(void);
+double real_timer_callback(void);
bool can_client_issue_orders(void);
bool can_client_change_view(void);
bool can_meet_with_player(struct player *pplayer);
Index: client/control.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.c,v
retrieving revision 1.143.2.13
diff -p -u -r1.143.2.13 control.c
--- client/control.c 26 May 2005 04:55:19 -0000 1.143.2.13
+++ client/control.c 11 Aug 2005 01:52:44 -0000
@@ -21,6 +21,7 @@
#include "log.h"
#include "map.h"
#include "mem.h"
+#include "timing.h"
#include "audio.h"
#include "chatline_g.h"
@@ -372,24 +373,41 @@ struct unit *find_visible_unit(struct ti
/**************************************************************************
...
**************************************************************************/
-void blink_active_unit(void)
+double blink_active_unit(void)
{
static bool is_shown;
static struct unit *pblinking_unit;
- struct unit *punit;
+ static struct timer *blink_timer = NULL;
+ const double blink_time = 0.5;
+
+ struct unit *punit = punit_focus;
+ bool need_update = FALSE;
- if ((punit = punit_focus)) {
+ if (punit) {
if (punit != pblinking_unit) {
/* When the focus unit changes, we reset the is_shown flag. */
pblinking_unit = punit;
is_shown = TRUE;
+ need_update = TRUE;
} else {
- /* Reverse the shown status. */
- is_shown = !is_shown;
+ if (read_timer_seconds(blink_timer) > blink_time) {
+ /* Reverse the shown status. */
+ is_shown = !is_shown;
+ need_update = TRUE;
+ }
+ }
+ if (need_update) {
+ /* If we lag, we don't try to catch up. Instead we just start a
+ * new blink_time on every update. */
+ blink_timer = renew_timer_start(blink_timer, TIMER_USER, TIMER_ACTIVE);
+ set_focus_unit_hidden_state(!is_shown);
+ refresh_tile_mapcanvas(punit->tile, TRUE);
}
- set_focus_unit_hidden_state(!is_shown);
- refresh_tile_mapcanvas(punit->tile, TRUE);
+
+ return blink_time - read_timer_seconds(blink_timer);
}
+
+ return blink_time;
}
/**************************************************************************
Index: client/control.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.h,v
retrieving revision 1.45
diff -p -u -r1.45 control.h
--- client/control.h 29 Sep 2004 02:24:19 -0000 1.45
+++ client/control.h 11 Aug 2005 01:52:44 -0000
@@ -106,7 +106,7 @@ void set_unit_focus_and_select(struct un
void update_unit_focus(void);
struct unit *find_visible_unit(struct tile *ptile);
void set_units_in_combat(struct unit *pattacker, struct unit *pdefender);
-void blink_active_unit(void);
+double blink_active_unit(void);
void update_unit_pix_label(struct unit *punit);
void process_caravan_arrival(struct unit *punit);
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.408.2.27
diff -p -u -r1.408.2.27 packhand.c
--- client/packhand.c 21 Jul 2005 19:32:03 -0000 1.408.2.27
+++ client/packhand.c 11 Aug 2005 01:52:46 -0000
@@ -827,7 +827,7 @@ void handle_new_year(int year, int turn)
update_unit_info_label(get_unit_in_focus());
update_menus();
- seconds_to_turndone=game.timeout;
+ set_seconds_to_turndone(game.timeout);
#if 0
/* This information shouldn't be needed, but if it is this is the only
@@ -1461,11 +1461,9 @@ void handle_game_info(struct packet_game
boot_help = (can_client_change_view()
&& game.spacerace != pinfo->spacerace);
game.spacerace=pinfo->spacerace;
- if (game.timeout != 0) {
- if (pinfo->seconds_to_turndone != 0)
- seconds_to_turndone = pinfo->seconds_to_turndone;
- } else
- seconds_to_turndone = 0;
+ if (game.timeout != 0 && pinfo->seconds_to_turndone != 0) {
+ set_seconds_to_turndone(pinfo->seconds_to_turndone);
+ }
if (boot_help) {
boot_help_texts(); /* reboot, after setting game.spacerace */
}
Index: client/text.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/text.c,v
retrieving revision 1.11.2.7
diff -p -u -r1.11.2.7 text.c
--- client/text.c 29 Dec 2004 17:25:00 -0000 1.11.2.7
+++ client/text.c 11 Aug 2005 01:52:46 -0000
@@ -639,7 +639,7 @@ const char *get_timeout_label_text(void)
if (game.timeout <= 0) {
add("%s", Q_("?timeout:off"));
} else {
- add("%s", format_duration(seconds_to_turndone));
+ add("%s", format_duration(get_seconds_to_turndone()));
}
RETURN;
Index: client/gui-ftwl/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-ftwl/gui_main.c,v
retrieving revision 1.3.2.2
diff -p -u -r1.3.2.2 gui_main.c
--- client/gui-ftwl/gui_main.c 1 Dec 2004 22:14:52 -0000 1.3.2.2
+++ client/gui-ftwl/gui_main.c 11 Aug 2005 01:52:46 -0000
@@ -65,9 +65,9 @@ void ui_init(void)
**************************************************************************/
static void timer_callback(void *data)
{
- real_timer_callback();
- //sw_add_timeout(TIMER_INTERVAL, timer_callback, NULL);
- sw_add_timeout(1000, timer_callback, NULL);
+ double msec = real_timer_callback() * 1000;
+ //sw_add_timeout(1000, timer_callback, NULL);
+ sw_add_timeout(msec, timer_callback, NULL);
}
/**************************************************************************
Index: client/gui-gtk/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/Attic/gui_main.c,v
retrieving revision 1.152.2.3
diff -p -u -r1.152.2.3 gui_main.c
--- client/gui-gtk/gui_main.c 16 Dec 2004 21:25:09 -0000 1.152.2.3
+++ client/gui-gtk/gui_main.c 11 Aug 2005 01:52:46 -0000
@@ -1063,6 +1063,7 @@ static void select_unit_pixmap_callback(
static gint timer_callback(gpointer data)
{
real_timer_callback();
+ freelog(LOG_ERROR, "FIXME: Need to update timer.");
return TRUE;
}
Index: client/gui-gtk-2.0/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/gui_main.c,v
retrieving revision 1.81.2.17
diff -p -u -r1.81.2.17 gui_main.c
--- client/gui-gtk-2.0/gui_main.c 4 Aug 2005 16:57:35 -0000
1.81.2.17
+++ client/gui-gtk-2.0/gui_main.c 11 Aug 2005 01:52:47 -0000
@@ -1352,8 +1352,11 @@ static gboolean select_unit_pixmap_callb
**************************************************************************/
static gint timer_callback(gpointer data)
{
- real_timer_callback();
- return TRUE;
+ double seconds = real_timer_callback();
+
+ timer_id = gtk_timeout_add(seconds * 1000, timer_callback, NULL);
+
+ return FALSE;
}
/**************************************************************************
Index: client/gui-mui/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-mui/gui_main.c,v
retrieving revision 1.86.2.2
diff -p -u -r1.86.2.2 gui_main.c
--- client/gui-mui/gui_main.c 22 Nov 2004 07:55:17 -0000 1.86.2.2
+++ client/gui-mui/gui_main.c 11 Aug 2005 01:52:47 -0000
@@ -133,6 +133,7 @@ static void parse_options(int argc, char
static void handle_timer(void)
{
real_timer_callback();
+ freelog(LOG_ERROR, "FIXME: Need to update timer.");
}
static BOOL connected; /* TRUE, if connected to the server */
Index: client/gui-win32/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/gui_main.c,v
retrieving revision 1.30.2.8
diff -p -u -r1.30.2.8 gui_main.c
--- client/gui-win32/gui_main.c 23 Mar 2005 04:04:43 -0000 1.30.2.8
+++ client/gui-win32/gui_main.c 11 Aug 2005 01:52:47 -0000
@@ -488,6 +488,7 @@ static VOID CALLBACK blink_timer(HWND hw
}
real_timer_callback();
+ freelog(LOG_ERROR, "FIXME: Need to update timer.");
}
/**************************************************************************
Index: client/gui-xaw/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/gui_main.c,v
retrieving revision 1.95.2.4
diff -p -u -r1.95.2.4 gui_main.c
--- client/gui-xaw/gui_main.c 24 Jan 2005 21:15:10 -0000 1.95.2.4
+++ client/gui-xaw/gui_main.c 11 Aug 2005 01:52:47 -0000
@@ -831,9 +831,10 @@ void end_turn_callback(Widget w, XtPoint
**************************************************************************/
void timer_callback(XtPointer client_data, XtIntervalId * id)
{
- x_interval_id = XtAppAddTimeOut(app_context, TIMER_INTERVAL,
+ int msec = real_timer_callback() * 1000;
+
+ x_interval_id = XtAppAddTimeOut(app_context, msec,
timer_callback, NULL);
- real_timer_callback();
}
/**************************************************************************
|
|