[gnome-games/glchess-vala] Add in basic history framework



commit 93c5b07b4141b4232cc2076e43f1486bce8d5ada
Author: Robert Ancell <robert ancell canonical com>
Date:   Fri Dec 31 15:35:39 2010 +1100

    Add in basic history framework

 configure.in             |   26 +++++++++-
 glchess/src/Makefile.am  |    6 ++-
 glchess/src/glchess.vala |   21 +++++++-
 glchess/src/history.vala |  121 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 168 insertions(+), 6 deletions(-)
---
diff --git a/configure.in b/configure.in
index 15a4b88..77bc6a2 100644
--- a/configure.in
+++ b/configure.in
@@ -110,6 +110,7 @@ AC_SUBST([gamelist])
 
 need_cxx=no
 need_rsvg=no
+need_sqlite=no
 need_guile=no
 need_opengl=no
 need_glx=no
@@ -167,6 +168,10 @@ for game in $gamelist; do
     *) need_rsvg=yes ;;
   esac
   case $game in
+    glchess) ;;
+    *) need_sqlite=yes ;;
+  esac
+  case $game in
     aisleriot|glines|gnobots2|gnomine|gnotravex|gnotski|iagno) allow_smclient=yes ;;
     *) ;;
   esac
@@ -704,9 +709,26 @@ if test "$need_rsvg" = "yes"; then
     fi
   fi
 fi
-
+  
 AM_CONDITIONAL([HAVE_RSVG],[test "$have_rsvg" = "yes"])
 
+# Check for SQLite
+
+have_sqlite=no
+if test "$need_sqlite" = "yes"; then
+  have_sqlite=yes
+
+  # Errors out if sqlite is not found
+  PKG_CHECK_MODULES([SQLITE],[sqlite3])
+
+  AC_SUBST([SQLITE_CFLAGS])
+  AC_SUBST([SQLITE_LIBS])
+
+  AC_DEFINE([HAVE_SQLITE],[1],[Refine if sqlite is available])
+fi
+
+AM_CONDITIONAL([HAVE_SQLITE],[test "$have_sqlite" = "yes"])
+
 # Check for OpenGL
 
 have_opengl=no
@@ -1286,7 +1308,7 @@ echo "
     Help method:           ${with_help_method} ${with_help_file_format}
     Using SM Client:       ${with_smclient}
     Using RSVG:            ${have_rsvg}
-    Using GtkGLExt:        ${have_gtkglext}
+    Using SQLite:          ${have_sqlite}
     Card theme formats:    ${with_card_theme_formats}
     Default theme format:  ${with_default_card_theme_format}
     Default theme:         ${with_default_card_theme}
diff --git a/glchess/src/Makefile.am b/glchess/src/Makefile.am
index aa05a6e..a2d8315 100644
--- a/glchess/src/Makefile.am
+++ b/glchess/src/Makefile.am
@@ -15,7 +15,8 @@ glchess_SOURCES = \
 	chess-view.vala \
 	chess-view-2d.vala \
 	chess-view-3d.vala \
-	chess-view-options.vala
+	chess-view-options.vala \
+	history.vala
 
 test_chess_game_SOURCES = \
 	chess-bitboard.vala \
@@ -39,6 +40,7 @@ glchess_CFLAGS = \
 	$(GLX_CFLAGS) \
 	$(OPENGL_CFLAGS) \
 	$(RSVG_CFLAGS) \
+	$(SQLITE_CFLAGS) \
 	$(GTKGLEXT_CFLAGS) \
 	$(WARN_CFLAGS)
 
@@ -49,6 +51,7 @@ glchess_LDADD = \
 	$(GLX_LIBS) \
 	$(OPENGL_LIBS) \
 	$(RSVG_LIBS) \
+	$(SQLITE_LIBS) \
 	$(GTKGLEXT_LIBS)
 
 glchess_VALAFLAGS = \
@@ -57,6 +60,7 @@ glchess_VALAFLAGS = \
     --pkg gmodule-2.0 \
     --pkg librsvg-2.0 \
     --pkg posix \
+    --pkg sqlite3 \
     --vapidir . \
     --pkg config \
     --pkg gl \
