[gnome-builder: 53/139] libide-plugins: add libide-plugins static library
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder: 53/139] libide-plugins: add libide-plugins static library
- Date: Thu, 10 Jan 2019 04:21:46 +0000 (UTC)
commit 4817db6543ff3747dab418050b16468583e12f5f
Author: Christian Hergert <chergert redhat com>
Date: Wed Jan 9 16:46:23 2019 -0800
libide-plugins: add libide-plugins static library
This moves the extension components into a static library and can bridge
the child extensions into the IdeObject tree.
src/libide/plugins/ide-extension-adapter.c | 105 ++++++-----
src/libide/plugins/ide-extension-adapter.h | 10 +-
src/libide/plugins/ide-extension-set-adapter.c | 204 ++++++++++++++-------
src/libide/plugins/ide-extension-set-adapter.h | 10 +-
...tension-util.h => ide-extension-util-private.h} | 0
src/libide/plugins/ide-extension-util.c | 26 ++-
src/libide/plugins/libide-plugins.h | 34 ++++
src/libide/plugins/meson.build | 57 +++++-
8 files changed, 314 insertions(+), 132 deletions(-)
---
diff --git a/src/libide/plugins/ide-extension-adapter.c b/src/libide/plugins/ide-extension-adapter.c
index 2480a0ce8..d6043385f 100644
--- a/src/libide/plugins/ide-extension-adapter.c
+++ b/src/libide/plugins/ide-extension-adapter.c
@@ -25,11 +25,8 @@
#include <dazzle.h>
#include <glib/gi18n.h>
-#include "ide-debug.h"
-
-#include "application/ide-application.h"
-#include "plugins/ide-extension-adapter.h"
-#include "plugins/ide-extension-util.h"
+#include "ide-extension-adapter.h"
+#include "ide-extension-util-private.h"
struct _IdeExtensionAdapter
{
@@ -62,6 +59,20 @@ enum {
static GParamSpec *properties [LAST_PROP];
+static gchar *
+ide_extension_adapter_repr (IdeObject *object)
+{
+ IdeExtensionAdapter *self = (IdeExtensionAdapter *)object;
+
+ g_assert (IDE_IS_EXTENSION_ADAPTER (self));
+
+ return g_strdup_printf ("%s interface=“%s” key=“%s” value=“%s”",
+ G_OBJECT_TYPE_NAME (self),
+ g_type_name (self->interface_type),
+ self->key ?: "",
+ self->value ?: "");
+}
+
static GSettings *
ide_extension_adapter_get_settings (IdeExtensionAdapter *self,
PeasPluginInfo *plugin_info)
@@ -107,9 +118,18 @@ ide_extension_adapter_set_extension (IdeExtensionAdapter *self,
self->plugin_info = plugin_info;
- if (g_set_object (&self->extension, extension))
+ if (extension != self->extension)
{
+ if (IDE_IS_OBJECT (self->extension))
+ ide_object_destroy (IDE_OBJECT (self->extension));
+
+ g_set_object (&self->extension, extension);
+
+ if (IDE_IS_OBJECT (extension))
+ ide_object_append (IDE_OBJECT (self), IDE_OBJECT (extension));
+
ide_extension_adapter_monitor (self, plugin_info);
+
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_EXTENSION]);
}
}
@@ -168,30 +188,10 @@ ide_extension_adapter_reload (IdeExtensionAdapter *self)
return;
if (best_match != NULL)
- {
- IdeContext *context = ide_object_get_context (IDE_OBJECT (self));
-
- if (g_type_is_a (self->interface_type, IDE_TYPE_OBJECT))
- extension = ide_extension_new (self->engine,
- best_match,
- self->interface_type,
- "context", context,
- NULL);
- else
- {
- extension = ide_extension_new (self->engine,
- best_match,
- self->interface_type,
- NULL);
- /*
- * If the plugin object turned out to have IdeObject
- * as a base, try to set it now (even though we couldn't
- * do it at construction time).
- */
- if (IDE_IS_OBJECT (extension))
- ide_object_set_context (IDE_OBJECT (extension), context);
- }
- }
+ extension = ide_extension_new (self->engine,
+ best_match,
+ self->interface_type,
+ NULL);
ide_extension_adapter_set_extension (self, best_match, extension);
@@ -220,7 +220,7 @@ ide_extension_adapter_queue_reload (IdeExtensionAdapter *self)
g_assert (IDE_IS_MAIN_THREAD ());
g_assert (IDE_IS_EXTENSION_ADAPTER (self));
- dzl_clear_source (&self->queue_handler);
+ g_clear_handle_id (&self->queue_handler, g_source_remove);
self->queue_handler = g_timeout_add (0, ide_extension_adapter_do_reload, self);
}
@@ -311,7 +311,7 @@ ide_extension_adapter__changed_disabled (IdeExtensionAdapter *self,
g_assert (IDE_IS_EXTENSION_ADAPTER (self));
g_assert (G_IS_SETTINGS (settings));
- if (dzl_str_equal0 (changed_key, "disabled"))
+ if (ide_str_equal0 (changed_key, "disabled"))
ide_extension_adapter_queue_reload (self);
}
@@ -322,7 +322,7 @@ ide_extension_adapter_dispose (GObject *object)
self->interface_type = G_TYPE_INVALID;
- dzl_clear_source (&self->queue_handler);
+ g_clear_handle_id (&self->queue_handler, g_source_remove);
ide_extension_adapter_monitor (self, NULL);
@@ -418,12 +418,15 @@ static void
ide_extension_adapter_class_init (IdeExtensionAdapterClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ IdeObjectClass *i_object_class = IDE_OBJECT_CLASS (klass);
object_class->dispose = ide_extension_adapter_dispose;
object_class->finalize = ide_extension_adapter_finalize;
object_class->get_property = ide_extension_adapter_get_property;
object_class->set_property = ide_extension_adapter_set_property;
+ i_object_class->repr = ide_extension_adapter_repr;
+
properties [PROP_ENGINE] =
g_param_spec_object ("engine",
"Engine",
@@ -491,7 +494,7 @@ ide_extension_adapter_set_key (IdeExtensionAdapter *self,
g_return_if_fail (IDE_IS_MAIN_THREAD ());
g_return_if_fail (IDE_IS_EXTENSION_ADAPTER (self));
- if (!dzl_str_equal0 (self->key, key))
+ if (!ide_str_equal0 (self->key, key))
{
g_free (self->key);
self->key = g_strdup (key);
@@ -516,7 +519,7 @@ ide_extension_adapter_set_value (IdeExtensionAdapter *self,
g_return_if_fail (IDE_IS_MAIN_THREAD ());
g_return_if_fail (IDE_IS_EXTENSION_ADAPTER (self));
- if (!dzl_str_equal0 (self->value, value))
+ if (!ide_str_equal0 (self->value, value))
{
g_free (self->value);
self->value = g_strdup (value);
@@ -573,46 +576,54 @@ ide_extension_adapter_get_extension (IdeExtensionAdapter *self)
/**
* ide_extension_adapter_new:
- * @context: An #IdeContext.
- * @engine: (allow-none): a #PeasEngine or %NULL.
+ * @parent: (nullable): An #IdeObject or %NULL
+ * @engine: (allow-none): a #PeasEngine or %NULL
* @interface_type: The #GType of the interface to be implemented.
* @key: The key for matching extensions from plugin info external data.
* @value: (allow-none): The value to use when matching keys.
*
* Creates a new #IdeExtensionAdapter.
*
- * The #IdeExtensionAdapter object can be used to wrap an extension that might need to change
- * at runtime based on various changing parameters. For example, it can watch the loading and
- * unloading of plugins and reload the #IdeExtensionAdapter:extension property.
+ * The #IdeExtensionAdapter object can be used to wrap an extension that might
+ * need to change at runtime based on various changing parameters. For example,
+ * it can watch the loading and unloading of plugins and reload the
+ * #IdeExtensionAdapter:extension property.
*
* Additionally, it can match a specific plugin based on the @value provided.
*
- * This uses #IdeExtensionPoint to create the extension implementation, which means that
- * extension points that are disabled (such as from the plugins GSettings) will be ignored.
- * As such, if one plugin that is higher priority than another, but is disabled, will be
- * ignored and the secondary plugin will be used.
+ * This uses #IdeExtensionPoint to create the extension implementation, which
+ * means that extension points that are disabled (such as from the plugins
+ * GSettings) will be ignored. As such, if one plugin that is higher priority
+ * than another, but is disabled, will be ignored and the secondary plugin will
+ * be used.
*
* Returns: (transfer full): A newly created #IdeExtensionAdapter.
*
* Since: 3.32
*/
IdeExtensionAdapter *
-ide_extension_adapter_new (IdeContext *context,
+ide_extension_adapter_new (IdeObject *parent,
PeasEngine *engine,
GType interface_type,
const gchar *key,
const gchar *value)
{
+ IdeExtensionAdapter *self;
+
g_return_val_if_fail (IDE_IS_MAIN_THREAD (), NULL);
g_return_val_if_fail (!engine || PEAS_IS_ENGINE (engine), NULL);
g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), NULL);
g_return_val_if_fail (key != NULL, NULL);
- return g_object_new (IDE_TYPE_EXTENSION_ADAPTER,
- "context", context,
+ self = g_object_new (IDE_TYPE_EXTENSION_ADAPTER,
"engine", engine,
"interface-type", interface_type,
"key", key,
"value", value,
NULL);
+
+ if (parent != NULL)
+ ide_object_append (parent, IDE_OBJECT (self));
+
+ return g_steal_pointer (&self);
}
diff --git a/src/libide/plugins/ide-extension-adapter.h b/src/libide/plugins/ide-extension-adapter.h
index 0a0aaea94..e8499ec69 100644
--- a/src/libide/plugins/ide-extension-adapter.h
+++ b/src/libide/plugins/ide-extension-adapter.h
@@ -20,10 +20,12 @@
#pragma once
-#include <libpeas/peas.h>
+#if !defined (IDE_PLUGINS_INSIDE) && !defined (IDE_PLUGINS_COMPILATION)
+# error "Only <libide-plugins.h> can be included directly."
+#endif
-#include "ide-object.h"
-#include "ide-version-macros.h"
+#include <libpeas/peas.h>
+#include <libide-core.h>
G_BEGIN_DECLS
@@ -33,7 +35,7 @@ IDE_AVAILABLE_IN_3_32
G_DECLARE_FINAL_TYPE (IdeExtensionAdapter, ide_extension_adapter, IDE, EXTENSION_ADAPTER, IdeObject)
IDE_AVAILABLE_IN_3_32
-IdeExtensionAdapter *ide_extension_adapter_new (IdeContext *context,
+IdeExtensionAdapter *ide_extension_adapter_new (IdeObject *parent,
PeasEngine *engine,
GType interface_type,
const gchar *key,
diff --git a/src/libide/plugins/ide-extension-set-adapter.c b/src/libide/plugins/ide-extension-set-adapter.c
index 966c26f4a..d4586b1f6 100644
--- a/src/libide/plugins/ide-extension-set-adapter.c
+++ b/src/libide/plugins/ide-extension-set-adapter.c
@@ -26,12 +26,8 @@
#include <glib/gi18n.h>
#include <stdlib.h>
-#include "ide-context.h"
-#include "ide-debug.h"
-
-#include "application/ide-application.h"
-#include "plugins/ide-extension-set-adapter.h"
-#include "plugins/ide-extension-util.h"
+#include "ide-extension-set-adapter.h"
+#include "ide-extension-util-private.h"
struct _IdeExtensionSetAdapter
{
@@ -71,6 +67,20 @@ static guint signals [LAST_SIGNAL];
static void ide_extension_set_adapter_queue_reload (IdeExtensionSetAdapter *);
+static gchar *
+ide_extension_set_adapter_repr (IdeObject *object)
+{
+ IdeExtensionSetAdapter *self = (IdeExtensionSetAdapter *)object;
+
+ g_assert (IDE_IS_EXTENSION_SET_ADAPTER (self));
+
+ return g_strdup_printf ("%s interface=\"%s\" key=\"%s\" value=\"%s\"",
+ G_OBJECT_TYPE_NAME (self),
+ g_type_name (self->interface_type),
+ self->key ?: "",
+ self->value ?: "");
+}
+
static void
add_extension (IdeExtensionSetAdapter *self,
PeasPluginInfo *plugin_info,
@@ -83,6 +93,19 @@ add_extension (IdeExtensionSetAdapter *self,
g_assert (g_type_is_a (G_OBJECT_TYPE (exten), self->interface_type));
g_hash_table_insert (self->extensions, plugin_info, exten);
+
+ /* Ensure that we take the reference in case it's a floating ref */
+ if (G_IS_INITIALLY_UNOWNED (exten) && g_object_is_floating (exten))
+ g_object_ref_sink (exten);
+
+ /*
+ * If the plugin object turned out to have IdeObject as a
+ * base, make it a child of ourselves, because we're an
+ * IdeObject too and that gives it access to the context.
+ */
+ if (IDE_IS_OBJECT (exten))
+ ide_object_append (IDE_OBJECT (self), IDE_OBJECT (exten));
+
g_signal_emit (self, signals [EXTENSION_ADDED], 0, plugin_info, exten);
}
@@ -104,6 +127,9 @@ remove_extension (IdeExtensionSetAdapter *self,
g_hash_table_remove (self->extensions, plugin_info);
g_signal_emit (self, signals [EXTENSION_REMOVED], 0, plugin_info, hold);
+
+ if (IDE_IS_OBJECT (hold))
+ ide_object_destroy (IDE_OBJECT (hold));
}
static void
@@ -130,7 +156,7 @@ watch_extension (IdeExtensionSetAdapter *self,
g_assert (IDE_IS_MAIN_THREAD ());
g_assert (IDE_IS_EXTENSION_SET_ADAPTER (self));
g_assert (plugin_info != NULL);
- g_assert (G_TYPE_IS_INTERFACE (interface_type));
+ g_assert (G_TYPE_IS_INTERFACE (interface_type) || G_TYPE_IS_OBJECT (interface_type));
path = g_strdup_printf ("/org/gnome/builder/extension-types/%s/%s/",
peas_plugin_info_get_module_name (plugin_info),
@@ -152,7 +178,6 @@ watch_extension (IdeExtensionSetAdapter *self,
static void
ide_extension_set_adapter_reload (IdeExtensionSetAdapter *self)
{
- IdeContext *context;
const GList *plugins;
g_assert (IDE_IS_MAIN_THREAD ());
@@ -170,11 +195,8 @@ ide_extension_set_adapter_reload (IdeExtensionSetAdapter *self)
g_ptr_array_remove_index (self->settings, self->settings->len - 1);
}
- context = ide_object_get_context (IDE_OBJECT (self));
plugins = peas_engine_get_plugin_list (self->engine);
- g_assert (IDE_IS_CONTEXT (context));
-
for (; plugins; plugins = plugins->next)
{
PeasPluginInfo *plugin_info = plugins->data;
@@ -183,8 +205,10 @@ ide_extension_set_adapter_reload (IdeExtensionSetAdapter *self)
if (!peas_plugin_info_is_loaded (plugin_info))
continue;
- if (peas_engine_provides_extension (self->engine, plugin_info, self->interface_type))
- watch_extension (self, plugin_info, self->interface_type);
+ if (!peas_engine_provides_extension (self->engine, plugin_info, self->interface_type))
+ continue;
+
+ watch_extension (self, plugin_info, self->interface_type);
if (ide_extension_util_can_use_plugin (self->engine,
plugin_info,
@@ -197,26 +221,10 @@ ide_extension_set_adapter_reload (IdeExtensionSetAdapter *self)
{
PeasExtension *exten;
- if (g_type_is_a (self->interface_type, IDE_TYPE_OBJECT))
- exten = ide_extension_new (self->engine,
- plugin_info,
- self->interface_type,
- "context", context,
- NULL);
- else
- {
- exten = ide_extension_new (self->engine,
- plugin_info,
- self->interface_type,
- NULL);
- /*
- * If the plugin object turned out to have IdeObject
- * as a base, try to set it now (even though we couldn't
- * do it at construction time).
- */
- if (IDE_IS_OBJECT (exten))
- ide_object_set_context (IDE_OBJECT (exten), context);
- }
+ exten = ide_extension_new (self->engine,
+ plugin_info,
+ self->interface_type,
+ NULL);
add_extension (self, plugin_info, exten);
}
@@ -255,7 +263,7 @@ ide_extension_set_adapter_queue_reload (IdeExtensionSetAdapter *self)
g_assert (IDE_IS_MAIN_THREAD ());
g_assert (IDE_IS_EXTENSION_SET_ADAPTER (self));
- dzl_clear_source (&self->reload_handler);
+ g_clear_handle_id (&self->reload_handler, g_source_remove);
self->reload_handler = g_idle_add_full (G_PRIORITY_HIGH,
ide_extension_set_adapter_do_reload,
@@ -263,16 +271,57 @@ ide_extension_set_adapter_queue_reload (IdeExtensionSetAdapter *self)
NULL);
}
+static void
+ide_extension_set_adapter_load_plugin (IdeExtensionSetAdapter *self,
+ PeasPluginInfo *plugin_info,
+ PeasEngine *engine)
+{
+ g_assert (IDE_IS_EXTENSION_SET_ADAPTER (self));
+ g_assert (plugin_info != NULL);
+ g_assert (PEAS_IS_ENGINE (engine));
+
+ ide_extension_set_adapter_queue_reload (self);
+}
+
+static void
+ide_extension_set_adapter_unload_plugin (IdeExtensionSetAdapter *self,
+ PeasPluginInfo *plugin_info,
+ PeasEngine *engine)
+{
+ PeasExtension *exten;
+
+ g_assert (IDE_IS_EXTENSION_SET_ADAPTER (self));
+ g_assert (plugin_info != NULL);
+ g_assert (PEAS_IS_ENGINE (engine));
+
+ if ((exten = g_hash_table_lookup (self->extensions, plugin_info)))
+ {
+ remove_extension (self, plugin_info, exten);
+ g_hash_table_remove (self->extensions, plugin_info);
+ }
+}
+
static void
ide_extension_set_adapter_set_engine (IdeExtensionSetAdapter *self,
PeasEngine *engine)
{
g_assert (IDE_IS_MAIN_THREAD ());
g_assert (IDE_IS_EXTENSION_SET_ADAPTER (self));
- g_assert (PEAS_IS_ENGINE (engine));
+ g_assert (!engine || PEAS_IS_ENGINE (engine));
+
+ if (engine == NULL)
+ engine = peas_engine_get_default ();
if (g_set_object (&self->engine, engine))
{
+ g_signal_connect_object (self->engine, "load-plugin",
+ G_CALLBACK (ide_extension_set_adapter_load_plugin),
+ self,
+ G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+ g_signal_connect_object (self->engine, "unload-plugin",
+ G_CALLBACK (ide_extension_set_adapter_unload_plugin),
+ self,
+ G_CONNECT_SWAPPED);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ENGINE]);
ide_extension_set_adapter_queue_reload (self);
}
@@ -284,7 +333,7 @@ ide_extension_set_adapter_set_interface_type (IdeExtensionSetAdapter *self,
{
g_assert (IDE_IS_MAIN_THREAD ());
g_assert (IDE_IS_EXTENSION_SET_ADAPTER (self));
- g_assert (G_TYPE_IS_INTERFACE (interface_type));
+ g_assert (G_TYPE_IS_INTERFACE (interface_type) || G_TYPE_IS_OBJECT (interface_type));
if (interface_type != self->interface_type)
{
@@ -295,7 +344,7 @@ ide_extension_set_adapter_set_interface_type (IdeExtensionSetAdapter *self,
}
static void
-ide_extension_set_adapter_dispose (GObject *object)
+ide_extension_set_adapter_destroy (IdeObject *object)
{
IdeExtensionSetAdapter *self = (IdeExtensionSetAdapter *)object;
g_autoptr(GHashTable) extensions = NULL;
@@ -307,7 +356,7 @@ ide_extension_set_adapter_dispose (GObject *object)
g_assert (IDE_IS_EXTENSION_SET_ADAPTER (self));
self->interface_type = G_TYPE_INVALID;
- dzl_clear_source (&self->reload_handler);
+ g_clear_handle_id (&self->reload_handler, g_source_remove);
/*
* Steal the extensions so we can be re-entrant safe and not break
@@ -327,7 +376,7 @@ ide_extension_set_adapter_dispose (GObject *object)
g_hash_table_iter_remove (&iter);
}
- G_OBJECT_CLASS (ide_extension_set_adapter_parent_class)->dispose (object);
+ IDE_OBJECT_CLASS (ide_extension_set_adapter_parent_class)->destroy (object);
}
static void
@@ -421,12 +470,15 @@ static void
ide_extension_set_adapter_class_init (IdeExtensionSetAdapterClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ IdeObjectClass *i_object_class = IDE_OBJECT_CLASS (klass);
- object_class->dispose = ide_extension_set_adapter_dispose;
object_class->finalize = ide_extension_set_adapter_finalize;
object_class->get_property = ide_extension_set_adapter_get_property;
object_class->set_property = ide_extension_set_adapter_set_property;
+ i_object_class->destroy = ide_extension_set_adapter_destroy;
+ i_object_class->repr = ide_extension_set_adapter_repr;
+
properties [PROP_ENGINE] =
g_param_spec_object ("engine",
"Engine",
@@ -438,7 +490,7 @@ ide_extension_set_adapter_class_init (IdeExtensionSetAdapterClass *klass)
g_param_spec_gtype ("interface-type",
"Interface Type",
"Interface Type",
- G_TYPE_INTERFACE,
+ G_TYPE_OBJECT,
(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
properties [PROP_KEY] =
@@ -535,7 +587,7 @@ ide_extension_set_adapter_set_key (IdeExtensionSetAdapter *self,
g_return_if_fail (IDE_IS_MAIN_THREAD ());
g_return_if_fail (IDE_IS_EXTENSION_SET_ADAPTER (self));
- if (!dzl_str_equal0 (self->key, key))
+ if (!ide_str_equal0 (self->key, key))
{
g_free (self->key);
self->key = g_strdup (key);
@@ -564,7 +616,7 @@ ide_extension_set_adapter_set_value (IdeExtensionSetAdapter *self,
g_type_name (self->interface_type),
value ?: "");
- if (!dzl_str_equal0 (self->value, value))
+ if (!ide_str_equal0 (self->value, value))
{
g_free (self->value);
self->value = g_strdup (value);
@@ -588,22 +640,25 @@ ide_extension_set_adapter_foreach (IdeExtensionSetAdapter *self,
IdeExtensionSetAdapterForeachFunc foreach_func,
gpointer user_data)
{
- GHashTableIter iter;
- gpointer key;
- gpointer value;
+ const GList *list;
- g_return_if_fail (IDE_IS_MAIN_THREAD ());
g_return_if_fail (IDE_IS_EXTENSION_SET_ADAPTER (self));
g_return_if_fail (foreach_func != NULL);
- g_hash_table_iter_init (&iter, self->extensions);
+ /*
+ * Use the ordered list of plugins as it is sorted including any
+ * dependencies of plugins.
+ */
- while (g_hash_table_iter_next (&iter, &key, &value))
+ list = peas_engine_get_plugin_list (self->engine);
+
+ for (const GList *iter = list; iter; iter = iter->next)
{
- PeasPluginInfo *plugin_info = key;
- PeasExtension *exten = value;
+ PeasPluginInfo *plugin_info = iter->data;
+ PeasExtension *exten = g_hash_table_lookup (self->extensions, plugin_info);
- foreach_func (self, plugin_info, exten, user_data);
+ if (exten != NULL)
+ foreach_func (self, plugin_info, exten, user_data);
}
}
@@ -651,6 +706,12 @@ ide_extension_set_adapter_foreach_by_priority (IdeExtensionSetAdapter
g_return_if_fail (IDE_IS_EXTENSION_SET_ADAPTER (self));
g_return_if_fail (foreach_func != NULL);
+ if (self->key == NULL)
+ {
+ ide_extension_set_adapter_foreach (self, foreach_func, user_data);
+ return;
+ }
+
prio_key = g_strdup_printf ("%s-Priority", self->key);
sorted = g_array_new (FALSE, FALSE, sizeof (SortedInfo));
@@ -689,25 +750,40 @@ ide_extension_set_adapter_get_n_extensions (IdeExtensionSetAdapter *self)
}
IdeExtensionSetAdapter *
-ide_extension_set_adapter_new (IdeContext *context,
+ide_extension_set_adapter_new (IdeObject *parent,
PeasEngine *engine,
GType interface_type,
const gchar *key,
const gchar *value)
{
+ IdeExtensionSetAdapter *ret;
+
g_return_val_if_fail (IDE_IS_MAIN_THREAD (), NULL);
- g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL);
+ g_return_val_if_fail (!parent || IDE_IS_OBJECT (parent), NULL);
g_return_val_if_fail (!engine || PEAS_IS_ENGINE (engine), NULL);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), NULL);
- g_return_val_if_fail (key != NULL, NULL);
-
- return g_object_new (IDE_TYPE_EXTENSION_SET_ADAPTER,
- "context", context,
- "engine", engine,
- "interface-type", interface_type,
- "key", key,
- "value", value,
- NULL);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type) ||
+ G_TYPE_IS_OBJECT (interface_type), NULL);
+
+ ret = g_object_new (IDE_TYPE_EXTENSION_SET_ADAPTER,
+ "engine", engine,
+ "interface-type", interface_type,
+ "key", key,
+ "value", value,
+ NULL);
+
+ if (parent != NULL)
+ ide_object_append (parent, IDE_OBJECT (ret));
+
+ /* If we have a reload queued, just process it immediately so that
+ * there is some determinism in plugin loading.
+ */
+ if (ret->reload_handler != 0)
+ {
+ g_clear_handle_id (&ret->reload_handler, g_source_remove);
+ ide_extension_set_adapter_do_reload (ret);
+ }
+
+ return ret;
}
/**
diff --git a/src/libide/plugins/ide-extension-set-adapter.h b/src/libide/plugins/ide-extension-set-adapter.h
index e61228450..24708e56f 100644
--- a/src/libide/plugins/ide-extension-set-adapter.h
+++ b/src/libide/plugins/ide-extension-set-adapter.h
@@ -20,10 +20,12 @@
#pragma once
-#include <libpeas/peas.h>
+#if !defined (IDE_PLUGINS_INSIDE) && !defined (IDE_PLUGINS_COMPILATION)
+# error "Only <libide-plugins.h> can be included directly."
+#endif
-#include "ide-object.h"
-#include "ide-version-macros.h"
+#include <libpeas/peas.h>
+#include <libide-core.h>
G_BEGIN_DECLS
@@ -38,7 +40,7 @@ typedef void (*IdeExtensionSetAdapterForeachFunc) (IdeExtensionSetAdapter *set,
gpointer user_data);
IDE_AVAILABLE_IN_3_32
-IdeExtensionSetAdapter *ide_extension_set_adapter_new (IdeContext
*context,
+IdeExtensionSetAdapter *ide_extension_set_adapter_new (IdeObject
*parent,
PeasEngine
*engine,
GType
interface_type,
const gchar *key,
diff --git a/src/libide/plugins/ide-extension-util.h b/src/libide/plugins/ide-extension-util-private.h
similarity index 100%
rename from src/libide/plugins/ide-extension-util.h
rename to src/libide/plugins/ide-extension-util-private.h
diff --git a/src/libide/plugins/ide-extension-util.c b/src/libide/plugins/ide-extension-util.c
index ffc12848d..bcd32b1cc 100644
--- a/src/libide/plugins/ide-extension-util.c
+++ b/src/libide/plugins/ide-extension-util.c
@@ -22,10 +22,11 @@
#include "config.h"
+#include <libide-core.h>
#include <gobject/gvaluecollector.h>
#include <stdlib.h>
-#include "plugins/ide-extension-util.h"
+#include "ide-extension-util-private.h"
gboolean
ide_extension_util_can_use_plugin (PeasEngine *engine,
@@ -39,7 +40,8 @@ ide_extension_util_can_use_plugin (PeasEngine *engine,
g_autoptr(GSettings) settings = NULL;
g_return_val_if_fail (plugin_info != NULL, FALSE);
- g_return_val_if_fail (g_type_is_a (interface_type, G_TYPE_INTERFACE), FALSE);
+ g_return_val_if_fail (g_type_is_a (interface_type, G_TYPE_INTERFACE) ||
+ g_type_is_a (interface_type, G_TYPE_OBJECT), FALSE);
g_return_val_if_fail (priority != NULL, FALSE);
*priority = 0;
@@ -49,7 +51,18 @@ ide_extension_util_can_use_plugin (PeasEngine *engine,
* information to do so.
*/
if ((key != NULL) && (value == NULL))
- return FALSE;
+ {
+ const gchar *found;
+
+ /* If the plugin has the key and its empty, or doesn't have the key,
+ * then we can assume it wants the equivalent of "*".
+ */
+ found = peas_plugin_info_get_external_data (plugin_info, key);
+ if (ide_str_empty0 (found))
+ return TRUE;
+
+ return FALSE;
+ }
/*
* If the plugin isn't loaded, then we shouldn't use it.
@@ -70,12 +83,15 @@ ide_extension_util_can_use_plugin (PeasEngine *engine,
if (key != NULL)
{
g_autofree gchar *priority_name = NULL;
+ g_autofree gchar *delimit = NULL;
g_auto(GStrv) values_array = NULL;
const gchar *values;
const gchar *priority_value;
values = peas_plugin_info_get_external_data (plugin_info, key);
- values_array = g_strsplit (values ? values : "", ",", 0);
+ /* Canonicalize input (for both , and ;) */
+ delimit = g_strdelimit (g_strdup (values ? values : ""), ";,", ';');
+ values_array = g_strsplit (delimit, ";", 0);
/* An empty value implies "*" to match anything */
if (!values || g_strv_contains ((const gchar * const *)values_array, "*"))
@@ -256,7 +272,7 @@ ide_extension_new (PeasEngine *engine,
va_list args;
g_return_val_if_fail (!engine || PEAS_IS_ENGINE (engine), NULL);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (type), NULL);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (type) || G_TYPE_IS_OBJECT (type), NULL);
if (engine == NULL)
engine = peas_engine_get_default ();
diff --git a/src/libide/plugins/libide-plugins.h b/src/libide/plugins/libide-plugins.h
new file mode 100644
index 000000000..1260890cd
--- /dev/null
+++ b/src/libide/plugins/libide-plugins.h
@@ -0,0 +1,34 @@
+/* libide-plugins.h
+ *
+ * Copyright 2018-2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libide-core.h>
+
+G_BEGIN_DECLS
+
+#define IDE_PLUGINS_INSIDE
+
+#include "ide-extension-adapter.h"
+#include "ide-extension-set-adapter.h"
+
+#undef IDE_PLUGINS_INSIDE
+
+G_END_DECLS
diff --git a/src/libide/plugins/meson.build b/src/libide/plugins/meson.build
index 07466addd..a33c528c9 100644
--- a/src/libide/plugins/meson.build
+++ b/src/libide/plugins/meson.build
@@ -1,20 +1,61 @@
-plugins_headers = [
+libide_plugins_header_subdir = join_paths(libide_header_subdir, 'plugins')
+libide_include_directories += include_directories('.')
+
+#
+# Public API Headers
+#
+
+libide_plugins_public_headers = [
'ide-extension-adapter.h',
'ide-extension-set-adapter.h',
+ 'libide-plugins.h',
+]
+
+libide_plugins_private_headers = [
+ 'ide-extension-util-private.h',
]
-plugins_sources = [
+install_headers(libide_plugins_public_headers, subdir: libide_plugins_header_subdir)
+
+#
+# Sources
+#
+
+libide_plugins_public_sources = [
'ide-extension-adapter.c',
'ide-extension-set-adapter.c',
]
-plugins_private_sources = [
+libide_plugins_private_sources = [
'ide-extension-util.c',
- 'ide-extension-util.h',
]
-libide_public_headers += files(plugins_headers)
-libide_public_sources += files(plugins_sources)
-libide_private_sources += files(plugins_private_sources)
+#
+# Library Definitions
+#
+
+libide_plugins_deps = [
+ libgio_dep,
+ libpeas_dep,
+ libdazzle_dep,
+
+ libide_core_dep,
+]
+
+libide_plugins = static_library('ide-plugins-' + libide_api_version,
+ libide_plugins_public_sources, libide_plugins_private_sources,
+ dependencies: libide_plugins_deps,
+ c_args: libide_args + release_args + ['-DIDE_PLUGINS_COMPILATION'],
+)
+
+libide_plugins_dep = declare_dependency(
+ sources: libide_plugins_private_headers,
+ dependencies: libide_plugins_deps,
+ link_whole: libide_plugins,
+ include_directories: include_directories('.'),
+)
-install_headers(plugins_headers, subdir: join_paths(libide_header_subdir, 'plugins'))
+gnome_builder_public_sources += files(libide_plugins_public_sources)
+gnome_builder_public_headers += files(libide_plugins_public_headers)
+gnome_builder_include_subdirs += libide_plugins_header_subdir
+gnome_builder_gir_extra_args += ['--c-include=libide-plugins.h', '-DIDE_PLUGINS_COMPILATION']
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]