Updated copyright in all the libgst files.
[platform/upstream/gstreamer.git] / gst / gstobject.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gstobject.c: Fundamental class used for all of GStreamer
6  *
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.
11  *
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.
16  *
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.
21  */
22
23 #include "gst_private.h"
24
25 #include "gstobject.h"
26
27 /* Object signals and args */
28 enum {
29   PARENT_SET,
30   LAST_SIGNAL
31 };
32
33 enum {
34   ARG_0,
35   /* FILL ME */
36 };
37
38
39 static void gst_object_class_init(GstObjectClass *klass);
40 static void gst_object_init(GstObject *object);
41
42
43 static GtkObjectClass *parent_class = NULL;
44 static guint gst_object_signals[LAST_SIGNAL] = { 0 };
45
46 GtkType gst_object_get_type(void) {
47   static GtkType object_type = 0;
48
49   if (!object_type) {
50     static const GtkTypeInfo object_info = {
51       "GstObject",
52       sizeof(GstObject),
53       sizeof(GstObjectClass),
54       (GtkClassInitFunc)gst_object_class_init,
55       (GtkObjectInitFunc)gst_object_init,
56       (GtkArgSetFunc)NULL,
57       (GtkArgGetFunc)NULL,
58       (GtkClassInitFunc)NULL,
59     };
60     object_type = gtk_type_unique(gtk_object_get_type(),&object_info);
61   }
62   return object_type;
63 }
64
65 static void gst_object_class_init(GstObjectClass *klass) {
66   GtkObjectClass *gtkobject_class;
67
68   gtkobject_class = (GtkObjectClass*)klass;
69
70   parent_class = gtk_type_class(gtk_object_get_type());
71
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,
76                    GST_TYPE_OBJECT);
77   gtk_object_class_add_signals(gtkobject_class,gst_object_signals,LAST_SIGNAL);
78 }
79
80 static void gst_object_init(GstObject *object) {
81   object->lock = g_mutex_new();
82 #ifdef HAVE_ATOMIC_H
83   atomic_set(&(object->refcount),1);
84 #else
85   object->refcount++;
86 #endif
87   object->parent = NULL;
88 }
89
90 /**
91  * gst_object_new:
92  *
93  * Create a new, empty object.  Not very useful, should never be used.
94  *
95  * Returns: new object
96  */
97 GstObject *gst_object_new() {
98   return GST_OBJECT(gtk_type_new(gst_object_get_type()));
99 }
100
101 /**
102  * gst_object_set_parent:
103  * @object: GstObject to set parent of
104  * @parent: new parent of object
105  *
106  * Set the parent of the object.  The object's reference count is
107  * incremented.
108  * signals the parent-set signal
109  */
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);
117
118   gst_object_ref(object);
119   gst_object_sink(object);
120   object->parent = parent;
121
122   gtk_signal_emit(GTK_OBJECT(object),gst_object_signals[PARENT_SET],parent);
123 }
124
125 /**
126  * gst_object_get_parent:
127  * @object: GstObject to get parent of
128  *
129  * Return the parent of the object.
130  *
131  * Returns: parent of the object
132  */
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);
136
137   return object->parent;
138 }
139
140 /**
141  * gst_object_unparent:
142  * @object: GstObject to unparent
143  *
144  * Clear the parent of the object, removing the associated reference.
145  */
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)
150     return;
151
152   object->parent = NULL;
153   gst_object_unref(object);
154 }
155
156 /**
157  * gst_object_ref:
158  * @object: GstObject to reference
159  *
160  * Increments the refence count on the object.
161  */
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));
166
167 #ifdef HAVE_ATOMIC_H
168   g_return_if_fail(atomic_read(&(object->refcount)) > 0);
169   atomic_inc(&(object->refcount))
170 #else
171   g_return_if_fail(object->refcount > 0);
172   GST_LOCK(object);
173   object->refcount++;
174   GST_UNLOCK(object);
175 #endif
176 }
177 #endif /* gst_object_ref */
178
179 /**
180  * gst_object_unref:
181  * @object: GstObject to unreference
182  *
183  * Decrements the refence count on the object.  If reference count hits
184  * zero, destroy the object.
185  */
186 #ifndef gst_object_unref
187 void gst_object_unref (GstObject *object) {
188   int reftest;
189
190   g_return_if_fail(object != NULL);
191   g_return_if_fail(GST_IS_OBJECT(object));
192
193 #ifdef HAVE_ATOMIC_H
194   g_return_if_fail(atomic_read(&(object->refcount)) > 0);
195   reftest = atomic_dec_and_test(&(object->refcount))
196 #else
197   g_return_if_fail(object->refcount > 0);
198   GST_LOCK(object);
199   object->refcount--;
200   reftest = (object->refcount == 0);
201   GST_UNLOCK(object);
202 #endif
203
204   /* if we ended up with the refcount at zero */
205   if (reftest) {
206     /* get the count to 1 for gtk_object_destroy() */
207 #ifdef HAVE_ATOMIC_H
208     atomic_set(&(object->refcount),1);
209 #else
210     object->refcount = 1;
211 #endif
212     /* destroy it */
213     gtk_object_destroy(GTK_OBJECT(object));
214     /* drop the refcount back to zero */
215 #ifdef HAVE_ATOMIC_H
216     atomic_set(&(object->refcount),0);
217 #else
218     object->refcount = 0;
219 #endif
220     /* finalize the object */
221     // FIXME this is an evil hack that should be killed
222 // FIXMEFIXMEFIXMEFIXME
223 //    gtk_object_finalize(GTK_OBJECT(object));
224   }
225 }
226 #endif /* gst_object_unref */
227
228 /**
229  * gst_object_sink:
230  * @object: GstObject to sink
231  *
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.
235  */
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));
240
241   if (GTK_OBJECT_FLOATING(object)) {
242     GTK_OBJECT_UNSET_FLAGS(object, GTK_FLOATING);
243     gst_object_unref(object);
244   }
245 }
246 #endif /* gst_object_sink */
247