[gimp/gimp-2-10] app: add gimp_idle_run_async[_full]()



commit d0d43ce2528dda8968bd645341c2af2a2c6317d3
Author: Ell <ell_se yahoo com>
Date:   Sat Mar 14 00:29:55 2020 +0200

    app: add gimp_idle_run_async[_full]()
    
    In gimp-utils, add new gimp_idle_run_async() and
    gimp_idle_run_async_full() functions, having the same signature as
    gimp_parallel_run_async[_full](), but running the async function in
    an idle source on the main thread, instead of in a separate thread.
    
    The 'priority' parameter of gimp_idle_run_async_full() specifies
    the idle-source priority.
    
    (cherry picked from commit 6733b153ccfd4e54d29683b0374e1b02528fe2d1)

 app/core/gimp-utils.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/core/gimp-utils.h |   7 ++++
 2 files changed, 110 insertions(+)
---
diff --git a/app/core/gimp-utils.c b/app/core/gimp-utils.c
index 82482edf51..1baab6c8cd 100644
--- a/app/core/gimp-utils.c
+++ b/app/core/gimp-utils.c
@@ -58,6 +58,7 @@
 
 #include "gimp.h"
 #include "gimp-utils.h"
+#include "gimpasync.h"
 #include "gimpcontext.h"
 #include "gimperror.h"
 
@@ -881,6 +882,108 @@ gimp_g_list_compare (GList *list1,
   return 0;
 }
 
+typedef struct
+{
+  GimpAsync        *async;
+  gint              idle_id;
+
+  GimpRunAsyncFunc  func;
+  gpointer          user_data;
+  GDestroyNotify    user_data_destroy_func;
+
+} GimpIdleRunAsyncData;
+
+static GimpIdleRunAsyncData *
+gimp_idle_run_async_data_new (void)
+{
+  return g_slice_new0 (GimpIdleRunAsyncData);
+}
+
+static void
+gimp_idle_run_async_data_free (GimpIdleRunAsyncData *data)
+{
+  g_signal_handlers_disconnect_by_data (data->async, data);
+
+  if (data->user_data && data->user_data_destroy_func)
+    data->user_data_destroy_func (data->user_data);
+
+  if (! gimp_async_is_stopped (data->async))
+    gimp_async_abort (data->async);
+
+  g_object_unref (data->async);
+
+  g_slice_free (GimpIdleRunAsyncData, data);
+}
+
+static void
+gimp_idle_run_async_cancel (GimpAsync            *async,
+                            GimpIdleRunAsyncData *data)
+{
+  g_source_remove (data->idle_id);
+}
+
+static gboolean
+gimp_idle_run_async_idle (GimpIdleRunAsyncData *data)
+{
+  g_signal_handlers_block_by_func (data->async,
+                                   gimp_idle_run_async_cancel,
+                                   data);
+
+  data->func (data->async, data->user_data);
+
+  g_signal_handlers_unblock_by_func (data->async,
+                                     gimp_idle_run_async_cancel,
+                                     data);
+
+  if (gimp_async_is_stopped (data->async))
+    {
+      data->user_data = NULL;
+
+      return G_SOURCE_REMOVE;
+    }
+
+  return G_SOURCE_CONTINUE;
+}
+
+GimpAsync *
+gimp_idle_run_async (GimpRunAsyncFunc func,
+                     gpointer         user_data)
+{
+  return gimp_idle_run_async_full (G_PRIORITY_DEFAULT_IDLE, func,
+                                   user_data, NULL);
+}
+
+GimpAsync *
+gimp_idle_run_async_full (gint             priority,
+                          GimpRunAsyncFunc func,
+                          gpointer         user_data,
+                          GDestroyNotify   user_data_destroy_func)
+{
+  GimpIdleRunAsyncData *data;
+
+  g_return_val_if_fail (func != NULL, NULL);
+
+  data = gimp_idle_run_async_data_new ();
+
+  data->func                   = func;
+  data->user_data              = user_data;
+  data->user_data_destroy_func = user_data_destroy_func;
+
+  data->async = gimp_async_new ();
+
+  g_signal_connect (data->async, "cancel",
+                    G_CALLBACK (gimp_idle_run_async_cancel),
+                    data);
+
+  data->idle_id = g_idle_add_full (
+    priority,
+    (GSourceFunc) gimp_idle_run_async_idle,
+    data,
+    (GDestroyNotify) gimp_idle_run_async_data_free);
+
+  return g_object_ref (data->async);
+}
+
 
 /*  debug stuff  */
 
diff --git a/app/core/gimp-utils.h b/app/core/gimp-utils.h
index 20b8b8afa2..8373de7779 100644
--- a/app/core/gimp-utils.h
+++ b/app/core/gimp-utils.h
@@ -101,6 +101,13 @@ gboolean     gimp_ascii_strtod                     (const gchar     *nptr,
 gint         gimp_g_list_compare                   (GList           *list1,
                                                     GList           *list2);
 
+GimpAsync  * gimp_idle_run_async                   (GimpRunAsyncFunc func,
+                                                    gpointer         user_data);
+GimpAsync  * gimp_idle_run_async_full              (gint             priority,
+                                                    GimpRunAsyncFunc func,
+                                                    gpointer         user_data,
+                                                    GDestroyNotify   user_data_destroy_func);
+
 GimpImage  * gimp_create_image_from_buffer         (Gimp            *gimp,
                                                     GeglBuffer      *buffer,
                                                     const gchar     *image_name);


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