[gnome-photos] item-manager: Add photos_item_manager_wait_for_changes_async



commit fa1232fec2f8b7ed4511c5d744f270479b7c6f96
Author: Debarshi Ray <debarshir gnome org>
Date:   Thu Sep 8 14:17:38 2016 +0200

    item-manager: Add photos_item_manager_wait_for_changes_async
    
    This is meant to let us work around the URN possibly changing due to
    an atomic file update. It will wait for any relevant changes and return
    the new URN, if any. This is only needed for LocalItems since the
    other BaseItem sub-classes are not backed by a file on the local hard
    disk.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=770267
    https://bugzilla.gnome.org/show_bug.cgi?id=771042

 src/photos-item-manager.c |   89 ++++++++++++++++++++++++++++++++++++++++++++-
 src/photos-item-manager.h |   10 +++++
 2 files changed, 98 insertions(+), 1 deletions(-)
---
diff --git a/src/photos-item-manager.c b/src/photos-item-manager.c
index 44b3f4f..eb3fcc2 100644
--- a/src/photos-item-manager.c
+++ b/src/photos-item-manager.c
@@ -52,6 +52,7 @@ struct _PhotosItemManager
   GCancellable *loader_cancellable;
   GHashTable *collections;
   GHashTable *hidden_items;
+  GHashTable *wait_for_changes_table;
   GIOExtensionPoint *extension_point;
   GQueue *collection_path;
   GQueue *history;
@@ -139,12 +140,31 @@ photos_item_manager_add_object (PhotosBaseManager *mngr, GObject *object)
 
 
 static void
+photos_item_manager_check_wait_for_changes (PhotosItemManager *self, const gchar *id, const gchar *uri)
+{
+  GList *l;
+  GList *tasks;
+
+  tasks = (GList *) g_hash_table_lookup (self->wait_for_changes_table, uri);
+  for (l = tasks; l != NULL; l = l->next)
+    {
+      GTask *task = G_TASK (l->data);
+      g_task_return_pointer (task, g_strdup (id), g_free);
+    }
+
+  g_hash_table_remove (self->wait_for_changes_table, uri);
+}
+
+
+static void
 photos_item_manager_item_created_executed (GObject *source_object, GAsyncResult *res, gpointer user_data)
 {
   PhotosItemManager *self = PHOTOS_ITEM_MANAGER (user_data);
   GError *error = NULL;
   PhotosSingleItemJob *job = PHOTOS_SINGLE_ITEM_JOB (source_object);
   TrackerSparqlCursor *cursor = NULL;
+  const gchar *id;
+  const gchar *uri;
 
   cursor = photos_single_item_job_finish (job, res, &error);
   if (error != NULL)
@@ -159,6 +179,10 @@ photos_item_manager_item_created_executed (GObject *source_object, GAsyncResult
 
   photos_item_manager_add_item (self, cursor, FALSE);
 
+  id = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_URN, NULL);
+  uri = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_URI, NULL);
+  photos_item_manager_check_wait_for_changes (self, id, uri);
+
  out:
   g_clear_object (&cursor);
   g_object_unref (self);
@@ -207,7 +231,14 @@ photos_item_manager_changes_pending_foreach (gpointer key, gpointer value, gpoin
 
       object = photos_base_manager_get_object_by_id (PHOTOS_BASE_MANAGER (self), change_urn);
       if (object != NULL)
-        photos_base_item_refresh (PHOTOS_BASE_ITEM (object));
+        {
+          const gchar *uri;
+
+          photos_base_item_refresh (PHOTOS_BASE_ITEM (object));
+
+          uri = photos_base_item_get_uri (PHOTOS_BASE_ITEM (object));
+          photos_item_manager_check_wait_for_changes (self, change_urn, uri);
+        }
     }
   else if (change_type == PHOTOS_TRACKER_CHANGE_EVENT_CREATED)
     {
@@ -571,6 +602,7 @@ photos_item_manager_dispose (GObject *object)
 
   g_clear_pointer (&self->collections, (GDestroyNotify) g_hash_table_unref);
   g_clear_pointer (&self->hidden_items, (GDestroyNotify) g_hash_table_unref);
+  g_clear_pointer (&self->wait_for_changes_table, (GDestroyNotify) g_hash_table_unref);
   g_clear_object (&self->active_object);
   g_clear_object (&self->loader_cancellable);
   g_clear_object (&self->active_collection);
@@ -606,6 +638,10 @@ photos_item_manager_init (PhotosItemManager *self)
                                               g_str_equal,
                                               g_free,
                                               (GDestroyNotify) photos_item_manager_hidden_item_free);
