[gnome-photos/wip/rishi/misc-fixes: 12/24] base-item, pipeline: Construct Pipeline asynchronously



commit f5f245c52e76f945497fc868a004f86d4ca64917
Author: Debarshi Ray <debarshir gnome org>
Date:   Fri Dec 18 15:47:40 2015 +0100

    base-item, pipeline: Construct Pipeline asynchronously
    
    We want to restore any saved Pipeline by reading the XML from disk
    during construction. Since there is no guarantee that the user's home
    directorywill be on a local filesystem, we have to do it
    asynchronously.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=759363

 src/photos-base-item.c |   56 +++++++++++++++++++++++++++----------
 src/photos-pipeline.c  |   72 +++++++++++++++++++++++++++++++++++++++++++++--
 src/photos-pipeline.h  |    9 +++++-
 3 files changed, 117 insertions(+), 20 deletions(-)
---
diff --git a/src/photos-base-item.c b/src/photos-base-item.c
index 55c2de8..669f2c5 100644
--- a/src/photos-base-item.c
+++ b/src/photos-base-item.c
@@ -799,17 +799,6 @@ photos_base_item_load_buffer_async (PhotosBaseItem *self,
       gegl_node_link_many (priv->load, orientation, priv->buffer_sink, NULL);
     }
 
-  if (priv->edit_graph == NULL)
-    {
-      GeglNode *graph;
-
-      priv->edit_graph = gegl_node_new ();
-      priv->buffer_source = gegl_node_new_child (priv->edit_graph, "operation", "gegl:buffer-source", NULL);
-      priv->pipeline = photos_pipeline_new (priv->edit_graph);
-      graph = photos_pipeline_get_graph (priv->pipeline);
-      gegl_node_link (priv->buffer_source, graph);
-    }
-
   task = g_task_new (self, cancellable, callback, user_data);
   g_task_set_source_tag (task, photos_base_item_load_buffer_async);
 
@@ -900,6 +889,39 @@ photos_base_item_load_load_buffer (GObject *source_object, GAsyncResult *res, gp
 
 
 static void
+photos_base_item_load_pipeline (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+  GTask *task = G_TASK (user_data);
+  PhotosBaseItem *self;
+  PhotosBaseItemPrivate *priv;
+  GeglNode *graph;
+  GCancellable *cancellable;
+  GError *error;
+
+  self = PHOTOS_BASE_ITEM (g_task_get_source_object (task));
+  priv = self->priv;
+
+  cancellable = g_task_get_cancellable (task);
+
+  error = NULL;
+  priv->pipeline = photos_pipeline_new_finish (res, &error);
+  if (error != NULL)
+    {
+      g_task_return_error (task, error);
+      goto out;
+    }
+
+  graph = photos_pipeline_get_graph (priv->pipeline);
+  gegl_node_link (priv->buffer_source, graph);
+
+  photos_base_item_load_buffer_async (self, cancellable, photos_base_item_load_load_buffer, g_object_ref 
(task));
+
+ out:
+  g_object_unref (task);
+}
+
+
+static void
 photos_base_item_pipeline_save_save (GObject *source_object, GAsyncResult *res, gpointer user_data)
 {
   GTask *task = G_TASK (user_data);
@@ -1788,6 +1810,8 @@ photos_base_item_load_async (PhotosBaseItem *self,
   g_return_if_fail (PHOTOS_IS_BASE_ITEM (self));
   priv = self->priv;
 
+  g_return_if_fail (priv->edit_graph == NULL || priv->pipeline != NULL);
+
   task = g_task_new (self, cancellable, callback, user_data);
   g_task_set_source_tag (task, photos_base_item_load_async);
 
@@ -1802,10 +1826,12 @@ photos_base_item_load_async (PhotosBaseItem *self,
     }
   else
     {
-      photos_base_item_load_buffer_async (self,
-                                          cancellable,
-                                          photos_base_item_load_load_buffer,
-                                          g_object_ref (task));
+      priv->edit_graph = gegl_node_new ();
+      priv->buffer_source = gegl_node_new_child (priv->edit_graph, "operation", "gegl:buffer-source", NULL);
+      photos_pipeline_new_async (priv->edit_graph,
+                                 cancellable,
+                                 photos_base_item_load_pipeline,
+                                 g_object_ref (task));
     }
 
   g_object_unref (task);
diff --git a/src/photos-pipeline.c b/src/photos-pipeline.c
index 150d858..c938cbb 100644
--- a/src/photos-pipeline.c
+++ b/src/photos-pipeline.c
@@ -24,7 +24,6 @@
 #include <string.h>
 
 #include <glib.h>
-#include <gio/gio.h>
 
 #include "egg-counter.h"
 #include "photos-debug.h"
@@ -52,8 +51,11 @@ enum
   PROP_PARENT,
 };
 
+static void photos_pipeline_async_initable_iface_init (GAsyncInitableIface *iface);
 
-G_DEFINE_TYPE (PhotosPipeline, photos_pipeline, G_TYPE_OBJECT);
+
+G_DEFINE_TYPE_EXTENDED (PhotosPipeline, photos_pipeline, G_TYPE_OBJECT, 0,
+                        G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, 
photos_pipeline_async_initable_iface_init));
 EGG_DEFINE_COUNTER (instances, "PhotosPipeline", "Instances", "Number of PhotosPipeline instances");
 
 
@@ -200,10 +202,72 @@ photos_pipeline_class_init (PhotosPipelineClass *class)
 }
 
 
