mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
gvalue: New g_value_init_from_instance
Used for the commonly used case (in signal emission) where we initialize and set a GValue for an instance Includes a fast-path for GObject Overall makes it 6 times faster than the previous combination of g_value_init + g_value_set_instance Makes signal emission around 10% faster https://bugzilla.gnome.org/show_bug.cgi?id=731950
This commit is contained in:
parent
f727c820b8
commit
c5c3c320a2
@ -438,6 +438,7 @@ g_value_init
|
|||||||
g_value_copy
|
g_value_copy
|
||||||
g_value_reset
|
g_value_reset
|
||||||
g_value_unset
|
g_value_unset
|
||||||
|
g_value_init_from_instance
|
||||||
g_value_set_instance
|
g_value_set_instance
|
||||||
g_value_fits_pointer
|
g_value_fits_pointer
|
||||||
g_value_peek_pointer
|
g_value_peek_pointer
|
||||||
|
@ -2157,8 +2157,7 @@ g_signal_chain_from_overridden_handler (gpointer instance,
|
|||||||
|
|
||||||
SIGNAL_UNLOCK ();
|
SIGNAL_UNLOCK ();
|
||||||
instance_and_params->g_type = 0;
|
instance_and_params->g_type = 0;
|
||||||
g_value_init (instance_and_params, G_TYPE_FROM_INSTANCE (instance));
|
g_value_init_from_instance (instance_and_params, instance);
|
||||||
g_value_set_instance (instance_and_params, instance);
|
|
||||||
SIGNAL_LOCK ();
|
SIGNAL_LOCK ();
|
||||||
|
|
||||||
emission->chain_type = chain_type;
|
emission->chain_type = chain_type;
|
||||||
@ -3305,8 +3304,7 @@ g_signal_emit_valist (gpointer instance,
|
|||||||
}
|
}
|
||||||
|
|
||||||
instance_and_params->g_type = 0;
|
instance_and_params->g_type = 0;
|
||||||
g_value_init (instance_and_params, G_TYPE_FROM_INSTANCE (instance));
|
g_value_init_from_instance (instance_and_params, instance);
|
||||||
g_value_set_instance (instance_and_params, instance);
|
|
||||||
if (signal_return_type == G_TYPE_NONE)
|
if (signal_return_type == G_TYPE_NONE)
|
||||||
signal_emit_unlocked_R (node, detail, instance, NULL, instance_and_params);
|
signal_emit_unlocked_R (node, detail, instance, NULL, instance_and_params);
|
||||||
else
|
else
|
||||||
|
@ -373,6 +373,71 @@ g_value_set_instance (GValue *value,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_value_init_from_instance:
|
||||||
|
* @value: An uninitialized #GValue structure.
|
||||||
|
* @instance: the instance
|
||||||
|
*
|
||||||
|
* Initializes and sets @value from an instantiatable type via the
|
||||||
|
* value_table's collect_value() function.
|
||||||
|
*
|
||||||
|
* Note: The @value will be initialised with the exact type of
|
||||||
|
* @instance. If you wish to set the @value's type to a different GType
|
||||||
|
* (such as a parent class GType), you need to manually call
|
||||||
|
* g_value_init() and g_value_set_instance().
|
||||||
|
*
|
||||||
|
* Since: 2.42
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
g_value_init_from_instance (GValue *value,
|
||||||
|
gpointer instance)
|
||||||
|
{
|
||||||
|
g_return_if_fail (value != NULL && G_VALUE_TYPE(value) == 0);
|
||||||
|
|
||||||
|
if (G_IS_OBJECT (instance))
|
||||||
|
{
|
||||||
|
/* Fast-path.
|
||||||
|
* If G_IS_OBJECT() succeeds we know:
|
||||||
|
* * that instance is present and valid
|
||||||
|
* * that it is a GObject, and therefore we can directly
|
||||||
|
* use the collect implementation (g_object_ref) */
|
||||||
|
value_meminit (value, G_TYPE_FROM_INSTANCE (instance));
|
||||||
|
value->data[0].v_pointer = g_object_ref (instance);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GType g_type;
|
||||||
|
GTypeValueTable *value_table;
|
||||||
|
GTypeCValue cvalue;
|
||||||
|
gchar *error_msg;
|
||||||
|
|
||||||
|
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
|
||||||
|
|
||||||
|
g_type = G_TYPE_FROM_INSTANCE (instance);
|
||||||
|
value_table = g_type_value_table_peek (g_type);
|
||||||
|
g_return_if_fail (strcmp (value_table->collect_format, "p") == 0);
|
||||||
|
|
||||||
|
memset (&cvalue, 0, sizeof (cvalue));
|
||||||
|
cvalue.v_pointer = instance;
|
||||||
|
|
||||||
|
/* setup and collect */
|
||||||
|
value_meminit (value, g_type);
|
||||||
|
value_table->value_init (value);
|
||||||
|
error_msg = value_table->collect_value (value, 1, &cvalue, 0);
|
||||||
|
if (error_msg)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error_msg);
|
||||||
|
g_free (error_msg);
|
||||||
|
|
||||||
|
/* we purposely leak the value here, it might not be
|
||||||
|
* in a sane state if an error condition occoured
|
||||||
|
*/
|
||||||
|
value_meminit (value, g_type);
|
||||||
|
value_table->value_init (value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GValueTransform
|
static GValueTransform
|
||||||
transform_func_lookup (GType src_type,
|
transform_func_lookup (GType src_type,
|
||||||
GType dest_type)
|
GType dest_type)
|
||||||
|
@ -137,6 +137,9 @@ void g_value_unset (GValue *value);
|
|||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
void g_value_set_instance (GValue *value,
|
void g_value_set_instance (GValue *value,
|
||||||
gpointer instance);
|
gpointer instance);
|
||||||
|
GLIB_AVAILABLE_IN_2_42
|
||||||
|
void g_value_init_from_instance (GValue *value,
|
||||||
|
gpointer instance);
|
||||||
|
|
||||||
|
|
||||||
/* --- private --- */
|
/* --- private --- */
|
||||||
|
Loading…
Reference in New Issue
Block a user