/** * gst_object_restore_thyself: * @object: a #GstObject to load into * @self: The XML node to load @object from * * Restores @object with the data from the parent XML node. */ void gst_object_restore_thyself (GstObject * object, xmlNodePtr self) { GstObjectClass *oclass; g_return_if_fail (GST_IS_OBJECT (object)); g_return_if_fail (self != NULL); oclass = GST_OBJECT_GET_CLASS (object); if (oclass->restore_thyself) oclass->restore_thyself (object, self); }
/** * gst_object_save_thyself: * @object: a #GstObject to save * @parent: The parent XML node to save @object into * * Saves @object into the parent XML node. * * Returns: the new xmlNodePtr with the saved object */ xmlNodePtr gst_object_save_thyself (GstObject * object, xmlNodePtr parent) { GstObjectClass *oclass; g_return_val_if_fail (GST_IS_OBJECT (object), parent); g_return_val_if_fail (parent != NULL, parent); oclass = GST_OBJECT_GET_CLASS (object); if (oclass->save_thyself) oclass->save_thyself (object, parent); g_signal_emit (object, gst_object_signals[OBJECT_SAVED], 0, parent); return parent; }
/* Changing a GObject property of a GstObject will result in "deep_notify" * signals being emitted by the object itself, as well as in each parent * object. This is so that an application can connect a listener to the * top-level bin to catch property-change notifications for all contained * elements. * * This function is not MT safe in glib < 2.8 so we need to lock it with a * classwide mutex in that case. * * MT safe. */ static void gst_object_dispatch_properties_changed (GObject * object, guint n_pspecs, GParamSpec ** pspecs) { GstObject *gst_object, *parent, *old_parent; guint i; gchar *name, *debug_name; GstObjectClass *klass; /* we fail when this is not a GstObject */ g_return_if_fail (GST_IS_OBJECT (object)); klass = GST_OBJECT_GET_CLASS (object); /* do the standard dispatching */ G_OBJECT_CLASS (parent_class)->dispatch_properties_changed (object, n_pspecs, pspecs); gst_object = GST_OBJECT_CAST (object); name = gst_object_get_name (gst_object); debug_name = GST_STR_NULL (name); /* now let the parent dispatch those, too */ parent = gst_object_get_parent (gst_object); while (parent) { for (i = 0; i < n_pspecs; i++) { GST_LOG_OBJECT (parent, "deep notification from %s (%s)", debug_name, pspecs[i]->name); g_signal_emit (parent, gst_object_signals[DEEP_NOTIFY], g_quark_from_string (pspecs[i]->name), GST_OBJECT_CAST (object), pspecs[i]); } old_parent = parent; parent = gst_object_get_parent (old_parent); gst_object_unref (old_parent); } g_free (name); }
EXPORT_C #endif gchar * gst_object_get_path_string (GstObject * object) { GSList *parentage; GSList *parents; void *parent; gchar *prevpath, *path; gchar *component; gchar *separator; /* ref object before adding to list */ gst_object_ref (object); parentage = g_slist_prepend (NULL, object); path = g_strdup (""); /* first walk the object hierarchy to build a list of the parents, * be carefull here with refcounting. */ do { if (GST_IS_OBJECT (object)) { parent = gst_object_get_parent (object); /* add parents to list, refcount remains increased while * we handle the object */ if (parent) parentage = g_slist_prepend (parentage, parent); } else { break; } object = parent; } while (object != NULL); /* then walk the parent list and print them out. we need to * decrease the refcounting on each element after we handled * it. */ for (parents = parentage; parents; parents = g_slist_next (parents)) { if (GST_IS_OBJECT (parents->data)) { GstObject *item = GST_OBJECT_CAST (parents->data); GstObjectClass *oclass = GST_OBJECT_GET_CLASS (item); component = gst_object_get_name (item); separator = oclass->path_string_separator; /* and unref now */ gst_object_unref (item); } else { component = g_strdup_printf ("%p", parents->data); separator = "/"; } prevpath = path; path = g_strjoin (separator, prevpath, component, NULL); g_free (prevpath); g_free (component); } g_slist_free (parentage); return path; }