[libpeas/wip/hadess/external-loaded-plugins] Add loaded-external-plugins property to PeasEngine



commit 6d452d415895021d668359fa7b26d891f3ea347e
Author: Bastien Nocera <hadess hadess net>
Date:   Sat Feb 23 16:28:08 2019 +0100

    Add loaded-external-plugins property to PeasEngine
    
    This will allow applications to bind this new property instead of
    "loaded-plugins" which causes GSettings writes on startup when builtin
    plugins are used.
    
    Closes: #145

 docs/reference/libpeas-sections.txt |   2 +
 libpeas/peas-engine.c               | 192 ++++++++++++++++++++++++++++--------
 libpeas/peas-engine.h               |   5 +
 tests/libpeas/engine.c              |  42 ++++++++
 4 files changed, 199 insertions(+), 42 deletions(-)
---
diff --git a/docs/reference/libpeas-sections.txt b/docs/reference/libpeas-sections.txt
index 610a163..dfeea45 100644
--- a/docs/reference/libpeas-sections.txt
+++ b/docs/reference/libpeas-sections.txt
@@ -69,6 +69,8 @@ peas_engine_rescan_plugins
 peas_engine_get_plugin_list
 peas_engine_get_loaded_plugins
 peas_engine_set_loaded_plugins
+peas_engine_get_loaded_external_plugins
+peas_engine_set_loaded_external_plugins
 peas_engine_get_plugin_info
 peas_engine_load_plugin
 peas_engine_unload_plugin
diff --git a/libpeas/peas-engine.c b/libpeas/peas-engine.c
index 5713cb0..2664cc2 100644
--- a/libpeas/peas-engine.c
+++ b/libpeas/peas-engine.c
@@ -75,6 +75,7 @@ enum {
   PROP_PLUGIN_LIST,
   PROP_LOADED_PLUGINS,
   PROP_NONGLOBAL_LOADERS,
+  PROP_LOADED_EXTERNAL_PLUGINS,
   N_PROPERTIES
 };
 
