[gnome-builder/wip/tintou/toolchain] Make IdeToolchainManager an GAsyncInitable



commit c2a6832e5308db65bb1f1fa4330b28db16c3747b
Author: Corentin Noël <corentin noel collabora co uk>
Date:   Mon Apr 16 16:16:30 2018 +0100

    Make IdeToolchainManager an GAsyncInitable

 src/libide/ide-context.c                     |  46 ++++++---
 src/libide/toolchain/ide-toolchain-manager.c | 145 +++++++++++++++++++++++----
 2 files changed, 157 insertions(+), 34 deletions(-)
---
diff --git a/src/libide/ide-context.c b/src/libide/ide-context.c
index 5732bdcad..e3e897a47 100644
--- a/src/libide/ide-context.c
+++ b/src/libide/ide-context.c
@@ -1150,25 +1150,41 @@ ide_context_init_runtimes (gpointer             source_object,
 }
 
 static void
-ide_context_init_toolchains (gpointer             source_object,
-                             GCancellable        *cancellable,
-                             GAsyncReadyCallback  callback,
-                             gpointer             user_data)
+ide_context_init_toolchain_manager_cb (GObject      *object,
+                                           GAsyncResult *result,
+                                           gpointer      user_data)
 {
-  IdeContext *self = source_object;
-  g_autoptr(GTask) task = NULL;
+  GAsyncInitable *initable = (GAsyncInitable *)object;
+  g_autoptr(IdeTask) task = user_data;
   g_autoptr(GError) error = NULL;
 
-  g_return_if_fail (IDE_IS_CONTEXT (self));
-
-  task = g_task_new (self, cancellable, callback, user_data);
-  g_task_set_source_tag (task, ide_context_init_toolchains);
-  g_task_set_priority (task, G_PRIORITY_LOW);
+  g_assert (G_IS_ASYNC_INITABLE (initable));
+  g_assert (G_IS_ASYNC_RESULT (result));
 
-  if (!g_initable_init (G_INITABLE (self->toolchain_manager), cancellable, &error))
-    g_task_return_error (task, g_steal_pointer (&error));
+  if (!g_async_initable_init_finish (initable, result, &error))
+    ide_task_return_error (task, g_steal_pointer (&error));
   else
-    g_task_return_boolean (task, TRUE);
+    ide_task_return_boolean (task, TRUE);
+}
+
+static void
+ide_context_init_toolchain_manager (gpointer             source_object,
+                                    GCancellable        *cancellable,
+                                    GAsyncReadyCallback  callback,
+                                    gpointer             user_data)
+{
+  IdeContext *self = source_object;
+  g_autoptr(IdeTask) task = NULL;
+
+  g_assert (IDE_IS_CONTEXT (self));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = ide_task_new (self, cancellable, callback, user_data);
+  g_async_initable_init_async (G_ASYNC_INITABLE (self->toolchain_manager),
+                               G_PRIORITY_DEFAULT,
+                               cancellable,
+                               ide_context_init_toolchain_manager_cb,
+                               g_object_ref (task));
 }
 
 static void
@@ -1839,7 +1855,7 @@ ide_context_init_async (GAsyncInitable      *initable,
                         ide_context_init_search_engine,
                         ide_context_init_documentation,
                         ide_context_init_runtimes,
-                        ide_context_init_toolchains,
+                        ide_context_init_toolchain_manager,
                         ide_context_init_configuration_manager,
                         ide_context_init_build_manager,
                         ide_context_init_run_manager,
diff --git a/src/libide/toolchain/ide-toolchain-manager.c b/src/libide/toolchain/ide-toolchain-manager.c
index de1dafdf0..2c44058b6 100644
--- a/src/libide/toolchain/ide-toolchain-manager.c
+++ b/src/libide/toolchain/ide-toolchain-manager.c
@@ -27,6 +27,7 @@
 #include "ide-context.h"
 #include "ide-debug.h"
 
+#include "application/ide-application.h"
 #include "buildsystem/ide-build-private.h"
 #include "config/ide-configuration.h"
 #include "devices/ide-device.h"
@@ -51,12 +52,12 @@ typedef struct
   gchar            *toolchain_id;
 } PrepareState;
 
-static void list_model_iface_init (GListModelInterface *iface);
-static void initable_iface_init   (GInitableIface      *iface);
+static void list_model_iface_init     (GListModelInterface *iface);
+static void async_initable_iface_init (GAsyncInitableIface *iface);
 
 G_DEFINE_TYPE_EXTENDED (IdeToolchainManager, ide_toolchain_manager, IDE_TYPE_OBJECT, 0,
                         G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init)
-                        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init))
+                        G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init))
 
 static void
 prepare_state_free (PrepareState *state)
@@ -211,23 +212,101 @@ ide_toolchain_manager_extension_removed (PeasExtensionSet *set,
   ide_toolchain_provider_unload (provider, self);
 }
 
-static gboolean
-ide_toolchain_manager_initable_init (GInitable     *initable,
-                                     GCancellable  *cancellable,
-                                     GError       **error)
+static void
+ide_toolchain_manager_init_load_cb (GObject      *object,
+                                    GAsyncResult *result,
+                                    gpointer      user_data)
 {
-  IdeToolchainManager *self = (IdeToolchainManager *)initable;
+  IdeToolchainProvider *provider = (IdeToolchainProvider *)object;
+  IdeToolchainManager *self;
+  g_autoptr(GError) error = NULL;
+  g_autoptr(IdeTask) task = user_data;
+  GPtrArray *providers;
   IdeContext *context;
-  g_autoptr(IdeSimpleToolchain) default_toolchain = NULL;
-  guint idx;
 
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_MAIN_THREAD ());
+  g_assert (IDE_IS_TOOLCHAIN_PROVIDER (provider));
+  g_assert (G_IS_ASYNC_RESULT (result));
+  g_assert (IDE_IS_TASK (task));
+
+  self = ide_task_get_source_object (task);
   g_assert (IDE_IS_TOOLCHAIN_MANAGER (self));
