(root)/
glib-2.79.0/
gobject/
tests/
properties-refcount4.c
       1  #include <glib.h>
       2  #include <glib-object.h>
       3  
       4  #define MY_TYPE_BADGER              (my_badger_get_type ())
       5  #define MY_BADGER(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), MY_TYPE_BADGER, MyBadger))
       6  #define MY_IS_BADGER(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MY_TYPE_BADGER))
       7  #define MY_BADGER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MY_TYPE_BADGER, MyBadgerClass))
       8  #define MY_IS_BADGER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MY_TYPE_BADGER))
       9  #define MY_BADGER_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MY_TYPE_BADGER, MyBadgerClass))
      10  
      11  enum {
      12    PROP_0,
      13    PROP_MAMA
      14  };
      15  
      16  typedef struct _MyBadger MyBadger;
      17  typedef struct _MyBadgerClass MyBadgerClass;
      18  
      19  struct _MyBadger
      20  {
      21    GObject parent_instance;
      22  
      23    MyBadger * mama;
      24    guint mama_notify_count;
      25  };
      26  
      27  struct _MyBadgerClass
      28  {
      29    GObjectClass parent_class;
      30  };
      31  
      32  static GType my_badger_get_type (void);
      33  G_DEFINE_TYPE (MyBadger, my_badger, G_TYPE_OBJECT)
      34  
      35  static void my_badger_dispose (GObject * object);
      36  
      37  static void my_badger_get_property (GObject    *object,
      38  				    guint       prop_id,
      39  				    GValue     *value,
      40  				    GParamSpec *pspec);
      41  static void my_badger_set_property (GObject      *object,
      42  				    guint         prop_id,
      43  				    const GValue *value,
      44  				    GParamSpec   *pspec);
      45  
      46  static void my_badger_mama_notify (GObject    *object,
      47  				   GParamSpec *pspec);
      48  
      49  static void
      50  my_badger_class_init (MyBadgerClass * klass)
      51  {
      52    GObjectClass *gobject_class;
      53  
      54    gobject_class = (GObjectClass *) klass;
      55  
      56    gobject_class->dispose = my_badger_dispose;
      57  
      58    gobject_class->get_property = my_badger_get_property;
      59    gobject_class->set_property = my_badger_set_property;
      60  
      61    g_object_class_install_property (gobject_class,
      62  				   PROP_MAMA,
      63  				   g_param_spec_object ("mama",
      64  							NULL,
      65  							NULL,
      66  							MY_TYPE_BADGER,
      67  							G_PARAM_READWRITE));
      68  }
      69  
      70  static void
      71  my_badger_init (MyBadger * self)
      72  {
      73    g_signal_connect (self, "notify::mama", G_CALLBACK (my_badger_mama_notify),
      74        NULL);
      75  }
      76  
      77  static void
      78  my_badger_dispose (GObject * object)
      79  {
      80    MyBadger * self;
      81  
      82    self = MY_BADGER (object);
      83  
      84    if (self->mama != NULL)
      85      {
      86        g_object_unref (self->mama);
      87        self->mama = NULL;
      88      }
      89  
      90    G_OBJECT_CLASS (my_badger_parent_class)->dispose (object);
      91  }
      92  
      93  static void
      94  my_badger_get_property (GObject    *object,
      95  			guint        prop_id,
      96  			GValue     *value,
      97  			GParamSpec *pspec)
      98  {
      99    MyBadger *self;
     100  
     101    self = MY_BADGER (object);
     102  
     103    switch (prop_id)
     104      {
     105      case PROP_MAMA:
     106        g_value_set_object (value, self->mama);
     107        break;
     108      default:
     109        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     110        break;
     111      }
     112  }
     113  
     114  static void
     115  my_badger_set_property (GObject      *object,
     116  			guint         prop_id,
     117  			const GValue *value,
     118  			GParamSpec   *pspec)
     119  {
     120    MyBadger *self;
     121  
     122    self = MY_BADGER (object);
     123  
     124    switch (prop_id)
     125      {
     126      case PROP_MAMA:
     127        if (self->mama)
     128  	g_object_unref (self->mama);
     129        self->mama = g_value_dup_object (value);
     130        if (self->mama)
     131  	g_object_set (self->mama, "mama", NULL, NULL); /* another notify */
     132        break;
     133      default:
     134        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     135        break;
     136      }
     137  }
     138  
     139  static void
     140  my_badger_mama_notify (GObject    *object,
     141                         GParamSpec *pspec)
     142  {
     143    MyBadger *self;
     144  
     145    self = MY_BADGER (object);
     146    self->mama_notify_count++;
     147  }
     148  
     149  static void
     150  test_refcount_properties_4 (void)
     151  {
     152    MyBadger * badger1, * badger2;
     153    gpointer test;
     154  
     155    badger1 = g_object_new (MY_TYPE_BADGER, NULL);
     156    badger2 = g_object_new (MY_TYPE_BADGER, NULL);
     157  
     158    g_object_set (badger1, "mama", badger2, NULL);
     159    g_assert_cmpuint (badger1->mama_notify_count, ==, 1);
     160    g_assert_cmpuint (badger2->mama_notify_count, ==, 1);
     161    g_object_get (badger1, "mama", &test, NULL);
     162    g_assert_cmpmem (test, sizeof (MyBadger), badger2, sizeof (MyBadger));
     163    g_object_unref (test);
     164  
     165    g_object_unref (badger1);
     166    g_object_unref (badger2);
     167  }
     168  
     169  int
     170  main (int argc, gchar *argv[])
     171  {
     172    g_log_set_always_fatal (G_LOG_LEVEL_WARNING |
     173                            G_LOG_LEVEL_CRITICAL |
     174                            g_log_set_always_fatal (G_LOG_FATAL_MASK));
     175  
     176    g_test_init (&argc, &argv, NULL);
     177  
     178    g_test_add_func ("/gobject/refcount/properties-4", test_refcount_properties_4);
     179  
     180    return g_test_run ();
     181  }