diff --git a/gobject/gproperty.c b/gobject/gproperty.c index 55c69c0ca..d847a0339 100644 --- a/gobject/gproperty.c +++ b/gobject/gproperty.c @@ -615,6 +615,10 @@ g_##g_t##_property_new (const gchar *name, \ \ if (setter == NULL && getter == NULL) \ g_return_val_if_fail (offset >= 0, NULL); \ + if (setter == NULL) \ + flags |= G_PROPERTY_DIRECT_SET; \ + if (getter == NULL) \ + flags |= G_PROPERTY_DIRECT_GET; \ \ prop = g_param_spec_internal (_g_##g_t##_property_get_type (), \ name, NULL, NULL, \ @@ -865,6 +869,23 @@ property_flags_to_param_flags (GPropertyFlags flags) return retval; } +gpointer +g_property_get_field (GProperty *property, + gpointer gobject) +{ + gpointer priv_p; + + g_return_val_if_fail (G_IS_PROPERTY (property), NULL); + g_return_val_if_fail (G_IS_OBJECT (gobject), NULL); + g_return_val_if_fail (property->field_offset >= 0, NULL); + + priv_p = get_private_pointer (gobject, property->priv_offset); + if (priv_p == NULL) + return NULL; + + return G_STRUCT_MEMBER_P (priv_p, property->field_offset); +} + /* forward declaration */ static void property_set_default (GParamSpec *pspec, GValue *value); @@ -1307,6 +1328,10 @@ g_enum_property_new (const gchar *name, if (setter == NULL && getter == NULL) g_return_val_if_fail (offset >= 0, NULL); + if (setter == NULL) + flags |= G_PROPERTY_DIRECT_SET; + if (getter == NULL) + flags |= G_PROPERTY_DIRECT_GET; prop = g_param_spec_internal (_g_enum_property_get_type (), name, NULL, NULL, @@ -1565,6 +1590,10 @@ g_flags_property_new (const gchar *name, if (setter == NULL && getter == NULL) g_return_val_if_fail (offset >= 0, NULL); + if (setter == NULL) + flags |= G_PROPERTY_DIRECT_SET; + if (getter == NULL) + flags |= G_PROPERTY_DIRECT_GET; prop = g_param_spec_internal (_g_flags_property_get_type (), name, NULL, NULL, @@ -1826,6 +1855,10 @@ g_float_property_new (const gchar *name, if (setter == NULL && getter == NULL) g_return_val_if_fail (offset >= 0, NULL); + if (setter == NULL) + flags |= G_PROPERTY_DIRECT_SET; + if (getter == NULL) + flags |= G_PROPERTY_DIRECT_GET; prop = g_param_spec_internal (_g_float_property_get_type (), name, NULL, NULL, @@ -2107,6 +2140,10 @@ g_double_property_new (const gchar *name, if (setter == NULL && getter == NULL) g_return_val_if_fail (offset >= 0, NULL); + if (setter == NULL) + flags |= G_PROPERTY_DIRECT_SET; + if (getter == NULL) + flags |= G_PROPERTY_DIRECT_GET; prop = g_param_spec_internal (_g_double_property_get_type (), name, NULL, NULL, @@ -2346,6 +2383,10 @@ g_string_property_new (const gchar *name, if (setter == NULL && getter == NULL) g_return_val_if_fail (offset >= 0, NULL); + if (setter == NULL) + flags |= G_PROPERTY_DIRECT_SET; + if (getter == NULL) + flags |= G_PROPERTY_DIRECT_GET; prop = g_param_spec_internal (_g_string_property_get_type (), name, NULL, NULL, @@ -2572,6 +2613,10 @@ g_boxed_property_new (const gchar *name, if (setter == NULL && getter == NULL) g_return_val_if_fail (offset >= 0, NULL); + if (setter == NULL) + flags |= G_PROPERTY_DIRECT_SET; + if (getter == NULL) + flags |= G_PROPERTY_DIRECT_GET; prop = g_param_spec_internal (_g_boxed_property_get_type (), name, NULL, NULL, @@ -2797,6 +2842,10 @@ g_object_property_new (const gchar *name, if (setter == NULL && getter == NULL) g_return_val_if_fail (offset >= 0, NULL); + if (setter == NULL) + flags |= G_PROPERTY_DIRECT_SET; + if (getter == NULL) + flags |= G_PROPERTY_DIRECT_GET; prop = g_param_spec_internal (_g_object_property_get_type (), name, NULL, NULL, @@ -3038,6 +3087,10 @@ g_pointer_property_new (const gchar *name, if (setter == NULL && getter == NULL) g_return_val_if_fail (offset >= 0, NULL); + if (setter == NULL) + flags |= G_PROPERTY_DIRECT_SET; + if (getter == NULL) + flags |= G_PROPERTY_DIRECT_GET; prop = g_param_spec_internal (_g_pointer_property_get_type (), name, NULL, NULL, @@ -5440,6 +5493,22 @@ g_property_is_copy_get (GProperty *property) return (property->flags & G_PROPERTY_COPY_GET) != 0; } +gboolean +g_property_is_direct_set (GProperty *property) +{ + g_return_val_if_fail (G_IS_PROPERTY (property), FALSE); + + return (property->flags & G_PROPERTY_DIRECT_SET) != 0; +} + +gboolean +g_property_is_direct_get (GProperty *property) +{ + g_return_val_if_fail (G_IS_PROPERTY (property), FALSE); + + return (property->flags & G_PROPERTY_DIRECT_GET) != 0; +} + /** * g_property_lock: * @property: a #GProperty diff --git a/gobject/gproperty.h b/gobject/gproperty.h index c78e44d28..8ec58a3df 100644 --- a/gobject/gproperty.h +++ b/gobject/gproperty.h @@ -78,7 +78,10 @@ typedef enum { G_PROPERTY_ATOMIC = 1 << 3, G_PROPERTY_COPY_SET = 1 << 4, G_PROPERTY_COPY_GET = 1 << 5, - G_PROPERTY_COPY = (G_PROPERTY_COPY_SET | G_PROPERTY_COPY_GET) + G_PROPERTY_COPY = (G_PROPERTY_COPY_SET | G_PROPERTY_COPY_GET), + G_PROPERTY_DIRECT_SET = 1 << 6, + G_PROPERTY_DIRECT_GET = 1 << 7, + G_PROPERTY_DIRECT = (G_PROPERTY_DIRECT_SET | G_PROPERTY_DIRECT_GET) } GPropertyFlags; GLIB_AVAILABLE_IN_2_36 @@ -103,6 +106,14 @@ GLIB_AVAILABLE_IN_2_36 gboolean g_property_is_copy_set (GProperty *property); GLIB_AVAILABLE_IN_2_36 gboolean g_property_is_copy_get (GProperty *property); +GLIB_AVAILABLE_IN_2_36 +gboolean g_property_is_direct_set (GProperty *property); +GLIB_AVAILABLE_IN_2_36 +gboolean g_property_is_direct_get (GProperty *property); + +GLIB_AVAILABLE_IN_2_36 +gpointer g_property_get_field (GProperty *property, + gpointer gobject); GLIB_AVAILABLE_IN_2_36 void g_property_describe (GProperty *property, @@ -490,6 +501,13 @@ GParamSpec * g_pointer_property_new (const gchar *name, g_critical (G_STRLOC ": The property " #f_n " is not readable"); \ return (f_t) 0; \ } \ +\ + if (g_property_is_direct_get (g_property) && \ + !g_property_is_atomic (g_property)) \ + { \ + gpointer field_p = g_property_get_field (g_property, self); \ + return (* (f_t *) field_p); \ + } \ \ if (!g_property_get (g_property, self, &retval)) \ { \ diff --git a/tests/gobject/performance.c b/tests/gobject/performance.c index 13b0ec72b..87b1b7c3b 100644 --- a/tests/gobject/performance.c +++ b/tests/gobject/performance.c @@ -730,6 +730,12 @@ property_object_get_foo (PropertyObject *self) { gint value; + if (g_property_is_direct_get (((GProperty *) property_props[PROP_PROPERTY_FOO]))) + { + gpointer field_p = g_property_get_field (((GProperty *) property_props[PROP_PROPERTY_FOO]), self); + return (* (int *) field_p); + } + g_property_get (((GProperty *) property_props[PROP_PROPERTY_FOO]), self, &value); return value; @@ -746,6 +752,12 @@ property_object_get_baz (PropertyObject *self) { float value; + if (g_property_is_direct_get (((GProperty *) property_props[PROP_PROPERTY_BAZ]))) + { + gpointer field_p = g_property_get_field (((GProperty *) property_props[PROP_PROPERTY_BAZ]), self); + return (* (float *) field_p); + } + g_property_get (((GProperty *) property_props[PROP_PROPERTY_BAZ]), self, &value); return value;