diff options
author | Garrett Regier <garrettregier@gmail.com> | 2017-03-24 12:41:09 -0700 |
---|---|---|
committer | Garrett Regier <garrettregier@gmail.com> | 2017-03-24 21:27:15 -0700 |
commit | 7e7e850d24a930ffdaf04d0feaf6607fe797f30e (patch) | |
tree | dbde908fd4a0969afe0ee49fd668a1f74f540009 /libpeas | |
parent | 743ca63655ac23c24efed5aad33479fa1f4faadf (diff) | |
download | libpeas-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.c | 33 | ||||
-rw-r--r-- | libpeas/peas-extension-set.c | 18 | ||||
-rw-r--r-- | libpeas/peas-extension.c | 32 | ||||
-rw-r--r-- | libpeas/peas-introspection.c | 29 | ||||
-rw-r--r-- | libpeas/peas-introspection.h | 4 | ||||
-rw-r--r-- | libpeas/peas-object-module.c | 116 | ||||
-rw-r--r-- | libpeas/peas-object-module.h | 10 | ||||
-rw-r--r-- | libpeas/peas-utils.c | 40 | ||||
-rw-r--r-- | libpeas/peas-utils.h | 2 |
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, ¶meters, @@ -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, ¶meters, @@ -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, >ype); /* 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, |