source: trunk/third/glib2/gobject/testgobject.c @ 20721

Revision 20721, 13.3 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20720, which included commits to RCS files with non-trunk default branches.
Line 
1/* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 2001 Red Hat, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20#include <string.h>
21
22#undef  G_LOG_DOMAIN
23#define G_LOG_DOMAIN "TestObject"
24#include        <glib-object.h>
25
26/* --- TestIface --- */
27#define TEST_TYPE_IFACE           (test_iface_get_type ())
28#define TEST_IFACE(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_IFACE, TestIface))
29#define TEST_IS_IFACE(obj)        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_IFACE))
30#define TEST_IFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE, TestIfaceClass))
31typedef struct _TestIface      TestIface;
32typedef struct _TestIfaceClass TestIfaceClass;
33struct _TestIfaceClass
34{
35  GTypeInterface base_iface;
36  void  (*print_string) (TestIface      *tiobj,
37                         const gchar    *string);
38};
39static void     iface_base_init         (TestIfaceClass *iface);
40static void     iface_base_finalize     (TestIfaceClass *iface);
41static void     print_foo               (TestIface      *tiobj,
42                                         const gchar    *string);
43GType
44test_iface_get_type (void)
45{
46  static GType test_iface_type = 0;
47
48  if (!test_iface_type)
49    {
50      static const GTypeInfo test_iface_info =
51      {
52        sizeof (TestIfaceClass),
53        (GBaseInitFunc) iface_base_init,                /* base_init */
54        (GBaseFinalizeFunc) iface_base_finalize,        /* base_finalize */
55      };
56
57      test_iface_type = g_type_register_static (G_TYPE_INTERFACE, "TestIface", &test_iface_info, 0);
58      g_type_interface_add_prerequisite (test_iface_type, G_TYPE_OBJECT);
59    }
60
61  return test_iface_type;
62}
63static guint iface_base_init_count = 0;
64static void
65iface_base_init (TestIfaceClass *iface)
66{
67  iface_base_init_count++;
68  if (iface_base_init_count == 1)
69    {
70      /* add signals here */
71    }
72}
73static void
74iface_base_finalize (TestIfaceClass *iface)
75{
76  iface_base_init_count--;
77  if (iface_base_init_count == 0)
78    {
79      /* destroy signals here */
80    }
81}
82static void
83print_foo (TestIface   *tiobj,
84           const gchar *string)
85{
86  if (!string)
87    string = "<NULL>";
88  g_print ("Iface-FOO: \"%s\" from %p\n", string, tiobj);
89}
90static void
91test_object_test_iface_init (gpointer giface,
92                             gpointer iface_data)
93{
94  TestIfaceClass *iface = giface;
95
96  g_assert (iface_data == GUINT_TO_POINTER (42));
97
98  g_assert (G_TYPE_FROM_INTERFACE (iface) == TEST_TYPE_IFACE);
99
100  /* assert iface_base_init() was already called */
101  g_assert (iface_base_init_count > 0);
102
103  /* initialize stuff */
104  iface->print_string = print_foo;
105}
106void
107iface_print_string (TestIface   *tiobj,
108                    const gchar *string)
109{
110  TestIfaceClass *iface;
111
112  g_return_if_fail (TEST_IS_IFACE (tiobj));
113  g_return_if_fail (G_IS_OBJECT (tiobj)); /* ensured through prerequisite */
114
115  iface = TEST_IFACE_GET_CLASS (tiobj);
116  g_object_ref (tiobj);
117  iface->print_string (tiobj, string);
118  g_object_unref (tiobj);
119}
120
121
122/* --- TestObject --- */
123#define TEST_TYPE_OBJECT            (test_object_get_type ())
124#define TEST_OBJECT(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), TEST_TYPE_OBJECT, TestObject))
125#define TEST_OBJECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass))
126#define TEST_IS_OBJECT(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), TEST_TYPE_OBJECT))
127#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
128#define TEST_OBJECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
129#define TEST_OBJECT_GET_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), TEST_TYPE_OBJECT, TestObjectPrivate))
130typedef struct _TestObject        TestObject;
131typedef struct _TestObjectClass   TestObjectClass;
132typedef struct _TestObjectPrivate TestObjectPrivate;
133struct _TestObject
134{
135  GObject parent_instance;
136};
137struct _TestObjectClass
138{
139  GObjectClass parent_class;
140
141  gchar* (*test_signal) (TestObject *tobject,
142                         TestIface  *iface_object,
143                         gpointer    tdata);
144};
145struct _TestObjectPrivate
146{
147  int     dummy1;
148  gdouble dummy2;
149};
150static void     test_object_class_init  (TestObjectClass        *class);
151static void     test_object_init        (TestObject             *tobject);
152static gboolean test_signal_accumulator (GSignalInvocationHint  *ihint,
153                                         GValue                 *return_accu,
154                                         const GValue           *handler_return,
155                                         gpointer                data);
156static gchar*   test_object_test_signal (TestObject             *tobject,
157                                         TestIface              *iface_object,
158                                         gpointer                tdata);
159GType
160test_object_get_type (void)
161{
162  static GType test_object_type = 0;
163
164  if (!test_object_type)
165    {
166      static const GTypeInfo test_object_info =
167      {
168        sizeof (TestObjectClass),
169        NULL,           /* base_init */
170        NULL,           /* base_finalize */
171        (GClassInitFunc) test_object_class_init,
172        NULL,           /* class_finalize */
173        NULL,           /* class_data */
174        sizeof (TestObject),
175        5,              /* n_preallocs */
176        (GInstanceInitFunc) test_object_init,
177      };
178      GInterfaceInfo iface_info = { test_object_test_iface_init, NULL, GUINT_TO_POINTER (42) };
179
180      test_object_type = g_type_register_static (G_TYPE_OBJECT, "TestObject", &test_object_info, 0);
181      g_type_add_interface_static (test_object_type, TEST_TYPE_IFACE, &iface_info);
182    }
183
184  return test_object_type;
185}
186static void
187test_object_class_init (TestObjectClass *class)
188{
189  /*  GObjectClass *gobject_class = G_OBJECT_CLASS (class); */
190
191  class->test_signal = test_object_test_signal;
192
193  g_signal_new ("test-signal",
194                G_OBJECT_CLASS_TYPE (class),
195                G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP,
196                G_STRUCT_OFFSET (TestObjectClass, test_signal),
197                test_signal_accumulator, NULL,
198                g_cclosure_marshal_STRING__OBJECT_POINTER,
199                G_TYPE_STRING, 2, TEST_TYPE_IFACE, G_TYPE_POINTER);
200
201  g_type_class_add_private (class, sizeof (TestObjectPrivate));
202}
203static void
204test_object_init (TestObject *tobject)
205{
206  TestObjectPrivate *priv;
207
208  priv = TEST_OBJECT_GET_PRIVATE (tobject);
209
210  g_assert (priv);
211  g_assert ((gchar *)priv >= (gchar *)tobject + sizeof (TestObject));
212
213  priv->dummy1 = 54321;
214}
215/* Check to see if private data initialization in the
216 * instance init function works.
217 */
218static void
219test_object_check_private_init (TestObject *tobject)
220{
221  TestObjectPrivate *priv;
222
223  priv = TEST_OBJECT_GET_PRIVATE (tobject);
224
225  g_print ("private data during initialization: %u == %u\n", priv->dummy1, 54321);
226  g_assert (priv->dummy1 == 54321);
227}
228static gboolean
229test_signal_accumulator (GSignalInvocationHint *ihint,
230                         GValue                *return_accu,
231                         const GValue          *handler_return,
232                         gpointer               data)
233{
234  gchar *accu_string = g_value_get_string (return_accu);
235  gchar *new_string = g_value_get_string (handler_return);
236  gchar *result_string;
237
238  if (accu_string)
239    result_string = g_strconcat (accu_string, new_string, NULL);
240  else if (new_string)
241    result_string = g_strdup (new_string);
242  else
243    result_string = NULL;
244
245  g_value_take_string (return_accu, result_string);
246
247  return TRUE;
248}
249static gchar*
250test_object_test_signal (TestObject *tobject,
251                         TestIface  *iface_object,
252                         gpointer    tdata)
253{
254  g_message ("::test_signal default_handler called");
255
256  g_return_val_if_fail (TEST_IS_IFACE (iface_object), NULL);
257 
258  return g_strdup ("<default_handler>");
259}
260
261
262/* --- TestIface for DerivedObject --- */
263static void
264print_bar (TestIface   *tiobj,
265           const gchar *string)
266{
267  TestIfaceClass *parent_iface;
268
269  g_return_if_fail (TEST_IS_IFACE (tiobj));
270
271  if (!string)
272    string = "<NULL>";
273  g_print ("Iface-BAR: \"%s\" from %p\n", string, tiobj);
274
275  g_print ("chaining: ");
276  parent_iface = g_type_interface_peek_parent (TEST_IFACE_GET_CLASS (tiobj));
277  parent_iface->print_string (tiobj, string);
278
279  g_assert (g_type_interface_peek_parent (parent_iface) == NULL);
280}
281
282static void
283derived_object_test_iface_init (gpointer giface,
284                                gpointer iface_data)
285{
286  TestIfaceClass *iface = giface;
287
288  g_assert (iface_data == GUINT_TO_POINTER (87));
289
290  g_assert (G_TYPE_FROM_INTERFACE (iface) == TEST_TYPE_IFACE);
291
292  /* assert test_object_test_iface_init() was already called */
293  g_assert (iface->print_string == print_foo);
294
295  /* override stuff */
296  iface->print_string = print_bar;
297}
298
299
300/* --- DerivedObject --- */
301#define DERIVED_TYPE_OBJECT            (derived_object_get_type ())
302#define DERIVED_OBJECT(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), DERIVED_TYPE_OBJECT, DerivedObject))
303#define DERIVED_OBJECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), DERIVED_TYPE_OBJECT, DerivedObjectClass))
304#define DERIVED_IS_OBJECT(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), DERIVED_TYPE_OBJECT))
305#define DERIVED_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DERIVED_TYPE_OBJECT))
306#define DERIVED_OBJECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), DERIVED_TYPE_OBJECT, DerivedObjectClass))
307#define DERIVED_OBJECT_GET_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), DERIVED_TYPE_OBJECT, DerivedObjectPrivate))
308typedef struct _DerivedObject        DerivedObject;
309typedef struct _TestObjectClass      DerivedObjectClass;
310typedef struct _DerivedObjectPrivate DerivedObjectPrivate;
311struct _DerivedObject
312{
313  TestObject parent_instance;
314  int  dummy1;
315  int  dummy2;
316};
317struct _DerivedObjectPrivate
318{
319  char dummy;
320};
321static void derived_object_class_init (DerivedObjectClass *class);
322static void derived_object_init       (DerivedObject      *dobject);
323GType
324derived_object_get_type (void)
325{
326  static GType derived_object_type = 0;
327
328  if (!derived_object_type)
329    {
330      static const GTypeInfo derived_object_info =
331      {
332        sizeof (DerivedObjectClass),
333        NULL,           /* base_init */
334        NULL,           /* base_finalize */
335        (GClassInitFunc) derived_object_class_init,
336        NULL,           /* class_finalize */
337        NULL,           /* class_data */
338        sizeof (DerivedObject),
339        5,              /* n_preallocs */
340        (GInstanceInitFunc) derived_object_init,
341      };
342      GInterfaceInfo iface_info = { derived_object_test_iface_init, NULL, GUINT_TO_POINTER (87) };
343
344      derived_object_type = g_type_register_static (TEST_TYPE_OBJECT, "DerivedObject", &derived_object_info, 0);
345      g_type_add_interface_static (derived_object_type, TEST_TYPE_IFACE, &iface_info);
346    }
347
348  return derived_object_type;
349}
350static void
351derived_object_class_init (DerivedObjectClass *class)
352{
353  g_type_class_add_private (class, sizeof (DerivedObjectPrivate));
354}
355static void
356derived_object_init (DerivedObject *dobject)
357{
358  TestObjectPrivate *test_priv;
359  DerivedObjectPrivate *derived_priv;
360
361  derived_priv = DERIVED_OBJECT_GET_PRIVATE (dobject);
362
363  g_assert (derived_priv);
364  g_assert ((gchar *)derived_priv >= (gchar *)TEST_OBJECT_GET_PRIVATE (dobject) + sizeof (TestObjectPrivate));
365
366  test_priv = TEST_OBJECT_GET_PRIVATE (dobject);
367 
368  g_assert (test_priv);
369  g_assert ((gchar *)test_priv >= (gchar *)dobject + sizeof (TestObject));
370
371}
372
373/* --- main --- */
374int
375main (int   argc,
376      char *argv[])
377{
378  GTypeInfo info = { 0, };
379  GTypeFundamentalInfo finfo = { 0, };
380  GType type;
381  TestObject *sigarg;
382  DerivedObject *dobject;
383  TestObjectPrivate *priv;
384  gchar *string = NULL;
385
386  g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
387                          G_LOG_LEVEL_WARNING |
388                          G_LOG_LEVEL_CRITICAL);
389  g_type_init_with_debug_flags (G_TYPE_DEBUG_OBJECTS | G_TYPE_DEBUG_SIGNALS);
390
391  /* test new fundamentals */
392  g_assert (G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST) == g_type_fundamental_next ());
393  type = g_type_register_fundamental (g_type_fundamental_next (), "FooShadow1", &info, &finfo, 0);
394  g_assert (G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST + 1) == g_type_fundamental_next ());
395  type = g_type_register_fundamental (g_type_fundamental_next (), "FooShadow2", &info, &finfo, 0);
396  g_assert (G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST + 2) == g_type_fundamental_next ());
397  g_assert (g_type_from_name ("FooShadow1") == G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST));
398  g_assert (g_type_from_name ("FooShadow2") == G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST + 1));
399
400  /* to test past class initialization interface setups, create the class here */
401  g_type_class_ref (TEST_TYPE_OBJECT);
402
403  dobject = g_object_new (DERIVED_TYPE_OBJECT, NULL);
404  test_object_check_private_init (TEST_OBJECT (dobject));
405
406  sigarg = g_object_new (TEST_TYPE_OBJECT, NULL);
407
408  g_print ("MAIN: emit test-signal:\n");
409  g_signal_emit_by_name (dobject, "test-signal", sigarg, NULL, &string);
410  g_message ("signal return: \"%s\"", string);
411  g_assert (strcmp (string, "<default_handler><default_handler>") == 0);
412  g_free (string);
413
414  g_print ("MAIN: call iface print-string on test and derived object:\n");
415  iface_print_string (TEST_IFACE (sigarg), "iface-string-from-test-type");
416  iface_print_string (TEST_IFACE (dobject), "iface-string-from-derived-type");
417
418  priv = TEST_OBJECT_GET_PRIVATE (dobject);
419  g_print ("private data after initialization: %u == %u\n", priv->dummy1, 54321);
420  g_assert (priv->dummy1 == 54321);
421 
422  g_object_unref (sigarg);
423  g_object_unref (dobject);
424
425  g_message ("%s done", argv[0]);
426
427  return 0;
428}
Note: See TracBrowser for help on using the repository browser.