diff --git a/ChangeLog b/ChangeLog index cc36442f1e..c193a7d777 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2005-04-08 Stefan Kost + + * docs/gst/gstreamer-sections.txt: + * gst/Makefile.am: + * gst/gstparent.c: (gst_parent_get_child_by_name), + (gst_parent_get_child_by_index), (gst_parent_get_children_count), + (gst_parent_get_valist), (gst_parent_get), (gst_parent_set_valist), + (gst_parent_set), (gst_parent_base_init), (gst_parent_get_type): + * gst/gstparent.h: + * gst/gstvalue.c: (_gst_value_initialize): + a new interface for managing elements with multiple children + 2005-04-05 Tim-Philipp Müller * examples/helloworld/helloworld.c: (error_cb), (main): diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index 5684febf58..c2a4dceba5 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -1113,6 +1113,29 @@ gst_pad_template_get_type gst_pad_template_flags_get_type +
+gstparent +GstParent +gst_parent_get_children_count +gst_parent_get_child_by_name +gst_parent_get_child_by_index +gst_parent_get_valist +gst_parent_get +gst_parent_set_valist +gst_parent_set + +GstParent +GstParentClass +GST_PARENT +GST_IS_PARENT +GST_IS_PARENT_CLASS +GST_PARENT_CLASS +GST_PARENT_GET_CLASS +GST_TYPE_PARENT + +gst_parent_get_type +
+
gstparse GstParse diff --git a/gst/Makefile.am b/gst/Makefile.am index 644b780f3d..99584e3235 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -100,6 +100,7 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \ gstinterface.c \ gstmemchunk.c \ gstpad.c \ + gstparent.c \ gstpipeline.c \ gstplugin.c \ gstpluginfeature.c \ @@ -174,6 +175,7 @@ gst_headers = \ gstmacros.h \ gstmemchunk.h \ gstpad.h \ + gstparent.h \ gstpipeline.h \ gstplugin.h \ gstpluginfeature.h \ diff --git a/gst/gstparent.c b/gst/gstparent.c new file mode 100644 index 0000000000..7ac8327868 --- /dev/null +++ b/gst/gstparent.c @@ -0,0 +1,247 @@ +/* GStreamer + * Copyright (C) 2005 Stefan Kost + * + * gstparent.c: interface for multi child elements + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "gst_private.h" + +#include "gstparent.h" + +/* Parent signals */ +/* +enum +{ + CHILD_ADDED, + CHILD_REMOVED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; +*/ + +/** + * gst_parent_get_child_by_name: + * @parent: the parent object to get the child from + * @name: the childs name + * + * Looks up a child element by the given name. + * + * Implementors can e.g. use #GstObject together with gst_object_set_name() or + * GObject with g_object_set_data() to identify objects. + * + * Returns: the child object or %NULL if not found + */ +GObject * +gst_parent_get_child_by_name (GstParent * parent, const gchar * name) +{ + return (GST_PARENT_GET_CLASS (parent)->get_child_by_name (parent, name)); +} + +/** + * gst_parent_get_child_by_index: + * @parent: the parent object to get the child from + * @index: the childs position in the child list + * + * Fetches a child by its number. + * + * Returns: the child object or %NULL if not found (index too high) + */ +GObject * +gst_parent_get_child_by_index (GstParent * parent, guint index) +{ + return (GST_PARENT_GET_CLASS (parent)->get_child_by_index (parent, index)); +} + +/** + * gst_parent_get_children_count: + * @parent: the parent object + * + * Gets the number of child objects this parent contains. + * + * Returns: the number of child objects + */ +guint +gst_parent_get_children_count (GstParent * parent) +{ + return (GST_PARENT_GET_CLASS (parent)->get_children_count (parent)); +} + +/** + * gst_parent_get_valist: + * @parent: the parent object + * @first_property_name: name of the first property to get + * @var_args: return location for the first property, followed optionally by more name/return location pairs, followed by NULL + * Gets properties of the parents child objects. + */ +void +gst_parent_get_valist (GstParent * parent, const gchar * first_property_name, + va_list var_args) +{ + GObject *child; + const gchar *name; + gchar *child_name, *prop_name; + + g_return_if_fail (G_IS_OBJECT (parent)); + + g_object_ref (parent); + + name = first_property_name; + + // iterate of pairs + while (name) { + // split on '::' into child_name, prop_name + prop_name = strstr (name, "::"); + if (prop_name) { + child_name = g_strndup (name, ((gulong) prop_name - (gulong) name)); + prop_name += 2; + // get the child by name + child = gst_parent_get_child_by_name (parent, child_name); + g_object_get (child, prop_name, var_args, NULL); + } else { + GST_WARNING ("property name '%s' has no '::' separator", name); + break; + } + name = va_arg (var_args, gchar *); + } + + g_object_unref (parent); +} + +/** + * gst_parent_get: + * @parent: the parent object + * @first_property_name: name of the first property to get + * @...: return location for the first property, followed optionally by more name/return location pairs, followed by NULL + * Gets properties of the parents child objects. + */ +void +gst_parent_get (GstParent * parent, const gchar * first_property_name, ...) +{ + va_list var_args; + + g_return_if_fail (G_IS_OBJECT (parent)); + + va_start (var_args, first_property_name); + gst_parent_get_valist (parent, first_property_name, var_args); + va_end (var_args); +} + +/** + * gst_parent_set_valist: + * @parent: the parent object + * @first_property_name: name of the first property to set + * @var_args: value for the first property, followed optionally by more name/value pairs, followed by NULL + * Sets properties of the parents child objects. + */ +void +gst_parent_set_valist (GstParent * parent, const gchar * first_property_name, + va_list var_args) +{ + GObject *child; + const gchar *name; + gchar *child_name, *prop_name; + + g_return_if_fail (G_IS_OBJECT (parent)); + + g_object_ref (parent); + + name = first_property_name; + + // iterate of pairs + while (name) { + // split on '::' into child_name, prop_name + prop_name = strstr (name, "::"); + if (prop_name) { + child_name = g_strndup (name, ((gulong) prop_name - (gulong) name)); + prop_name += 2; + // get the child by name + child = gst_parent_get_child_by_name (parent, child_name); + g_object_set (child, prop_name, var_args, NULL); + } else { + GST_WARNING ("property name '%s' has no '::' separator", name); + break; + } + name = va_arg (var_args, gchar *); + } + + g_object_unref (parent); +} + +/** + * gst_parent_set: + * @parent: the parent object + * @first_property_name: name of the first property to set + * @...: value for the first property, followed optionally by more name/value pairs, followed by NULL + * Sets properties of the parents child objects. + */ +void +gst_parent_set (GstParent * parent, const gchar * first_property_name, ...) +{ + va_list var_args; + + g_return_if_fail (G_IS_OBJECT (parent)); + + va_start (var_args, first_property_name); + gst_parent_set_valist (parent, first_property_name, var_args); + va_end (var_args); +} + +static void +gst_parent_base_init (gpointer g_class) +{ + static gboolean initialized = FALSE; + + if (!initialized) { + /* create interface signals and properties here. */ + /* + signals[CHILD_ADDED] = + g_signal_new ("child-added", G_TYPE_FROM_CLASS (g_class), + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstParentClass, child_added), NULL, + NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[CHILD_REMOVED] = + g_signal_new ("child-removed", G_TYPE_FROM_CLASS (g_class), + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstParentClass, child_removed), NULL, + NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); + */ + initialized = TRUE; + } +} + +GType +gst_parent_get_type (void) +{ + static GType type = 0; + + if (type == 0) { + static const GTypeInfo info = { + sizeof (GstParentClass), + gst_parent_base_init, /* base_init */ + NULL, /* base_finalize */ + NULL, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, /* n_preallocs */ + NULL /* instance_init */ + }; + type = g_type_register_static (G_TYPE_INTERFACE, "GstParent", &info, 0); + } + return type; +} diff --git a/gst/gstparent.h b/gst/gstparent.h new file mode 100644 index 0000000000..823d0e2ed4 --- /dev/null +++ b/gst/gstparent.h @@ -0,0 +1,65 @@ +/* GStreamer + * Copyright (C) 2005 Stefan Kost + * + * gstparent.h: interface header for multi child elements + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_PARENT_H__ +#define __GST_PARENT_H__ + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_PARENT (gst_parent_get_type()) +#define GST_PARENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PARENT, GstParent)) +#define GST_PARENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PARENT, GstParentClass)) +#define GST_IS_PARENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PARENT)) +#define GST_IS_PARENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PARENT)) +#define GST_PARENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GST_TYPE_PARENT, GstParentClass)) + + +typedef struct _GstParent GstParent; /* dummy object */ +typedef struct _GstParentClass GstParentClass; + +struct _GstParentClass { + GTypeInterface parent; + + // methods + GObject * (* get_child_by_name) (GstParent *parent, const gchar *name); + GObject * (* get_child_by_index) (GstParent *parent, guint index); + guint (* get_children_count) (GstParent *parent); + // signals + void (* child_added) (GstParent *parent, GObject *child); + void (* child_removed) (GstParent *parent, GObject *child); +}; + +GType gst_parent_get_type(void); + +GObject * gst_parent_get_child_by_name (GstParent *parent, const gchar *name); +GObject * gst_parent_get_child_by_index (GstParent *parent, guint index); +guint gst_parent_get_children_count(GstParent *parent); + +void gst_parent_get_valist (GstParent *parent, const gchar *first_property_name, va_list var_args); +void gst_parent_get (GstParent *parent, const gchar *first_property_name, ...); +void gst_parent_set_valist (GstParent *parent, const gchar *first_property_name, va_list var_args); +void gst_parent_set (GstParent *parent, const gchar *first_property_name, ...); + +G_END_DECLS + +#endif /* __GST_PARENT_H__ */