[gnome-games] tracker: Split result handling from game creation



commit 68bdb83d36ff48234b06eb8e8dbf121f75061048
Author: Ricard Gascons <gascons1995 gmail com>
Date:   Mon Jul 11 13:21:03 2016 +0200

    tracker: Split result handling from game creation
    
    Replace the each_game_for_query() method of TrackerGameSource and its
    subtypes by the process_cursor() and foreach_game() methods.
    
    This unties the number of tracker query results from the number of
    produced games, avoiding useless errors in case of invalid query result
    and allowing to build a game from multiple results, for example for
    multi-disc games.
    
    Fixes #304

 plugins/desktop/src/desktop-tracker-query.vala |   30 ++++++++++++++++-
 src/tracker/mime-type-tracker-query.vala       |   40 +++++++++++++++++++++---
 src/tracker/tracker-game-source.vala           |   35 ++++++++------------
 src/tracker/tracker-query.vala                 |    3 +-
 4 files changed, 79 insertions(+), 29 deletions(-)
---
diff --git a/plugins/desktop/src/desktop-tracker-query.vala b/plugins/desktop/src/desktop-tracker-query.vala
index 7a01307..9276b08 100644
--- a/plugins/desktop/src/desktop-tracker-query.vala
+++ b/plugins/desktop/src/desktop-tracker-query.vala
@@ -1,6 +1,14 @@
 // This file is part of GNOME Games. License: GPLv3
 
 private class Games.DesktopTrackerQuery : Object, TrackerQuery {
+       private const uint HANDLED_GAMES_PER_CYCLE = 5;
+
+       private Game[] games;
+
+       construct {
+               games = {};
+       }
+
        public string get_query () {
                return "SELECT ?soft WHERE { ?soft nie:isLogicalPartOf 'urn:software-category:Game' . }";
        }
@@ -21,7 +29,7 @@ private class Games.DesktopTrackerQuery : Object, TrackerQuery {
                return true;
        }
 
-       public Game game_for_cursor (Tracker.Sparql.Cursor cursor) throws Error {
+       public void process_cursor (Tracker.Sparql.Cursor cursor) {
                var uri = cursor.get_string (0);
                check_uri (uri);
 
@@ -39,7 +47,25 @@ private class Games.DesktopTrackerQuery : Object, TrackerQuery {
                        throw new CommandError.INVALID_COMMAND ("Invalid command '%s'", command);
                var runner = new CommandRunner (args, true);
 
-               return new GenericGame (title, icon, cover, runner);
+               games += new GenericGame (title, icon, cover, runner);
+       }
+
+       public async void foreach_game (GameCallback game_callback) {
+               uint handled_games = 0;
+               foreach (var game in games) {
+                       game_callback (game);
+                       handled_games++;
+
+                       // Free the execution only once every HANDLED_GAMES_PER_CYCLE
+                       // games to speed up the execution by avoiding too many context
+                       // switching.
+                       if (handled_games >= HANDLED_GAMES_PER_CYCLE) {
+                               handled_games = 0;
+
+                               Idle.add (this.foreach_game.callback);
+                               yield;
+                       }
+               }
        }
 
        private void check_uri (string uri) throws Error {
diff --git a/src/tracker/mime-type-tracker-query.vala b/src/tracker/mime-type-tracker-query.vala
index 8920f78..dca3ff1 100644
--- a/src/tracker/mime-type-tracker-query.vala
+++ b/src/tracker/mime-type-tracker-query.vala
@@ -3,12 +3,16 @@
 public class Games.MimeTypeTrackerQuery : Object, TrackerQuery {
        public delegate Game GameForUri (string uri) throws Error;
 
+       private const uint HANDLED_URIS_PER_CYCLE = 5;
+
        private string mime_type;
        private GameForUri game_for_uri;
+       private string[] uris;
 
        public MimeTypeTrackerQuery (string mime_type, GameForUri game_for_uri) {
                this.mime_type = mime_type;
                this.game_for_uri = game_for_uri;
+               this.uris = {};
        }
 
        public string get_query () {
@@ -34,13 +38,39 @@ public class Games.MimeTypeTrackerQuery : Object, TrackerQuery {
                return false;
        }
 
-       public Game game_for_cursor (Tracker.Sparql.Cursor cursor) throws Error {
+       public void process_cursor (Tracker.Sparql.Cursor cursor) {
                var uri = cursor.get_string (0);
+               uris += uri;
+       }
+
+       public async void foreach_game (GameCallback game_callback) {
+               uint handled_uris = 0;
+               foreach (var uri in uris) {
+                       var file = File.new_for_uri (uri);
+                       if (!file.query_exists ())
+                               continue;
+
+                       try {
+                               var game = game_for_uri (uri);
+                               game_callback (game);
+                       }
+                       catch (Error e) {
+                               debug (e.message);
 
-               var file = File.new_for_uri (uri);
-               if (!file.query_exists ())
-                       throw new TrackerError.FILE_NOT_FOUND ("Tracker listed file not found: '%s'.", uri);
+                               continue;
+                       }
 
-               return game_for_uri (uri);
+                       handled_uris++;
+
+                       // Free the execution only once every HANDLED_URIS_PER_CYCLE
+                       // games to speed up the execution by avoiding too many context
+                       // switching.
+                       if (handled_uris >= HANDLED_URIS_PER_CYCLE) {
+                               handled_uris = 0;
+
+                               Idle.add (this.foreach_game.callback);
+                               yield;
+                       }
+               }
        }
 }
diff --git a/src/tracker/tracker-game-source.vala b/src/tracker/tracker-game-source.vala
index 6c53a51..cae3e13 100644
--- a/src/tracker/tracker-game-source.vala
+++ b/src/tracker/tracker-game-source.vala
@@ -1,7 +1,7 @@
 // This file is part of GNOME Games. License: GPLv3
 
 public class Games.TrackerGameSource : Object, GameSource {
-       private const uint HANDLED_GAMES_PER_CYCLE = 5;
+       private const uint HANDLED_CURSORS_PER_CYCLE = 5;
 
        private Tracker.Sparql.Connection connection { private set; get; }
        private TrackerQuery[] queries;
@@ -36,7 +36,7 @@ public class Games.TrackerGameSource : Object, GameSource {
                }
 
                bool is_cursor_valid = false;
-               uint handled_games = 0;
+               uint handled_cursors = 0;
 
                try {
                        is_cursor_valid = cursor.next ();
@@ -46,28 +46,20 @@ public class Games.TrackerGameSource : Object, GameSource {
                        warning ("Error: %s\n", e.message);
                }
                while (is_cursor_valid) {
-                       if (query.is_cursor_valid (cursor))
-                               try {
-                                       var game = query.game_for_cursor (cursor);
-                                       game_callback (game);
-                                       handled_games++;
+                       if (query.is_cursor_valid (cursor)) {
+                               query.process_cursor (cursor);
+                               handled_cursors++;
 
-                                       // Free the execution only once every HANDLED_GAMES_PER_CYCLE
-                                       // games to speed up the execution by avoiding too many context
-                                       // switching.
-                                       if (handled_games >= HANDLED_GAMES_PER_CYCLE) {
-                                               handled_games = 0;
+                               // Free the execution only once every HANDLED_CURSORS_PER_CYCLE
+                               // games to speed up the execution by avoiding too many context
+                               // switching.
+                               if (handled_cursors >= HANDLED_CURSORS_PER_CYCLE) {
+                                       handled_cursors = 0;
 
-                                               Idle.add (this.each_game_for_query.callback);
-                                               yield;
-                                       }
-                               }
-                               catch (TrackerError.FILE_NOT_FOUND e) {
-                                       debug (e.message);
-                               }
-                               catch (Error e) {
-                                       warning ("Error: %s\n", e.message);
+                                       Idle.add (this.each_game_for_query.callback);
+                                       yield;
                                }
+                       }
 
                        try {
                                is_cursor_valid = cursor.next ();
@@ -78,6 +70,7 @@ public class Games.TrackerGameSource : Object, GameSource {
                                continue;
                        }
                }
+               yield query.foreach_game (game_callback);
        }
 }
 
diff --git a/src/tracker/tracker-query.vala b/src/tracker/tracker-query.vala
index 5f90988..175b881 100644
--- a/src/tracker/tracker-query.vala
+++ b/src/tracker/tracker-query.vala
@@ -3,5 +3,6 @@
 public interface Games.TrackerQuery : Object {
        public abstract bool is_cursor_valid (Tracker.Sparql.Cursor cursor);
        public abstract string get_query ();
-       public abstract Game game_for_cursor (Tracker.Sparql.Cursor cursor) throws Error;
+       public abstract void process_cursor (Tracker.Sparql.Cursor cursor);
+       public abstract async void foreach_game (GameCallback game_callback);
 }


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