@@ -551,6 +552,10 @@ peas_engine_set_property (GObject      *object,
     case PROP_NONGLOBAL_LOADERS:
       priv->use_nonglobal_loaders = g_value_get_boolean (value);
       break;
+    case PROP_LOADED_EXTERNAL_PLUGINS:
+      peas_engine_set_loaded_external_plugins (engine,
+                                               (const gchar **) g_value_get_boxed (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -579,6 +584,10 @@ peas_engine_get_property (GObject    *object,
     case PROP_NONGLOBAL_LOADERS:
       g_value_set_boolean (value, priv->use_nonglobal_loaders);
       break;
+    case PROP_LOADED_EXTERNAL_PLUGINS:
+      g_value_take_boxed (value,
+                          (gconstpointer) peas_engine_get_loaded_external_plugins (engine));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -685,15 +694,8 @@ peas_engine_class_init (PeasEngineClass *klass)
    * This will be modified when peas_engine_load_plugin() or
    * peas_engine_unload_plugin() is called.
    *
-   * This can be used with GSettings to save the loaded plugins by binding
-   * to this property after instantiating the engine by doing:
-   * |[
-   *   g_settings_bind (gsettings_object,
-   *                    LOADED_PLUGINS_KEY,
-   *                    engine,
-   *                    "loaded-plugins",
-   *                    G_SETTINGS_BIND_DEFAULT);
-   * ]|
+   * It is recommended that you bind a GSettings to
+   * PeasEngine:loaded-external-plugins instead.
    *
    * Note: notify will not be called when the engine is being destroyed.
    */
@@ -723,6 +725,37 @@ peas_engine_class_init (PeasEngineClass *klass)
                           G_PARAM_CONSTRUCT_ONLY |
                           G_PARAM_STATIC_STRINGS);
 
+  /**
+   * PeasEngine:loaded-external-plugins:
+   *
+   * The list of loaded external plugins.
+   *
+   * The same list of plugins as PeasEngine:loaded-plugins, minus builtin
+   * ones.
+   *
+   * This can be used with GSettings to save the loaded plugins in a setting
+   * by binding to this property after instantiating the engine by doing:
+   * |[
+   *   g_settings_bind (gsettings_object,
+   *                    LOADED_PLUGINS_KEY,
+   *                    engine,
+   *                    "loaded-external-plugins",
+   *                    G_SETTINGS_BIND_DEFAULT);
+   * ]|
+   *
+   * Note that you will need to load and activate the builtin plugins
+   * after doing this.
+   *
+   * Note: notify will not be called when the engine is being destroyed.
+   */
+  properties[PROP_LOADED_EXTERNAL_PLUGINS] =
+    g_param_spec_boxed ("loaded-external-plugins",
+                        "Loaded external plugins",
+                        "The list of loaded external plugins",
+                        G_TYPE_STRV,
+                        G_PARAM_READWRITE |
+                        G_PARAM_STATIC_STRINGS);
+
   /**
    * PeasEngine::load-plugin:
    * @engine: A #PeasEngine.
@@ -1160,6 +1193,12 @@ peas_engine_load_plugin_real (PeasEngine     *engine,
   g_object_notify_by_pspec (G_OBJECT (engine),
                             properties[PROP_LOADED_PLUGINS]);
 
+  if (!peas_plugin_info_is_builtin (info))
+    {
+      g_object_notify_by_pspec (G_OBJECT (engine),
+                                properties[PROP_LOADED_EXTERNAL_PLUGINS]);
+    }
+
   return;
 
 error:
@@ -1238,8 +1277,15 @@ peas_engine_unload_plugin_real (PeasEngine     *engine,
    * loaded plugins can easily be kept in GSettings
    */
   if (!priv->in_dispose)
-    g_object_notify_by_pspec (G_OBJECT (engine),
-                              properties[PROP_LOADED_PLUGINS]);
+    {
+      g_object_notify_by_pspec (G_OBJECT (engine),
+                                properties[PROP_LOADED_PLUGINS]);
+      if (!peas_plugin_info_is_builtin (info))
+        {
+          g_object_notify_by_pspec (G_OBJECT (engine),
+                                    properties[PROP_LOADED_EXTERNAL_PLUGINS]);
+        }
+    }
 }
 
 /**
@@ -1461,21 +1507,9 @@ peas_engine_create_extension (PeasEngine     *engine,
   return exten;
 }
 
-/**
- * peas_engine_get_loaded_plugins:
- * @engine: A #PeasEngine.
- *
- * Returns the list of the names of all the loaded plugins, or an array
- * containing a single %NULL element if there is no plugin currently loaded.
- *
- * Please note that the returned array is a newly allocated one: you will need
- * to free it using g_strfreev().
- *
- * Returns: (transfer full) (array zero-terminated=1): A newly-allocated
- * %NULL-terminated array of strings.
- */
-gchar **
-peas_engine_get_loaded_plugins (PeasEngine *engine)
+static gchar **
+_peas_engine_get_loaded_plugins (PeasEngine *engine,
+                                 gboolean    with_builtin)
 {
   PeasEnginePrivate *priv = GET_PRIV (engine);
   GArray *array;
@@ -1490,7 +1524,8 @@ peas_engine_get_loaded_plugins (PeasEngine *engine)
       PeasPluginInfo *info = (PeasPluginInfo *) pl->data;
       gchar *module_name;
 
-      if (peas_plugin_info_is_loaded (info))
+      if (peas_plugin_info_is_loaded (info) &&
+          (with_builtin || !peas_plugin_info_is_builtin (info)))
         {
           module_name = g_strdup (peas_plugin_info_get_module_name (info));
           g_array_append_val (array, module_name);
@@ -1500,6 +1535,45 @@ peas_engine_get_loaded_plugins (PeasEngine *engine)
   return (gchar **) g_array_free (array, FALSE);
 }
 
+/**
+ * peas_engine_get_loaded_plugins:
+ * @engine: A #PeasEngine.
+ *
+ * Returns the list of the names of all the loaded plugins, or an array
+ * containing a single %NULL element if there is no plugin currently loaded.
+ *
+ * Please note that the returned array is a newly allocated one: you will need
+ * to free it using g_strfreev().
+ *
+ * Returns: (transfer full) (array zero-terminated=1): A newly-allocated
+ * %NULL-terminated array of strings.
+ */
+gchar **
+peas_engine_get_loaded_plugins (PeasEngine *engine)
+{
+  return _peas_engine_get_loaded_plugins (engine, TRUE);
+}
+
+/**
+ * peas_engine_get_loaded_external_plugins:
+ * @engine: A #PeasEngine.
+ *
+ * Returns the list of the names of all the loaded external plugins, or an array
+ * containing a single %NULL element if there is no external plugin currently
+ * loaded.
+ *
+ * Please note that the returned array is a newly allocated one: you will need
+ * to free it using g_strfreev().
+ *
+ * Returns: (transfer full) (array zero-terminated=1): A newly-allocated
+ * %NULL-terminated array of strings.
+ */
+gchar **
+peas_engine_get_loaded_external_plugins (PeasEngine *engine)
+{
+  return _peas_engine_get_loaded_plugins (engine, FALSE);
+}
+
 static gboolean
 string_in_strv (const gchar  *needle,
                 const gchar **haystack)
@@ -1518,21 +1592,10 @@ string_in_strv (const gchar  *needle,
   return FALSE;
 }
 
-/**
- * peas_engine_set_loaded_plugins:
- * @engine: A #PeasEngine.
- * @plugin_names: (allow-none) (array zero-terminated=1): A %NULL-terminated
- *  array of plugin names, or %NULL.
- *
- * Sets the list of loaded plugins for @engine. When this function is called,
- * the #PeasEngine will load all the plugins whose names are in @plugin_names,
- * and ensures all other active plugins are unloaded.
- *
- * If @plugin_names is %NULL, all plugins will be unloaded.
- */
-void
-peas_engine_set_loaded_plugins (PeasEngine   *engine,
-                                const gchar **plugin_names)
+static void
+_peas_engine_set_loaded_plugins (PeasEngine   *engine,
+                                 const gchar **plugin_names,
+                                 gboolean      with_builtin)
 {
   PeasEnginePrivate *priv = GET_PRIV (engine);
   GList *pl;
@@ -1549,6 +1612,12 @@ peas_engine_set_loaded_plugins (PeasEngine   *engine,
       if (!peas_plugin_info_is_available (info, NULL))
         continue;
 
+      /* If we're not modifying builtin plugins, then we don't
+       * care whether they're to loaded or not, skip them */
+      if (!with_builtin &&
+          peas_plugin_info_is_builtin (info))
+        continue;
+
       module_name = peas_plugin_info_get_module_name (info);
       is_loaded = peas_plugin_info_is_loaded (info);
 
@@ -1559,6 +1628,45 @@ peas_engine_set_loaded_plugins (PeasEngine   *engine,
       else if (is_loaded && !to_load)
         g_signal_emit (engine, signals[UNLOAD_PLUGIN], 0, info);
     }
+
+}
+
+/**
+ * peas_engine_set_loaded_plugins:
+ * @engine: A #PeasEngine.
+ * @plugin_names: (allow-none) (array zero-terminated=1): A %NULL-terminated
+ *  array of plugin names, or %NULL.
+ *
+ * Sets the list of loaded plugins for @engine. When this function is called,
+ * the #PeasEngine will load all the plugins whose names are in @plugin_names,
+ * and ensures all other active plugins are unloaded.
+ *
+ * If @plugin_names is %NULL, all plugins will be unloaded.
+ */
+void
+peas_engine_set_loaded_plugins (PeasEngine   *engine,
+                                const gchar **plugin_names)
+{
+  _peas_engine_set_loaded_plugins (engine, plugin_names, TRUE);
+}
+
+/**
+ * peas_engine_set_loaded_external_plugins:
+ * @engine: A #PeasEngine.
+ * @plugin_names: (allow-none) (array zero-terminated=1): A %NULL-terminated
+ *  array of plugin names, or %NULL.
+ *
+ * Sets the list of loaded external plugins for @engine. When this function is
+ * called, the #PeasEngine will load all the external plugins whose names are in
+ * @plugin_names, and ensures all other active external plugins are unloaded.
+ *
+ * If @plugin_names is %NULL, all external plugins will be unloaded.
+ */
+void
+peas_engine_set_loaded_external_plugins (PeasEngine   *engine,
+                                         const gchar **plugin_names)
+{
+  _peas_engine_set_loaded_plugins (engine, plugin_names, FALSE);
 }
 
 /**
diff --git a/libpeas/peas-engine.h b/libpeas/peas-engine.h
index 8453c57..4e26a3f 100644
--- a/libpeas/peas-engine.h
+++ b/libpeas/peas-engine.h
@@ -94,6 +94,11 @@ const GList      *peas_engine_get_plugin_list     (PeasEngine      *engine);
 gchar           **peas_engine_get_loaded_plugins  (PeasEngine      *engine);
 void              peas_engine_set_loaded_plugins  (PeasEngine      *engine,
                                                    const gchar    **plugin_names);
+gchar           **peas_engine_get_loaded_external_plugins
+                                                  (PeasEngine      *engine);
+void              peas_engine_set_loaded_external_plugins
+                                                  (PeasEngine      *engine,
+                                                   const gchar    **plugin_names);
 PeasPluginInfo   *peas_engine_get_plugin_info     (PeasEngine      *engine,
                                                    const gchar     *plugin_name);
 
diff --git a/tests/libpeas/engine.c b/tests/libpeas/engine.c
index 0c975f4..5196338 100644
--- a/tests/libpeas/engine.c
+++ b/tests/libpeas/engine.c
@@ -31,6 +31,24 @@
 
 #include "testing/testing.h"
 
+static void
+peas_engine_dump_loaded_plugins (PeasEngine *engine)
+{
+  char **plugins;
+  char *list;
+
+  plugins = peas_engine_get_loaded_plugins (engine);
+  if (plugins[0] == NULL)
+    {
+      g_print ("Plugins loaded: (none)\n");
+      return;
+    }
+  list = g_strjoinv (", ", plugins);
+  g_strfreev (plugins);
+  g_print ("Plugins loaded: %s\n", list);
+  g_free (list);
+}
+
 typedef struct _TestFixture TestFixture;
 
 struct _TestFixture {
@@ -356,6 +374,20 @@ test_engine_loaded_plugins (PeasEngine *engine)
 
   g_object_notify (G_OBJECT (engine), "loaded-plugins");
 
+  /* Unload all the external plugins */
+  info = peas_engine_get_plugin_info (engine, "builtin");
+  g_assert (peas_engine_load_plugin (engine, info));
+  info = peas_engine_get_plugin_info (engine, "loadable");
+  g_assert (peas_engine_load_plugin (engine, info));
+  g_assert_cmpint (loaded, ==, 2);
+  g_assert (loaded_plugins[0] != NULL);
+  g_assert (loaded_plugins[1] != NULL);
+  g_assert (loaded_plugins[2] == NULL);
+  peas_engine_set_loaded_external_plugins (engine, NULL);
+  g_assert_cmpint (loaded, ==, 1);
+  g_assert (loaded_plugins != NULL);
+  g_assert (loaded_plugins[0] != NULL);
+  g_assert_cmpstr (loaded_plugins[0], ==, "builtin");
 
   /* Unload all plugins */
   peas_engine_set_loaded_plugins (engine, NULL);
@@ -383,6 +415,16 @@ test_engine_loaded_plugins (PeasEngine *engine)
   g_assert_cmpstr (loaded_plugins[0], ==, "loadable");
   g_assert (loaded_plugins[1] == NULL);
 
+  /* Unload loadable, and don't load builtin */
+  load_plugins = g_new0 (gchar *, 2);
+  load_plugins[0] = g_strdup ("builtin");
+  peas_engine_set_loaded_external_plugins (engine, (const gchar **) load_plugins);
+  g_strfreev (load_plugins);
+
+  g_assert_cmpint (loaded, ==, 0);
+  g_assert (loaded_plugins != NULL);
+  g_assert (loaded_plugins[0] == NULL);
+
 
   /* Try to load an unavailable plugin */
   load_plugins = g_new0 (gchar *, 2);


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