2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
5 * gstobject.c: Fundamental class used for all of GStreamer
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 #include "gst_private.h"
25 #include "gstobject.h"
27 /* Object signals and args */
39 static void gst_object_class_init(GstObjectClass *klass);
40 static void gst_object_init(GstObject *object);
43 static GtkObjectClass *parent_class = NULL;
44 static guint gst_object_signals[LAST_SIGNAL] = { 0 };
46 GtkType gst_object_get_type(void) {
47 static GtkType object_type = 0;
50 static const GtkTypeInfo object_info = {
53 sizeof(GstObjectClass),
54 (GtkClassInitFunc)gst_object_class_init,
55 (GtkObjectInitFunc)gst_object_init,
58 (GtkClassInitFunc)NULL,
60 object_type = gtk_type_unique(gtk_object_get_type(),&object_info);
65 static void gst_object_class_init(GstObjectClass *klass) {
66 GtkObjectClass *gtkobject_class;
68 gtkobject_class = (GtkObjectClass*)klass;
70 parent_class = gtk_type_class(gtk_object_get_type());
72 gst_object_signals[PARENT_SET] =
73 gtk_signal_new("parent_set",GTK_RUN_LAST,gtkobject_class->type,
74 GTK_SIGNAL_OFFSET(GstObjectClass,parent_set),
75 gtk_marshal_NONE__POINTER,GTK_TYPE_NONE,1,
77 gtk_object_class_add_signals(gtkobject_class,gst_object_signals,LAST_SIGNAL);
80 static void gst_object_init(GstObject *object) {
81 object->lock = g_mutex_new();
83 atomic_set(&(object->refcount),1);
87 object->parent = NULL;
93 * Create a new, empty object. Not very useful, should never be used.
97 GstObject *gst_object_new() {
98 return GST_OBJECT(gtk_type_new(gst_object_get_type()));
102 * gst_object_set_parent:
103 * @object: GstObject to set parent of
104 * @parent: new parent of object
106 * Set the parent of the object. The object's reference count is
108 * signals the parent-set signal
110 void gst_object_set_parent(GstObject *object,GstObject *parent) {
111 g_return_if_fail(object != NULL);
112 g_return_if_fail(GST_IS_OBJECT(object));
113 g_return_if_fail(object->parent == NULL);
114 g_return_if_fail(parent != NULL);
115 g_return_if_fail(GST_IS_OBJECT(parent));
116 g_return_if_fail(object != parent);
118 gst_object_ref(object);
119 gst_object_sink(object);
120 object->parent = parent;
122 gtk_signal_emit(GTK_OBJECT(object),gst_object_signals[PARENT_SET],parent);
126 * gst_object_get_parent:
127 * @object: GstObject to get parent of
129 * Return the parent of the object.
131 * Returns: parent of the object
133 GstObject *gst_object_get_parent(GstObject *object) {
134 g_return_val_if_fail(object != NULL, NULL);
135 g_return_val_if_fail(GST_IS_OBJECT(object), NULL);
137 return object->parent;
141 * gst_object_unparent:
142 * @object: GstObject to unparent
144 * Clear the parent of the object, removing the associated reference.
146 void gst_object_unparent(GstObject *object) {
147 g_return_if_fail(object != NULL);
148 g_return_if_fail(GST_IS_OBJECT(object));
149 if (object->parent == NULL)
152 object->parent = NULL;
153 gst_object_unref(object);
158 * @object: GstObject to reference
160 * Increments the refence count on the object.
162 #ifndef gst_object_ref
163 void gst_object_ref (GstObject *object) {
164 g_return_if_fail(object != NULL);
165 g_return_if_fail(GST_IS_OBJECT(object));
168 g_return_if_fail(atomic_read(&(object->refcount)) > 0);
169 atomic_inc(&(object->refcount))
171 g_return_if_fail(object->refcount > 0);
177 #endif /* gst_object_ref */
181 * @object: GstObject to unreference
183 * Decrements the refence count on the object. If reference count hits
184 * zero, destroy the object.
186 #ifndef gst_object_unref
187 void gst_object_unref (GstObject *object) {
190 g_return_if_fail(object != NULL);
191 g_return_if_fail(GST_IS_OBJECT(object));
194 g_return_if_fail(atomic_read(&(object->refcount)) > 0);
195 reftest = atomic_dec_and_test(&(object->refcount))
197 g_return_if_fail(object->refcount > 0);
200 reftest = (object->refcount == 0);
204 /* if we ended up with the refcount at zero */
206 /* get the count to 1 for gtk_object_destroy() */
208 atomic_set(&(object->refcount),1);
210 object->refcount = 1;
213 gtk_object_destroy(GTK_OBJECT(object));
214 /* drop the refcount back to zero */
216 atomic_set(&(object->refcount),0);
218 object->refcount = 0;
220 /* finalize the object */
221 // FIXME this is an evil hack that should be killed
222 // FIXMEFIXMEFIXMEFIXME
223 // gtk_object_finalize(GTK_OBJECT(object));
226 #endif /* gst_object_unref */
230 * @object: GstObject to sink
232 * Removes floating reference on an object. Any newly created object has
233 * a refcount of 1 and is FLOATING. This function should be used when
234 * creating a new object to symbolically 'take ownership of' the object.
236 #ifndef gst_object_sink
237 void gst_object_sink(GstObject *object) {
238 g_return_if_fail(object != NULL);
239 g_return_if_fail(GST_IS_OBJECT(object));
241 if (GTK_OBJECT_FLOATING(object)) {
242 GTK_OBJECT_UNSET_FLAGS(object, GTK_FLOATING);
243 gst_object_unref(object);
246 #endif /* gst_object_sink */