1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
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.
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.
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.
22 #include "gvaluecollector.h"
29 #define PARAM_SPEC_PARAM_ID(pspec) (GPOINTER_TO_UINT (g_param_spec_get_qdata ((pspec), quark_param_id)))
32 /* --- prototypes --- */
33 static void g_object_base_class_init (GObjectClass *class);
34 static void g_object_base_class_finalize (GObjectClass *class);
35 static void g_object_do_class_init (GObjectClass *class);
36 static void g_object_do_init (GObject *object);
37 static void g_object_do_queue_param_changed (GObject *object,
39 static void g_object_do_dispatch_param_changed (GObject *object,
41 static void g_object_last_unref (GObject *object);
42 static void g_object_do_shutdown (GObject *object);
43 static void g_object_do_finalize (GObject *object);
44 static void g_value_object_init (GValue *value);
45 static void g_value_object_free_value (GValue *value);
46 static void g_value_object_copy_value (const GValue *src_value,
48 static gchar* g_value_object_collect_value (GValue *value,
51 GTypeCValue *collect_value);
52 static gchar* g_value_object_lcopy_value (const GValue *value,
55 GTypeCValue *collect_value);
58 /* --- variables --- */
59 static GQuark quark_param_id = 0;
60 static GQuark quark_param_changed_queue = 0;
61 static GHashTable *param_spec_hash_table = NULL;
64 /* --- functions --- */
66 static guint debug_objects_count = 0;
67 static GHashTable *debug_objects_ht = NULL;
69 debug_objects_foreach (gpointer key,
73 GObject *object = value;
75 g_message ("[%p] stale %s\tref_count=%u",
77 G_OBJECT_TYPE_NAME (object),
81 debug_objects_atexit (void)
85 g_message ("stale GObjects: %u", debug_objects_count);
86 g_hash_table_foreach (debug_objects_ht, debug_objects_foreach, NULL);
92 g_object_type_init (void) /* sync with gtype.c */
94 static gboolean initialized = FALSE;
95 static const GTypeFundamentalInfo finfo = {
96 G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE,
98 static GTypeInfo info = {
99 sizeof (GObjectClass),
100 (GBaseInitFunc) g_object_base_class_init,
101 (GBaseFinalizeFunc) g_object_base_class_finalize,
102 (GClassInitFunc) g_object_do_class_init,
103 NULL /* class_destroy */,
104 NULL /* class_data */,
107 (GInstanceInitFunc) g_object_do_init,
108 NULL, /* value_table */
110 static const GTypeValueTable value_table = {
111 g_value_object_init, /* value_init */
112 g_value_object_free_value, /* value_free */
113 g_value_object_copy_value, /* value_copy */
114 G_VALUE_COLLECT_POINTER, /* collect_type */
115 g_value_object_collect_value, /* collect_value */
116 G_VALUE_COLLECT_POINTER, /* lcopy_type */
117 g_value_object_lcopy_value, /* lcopy_value */
121 g_return_if_fail (initialized == FALSE);
126 info.value_table = &value_table;
127 type = g_type_register_fundamental (G_TYPE_OBJECT, "GObject", &info, &finfo);
128 g_assert (type == G_TYPE_OBJECT);
131 g_atexit (debug_objects_atexit);
136 g_object_base_class_init (GObjectClass *class)
138 /* reset instance specific fields and methods that don't get inherited */
139 class->n_param_specs = 0;
140 class->param_specs = NULL;
141 class->get_param = NULL;
142 class->set_param = NULL;
146 g_object_base_class_finalize (GObjectClass *class)
150 g_message ("finallizing base class of %s", G_OBJECT_CLASS_NAME (class));
152 for (i = 0; i < class->n_param_specs; i++)
154 GParamSpec *pspec = class->param_specs[i];
156 g_param_spec_hash_table_remove (param_spec_hash_table, pspec);
157 g_param_spec_set_qdata (pspec, quark_param_id, NULL);
158 g_param_spec_unref (pspec);
160 class->n_param_specs = 0;
161 g_free (class->param_specs);
162 class->param_specs = NULL;
166 g_object_do_class_init (GObjectClass *class)
168 quark_param_id = g_quark_from_static_string ("glib-object-param-id");
169 quark_param_changed_queue = g_quark_from_static_string ("glib-object-param-changed-queue");
170 param_spec_hash_table = g_param_spec_hash_table_new ();
172 class->queue_param_changed = g_object_do_queue_param_changed;
173 class->dispatch_param_changed = g_object_do_dispatch_param_changed;
174 class->shutdown = g_object_do_shutdown;
175 class->finalize = g_object_do_finalize;
179 g_object_class_install_param (GObjectClass *class,
181 GParamSpec *pspec /* 1 ref_count taken over */)
185 g_return_if_fail (G_IS_OBJECT_CLASS (class));
186 g_return_if_fail (G_IS_PARAM_SPEC (pspec));
187 if (pspec->flags & G_PARAM_WRITABLE)
188 g_return_if_fail (class->set_param != NULL);
189 if (pspec->flags & G_PARAM_READABLE)
190 g_return_if_fail (class->get_param != NULL);
191 g_return_if_fail (param_id > 0);
192 g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0); /* paranoid */
194 /* expensive paranoia checks ;( */
195 for (i = 0; i < class->n_param_specs; i++)
196 if (PARAM_SPEC_PARAM_ID (class->param_specs[i]) == param_id)
198 g_warning (G_STRLOC ": class `%s' already contains a parameter `%s' with id %u, "
199 "cannot install parameter `%s'",
200 G_OBJECT_CLASS_NAME (class),
201 class->param_specs[i]->name,
206 if (g_object_class_find_param_spec (class, pspec->name))
208 g_warning (G_STRLOC ": class `%s' already contains a parameter named `%s'",
209 G_OBJECT_CLASS_NAME (class),
214 g_param_spec_set_qdata (pspec, quark_param_id, GUINT_TO_POINTER (param_id));
215 g_param_spec_hash_table_insert (param_spec_hash_table, pspec, G_OBJECT_CLASS_TYPE (class));
216 i = class->n_param_specs++;
217 class->param_specs = g_renew (GParamSpec*, class->param_specs, class->n_param_specs);
218 class->param_specs[i] = pspec;
222 g_object_class_find_param_spec (GObjectClass *class,
223 const gchar *param_name)
225 g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL);
226 g_return_val_if_fail (param_name != NULL, NULL);
228 return g_param_spec_hash_table_lookup (param_spec_hash_table,
230 G_OBJECT_CLASS_TYPE (class),
235 g_object_do_init (GObject *object)
237 object->ref_count = 1;
238 object->qdata = NULL;
241 if (!debug_objects_ht)
242 debug_objects_ht = g_hash_table_new (g_direct_hash, NULL);
243 debug_objects_count++;
244 g_hash_table_insert (debug_objects_ht, object, object);
249 g_object_last_unref (GObject *object)
251 g_return_if_fail (object->ref_count > 0);
253 if (object->ref_count == 1) /* may have been re-referenced meanwhile */
254 G_OBJECT_GET_CLASS (object)->shutdown (object);
256 object->ref_count -= 1;
258 if (object->ref_count == 0) /* may have been re-referenced meanwhile */
259 G_OBJECT_GET_CLASS (object)->finalize (object);
263 g_object_do_shutdown (GObject *object)
265 /* this function needs to be always present for unconditional
266 * chaining, we also might add some code here later.
267 * beware though, subclasses may invoke shutdown() arbitrarily.
272 g_object_do_finalize (GObject *object)
274 g_datalist_clear (&object->qdata);
277 g_assert (g_hash_table_lookup (debug_objects_ht, object) == object);
279 g_hash_table_remove (debug_objects_ht, object);
280 debug_objects_count--;
283 g_type_free_instance ((GTypeInstance*) object);
287 g_object_new (GType object_type,
288 const gchar *first_param_name,
294 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
296 va_start (var_args, first_param_name);
297 object = g_object_new_valist (object_type, first_param_name, var_args);
304 g_object_new_valist (GType object_type,
305 const gchar *first_param_name,
310 g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
312 object = (GObject*) g_type_create_instance (object_type);
313 if (first_param_name)
314 g_object_set_valist (object, first_param_name, var_args);
320 g_object_do_dispatch_param_changed (GObject *object,
323 g_message ("NOTIFICATION: parameter `%s' changed on object `%s'",
325 G_OBJECT_TYPE_NAME (object));
329 notify_param_changed_handler (gpointer data)
335 /* FIXME: need GDK_THREADS lock */
337 object = G_OBJECT (data);
338 class = G_OBJECT_GET_CLASS (object);
339 slist = g_datalist_id_get_data (&object->qdata, quark_param_changed_queue);
341 /* a reference count is still being held */
343 for (; slist; slist = slist->next)
346 GParamSpec *pspec = slist->data;
349 class->dispatch_param_changed (object, pspec);
352 g_datalist_id_set_data (&object->qdata, quark_param_changed_queue, NULL);
358 g_object_do_queue_param_changed (GObject *object,
361 GSList *slist, *last = NULL;
363 /* if this is a recursive call on this object (i.e. pspecs are queued
364 * for notification, while param_changed notification is currently in
365 * progress), we simply add them to the queue that is currently being
366 * dispatched. otherwise, we later dispatch parameter changed notification
367 * asyncronously from an idle handler untill the queue is completely empty.
370 slist = g_datalist_id_get_data (&object->qdata, quark_param_changed_queue);
371 for (; slist; last = slist, slist = last->next)
372 if (slist->data == pspec)
377 g_object_ref (object);
378 g_idle_add_full (G_NOTIFY_PRIORITY,
379 notify_param_changed_handler,
381 (GDestroyNotify) g_object_unref);
382 g_object_set_qdata_full (object,
383 quark_param_changed_queue,
384 g_slist_prepend (NULL, pspec),
385 (GDestroyNotify) g_slist_free);
388 last->next = g_slist_prepend (NULL, pspec);
392 object_get_param (GObject *object,
395 const gchar *trailer)
399 g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */
401 class = g_type_class_peek (pspec->owner_type);
403 class->get_param (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
407 object_set_param (GObject *object,
410 const gchar *trailer)
414 g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */
416 class = g_type_class_peek (pspec->owner_type);
418 class->set_param (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer);
420 class->queue_param_changed (object, pspec);
424 g_object_set_valist (GObject *object,
425 const gchar *first_param_name,
430 g_return_if_fail (G_IS_OBJECT (object));
432 g_object_ref (object);
434 name = first_param_name;
438 const gchar *trailer = NULL;
439 GValue value = { 0, };
443 pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
445 G_OBJECT_TYPE (object),
450 g_warning ("%s: object class `%s' has no parameter named `%s'",
452 G_OBJECT_TYPE_NAME (object),
456 if (!(pspec->flags & G_PARAM_WRITABLE))
458 g_warning ("%s: parameter `%s' of object class `%s' is not writable",
461 G_OBJECT_TYPE_NAME (object));
465 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
467 G_VALUE_COLLECT (&value, var_args, &error);
470 g_warning ("%s: %s", G_STRLOC, error);
473 /* we purposely leak the value here, it might not be
474 * in a sane state if an error condition occoured
479 object_set_param (object, &value, pspec, trailer);
481 g_value_unset (&value);
483 name = va_arg (var_args, gchar*);
486 g_object_unref (object);
490 g_object_get_valist (GObject *object,
491 const gchar *first_param_name,
496 g_return_if_fail (G_IS_OBJECT (object));
498 g_object_ref (object);
500 name = first_param_name;
504 const gchar *trailer = NULL;
505 GValue value = { 0, };
509 pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
511 G_OBJECT_TYPE (object),
516 g_warning ("%s: object class `%s' has no parameter named `%s'",
518 G_OBJECT_TYPE_NAME (object),
522 if (!(pspec->flags & G_PARAM_READABLE))
524 g_warning ("%s: parameter `%s' of object class `%s' is not readable",
527 G_OBJECT_TYPE_NAME (object));
531 g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
533 object_get_param (object, &value, pspec, trailer);
535 G_VALUE_LCOPY (&value, var_args, &error);
538 g_warning ("%s: %s", G_STRLOC, error);
541 /* we purposely leak the value here, it might not be
542 * in a sane state if an error condition occoured
547 g_value_unset (&value);
549 name = va_arg (var_args, gchar*);
552 g_object_unref (object);
556 g_object_set (GObject *object,
557 const gchar *first_param_name,
562 g_return_if_fail (G_IS_OBJECT (object));
564 va_start (var_args, first_param_name);
565 g_object_set_valist (object, first_param_name, var_args);
570 g_object_get (GObject *object,
571 const gchar *first_param_name,
576 g_return_if_fail (G_IS_OBJECT (object));
578 va_start (var_args, first_param_name);
579 g_object_get_valist (object, first_param_name, var_args);
584 g_object_set_param (GObject *object,
585 const gchar *param_name,
589 const gchar *trailer;
591 g_return_if_fail (G_IS_OBJECT (object));
592 g_return_if_fail (param_name != NULL);
593 g_return_if_fail (G_IS_VALUE (value));
595 g_object_ref (object);
597 pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
599 G_OBJECT_TYPE (object),
603 g_warning ("%s: object class `%s' has no parameter named `%s'",
605 G_OBJECT_TYPE_NAME (object),
609 GValue tmp_value = { 0, };
611 /* provide a copy to work from and convert if necessary */
612 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
614 if (!g_value_convert (value, &tmp_value) ||
615 g_param_value_validate (pspec, &tmp_value))
616 g_warning ("%s: cannot convert `%s' value to parameter `%s' value of type `%s'",
618 G_VALUE_TYPE_NAME (value),
620 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
622 object_set_param (object, &tmp_value, pspec, trailer);
624 g_value_unset (&tmp_value);
627 g_object_unref (object);
631 g_object_get_param (GObject *object,
632 const gchar *param_name,
636 const gchar *trailer;
638 g_return_if_fail (G_IS_OBJECT (object));
639 g_return_if_fail (param_name != NULL);
640 g_return_if_fail (G_IS_VALUE (value));
642 g_object_ref (object);
644 pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
646 G_OBJECT_TYPE (object),
650 g_warning ("%s: object class `%s' has no parameter named `%s'",
652 G_OBJECT_TYPE_NAME (object),
656 GValue tmp_value = { 0, };
658 /* provide a copy to work from and later convert if necessary, so
659 * _get_param() implementations need *not* care about freeing values
660 * that might be already set in the parameter to get.
661 * (though, at this point, GValue should exclusively be modified
662 * through the accessor functions anyways)
664 g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
666 if (!g_value_types_exchangable (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
667 g_warning ("%s: can't retrive parameter `%s' value of type `%s' as value of type `%s'",
670 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
671 G_VALUE_TYPE_NAME (value));
674 object_get_param (object, &tmp_value, pspec, trailer);
675 g_value_convert (&tmp_value, value);
676 /* g_value_validate (value, pspec); */
679 g_value_unset (&tmp_value);
682 g_object_unref (object);
686 g_object_queue_param_changed (GObject *object,
687 const gchar *param_name)
691 g_return_if_fail (G_IS_OBJECT (object));
692 g_return_if_fail (param_name != NULL);
694 pspec = g_param_spec_hash_table_lookup (param_spec_hash_table,
696 G_OBJECT_TYPE (object),
699 g_warning ("%s: object class `%s' has no parameter named `%s'",
701 G_OBJECT_TYPE_NAME (object),
704 G_OBJECT_GET_CLASS (object)->queue_param_changed (object, pspec);
708 g_object_ref (GObject *object)
710 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
711 g_return_val_if_fail (object->ref_count > 0, NULL);
713 object->ref_count += 1;
719 g_object_unref (GObject *object)
721 g_return_if_fail (G_IS_OBJECT (object));
722 g_return_if_fail (object->ref_count > 0);
724 if (object->ref_count > 1)
725 object->ref_count -= 1;
727 g_object_last_unref (object);
731 g_object_get_qdata (GObject *object,
734 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
736 return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
740 g_object_set_qdata (GObject *object,
744 g_return_if_fail (G_IS_OBJECT (object));
745 g_return_if_fail (quark > 0);
747 g_datalist_id_set_data (&object->qdata, quark, data);
751 g_object_set_qdata_full (GObject *object,
754 GDestroyNotify destroy)
756 g_return_if_fail (G_IS_OBJECT (object));
757 g_return_if_fail (quark > 0);
759 g_datalist_id_set_data_full (&object->qdata, quark, data, data ? destroy : NULL);
763 g_object_steal_qdata (GObject *object,
766 g_return_val_if_fail (G_IS_OBJECT (object), NULL);
767 g_return_val_if_fail (quark > 0, NULL);
769 return g_datalist_id_remove_no_notify (&object->qdata, quark);
773 g_value_object_init (GValue *value)
775 value->data[0].v_pointer = NULL;
779 g_value_object_free_value (GValue *value)
781 if (value->data[0].v_pointer)
782 g_object_unref (value->data[0].v_pointer);
786 g_value_object_copy_value (const GValue *src_value,
789 if (src_value->data[0].v_pointer)
790 dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer);
792 dest_value->data[0].v_pointer = NULL;
796 g_value_object_collect_value (GValue *value,
799 GTypeCValue *collect_value)
801 if (collect_value->v_pointer)
803 GObject *object = collect_value->v_pointer;
805 if (object->g_type_instance.g_class == NULL)
806 return g_strconcat ("invalid unclassed object pointer for value type `",
807 G_VALUE_TYPE_NAME (value),
810 else if (!g_type_is_a (G_OBJECT_TYPE (object), G_VALUE_TYPE (value)))
811 return g_strconcat ("invalid object type `",
812 G_OBJECT_TYPE_NAME (object),
813 "' for value type `",
814 G_VALUE_TYPE_NAME (value),
817 value->data[0].v_pointer = g_object_ref (object);
820 value->data[0].v_pointer = NULL;
827 g_value_object_lcopy_value (const GValue *value,
830 GTypeCValue *collect_value)
832 GObject **object_p = collect_value->v_pointer;
835 return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
837 *object_p = value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;
844 g_value_set_object (GValue *value,
847 g_return_if_fail (G_IS_VALUE_OBJECT (value));
849 g_return_if_fail (G_IS_OBJECT (v_object));
851 if (value->data[0].v_pointer)
852 g_object_unref (value->data[0].v_pointer);
853 value->data[0].v_pointer = v_object;
854 if (value->data[0].v_pointer)
855 g_object_ref (value->data[0].v_pointer);
859 g_value_get_object (GValue *value)
861 g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
863 return value->data[0].v_pointer;
867 g_value_dup_object (GValue *value)
869 g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL);
871 return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL;