gobject: Use value_is_valid

Avoid GValue transformation when we can, using
the new value_is_valid vfunc.

This is particularly useful for string properties,
where g_value_transform will make a copy of the string.
This commit is contained in:
Matthias Clasen 2021-09-29 01:20:36 -04:00 committed by Philip Withnall
parent b0d15068c4
commit c72de9dd99

View File

@ -1573,12 +1573,12 @@ object_set_property (GObject *object,
const GValue *value, const GValue *value,
GObjectNotifyQueue *nqueue) GObjectNotifyQueue *nqueue)
{ {
GValue tmp_value = G_VALUE_INIT;
GObjectClass *class = g_type_class_peek (pspec->owner_type); GObjectClass *class = g_type_class_peek (pspec->owner_type);
GParamSpecClass *pclass;
guint param_id = PARAM_SPEC_PARAM_ID (pspec); guint param_id = PARAM_SPEC_PARAM_ID (pspec);
GParamSpec *redirect; GParamSpec *redirect;
if (class == NULL) if (G_UNLIKELY (class == NULL))
{ {
g_warning ("'%s::%s' is not a valid property name; '%s' is not a GObject subtype", g_warning ("'%s::%s' is not a valid property name; '%s' is not a GObject subtype",
g_type_name (pspec->owner_type), pspec->name, g_type_name (pspec->owner_type)); g_type_name (pspec->owner_type), pspec->name, g_type_name (pspec->owner_type));
@ -1589,8 +1589,20 @@ object_set_property (GObject *object,
if (redirect) if (redirect)
pspec = redirect; pspec = redirect;
pclass = G_PARAM_SPEC_GET_CLASS (pspec);
if (g_value_type_compatible (G_VALUE_TYPE (value), pspec->value_type) &&
(pclass->value_validate == NULL ||
(pclass->value_is_valid != NULL && pclass->value_is_valid (pspec, value))))
{
class->set_property (object, param_id, value, pspec);
}
else
{
/* provide a copy to work from, convert (if necessary) and validate */ /* provide a copy to work from, convert (if necessary) and validate */
GValue tmp_value = G_VALUE_INIT;
g_value_init (&tmp_value, pspec->value_type); g_value_init (&tmp_value, pspec->value_type);
if (!g_value_transform (value, &tmp_value)) if (!g_value_transform (value, &tmp_value))
g_warning ("unable to set property '%s' of type '%s' from value of type '%s'", g_warning ("unable to set property '%s' of type '%s' from value of type '%s'",
pspec->name, pspec->name,
@ -1610,12 +1622,13 @@ object_set_property (GObject *object,
else else
{ {
class->set_property (object, param_id, &tmp_value, pspec); class->set_property (object, param_id, &tmp_value, pspec);
if (~pspec->flags & G_PARAM_EXPLICIT_NOTIFY &&
pspec->flags & G_PARAM_READABLE)
g_object_notify_queue_add (object, nqueue, pspec);
} }
g_value_unset (&tmp_value); g_value_unset (&tmp_value);
}
if ((pspec->flags & (G_PARAM_EXPLICIT_NOTIFY|G_PARAM_READABLE)) == G_PARAM_READABLE)
g_object_notify_queue_add (object, nqueue, pspec);
} }
static void static void