[rygel] tracker: Use static client D-Bus syntax



commit c829b662fcc1b5fb59bc152475e81c00e331bf2a
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Wed Oct 14 20:33:12 2009 +0300

    tracker: Use static client D-Bus syntax
    
    This also implies that we now use multidimensional arrays to deal with
    search results. This combination of static D-Bus and multidimensional
    arrays gives us quite a speed boost.

 src/plugins/tracker/Makefile.am                    |    5 +-
 .../tracker/rygel-tracker-get-metadata-result.vala |   56 --------
 src/plugins/tracker/rygel-tracker-interfaces.vala  |   66 +++++++++
 src/plugins/tracker/rygel-tracker-keywords.vala    |   32 ++--
 .../tracker/rygel-tracker-metadata-values.vala     |   43 +++---
 .../tracker/rygel-tracker-plugin-factory.vala      |   28 ++---
 .../tracker/rygel-tracker-search-container.vala    |  147 +++++++++++---------
 .../tracker/rygel-tracker-search-result.vala       |   97 -------------
 8 files changed, 195 insertions(+), 279 deletions(-)
---
diff --git a/src/plugins/tracker/Makefile.am b/src/plugins/tracker/Makefile.am
index 7cee5c0..2418883 100644
--- a/src/plugins/tracker/Makefile.am
+++ b/src/plugins/tracker/Makefile.am
@@ -15,14 +15,13 @@ librygel_media_tracker_la_SOURCES = \
 				    rygel-tracker-metadata-values.vala \
 				    rygel-tracker-keywords.vala \
 				    rygel-tracker-search-container.vala \
-				    rygel-tracker-search-result.vala \
-				    rygel-tracker-get-metadata-result.vala \
 				    rygel-tracker-item.vala \
 				    rygel-tracker-video-item.vala \
 				    rygel-tracker-music-item.vala \
 				    rygel-tracker-image-item.vala \
 				    rygel-tracker-plugin.vala \
-				    rygel-tracker-plugin-factory.vala
+				    rygel-tracker-plugin-factory.vala \
+				    rygel-tracker-interfaces.vala
 
 librygel_media_tracker_la_VALAFLAGS = \
 	--vapidir=$(top_srcdir)/src/rygel \
