[gnome-games/glchess-vala] Autosave games



commit 6afb2d3c530251f187165e3ee685aae8e1eed73a
Author: Robert Ancell <robert ancell canonical com>
Date:   Sat Jan 1 14:24:41 2011 +1100

    Autosave games

 glchess/src/chess-pgn.vala |   34 +++++++++++++----------
 glchess/src/glchess.vala   |   62 ++++++++++++++++++++++++++++++++------------
 glchess/src/history.vala   |   28 ++++++++++----------
 3 files changed, 78 insertions(+), 46 deletions(-)
---
diff --git a/glchess/src/chess-pgn.vala b/glchess/src/chess-pgn.vala
index 2eb1f7c..e06d557 100644
--- a/glchess/src/chess-pgn.vala
+++ b/glchess/src/chess-pgn.vala
@@ -40,6 +40,11 @@ public class PGNGame
     public HashTable<string, string> tags;
     public List<string> moves;
 
+    public static string RESULT_IN_PROGRESS = "*";
+    public static string RESULT_DRAW        = "1/2-1/2";
+    public static string RESULT_WHITE       = "1-0";
+    public static string RESULT_BLACK       = "0-1";
+
     public string event
     {
         get { return tags.lookup ("Event"); }
@@ -105,34 +110,33 @@ public class PGNGame
         tags.insert ("Round", "?");
         tags.insert ("White", "?");
         tags.insert ("Black", "?");
-        tags.insert ("Result", "*");
+        tags.insert ("Result", PGNGame.RESULT_IN_PROGRESS);
     }
 
-    public void write (OutputStream stream) throws Error
+    public void write (File file) throws Error
     {
+        var data = new StringBuilder ();
+
         // FIXME: Escape \ and " in tag values
         var keys = tags.get_keys ();
         keys.sort ((CompareFunc) compare_tag);
         foreach (var key in keys)
-            write_string (stream, "[%s \"%s\"]\n".printf (key, tags.lookup (key)));
-        write_string (stream, "\n");
+            data.append ("[%s \"%s\"]\n".printf (key, tags.lookup (key)));
+        data.append ("\n");
 
         int i = 0;
         foreach (string move in moves)
         {
             if (i % 2 == 0)
-                write_string (stream, "%d. ".printf (i / 2 + 1));
-            write_string (stream, move);
-            write_string (stream, " ");
+                data.append ("%d. ".printf (i / 2 + 1));
+            data.append (move);
+            data.append (" ");
             i++;
         }
-        write_string (stream, result);
-        write_string (stream, "\n");
-    }
+        data.append (result);
+        data.append ("\n");
 
-    private void write_string (OutputStream stream, string value) throws Error
-    {
-        stream.write_all ((uint8[]) value, null);
+        file.replace_contents (data.str, data.len, null, false, FileCreateFlags.NONE, null);
     }
 }
 
