summaryrefslogtreecommitdiff
path: root/libpeas
diff options
context:
space:
mode:
authorGarrett Regier <garrettregier@gmail.com>2017-03-24 12:41:09 -0700
committerGarrett Regier <garrettregier@gmail.com>2017-03-24 21:27:15 -0700
commit7e7e850d24a930ffdaf04d0feaf6607fe797f30e (patch)
treedbde908fd4a0969afe0ee49fd668a1f74f540009 /libpeas
parent743ca63655ac23c24efed5aad33479fa1f4faadf (diff)
downloadlibpeas-7e7e850d24a930ffdaf04d0feaf6607fe797f30e.tar.gz
Allow extensions to be an Abstract Base Class
https://bugzilla.gnome.org/show_bug.cgi?id=767223
Diffstat (limited to 'libpeas')
-rw-r--r--libpeas/peas-engine.c33
-rw-r--r--libpeas/peas-extension-set.c18
-rw-r--r--libpeas/peas-extension.c32
-rw-r--r--libpeas/peas-introspection.c29
-rw-r--r--libpeas/peas-introspection.h4
-rw-r--r--libpeas/peas-object-module.c116
-rw-r--r--libpeas/peas-object-module.h10
-rw-r--r--libpeas/peas-utils.c40
-rw-r--r--libpeas/peas-utils.h2
9 files changed, 176 insertions, 108 deletions
diff --git a/libpeas/peas-engine.c b/libpeas/peas-engine.c
index 3b35145..5713cb0 100644
--- a/libpeas/peas-engine.c
+++ b/libpeas/peas-engine.c
@@ -57,6 +57,9 @@
* plugins and their extensions from within your application.</para>
* </listitem>
* </itemizedlist>
+ *
+ * Since libpeas 1.22, @extension_type can be an Abstract #GType
+ * and not just an Interface #GType.
**/
/* Signals */
@@ -1274,6 +1277,9 @@ peas_engine_unload_plugin (PeasEngine *engine,
* Returns if @info provides an extension for @extension_type.
* If the @info is not loaded than %FALSE will always be returned.
*
+ * Since libpeas 1.22, @extension_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* Returns: if @info provides an extension for @extension_type.
*/
gboolean
@@ -1285,7 +1291,8 @@ peas_engine_provides_extension (PeasEngine *engine,
g_return_val_if_fail (PEAS_IS_ENGINE (engine), FALSE);
g_return_val_if_fail (info != NULL, FALSE);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type), FALSE);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type) ||
+ G_TYPE_IS_ABSTRACT (extension_type), FALSE);
if (!peas_plugin_info_is_loaded (info))
return FALSE;
@@ -1303,10 +1310,13 @@ peas_engine_provides_extension (PeasEngine *engine,
* @parameters: (allow-none) (array length=n_parameters):
* an array of #GParameter.
*
- * If the plugin identified by @info implements the @extension_type interface,
+ * If the plugin identified by @info implements the @extension_type,
* then this function will return a new instance of this implementation,
* wrapped in a new #PeasExtension instance. Otherwise, it will return %NULL.
*
+ * Since libpeas 1.22, @extension_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* See peas_engine_create_extension() for more information.
*
* Returns: (transfer full): a new instance of #PeasExtension wrapping
@@ -1324,8 +1334,9 @@ peas_engine_create_extensionv (PeasEngine *engine,
g_return_val_if_fail (PEAS_IS_ENGINE (engine), NULL);
g_return_val_if_fail (info != NULL, NULL);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type) ||
+ G_TYPE_IS_ABSTRACT (extension_type), NULL);
g_return_val_if_fail (peas_plugin_info_is_loaded (info), NULL);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type), FALSE);
loader = get_plugin_loader (engine, info->loader_id);
extension = peas_plugin_loader_create_extension (loader, info, extension_type,
@@ -1351,10 +1362,13 @@ peas_engine_create_extensionv (PeasEngine *engine,
* @var_args: the value of the first property, followed optionally by more
* name/value pairs, followed by %NULL.
*
- * If the plugin identified by @info implements the @extension_type interface,
+ * If the plugin identified by @info implements the @extension_type,
* then this function will return a new instance of this implementation,
* wrapped in a new #PeasExtension instance. Otherwise, it will return %NULL.
*
+ * Since libpeas 1.22, @extension_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* See peas_engine_create_extension() for more information.
*
* Returns: a new instance of #PeasExtension wrapping
@@ -1374,7 +1388,8 @@ peas_engine_create_extension_valist (PeasEngine *engine,
g_return_val_if_fail (PEAS_IS_ENGINE (engine), NULL);
g_return_val_if_fail (info != NULL, NULL);
g_return_val_if_fail (peas_plugin_info_is_loaded (info), NULL);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type), FALSE);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type) ||
+ G_TYPE_IS_ABSTRACT (extension_type), FALSE);
if (!peas_utils_valist_to_parameter_list (extension_type, first_property,
var_args, &parameters,
@@ -1403,7 +1418,7 @@ peas_engine_create_extension_valist (PeasEngine *engine,
* @...: the value of the first property, followed optionally by more
* name/value pairs, followed by %NULL.
*
- * If the plugin identified by @info implements the @extension_type interface,
+ * If the plugin identified by @info implements the @extension_type,
* then this function will return a new instance of this implementation,
* wrapped in a new #PeasExtension instance. Otherwise, it will return %NULL.
*
@@ -1416,6 +1431,9 @@ peas_engine_create_extension_valist (PeasEngine *engine,
* principle of never giving you the actual object (also because it might as
* well *not* be an actual object).
*
+ * Since libpeas 1.22, @extension_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* Returns: a new instance of #PeasExtension wrapping
* the @extension_type instance, or %NULL.
*/
@@ -1432,7 +1450,8 @@ peas_engine_create_extension (PeasEngine *engine,
g_return_val_if_fail (PEAS_IS_ENGINE (engine), NULL);
g_return_val_if_fail (info != NULL, NULL);
g_return_val_if_fail (peas_plugin_info_is_loaded (info), NULL);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type), FALSE);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type) ||
+ G_TYPE_IS_ABSTRACT (extension_type), FALSE);
va_start (var_args, first_property);
exten = peas_engine_create_extension_valist (engine, info, extension_type,
diff --git a/libpeas/peas-extension-set.c b/libpeas/peas-extension-set.c
index cb3f9cc..a4e0f3f 100644
--- a/libpeas/peas-extension-set.c
+++ b/libpeas/peas-extension-set.c
@@ -615,6 +615,9 @@ peas_extension_set_foreach (PeasExtensionSet *set,
*
* If @engine is %NULL, then the default engine will be used.
*
+ * Since libpeas 1.22, @exten_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* See peas_extension_set_new() for more information.
*
* Returns: (transfer full): a new instance of #PeasExtensionSet.
@@ -628,7 +631,8 @@ peas_extension_set_newv (PeasEngine *engine,
PeasParameterArray construct_properties = { n_parameters, parameters };
g_return_val_if_fail (engine == NULL || PEAS_IS_ENGINE (engine), NULL);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type), NULL);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_ABSTRACT (exten_type), NULL);
return PEAS_EXTENSION_SET (g_object_new (PEAS_TYPE_EXTENSION_SET,
"engine", engine,
@@ -649,6 +653,9 @@ peas_extension_set_newv (PeasEngine *engine,
*
* If @engine is %NULL, then the default engine will be used.
*
+ * Since libpeas 1.22, @exten_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* See peas_extension_set_new() for more information.
*
* Returns: a new instance of #PeasExtensionSet.
@@ -664,7 +671,8 @@ peas_extension_set_new_valist (PeasEngine *engine,
PeasExtensionSet *set;
g_return_val_if_fail (engine == NULL || PEAS_IS_ENGINE (engine), NULL);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type), NULL);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_ABSTRACT (exten_type), NULL);
if (!peas_utils_valist_to_parameter_list (exten_type, first_property,
var_args, &parameters,
@@ -702,6 +710,9 @@ peas_extension_set_new_valist (PeasEngine *engine,
*
* If @engine is %NULL, then the default engine will be used.
*
+ * Since libpeas 1.22, @exten_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* See peas_engine_create_extension() for more information.
*
* Returns: a new instance of #PeasExtensionSet.
@@ -716,7 +727,8 @@ peas_extension_set_new (PeasEngine *engine,
PeasExtensionSet *set;
g_return_val_if_fail (engine == NULL || PEAS_IS_ENGINE (engine), NULL);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type), NULL);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_ABSTRACT (exten_type), NULL);
va_start (var_args, first_property);
set = peas_extension_set_new_valist (engine, exten_type, first_property, var_args);
diff --git a/libpeas/peas-extension.c b/libpeas/peas-extension.c
index 773d9f2..8e46920 100644
--- a/libpeas/peas-extension.c
+++ b/libpeas/peas-extension.c
@@ -37,8 +37,8 @@
* loaded plugins.
*
* To properly use the proxy instances, you will need GObject-introspection
- * data for the #GInterface or #GObjectClass you want to use as an extension
- * point. For instance, if you wish to use #PeasActivatable, you will need to
+ * data for the #GType you want to use as an extension point.
+ * For instance, if you wish to use #PeasActivatable, you will need to
* put the following code excerpt in the engine initialization code, in order
* to load the required "Peas" typelib:
*
@@ -47,7 +47,7 @@
* "Peas", "1.0", 0, NULL);
* ]|
*
- * You should proceed the same way for any namespace which provides interfaces
+ * You should proceed the same way for any namespace which provides types
* you want to use as extension points. GObject-introspection data is required
* for all the supported languages, even for C.
*
@@ -72,7 +72,7 @@ G_DEFINE_QUARK (peas-extension-type, extension_type)
static GICallableInfo *
get_method_info (PeasExtension *exten,
const gchar *method_name,
- GType *interface)
+ GType *gtype)
{
guint i;
GType exten_type;
@@ -85,8 +85,8 @@ get_method_info (PeasExtension *exten,
if (method_info != NULL)
{
- if (interface != NULL)
- *interface = exten_type;
+ if (gtype != NULL)
+ *gtype = exten_type;
return method_info;
}
@@ -99,15 +99,15 @@ get_method_info (PeasExtension *exten,
if (method_info != NULL)
{
- if (interface != NULL)
- *interface = interfaces[i];
+ if (gtype != NULL)
+ *gtype = interfaces[i];
break;
}
}
if (method_info == NULL)
- g_warning ("Could not find the interface for method '%s'", method_name);
+ g_warning ("Could not find the GType for method '%s'", method_name);
g_free (interfaces);
return method_info;
@@ -117,7 +117,7 @@ get_method_info (PeasExtension *exten,
* peas_extension_get_extension_type:
* @exten: A #PeasExtension.
*
- * Get the type of the extension interface of the object proxied by @exten.
+ * Get the #GType of the extension proxied by @exten.
*
* Return value: The #GType proxied by @exten.
*
@@ -154,7 +154,7 @@ peas_extension_get_extension_type (PeasExtension *exten)
*
* Return value: %TRUE on successful call.
*
- * Deprecated: 1.2: Use the interface directly instead.
+ * Deprecated: 1.2: Use the object directly instead.
*/
gboolean
peas_extension_call (PeasExtension *exten,
@@ -186,7 +186,7 @@ peas_extension_call (PeasExtension *exten,
*
* Return value: %TRUE on successful call.
*
- * Deprecated: 1.2: Use the interface directly instead.
+ * Deprecated: 1.2: Use the object directly instead.
*/
gboolean
peas_extension_call_valist (PeasExtension *exten,
@@ -241,7 +241,7 @@ peas_extension_call_valist (PeasExtension *exten,
*
* Return value: %TRUE on successful call.
*
- * Deprecated: 1.2: Use the interface directly instead.
+ * Deprecated: 1.2: Use the object directly instead.
*/
gboolean
peas_extension_callv (PeasExtension *exten,
@@ -250,19 +250,19 @@ peas_extension_callv (PeasExtension *exten,
GIArgument *return_value)
{
GICallableInfo *method_info;
- GType interface;
+ GType gtype;
gboolean success;
g_return_val_if_fail (PEAS_IS_EXTENSION (exten), FALSE);
g_return_val_if_fail (method_name != NULL, FALSE);
- method_info = get_method_info (exten, method_name, &interface);
+ method_info = get_method_info (exten, method_name, &gtype);
/* Already warned */
if (method_info == NULL)
return FALSE;
- success = peas_gi_method_call (G_OBJECT (exten), method_info, interface,
+ success = peas_gi_method_call (G_OBJECT (exten), method_info, gtype,
method_name, args, return_value);
g_base_info_unref (method_info);
diff --git a/libpeas/peas-introspection.c b/libpeas/peas-introspection.c
index 89aa41e..49ac178 100644
--- a/libpeas/peas-introspection.c
+++ b/libpeas/peas-introspection.c
@@ -239,44 +239,44 @@ peas_gi_argument_to_pointer (GITypeInfo *type_info,
}
GICallableInfo *
-peas_gi_get_method_info (GType iface_type,
+peas_gi_get_method_info (GType gtype,
const gchar *method_name)
{
GIRepository *repo;
- GIBaseInfo *iface_info;
+ GIBaseInfo *type_info;
GIFunctionInfo *func_info;
repo = g_irepository_get_default ();
- iface_info = g_irepository_find_by_gtype (repo, iface_type);
- if (iface_info == NULL)
+ type_info = g_irepository_find_by_gtype (repo, gtype);
+ if (type_info == NULL)
{
g_warning ("Type not found in introspection: '%s'",
- g_type_name (iface_type));
+ g_type_name (gtype));
return NULL;
}
- switch (g_base_info_get_type (iface_info))
+ switch (g_base_info_get_type (type_info))
{
case GI_INFO_TYPE_OBJECT:
- func_info = g_object_info_find_method ((GIObjectInfo *) iface_info,
+ func_info = g_object_info_find_method ((GIObjectInfo *) type_info,
method_name);
break;
case GI_INFO_TYPE_INTERFACE:
- func_info = g_interface_info_find_method ((GIInterfaceInfo *) iface_info,
+ func_info = g_interface_info_find_method ((GIInterfaceInfo *) type_info,
method_name);
break;
default:
func_info = NULL;
}
- g_base_info_unref (iface_info);
+ g_base_info_unref (type_info);
return (GICallableInfo *) func_info;
}
gboolean
peas_gi_method_call (GObject *instance,
GICallableInfo *func_info,
- GType iface_type,
+ GType gtype,
const gchar *method_name,
GIArgument *args,
GIArgument *return_value)
@@ -289,8 +289,9 @@ peas_gi_method_call (GObject *instance,
g_return_val_if_fail (G_IS_OBJECT (instance), FALSE);
g_return_val_if_fail (func_info != NULL, FALSE);
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_type), FALSE);
- g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (instance, iface_type),
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (gtype) ||
+ G_TYPE_IS_ABSTRACT (gtype), FALSE);
+ g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (instance, gtype),
FALSE);
g_return_val_if_fail (method_name != NULL, FALSE);
@@ -311,14 +312,14 @@ peas_gi_method_call (GObject *instance,
n_in_args++;
g_debug ("Calling '%s.%s' on '%p'",
- g_type_name (iface_type), method_name, instance);
+ g_type_name (gtype), method_name, instance);
ret = g_function_info_invoke (func_info, in_args, n_in_args, out_args,
n_out_args, return_value, &error);
if (!ret)
{
g_warning ("Error while calling '%s.%s': %s",
- g_type_name (iface_type), method_name, error->message);
+ g_type_name (gtype), method_name, error->message);
g_error_free (error);
}
diff --git a/libpeas/peas-introspection.h b/libpeas/peas-introspection.h
index 53af722..e5f3bbd 100644
--- a/libpeas/peas-introspection.h
+++ b/libpeas/peas-introspection.h
@@ -27,7 +27,7 @@
G_BEGIN_DECLS
-GICallableInfo *peas_gi_get_method_info (GType iface_type,
+GICallableInfo *peas_gi_get_method_info (GType gtype,
const gchar *method_name);
void peas_gi_valist_to_arguments (GICallableInfo *callable_info,
@@ -39,7 +39,7 @@ void peas_gi_argument_to_pointer (GITypeInfo *type_info,
gpointer ptr);
gboolean peas_gi_method_call (GObject *instance,
GICallableInfo *method_info,
- GType iface_type,
+ GType gtype,
const gchar *method_name,
GIArgument *args,
GIArgument *return_value);
diff --git a/libpeas/peas-object-module.c b/libpeas/peas-object-module.c
index fbd81f2..6711667 100644
--- a/libpeas/peas-object-module.c
+++ b/libpeas/peas-object-module.c
@@ -40,6 +40,9 @@
* of extensions. It will be used by C extensions implementors to register
* extension implementations from within the peas_register_types module
* function.
+ *
+ * Since libpeas 1.22, @extension_type can be an Abstract #GType
+ * and not just an Interface #GType.
**/
typedef void (*PeasObjectModuleRegisterFunc) (PeasObjectModule *module);
@@ -57,11 +60,11 @@ enum {
static GParamSpec *properties[N_PROPERTIES] = { NULL };
typedef struct {
- GType iface_type;
+ GType exten_type;
PeasFactoryFunc func;
gpointer user_data;
GDestroyNotify destroy_func;
-} InterfaceImplementation;
+} ExtensionImplementation;
struct _PeasObjectModulePrivate {
GModule *library;
@@ -171,7 +174,7 @@ peas_object_module_unload (GTypeModule *gmodule)
{
PeasObjectModule *module = PEAS_OBJECT_MODULE (gmodule);
PeasObjectModulePrivate *priv = GET_PRIV (module);
- InterfaceImplementation *impls;
+ ExtensionImplementation *impls;
guint i;
g_module_close (priv->library);
@@ -179,7 +182,7 @@ peas_object_module_unload (GTypeModule *gmodule)
priv->library = NULL;
priv->register_func = NULL;
- impls = (InterfaceImplementation *) priv->implementations->data;
+ impls = (ExtensionImplementation *) priv->implementations->data;
for (i = 0; i < priv->implementations->len; ++i)
{
if (impls[i].destroy_func != NULL)
@@ -196,7 +199,7 @@ peas_object_module_init (PeasObjectModule *module)
PeasObjectModulePrivate *priv = GET_PRIV (module);
priv->implementations = g_array_new (FALSE, FALSE,
- sizeof (InterfaceImplementation));
+ sizeof (ExtensionImplementation));
}
static void
@@ -433,36 +436,38 @@ peas_object_module_new_embedded (const gchar *module_name,
/**
* peas_object_module_create_object: (skip)
* @module: A #PeasObjectModule.
- * @interface: The #GType of the extension interface.
+ * @exten_type: The #GType of the extension.
* @n_parameters: The number of paramteters.
* @parameters: (array length=n_parameters): The parameters.
*
- * Creates an object for the @interface passing @n_parameters
+ * Creates an object for the @exten_type passing @n_parameters
* and @parameters to the #PeasFactoryFunc. If @module does
- * not provide a #PeasFactoryFunc for @interface then
+ * not provide a #PeasFactoryFunc for @exten_type then
* %NULL is returned.
*
+ * Since libpeas 1.22, @exten_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
* Return value: (transfer full): The created object, or %NULL.
*/
GObject *
peas_object_module_create_object (PeasObjectModule *module,
- GType interface,
+ GType exten_type,
guint n_parameters,
GParameter *parameters)
{
PeasObjectModulePrivate *priv = GET_PRIV (module);
guint i;
- InterfaceImplementation *impls;
+ ExtensionImplementation *impls;
g_return_val_if_fail (PEAS_IS_OBJECT_MODULE (module), NULL);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_ABSTRACT (exten_type), NULL);
- if (interface != PEAS_TYPE_PLUGIN_LOADER)
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface), NULL);
-
- impls = (InterfaceImplementation *) priv->implementations->data;
+ impls = (ExtensionImplementation *) priv->implementations->data;
for (i = 0; i < priv->implementations->len; ++i)
{
- if (impls[i].iface_type == interface)
+ if (impls[i].exten_type == exten_type)
return impls[i].func (n_parameters, parameters, impls[i].user_data);
}
@@ -472,29 +477,31 @@ peas_object_module_create_object (PeasObjectModule *module,
/**
* peas_object_module_provides_object: (skip)
* @module: A #PeasObjectModule.
- * @interface: The #GType of the extension interface.
+ * @exten_type: The #GType of the extension.
*
- * Determines if the module provides an extension for @interface.
+ * Determines if the module provides an extension for @exten_type.
*
- * Return value: if the module provides an extension for @interface.
+ * Since libpeas 1.22, @exten_type can be an Abstract #GType
+ * and not just an Interface #GType.
+ *
+ * Return value: if the module provides an extension for @exten_type.
*/
gboolean
peas_object_module_provides_object (PeasObjectModule *module,
- GType interface)
+ GType exten_type)
{
PeasObjectModulePrivate *priv = GET_PRIV (module);
guint i;
- InterfaceImplementation *impls;
+ ExtensionImplementation *impls;
g_return_val_if_fail (PEAS_IS_OBJECT_MODULE (module), FALSE);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_ABSTRACT (exten_type), FALSE);
- if (interface != PEAS_TYPE_PLUGIN_LOADER)
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface), FALSE);
-
- impls = (InterfaceImplementation *) priv->implementations->data;
+ impls = (ExtensionImplementation *) priv->implementations->data;
for (i = 0; i < priv->implementations->len; ++i)
{
- if (impls[i].iface_type == interface)
+ if (impls[i].exten_type == exten_type)
return TRUE;
}
@@ -578,8 +585,8 @@ peas_object_module_get_library (PeasObjectModule *module)
/**
* peas_object_module_register_extension_factory:
* @module: Your plugin's #PeasObjectModule.
- * @iface_type: The #GType of the extension interface you implement.
- * @factory_func: The #PeasFactoryFunc that will create the @iface_type
+ * @exten_type: The #GType of the extension you implement.
+ * @factory_func: The #PeasFactoryFunc that will create the @exten_type
* instance when requested.
* @user_data: Data to pass to @func calls.
* @destroy_func: A #GDestroyNotify for @user_data.
@@ -592,27 +599,29 @@ peas_object_module_get_library (PeasObjectModule *module)
* creating native types which cannot be instantiated correctly using
* g_object_new(). For other uses, you will usually prefer relying on
* peas_object_module_register_extension_type().
+ *
+ * Since libpeas 1.22, @exten_type can be an Abstract #GType
+ * and not just an Interface #GType.
*/
void
peas_object_module_register_extension_factory (PeasObjectModule *module,
- GType iface_type,
+ GType exten_type,
PeasFactoryFunc factory_func,
gpointer user_data,
GDestroyNotify destroy_func)
{
PeasObjectModulePrivate *priv = GET_PRIV (module);
- InterfaceImplementation impl = { iface_type, factory_func, user_data, destroy_func };
+ ExtensionImplementation impl = { exten_type, factory_func, user_data, destroy_func };
g_return_if_fail (PEAS_IS_OBJECT_MODULE (module));
- g_return_if_fail (!peas_object_module_provides_object (module, iface_type));
+ g_return_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_ABSTRACT (exten_type));
+ g_return_if_fail (!peas_object_module_provides_object (module, exten_type));
g_return_if_fail (factory_func != NULL);
- if (iface_type != PEAS_TYPE_PLUGIN_LOADER)
- g_return_if_fail (G_TYPE_IS_INTERFACE (iface_type));
-
g_array_append_val (priv->implementations, impl);
- g_debug ("Registered extension for type '%s'", g_type_name (iface_type));
+ g_debug ("Registered extension for type '%s'", g_type_name (exten_type));
}
static GObject *
@@ -620,15 +629,15 @@ create_gobject_from_type (guint n_parameters,
GParameter *parameters,
gpointer user_data)
{
- GType exten_type = GPOINTER_TO_SIZE (user_data);
+ GType impl_type = GPOINTER_TO_SIZE (user_data);
/* We should be called with a "plugin-info" property appended
* to the parameters. Let's get rid of it if the actual type
* doesn't have such a property as it would cause a warning.
*/
- if ((exten_type & TYPE_MISSING_PLUGIN_INFO_PROPERTY) != 0)
+ if ((impl_type & TYPE_MISSING_PLUGIN_INFO_PROPERTY) != 0)
{
- exten_type &= ~TYPE_MISSING_PLUGIN_INFO_PROPERTY;
+ impl_type &= ~TYPE_MISSING_PLUGIN_INFO_PROPERTY;
if (n_parameters > 0)
{
@@ -642,44 +651,45 @@ create_gobject_from_type (guint n_parameters,
}
}
- return G_OBJECT (g_object_newv (exten_type, n_parameters, parameters));
+ return G_OBJECT (g_object_newv (impl_type, n_parameters, parameters));
}
/**
* peas_object_module_register_extension_type:
* @module: Your plugin's #PeasObjectModule.
- * @iface_type: The #GType of the extension interface you implement.
- * @extension_type: The #GType of your implementation of @iface_type.
+ * @exten_type: The #GType of the extension you implement.
+ * @impl_type: The #GType of your implementation of @exten_type.
*
- * Register an extension type which implements the extension interface
- * @iface_type.
+ * Register @impl_type as an extension which implements @extension_type.
+ *
+ * Since libpeas 1.22, @exten_type can be an Abstract #GType
+ * and not just an Interface #GType.
*/
void
peas_object_module_register_extension_type (PeasObjectModule *module,
- GType iface_type,
- GType extension_type)
+ GType exten_type,
+ GType impl_type)
{
GObjectClass *cls;
GParamSpec *pspec;
g_return_if_fail (PEAS_IS_OBJECT_MODULE (module));
- g_return_if_fail (!peas_object_module_provides_object (module, iface_type));
- g_return_if_fail (g_type_is_a (extension_type, iface_type));
-
- if (iface_type != PEAS_TYPE_PLUGIN_LOADER)
- g_return_if_fail (G_TYPE_IS_INTERFACE (iface_type));
+ g_return_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_ABSTRACT (exten_type));
+ g_return_if_fail (!peas_object_module_provides_object (module, exten_type));
+ g_return_if_fail (g_type_is_a (impl_type, exten_type));
- cls = g_type_class_ref (extension_type);
+ cls = g_type_class_ref (impl_type);
pspec = g_object_class_find_property (cls, "plugin-info");
/* Avoid checking for this each time in the factory function */
if (pspec == NULL || pspec->value_type != PEAS_TYPE_PLUGIN_INFO)
- extension_type |= TYPE_MISSING_PLUGIN_INFO_PROPERTY;
+ impl_type |= TYPE_MISSING_PLUGIN_INFO_PROPERTY;
peas_object_module_register_extension_factory (module,
- iface_type,
+ exten_type,
create_gobject_from_type,
- GSIZE_TO_POINTER (extension_type),
+ GSIZE_TO_POINTER (impl_type),
NULL);
g_type_class_unref (cls);
diff --git a/libpeas/peas-object-module.h b/libpeas/peas-object-module.h
index 70a0265..08c5d6b 100644
--- a/libpeas/peas-object-module.h
+++ b/libpeas/peas-object-module.h
@@ -95,11 +95,11 @@ PeasObjectModule *peas_object_module_new_embedded (const gchar
const gchar *symbol);
GObject *peas_object_module_create_object (PeasObjectModule *module,
- GType interface,
+ GType exten_type,
guint n_parameters,
GParameter *parameters);
gboolean peas_object_module_provides_object (PeasObjectModule *module,
- GType interface);
+ GType exten_type);
const gchar *peas_object_module_get_path (PeasObjectModule *module);
const gchar *peas_object_module_get_module_name (PeasObjectModule *module);
@@ -109,14 +109,14 @@ GModule *peas_object_module_get_library (PeasObjectModule
void peas_object_module_register_extension_factory
(PeasObjectModule *module,
- GType iface_type,
+ GType exten_type,
PeasFactoryFunc factory_func,
gpointer user_data,
GDestroyNotify destroy_func);
void peas_object_module_register_extension_type
(PeasObjectModule *module,
- GType iface_type,
- GType extension_type);
+ GType exten_type,
+ GType impl_type);
G_END_DECLS
diff --git a/libpeas/peas-utils.c b/libpeas/peas-utils.c
index 1051d20..7d3bd91 100644
--- a/libpeas/peas-utils.c
+++ b/libpeas/peas-utils.c
@@ -91,6 +91,34 @@ add_all_prerequisites (GType iface_type,
g_free (prereq);
}
+static GPtrArray *
+find_base_type_and_interfaces (GType exten_type,
+ GType *base_type)
+{
+ GPtrArray *ifaces;
+ GType *interfaces;
+ gint i;
+
+ ifaces = g_ptr_array_new ();
+ g_ptr_array_set_free_func (ifaces,
+ (GDestroyNotify) g_type_default_interface_unref);
+
+ if (G_TYPE_IS_INTERFACE (exten_type))
+ {
+ add_all_prerequisites (exten_type, base_type, ifaces);
+ return ifaces;
+ }
+
+ interfaces = g_type_interfaces (exten_type, NULL);
+ for (i = 0; interfaces[i] != G_TYPE_INVALID; ++i)
+ add_all_prerequisites (exten_type, base_type, ifaces);
+
+ *base_type = exten_type;
+
+ g_free (interfaces);
+ return ifaces;
+}
+
static GParamSpec *
find_param_spec_for_prerequisites (const gchar *name,
GObjectClass *klass,
@@ -113,7 +141,7 @@ find_param_spec_for_prerequisites (const gchar *name,
}
gboolean
-peas_utils_valist_to_parameter_list (GType iface_type,
+peas_utils_valist_to_parameter_list (GType exten_type,
const gchar *first_property,
va_list args,
GParameter **params,
@@ -125,12 +153,10 @@ peas_utils_valist_to_parameter_list (GType iface_type,
const gchar *name;
guint n_allocated_params;
- g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface_type), FALSE);
+ g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
+ G_TYPE_IS_OBJECT (exten_type), FALSE);
- ifaces = g_ptr_array_new ();
- g_ptr_array_set_free_func (ifaces,
- (GDestroyNotify) g_type_default_interface_unref);
- add_all_prerequisites (iface_type, &base_type, ifaces);
+ ifaces = find_base_type_and_interfaces (exten_type, &base_type);
if (base_type != G_TYPE_INVALID)
klass = g_type_class_ref (base_type);
@@ -150,7 +176,7 @@ peas_utils_valist_to_parameter_list (GType iface_type,
if (!pspec)
{
g_warning ("%s: type '%s' has no property named '%s'",
- G_STRFUNC, g_type_name (iface_type), name);
+ G_STRFUNC, g_type_name (exten_type), name);
goto error;
}
diff --git a/libpeas/peas-utils.h b/libpeas/peas-utils.h
index adca711..5a19ba0 100644
--- a/libpeas/peas-utils.h
+++ b/libpeas/peas-utils.h
@@ -27,7 +27,7 @@
#define PEAS_UTILS_C_LOADER_ID 0
#define PEAS_UTILS_N_LOADERS 4
-gboolean peas_utils_valist_to_parameter_list (GType iface_type,
+gboolean peas_utils_valist_to_parameter_list (GType exten_type,
const gchar *first_property,
va_list var_args,
GParameter **params,