diff --git a/src/plugins/tracker/rygel-tracker-interfaces.vala b/src/plugins/tracker/rygel-tracker-interfaces.vala
new file mode 100644
index 0000000..a4b9def
--- /dev/null
+++ b/src/plugins/tracker/rygel-tracker-interfaces.vala
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation.
+ *
+ * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ *                               <zeeshan ali nokia com>
+ *
+ * This file is part of Rygel.
+ *
+ * Rygel is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Rygel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+using DBus;
+
+[DBus (name = "org.freedesktop.Tracker")]
+public interface Rygel.TrackerIface : DBus.Object {
+    public abstract int get_version () throws DBus.Error;
+}
+
+[DBus (name = "org.freedesktop.Tracker.Keywords")]
+public interface Rygel.TrackerKeywordsIface : DBus.Object {
+    public abstract string[,] get_list (string service) throws DBus.Error;
+}
+
+[DBus (name = "org.freedesktop.Tracker.Metadata")]
+public interface Rygel.TrackerMetadataIface: DBus.Object {
+    public abstract string[,] get_unique_values (string   service,
+                                                 string[] meta_types,
+                                                 string   query,
+                                                 bool     descending,
+                                                 int      offset,
+                                                 int      max_hits)
+                                                 throws DBus.Error;
+
+    public abstract string[] @get (string   service_type,
+                                   string   uri,
+                                   string[] keys)
+                                   throws DBus.Error;
+}
+
+[DBus (name = "org.freedesktop.Tracker.Search")]
+public interface Rygel.TrackerSearchIface: DBus.Object {
+    public abstract string[,] query (int live_query_id,
+                                     string   service,
+                                     string[] fields,
+                                     string   search_text,
+                                     string[] keywords,
+                                     string   query_condition,
+                                     bool     sort_by_service,
+                                     string[] sort_fields,
+                                     bool     sort_descending,
+                                     int      offset,
+                                     int      max_hits)
+                                     throws DBus.Error;
+}
diff --git a/src/plugins/tracker/rygel-tracker-keywords.vala b/src/plugins/tracker/rygel-tracker-keywords.vala
index cd7b8ff..2197b71 100644
--- a/src/plugins/tracker/rygel-tracker-keywords.vala
+++ b/src/plugins/tracker/rygel-tracker-keywords.vala
@@ -32,12 +32,11 @@ public class Rygel.TrackerKeywords : Rygel.SimpleContainer {
     /* class-wide constants */
     private const string TRACKER_SERVICE = "org.freedesktop.Tracker";
     private const string KEYWORDS_PATH = "/org/freedesktop/Tracker/Keywords";
-    private const string KEYWORDS_IFACE = "org.freedesktop.Tracker.Keywords";
 
     private const string SERVICE = "Files";
     private const string TITLE = "Tags";
 
-    public dynamic DBus.Object keywords;
+    public TrackerKeywordsIface keywords;
 
     public TrackerKeywords (string         id,
                             MediaContainer parent) {
@@ -45,28 +44,29 @@ public class Rygel.TrackerKeywords : Rygel.SimpleContainer {
 
         try {
             this.create_proxies ();
-
-            /* FIXME: We need to hook to some tracker signals to keep
-             *        this field up2date at all times
-             */
-            this.keywords.GetList (SERVICE, on_get_keywords_cb);
-        } catch (GLib.Error error) {
+        } catch (DBus.Error error) {
             critical ("Failed to create to Session bus: %s\n",
                       error.message);
+
+            return;
         }
-    }
 
-    private void on_get_keywords_cb (string[][] keywords_list,
-                                     GLib.Error error) {
-        if (error != null) {
+        string[,] keywords_list;
+
+        try {
+            /* FIXME: We need to hook to some tracker signals to keep
+             *        this field up2date at all times
+             */
+            keywords_list = this.keywords.get_list (SERVICE);
+        } catch (DBus.Error error) {
             critical ("error getting all keywords: %s", error.message);
 
             return;
         }
 
         /* Iterate through all the values */
-        for (uint i = 0; i < keywords_list.length; i++) {
-            string keyword = keywords_list[i][0];
+        for (uint i = 0; i < keywords_list.length[0]; i++) {
+            string keyword = keywords_list[i, 0];
 
             var keywords = new string[] { keyword };
 
@@ -87,8 +87,8 @@ public class Rygel.TrackerKeywords : Rygel.SimpleContainer {
         DBus.Connection connection = DBus.Bus.get (DBus.BusType.SESSION);
 
         this.keywords = connection.get_object (TRACKER_SERVICE,
-                                               KEYWORDS_PATH,
-                                               KEYWORDS_IFACE);
+                                               KEYWORDS_PATH)
+                                               as TrackerKeywordsIface;
     }
 }
 
diff --git a/src/plugins/tracker/rygel-tracker-metadata-values.vala b/src/plugins/tracker/rygel-tracker-metadata-values.vala
index b7f3c09..d39f27d 100644
--- a/src/plugins/tracker/rygel-tracker-metadata-values.vala
+++ b/src/plugins/tracker/rygel-tracker-metadata-values.vala
@@ -32,7 +32,6 @@ public class Rygel.TrackerMetadataValues : Rygel.SimpleContainer {
     /* class-wide constants */
     private const string TRACKER_SERVICE = "org.freedesktop.Tracker";
     private const string METADATA_PATH = "/org/freedesktop/Tracker/Metadata";
-    private const string METADATA_IFACE = "org.freedesktop.Tracker.Metadata";
 
     private const string SERVICE = "Files";
     private const string QUERY_CONDITION =
@@ -43,7 +42,7 @@ public class Rygel.TrackerMetadataValues : Rygel.SimpleContainer {
                 "</rdfq:equals>\n" +
         "</rdfq:Condition>";
 
-    public dynamic DBus.Object metadata;
+    public TrackerMetadataIface metadata;
 
     public string key;
 
@@ -57,28 +56,28 @@ public class Rygel.TrackerMetadataValues : Rygel.SimpleContainer {
 
         try {
             this.create_proxies ();
+        } catch (DBus.Error error) {
+            critical ("Failed to create to Session bus: %s\n",
+                      error.message);
+
+            return;
+        }
+
+        string[,] values;
 
+        try {
             var keys = new string[] { this.key };
 
             /* FIXME: We need to hook to some tracker signals to keep
              *        this field up2date at all times
              */
-            this.metadata.GetUniqueValues (SERVICE,
-                                           keys,
-                                           "",
-                                           false,
-                                           0,
-                                           -1,
-                                           on_get_unique_values_cb);
-        } catch (GLib.Error error) {
-            critical ("Failed to create to Session bus: %s\n",
-                      error.message);
-        }
-    }
-
-    private void on_get_unique_values_cb (string[][] search_result,
-                                          GLib.Error error) {
-        if (error != null) {
+            values = this.metadata.get_unique_values (SERVICE,
+                                                    keys,
+                                                    "",
+                                                    false,
+                                                    0,
+                                                    -1);
+        } catch (DBus.Error error) {
             critical ("error getting all values for '%s': %s",
                       this.key,
                       error.message);
@@ -87,8 +86,8 @@ public class Rygel.TrackerMetadataValues : Rygel.SimpleContainer {
         }
 
         /* Iterate through all the values */
-        for (uint i = 0; i < search_result.length; i++) {
-            string value = search_result[i][0];
+        for (uint i = 0; i < values.length[0]; i++) {
+            string value = values[i, 0];
 
             if (value == "") {
                 continue;
@@ -113,8 +112,8 @@ public class Rygel.TrackerMetadataValues : Rygel.SimpleContainer {
         DBus.Connection connection = DBus.Bus.get (DBus.BusType.SESSION);
 
         this.metadata = connection.get_object (TRACKER_SERVICE,
-                                               METADATA_PATH,
-                                               METADATA_IFACE);
+                                               METADATA_PATH)
+                                               as TrackerMetadataIface;
     }
 }
 
diff --git a/src/plugins/tracker/rygel-tracker-plugin-factory.vala b/src/plugins/tracker/rygel-tracker-plugin-factory.vala
index 09c5f48..f057752 100644
--- a/src/plugins/tracker/rygel-tracker-plugin-factory.vala
+++ b/src/plugins/tracker/rygel-tracker-plugin-factory.vala
@@ -32,39 +32,29 @@ private TrackerPluginFactory plugin_factory;
 public void module_init (PluginLoader loader) {
     try {
         plugin_factory = new TrackerPluginFactory (loader);
-    } catch (DBus.Error error) {
-        critical ("Failed to fetch list of external services: %s\n",
-                error.message);
+    } catch (DBus.Error err) {
+        warning ("Failed to start Tracker service: " +
+                 err.message +
+                 ". Tracker plugin disabled.");
     }
 }
 
 public class TrackerPluginFactory {
     private const string TRACKER_SERVICE = "org.freedesktop.Tracker";
     private const string TRACKER_OBJECT = "/org/freedesktop/Tracker";
-    private const string TRACKER_IFACE = "org.freedesktop.Tracker";
 
-    dynamic DBus.Object tracker;
-    PluginLoader        loader;
+    TrackerIface tracker;
+    PluginLoader loader;
 
     public TrackerPluginFactory (PluginLoader loader) throws DBus.Error {
         var connection = DBus.Bus.get (DBus.BusType.SESSION);
 
         this.tracker = connection.get_object (TRACKER_SERVICE,
-                                              TRACKER_OBJECT,
-                                              TRACKER_IFACE);
+                                              TRACKER_OBJECT)
+                                              as TrackerIface;
         this.loader = loader;
 
-        tracker.GetVersion (this.get_version_cb);
-    }
-
-    private void get_version_cb (int32 version, GLib.Error err) {
-        if (err != null) {
-            warning ("Failed to start Tracker service: %s\n",
-                     err.message);
-            warning ("Tracker plugin disabled.\n");
-
-            return;
-        }
+        this.tracker.get_version ();
 
         this.loader.add_plugin (new TrackerPlugin ());
     }
diff --git a/src/plugins/tracker/rygel-tracker-search-container.vala b/src/plugins/tracker/rygel-tracker-search-container.vala
index f56bb50..5e2159f 100644
--- a/src/plugins/tracker/rygel-tracker-search-container.vala
+++ b/src/plugins/tracker/rygel-tracker-search-container.vala
@@ -38,9 +38,8 @@ public class Rygel.TrackerSearchContainer : Rygel.MediaContainer {
     private const string METADATA_PATH = "/org/freedesktop/Tracker/Metadata";
     private const string METADATA_IFACE = "org.freedesktop.Tracker.Metadata";
 
-    public dynamic DBus.Object metadata;
-    public dynamic DBus.Object search;
-    public dynamic DBus.Object tracker;
+    public TrackerMetadataIface metadata;
+    public TrackerSearchIface search;
 
     public string service;
 
@@ -81,18 +80,20 @@ public class Rygel.TrackerSearchContainer : Rygel.MediaContainer {
             // We are performing actual search (though an optimized one) to get
             // the hitcount rather than GetHitCount because GetHitCount only
             // allows us to get hit count for Text searches.
-            this.search.Query (0,
-                               this.service,
-                               new string[0],
-                               "",
-                               this.keywords,
-                               this.query_condition,
-                               false,
-                               new string[0],
-                               false,
-                               0,
-                               -1,
-                               on_search_query_cb);
+            var search_result = this.search.query (0,
+                                                   this.service,
+                                                   new string[0],
+                                                   "",
+                                                   this.keywords,
+                                                   this.query_condition,
+                                                   false,
+                                                   new string[0],
+                                                   false,
+                                                   0,
+                                                   -1);
+
+            this.child_count = search_result.length[0];
+            this.updated ();
         } catch (GLib.Error error) {
             critical ("error getting items under service '%s': %s",
                       this.service,
@@ -102,52 +103,50 @@ public class Rygel.TrackerSearchContainer : Rygel.MediaContainer {
         }
     }
 
-    private void on_search_query_cb (string[][] search_result,
-                                     GLib.Error error) {
-        if (error != null) {
-            critical ("error getting items under service '%s': %s",
-                      this.service,
-                      error.message);
-
-            return;
-        }
-
-        this.child_count = search_result.length;
-        this.updated ();
-    }
-
     public override void get_children (uint               offset,
                                        uint               max_count,
                                        Cancellable?       cancellable,
                                        AsyncReadyCallback callback) {
-        var res = new TrackerSearchResult (this, callback);
-
+        var res = new SimpleAsyncResult<ArrayList<MediaObject>> (this,
+                                                                 callback);
+        res.data = new ArrayList<MediaObject> ();
         this.results.add (res);
 
         try {
-            this.search.Query (0,
-                               this.service,
-                               TrackerItem.get_metadata_keys (),
-                               "",
-                               this.keywords,
-                               this.query_condition,
-                               false,
-                               new string[0],
-                               false,
-                               (int) offset,
-                               (int) max_count,
-                               res.ready);
+            string[] keys = TrackerItem.get_metadata_keys ();
+
+            var search_result = this.search.query (0,
+                                                   this.service,
+                                                   keys,
+                                                   "",
+                                                   this.keywords,
+                                                   this.query_condition,
+                                                   false,
+                                                   new string[0],
+                                                   false,
+                                                   (int) offset,
+                                                   (int) max_count);
+
+            /* Iterate through all items */
+            for (uint i = 0; i < search_result.length[0]; i++) {
+                string path = search_result[i, 0];
+                string service = search_result[i, 1];
+                string[] metadata = this.slice_strvv_tail (search_result, i, 2);
+
+                var item = this.create_item (service, path, metadata);
+                res.data.add (item);
+            }
         } catch (GLib.Error error) {
             res.error = error;
-
-            res.complete_in_idle ();
         }
+
+        res.complete_in_idle ();
     }
 
     public override Gee.List<MediaObject>? get_children_finish (
                                                          AsyncResult res)
                                                          throws GLib.Error {
-        var search_res = (Rygel.TrackerSearchResult) res;
+        var search_res = res as SimpleAsyncResult<ArrayList<MediaObject>>;
 
         this.results.remove (search_res);
 
@@ -161,17 +160,16 @@ public class Rygel.TrackerSearchContainer : Rygel.MediaContainer {
     public override void find_object (string             id,
                                       Cancellable?       cancellable,
                                       AsyncReadyCallback callback) {
-        var res = new TrackerGetMetadataResult (this, callback, id);
+        var res = new SimpleAsyncResult<MediaObject> (this, callback);
 
         this.results.add (res);
 
         try {
             string parent_id;
+            string service;
 
-            res.item_path = this.get_item_info (id,
-                                                out parent_id,
-                                                out res.item_service);
-            if (res.item_path == null) {
+            var path = this.get_item_info (id, out parent_id, out service);
+            if (path == null) {
                 res.complete_in_idle ();
 
                 return;
@@ -179,20 +177,21 @@ public class Rygel.TrackerSearchContainer : Rygel.MediaContainer {
 
             string[] keys = TrackerItem.get_metadata_keys ();
 
-            this.metadata.Get (res.item_service,
-                               res.item_path,
-                               keys,
-                               res.ready);
-        } catch (GLib.Error error) {
-            res.error = error;
+            var values = this.metadata.get (service, path, keys);
 
-            res.complete_in_idle ();
+            res.data = this.create_item (service, path, values);
+        } catch (DBus.Error error) {
+            res.error = error;
         }
+
+        res.complete_in_idle ();
     }
 
     public override MediaObject? find_object_finish (AsyncResult res)
                                                      throws GLib.Error {
-        var metadata_res = (TrackerGetMetadataResult) res;
+        var metadata_res = res as SimpleAsyncResult<MediaObject>;
+
+        this.results.remove (metadata_res);
 
         if (metadata_res.error != null) {
             throw metadata_res.error;
@@ -258,14 +257,30 @@ public class Rygel.TrackerSearchContainer : Rygel.MediaContainer {
         DBus.Connection connection = DBus.Bus.get (DBus.BusType.SESSION);
 
         this.metadata = connection.get_object (TRACKER_SERVICE,
-                                               METADATA_PATH,
-                                               METADATA_IFACE);
+                                               METADATA_PATH)
+                                               as TrackerMetadataIface;
         this.search = connection.get_object (TRACKER_SERVICE,
-                                             SEARCH_PATH,
-                                             SEARCH_IFACE);
-        this.tracker = connection.get_object (TRACKER_SERVICE,
-                                              TRACKER_PATH,
-                                              TRACKER_IFACE);
+                                             SEARCH_PATH)
+                                             as TrackerSearchIface;
+    }
+
+    /**
+     * Chops the tail of a particular row in a 2-dimensional string array.
+     *
+     * param strvv the 2-dimenstional string array to chop the tail of.
+     * param row the row whose tail needs to be chopped off.
+     * param index index of the first element in the tail.
+     *
+     * FIXME: Stop using it once vala supports array[N:M] syntax.
+     */
+    private string[] slice_strvv_tail (string[,] strvv, uint row, uint index) {
+        var slice = new string[strvv.length[1] - index];
+
+        for (var i = 0; i < slice.length; i++) {
+            slice[i] = strvv[row, i + index];
+        }
+
+        return slice;
     }
 }
 



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