From 2aa179d5ecae6bc723a97ad5b814e0a01d056d47 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Thu, 21 Apr 2005 17:10:09 +0000 Subject: [PATCH] new iface to uniformly access elements children and their properties Original commit message from CVS: new iface to uniformly access elements children and their properties --- configure.ac | 1 + docs/gst/gstreamer-sections.txt | 26 ++ docs/gst/tmpl/gstchildproxy.sgml | 140 +++++++ gst/Makefile.am | 2 + gst/gst.h | 1 + gst/gstbin.c | 35 ++ gst/gstchildproxy.c | 407 ++++++++++++++++++++ gst/gstchildproxy.h | 76 ++++ gst/parse/grammar.y | 6 +- tests/old/testsuite/Makefile.am | 4 +- tests/old/testsuite/childproxy/Makefile.am | 6 + tests/old/testsuite/childproxy/childproxy.c | 114 ++++++ testsuite/Makefile.am | 4 +- testsuite/childproxy/Makefile.am | 6 + testsuite/childproxy/childproxy.c | 114 ++++++ 15 files changed, 936 insertions(+), 6 deletions(-) create mode 100644 docs/gst/tmpl/gstchildproxy.sgml create mode 100644 gst/gstchildproxy.c create mode 100644 gst/gstchildproxy.h create mode 100644 tests/old/testsuite/childproxy/Makefile.am create mode 100644 tests/old/testsuite/childproxy/childproxy.c create mode 100644 testsuite/childproxy/Makefile.am create mode 100644 testsuite/childproxy/childproxy.c diff --git a/configure.ac b/configure.ac index 2844e0fe12..a1a00388c7 100644 --- a/configure.ac +++ b/configure.ac @@ -676,6 +676,7 @@ testsuite/Makefile testsuite/bins/Makefile testsuite/bytestream/Makefile testsuite/caps/Makefile +testsuite/childproxy/Makefile testsuite/cleanup/Makefile testsuite/clock/Makefile testsuite/debug/Makefile diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index 26af6f0c23..fe897d4d9e 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -1113,6 +1113,32 @@ gst_pad_template_get_type gst_pad_template_flags_get_type +
+gstchildproxy +GstChildProxy +gst_child_proxy_get_children_count +gst_child_proxy_get_child_by_name +gst_child_proxy_get_child_by_index +gst_child_proxy_lookup +gst_child_proxy_get_property +gst_child_proxy_get_valist +gst_child_proxy_get +gst_child_proxy_set_property +gst_child_proxy_set_valist +gst_child_proxy_set +gst_child_proxy_child_added +gst_child_proxy_child_removed + +GstChildProxy +GstChildProxyInterface +GST_CHILD_PROXY +GST_IS_CHILD_PROXY +GST_CHILD_PROXY_GET_INTERFACE +GST_TYPE_CHILD_PROXY + +gst_child_proxy_get_type +
+
gstparse GstParse diff --git a/docs/gst/tmpl/gstchildproxy.sgml b/docs/gst/tmpl/gstchildproxy.sgml new file mode 100644 index 0000000000..a8185b119e --- /dev/null +++ b/docs/gst/tmpl/gstchildproxy.sgml @@ -0,0 +1,140 @@ + +GstChildProxy + + +interface for multi child element property access + + + +This interface provides a uniform way to access child objects of elements. +There are methods to get the children and methods to (recursivly) set and get +their properties. + + + + + + + + + + + + + + + +@parent: +@Returns: + + + + + + + +@parent: +@name: +@Returns: + + + + + + + +@parent: +@index: +@Returns: + + + + + + + +@object: +@name: +@target: +@pspec: +@Returns: + + + + + + + +@object: +@name: +@value: + + + + + + + +@object: +@first_property_name: +@var_args: + + + + + + + +@object: +@first_property_name: +@Varargs: + + + + + + + +@object: +@name: +@value: + + + + + + + +@object: +@first_property_name: +@var_args: + + + + + + + +@object: +@first_property_name: +@Varargs: + + + + + + + +@object: +@child: + + + + + + + +@object: +@child: + + diff --git a/gst/Makefile.am b/gst/Makefile.am index 644b780f3d..b609eb401d 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -100,6 +100,7 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \ gstinterface.c \ gstmemchunk.c \ gstpad.c \ + gstchildproxy.c \ gstpipeline.c \ gstplugin.c \ gstpluginfeature.c \ @@ -174,6 +175,7 @@ gst_headers = \ gstmacros.h \ gstmemchunk.h \ gstpad.h \ + gstchildproxy.h \ gstpipeline.h \ gstplugin.h \ gstpluginfeature.h \ diff --git a/gst/gst.h b/gst/gst.h index 2f25b2eb68..126448fece 100644 --- a/gst/gst.h +++ b/gst/gst.h @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include diff --git a/gst/gstbin.c b/gst/gstbin.c index 438ccef5da..579052966c 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -33,6 +33,7 @@ #include "gstscheduler.h" #include "gstindex.h" #include "gstutils.h" +#include "gstchildproxy.h" GST_DEBUG_CATEGORY_STATIC (bin_debug); #define GST_CAT_DEFAULT bin_debug @@ -97,6 +98,7 @@ enum static void gst_bin_base_init (gpointer g_class); static void gst_bin_class_init (GstBinClass * klass); static void gst_bin_init (GstBin * bin); +static void gst_bin_child_proxy_init (gpointer g_iface, gpointer iface_data); static GstElementClass *parent_class = NULL; static guint gst_bin_signals[LAST_SIGNAL] = { 0 }; @@ -123,9 +125,18 @@ gst_bin_get_type (void) NULL }; + static const GInterfaceInfo child_proxy_info = { + gst_bin_child_proxy_init, + NULL, + NULL + }; + _gst_bin_type = g_type_register_static (GST_TYPE_ELEMENT, "GstBin", &bin_info, 0); + g_type_add_interface_static (_gst_bin_type, GST_TYPE_CHILD_PROXY, + &child_proxy_info); + GST_DEBUG_CATEGORY_INIT (bin_debug, "bin", GST_DEBUG_BOLD, "debugging info for the 'bin' container element"); } @@ -213,6 +224,28 @@ gst_bin_init (GstBin * bin) bin->children = NULL; } +static GstObject * +gst_bin_child_proxy_get_child_by_index (GstChildProxy * child_proxy, + guint index) +{ + return g_list_nth_data (GST_BIN (child_proxy)->children, index); +} + +guint +gst_bin_child_proxy_get_children_count (GstChildProxy * child_proxy) +{ + return GST_BIN (child_proxy)->numchildren; +} + +static void +gst_bin_child_proxy_init (gpointer g_iface, gpointer iface_data) +{ + GstChildProxyInterface *iface = g_iface; + + iface->get_children_count = gst_bin_child_proxy_get_children_count; + iface->get_child_by_index = gst_bin_child_proxy_get_child_by_index; +} + /** * gst_bin_new: * @name: name of new bin @@ -529,6 +562,7 @@ gst_bin_add (GstBin * bin, GstElement * element) if (bclass->add_element) { bclass->add_element (bin, element); + gst_child_proxy_child_added (GST_OBJECT (bin), GST_OBJECT (element)); } else { GST_ELEMENT_ERROR (bin, CORE, FAILED, (NULL), ("cannot add element %s to bin %s", @@ -620,6 +654,7 @@ gst_bin_remove (GstBin * bin, GstElement * element) bclass = GST_BIN_GET_CLASS (bin); if (bclass->remove_element) { + gst_child_proxy_child_removed (GST_OBJECT (bin), GST_OBJECT (element)); bclass->remove_element (bin, element); } else { g_warning ("cannot remove elements from bin %s\n", GST_ELEMENT_NAME (bin)); diff --git a/gst/gstchildproxy.c b/gst/gstchildproxy.c new file mode 100644 index 0000000000..1e97194e53 --- /dev/null +++ b/gst/gstchildproxy.c @@ -0,0 +1,407 @@ +/* GStreamer + * Copyright (C) 2005 Stefan Kost + * + * gstchildproxy.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 "gstchildproxy.h" +#include + +/* signals */ +enum +{ + CHILD_ADDED, + CHILD_REMOVED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +/** + * gst_child_proxy_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 use #GstObject together with gst_object_get_name() + * + * Returns: the child object or %NULL if not found + */ +GstObject * +gst_child_proxy_get_child_by_name (GstChildProxy * parent, const gchar * name) +{ + guint count, i; + GstObject *object; + const gchar *object_name; + + g_return_val_if_fail (GST_IS_CHILD_PROXY (parent), NULL); + g_return_val_if_fail (name != NULL, NULL); + + count = gst_child_proxy_get_children_count (parent); + for (i = 0; i < count; i++) { + object = gst_child_proxy_get_child_by_index (parent, i); + object_name = gst_object_get_name (object); + if (object_name == NULL) { + g_warning ("child %u of parent %s has no name", i, + GST_OBJECT_NAME (parent)); + continue; + } + if (g_str_equal (object_name, name)) + return object; + } + return NULL; +} + +/** + * gst_child_proxy_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) + */ +GstObject * +gst_child_proxy_get_child_by_index (GstChildProxy * parent, guint index) +{ + g_return_val_if_fail (GST_IS_CHILD_PROXY (parent), NULL); + + return (GST_CHILD_PROXY_GET_INTERFACE (parent)->get_child_by_index (parent, + index)); +} + +/** + * gst_child_proxy_get_children_count: + * @parent: the parent object + * + * Gets the number of child objects this parent contains. + * + * Returns: the number of child objects + */ +guint +gst_child_proxy_get_children_count (GstChildProxy * parent) +{ + g_return_val_if_fail (GST_IS_CHILD_PROXY (parent), 0); + + return (GST_CHILD_PROXY_GET_INTERFACE (parent)->get_children_count (parent)); +} + +/** + * gst_child_proxy_lookup: + * @object: object to lookup the property in + * @name: name of the property to look up + * @target: pointer to a #GstObject that takes the real object to set property on + * @pspec: pointer to take the #GParamSpec describing the property + * + * Looks up which object and #GParamSpec would be effected by the given @name. + * + * Returns: TRUE if @target and @pspec could be found. FALSE otherwise. In that + * case the values for @pspec and @target are not modified + */ +gboolean +gst_child_proxy_lookup (GstObject * object, const gchar * name, + GstObject ** target, GParamSpec ** pspec) +{ + gboolean res = FALSE; + gchar **names, **current; + + g_return_val_if_fail (GST_IS_OBJECT (object), FALSE); + g_return_val_if_fail (name != NULL, FALSE); + + current = names = g_strsplit (name, "::", -1); + while (current[1]) { + if (!GST_IS_CHILD_PROXY (object)) { + GST_INFO + ("object %s is not a parent, so you cannot request a child by name %s", + GST_OBJECT_NAME (object), current[0]); + break; + } + object = + gst_child_proxy_get_child_by_name (GST_CHILD_PROXY (object), + current[0]); + if (!object) { + GST_INFO ("no such object %s", current[0]); + break; + } + current++; + }; + if (current[1] == NULL) { + GParamSpec *spec = + g_object_class_find_property (G_OBJECT_GET_CLASS (object), current[0]); + if (spec == NULL) { + GST_INFO ("no param spec named %s", current[0]); + } else { + if (pspec) + *pspec = spec; + if (target) + *target = object; + res = TRUE; + } + } + g_strfreev (names); + return res; +} + +/** + * gst_child_proxy_get_property: + * @object: object to query + * @name: name of the property + * @value: an uninitialized GValue that should take the result. + * + * You are responsible for for freeing it by calling g_value_unset() + * Gets a single property using the GstChildProxy mechanism. + */ +void +gst_child_proxy_get_property (GstObject * object, const gchar * name, + GValue * value) +{ + GParamSpec *pspec; + GstObject *target; + + g_return_if_fail (GST_IS_OBJECT (object)); + g_return_if_fail (name != NULL); + g_return_if_fail (!G_IS_VALUE (value)); + + if (!gst_child_proxy_lookup (object, name, &target, &pspec)) { + g_warning ("cannot get property %s from object %s", name, + GST_OBJECT_NAME (object)); + return; + } + g_object_get_property (G_OBJECT (target), pspec->name, value); +} + +/** + * gst_child_proxy_get_valist: + * @object: the object to query + * @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 parent object and its children. + */ +void +gst_child_proxy_get_valist (GstObject * object, + const gchar * first_property_name, va_list var_args) +{ + const gchar *name; + gchar *error = NULL; + GValue value = { 0, }; + + g_return_if_fail (G_IS_OBJECT (object)); + + g_object_ref (object); + + name = first_property_name; + + /* iterate over pairs */ + while (name) { + gst_child_proxy_get_property (object, name, &value); + G_VALUE_LCOPY (&value, var_args, 0, &error); + if (error) { + g_warning ("error copying value: %s", error); + return; + } + g_value_unset (&value); + name = va_arg (var_args, gchar *); + } + + g_object_unref (object); +} + +/** + * gst_child_proxy_get: + * @object: 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 parent object and its children. + */ +void +gst_child_proxy_get (GstObject * object, const gchar * first_property_name, ...) +{ + va_list var_args; + + g_return_if_fail (GST_IS_OBJECT (object)); + + va_start (var_args, first_property_name); + gst_child_proxy_get_valist (object, first_property_name, var_args); + va_end (var_args); +} + +void +gst_child_proxy_set_property (GstObject * object, const gchar * name, + const GValue * value) +{ + GParamSpec *pspec; + GstObject *target; + + g_return_if_fail (GST_IS_OBJECT (object)); + g_return_if_fail (name != NULL); + g_return_if_fail (!G_IS_VALUE (value)); + + if (!gst_child_proxy_lookup (object, name, &target, &pspec)) { + g_warning ("cannot set property %s on object %s", name, + GST_OBJECT_NAME (object)); + return; + } + g_object_set_property (G_OBJECT (target), pspec->name, value); +} + +/** + * gst_child_proxy_set_valist: + * @object: 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 parent object and its children. + */ +void +gst_child_proxy_set_valist (GstObject * object, + const gchar * first_property_name, va_list var_args) +{ + const gchar *name; + gchar *error = NULL; + GValue value = { 0, }; + + g_return_if_fail (G_IS_OBJECT (object)); + + g_object_ref (object); + + name = first_property_name; + + /* iterate over pairs */ + while (name) { + GParamSpec *pspec; + GstObject *target; + + if (!gst_child_proxy_lookup (object, name, &target, &pspec)) { + g_warning ("no such property %s in object %s", name, + GST_OBJECT_NAME (object)); + g_object_unref (object); + } + g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + G_VALUE_COLLECT (&value, var_args, G_VALUE_NOCOPY_CONTENTS, &error); + if (error) { + g_warning ("error copying value: %s", error); + g_object_unref (object); + return; + } + g_object_set_property (G_OBJECT (target), pspec->name, &value); + g_value_unset (&value); + name = va_arg (var_args, gchar *); + } + + g_object_unref (object); +} + +/** + * gst_child_proxy_set: + * @object: 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 parent object and its children. + */ +void +gst_child_proxy_set (GstObject * object, const gchar * first_property_name, ...) +{ + va_list var_args; + + g_return_if_fail (GST_IS_OBJECT (object)); + + va_start (var_args, first_property_name); + gst_child_proxy_set_valist (object, first_property_name, var_args); + va_end (var_args); +} + +/** + * gst_child_proxy_child_added: + * @object: the parent object + * @child: the newly added child + * + * Emits the "child-added" signal. + */ +void +gst_child_proxy_child_added (GstObject * object, GstObject * child) +{ + g_signal_emit (G_OBJECT (object), signals[CHILD_ADDED], 0, child); +} + +/** + * gst_child_proxy_child_removed: + * @object: the parent object + * @child: the newly added child + * + * Emits the "child-removed" signal. + */ +void +gst_child_proxy_child_removed (GstObject * object, GstObject * child) +{ + g_signal_emit (G_OBJECT (object), signals[CHILD_REMOVED], 0, child); +} + +/* gobject methods */ + +static void +gst_child_proxy_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 (GstChildProxyInterface, + 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 (GstChildProxyInterface, + child_removed), NULL, NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, + 1, G_TYPE_OBJECT); + + initialized = TRUE; + } +} + +GType +gst_child_proxy_get_type (void) +{ + static GType type = 0; + + if (type == 0) { + static const GTypeInfo info = { + sizeof (GstChildProxyInterface), + gst_child_proxy_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, "GstChildProxy", &info, 0); + + g_type_interface_add_prerequisite (type, GST_TYPE_OBJECT); + } + return type; +} diff --git a/gst/gstchildproxy.h b/gst/gstchildproxy.h new file mode 100644 index 0000000000..5f5580cb78 --- /dev/null +++ b/gst/gstchildproxy.h @@ -0,0 +1,76 @@ +/* GStreamer + * Copyright (C) 2005 Stefan Kost + * + * gstchildproxy.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_CHILD_PROXY_H__ +#define __GST_CHILD_PROXY_H__ + +#include +#include + +G_BEGIN_DECLS + + +#define GST_TYPE_CHILD_PROXY (gst_child_proxy_get_type ()) +#define GST_CHILD_PROXY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CHILD_PROXY, GstChildProxy)) +#define GST_IS_CHILD_PROXY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CHILD_PROXY)) +#define GST_CHILD_PROXY_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GST_TYPE_CHILD_PROXY, GstChildProxyInterface)) + +typedef struct _GstChildProxy GstChildProxy; /* dummy object */ +typedef struct _GstChildProxyInterface GstChildProxyInterface; + +struct _GstChildProxyInterface +{ + GTypeInterface parent; + + /* methods */ + GstObject *(*get_child_by_index) (GstChildProxy * parent, guint index); + guint (*get_children_count) (GstChildProxy * parent); + /* signals */ + void (*child_added) (GstChildProxy * parent, GstObject * child); + void (*child_removed) (GstChildProxy * parent, GstObject * child); + + gpointer _gst_reserved[GST_PADDING]; +}; + +GType gst_child_proxy_get_type (void); + +GstObject *gst_child_proxy_get_child_by_name (GstChildProxy * parent, const gchar * name); +GstObject *gst_child_proxy_get_child_by_index (GstChildProxy * parent, guint index); +guint gst_child_proxy_get_children_count (GstChildProxy * parent); + +gboolean gst_child_proxy_lookup (GstObject *object, const gchar *name, + GstObject **target, GParamSpec **pspec); +void gst_child_proxy_get_property (GstObject * object, const gchar *name, GValue *value); +void gst_child_proxy_get_valist (GstObject * object, + const gchar * first_property_name, va_list var_args); +void gst_child_proxy_get (GstObject * object, const gchar * first_property_name, + ...); +void gst_child_proxy_set_property (GstObject * object, const gchar *name, const GValue *value); +void gst_child_proxy_set_valist (GstObject* object, + const gchar * first_property_name, va_list var_args); +void gst_child_proxy_set (GstObject * object, const gchar * first_property_name, + ...); +void gst_child_proxy_child_added (GstObject * object, GstObject * child); +void gst_child_proxy_child_removed (GstObject * object, GstObject * child); + +G_END_DECLS + +#endif /* __GST_CHILD_PROXY_H__ */ diff --git a/gst/parse/grammar.y b/gst/parse/grammar.y index 05b8033190..c425d2de8f 100644 --- a/gst/parse/grammar.y +++ b/gst/parse/grammar.y @@ -14,6 +14,7 @@ #include "../gsterror.h" #include "../gsturi.h" #include "../gstvalue.h" +#include "../gstchildproxy.h" #include "types.h" /* All error messages in this file are user-visible and need to be translated. @@ -236,6 +237,7 @@ gst_parse_element_set (gchar *value, GstElement *element, graph_t *graph) gchar *pos = value; GValue v = { 0, }; GValue v2 = { 0, }; + GstObject *target; /* parse the string, so the property name is null-terminated an pos points to the beginning of the value */ while (!g_ascii_isspace (*pos) && (*pos != '=')) pos++; @@ -253,11 +255,11 @@ gst_parse_element_set (gchar *value, GstElement *element, graph_t *graph) pos[strlen (pos) - 1] = '\0'; } gst_parse_unescape (pos); - if ((pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (element), value))) { + if (gst_child_proxy_lookup (GST_OBJECT (element), value, &target, &pspec)) { g_value_init (&v, G_PARAM_SPEC_VALUE_TYPE(pspec)); if (!gst_value_deserialize (&v, pos)) goto error; - g_object_set_property (G_OBJECT (element), value, &v); + g_object_set_property (G_OBJECT (target), pspec->name, &v); } else { SET_ERROR (((graph_t *) graph)->error, GST_PARSE_ERROR_NO_SUCH_PROPERTY, _("no property \"%s\" in element \"%s\""), value, GST_ELEMENT_NAME (element)); } diff --git a/tests/old/testsuite/Makefile.am b/tests/old/testsuite/Makefile.am index 54507be990..df8249a062 100644 --- a/tests/old/testsuite/Makefile.am +++ b/tests/old/testsuite/Makefile.am @@ -14,7 +14,7 @@ GST_DEBUG_DIRS = debug endif SUBDIRS = \ - bins bytestream caps cleanup clock \ + bins bytestream caps childproxy cleanup clock \ $(GST_DEBUG_DIRS) \ dlopen dynparams \ elements ghostpads indexers negotiation pad \ @@ -22,7 +22,7 @@ SUBDIRS = \ plugin refcounting schedulers states tags threads DIST_SUBDIRS = \ - bins bytestream caps cleanup clock \ + bins bytestream caps childproxy cleanup clock \ debug \ dlopen dynparams \ elements ghostpads indexers negotiation pad \ diff --git a/tests/old/testsuite/childproxy/Makefile.am b/tests/old/testsuite/childproxy/Makefile.am new file mode 100644 index 0000000000..f2324c8a9f --- /dev/null +++ b/tests/old/testsuite/childproxy/Makefile.am @@ -0,0 +1,6 @@ +include ../Rules + +tests_pass = childproxy +tests_fail = +tests_ignore = + diff --git a/tests/old/testsuite/childproxy/childproxy.c b/tests/old/testsuite/childproxy/childproxy.c new file mode 100644 index 0000000000..07f5f100fc --- /dev/null +++ b/tests/old/testsuite/childproxy/childproxy.c @@ -0,0 +1,114 @@ +/* GStreamer + * Copyright (C) 2005 Stefan Kost + * + * childproxy.c: test for GstChildProxy iface + * + * 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 + +gboolean added = FALSE; +gboolean removed = FALSE; + +static void +my_child_added (GstChildProxy * parent, GstObject * child, gpointer user_data) +{ + if (child == GST_OBJECT (user_data)) { + added = TRUE; + } +} + +static void +my_child_removed (GstChildProxy * parent, GstObject * child, gpointer user_data) +{ + if (child == GST_OBJECT (user_data)) { + removed = TRUE; + } +} + +int +main (int argc, char *argv[]) +{ + GstBin *bin; + GstElement *child1, *child2; + gboolean state; + + gst_init (&argc, &argv); + + if ((bin = GST_BIN (gst_bin_new ("bin"))) == NULL) { + g_print ("Could not create a bin element!\n"); + return 1; + } + + if ((child1 = gst_element_factory_make ("identity", "filter")) == NULL) { + g_print ("Could not create a identity element!\n"); + return 1; + } + + g_signal_connect (G_OBJECT (bin), "child-added", G_CALLBACK (my_child_added), + child1); + g_signal_connect (G_OBJECT (bin), "child-removed", + G_CALLBACK (my_child_removed), child1); + + gst_bin_add (bin, child1); + + if (!added) { + g_print ("ChildProxy::child-added has not been caught!\n"); + return 1; + } + + if (gst_child_proxy_get_children_count (GST_CHILD_PROXY (bin)) != 1) { + g_print ("ChildProxy should manage exactly one child now!\n"); + return 1; + } + + child2 = + GST_ELEMENT (gst_child_proxy_get_child_by_index (GST_CHILD_PROXY (bin), + 0)); + if (child2 != child1) { + g_print ("ChildProxy's first child is not what we have added!\n"); + return 1; + } + + gst_child_proxy_set (GST_OBJECT (bin), "filter::silent", TRUE, NULL); + + g_object_get (G_OBJECT (child1), "silent", &state, NULL); + if (!state) { + g_print ("ChildProxy's child property access failed !\n"); + return 1; + } + + gst_child_proxy_set (GST_OBJECT (bin), "filter::silent", FALSE, NULL); + + g_object_get (G_OBJECT (child1), "silent", &state, NULL); + if (state) { + g_print ("ChildProxy's child property access failed !\n"); + return 1; + } + + gst_bin_remove (bin, child1); + + if (!removed) { + g_print ("ChildProxy::child-added has not been caught!\n"); + return 1; + } + + g_object_unref (G_OBJECT (bin)); + + /* success */ + return 0; +} diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index 54507be990..df8249a062 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -14,7 +14,7 @@ GST_DEBUG_DIRS = debug endif SUBDIRS = \ - bins bytestream caps cleanup clock \ + bins bytestream caps childproxy cleanup clock \ $(GST_DEBUG_DIRS) \ dlopen dynparams \ elements ghostpads indexers negotiation pad \ @@ -22,7 +22,7 @@ SUBDIRS = \ plugin refcounting schedulers states tags threads DIST_SUBDIRS = \ - bins bytestream caps cleanup clock \ + bins bytestream caps childproxy cleanup clock \ debug \ dlopen dynparams \ elements ghostpads indexers negotiation pad \ diff --git a/testsuite/childproxy/Makefile.am b/testsuite/childproxy/Makefile.am new file mode 100644 index 0000000000..f2324c8a9f --- /dev/null +++ b/testsuite/childproxy/Makefile.am @@ -0,0 +1,6 @@ +include ../Rules + +tests_pass = childproxy +tests_fail = +tests_ignore = + diff --git a/testsuite/childproxy/childproxy.c b/testsuite/childproxy/childproxy.c new file mode 100644 index 0000000000..07f5f100fc --- /dev/null +++ b/testsuite/childproxy/childproxy.c @@ -0,0 +1,114 @@ +/* GStreamer + * Copyright (C) 2005 Stefan Kost + * + * childproxy.c: test for GstChildProxy iface + * + * 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 + +gboolean added = FALSE; +gboolean removed = FALSE; + +static void +my_child_added (GstChildProxy * parent, GstObject * child, gpointer user_data) +{ + if (child == GST_OBJECT (user_data)) { + added = TRUE; + } +} + +static void +my_child_removed (GstChildProxy * parent, GstObject * child, gpointer user_data) +{ + if (child == GST_OBJECT (user_data)) { + removed = TRUE; + } +} + +int +main (int argc, char *argv[]) +{ + GstBin *bin; + GstElement *child1, *child2; + gboolean state; + + gst_init (&argc, &argv); + + if ((bin = GST_BIN (gst_bin_new ("bin"))) == NULL) { + g_print ("Could not create a bin element!\n"); + return 1; + } + + if ((child1 = gst_element_factory_make ("identity", "filter")) == NULL) { + g_print ("Could not create a identity element!\n"); + return 1; + } + + g_signal_connect (G_OBJECT (bin), "child-added", G_CALLBACK (my_child_added), + child1); + g_signal_connect (G_OBJECT (bin), "child-removed", + G_CALLBACK (my_child_removed), child1); + + gst_bin_add (bin, child1); + + if (!added) { + g_print ("ChildProxy::child-added has not been caught!\n"); + return 1; + } + + if (gst_child_proxy_get_children_count (GST_CHILD_PROXY (bin)) != 1) { + g_print ("ChildProxy should manage exactly one child now!\n"); + return 1; + } + + child2 = + GST_ELEMENT (gst_child_proxy_get_child_by_index (GST_CHILD_PROXY (bin), + 0)); + if (child2 != child1) { + g_print ("ChildProxy's first child is not what we have added!\n"); + return 1; + } + + gst_child_proxy_set (GST_OBJECT (bin), "filter::silent", TRUE, NULL); + + g_object_get (G_OBJECT (child1), "silent", &state, NULL); + if (!state) { + g_print ("ChildProxy's child property access failed !\n"); + return 1; + } + + gst_child_proxy_set (GST_OBJECT (bin), "filter::silent", FALSE, NULL); + + g_object_get (G_OBJECT (child1), "silent", &state, NULL); + if (state) { + g_print ("ChildProxy's child property access failed !\n"); + return 1; + } + + gst_bin_remove (bin, child1); + + if (!removed) { + g_print ("ChildProxy::child-added has not been caught!\n"); + return 1; + } + + g_object_unref (G_OBJECT (bin)); + + /* success */ + return 0; +}