[gnome-photos] base-item, pipeline: Construct Pipeline asynchronously



commit 04012f21e010a5cddf96061108d67e9ac6cc58d9
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
    directory will be on a local filesystem, we have to do it
    asynchronously.

 src/photos-base-item.c |   56 +++++++++++++++++++++++++++----------
 src/photos-pipeline.c  |   71 +++++++++++++++++++++++++++++++++++++++++++++--
 src/photos-pipeline.h  |    9 +++++-
 3 files changed, 117 insertions(+), 19 deletions(-)
---
diff --git a/src/photos-base-item.c b/src/photos-base-item.c
index a6f2433..97c16cd 100644
--- a/src/photos-base-item.c
+++ b/src/photos-base-item.c
@@ -796,17 +796,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);
 
@@ -896,6 +885,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 gboolean
 photos_base_item_process_idle (gpointer user_data)
 {
@@ -1759,6 +1781,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);
 
@@ -1771,10 +1795,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 984b312..8131f29 100644
--- a/src/photos-pipeline.c
+++ b/src/photos-pipeline.c
@@ -48,8 +48,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));
 
 
 static gchar *
@@ -169,10 +172,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 e64e672..b6e1d34 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]