From f8900df2cfe73b4b0231f3e36bc1ffcce3c05bc1 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 24 Apr 2013 17:41:15 -0400 Subject: [PATCH] property: Add macros for defining properties Alongside the macros for defining accessors we may want to use simple macros for defining properties to install on a GObject class. https://bugzilla.gnome.org/show_bug.cgi?id=648526 --- gobject/gproperty.h | 349 ++++++++++++++++++++++++++++++++++----- gobject/gtype.h | 10 +- gobject/tests/property.c | 154 +++++++++-------- 3 files changed, 391 insertions(+), 122 deletions(-) diff --git a/gobject/gproperty.h b/gobject/gproperty.h index 69ded229d..d4b4ac81d 100644 --- a/gobject/gproperty.h +++ b/gobject/gproperty.h @@ -431,7 +431,259 @@ void g_property_set_installed (GProperty *property, void g_property_init_default (GProperty *property, gpointer object); +/* property generation */ +/** + * G_PROPERTY_DESCRIBE: + * @p_nick: a human readable, translatable name for the property + * @p_blurb: a human readable, translatable description for the property + * + * Sets the property nick and blurb using two static strings. + * + * This macro can only be called inside %G_DEFINE_PROPERTY_EXTENDED. + * + * Since: 2.38 + */ +#define G_PROPERTY_DESCRIBE(p_nick, p_blurb) \ + { \ + GParamSpec *__g_param_spec = (GParamSpec *) g_property; \ + g_param_spec_set_static_nick (__g_param_spec, p_nick); \ + g_param_spec_set_static_blurb (__g_param_spec, p_blurb); \ + } + +/** + * G_PROPERTY_DEFAULT: + * @p_val: the default value of the property + * + * Sets the default value for the property. + * + * This macro can only be called inside %G_DEFINE_PROPERTY_EXTENDED. + * + * Since: 2.38 + */ +#define G_PROPERTY_DEFAULT(p_val) \ + g_property_set_default (g_property, p_val); + +/** + * G_PROPERTY_RANGE: + * @p_min: the minimum value of the valid range for the property + * @p_max: the maximum value of the valid range for the property + * + * Sets the range of valid values for the property. + * + * This macro can only be called inside %G_DEFINE_PROPERTY_EXTENDED. + * + * Since: 2.38 + */ +#define G_PROPERTY_RANGE(p_min, p_max) \ + g_property_set_range (g_property, p_min, p_max); + +/** + * G_PROPERTY_PREREQUISITE: + * @type: the prerequisite type for the property + * + * Sets the prerequisite type for enumeration, flags, boxed, + * and object properties. + * + * This macro can only be called inside %G_DEFINE_PROPERTY_EXTENDED. + * + * Since: 2.38 + */ +#define G_PROPERTY_PREREQUISITE(type) \ + g_property_set_prerequisite (g_property, type); + +#define _G_DEFINE_PROPERTIES_BEGIN() \ + { \ + GPtrArray *g_define_properties = g_ptr_array_new (); \ + g_ptr_array_add (g_define_properties, NULL); + +#define _G_DEFINE_PROPERTIES_END(T_N, t_n, g_class) \ + t_n##_properties_len = g_define_properties->len; \ + t_n##_properties = (GParamSpec **) g_ptr_array_free (g_define_properties, FALSE); \ + g_object_class_install_properties (G_OBJECT_CLASS (g_class), \ + t_n##_properties_len, \ + t_n##_properties); \ + } + +/** + * G_DEFINE_PROPERTIES: + * @T_N: the name of the type, in CamelCase + * @t_n: the name of the type, in lower case, with spaces replaced by underscores + * @g_class: a pointer to the class structure of the type + * @_C_: a list of G_DEFINE_PROPERTY_EXTENDED calls + * + * Defines a list of properties and installs them on the class. + * + * Note that this macro can only be used with types defined using + * G_DEFINE_TYPE_* macros, as it depends on variables defined by + * those macros. + * + * Since: 2.38 + */ +#define G_DEFINE_PROPERTIES(T_N, t_n, g_class, _C_) \ + _G_DEFINE_PROPERTIES_BEGIN() \ + { _C_; } \ + _G_DEFINE_PROPERTIES_END(T_N, t_n, g_class) + +#define _G_DEFINE_DIRECT_PROPERTY_EXTENDED_BEGIN(T_N, c_type, name, flags) \ +{ \ + GProperty *g_property = (GProperty *) \ + g_##c_type##_property_new (#name, flags, \ + G_STRUCT_OFFSET (T_N##Private, name), \ + NULL, \ + NULL); +#define _G_DEFINE_PROPERTY_EXTENDED_BEGIN(T_N, c_type, name, offset, setterFunc, getterFunc, flags) \ +{ \ + GProperty *g_property = (GProperty *) \ + g_##c_type##_property_new (#name, flags, \ + offset, \ + setterFunc, \ + getterFunc); +#define _G_DEFINE_PROPERTY_EXTENDED_END \ + g_ptr_array_add (g_define_properties, g_property); \ +} + +/** + * G_DEFINE_PROPERTY_EXTENDED: + * @T_N: the name of the type, in CamelCase + * @c_type: the C type of the property, in lower case, minus the "g" if the type + * is defined by GLib; for instance "int" for "gint", "uint8" for "guint8", + * "boolean" for "gboolean"; strings stored in a gchar* are defined as "string" + * @name: the name of the property, in lower case, with '-' replaced by '_' + * @offset: the offset of the field in the structure that stores the property, or 0 + * @setterFunc: the explicit setter function, or %NULL for direct access + * @getterFunc: the explicit getter function, or %NULL for direct access + * @flags: #GPropertyFlags for the property + * @_C_: custom code to be called after the property has been defined; the + * GProperty instance is available under the "g_property" variable + * + * The most generic property definition macro. + * + * |[ + * G_DEFINE_PROPERTY_EXTENDED (GtkGadget, + * int, + * width, + * G_STRUCT_OFFSET (GtkGadgetPrivate, width), + * NULL, NULL, + * G_PROPERTY_READWRITE, + * G_PROPERTY_RANGE (0, G_MAXINT)) + * ]| + * expands to + * |[ + * { + * GProperty *g_property = + * g_int_property_new ("width", G_PROPERTY_READWRITE, + * G_STRUCT_OFFSET (GtkGadgetPrivate, width), + * NULL, NULL); + * g_property_set_range (g_property, 0, G_MAXINT); + * gtk_gadget_properties[PROP_GtkGadget_width] = g_property; + * } + * ]| + * + * This macro should only be used with G_DEFINE_PROPERTIES() as it depends + * on variables and functions defined by that macro. + * + * Since: 2.38 + */ +#define G_DEFINE_PROPERTY_EXTENDED(T_N, c_type, name, offset, setterFunc, getterFunc, flags, _C_) \ + _G_DEFINE_PROPERTY_EXTENDED_BEGIN (T_N, c_type, name, offset, setterFunc, getterFunc, flags) \ + { _C_; } \ + _G_DEFINE_PROPERTY_EXTENDED_END + +/** + * G_DEFINE_PROPERTY_WITH_CODE: + * @T_N: the name of the type, in CamelCase + * @c_type: the C type of the property, in lower case, minus the "g" if the type + * is defined by GLib; for instance "int" for "gint", "uint8" for "guint8", + * "boolean" for "gboolean"; strings stored in a gchar* are defined as "string" + * @name: the name of the property, in lower case, with '-' replaced by '_'; the + * name of the property must exist as a member of the per-instance private data + * structure of the type name + * @flags: #GPropertyFlags for the property + * @_C_: custom code to be called after the property has been defined; the + * GProperty instance is available under the "g_property" variable + * + * A variant of G_DEFINE_PROPERTY_EXTENDED() that only allows properties + * with direct access, stored on the per-instance private data structure + * for the given type. + * + * Since: 2.38 + */ +#define G_DEFINE_PROPERTY_WITH_CODE(T_N, c_type, name, flags, _C_) \ + _G_DEFINE_DIRECT_PROPERTY_EXTENDED_BEGIN (T_N, c_type, name, flags) \ + { _C_; } \ + _G_DEFINE_PROPERTY_EXTENDED_END + +/** + * G_DEFINE_PROPERTY_WITH_DEFAULT: + * @T_N: the name of the type, in CamelCase + * @c_type: the C type of the property, in lower case, minus the "g" if the type + * is defined by GLib; for instance "int" for "gint", "uint8" for "guint8", + * "boolean" for "gboolean"; strings stored in a gchar* are defined as "string" + * @name: the name of the property, in lower case, with '-' replaced by '_'; the + * name of the property must exist as a member of the per-instance private data + * structure of the type name + * @flags: #GPropertyFlags for the property + * @defVal: the default value of the property + * + * A convenience macro for defining a direct access property with a default + * value. + * + * See G_DEFINE_PROPERTY_WITH_CODE() and G_PROPERTY_DEFAULT(). + * + * Since: 2.38 + */ +#define G_DEFINE_PROPERTY_WITH_DEFAULT(T_N, c_type, name, flags, defVal) \ + _G_DEFINE_DIRECT_PROPERTY_EXTENDED_BEGIN (T_N, c_type, name, flags) \ + G_PROPERTY_DEFAULT (defVal) \ + _G_DEFINE_PROPERTY_EXTENDED_END + +/** + * G_DEFINE_PROPERTY_WITH_RANGE: + * @T_N: the name of the type, in CamelCase + * @c_type: the C type of the property, in lower case, minus the "g" if the type + * is defined by GLib; for instance "int" for "gint", "uint8" for "guint8", + * "boolean" for "gboolean"; strings stored in a gchar* are defined as "string" + * @name: the name of the property, in lower case, with '-' replaced by '_'; the + * name of the property must exist as a member of the per-instance private data + * structure of the type name + * @flags: #GPropertyFlags for the property + * @minVal: the minimum value of the property + * @maxVal: the maximum value of the property + * + * A convenience macro for defining a direct access property with a range + * of valid values. + * + * See G_DEFINE_PROPERTY_WITH_CODE() and G_PROPERTY_RANGE(). + * + * Since: 2.38 + */ +#define G_DEFINE_PROPERTY_WITH_RANGE(T_N, c_type, name, flags, minVal, maxVal) \ + _G_DEFINE_DIRECT_PROPERTY_EXTENDED_BEGIN (T_N, c_type, name, flags) \ + G_PROPERTY_RANGE (minVal, maxVal) \ + _G_DEFINE_PROPERTY_EXTENDED_END + +/** + * G_DEFINE_PROPERTY: + * @T_N: the name of the type, in CamelCase + * @c_type: the C type of the property, in lower case, minus the "g" if the type + * is defined by GLib; for instance "int" for "gint", "uint8" for "guint8", + * "boolean" for "gboolean"; strings stored in a gchar* are defined as "string" + * @name: the name of the property, in lower case, with '-' replaced by '_'; the + * name of the property must exist as a member of the per-instance private data + * structure of the type name + * @flags: #GPropertyFlags for the property + * + * A convenience macro for defining a direct access property. + * + * See G_DEFINE_PROPERTY_WITH_CODE() and G_DEFINE_PROPERTY_EXTENDED() if + * you need more flexibility. + * + * Since: 2.38 + */ +#define G_DEFINE_PROPERTY(T_N, c_type, name, flags) \ + _G_DEFINE_DIRECT_PROPERTY_EXTENDED_BEGIN (T_N, c_type, name, flags) \ + _G_DEFINE_PROPERTY_EXTENDED_END /* accessors generation */ #define _G_DECLARE_PROPERTY_GETTER(T_n, t_n, f_t, f_n) f_t t_n##_get_##f_n (T_n *self) @@ -456,9 +708,19 @@ void g_property_init_default (GProperty *property, g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (self, t_n##_get_type ()), (f_t) 0); \ \ { \ - GObjectClass *_self_class; \ - _self_class = G_OBJECT_GET_CLASS (self); \ - g_property = (GProperty *) g_object_class_find_property (_self_class, #f_n); \ + const char *pname = g_property_canonicalize_name (#f_n); \ + int i; \ +\ + for (i = 1; i < t_n##_properties_len; i++) \ + { \ + GParamSpec *pspec = t_n##_properties[i]; \ + if (pspec != NULL && pspec->name == pname) \ + { \ + g_property = (GProperty *) pspec; \ + break; \ + } \ + } \ +\ if (G_UNLIKELY (g_property == NULL)) \ { \ g_critical (G_STRLOC ": No property " #f_n " found for class %s", \ @@ -466,18 +728,6 @@ void g_property_init_default (GProperty *property, return (f_t) 0; \ } \ } \ -\ - if (!G_IS_PROPERTY (g_property)) \ - { \ - g_critical (G_STRLOC ": Property " #f_n " is not a GProperty"); \ - return (f_t) 0; \ - } \ -\ - if (!g_property_is_readable (g_property)) \ - { \ - g_critical (G_STRLOC ": The property " #f_n " is not readable"); \ - return (f_t) 0; \ - } \ \ if (!g_property_get (g_property, self, &retval)) \ { \ @@ -501,27 +751,25 @@ void g_property_init_default (GProperty *property, g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (self, t_n##_get_type ())); \ \ { \ - GObjectClass *_self_class; \ - _self_class = G_OBJECT_GET_CLASS (self); \ - g_property = (GProperty *) g_object_class_find_property (_self_class, #f_n); \ + const char *pname = g_property_canonicalize_name (#f_n); \ + int i; \ +\ + for (i = 1; i < t_n##_properties_len; i++) \ + { \ + GParamSpec *pspec = t_n##_properties[i]; \ + if (pspec != NULL && pspec->name == pname) \ + { \ + g_property = (GProperty *) pspec; \ + break; \ + } \ + } \ +\ if (G_UNLIKELY (g_property == NULL)) \ { \ g_critical (G_STRLOC ": No property " #f_n " found for class %s", G_OBJECT_TYPE_NAME (self)); \ return; \ } \ } \ -\ - if (!G_IS_PROPERTY (g_property)) \ - { \ - g_critical (G_STRLOC ": Property " #f_n " is not a GProperty"); \ - return; \ - } \ -\ - if (!g_property_is_writable (g_property)) \ - { \ - g_critical (G_STRLOC ": The property " #f_n " is not writable"); \ - return; \ - } \ \ if (!g_property_set (g_property, self, value)) \ return; \ @@ -590,9 +838,8 @@ _G_DECLARE_PROPERTY_GETTER (T_n, t_n, f_t, f_n); * @_C_: C code that should be called after the property has been set * * Defines the setter function for a @field_name property in the - * class @TypeName, with the possibility of calling custom code. - * - * This macro should only be used in C source files. + * class @TypeName, with the possibility of calling custom code, for + * instance: * * |[ * G_DEFINE_PROPERTY_SET_WITH_CODE (ClutterActor, clutter_actor, @@ -633,10 +880,16 @@ _G_DEFINE_PROPERTY_SETTER_END * class @T_n, with the possibility of calling custom code. * * This macro will directly access the field on the private - * data structure. + * data structure, and should only be used if the property + * has been defined to use an offset instead of an explicit + * getter. Use G_DEFINE_PROPERTY_COMPUTED_GET_WITH_CODE() if + * you have an internal getter function. * * This macro should only be used in C source files. * + * Note that this macro should be used with types defined using G_DEFINE_TYPE_* + * macros, as it depends on variables and functions defined by those macros. + * * Since: 2.38 */ #define G_DEFINE_PROPERTY_GET_WITH_CODE(T_n, t_n, f_t, f_n, _C_) \ @@ -662,6 +915,9 @@ _G_DEFINE_PROPERTY_GETTER_END * * This macro should only be used in C source files. * + * Note that this macro should be used with types defined using G_DEFINE_TYPE_* + * macros, as it depends on variables and functions defined by those macros. + * * Since: 2.38 */ #define G_DEFINE_PROPERTY_INDIRECT_GET_WITH_CODE(T_n, t_n, f_t, f_n, _C_) \ @@ -682,6 +938,9 @@ _G_DEFINE_PROPERTY_GETTER_END * Defines the setter function for a @field_name property in the * class @TypeName. This macro should only be used in C source files. * + * Note that this macro should be used with types defined using G_DEFINE_TYPE_* + * macros, as it depends on variables and functions defined by those macros. + * * See also: %G_DEFINE_PROPERTY_SET_WITH_CODE * * Since: 2.38 @@ -700,6 +959,9 @@ _G_DEFINE_PROPERTY_GETTER_END * Defines the getter function for a @field_name property in the * class @TypeName. This macro should only be used in C source files. * + * Note that this macro should be used with types defined using G_DEFINE_TYPE_* + * macros, as it depends on variables and functions defined by those macros. + * * See also %G_DEFINE_PROPERTY_GET_WITH_CODE. * * Since: 2.38 @@ -718,6 +980,9 @@ _G_DEFINE_PROPERTY_GETTER_END * Defines the getter function for a @field_name property in the * class @TypeName. This macro should only be used in C source files. * + * Note that this macro should be used with types defined using G_DEFINE_TYPE_* + * macros, as it depends on variables and functions defined by those macros. + * * See also %G_DEFINE_PROPERTY_COMPUTED_GET_WITH_CODE. * * Since: 2.38 @@ -754,17 +1019,19 @@ _G_DEFINE_PROPERTY_GETTER_END * * priv = clutter_actor_get_instance_private (self); * - * if (priv->margin_top == value) - * return; + * if (priv->margin_top != value) + * { + * priv->value = value; * - * priv->value = value; - * - * g_object_notify (G_OBJECT (self), "margin-top"); + * g_object_notify (G_OBJECT (self), "margin-top"); + * } * } * * int * clutter_actor_get_margin_top (ClutterActor *self) * { + * ClutterActorPrivate *priv; + * * g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (self, clutter_actor_get_type ()), 0); * * priv = clutter_actor_get_instance_private (self); @@ -782,6 +1049,10 @@ _G_DEFINE_PROPERTY_GETTER_END * %G_DEFINE_PROPERTY_GET_WITH_CODE and %G_DEFINE_PROPERTY_SET_WITH_CODE * variants. * + * Note that this macro should only be used with types defined using + * G_DEFINE_TYPE_* macros, as it depends on variable and functions defined + * by those macros. + * * Since: 2.38 */ #define G_DEFINE_PROPERTY_GET_SET(T_n, t_n, f_t, f_n) \ diff --git a/gobject/gtype.h b/gobject/gtype.h index 282789676..75686da83 100644 --- a/gobject/gtype.h +++ b/gobject/gtype.h @@ -1661,10 +1661,12 @@ static void type_name##_class_intern_init (gpointer klass) \ #define _G_DEFINE_TYPE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PARENT, flags) \ \ -static void type_name##_init (TypeName *self); \ -static void type_name##_class_init (TypeName##Class *klass); \ -static gpointer type_name##_parent_class = NULL; \ -static gint TypeName##_private_offset; \ +static void type_name##_init (TypeName *self); \ +static void type_name##_class_init (TypeName##Class *klass); \ +static gpointer type_name##_parent_class = NULL; \ +static gint TypeName##_private_offset; \ +static GParamSpec **type_name##_properties G_GNUC_UNUSED; \ +static guint type_name##_properties_len G_GNUC_UNUSED; \ \ _G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \ \ diff --git a/gobject/tests/property.c b/gobject/tests/property.c index 64a1fe503..0f4f57f0b 100644 --- a/gobject/tests/property.c +++ b/gobject/tests/property.c @@ -5,10 +5,11 @@ typedef struct _TestObjectPrivate TestObjectPrivate; typedef struct _TestObjectClass TestObjectClass; typedef enum { - TEST_ENUM_UNSET, TEST_ENUM_ONE, TEST_ENUM_TWO, - TEST_ENUM_THREE + TEST_ENUM_THREE, + + TEST_ENUM_UNSET = -1 } TestEnum; struct _TestObject @@ -27,14 +28,17 @@ struct _TestObjectPrivate double double_val; - char *str_val; + char *string_val; gboolean bool_val; TestEnum enum_val; - guint enum_val_set : 1; + gboolean enum_val_set; guint8 with_default; + + float width; + float height; }; GType test_enum_get_type (void); @@ -64,28 +68,12 @@ test_enum_get_type (void) G_DEFINE_TYPE_WITH_PRIVATE (TestObject, test_object, G_TYPE_OBJECT) -enum -{ - PROP_0, - - PROP_INTEGER_VAL, - PROP_DOUBLE_VAL, - PROP_STRING_VAL, - PROP_BOOL_VAL, - PROP_ENUM_VAL, - PROP_WITH_DEFAULT, - - LAST_PROP -}; - -static GParamSpec *test_object_properties[LAST_PROP] = { NULL, }; - static void test_object_finalize (GObject *gobject) { TestObjectPrivate *priv = test_object_get_instance_private ((TestObject *) gobject); - g_free (priv->str_val); + g_free (priv->string_val); if (priv->enum_val != TEST_ENUM_UNSET) g_assert (priv->enum_val_set); @@ -94,8 +82,8 @@ test_object_finalize (GObject *gobject) } static gboolean -test_object_set_enum_val (gpointer obj, - gint val) +test_object_set_enum_val_internal (gpointer obj, + gint val) { TestObjectPrivate *priv = test_object_get_instance_private (obj); @@ -126,60 +114,73 @@ test_object_class_init (TestObjectClass *klass) gobject_class->constructed = test_object_constructed; gobject_class->finalize = test_object_finalize; - test_object_properties[PROP_INTEGER_VAL] = - g_int_property_new ("integer-val", - G_PROPERTY_READWRITE, - G_STRUCT_OFFSET (TestObjectPrivate, integer_val), - NULL, NULL); - - test_object_properties[PROP_DOUBLE_VAL] = - g_double_property_new ("double-val", - G_PROPERTY_READWRITE, - G_STRUCT_OFFSET (TestObjectPrivate, double_val), - NULL, NULL); - - test_object_properties[PROP_STRING_VAL] = - g_string_property_new ("string-val", - G_PROPERTY_READWRITE | G_PROPERTY_COPY_SET, - G_STRUCT_OFFSET (TestObjectPrivate, str_val), - NULL, NULL); - - test_object_properties[PROP_BOOL_VAL] = - g_boolean_property_new ("bool-val", - G_PROPERTY_READWRITE, - G_STRUCT_OFFSET (TestObjectPrivate, bool_val), - NULL, NULL); - - test_object_properties[PROP_ENUM_VAL] = - g_enum_property_new ("enum-val", - G_PROPERTY_READWRITE, - G_STRUCT_OFFSET (TestObjectPrivate, enum_val), - test_object_set_enum_val, - NULL); - g_property_set_prerequisite ((GProperty *) test_object_properties[PROP_ENUM_VAL], - test_enum_get_type ()); - g_property_set_default ((GProperty *) test_object_properties[PROP_ENUM_VAL], - TEST_ENUM_UNSET); - - test_object_properties[PROP_WITH_DEFAULT] = - g_uint8_property_new ("with-default", - G_PROPERTY_READWRITE, - G_STRUCT_OFFSET (TestObjectPrivate, with_default), - NULL, - NULL); - g_property_set_default ((GProperty *) test_object_properties[PROP_WITH_DEFAULT], 255); - - g_object_class_install_properties (gobject_class, LAST_PROP, test_object_properties); + G_DEFINE_PROPERTIES (TestObject, test_object, klass, + G_DEFINE_PROPERTY (TestObject, + int, + integer_val, + G_PROPERTY_READWRITE) + G_DEFINE_PROPERTY (TestObject, + double, + double_val, + G_PROPERTY_READWRITE) + G_DEFINE_PROPERTY (TestObject, + string, + string_val, + G_PROPERTY_READWRITE | G_PROPERTY_COPY_SET) + G_DEFINE_PROPERTY (TestObject, + boolean, + bool_val, + G_PROPERTY_READWRITE) + G_DEFINE_PROPERTY (TestObject, + float, + width, + G_PROPERTY_READWRITE) + G_DEFINE_PROPERTY (TestObject, + float, + height, + G_PROPERTY_READWRITE) + G_DEFINE_PROPERTY_EXTENDED (TestObject, + enum, + enum_val, + G_STRUCT_OFFSET (TestObjectPrivate, enum_val), + test_object_set_enum_val_internal, + NULL, + G_PROPERTY_READWRITE, + G_PROPERTY_DEFAULT (TEST_ENUM_UNSET) + g_property_set_prerequisite (g_property, test_enum_get_type ());) + G_DEFINE_PROPERTY (TestObject, + boolean, + enum_val_set, + G_PROPERTY_READABLE); + G_DEFINE_PROPERTY_WITH_CODE (TestObject, + uint8, + with_default, + G_PROPERTY_READWRITE, + G_PROPERTY_DEFAULT (255) + G_PROPERTY_DESCRIBE ("With Default", + "A property with a default value"))) } static void test_object_init (TestObject *self) { + TestObjectPrivate *priv = test_object_get_private (self); + + g_assert (priv->enum_val == TEST_ENUM_UNSET); + g_assert (!priv->enum_val_set); } G_DECLARE_PROPERTY_GET_SET (TestObject, test_object, gboolean, bool_val) +G_DECLARE_PROPERTY_GET_SET (TestObject, test_object, float, width) +G_DECLARE_PROPERTY_GET_SET (TestObject, test_object, float, height) +G_DECLARE_PROPERTY_GET_SET (TestObject, test_object, TestEnum, enum_val) +G_DECLARE_PROPERTY_GET (TestObject, test_object, gboolean, enum_val_set) G_DEFINE_PROPERTY_GET_SET (TestObject, test_object, gboolean, bool_val) +G_DEFINE_PROPERTY_GET_SET (TestObject, test_object, float, width) +G_DEFINE_PROPERTY_GET_SET (TestObject, test_object, float, height) +G_DEFINE_PROPERTY_GET_SET (TestObject, test_object, TestEnum, enum_val) +G_DEFINE_PROPERTY_INDIRECT_GET (TestObject, test_object, gboolean, enum_val_set) /* test units start here */ @@ -206,7 +207,7 @@ gproperty_construct (void) g_assert_cmpint (priv->integer_val, ==, 42); g_assert (priv->bool_val); - g_assert_cmpstr (priv->str_val, ==, "Hello, world"); + g_assert_cmpstr (priv->string_val, ==, "Hello, world"); g_assert_cmpfloat ((float) priv->double_val, ==, 3.14159f); g_object_unref (obj); @@ -223,14 +224,14 @@ gproperty_object_set (void) g_signal_connect (obj, "notify::string-val", G_CALLBACK (check_notify_emission), &did_emit_notify); g_object_set (obj, "string-val", "Hello!", NULL); - g_assert_cmpstr (priv->str_val, ==, "Hello!"); + g_assert_cmpstr (priv->string_val, ==, "Hello!"); g_assert (did_emit_notify); did_emit_notify = FALSE; g_object_set (obj, "string-val", "Hello!", NULL); - g_assert_cmpstr (priv->str_val, ==, "Hello!"); + g_assert_cmpstr (priv->string_val, ==, "Hello!"); g_assert (!did_emit_notify); @@ -264,23 +265,18 @@ gproperty_explicit_set (void) gboolean did_emit_notify = FALSE; TestEnum enum_val; - TestObjectPrivate *priv = - g_type_instance_get_private ((GTypeInstance *) obj, test_object_get_type ()); - g_signal_connect (obj, "notify::enum-val", G_CALLBACK (check_notify_emission), &did_emit_notify); g_object_set (obj, "enum-val", TEST_ENUM_THREE, NULL); - g_assert_cmpint (priv->enum_val, ==, TEST_ENUM_THREE); - g_assert (priv->enum_val_set); - + g_assert_cmpint (test_object_get_enum_val (obj), ==, TEST_ENUM_THREE); + g_assert (test_object_get_enum_val_set (obj)); g_assert (did_emit_notify); did_emit_notify = FALSE; - g_object_set (obj, "enum-val", TEST_ENUM_THREE, NULL); - g_assert (!did_emit_notify); - + test_object_set_enum_val (obj, TEST_ENUM_THREE); g_object_get (obj, "enum-val", &enum_val, NULL); g_assert_cmpint (enum_val, ==, TEST_ENUM_THREE); + g_assert (!did_emit_notify); g_object_unref (obj); }