+static void
+photos_pipeline_async_initable_init_async (GAsyncInitable *initable,
+                                           gint io_priority,
+                                           GCancellable *cancellable,
+                                           GAsyncReadyCallback callback,
+                                           gpointer user_data)
+{
+  PhotosPipeline *self = PHOTOS_PIPELINE (initable);
+  GTask *task;
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_source_tag (task, photos_pipeline_async_initable_init_async);
+
+  g_task_return_boolean (task, TRUE);
+  g_object_unref (task);
+}
+
+
+static gboolean
+photos_pipeline_async_initable_init_finish (GAsyncInitable *initable, GAsyncResult *res, GError **error)
+{
+  PhotosPipeline *self = PHOTOS_PIPELINE (initable);
+  GTask *task = G_TASK (res);
+
+  g_return_val_if_fail (g_task_is_valid (res, self), FALSE);
+  g_return_val_if_fail (g_task_get_source_tag (task) == photos_pipeline_async_initable_init_async, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  return g_task_propagate_boolean (task, error);
+}
+
+
+static void
+photos_pipeline_async_initable_iface_init (GAsyncInitableIface *iface)
+{
+  iface->init_async = photos_pipeline_async_initable_init_async;
+  iface->init_finish = photos_pipeline_async_initable_init_finish;
+}
+
+
+void
+photos_pipeline_new_async (GeglNode *parent,
+                           GCancellable *cancellable,
+                           GAsyncReadyCallback callback,
+                           gpointer user_data)
+{
+  g_async_initable_new_async (PHOTOS_TYPE_PIPELINE,
+                              G_PRIORITY_DEFAULT,
+                              cancellable,
+                              callback,
+                              user_data,
+                              "parent", parent,
+                              NULL);
+}
+
+
 PhotosPipeline *
-photos_pipeline_new (GeglNode *parent)
+photos_pipeline_new_finish (GAsyncResult *res, GError **error)
 {
-  return g_object_new (PHOTOS_TYPE_PIPELINE, "parent", parent, NULL);
+  GObject *ret_val;
+  GObject *source_object;
+
+  source_object = g_async_result_get_source_object (res);
+  ret_val = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
+  g_object_unref (source_object);
+  return PHOTOS_PIPELINE (ret_val);
 }
 
 
diff --git a/src/photos-pipeline.h b/src/photos-pipeline.h
index 69dd81a..d0a6577 100644
--- a/src/photos-pipeline.h
+++ b/src/photos-pipeline.h
@@ -24,6 +24,7 @@
 #include <stdarg.h>
 
 #include <gegl.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS
 
@@ -54,7 +55,13 @@ typedef struct _PhotosPipelineClass PhotosPipelineClass;
 
 GType                  photos_pipeline_get_type          (void) G_GNUC_CONST;
 
-PhotosPipeline        *photos_pipeline_new               (GeglNode *parent);
+void                   photos_pipeline_new_async         (GeglNode *parent,
+                                                          GCancellable *cancellable,
+                                                          GAsyncReadyCallback callback,
+                                                          gpointer user_data);
+
+PhotosPipeline        *photos_pipeline_new_finish        (GAsyncResult *res,
+                                                          GError **error);
 
 void                   photos_pipeline_add               (PhotosPipeline *self,
                                                           const gchar *operation,


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