[gnome-chess] Fix desync when viewing history on engine's turn



commit 0257d1aeff78104c0e17d54fc01917715770759e
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Thu Jun 26 09:28:24 2014 -0500

    Fix desync when viewing history on engine's turn
    
    If you use the history buttons while the engine was thinking, we would
    get an "oops! something has gone wrong" once the engine decided to move.

 src/gnome-chess.vala |   39 +++++++++++++++++++++++++++++++++++----
 1 files changed, 35 insertions(+), 4 deletions(-)
---
diff --git a/src/gnome-chess.vala b/src/gnome-chess.vala
index 9a07525..ed7e318 100644
--- a/src/gnome-chess.vala
+++ b/src/gnome-chess.vala
@@ -51,6 +51,7 @@ public class ChessApplication : Gtk.Application
     private File game_file;
     private bool game_needs_saving = false;
     private bool allow_claim_draw_dialog = true;
+    private bool starting = true;
     private List<AIProfile> ai_profiles;
     private ChessPlayer? opponent = null;
     private ChessPlayer? human_player = null;
@@ -443,6 +444,8 @@ public class ChessApplication : Gtk.Application
 
     private void start_game ()
     {
+        starting = true;
+
         if (game_file != null && game_file.get_path () != autosave_filename)
             headerbar.set_subtitle (game_file.get_basename ());
         else
@@ -608,6 +611,15 @@ public class ChessApplication : Gtk.Application
 
         white_time_label.queue_draw ();
         black_time_label.queue_draw ();
+
+        starting = false;
+
+        if (white_engine != null && game.current_player.color == Color.WHITE ||
+            black_engine != null && game.current_player.color == Color.BLACK)
+        {
+            assert (opponent_engine != null);
+            opponent_engine.move ();
+        }
     }
 
     private ChessEngine? get_engine (string name, string difficulty)
@@ -778,15 +790,26 @@ public class ChessApplication : Gtk.Application
 
     private void game_turn_cb (ChessGame game, ChessPlayer player)
     {
+        /*
+         * Warning: this callback is invoked in response to the signal
+         * ChessGame.turn_started (), which is misleadingly-named. It can fire
+         * whenever an animation completes, such as when moving through history view.
+         * Do not do anything here that cannot safely be done after pressing a
+         * history button; in particular, anything involving an engine is probably
+         * unsafe. Use game_move_cb () instead.
+         *
+         * It is really not possible to detect if we're using the history controls
+         * or not, since even if we're viewing the most recent move, we could have
+         * just returned from the past via history controls.
+         */
+
         if (!game.is_started)
             return;
 
         if (game.clock != null)
             enable_window_action (PAUSE_RESUME_ACTION_NAME);
 
-        if (opponent_engine != null && player == opponent)
-            opponent_engine.move ();
-        else if (game.can_claim_draw () && allow_claim_draw_dialog)
+        if (game.can_claim_draw () && allow_claim_draw_dialog)
             present_claim_draw_dialog ();
     }
 
@@ -997,6 +1020,8 @@ public class ChessApplication : Gtk.Application
 
     private void game_move_cb (ChessGame game, ChessMove move)
     {
+        /* Warning: this callback is invoked several times when loading a game. */
+
         enable_window_action (NEW_GAME_ACTION_NAME);
 
         /* Need to save after each move */
@@ -1028,9 +1053,15 @@ public class ChessApplication : Gtk.Application
         update_action_status ();
         update_headerbar_title ();
 
+        view.queue_draw ();
+
         if (opponent_engine != null)
+        {
             opponent_engine.report_move (move);
-        view.queue_draw ();
+
+            if (move.piece.color != opponent.color && !starting)
+                opponent_engine.move ();
+        }
     }
 
     private void game_undo_cb (ChessGame game)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]