+  self->wait_for_changes_table = g_hash_table_new_full (g_str_hash,
+                                                        g_str_equal,
+                                                        g_free,
+                                                        (GDestroyNotify) photos_utils_object_list_free_full);
   self->extension_point = g_io_extension_point_lookup (PHOTOS_BASE_ITEM_EXTENSION_POINT_NAME);
   self->collection_path = g_queue_new ();
   self->history = g_queue_new ();
@@ -1027,6 +1063,57 @@ photos_item_manager_unhide_item (PhotosItemManager *self, PhotosBaseItem *item)
 }
 
 
+void
+photos_item_manager_wait_for_changes_async (PhotosItemManager *self,
+                                            PhotosBaseItem *item,
+                                            GCancellable *cancellable,
+                                            GAsyncReadyCallback callback,
+                                            gpointer user_data)
+{
+  GList *tasks;
+  GTask *task = NULL;
+  const gchar *uri;
+
+  g_return_if_fail (PHOTOS_IS_ITEM_MANAGER (self));
+  g_return_if_fail (PHOTOS_IS_BASE_ITEM (item));
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_source_tag (task, photos_item_manager_wait_for_changes_async);
+
+  if (!PHOTOS_IS_LOCAL_ITEM (item))
+    {
+      const gchar *id;
+
+      id = photos_filterable_get_id (PHOTOS_FILTERABLE (item));
+      g_task_return_pointer (task, g_strdup (id), g_free);
+      goto out;
+    }
+
+  uri = photos_base_item_get_uri (item);
+  tasks = (GList *) g_hash_table_lookup (self->wait_for_changes_table, uri);
+  tasks = g_list_copy_deep (tasks, (GCopyFunc) g_object_ref, NULL);
+  tasks = g_list_prepend (tasks, g_object_ref (task));
+  g_hash_table_insert (self->wait_for_changes_table, g_strdup (uri), tasks);
+
+ out:
+  g_clear_object (&task);
+}
+
+
+gchar *
+photos_item_manager_wait_for_changes_finish (PhotosItemManager *self, GAsyncResult *res, GError **error)
+{
+  GTask *task = G_TASK (res);
+
+  g_return_val_if_fail (PHOTOS_IS_ITEM_MANAGER (self), NULL);
+  g_return_val_if_fail (g_task_is_valid (res, self), NULL);
+  g_return_val_if_fail (g_task_get_source_tag (task) == photos_item_manager_wait_for_changes_async, NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+  return g_task_propagate_pointer (task, error);
+}
+
+
 gboolean
 photos_mode_controller_get_can_fullscreen (PhotosModeController *self)
 {
diff --git a/src/photos-item-manager.h b/src/photos-item-manager.h
index a14e10b..1ba0884 100644
--- a/src/photos-item-manager.h
+++ b/src/photos-item-manager.h
@@ -111,6 +111,16 @@ PhotosLoadState           photos_item_manager_get_load_state               (Phot
 void                      photos_item_manager_hide_item                    (PhotosItemManager *self,
                                                                             PhotosBaseItem *item);
 
+void                      photos_item_manager_wait_for_changes_async       (PhotosItemManager *self,
+                                                                            PhotosBaseItem *item,
+                                                                            GCancellable *cancellable,
+                                                                            GAsyncReadyCallback callback,
+                                                                            gpointer user_data);
+
+gchar                    *photos_item_manager_wait_for_changes_finish      (PhotosItemManager *self,
+                                                                            GAsyncResult *res,
+                                                                            GError **error);
+
 void                      photos_item_manager_unhide_item                  (PhotosItemManager *self,
                                                                             PhotosBaseItem *item);
 


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