1#include <unistd.h>
2#include <glib.h>
3#include <glib-object.h>
4
5#define G_TYPE_TEST                (my_test_get_type ())
6#define MY_TEST(test)              (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest))
7#define MY_IS_TEST(test)           (G_TYPE_CHECK_INSTANCE_TYPE ((test), G_TYPE_TEST))
8#define MY_TEST_CLASS(tclass)      (G_TYPE_CHECK_CLASS_CAST ((tclass), G_TYPE_TEST, GTestClass))
9#define MY_IS_TEST_CLASS(tclass)   (G_TYPE_CHECK_CLASS_TYPE ((tclass), G_TYPE_TEST))
10#define MY_TEST_GET_CLASS(test)    (G_TYPE_INSTANCE_GET_CLASS ((test), G_TYPE_TEST, GTestClass))
11
12enum {
13  PROP_0,
14  PROP_DUMMY
15};
16
17typedef struct _GTest GTest;
18typedef struct _GTestClass GTestClass;
19
20struct _GTest
21{
22  GObject object;
23
24  gint dummy;
25};
26
27struct _GTestClass
28{
29  GObjectClass parent_class;
30};
31
32static GType my_test_get_type (void);
33
34static void my_test_class_init (GTestClass * klass);
35static void my_test_init (GTest * test);
36static void my_test_dispose (GObject * object);
37static void my_test_get_property (GObject    *object,
38                                  guint       prop_id,
39                                  GValue     *value,
40                                  GParamSpec *pspec);
41static void my_test_set_property (GObject      *object,
42                                  guint         prop_id,
43                                  const GValue *value,
44                                  GParamSpec   *pspec);
45
46static GObjectClass *parent_class = NULL;
47
48static GType
49my_test_get_type (void)
50{
51  static GType test_type = 0;
52
53  if (!test_type) {
54    static const GTypeInfo test_info = {
55      sizeof (GTestClass),
56      NULL,
57      NULL,
58      (GClassInitFunc) my_test_class_init,
59      NULL,
60      NULL,
61      sizeof (GTest),
62      0,
63      (GInstanceInitFunc) my_test_init,
64      NULL
65    };
66
67    test_type = g_type_register_static (G_TYPE_OBJECT, "GTest",
68        &test_info, 0);
69  }
70  return test_type;
71}
72
73static void
74my_test_class_init (GTestClass * klass)
75{
76  GObjectClass *gobject_class;
77
78  gobject_class = (GObjectClass *) klass;
79
80  parent_class = g_type_class_ref (G_TYPE_OBJECT);
81
82  gobject_class->dispose = my_test_dispose;
83  gobject_class->get_property = my_test_get_property;
84  gobject_class->set_property = my_test_set_property;
85
86  g_object_class_install_property (gobject_class,
87				   PROP_DUMMY,
88				   g_param_spec_int ("dummy",
89						     NULL,
90						     NULL,
91						     0, G_MAXINT, 0,
92						     G_PARAM_READWRITE));
93}
94
95static void
96my_test_init (GTest * test)
97{
98  g_print ("init %p\n", test);
99}
100
101static void
102my_test_dispose (GObject * object)
103{
104  GTest *test;
105
106  test = MY_TEST (object);
107
108  g_print ("dispose %p!\n", object);
109
110  G_OBJECT_CLASS (parent_class)->dispose (object);
111}
112
113static void
114my_test_get_property (GObject    *object,
115                      guint       prop_id,
116                      GValue     *value,
117                      GParamSpec *pspec)
118{
119  GTest *test;
120
121  test = MY_TEST (object);
122
123  switch (prop_id)
124    {
125    case PROP_DUMMY:
126      g_value_set_int (value, test->dummy);
127      break;
128    default:
129      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
130      break;
131    }
132}
133
134static void
135my_test_set_property (GObject      *object,
136                      guint         prop_id,
137                      const GValue *value,
138                      GParamSpec   *pspec)
139{
140  GTest *test;
141
142  test = MY_TEST (object);
143
144  switch (prop_id)
145    {
146    case PROP_DUMMY:
147      test->dummy = g_value_get_int (value);
148      break;
149    default:
150      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
151      break;
152    }
153}
154
155static gint count = 0;
156
157static void
158dummy_notify (GObject    *object,
159              GParamSpec *pspec)
160{
161  count++;
162  if (count % 10000 == 0)
163    g_print (".");
164}
165
166static void
167my_test_do_property (GTest * test)
168{
169  gint dummy;
170
171  g_object_get (test, "dummy", &dummy, NULL);
172  g_object_set (test, "dummy", dummy + 1, NULL);
173}
174
175int
176main (int argc, char **argv)
177{
178  gint i;
179  GTest *test;
180
181  g_thread_init (NULL);
182  g_print ("START: %s\n", argv[0]);
183  g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | g_log_set_always_fatal (G_LOG_FATAL_MASK));
184  g_type_init ();
185
186  test = g_object_new (G_TYPE_TEST, NULL);
187
188  g_signal_connect (test, "notify::dummy", G_CALLBACK (dummy_notify), NULL);
189
190  g_assert (count == test->dummy);
191
192  for (i=0; i<1000000; i++) {
193    my_test_do_property (test);
194  }
195
196  g_assert (count == test->dummy);
197
198  return 0;
199}
200