@@ -204,7 +208,7 @@ public class PGN
                 {
                     if (rav_level == 0)
                     {
-                        game.result = "*";
+                        game.result = PGNGame.RESULT_IN_PROGRESS;
                         games.append (game);
                         game = new PGNGame ();
                         have_tags = false;
@@ -326,7 +330,7 @@ public class PGN
                            is_number = false;
 
                     /* Game termination markers */
-                    if (symbol == "1/2-1/2" || symbol == "1-0" || symbol == "0-1")
+                    if (symbol == PGNGame.RESULT_DRAW || symbol == PGNGame.RESULT_WHITE || symbol == PGNGame.RESULT_BLACK)
                     {
                         if (rav_level == 0)
                         {
diff --git a/glchess/src/glchess.vala b/glchess/src/glchess.vala
index 3bdb623..b602cf7 100644
--- a/glchess/src/glchess.vala
+++ b/glchess/src/glchess.vala
@@ -34,6 +34,9 @@ public class Application
     private Gtk.AboutDialog? about_dialog = null;
 
     private ChessGame game;
+    private bool in_history;
+    private File autosave_file;
+    private PGNGame pgn_game;
     private List<AIProfile> ai_profiles;
     private ChessPlayer? opponent = null;
     private ChessEngine? opponent_engine = null;
@@ -100,6 +103,23 @@ public class Application
     {
         if (save_duration_timeout != 0)
             save_duration ();
+
+        /* Autosave */
+        // FIXME: Only once a human has moved
+        if (in_history && pgn_game.moves != null)
+        {
+            try
+            {
+                if (autosave_file == null)
+                    autosave_file = history.add (pgn_game.date, pgn_game.result);
+                pgn_game.write (autosave_file);
+            }
+            catch (Error e)
+            {
+                warning ("Failed to autosave: %s", e.message);
+            }
+        }
+
         settings.sync ();
         Gtk.main_quit ();
     }
@@ -243,14 +263,14 @@ public class Application
             var unfinished = history.get_unfinished ();
             if (unfinished != null)
             {
-                var file = unfinished.data;
-                load_game (file);
+                autosave_file = unfinished.data;
+                load_game (autosave_file, true);
             }
             else
-                start_game (new ChessGame ());
+                start_new_game ();
         }
         else
-            load_game (game);
+            load_game (game, false);
 
         if (settings.get_boolean ("fullscreen"))
             window.fullscreen ();
@@ -410,6 +430,9 @@ public class Application
 
     private void game_move_cb (ChessGame game, ChessMove move)
     {
+        if (move.number > pgn_game.moves.length ())
+            pgn_game.moves.append (move.san);
+
         Gtk.TreeIter iter;
         var model = (Gtk.ListStore) history_combo.model;
         model.append (out iter);
@@ -434,12 +457,15 @@ public class Application
         {
         case ChessResult.WHITE_WON:
             title = "White wins";
+            pgn_game.result = PGNGame.RESULT_WHITE;
             break;
         case ChessResult.BLACK_WON:
             title = "Black wins";
+            pgn_game.result = PGNGame.RESULT_BLACK;
             break;
         case ChessResult.DRAW:
             title = "Game is drawn";
+            pgn_game.result = PGNGame.RESULT_DRAW;            
             break;
         default:
             break;
@@ -527,7 +553,7 @@ public class Application
     [CCode (cname = "G_MODULE_EXPORT new_game_cb", instance_pos = -1)]
     public void new_game_cb (Gtk.Widget widget)
     {
-        start_game (new ChessGame ());
+        start_new_game ();
     }
 
     [CCode (cname = "G_MODULE_EXPORT resign_cb", instance_pos = -1)]
@@ -1026,17 +1052,9 @@ public class Application
         {
             save_menu.sensitive = false;
 
-            var pgn = new PGNGame ();
-            foreach (var i in game.move_stack)
-            {
-                if (i.last_move != null)
-                    pgn.moves.append (i.last_move.lan);
-            }
-
             try
             {
-                var stream = save_dialog.get_file ().replace (null, false, FileCreateFlags.NONE);
-                pgn.write (stream);
+                pgn_game.write (save_dialog.get_file ());
             }
             catch (Error e)
             {
@@ -1096,7 +1114,7 @@ public class Application
         {
             try
             {
-                load_game (open_dialog.get_file ());
+                load_game (open_dialog.get_file (), false);
             }
             catch (Error e)
             {
@@ -1112,11 +1130,20 @@ public class Application
         open_dialog_info_bar = null;
         open_dialog_error_label = null;
     }
+    
+    private void start_new_game ()
+    {
+        in_history = true;
+        pgn_game = new PGNGame ();
+        var now = new DateTime.now_local ();
+        pgn_game.date = now.format ("%Y.%M.%d");
+        start_game (new ChessGame ());    
+    }
 
-    private void load_game (File file) throws Error
+    private void load_game (File file, bool in_history) throws Error
     {
         var pgn = new PGN.from_file (file);
-        var pgn_game = pgn.games.nth_data (0);
+        pgn_game = pgn.games.nth_data (0);
 
         ChessGame game;
         if (pgn_game.set_up)
@@ -1132,6 +1159,7 @@ public class Application
         else
             game = new ChessGame ();
 
+        this.in_history = in_history;
         start_game (game);
         foreach (var move in pgn_game.moves)
         {
diff --git a/glchess/src/history.vala b/glchess/src/history.vala
index 6c99718..ba22f70 100644
--- a/glchess/src/history.vala
+++ b/glchess/src/history.vala
@@ -9,10 +9,19 @@ public class History
         history_dir = File.new_for_path (Path.build_filename (data_dir.get_path (), "history", null));
     }
     
-    public File add (int year, int month, int day, string result) throws Error
+    public File add (string date, string result) throws Error
     {
         load ();
 
+        var tokens = date.split (".");
+        string year = "????", month = "??", day = "??";
+        if (tokens.length == 3)
+        {
+            year = tokens[0];
+            month = tokens[1];
+            day = tokens[2];
+        }
+
         string relative_path;
         File file;
         int version = 0;
@@ -20,10 +29,10 @@ public class History
         {
             string filename;
             if (version == 0)
-                filename = "%04d-%02d-%02d.pgn".printf (year, month, day);
+                filename = "%s-%s-%s.pgn".printf (year, month, day);
             else
-                filename = "%04d-%02d-%02d-%d.pgn".printf (year, month, day, version);
-            relative_path = Path.build_filename ("%04d".printf (year), "%02d".printf (month), "%02d".printf (day), filename, null);
+                filename = "%s-%s-%s-%d.pgn".printf (year, month, day, version);
+            relative_path = Path.build_filename (year, month, day, filename, null);
 
             file = File.new_for_path (Path.build_filename (history_dir.get_path (), relative_path, null));
             DirUtils.create_with_parents (Path.get_dirname (file.get_path ()), 0755);
@@ -133,17 +142,8 @@ public class History
                     var pgn = new PGN.from_file (f);
                     var game = pgn.games.nth_data (0);
 
-                    var tokens = game.date.split (".");
-                    int year = 0, month = 0, day = 0;
-                    if (tokens.length == 3)
-                    {
-                        year = tokens[0].to_int ();
-                        month = tokens[1].to_int ();
-                        day = tokens[2].to_int ();
-                    }
-
                     /* Copy file */
-                    var new_file = add (year, month, day, game.result);
+                    var new_file = add (game.date, game.result);
                     f.copy (new_file, FileCopyFlags.OVERWRITE);
                 }
                 catch (Error e)



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