diff --git a/glchess/src/glchess.vala b/glchess/src/glchess.vala
index 5387d48..ba0971a 100644
--- a/glchess/src/glchess.vala
+++ b/glchess/src/glchess.vala
@@ -1,6 +1,7 @@
 public class Application
 {
     private GLib.Settings settings;
+    private History history;
     private Gtk.Builder builder;
     private Gtk.Builder preferences_builder;
     private Gtk.Window window;
@@ -41,6 +42,11 @@ public class Application
     {
         settings = new GLib.Settings ("org.gnome.glchess.Settings");
 
+        var data_dir = File.new_for_path (Path.build_filename (Environment.get_user_data_dir (), "glchess", null));
+        DirUtils.create_with_parents (data_dir.get_path (), 0755);
+
+        history = new History (data_dir);
+
         builder = new Gtk.Builder ();
         try
         {
@@ -232,10 +238,19 @@ public class Application
         foreach (var profile in ai_profiles)
             GLib.message ("Detected AI profile %s", profile.name);
 
-        if (game != null)
-            load_game (game);
+        if (game == null)
+        {
+            var unfinished = history.get_unfinished ();
+            if (unfinished != null)
+            {
+                var key = unfinished.data;
+                load_game (history.get_game_file (key));
+            }
+            else
+                start_game (new ChessGame ());
+        }
         else
-            start_game (new ChessGame ());
+            load_game (game);
 
         if (settings.get_boolean ("fullscreen"))
             window.fullscreen ();
diff --git a/glchess/src/history.vala b/glchess/src/history.vala
new file mode 100644
index 0000000..d1de781
--- /dev/null
+++ b/glchess/src/history.vala
@@ -0,0 +1,121 @@
+public class History
+{
+    private File history_dir;
+    private Sqlite.Database db;
+
+    public History (File data_dir)
+    {
+        history_dir = File.new_for_path (Path.build_filename (data_dir.get_path (), "history", null));
+
+        var have_history = history_dir.query_exists ();
+        DirUtils.create_with_parents (history_dir.get_path (), 0755);
+
+        /* Open the database */
+        var result = Sqlite.Database.open_v2 (Path.build_filename (history_dir.get_path (), "index.db"), out db);
+        if (result != Sqlite.OK)
+            warning ("Failed to load history index: %s", db.errmsg ());
+
+        /* Create table */
+        Sqlite.Statement statement;
+        result = db.prepare_v2 ("CREATE TABLE IF NOT EXISTS GameTable (id INTEGER PRIMARY KEY, date INTEGER, path TEXT, fen TEXT, result TEXT)", -1, out statement);
+        assert (result == Sqlite.OK);
+        result = statement.step ();
+        if (result != Sqlite.DONE)
+            warning ("Failed to create game table: %s", db.errmsg ());
+
+        /* Migrate from old settings */
+        var old_history_dir = File.new_for_path (Path.build_filename (Environment.get_home_dir (), ".gnome2", "glchess", "history", null));
+        if (!have_history && old_history_dir.query_exists ())
+        {
+            debug ("Migrating history from %s to %s", old_history_dir.get_path (), history_dir.get_path ());
+            try
+            {
+                load_history_recursive (old_history_dir, old_history_dir, false);
+            }
+            catch (Error e)
+            {
+                warning ("Failed to migrate history: %s", e.message);
+            }
+        }
+    }
+
+    private void load_history_recursive (File base_dir, File dir, bool load_files) throws Error
+    {
+        var children = dir.enumerate_children ("standard::*", FileQueryInfoFlags.NOFOLLOW_SYMLINKS);
+
+        while (true)
+        {
+            var info = children.next_file ();
+            if (info == null)
+                return;
+
+            switch (info.get_file_type ())
+            {
+            case FileType.REGULAR:
+                if (load_files)
+                {
+                    var f = File.new_for_path (Path.build_filename (dir.get_path (), info.get_name (), null));
+                    var relative_path = base_dir.get_relative_path (f);
+                    var pgn = new PGN.from_file (f);
+                    var game = pgn.games.nth_data (0);
+                    if (game != null)
+                    {
+                        /* Copy file */
+                        var new_file = File.new_for_path (Path.build_filename (history_dir.get_path (), relative_path, null));
+                        DirUtils.create_with_parents (Path.get_dirname (new_file.get_path ()), 0755);
+                        f.copy (new_file, FileCopyFlags.NONE);
+
+                        /* Insert into index */
+                        Sqlite.Statement statement;
+                        debug ("  Migrating %s", relative_path);
+                        var result = db.prepare_v2 ("INSERT INTO GameTable (date, path, result) VALUES (0, \"%s\", \"%s\")".printf (relative_path, game.result), -1, out statement);
+                        assert (result == Sqlite.OK);
+                        result = statement.step ();
+                        if (result != Sqlite.DONE)
+                            warning ("Failed to insert game into history index: %s", db.errmsg ());
+                    }
+                }
+                break;
+            case FileType.DIRECTORY:
+                var path = Path.build_filename (dir.get_path (), info.get_name (), null);
+                try
+                {
+                    load_history_recursive (base_dir, File.new_for_path (path), true);
+                }
+                catch (Error e)
+                {
+                    warning ("Couldn't open directory %s: %s", path, e.message);
+                }
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
+    public List<string> get_unfinished ()
+    {
+        List<string> values = null;
+
+        Sqlite.Statement statement;
+        var result = db.prepare_v2 ("SELECT path FROM GameTable WHERE result=\"*\"", -1, out statement);
+        assert (result == Sqlite.OK);
+
+        while ((result = statement.step ()) == Sqlite.ROW)
+        {
+            var path = statement.column_text (0);
+            debug ("%s is unfinished", path);
+            values.append (path);
+        }
+
+        if (result != Sqlite.DONE)
+            warning ("Failed to get unfinished games: %s", db.errmsg ());
+
+        return values;
+    }
+
+    public File get_game_file (string key)
+    {
+        return File.new_for_path (Path.build_filename (history_dir.get_path(), key, null));
+    }
+}



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