+
+  context = ide_object_get_context (IDE_OBJECT (self));
+  g_assert (IDE_IS_CONTEXT (context));
+
+  if (!ide_toolchain_provider_load_finish (provider, result, &error))
+    {
+      g_print ("%s\n", G_OBJECT_TYPE_NAME (provider));
+      g_assert (error != NULL);
+      ide_context_warning (context,
+                           "Failed to initialize toolchain provider: %s: %s",
+                           G_OBJECT_TYPE_NAME (provider), error->message);
+    }
+
+  providers = ide_task_get_task_data (task);
+  g_assert (providers != NULL);
+  g_assert (providers->len > 0);
+
+  if (!g_ptr_array_remove (providers, provider))
+    g_critical ("Failed to locate provider in active set");
+
+  if (providers->len == 0)
+    ide_task_return_boolean (task, TRUE);
+
+  IDE_EXIT;
+}
+
+static void
+ide_toolchain_manager_collect_providers (PeasExtensionSet *set,
+                                         PeasPluginInfo   *plugin_info,
+                                         PeasExtension    *exten,
+                                         gpointer          user_data)
+{
+  IdeToolchainProvider *provider = (IdeToolchainProvider *)exten;
+  GPtrArray *providers = user_data;
+
+  g_assert (PEAS_IS_EXTENSION_SET (set));
+  g_assert (plugin_info != NULL);
+  g_assert (IDE_IS_TOOLCHAIN_PROVIDER (provider));
+  g_assert (providers != NULL);
+
+  g_ptr_array_add (providers, g_object_ref (provider));
+}
+
+static void
+ide_toolchain_manager_init_async (GAsyncInitable      *initable,
+                                  gint                 priority,
+                                  GCancellable        *cancellable,
+                                  GAsyncReadyCallback  callback,
+                                  gpointer             user_data)
+{
+  IdeToolchainManager *self = (IdeToolchainManager *)initable;
+  g_autoptr(IdeSimpleToolchain) default_toolchain = NULL;
+  g_autoptr(GPtrArray) providers = NULL;
+  g_autoptr(IdeTask) task = NULL;
+  IdeContext *context;
+
+  g_assert (G_IS_ASYNC_INITABLE (self));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = ide_task_new (self, cancellable, callback, user_data);
+  ide_task_set_source_tag (task, ide_toolchain_manager_init_async);
+  ide_task_set_priority (task, priority);
+
+  /*g_signal_connect_swapped (task,
+                            "notify::completed",
+                            G_CALLBACK (notify_providers_loaded),
+                            self);*/
+
   context = ide_object_get_context (IDE_OBJECT (self));
   g_assert (IDE_IS_CONTEXT (context));
 
   self->extensions = peas_extension_set_new (peas_engine_get_default (),
                                              IDE_TYPE_TOOLCHAIN_PROVIDER,
-                                            "context", context,
+                                             "context", context,
                                              NULL);
 
   g_signal_connect (self->extensions,
@@ -240,22 +319,50 @@ ide_toolchain_manager_initable_init (GInitable     *initable,
                     G_CALLBACK (ide_toolchain_manager_extension_removed),
                     self);
 
+  providers = g_ptr_array_new_with_free_func (g_object_unref);
   peas_extension_set_foreach (self->extensions,
-                              ide_toolchain_manager_extension_added,
-                              self);
+                              ide_toolchain_manager_collect_providers,
+                              providers);
+  ide_task_set_task_data (task, g_ptr_array_ref (providers), (GDestroyNotify)g_ptr_array_unref);
 
-  idx = self->toolchains->len;
   default_toolchain = ide_simple_toolchain_new (context, "default");
-  g_ptr_array_add (self->toolchains, g_object_ref (default_toolchain));
-  g_list_model_items_changed (G_LIST_MODEL (self), idx, 0, 1);
+  g_ptr_array_add (self->toolchains, g_steal_pointer (&default_toolchain));
+
+  for (guint i = 0; i < providers->len; i++)
+    {
+      IdeToolchainProvider *provider = g_ptr_array_index (providers, i);
+
+      g_assert (IDE_IS_TOOLCHAIN_PROVIDER (provider));
+
+      provider_connect (self, provider);
+
+      ide_toolchain_provider_load_async (provider,
+                                         cancellable,
+                                         ide_toolchain_manager_init_load_cb,
+                                         g_object_ref (task));
+    }
+
+  if (providers->len == 0)
+    ide_task_return_boolean (task, TRUE);
+}
+
+static gboolean
+ide_toolchain_manager_init_finish (GAsyncInitable  *initable,
+                                   GAsyncResult    *result,
+                                   GError         **error)
+{
+  g_assert (IDE_IS_MAIN_THREAD ());
+  g_assert (IDE_IS_TOOLCHAIN_MANAGER (initable));
+  g_assert (IDE_IS_TASK (result));
 
-  return TRUE;
+  return ide_task_propagate_boolean (IDE_TASK (result), error);
 }
 
 static void
-initable_iface_init (GInitableIface *iface)
+async_initable_iface_init (GAsyncInitableIface *iface)
 {
-  iface->init = ide_toolchain_manager_initable_init;
+  iface->init_async = ide_toolchain_manager_init_async;
+  iface->init_finish = ide_toolchain_manager_init_finish;
 }
 
 static void


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