Commit 936959ba authored by Fabián Orccón's avatar Fabián Orccón Committed by Christian Hergert

extension-set: adds peas_extension_set_new_with_properties()

Adds a new introspectable variant of peas_extension_set_new() for
language bindings.

Fixes #8
parent f7aae325
......@@ -650,6 +650,72 @@ peas_extension_set_newv (PeasEngine *engine,
NULL));
}
/**
* peas_extension_set_new_with_properties: (rename-to peas_extension_set_new)
* @engine: (allow-none): A #PeasEngine, or %NULL.
* @exten_type: the extension #GType.
* @n_properties: the length of the @prop_names and @prop_values array.
* @prop_names: (array length=n_properties): an array of property names.
* @prop_values: (array length=n_properties): an array of property values.
*
* Create a new #PeasExtensionSet for the @exten_type extension type.
*
* 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.
*
* Since 1.24.0
*/
PeasExtensionSet *
peas_extension_set_new_with_properties (PeasEngine *engine,
GType exten_type,
guint n_properties,
const gchar **prop_names,
const GValue *prop_values)
{
PeasExtensionSet *ret;
PeasParameterArray construct_properties;
GParameter *parameters = NULL;
g_return_val_if_fail (engine == NULL || PEAS_IS_ENGINE (engine), NULL);
g_return_val_if_fail (G_TYPE_IS_INTERFACE (exten_type) ||
G_TYPE_IS_ABSTRACT (exten_type), NULL);
g_return_val_if_fail (n_properties == 0 || prop_names != NULL, NULL);
g_return_val_if_fail (n_properties == 0 || prop_values != NULL, NULL);
if (n_properties > 0)
{
parameters = g_new0 (GParameter, n_properties);
if (!peas_utils_properties_array_to_parameter_list (exten_type,
n_properties,
prop_names,
prop_values,
parameters))
{
/* Already warned */
g_free (parameters);
return NULL;
}
}
construct_properties.n_parameters = n_properties;
construct_properties.parameters = parameters;
ret = g_object_new (PEAS_TYPE_EXTENSION_SET,
"engine", engine,
"extension-type", exten_type,
"construct-properties", &construct_properties,
NULL);
g_free (parameters);
return ret;
}
/**
* peas_extension_set_new_valist: (skip)
* @engine: (allow-none): A #PeasEngine, or %NULL.
......
......@@ -147,8 +147,14 @@ PeasExtensionSet *peas_extension_set_newv (PeasEngine *engine,
GType exten_type,
guint n_parameters,
GParameter *parameters);
G_GNUC_END_IGNORE_DEPRECATIONS
PEAS_AVAILABLE_IN_1_24
PeasExtensionSet *peas_extension_set_new_with_properties (PeasEngine *engine,
GType exten_type,
guint n_properties,
const gchar **prop_names,
const GValue *prop_values);
G_GNUC_END_IGNORE_DEPRECATIONS
PEAS_AVAILABLE_IN_ALL
PeasExtensionSet *peas_extension_set_new_valist (PeasEngine *engine,
GType exten_type,
......
......@@ -181,6 +181,60 @@ find_param_spec_for_prerequisites (const gchar *name,
}
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gboolean
peas_utils_properties_array_to_parameter_list (GType exten_type,
guint n_properties,
const gchar **prop_names,
const GValue *prop_values,
GParameter *parameters)
{
guint i;
gpointer *ifaces;
GObjectClass *base_class;
g_return_val_if_fail (n_properties == 0 || prop_names != NULL, FALSE);
g_return_val_if_fail (n_properties == 0 || prop_values != NULL, FALSE);
g_return_val_if_fail (n_properties == 0 || parameters != NULL, FALSE);
ifaces = get_base_class_and_interfaces (exten_type, &base_class);
memset (parameters, 0, sizeof (GParameter) * n_properties);
for (i = 0; i < n_properties; i++)
{
GParamSpec *pspec;
if (prop_names[i] == NULL)
{
g_warning ("The property name at index %u should not be NULL.", i);
goto error;
}
if (!G_IS_VALUE (&prop_values[i]))
{
g_warning ("The property value at index %u should be an initialized GValue.", i);
goto error;
}
pspec = find_param_spec_for_prerequisites (prop_names[i], base_class,
ifaces);
if (!pspec)
{
g_warning ("%s: type '%s' has no property named '%s'",
G_STRFUNC, g_type_name (exten_type), prop_names[i]);
goto error;
}
parameters[i].name = prop_names[i];
g_value_init (&parameters[i].value,
G_VALUE_TYPE (&prop_values[i]));
g_value_copy (&prop_values[i], &parameters[i].value);
}
return TRUE;
error:
n_properties = i;
for (i = 0; i < n_properties; i++)
g_value_unset (&parameters[i].value);
return FALSE;
}
gboolean
peas_utils_valist_to_parameter_list (GType exten_type,
const gchar *first_property,
......
......@@ -27,6 +27,13 @@
#define PEAS_UTILS_C_LOADER_ID 0
#define PEAS_UTILS_N_LOADERS 4
gboolean peas_utils_properties_array_to_parameter_list
(GType exten_type,
guint n_properties,
const gchar **prop_names,
const GValue *prop_values,
GParameter *params);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
gboolean peas_utils_valist_to_parameter_list (GType exten_type,
const gchar *first_property,
......
......@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <glib.h>
#include <glib-object.h>
#include <libpeas/peas.h>
#include "testing/testing.h"
......@@ -146,6 +147,48 @@ test_extension_set_create_valid (PeasEngine *engine)
g_object_unref (extension_set);
}
static void
valid_extension_added_cb (PeasExtensionSet *extension_set,
PeasPluginInfo *info,
PeasExtension *extension,
GObject **obj_ptr)
{
g_object_get (PEAS_ACTIVATABLE (extension), "object", obj_ptr, NULL);
}
static void
test_extension_set_create_valid_with_properties (PeasEngine *engine)
{
PeasPluginInfo *info;
PeasExtensionSet *extension_set;
GValue prop_value = G_VALUE_INIT;
GObject *obj, *obj_cmp;
const gchar *prop_names[1] = { "object" };
obj = g_object_new (G_TYPE_OBJECT, NULL);
g_value_init (&prop_value, G_TYPE_OBJECT);
g_value_set_object (&prop_value, obj);
extension_set = peas_extension_set_new_with_properties (engine,
PEAS_TYPE_ACTIVATABLE,
G_N_ELEMENTS (prop_names),
prop_names,
&prop_value);
g_signal_connect (extension_set,
"extension-added",
G_CALLBACK (valid_extension_added_cb),
&obj_cmp);
info = peas_engine_get_plugin_info (engine, "builtin");
g_assert (peas_engine_load_plugin (engine, info));
g_assert (obj == obj_cmp);
g_assert (PEAS_IS_EXTENSION_SET (extension_set));
g_object_unref (extension_set);
g_value_unset (&prop_value);
}
static void
test_extension_set_create_invalid (PeasEngine *engine)
{
......@@ -172,6 +215,62 @@ test_extension_set_create_invalid (PeasEngine *engine)
g_assert (!PEAS_IS_EXTENSION_SET (extension_set));
}
static void
test_extension_set_create_invalid_with_properties (PeasEngine *engine)
{
PeasExtensionSet *extension_set;
GValue prop_values[2] = { G_VALUE_INIT };
const gchar *prop_names[2] = { "object", NULL };
const gchar *prop_names_not_exist[1] = { "aleb" };
guint n_elements;
testing_util_push_log_hook ("*property name*should not be NULL.");
testing_util_push_log_hook ("*assertion*G_TYPE_IS_INTERFACE*failed");
testing_util_push_log_hook ("*should be an initialized GValue.");
testing_util_push_log_hook ("*has no property named 'aleb'*");
g_value_init (&prop_values[0], G_TYPE_POINTER);
g_value_set_pointer (&prop_values[0], NULL);
/* Interface has a NULL property name*/
n_elements = G_N_ELEMENTS (prop_values);
extension_set = peas_extension_set_new_with_properties (engine,
PEAS_TYPE_ACTIVATABLE,
n_elements,
prop_names,
prop_values);
g_assert (!PEAS_IS_EXTENSION_SET (extension_set));
g_value_unset (&prop_values[0]);
/* Invalid GType */
extension_set = peas_extension_set_new_with_properties (engine,
G_TYPE_INVALID,
0, NULL, NULL);
g_assert (!PEAS_IS_EXTENSION_SET (extension_set));
/* Uninitialized GValue */
n_elements = 1;
extension_set = peas_extension_set_new_with_properties (engine,
PEAS_TYPE_ACTIVATABLE,
n_elements,
prop_names,
prop_values);
g_assert (!PEAS_IS_EXTENSION_SET (extension_set));
/* Uninitialized GValue*/
g_value_init (&prop_values[0], G_TYPE_POINTER);
g_value_set_pointer (&prop_values[0], NULL);
n_elements = G_N_ELEMENTS (prop_names_not_exist);
extension_set = peas_extension_set_new_with_properties (engine,
PEAS_TYPE_ACTIVATABLE,
n_elements,
prop_names_not_exist,
prop_values);
g_assert (!PEAS_IS_EXTENSION_SET (extension_set));
g_value_unset (&prop_values[0]);
}
static void
test_extension_set_extension_added (PeasEngine *engine)
{
......@@ -345,6 +444,8 @@ main (int argc,
TEST ("create-valid", create_valid);
TEST ("create-invalid", create_invalid);
TEST ("create-valid-with-properties", create_valid_with_properties);
TEST ("create-invalid-with-properties", create_invalid_with_properties);
TEST ("extension-added", extension_added);
TEST ("extension-removed", extension_removed);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment